北京网站定制流程网页版微信登录入口官网
news/
2025/9/23 19:27:36/
文章来源:
北京网站定制流程,网页版微信登录入口官网,中国工程预算网,网站种类有哪些AI 对话【人工智能】 前言版权开源推荐AI 对话v0版本#xff1a;基础v1版本#xff1a;对话数据表tag.jsTagController v2版本#xff1a;回复中textarea.jsChatController v3版本#xff1a;流式输出chatLast.jsChatController v4版本#xff1a;多轮对话QianfanUtilChat… AI 对话【人工智能】 前言版权开源推荐AI 对话v0版本基础v1版本对话数据表tag.jsTagController v2版本回复中textarea.jsChatController v3版本流式输出chatLast.jsChatController v4版本多轮对话QianfanUtilChatController v5其他修改前端样式跳转到最后一个消息前端样式Message保留空白符前端样式最新回复保留空白符 最后 前言
2024-4-7 15:04:07
以下内容源自《【人工智能】》 仅供学习交流使用
版权
禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://jsss-1.blog.csdn.net 禁止其他平台发布时删除以上此话
开源
日星月云 / AI对话完善版
jsss-1/aichat
推荐
百度智能云SpringBootAI对话【人工智能】
对话Chat-千帆大模型平台
AI 对话
以下版本除了最简单的AI对话还完善了一下功能。
以下是部分代码完整代码请移步GIT。
v0版本基础
聊天
v1版本对话
新建新对话
可以置顶取消置顶、删除、修改对应的对话 数据表
create table tag
(id int auto_incrementprimary key,user_id int not null,tag_name varchar(16) not null,top int default 0 null
);create table conversation
(id int auto_incrementprimary key,tag_id int null,user_message text null,bot_message text null,create_time varchar(32) null,username varchar(16) null
);
tag.js
$(document).ready(function () {tagList();$(#editBlock).hide();$(.add-button).on(click, function() {addTag();});});function tagSearch(data) {var data$(#search-input).val();if(!data){//没有数据搜索全部tagList();return false;}$.ajax({type: GET,url: SERVER_PATH /tag/search,data: {data: data},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_tags(result.data);}});
}function addTag() {$.ajax({type: POST,url: SERVER_PATH /tag/addTag,xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function tagList() {$.ajax({type: GET,url: SERVER_PATH /tag/tagList,xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_tags(result.data);}});
}function set_tags(tags) {if (!tags) {return false;}$(.tag-list).empty();$.each(tags, function (i, tag) {var btnClass tag.top 0 ? top-btn : notop-btn;var topClass tag.top 0 ? ptTag : topTag;var tagDiv div classtagimg classtag-btn ${topClass}/imgspan classshow-btn data-id${tag.id}${tag.tagName}/spandiv classbutton-groupimg classicon-btn ${btnClass} data-id${tag.id}/imgimg classicon-btn modify-btn data-id${tag.id} data-name${tag.tagName}/imgimg classicon-btn delete-btn data-id${tag.id}/img/div/div;$(.tag-list).append(tagDiv);});$(.show-btn).on(click, function() {var tagId $(this).data(id);window.location.hrefaichat.html?tagIdtagId;});$(.notop-btn).on(click, function() {var tagId $(this).data(id);var newTop0;topTag(tagId,newTop);});$(.top-btn).on(click, function() {var tagId $(this).data(id);var newToptop1;topTag(tagId,newTop);});$(.modify-btn).on(click, function() {var tagId $(this).data(id);var tagName $(this).data(name); // 获取标签名称// 将标签名称填充到输入框中$(#newName).val(tagName);// 显示编辑界面块$(#editBlock).show();// 保存按钮点击事件$(#saveBtn).off(click).on(click, function() {var newName $(#newName).val();if(!newName){alertBox(请输入新名字);return false;}modify(tagId,newName);// 关闭编辑界面块$(#editBlock).hide();});$(#cancelBtn).on(click, function() {$(#editBlock).hide();});});$(.delete-btn).on(click, function() {var tagId $(this).data(id);// 弹出确认删除的提示框var confirmDelete confirm(确定要删除这个标签吗);// 如果用户点击确定删除则执行删除操作if (confirmDelete) {deleteTag(tagId);} });}function topTag(tagId,newTop){$.ajax({type: POST,url: SERVER_PATH /tag/top,data: {tagId: tagId,top: newTop},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function modify(tagId,newName){$.ajax({type: POST,url: SERVER_PATH /tag/modify,data: {tagId: tagId,tagName: newName},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function deleteTag(tagId){$.ajax({type: GET,url: SERVER_PATH /tag/delete,data: {tagId: tagId},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}
TagController
package com.jsss.qianfan.controller;import com.jsss.common.BusinessException;
import com.jsss.common.ErrorCode;
import com.jsss.common.ResponseModel;
import com.jsss.entity.User;
import com.jsss.qianfan.entity.Tag;
import com.jsss.qianfan.service.TagService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;import java.util.List;RestController
RequestMapping(tag)
CrossOrigin(origins ${jsss.web.path}, allowedHeaders *, allowCredentials true)
public class TagController implements ErrorCode {AutowiredRedisTemplate redisTemplate;AutowiredTagService tagService;GetMapping(/tagList)public ResponseModel getTags(String token) {User user null;if (StringUtils.isNotEmpty(token)) {user (User) redisTemplate.opsForValue().get(token);}if (user null) {throw new BusinessException(USER_NOT_LOGIN, 用户未登录);}ListTag tags tagService.searchByUserId(user.getUserId());return new ResponseModel(tags);}PostMapping(/addTag)public ResponseModel addTag(String token) {User user null;if (StringUtils.isNotEmpty(token)) {user (User) redisTemplate.opsForValue().get(token);}if (user null) {throw new BusinessException(USER_NOT_LOGIN, 用户未登录);}String tagName 新对话;Tag tag new Tag(null, user.getUserId(), tagName, 0);tagService.addTag(tag);return new ResponseModel(添加成功);}PostMapping(/modify)public ResponseModel modifyTag(Integer tagId, String tagName) {if (StringUtils.isEmpty(tagName)){throw new BusinessException(PARAMETER_ERROR, 缺失新的tag名);}tagService.updateTagName(tagId, tagName);return new ResponseModel(修改成功);}PostMapping(/top)public ResponseModel topTag(Integer tagId, Integer top) {tagService.updateTagTop(tagId, top);String res top 1 ? 置顶成功 : 取消置顶成功;return new ResponseModel(res);}GetMapping(/delete)public ResponseModel deleteTag(Integer tagId) {tagService.deleteTag(tagId);return new ResponseModel(删除成功);}GetMapping(/search)public ResponseModel searchTag(String token, String data) {User user null;if (StringUtils.isNotEmpty(token)) {user (User) redisTemplate.opsForValue().get(token);}if (user null) {throw new BusinessException(USER_NOT_LOGIN, 用户未登录);}ListTag tags tagService.searchTag(user.getUserId(),data);return new ResponseModel(tags);}}
v2版本回复中
用户发送问题之后显示回复中得到回复后显示。
前端发送请求之后先会得到“回复中” 之后去轮询获取最新回复。
后端接受请求之后先存入到数据库中一个未回复请求。 然后异步得到回复之后再去更新数据库。 textarea.js
var textarea document.getElementById(messageInput);var isSendingMessage false; // 添加一个变量用于标识是否正在发送消息textarea.addEventListener(keydown, function(event) {if (event.key Enter !event.shiftKey) {event.preventDefault();if (isSendingMessage) {// 如果正在发送消息则在文本框中添加换行符textarea.value \n;} else{var message textarea.value.trim();textarea.value ;if(!message){alertBox(输入内容不能为空);return false;}var tagId$.getUrlParam(tagId);;if(!tagId){alertBox(没有对应的参数);return false;}isSendingMessage true; // 设置为true表示正在发送消息$.ajax({type: POST,url: SERVER_PATH/chat/chat,data:{tagId: tagId,content:message},xhrFields: {withCredentials: true},success:function(result){isSendingMessage false; // 发送完成后设置为falseif (result.status) {alertBox(result.data.message);return false;}//请求成功之后list(tagId);getChat(result.data.id);}});}}
});textarea.addEventListener(keydown, function(event) {if (event.key Enter event.shiftKey) {// 在 ShiftEnter 情况下允许换行textarea.value \n;event.preventDefault();}
});function getChat(chatId){var tagId$.getUrlParam(tagId);;$.ajax({type: GET,url: SERVER_PATH/chat/getChat,data:{id: chatId,},xhrFields: {withCredentials: true},success:function(result){isSendingMessage false; // 发送完成后设置为falseif (result.status) {alertBox(result.data.message);return false;}if (result.data.botMessage 回复中...) {// 继续轮询100ms 一次setTimeout(function() {getChat(chatId);}, 100);} else {// 获取到最终回复// 处理回复逻辑list(tagId);}}});
}
ChatController PostMapping(/chat)public ResponseModel chat(Integer tagId,String content){if (tagIdnull){throw new BusinessException(PARAMETER_ERROR,没有指定响应的tag);}if (StringUtils.isEmpty(content)){throw new BusinessException(PARAMETER_ERROR,输入内容不能为空);}Tag tag tagService.searchById(tagId);if (tagnull){throw new BusinessException(NOT_FIND,没有找到对应的对话);}String usernameuserService.selectUserById(tag.getUserId()).getUsername();Conversation conversation new Conversation(null, tagId,username, content, 回复中..., format(new Date()));chatService.addChat(conversation);// 异步处理AI回复CompletableFuture.runAsync(() - {Integer idconversation.getId();String res null;try {res qianfanUtil.addMessage(content);} catch (Exception e) {res 回复失败;}Conversation aiConversation new Conversation();aiConversation.setId(id);aiConversation.setBotMessage(res);chatService.updateChat(aiConversation);});return new ResponseModel(conversation);}
v3版本流式输出
流式输出终止生成。
前端实现让消息一个字符一个字符显示 chatLast.js
var lastId;
var interval;$(document).ready(function () {$(#stopButton).on(click, function() {var latestReply $(.latest-reply);var latestReplyText latestReply.text();clearInterval(interval); // 停止字符流输出$(#stopButton).hide();updateStop(lastId,latestReplyText);});});function listLastReply(tagId) {$.ajax({type: GET,url: SERVER_PATH /chat/list,data: {tagId: tagId},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_conversations_last(result.data);}});
}function set_conversations_last(conversations) {if (!conversations) {return false;}$(.conversation-list).empty();var lenconversations.length;$.each(conversations, function (i, conversation) {var questionDiv div classquestion-container table classquestion td span conversation.createTime /span div classuser-message conversation.userMessage /div /td td typetext conversation.username /td /table /div;var answerDiv div classanswer-container table classanswer td typetextAI/td td span conversation.createTime /span div classbot-message conversation.botMessage /div /td /table /div;if(i!len-1){$(.conversation-list).append(questionDiv);$(.conversation-list).append(answerDiv);}});// 获取最新对话的回复var lastConversation conversations[len - 1];lastIdlastConversation.id;var questionDiv div classquestion-container table classquestion td span lastConversation.createTime /span div classuser-message lastConversation.userMessage /div /td td typetext lastConversation.username /td /table /div;$(.conversation-list).append(questionDiv);var answerDiv div classanswer-container table classanswer td typetextAI/td td span lastConversation.createTime /span div classbot-message latest-reply lastConversation.botMessage /div /td /table /div;$(.conversation-list).append(answerDiv);// 逐字显示最新回复var latestReply $(.latest-reply);var latestReplyText latestReply.text();latestReply.empty();var index 0;interval setInterval(function() {if (index latestReplyText.length) {$(#stopButton).show();latestReply.append(latestReplyText.charAt(index));index;} else {clearInterval(interval);$(#stopButton).hide();}}, 10); // 逐字显示的速度您可以根据需要调整}function updateStop(tagId,message){$.ajax({type: POST,url: SERVER_PATH /chat/updateStop,data: {id: tagId,botMessage: message},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}}});
}ChatController PostMapping(/updateStop)public ResponseModel updateStop(Integer id,String botMessage){Conversation conversationnew Conversation();conversation.setId(id);conversation.setBotMessage(botMessage);chatService.updateChat(conversation);return new ResponseModel();}v4版本多轮对话
实现上下文有关的对话
多次调用qianfan.addMessage().addMessage() QianfanUtil public String addMessagePlus(ListMessage messages, String content) {ChatResponse response qianfan.chatCompletion().messages(messages).addMessage(user, content).temperature(0.7).execute();return response.getResult();}ChatController
PostMapping(/chat)public ResponseModel chat(Integer tagId, String content) {if (tagId null) {throw new BusinessException(PARAMETER_ERROR, 没有指定响应的tag);}if (StringUtils.isEmpty(content)) {throw new BusinessException(PARAMETER_ERROR, 输入内容不能为空);}Tag tag tagService.searchById(tagId);if (tag null) {throw new BusinessException(NOT_FIND, 没有找到对应的对话);}String username userService.selectUserById(tag.getUserId()).getUsername();Conversation conversation new Conversation(null, tagId, username, content, 回复中..., format(new Date()));chatService.addChat(conversation);// 异步处理AI回复CompletableFuture.runAsync(() - {Integer id conversation.getId();String res null;try {
// res qianfanUtil.addMessage(content);res qianfanUtil.addMessagePlus(getMessages(tagId), content);} catch (Exception e) {res 回复失败;}Conversation aiConversation new Conversation();aiConversation.setId(id);aiConversation.setBotMessage(res);chatService.updateChat(aiConversation);});return new ResponseModel(conversation);}public ListMessage getMessages(Integer tagId) {ListMessage messages new ArrayList();ListConversation conversations chatService.searchByTagId(tagId);int size conversations.size() - 1;//最新的不需要for (int i 0; i size; i) {Conversation conversation conversations.get(i);Message userMessage new Message();userMessage.setRole(user);userMessage.setContent(conversation.getUserMessage());messages.add(userMessage);Message botMessage new Message();botMessage.setRole(assistant);botMessage.setContent(conversation.getBotMessage());messages.add(botMessage);}return messages;}
v5其他修改 前端样式跳转到最后一个消息
在aichat.html中 scriptfunction scrollToLastMessage() {// 找到消息容器var messageContainer document.querySelector(.message-container);// 找到消息容器中最后一个子元素var lastMessage messageContainer.lastElementChild;// 将最后一个消息元素滚动到可见区域lastMessage.scrollIntoView({ behavior: auto, block: end });}function onLoad() {setTimeout(scrollToLastMessage, 100); // 添加100毫秒的延迟}window.addEventListener(load, onLoad);/script前端样式Message保留空白符
savePre(conversation.userMessage)
savePre(conversation.botMessage)function savePre(content){return content.replace(/\n/g, br).replace(/ /g, spannbsp;/span);
}前端样式最新回复保留空白符 var botMessageWithBrAndSpace lastConversation.botMessage.replace(/\n/g, \\n);var answerDiv div classanswer-container table classanswer td typetextAI/td td span lastConversation.createTime /span div classbot-message latest-reply botMessageWithBrAndSpace /div /td /table /div;$(.conversation-list).append(answerDiv);// 逐字显示最新回复var latestReply $(.latest-reply);var latestReplyText botMessageWithBrAndSpace;latestReply.empty();var index 0;interval setInterval(function() {if (index latestReplyText.length) {$(#stopButton).show();if (latestReplyText.charAt(index) \\) {if (latestReplyText.charAt(index 1) n) {latestReply.append(br);index; // 跳过n} else {latestReply.append(latestReplyText.charAt(index));}} else if(latestReplyText.charAt(index) ){latestReply.append(nbsp;);}else {latestReply.append(latestReplyText.charAt(index));}index;} else {clearInterval(interval);$(#stopButton).hide();}}, 25); // 逐字显示的速度您可以根据需要调整}
最后
2024-4-10 17:02:49
迎着日光月光星光直面风霜雨霜雪霜。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/913627.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!