|
@@ -5,7 +5,11 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="conversation-chat-main" ref="chat_main">
|
|
<div class="conversation-chat-main" ref="chat_main">
|
|
|
- <DialogHeader class="conversation-chat-header" :style="{ height: header_height + 'px' }" />
|
|
|
|
|
|
|
+ <DialogHeader
|
|
|
|
|
+ class="conversation-chat-header"
|
|
|
|
|
+ :agent_info="CHAT_AGENT_INFOMATION"
|
|
|
|
|
+ :style="{ height: header_height + 'px' }"
|
|
|
|
|
+ />
|
|
|
|
|
|
|
|
<div class="conversation-chat-content">
|
|
<div class="conversation-chat-content">
|
|
|
<DialogWelcome v-if="show_welcome" class="conversation-chat-area" />
|
|
<DialogWelcome v-if="show_welcome" class="conversation-chat-area" />
|
|
@@ -25,9 +29,9 @@
|
|
|
ref="dialog_input"
|
|
ref="dialog_input"
|
|
|
class="conversation-chat-input"
|
|
class="conversation-chat-input"
|
|
|
:style="{ height: input_height + 'px' }"
|
|
:style="{ height: input_height + 'px' }"
|
|
|
|
|
+ :agent_info="CHAT_AGENT_INFOMATION.agent"
|
|
|
|
|
+ :agent_config="CHAT_AGENT_INFOMATION.config"
|
|
|
:disabled="input_disabled"
|
|
:disabled="input_disabled"
|
|
|
- @inputTextChange="handleTextChange"
|
|
|
|
|
- @inputFileChange="handleFileChange"
|
|
|
|
|
@submit="handleInputSubmit"
|
|
@submit="handleInputSubmit"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -52,8 +56,12 @@ import DialogInput from '../../modules/conversation-chat/DialogInput.vue';
|
|
|
import DialogFooter from '../../modules/conversation-chat/DialogFooter.vue';
|
|
import DialogFooter from '../../modules/conversation-chat/DialogFooter.vue';
|
|
|
import DialogAsideRight from '../../modules/conversation-chat/DialogAsideRight.vue';
|
|
import DialogAsideRight from '../../modules/conversation-chat/DialogAsideRight.vue';
|
|
|
|
|
|
|
|
|
|
+import { useAllAgentStore } from '../../base/store/use-all-agents';
|
|
|
|
|
+import getAgentClientConfig from '../../modules/conversation-board/get-agent-client-config';
|
|
|
|
|
+
|
|
|
import useWebSocketChat from '../../modules/conversation-dialog/use-websocket-chat';
|
|
import useWebSocketChat from '../../modules/conversation-dialog/use-websocket-chat';
|
|
|
-import { getHistoryLogs, getDialogChatId } from '../../modules/conversation-dialog/api-dialog';
|
|
|
|
|
|
|
+import { getHistoryLogs, getDialogChatId, uploadFiles } from '../../modules/conversation-dialog/api-dialog';
|
|
|
|
|
+import files2Formdata from '../../modules/file-upload/files-2-formdata';
|
|
|
|
|
|
|
|
import formatDialogSendOptions from '../../modules/conversation-dialog/format-dialog-send-options';
|
|
import formatDialogSendOptions from '../../modules/conversation-dialog/format-dialog-send-options';
|
|
|
|
|
|
|
@@ -87,6 +95,19 @@ const props = defineProps({
|
|
|
chat_type: String
|
|
chat_type: String
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+const allAgents = useAllAgentStore();
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 对话使用到的agent信息
|
|
|
|
|
+ * agent属性是由接口返回的数据
|
|
|
|
|
+ * config属性是客户端自定义的数据,针对特定的agent的一些个性化配置,可由此进行配置
|
|
|
|
|
+ * 二者结合,形成对话组件所需要的一些参数
|
|
|
|
|
+ */
|
|
|
|
|
+const CHAT_AGENT_INFOMATION = ref({
|
|
|
|
|
+ agent: {},
|
|
|
|
|
+ config: {}
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
const header_height = 30;
|
|
const header_height = 30;
|
|
|
const footer_height = 30;
|
|
const footer_height = 30;
|
|
|
const input_height = 100;
|
|
const input_height = 100;
|
|
@@ -168,31 +189,11 @@ const handleSuggestSubmit = (suggest) => {};
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
// ---------------------------------------------
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * 输入区域数据控制
|
|
|
|
|
- */
|
|
|
|
|
-const input_text = ref('');
|
|
|
|
|
-const input_files = ref([]);
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* 是否禁用输入组件
|
|
* 是否禁用输入组件
|
|
|
*/
|
|
*/
|
|
|
const input_disabled = ref(false);
|
|
const input_disabled = ref(false);
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * 输入文本发生了变化
|
|
|
|
|
- * @param value
|
|
|
|
|
- */
|
|
|
|
|
-const handleTextChange = (value) => {
|
|
|
|
|
- input_text.value = value;
|
|
|
|
|
-};
|
|
|
|
|
-/**
|
|
|
|
|
- * 输入的文件发生了变化
|
|
|
|
|
- * @param files
|
|
|
|
|
- */
|
|
|
|
|
-const handleFileChange = (files) => {
|
|
|
|
|
- input_files.value = files;
|
|
|
|
|
-};
|
|
|
|
|
/**
|
|
/**
|
|
|
* 输入已经确认要提交了
|
|
* 输入已经确认要提交了
|
|
|
*
|
|
*
|
|
@@ -201,7 +202,12 @@ const handleFileChange = (files) => {
|
|
|
* 3. 连接socket,socket 发送文本与文件数据内容
|
|
* 3. 连接socket,socket 发送文本与文件数据内容
|
|
|
* 4. 接收 socket 返回的数据项
|
|
* 4. 接收 socket 返回的数据项
|
|
|
*/
|
|
*/
|
|
|
-const handleInputSubmit = async () => {
|
|
|
|
|
|
|
+const handleInputSubmit = async (options) => {
|
|
|
|
|
+ const ask_text = options.text; // 文本
|
|
|
|
|
+ const ask_files = options.files; // 文件列表
|
|
|
|
|
+
|
|
|
|
|
+ const agent_id = props.agent_id;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 创建会话 get chat id
|
|
* 创建会话 get chat id
|
|
|
* 判断对话是否已经创建
|
|
* 判断对话是否已经创建
|
|
@@ -211,7 +217,7 @@ const handleInputSubmit = async () => {
|
|
|
if (chat_new_id.value === null) {
|
|
if (chat_new_id.value === null) {
|
|
|
// 未创建chat,开始创建
|
|
// 未创建chat,开始创建
|
|
|
try {
|
|
try {
|
|
|
- const chatResult = await getDialogChatId(props.agent_id);
|
|
|
|
|
|
|
+ const chatResult = await getDialogChatId(agent_id);
|
|
|
|
|
|
|
|
if (chatResult.code / 1 === 200) {
|
|
if (chatResult.code / 1 === 200) {
|
|
|
// 成功
|
|
// 成功
|
|
@@ -234,24 +240,52 @@ const handleInputSubmit = async () => {
|
|
|
console.log(chat_new_id.value, '已创建');
|
|
console.log(chat_new_id.value, '已创建');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 文件上传后的信息
|
|
|
|
|
+ let files_response = null;
|
|
|
/**
|
|
/**
|
|
|
* 如果存在文件数据,则进行文件上传
|
|
* 如果存在文件数据,则进行文件上传
|
|
|
*/
|
|
*/
|
|
|
- if (input_files.value.length !== 0) {
|
|
|
|
|
|
|
+ if (ask_files.length !== 0) {
|
|
|
// 进行文件上传,获取文件信息
|
|
// 进行文件上传,获取文件信息
|
|
|
|
|
+ const file_params = files2Formdata(ask_files);
|
|
|
|
|
+ const chat_id = chat_new_id.value;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const uploadResult = await uploadFiles(agent_id, chat_id, file_params);
|
|
|
|
|
+
|
|
|
|
|
+ if (uploadResult.code / 1 === 200) {
|
|
|
|
|
+ // 文件上传成功
|
|
|
|
|
+ const file_uploaded = uploadResult.data;
|
|
|
|
|
+
|
|
|
|
|
+ if (Array.isArray(file_uploaded)) {
|
|
|
|
|
+ files_response = file_uploaded;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ files_response = [file_uploaded];
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 文件上传异常
|
|
|
|
|
+ // TODO: 处理错误
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.log(err);
|
|
|
|
|
+ // 文件上传失败
|
|
|
|
|
+ // TODO: 处理错误
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 获取文件参数
|
|
* 获取文件参数
|
|
|
* 组装socket参数
|
|
* 组装socket参数
|
|
|
*/
|
|
*/
|
|
|
- const msg = formatDialogSendOptions(input_text.value, input_files.value);
|
|
|
|
|
|
|
+ const msg = formatDialogSendOptions(ask_text, files_response);
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 整理客户端提问的数据
|
|
* 整理客户端提问的数据
|
|
|
* 组装Question数据
|
|
* 组装Question数据
|
|
|
*/
|
|
*/
|
|
|
- const client_question = formatDialogQuestionByClient(input_text.value, input_files.value);
|
|
|
|
|
|
|
+ const client_question = formatDialogQuestionByClient(ask_text, ask_files);
|
|
|
// 保存用户的提问信息
|
|
// 保存用户的提问信息
|
|
|
// 当消息正式发出后,将提问数据放入列表中
|
|
// 当消息正式发出后,将提问数据放入列表中
|
|
|
chat_new_question.value = client_question;
|
|
chat_new_question.value = client_question;
|
|
@@ -333,8 +367,6 @@ function handleWSSend(chat_id, value) {
|
|
|
*/
|
|
*/
|
|
|
show_welcome.value = false;
|
|
show_welcome.value = false;
|
|
|
// 清空文本数据和文件数据,避免下一次会话冲突
|
|
// 清空文本数据和文件数据,避免下一次会话冲突
|
|
|
- input_text.value = '';
|
|
|
|
|
- input_files.value = [];
|
|
|
|
|
// 清空表单里的数据
|
|
// 清空表单里的数据
|
|
|
inputClear();
|
|
inputClear();
|
|
|
// 清空可能存在的推荐项目
|
|
// 清空可能存在的推荐项目
|
|
@@ -364,40 +396,51 @@ function handleWSMessage(e) {
|
|
|
const currentChat = formatDialogAnswerFromWebsocketReceiveMessage(res_data, last_msg);
|
|
const currentChat = formatDialogAnswerFromWebsocketReceiveMessage(res_data, last_msg);
|
|
|
const chat_status = currentChat.status;
|
|
const chat_status = currentChat.status;
|
|
|
const chat_message = currentChat.message;
|
|
const chat_message = currentChat.message;
|
|
|
- const chat_data = currentChat.data;
|
|
|
|
|
-
|
|
|
|
|
- if (chat_status === 0) {
|
|
|
|
|
- // 未开始: 此状态不存在,无需处理
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- if (chat_status === 1) {
|
|
|
|
|
- // 此轮对话仍然在进行中
|
|
|
|
|
|
|
+ // 处理对话数据
|
|
|
|
|
+ const handleChatData = () => {
|
|
|
|
|
+ const chat_data = currentChat.data; // 对话相关的数据项
|
|
|
|
|
|
|
|
// 原来的最后一项弹出
|
|
// 原来的最后一项弹出
|
|
|
chat_new_list.value.pop();
|
|
chat_new_list.value.pop();
|
|
|
// 添加新的最后一项
|
|
// 添加新的最后一项
|
|
|
chat_new_list.value.push(chat_data);
|
|
chat_new_list.value.push(chat_data);
|
|
|
|
|
+
|
|
|
// 滚动到底部
|
|
// 滚动到底部
|
|
|
scroll2ListBottom();
|
|
scroll2ListBottom();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (chat_status === 0) {
|
|
|
|
|
+ // 未开始: 此状态不存在,无需处理
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (chat_status === 1) {
|
|
|
|
|
+ // 此轮对话仍然在进行中
|
|
|
|
|
+ handleChatData();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (chat_status === 2) {
|
|
if (chat_status === 2) {
|
|
|
// 此轮对话已结束
|
|
// 此轮对话已结束
|
|
|
|
|
+ handleChatData();
|
|
|
|
|
|
|
|
- // 原来的最后一项弹出
|
|
|
|
|
- chat_new_list.value.pop();
|
|
|
|
|
- // 添加新的最后一项
|
|
|
|
|
- chat_new_list.value.push(chat_data);
|
|
|
|
|
- // 滚动到底部
|
|
|
|
|
- scroll2ListBottom();
|
|
|
|
|
|
|
+ // 对话已结束:检查是否存在推荐数据
|
|
|
|
|
+ const chat_suggest = currentChat.suggest; // 对话相关的推荐数据
|
|
|
|
|
+ if (chat_suggest) {
|
|
|
|
|
+ chat_suggestion.value = chat_suggest;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 文件上传、文本输入区域放开使用
|
|
|
|
|
|
|
+ // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
input_disabled.value = false;
|
|
input_disabled.value = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (chat_status === 3) {
|
|
if (chat_status === 3) {
|
|
|
// 此轮对话出错了
|
|
// 此轮对话出错了
|
|
|
// TODO: 错误处理
|
|
// TODO: 错误处理
|
|
|
|
|
+
|
|
|
|
|
+ // 此轮对话已结束
|
|
|
|
|
+ handleChatData();
|
|
|
|
|
+ // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
|
|
+ input_disabled.value = false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -414,10 +457,13 @@ function handleWSError(e) {}
|
|
|
function handleWSClose(e) {}
|
|
function handleWSClose(e) {}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
|
|
+ const agent_id = props.agent_id;
|
|
|
|
|
+ const session_id = props.session_id;
|
|
|
|
|
+
|
|
|
// 组件挂载
|
|
// 组件挂载
|
|
|
- if (props.session_id) {
|
|
|
|
|
|
|
+ if (session_id) {
|
|
|
// 有历史记录:获取历史记录内容进行展示
|
|
// 有历史记录:获取历史记录内容进行展示
|
|
|
- getHistoryLogs(props.agent_id, props.session_id)
|
|
|
|
|
|
|
+ getHistoryLogs(agent_id, session_id)
|
|
|
.then((res) => {
|
|
.then((res) => {
|
|
|
if (res.code / 1 === 200) {
|
|
if (res.code / 1 === 200) {
|
|
|
// 成功
|
|
// 成功
|
|
@@ -447,6 +493,27 @@ onMounted(() => {
|
|
|
} else {
|
|
} else {
|
|
|
// 无历史记录:等待创建会话内容(用户开始输入、提交完成),列表区域显示欢迎界面
|
|
// 无历史记录:等待创建会话内容(用户开始输入、提交完成),列表区域显示欢迎界面
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据agent_id 查询到agent的基本信息
|
|
|
|
|
+ * 从而确定agent的相关功能支持,例如:是否需要上传文件,支持上传什么类型的文件、支持上传多少个文件?
|
|
|
|
|
+ * 例如:主题、背景、等等
|
|
|
|
|
+ */
|
|
|
|
|
+ const agentInfo = allAgents.getInfo(agent_id);
|
|
|
|
|
+ if (agentInfo) {
|
|
|
|
|
+ const client_config = getAgentClientConfig(agent_id);
|
|
|
|
|
+ if (client_config) {
|
|
|
|
|
+ CHAT_AGENT_INFOMATION.value = {
|
|
|
|
|
+ config: client_config,
|
|
|
|
|
+ agent: agentInfo
|
|
|
|
|
+ };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ CHAT_AGENT_INFOMATION.value = {
|
|
|
|
|
+ config: {},
|
|
|
|
|
+ agent: agentInfo
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
// ---------------------------------------------------------
|
|
@@ -484,7 +551,7 @@ onUnmounted(() => {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
- background-color: #aaa;
|
|
|
|
|
|
|
+ /* background-color: #aaa; */
|
|
|
}
|
|
}
|
|
|
.conversation-chat-content {
|
|
.conversation-chat-content {
|
|
|
flex-grow: 1;
|
|
flex-grow: 1;
|