|
|
@@ -2,16 +2,22 @@
|
|
|
<div class="conversation-chat">
|
|
|
<div class="conversation-header">
|
|
|
<div class="header-nav">
|
|
|
- <img class="icon" :src="Icon" alt="" />
|
|
|
+ <img class="icon" :src="target_robot_icon" alt="" />
|
|
|
<div class="title">{{ header_title }}</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="conversation-body">
|
|
|
- <div class="chat-container">
|
|
|
- <ChatList :chat_list="chat_display_list"></ChatList>
|
|
|
+ <div class="chat-container" ref="list_scroller">
|
|
|
+ <ChatList :chat_list="chat_display_list" :target_agent_icon="target_icon" @insertEchart="insert"></ChatList>
|
|
|
</div>
|
|
|
<div class="chat-input">
|
|
|
- <DialogInput></DialogInput>
|
|
|
+ <DialogInput
|
|
|
+ ref="dialog_input"
|
|
|
+ :chat_type="chat_type"
|
|
|
+ :is_input_ing="input_ing"
|
|
|
+ @submit="handleSubmit"
|
|
|
+ @stop="stopResponse"
|
|
|
+ ></DialogInput>
|
|
|
<DialogFooter></DialogFooter>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -19,15 +25,59 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="js">
|
|
|
-import { ref,computed } from 'vue'
|
|
|
+import { ref,computed,nextTick,onMounted } from 'vue'
|
|
|
import Icon from '../../assets/agent/icon_1.svg'
|
|
|
import DialogInput from '../../modules/conversation-chat/DialogInput.vue'
|
|
|
import DialogFooter from '../../modules/conversation-chat/DialogFooter.vue'
|
|
|
import ChatList from './conversation-znws/ChatList.vue'
|
|
|
+import formatDialogQuestionByClient from '../../modules/conversation-dialog/format-dialog-question-by-client';
|
|
|
+import formatDialogAnswerForLoading from '../../modules/conversation-dialog/format-dialog-answer-for-loading';
|
|
|
+import formatDialogAnswerForException from '../../modules/conversation-dialog/format-dialog-answer-for-exception';
|
|
|
+import formatDialogAnswerFromSseReceiveMessageZnws from '../../modules/conversation-dialog/format-dialog-answer-from-sse_receive_message_znws';
|
|
|
+
|
|
|
+import { getUserName } from '../../utils/get-user-name';
|
|
|
+import { getUserId } from '../../utils/get-user-id';
|
|
|
+import { getIcon } from '../common/use-icon-map';
|
|
|
+import { useThemeStore } from '../../base/store/use-theme';
|
|
|
+import { THEME_LIGHT, THEME_DARK, THEME_GREEN, THEME_PARTY } from '../../base/variables';
|
|
|
+import useInputClear from './use-input-clear';
|
|
|
+import { useAgentUsedStore } from '../../base/store/use-agent-used';
|
|
|
+import {
|
|
|
+ getDialogSessionId_AL,
|
|
|
+ getAgentIcons,
|
|
|
+} from '../../modules/conversation-dialog/api-dialog';
|
|
|
+import useFetchEventSourceZnws from '../../modules/conversation-dialog/use-sse-znws';
|
|
|
+
|
|
|
const props = defineProps({
|
|
|
})
|
|
|
+const emit = defineEmits(['insertEchart']);
|
|
|
+
|
|
|
+const agentUsedStore = useAgentUsedStore();
|
|
|
|
|
|
const header_title = ref('智能问数助手')
|
|
|
+const chat_type = ref('znws')
|
|
|
+// 是否正在对话
|
|
|
+const input_ing = ref(false)
|
|
|
+// 会话id阿里智能体(问数)
|
|
|
+const WS_session = ref({
|
|
|
+ conversation_id: '',
|
|
|
+ record_id: ''
|
|
|
+});
|
|
|
+const target_icon = ref('')
|
|
|
+const themeStore = useThemeStore();
|
|
|
+
|
|
|
+const target_robot_icon = computed(() => {
|
|
|
+ if (themeStore.value == THEME_GREEN) {
|
|
|
+ return getIcon(target_icon.value, 'a');
|
|
|
+ } else if (themeStore.value == THEME_PARTY) {
|
|
|
+ return getIcon(target_icon.value, 'b');
|
|
|
+ } else if (themeStore.value == THEME_LIGHT) {
|
|
|
+ return getIcon(target_icon.value, 'c');
|
|
|
+ } else {
|
|
|
+ return getIcon(target_icon.value, 'a');
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
|
|
|
// 聊天对话列表
|
|
|
const moke_data = ref([
|
|
|
@@ -36,24 +86,140 @@ const moke_data = ref([
|
|
|
answer:'你好,我是你的专属报告生成助手,有什么可以帮助您的么?',
|
|
|
result_list:['你好,我是你的专属报告生成助手,有什么可以帮助您的么?']
|
|
|
},
|
|
|
- {
|
|
|
- client_custom_item_type:'q',
|
|
|
- question:'什么是大模型?'
|
|
|
- },
|
|
|
- {
|
|
|
- client_custom_item_type:'a',
|
|
|
- answer:'',
|
|
|
- result_list:['不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据']
|
|
|
- },
|
|
|
- {
|
|
|
- client_custom_item_type:'q',
|
|
|
- question:'什么是大模型?'
|
|
|
- },
|
|
|
- {
|
|
|
- client_custom_item_type:'a',
|
|
|
- answer:'',
|
|
|
- result_list:['不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据不知道参测试数测试数据']
|
|
|
- }
|
|
|
+// {
|
|
|
+// client_custom_item_type:'q',
|
|
|
+// question:'什么是大模型?'
|
|
|
+// },
|
|
|
+// {
|
|
|
+// client_custom_item_type:'a',
|
|
|
+// answer:'',
|
|
|
+// result_list:['不知道参测试数测试数据不知道参测试数测试',{
|
|
|
+// "type": "bar",
|
|
|
+// "title": "供电可靠率情况",
|
|
|
+// "color": "xxx",
|
|
|
+// 'origin_chart':'</table>{\"type\": \"bar\", \"title\": \"供电可靠率情况\", \"color\": \"xxx\", \"chartData\": [{\"name\": \"成都\", \"type\": \"bar\", \"value\": \"99.96%\"}, {\"name\": \"宜宾\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"天府\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"攀枝花\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"遂宁\", \"type\": \"bar\", \"value\": \"99.93%\"}, {\"name\": \"自贡\", \"type\": \"bar\", \"value\": \"99.92%\"}, {\"name\": \"内江\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"南充\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"德阳\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"绵阳\", \"type\": \"bar\", \"value\": \"99.89%\"}, {\"name\": \"达州\", \"type\": \"bar\", \"value\": \"99.89%\"}, {\"name\": \"眉山\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"广元\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"巴中\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"乐山\", \"type\": \"bar\", \"value\": \"99.86%\"}, {\"name\": \"泸州\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"雅安\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"广安\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"资阳\", \"type\": \"bar\", \"value\": \"99.84%\"}, {\"name\": \"凉山\", \"type\": \"bar\", \"value\": \"99.65%\"}, {\"name\": \"阿坝\", \"type\": \"bar\", \"value\": \"99.34%\"}, {\"name\": \"甘孜\", \"type\": \"bar\", \"value\": \"98.81%\"}, {\"name\": \"岷江\", \"type\": \"bar\", \"value\": \"100.00%\"}]}<table/>',
|
|
|
+// "chartData": [
|
|
|
+// {
|
|
|
+// "name": "成都",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.96%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "宜宾",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.94%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "天府",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.94%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "攀枝花",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.94%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "遂宁",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.93%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "自贡",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.92%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "内江",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.90%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "南充",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.90%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "德阳",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.90%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "绵阳",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.89%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "达州",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.89%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "眉山",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.87%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "广元",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.87%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "巴中",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.87%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "乐山",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.86%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "泸州",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.85%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "雅安",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.85%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "广安",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.85%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "资阳",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.84%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "凉山",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.65%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "阿坝",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "99.34%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "甘孜",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "98.81%"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "岷江",
|
|
|
+// "type": "bar",
|
|
|
+// "value": "100.00%"
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// }
|
|
|
+// ],
|
|
|
+// origin_chart:'</table>{\"type\": \"bar\", \"title\": \"供电可靠率情况\", \"color\": \"xxx\", \"chartData\": [{\"name\": \"成都\", \"type\": \"bar\", \"value\": \"99.96%\"}, {\"name\": \"宜宾\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"天府\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"攀枝花\", \"type\": \"bar\", \"value\": \"99.94%\"}, {\"name\": \"遂宁\", \"type\": \"bar\", \"value\": \"99.93%\"}, {\"name\": \"自贡\", \"type\": \"bar\", \"value\": \"99.92%\"}, {\"name\": \"内江\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"南充\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"德阳\", \"type\": \"bar\", \"value\": \"99.90%\"}, {\"name\": \"绵阳\", \"type\": \"bar\", \"value\": \"99.89%\"}, {\"name\": \"达州\", \"type\": \"bar\", \"value\": \"99.89%\"}, {\"name\": \"眉山\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"广元\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"巴中\", \"type\": \"bar\", \"value\": \"99.87%\"}, {\"name\": \"乐山\", \"type\": \"bar\", \"value\": \"99.86%\"}, {\"name\": \"泸州\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"雅安\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"广安\", \"type\": \"bar\", \"value\": \"99.85%\"}, {\"name\": \"资阳\", \"type\": \"bar\", \"value\": \"99.84%\"}, {\"name\": \"凉山\", \"type\": \"bar\", \"value\": \"99.65%\"}, {\"name\": \"阿坝\", \"type\": \"bar\", \"value\": \"99.34%\"}, {\"name\": \"甘孜\", \"type\": \"bar\", \"value\": \"98.81%\"}, {\"name\": \"岷江\", \"type\": \"bar\", \"value\": \"100.00%\"}]}<table/>'
|
|
|
+// },
|
|
|
+
|
|
|
]);
|
|
|
const chat_new_list = ref([])
|
|
|
const chat_log_list = ref([])
|
|
|
@@ -62,6 +228,266 @@ const chat_display_list = computed(() => {
|
|
|
return [...moke_data.value].concat(chat_log_list.value, chat_new_list.value);
|
|
|
});
|
|
|
|
|
|
+/**
|
|
|
+ * 新对话,客户端的提问数据
|
|
|
+ * 用以临时保存客户端的提问数据
|
|
|
+ * 每当用户确认进行提问时,将新提问赋给此值
|
|
|
+ * 一旦对话消息通过sse发送到服务器,此值可清空
|
|
|
+ */
|
|
|
+const chat_new_question = ref({});
|
|
|
+/**
|
|
|
+ * 对话区域滚动到底部
|
|
|
+ */
|
|
|
+const list_scroller = ref(null);
|
|
|
+const scroll2ListBottom = () => {
|
|
|
+ // if (!shouldAutoScroll.value) return;
|
|
|
+ nextTick(() => {
|
|
|
+ if (list_scroller.value) {
|
|
|
+ // list_scroller.value.scrollTop = list_scroller.value.scrollHeight;
|
|
|
+ list_scroller.value.scrollTo({
|
|
|
+ top: list_scroller.value.scrollHeight,
|
|
|
+ behavior: 'smooth' // 平滑滚动动画
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * input的一些操作方法
|
|
|
+ */
|
|
|
+const inputClearFn1 = useInputClear('dialog_input'); // 主表单清空
|
|
|
+
|
|
|
+// 初始化sse相关方法
|
|
|
+const { startZnwsStream, stopZnwsStream } = useFetchEventSourceZnws();
|
|
|
+
|
|
|
+/**
|
|
|
+ * 智能问数提交
|
|
|
+ * */
|
|
|
+const handleSubmit = async (options) => {
|
|
|
+ let ask_text = options.text; // 文本
|
|
|
+ let ask_files = options.files || [];
|
|
|
+ /**
|
|
|
+ * 当新消息发送时
|
|
|
+ * 意味着新一轮对话的开始
|
|
|
+ * 此时应该将之前一轮对话的信息进行清空
|
|
|
+ *
|
|
|
+ * 整理客户端提问的数据
|
|
|
+ * 组装Question数据
|
|
|
+ * */
|
|
|
+ const client_question = formatDialogQuestionByClient(ask_text, ask_files);
|
|
|
+ // 保存用户的提问信息
|
|
|
+ // 当消息正式发出后,将提问数据放入列表中
|
|
|
+ chat_new_question.value = client_question;
|
|
|
+ // 消息即将发送,记录用户的提问数据
|
|
|
+ chat_new_list.value.push(chat_new_question.value);
|
|
|
+ // 客户端答案数据(loading状态),客户端模拟的答案数据,依据此数据展示加载中的动画
|
|
|
+ // if (chat_type.value !== 'bgcl') {
|
|
|
+ const answerLoadingMsg = formatDialogAnswerForLoading();
|
|
|
+ chat_new_list.value.push(answerLoadingMsg);
|
|
|
+ // 清空文本数据和文件数据,避免下一次会话冲突
|
|
|
+ inputClearFn1();
|
|
|
+ // 清空已保存的提问数据(提问数据已经推入数组,此处无需继续保存)
|
|
|
+ chat_new_question.value = null;
|
|
|
+ // 文件上传、文本输入区域禁用
|
|
|
+ // input_disabled.value = true;
|
|
|
+ input_ing.value = true;
|
|
|
+ // 对话区域滚动到底部
|
|
|
+ scroll2ListBottom();
|
|
|
+ if (chat_type.value == 'znws') {
|
|
|
+ if (!WS_session.value.conversation_id) {
|
|
|
+ try {
|
|
|
+ const chatResult = await getDialogSessionId_AL({
|
|
|
+ app_id: window.APP_ID_AL_WS,
|
|
|
+ app_version: window.APP_VERSION_AL_WS
|
|
|
+ });
|
|
|
+ if (chatResult.code / 1 === 200) {
|
|
|
+ WS_session.value.conversation_id = chatResult.data.data.uniqueCode;
|
|
|
+ // session_id.value = chatResult.data.request_id;
|
|
|
+ } else {
|
|
|
+ // 失败
|
|
|
+ // 处理异常:直接在界面上显示
|
|
|
+ handleChatRequestionException({
|
|
|
+ message: `code: ${chatResult.errorCode} message: ${chatResult.errorMsg}`
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // 处理错误
|
|
|
+ handleChatRequestionException({
|
|
|
+ message: e.message
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ agentUsedStore.updateAgentUsed('znws');
|
|
|
+ const username = await getUserName();
|
|
|
+ const power_id = await getUserId();
|
|
|
+ const query_params = {
|
|
|
+ conversation_id: WS_session.value.conversation_id,
|
|
|
+ user_id: convertToLowerCase(username),
|
|
|
+ query: ask_text,
|
|
|
+ app_id: window.APP_ID_AL_WS,
|
|
|
+ power_id
|
|
|
+ };
|
|
|
+ startZnwsStream(query_params, sseOnMessageZnws);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
+let markdown_chart = null;
|
|
|
+//智能问数sse返回内容
|
|
|
+const sseOnMessageZnws = (event) => {
|
|
|
+ const res_data = JSON.parse(event.data);
|
|
|
+ // let markdown_chart = null;
|
|
|
+ if (res_data.metadata && res_data.metadata.markdown_chart) {
|
|
|
+ console.log(res_data.metadata.markdown_chart);
|
|
|
+ markdown_chart = JSON.parse(JSON.stringify(res_data.metadata.markdown_chart));
|
|
|
+ markdown_chart.origin_chart = `</table>${JSON.stringify(res_data.metadata.markdown_chart)}<table/>`
|
|
|
+ }
|
|
|
+ if (res_data.end) {
|
|
|
+ stopResponse();
|
|
|
+ }
|
|
|
+ if (res_data.object && res_data.object === 'error') {
|
|
|
+ handleChatRequestionException({
|
|
|
+ message: `code: ${res_data.content.errorCode} message: ${res_data.content.errorMsg}`
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if(!res_data) {
|
|
|
+ handleChatRequestionException({
|
|
|
+ message: `message: 接口内容返回失败,请稍后重试`
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // TODO: 将返回数据填充到页面
|
|
|
+
|
|
|
+ // 获取当前对话中最后一个对话数据
|
|
|
+ // 最后一个对话数据为当前正在进行的对话
|
|
|
+ const last_msg = chat_new_list.value[chat_new_list.value.length - 1];
|
|
|
+ /**
|
|
|
+ * 整理返回的数据
|
|
|
+ *
|
|
|
+ */
|
|
|
+ const currentChat = formatDialogAnswerFromSseReceiveMessageZnws(
|
|
|
+ res_data?.content,
|
|
|
+ last_msg,
|
|
|
+ res_data.end,
|
|
|
+ markdown_chart
|
|
|
+ );
|
|
|
+ const chat_status = currentChat.status;
|
|
|
+
|
|
|
+ // 处理对话数据
|
|
|
+ const handleChatData = () => {
|
|
|
+ const chat_data = currentChat.data; // 对话相关的数据项
|
|
|
+ // TODO: 为演示使用,判断是报告生成,新增两个字段一个是否有图标,另一个是文档数据
|
|
|
+ // 原来的最后一项弹出
|
|
|
+ chat_new_list.value.pop();
|
|
|
+ // 添加新的最后一项
|
|
|
+ chat_new_list.value.push(chat_data);
|
|
|
+
|
|
|
+ // 滚动到底部
|
|
|
+ scroll2ListBottom();
|
|
|
+ };
|
|
|
+
|
|
|
+ if (chat_status === 0) {
|
|
|
+ // 未开始: 此状态不存在,无需处理
|
|
|
+ }
|
|
|
+
|
|
|
+ if (chat_status === 1) {
|
|
|
+ // 此轮对话仍然在进行中
|
|
|
+ handleChatData();
|
|
|
+ // show_stop_sse.value = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (chat_status === 2) {
|
|
|
+ // 此轮对话已结束
|
|
|
+ handleChatData();
|
|
|
+
|
|
|
+ // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
+ // input_disabled.value = false;
|
|
|
+ input_ing.value = false;
|
|
|
+ // show_stop_sse.value = false;
|
|
|
+ emit('updateHistory');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (chat_status === 3) {
|
|
|
+ // 此轮对话出错了
|
|
|
+ // TODO: 错误处理
|
|
|
+
|
|
|
+ // 此轮对话已结束
|
|
|
+ handleChatData();
|
|
|
+ // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
+ input_disabled.value = false;
|
|
|
+ input_ing.value = false;
|
|
|
+ // show_stop_sse.value = false;
|
|
|
+ emit('updateHistory');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理错误显示
|
|
|
+ if (
|
|
|
+ res_data.result === 'error' ||
|
|
|
+ res_data.result?.content === 'error' ||
|
|
|
+ res_data.result?.content?.outputs === 'error'
|
|
|
+ ) {
|
|
|
+ //sse错误,显示错误信息
|
|
|
+ handleChatRequestionException({
|
|
|
+ message: res_data.error
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 停止
|
|
|
+ * */
|
|
|
+const stopResponse = () => {
|
|
|
+ stopZnwsStream();
|
|
|
+ input_ing.value = false;
|
|
|
+ const lastItem = chat_new_list.value.pop();
|
|
|
+ if (lastItem) {
|
|
|
+ lastItem.client_custom_chat_status = 2;
|
|
|
+ chat_new_list.value.push(lastItem);
|
|
|
+ }
|
|
|
+ scroll2ListBottom();
|
|
|
+}
|
|
|
+const convertToLowerCase = (str) => {
|
|
|
+ return str.toLowerCase();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 异常处理
|
|
|
+ * 异常处理过程是一个会话模拟的过程)
|
|
|
+ * 先在界面上显示加载动画,然后紧接着显示错误提示
|
|
|
+ * 让用户感知到智能体有处理数据的过程
|
|
|
+ * 所以在异常处理阶段,有一些需要处理的关键点,比如欢迎界面的显示(如果在显示,则需要隐藏,否则对话显示不了)
|
|
|
+ * @param exceptionInfo
|
|
|
+ */
|
|
|
+const handleChatRequestionException = (exceptionInfo) => {
|
|
|
+ // 已结束
|
|
|
+ const answerData = formatDialogAnswerForException(exceptionInfo);
|
|
|
+
|
|
|
+ // 原来的最后一项弹出
|
|
|
+ chat_new_list.value.pop();
|
|
|
+ // 添加新的最后一项
|
|
|
+ chat_new_list.value.push(answerData);
|
|
|
+
|
|
|
+ // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
+ input_ing.value = false;
|
|
|
+ // 对话区域滚动到底部
|
|
|
+ scroll2ListBottom();
|
|
|
+};
|
|
|
+
|
|
|
+const insert = (data) => {
|
|
|
+ emit('insertEchart', data);
|
|
|
+};
|
|
|
+//获取头像
|
|
|
+const getAgentIconsFun = async () => {
|
|
|
+ const username = await getUserName();
|
|
|
+ // target_agent_icon.value = '';
|
|
|
+ const res = await getAgentIcons({ username });
|
|
|
+ target_icon.value = res.data.user_icon['03']?.user_icon || 'icon_1'
|
|
|
+ console.log(target_icon.value)
|
|
|
+};
|
|
|
+onMounted(()=>{
|
|
|
+ getAgentIconsFun()
|
|
|
+})
|
|
|
|
|
|
</script>
|
|
|
<style scoped lang="css">
|