【创新】springboot框架整合ai智能对话(超简单)

在这里插入图片描述

一、后端controller

package com.mentalhealth.ai;

import com.baidubce.appbuilder.console.appbuilderclient.AppBuilderClient;
import com.baidubce.appbuilder.model.appbuilderclient.AppBuilderClientIterator;
import com.baidubce.appbuilder.model.appbuilderclient.AppBuilderClientResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class AiController {

    @ResponseBody
    @RequestMapping("/aiduihua")
    public String ai(@RequestParam("question") String question){

        String aiAnswer = null;
        try {
            aiAnswer = getAiAnswer(question);
        } catch (Exception e) {
            e.printStackTrace();
            return "ai系统报错,请稍后再试!";
        }

        return aiAnswer;
    }

    public  String  getAiAnswer(String question) throws Exception {
        // 设置环境中的TOKEN,以下TOKEN请替换为您的个人TOKEN,个人TOKEN可通过该页面【获取鉴权参数】或控制台页【密钥管理】处获取
        System.setProperty("APPBUILDER_TOKEN", "自己去申请一个秘钥");
        // 从AppBuilder控制台【个人空间】-【应用】网页获取已发布应用的ID
        String appId = "8c9c0cd0-df9d-41ce-9da7-5d80b6df140d";
        AppBuilderClient builder = new AppBuilderClient(appId);
        String conversationId = builder.createConversation();

        AppBuilderClientIterator itor = builder.run(question, conversationId, new String[] {}, false);
        StringBuilder answer = new StringBuilder();
        while (itor.hasNext()) {
            AppBuilderClientResult response = itor.next();
            answer.append(response.getAnswer());
        }
        System.out.println(answer);

        return answer.toString();
    }

}

二、前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI 对话</title>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #f2f2f2;
        }
        .chat-container {
            width: 800px;
            height: 600px;
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            overflow: hidden;
            display: flex;
            flex-direction: column;
            margin-top: 50px;
        }
        .chat-history {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
        }
        .chat-message {
            display: flex;
            margin-bottom: 15px;
            max-width: 99%;
            border-radius: 10px;
            padding: 10px;
        }
        .chat-message.user {
            justify-content: flex-end;
            background-color: #dcf8c6;
            align-items: flex-end;
        }
        .chat-message.ai {
            justify-content: flex-start;
            background-color: #e0e0e0;
            align-items: flex-start;
        }
        .chat-message .text {
            word-wrap: break-word;
        }
        .chat-input {
            display: flex;
            padding: 10px;
            background-color: #f9f9f9;
            border-top: 1px solid #ddd;
        }
        .chat-input input {
            flex: 1;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            outline: none;
        }
        .chat-input button {
            margin-left: 10px;
            padding: 10px 20px;
            border: none;
            background-color: #1aad19;
            color: #fff;
            border-radius: 5px;
            cursor: pointer;
        }
        .chat-input button:hover {
            background-color: #168d12;
        }
    </style>
</head>

<body>
<div style="position: absolute;top: 0;width: 100%;">
    <div th:replace="foreground/client/header::header(心理社区,null)"></div>
</div>
<div class="chat-container">
    <div class="chat-history" id="chatHistory">
        <!-- 历史对话将动态添加到这里 -->
    </div>
    <div class="chat-input">
        <input type="text" id="questionInput" placeholder="输入您的问题...">
        <button onclick="sendQuestion()">发送</button>
    </div>
</div>

<script>
    function sendQuestion() {
        const question = document.getElementById('questionInput').value;
        const xhr = new XMLHttpRequest();
        xhr.open('GET', `/aiduihua?question=${encodeURIComponent(question)}`, true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                displayAnswer(xhr.responseText);
                document.getElementById('questionInput').value = ''; // 清空输入框
            }
        };
        xhr.send();
    }

    function displayAnswer(answer) {
        const chatHistory = document.getElementById('chatHistory');

        // 创建AI回答的消息元素
        const aiMessage = document.createElement('div');
        aiMessage.className = 'chat-message ai';
        aiMessage.innerHTML = `<span class="text">${answer}</span>`;

        // 创建用户问题的消息元素(假设这里只是为了展示布局,实际上不需要再次发送请求获取)
        const userMessage = document.createElement('div');
        userMessage.className = 'chat-message user';
        const userInputText = document.getElementById('questionInput').value; // 注意:这里应该是之前发送的问题,但为了演示我们再次获取(实际中应从发送前的状态获取)
        userMessage.innerHTML = `<span class="text">${userInputText}</span>`; // 注意:这里应该使用之前的问题文本,但为了简化代码我们直接用了输入框的值(在发送后应为空)

        // 正常情况下,我们应该只添加AI的回答,因为用户的问题已经在发送前添加到DOM中了(如果需要的话)
        // 但为了展示布局效果,我们在这里再次“模拟”添加用户问题(实际上这是不必要的)
        // 正确的做法是在发送问题后立即(或在sendQuestion函数内)添加用户问题到DOM,然后接收回答后添加AI回答

        // 正确的添加顺序(这里仅作为注释说明,实际代码已在下方实现):
        // 1. 在sendQuestion函数内,发送问题前或发送成功后(使用setTimeout模拟异步),添加用户问题到DOM
        // 2. 接收回答后,在这里添加AI回答到DOM

        // 由于我们在这个示例中是为了展示布局,所以下面会“错误地”再次添加用户问题(仅为了展示左右布局)
        // 在实际应用中,应该避免这种重复添加

        // 正确的添加用户问题(应在发送问题后立即或成功后添加,这里仅作为说明):
        chatHistory.appendChild(userMessage); // 这行代码应该在发送问题后立即执行(但不在这个函数内)

        // 现在只添加AI的回答
        chatHistory.appendChild(aiMessage);

        // 为了模拟发送问题后立即显示用户问题(实际中应在发送前或发送成功后添加),
        // 我们可以注释掉上面的“错误”添加用户问题的代码,并在sendQuestion函数内添加。
        // 但由于这个示例的目的是展示布局,所以上面“错误”的代码保留用于展示。

        // 滚动到底部以便查看最新消息
        chatHistory.scrollTop = chatHistory.scrollHeight;
    }

    // 示例:模拟用户发送一个问题(可选,仅用于展示布局效果)
    // 注意:这里的模拟发送是不必要的,仅用于页面加载时展示一个示例对话
    // 在实际应用中,应该移除这段代码
    window.onload = function () {
        // 模拟用户输入一个问题(这里使用setTimeout模拟异步发送和接收)
        const simulatedQuestion = "你好,AI!";
        document.getElementById('questionInput').value = simulatedQuestion;
        setTimeout(() => {
            // 模拟AI的回答
            const simulatedAnswer = "您好!我是AI助手,很高兴与您对话。";
            // 由于我们在这个示例中模拟了用户问题的添加,所以这里不需要再次发送请求
            // 直接调用displayAnswer函数显示AI的回答
            displayAnswer(simulatedAnswer);

            // 正常情况下,我们应该在发送问题后立即(或在sendQuestion内)添加用户问题到DOM
            // 但由于这个示例的特殊性,我们已经在displayAnswer内“错误地”添加了用户问题
            // 所以这里不需要再次添加。在实际应用中,应该按照正确的顺序添加消息。

            // 清空输入框(模拟用户发送问题后的行为)
            document.getElementById('questionInput').value = '';
        }, 1000); // 模拟网络延迟,1秒后显示AI的回答
    };

    // 注意:上面的window.onload函数内的模拟发送和接收是不必要的,并且在实际应用中应该移除。
    // 它仅用于在这个示例中展示一个初始的对话布局效果。
    // 在实际应用中,用户输入问题后,应该调用sendQuestion函数发送问题,
    // 然后在接收到回答后调用displayAnswer函数显示AI的回答。

    // 为了避免混淆,下面的代码是实际应用中应该采用的逻辑(但已在上文中通过注释说明):
    // 1. 用户输入问题
    // 2. 调用sendQuestion函数发送问题(并在发送前或发送成功后立即将用户问题添加到DOM)
    // 3. 在sendQuestion函数的xhr.onreadystatechange回调中接收回答
    // 4. 调用displayAnswer函数显示AI的回答

    // 由于这个示例已经包含了这些逻辑(尽管在window.onload中有一些不必要的模拟代码),
    // 所以下面的实际逻辑代码没有再次重复写出。只需按照上面的注释说明理解即可。
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值