|
|
@@ -1,1674 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="conversation-container">
|
|
|
- <!-- <Header v-if="show_header"></Header> -->
|
|
|
- <div class="conversation-container-top" :style="StyleConversationTop">
|
|
|
- <DialogInfo :chat_list="chat_display_list" :type="chat_type" :target_agent_icon="target_agent_icon"></DialogInfo>
|
|
|
- </div>
|
|
|
- <div class="main-conversation-container" :style="main_conversation_container" ref="list_scroller">
|
|
|
- <div class="loading-more" v-if="is_loading_more">
|
|
|
- <a-spin></a-spin>
|
|
|
- <!-- <span>加载中...</span> -->
|
|
|
- </div>
|
|
|
- <div class="main-container-1" v-if="!chat_display_list.length && !history_detail_loading">
|
|
|
- <ConversationChatHome @send="toSend" :type="chat_type" :target_agent_icon="target_agent_icon">
|
|
|
- </ConversationChatHome>
|
|
|
- </div>
|
|
|
- <div class="main-container-2" v-else>
|
|
|
- <chatList :chat_list="chat_display_list" :type="chat_type" :target_agent_icon="target_agent_icon"
|
|
|
- @update="handleUpdate" @merge="toMerge"></chatList>
|
|
|
- </div>
|
|
|
- <div class="loading" v-if="history_detail_loading">
|
|
|
- <a-skeleton :animation="true">
|
|
|
- <a-skeleton-line :rows="10" :line-height="30" />
|
|
|
- </a-skeleton>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="main-footer" :style="StyleMainFooter">
|
|
|
- <DialogInput ref="dialog_input" :chat_type="chat_type" @submit="handleSubmit" @stop="stopResponse"
|
|
|
- :is_input_ing="input_ing" @changeFooterStyle="changeFooterStyle" :is_merge_table="is_merge_table">
|
|
|
- </DialogInput>
|
|
|
- <DialogFooter></DialogFooter>
|
|
|
- </div>
|
|
|
- <img class="bg-aside" src="../../assets/bg/bg-aside.svg" alt="" />
|
|
|
- <img class="bg-left-footer" src="../../assets/bg/bg-left-footer.svg" alt="" />
|
|
|
- <img class="bg-right-footer" src="../../assets/bg/bg-right-footer.svg" alt="" />
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { ref, computed, watch, nextTick, onMounted, onUnmounted, inject, watchEffect } from 'vue';
|
|
|
-
|
|
|
-import DialogInfo from '../../modules/conversation-chat/DialogInfo.vue';
|
|
|
-import ConversationChatHome from './ConversationChatHome.vue';
|
|
|
-import DialogInput from '../../modules/conversation-chat/DialogInput.vue';
|
|
|
-import DialogFooter from '../../modules/conversation-chat/DialogFooter.vue';
|
|
|
-import chatList from '../../modules/conversation-chat/chatList.vue';
|
|
|
-import Header from '../common/Header.vue';
|
|
|
-
|
|
|
-import useFetchEventSource from '../../modules/conversation-dialog/use-sse-chat';
|
|
|
-import useFetchEventSourceReport from '../../modules/conversation-dialog/use-sse-report';
|
|
|
-import useFetchEventSourceZnws from '../../modules/conversation-dialog/use-sse-znws';
|
|
|
-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 useInputClear from './use-input-clear';
|
|
|
-import formatDialogAnswerFromSseReceiveMessage from '../../modules/conversation-dialog/format-dialog-answer-from-Sse_receive_message';
|
|
|
-import formatDialogAnswerFromSseReceiveMessageReport from '../../modules/conversation-dialog/format-dialog-answer-from-sse_receive_message_report';
|
|
|
-import formatDialogAnswerFromSseReceiveMessageZnws from '../../modules/conversation-dialog/format-dialog-answer-from-sse_receive_message_znws';
|
|
|
-
|
|
|
-import { isElectron } from '../../utils/env';
|
|
|
-import { getUserName } from '../../utils/get-user-name';
|
|
|
-import { funcThrottle } from '../../utils/utils';
|
|
|
-import { getFileSize } from '../../utils/file-utils';
|
|
|
-import generateClientUniqueId from '../../utils/generate-client-unique-id';
|
|
|
-
|
|
|
-import {
|
|
|
- getDialogSessionId_BD,
|
|
|
- getDialogSessionId_AL,
|
|
|
- getAgentIcons,
|
|
|
- updateAgentIcons,
|
|
|
- downloadReport
|
|
|
-} from '../../modules/conversation-dialog/api-dialog';
|
|
|
-
|
|
|
-import { mergeTableData, getCheckedErrorList } from '../../modules/table-dialog/api-dialog';
|
|
|
-import { getDialogHistoryDetail } from '../../modules/conversation-dialog/api-dialog';
|
|
|
-import formatDialogHistoryMessages from '../../modules/conversation-dialog/format-dialog-history';
|
|
|
-import { useRoute, useRouter } from 'vue-router';
|
|
|
-
|
|
|
-import { Message } from '@arco-design/web-vue';
|
|
|
-
|
|
|
-const route = useRoute();
|
|
|
-const router = useRouter();
|
|
|
-
|
|
|
-const props = defineProps({
|
|
|
- chatType: String,
|
|
|
- mainStyle: Object
|
|
|
-});
|
|
|
-
|
|
|
-const emit = defineEmits(['updateHistory']);
|
|
|
-
|
|
|
-const chat_type = ref('znwd');
|
|
|
-
|
|
|
-const is_change_footer_height = ref(false);
|
|
|
-const is_merge_table = ref(false); //是否正在合并表格
|
|
|
-// const show_dialog_input = ref(true) //底部输入框组件显示隐藏,当新对话是重置该状态刷新该组件
|
|
|
-
|
|
|
-/**
|
|
|
- * 报告生成存在缓存问题,浏览器一次性返回很多条数据
|
|
|
- * 这是浏览器遵循高效触发原则,减少js执行次数
|
|
|
- * postman遵循一消息一事件,所以有区别
|
|
|
- *
|
|
|
- * */
|
|
|
-const report_message_queue = []
|
|
|
-let isProcessingQueue = false
|
|
|
-const PROCESS_INTERVAL = 300
|
|
|
-
|
|
|
-
|
|
|
-// 聊天对话列表
|
|
|
-const moke_data = ref([
|
|
|
- // {
|
|
|
- // report_excels: {
|
|
|
- // file_name: '附件:国网四川省电力公司配网运营分析周报.xlsx',
|
|
|
- // file_type: 'xlsx',
|
|
|
- // file_size: '12.2KB',
|
|
|
- // record_id: '12345'
|
|
|
- // },
|
|
|
- // report_files: {
|
|
|
- // file_name: '附件:国网四川省电力公司配网运营分析周报.docx',
|
|
|
- // file_type: 'docx',
|
|
|
- // file_size: '12.2KB',
|
|
|
- // record_id: '12345'
|
|
|
- // },
|
|
|
- // client_custom_item_type: 'a',
|
|
|
- // client_custom_chat_status: 2
|
|
|
- // }
|
|
|
- // {
|
|
|
- // client_custom_item_type: 'a',
|
|
|
- // client_custom_attach_list: [
|
|
|
- // {
|
|
|
- // "title": "附件1:1-5月供电可靠性数据明细表",
|
|
|
- // "columns": [
|
|
|
- // {
|
|
|
- // "title": "单位",
|
|
|
- // "dataIndex": "name"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "用户平均停电时间",
|
|
|
- // "dataIndex": "salary"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "供电可靠率",
|
|
|
- // "dataIndex": "address"
|
|
|
- // }
|
|
|
- // ],
|
|
|
- // "data": [
|
|
|
- // {
|
|
|
- // "key": "1",
|
|
|
- // "name": "成都市",
|
|
|
- // "salary": "0.93",
|
|
|
- // "address": "99.97%"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "2",
|
|
|
- // "name": "巴中市",
|
|
|
- // "salary": "1.06",
|
|
|
- // "address": "99.97%"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "3",
|
|
|
- // "name": "乐山市",
|
|
|
- // "salary": "1.07",
|
|
|
- // "address": "99.97%"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "4",
|
|
|
- // "name": "眉山市",
|
|
|
- // "salary": "1.00",
|
|
|
- // "address": "99.97%"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "5",
|
|
|
- // "name": "合计",
|
|
|
- // "salary": "1.04",
|
|
|
- // "address": "99.97%"
|
|
|
- // }
|
|
|
- // ]
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "附件2:5月全省停电时户数预算式管控明细表",
|
|
|
- // "columns": [
|
|
|
- // {
|
|
|
- // "title": "单位",
|
|
|
- // "dataIndex": "name"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "5月停电总消耗",
|
|
|
- // "dataIndex": "total_flow"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "截至5月停电总消耗",
|
|
|
- // "dataIndex": "to_total_flow"
|
|
|
- // }
|
|
|
- // ],
|
|
|
- // "data": [
|
|
|
- // {
|
|
|
- // "key": "1",
|
|
|
- // "name": "巴中市",
|
|
|
- // "total_flow": "490.00",
|
|
|
- // "to_total_flow": "970.00"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "2",
|
|
|
- // "name": "乐山市",
|
|
|
- // "total_flow": "460.00",
|
|
|
- // "to_total_flow": "940.00"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "3",
|
|
|
- // "name": "成都市",
|
|
|
- // "total_flow": "150.00",
|
|
|
- // "to_total_flow": "270.00"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "4",
|
|
|
- // "name": "眉山市",
|
|
|
- // "total_flow": "120.00",
|
|
|
- // "to_total_flow": "240.00"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "5",
|
|
|
- // "name": "合计",
|
|
|
- // "total_flow": "1220.00",
|
|
|
- // "to_total_flow": "2420.00"
|
|
|
- // }
|
|
|
- // ]
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "附件3:5月配变轻重载情况表",
|
|
|
- // "columns": [
|
|
|
- // {
|
|
|
- // "title": "单位",
|
|
|
- // "dataIndex": "name"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "5月重过载配变数量",
|
|
|
- // "dataIndex": "zgz_num"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "截止5月轻载数量",
|
|
|
- // "dataIndex": "qz_num"
|
|
|
- // }
|
|
|
- // ],
|
|
|
- // "data": [
|
|
|
- // {
|
|
|
- // "key": "1",
|
|
|
- // "name": "乐山市",
|
|
|
- // "zgz_num": 10,
|
|
|
- // "qz_num": 10
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "2",
|
|
|
- // "name": "巴中市",
|
|
|
- // "zgz_num": 8,
|
|
|
- // "qz_num": 8
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "3",
|
|
|
- // "name": "成都市",
|
|
|
- // "zgz_num": 4,
|
|
|
- // "qz_num": 4
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "4",
|
|
|
- // "name": "合计",
|
|
|
- // "zgz_num": 22,
|
|
|
- // "qz_num": 22
|
|
|
- // }
|
|
|
- // ]
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "附件12:5月跳闸情况表",
|
|
|
- // "columns": [
|
|
|
- // {
|
|
|
- // "title": "所属地市",
|
|
|
- // "dataIndex": "city"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "线路跳闸次数",
|
|
|
- // "dataIndex": "times"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "重合闸成功次数",
|
|
|
- // "dataIndex": "chzcg_times"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "重合闸失败次数",
|
|
|
- // "dataIndex": "chzsb_times"
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "title": "未重合闸次数",
|
|
|
- // "dataIndex": "none_times"
|
|
|
- // }
|
|
|
- // ],
|
|
|
- // "data": [
|
|
|
- // {
|
|
|
- // "key": "1",
|
|
|
- // "city": "天府",
|
|
|
- // "times": 3,
|
|
|
- // "chzcg_times": 1,
|
|
|
- // "chzsb_times": 1,
|
|
|
- // "none_times": 0
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "2",
|
|
|
- // "city": "成都",
|
|
|
- // "times": 3,
|
|
|
- // "chzcg_times": 1,
|
|
|
- // "chzsb_times": 1,
|
|
|
- // "none_times": 0
|
|
|
- // },
|
|
|
- // {
|
|
|
- // "key": "3",
|
|
|
- // "city": "合计",
|
|
|
- // "times": "6",
|
|
|
- // "chzcg_times": "2",
|
|
|
- // "chzsb_times": "2",
|
|
|
- // "none_times": "2"
|
|
|
- // }
|
|
|
- // ]
|
|
|
- // }
|
|
|
- // ]
|
|
|
- // }
|
|
|
-]);
|
|
|
-// 历史记录参数
|
|
|
-const history_item_params = ref({
|
|
|
- conversation_id: '',
|
|
|
- page_index: 1,
|
|
|
- page_size: 10,
|
|
|
- total: 0
|
|
|
-});
|
|
|
-// 正在加载初次数据
|
|
|
-const history_detail_loading = ref(false);
|
|
|
-
|
|
|
-// 是否加载更多,滑动到顶部
|
|
|
-const is_loading_more = ref(false);
|
|
|
-/**
|
|
|
- * 是否禁用输入组件
|
|
|
- */
|
|
|
-const input_disabled = ref(false);
|
|
|
-// 是否正在对话
|
|
|
-const input_ing = ref(false);
|
|
|
-
|
|
|
-const chat_log_list = ref([]); // 历史对话的数据列表
|
|
|
-const chat_new_list = ref([]); // 新对话的数据列表
|
|
|
-/**
|
|
|
- * 新对话,客户端的提问数据
|
|
|
- * 用以临时保存客户端的提问数据
|
|
|
- * 每当用户确认进行提问时,将新提问赋给此值
|
|
|
- * 一旦对话消息通过sse发送到服务器,此值可清空
|
|
|
- */
|
|
|
-const chat_new_question = ref({});
|
|
|
-
|
|
|
-// 会话id和message id 千帆智能体
|
|
|
-const BD_session = ref({
|
|
|
- conversation_id: '',
|
|
|
- message_id: ''
|
|
|
-});
|
|
|
-// 会话id阿里智能体(报告)
|
|
|
-const AL_session = ref({
|
|
|
- conversation_id: '',
|
|
|
- record_id: ''
|
|
|
-});
|
|
|
-// 会话id阿里智能体(问数)
|
|
|
-const WS_session = ref({
|
|
|
- conversation_id: '',
|
|
|
- record_id: ''
|
|
|
-});
|
|
|
-// const conversation_id = ref('');
|
|
|
-// const message_id = ref('');
|
|
|
-
|
|
|
-/**
|
|
|
- * 界面展示的对话列表
|
|
|
- * 当用户从历史会话进入时,历史会话记录有数据,当用户基于历史会话进行对话时,新会话也有数据,
|
|
|
- * 当用户从agent进入时,仅有新会话,没有历史会话
|
|
|
- *
|
|
|
- * 页面渲染的会话列表是 历史会话 + 新会话数据
|
|
|
- */
|
|
|
-const chat_display_list = computed(() => {
|
|
|
- return [...moke_data.value].concat(chat_log_list.value, chat_new_list.value);
|
|
|
-});
|
|
|
-
|
|
|
-const StyleConversationTop = computed(() => {
|
|
|
- const is_electron = isElectron();
|
|
|
- if (!is_electron) {
|
|
|
- return {
|
|
|
- width: 'calc(100%)'
|
|
|
- };
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-const main_conversation_container = computed(() => {
|
|
|
- const is_electron = isElectron();
|
|
|
- if (is_electron) {
|
|
|
- return {
|
|
|
- height: 'calc(100% - 160px - 100px - 25px - 20px)'
|
|
|
- };
|
|
|
- } else {
|
|
|
- if (is_change_footer_height.value) {
|
|
|
- if (chat_type.value === 'bgcl') {
|
|
|
- return {
|
|
|
- height: 'calc(100% - 160px - 94px - 100px - 25px - 15px + 66px)'
|
|
|
- };
|
|
|
- } else {
|
|
|
- return {
|
|
|
- height: 'calc(100% - 160px - 94px - 100px - 25px - 15px)'
|
|
|
- };
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (chat_type.value === 'bgcl') {
|
|
|
- return {
|
|
|
- height: 'calc(100% - 160px - 100px - 25px - 15px + 66px)'
|
|
|
- };
|
|
|
- } else {
|
|
|
- return {
|
|
|
- height: 'calc(100% - 160px - 100px - 25px - 15px)'
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-const StyleMainFooter = computed(() => {
|
|
|
- if (is_change_footer_height.value) {
|
|
|
- if (chat_type.value === 'bgcl') {
|
|
|
- return {
|
|
|
- height: 'calc(160px + 94px - 66px)'
|
|
|
- };
|
|
|
- } else {
|
|
|
- return {
|
|
|
- height: 'calc(160px + 94px)'
|
|
|
- };
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (chat_type.value === 'bgcl') {
|
|
|
- return {
|
|
|
- height: 'calc(160px - 66px)'
|
|
|
- };
|
|
|
- } else {
|
|
|
- return {
|
|
|
- height: '160px'
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-/**
|
|
|
- * input的一些操作方法
|
|
|
- */
|
|
|
-const inputClearFn1 = useInputClear('dialog_input'); // 主表单清空
|
|
|
-
|
|
|
-/**
|
|
|
- * 对话区域滚动到底部
|
|
|
- */
|
|
|
-const list_scroller = ref(null);
|
|
|
-const scroll2ListBottom = () => {
|
|
|
- nextTick(() => {
|
|
|
- if (list_scroller.value) {
|
|
|
- list_scroller.value.scrollTop = list_scroller.value.scrollHeight;
|
|
|
- }
|
|
|
- });
|
|
|
-};
|
|
|
-// 展示停止问答按钮
|
|
|
-const show_stop_sse = ref(false);
|
|
|
-
|
|
|
-// 初始化sse相关方法
|
|
|
-const { startStream, stopStream } = useFetchEventSource();
|
|
|
-const { startReportStream, stopReportStream } = useFetchEventSourceReport();
|
|
|
-const { startZnwsStream, stopZnwsStream } = useFetchEventSourceZnws();
|
|
|
-
|
|
|
-const toSend = (txt) => {
|
|
|
- const options = {
|
|
|
- text: txt,
|
|
|
- files: []
|
|
|
- };
|
|
|
- handleSubmit(options);
|
|
|
-};
|
|
|
-const convertToLowerCase = (str) => {
|
|
|
- return str.toLowerCase();
|
|
|
-};
|
|
|
-// 发送对话
|
|
|
-const handleSubmit = async (options) => {
|
|
|
- console.log(isElectron(), '环境');
|
|
|
- let ask_text = options.text; // 文本
|
|
|
- let ask_files = options.files || [];
|
|
|
- let event_id = options.event_id; //表格处理专用
|
|
|
-
|
|
|
- /**
|
|
|
- * 当新消息发送时
|
|
|
- * 意味着新一轮对话的开始
|
|
|
- * 此时应该将之前一轮对话的信息进行清空
|
|
|
- *
|
|
|
- * 整理客户端提问的数据
|
|
|
- * 组装Question数据
|
|
|
- * */
|
|
|
- const client_question = formatDialogQuestionByClient(ask_text, ask_files, event_id);
|
|
|
- // 保存用户的提问信息
|
|
|
- // 当消息正式发出后,将提问数据放入列表中
|
|
|
- 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 == 'znwd') {
|
|
|
- // TODO:判断是否有session_id,没有就去创建session_id
|
|
|
- if (!BD_session.value.conversation_id) {
|
|
|
- try {
|
|
|
- const chatResult = await getDialogSessionId_BD(window.APP_ID);
|
|
|
- if (chatResult.code / 1 === 200) {
|
|
|
- BD_session.value = chatResult.data;
|
|
|
- // session_id.value = chatResult.data.request_id;
|
|
|
- } else {
|
|
|
- // 失败
|
|
|
- // 处理异常:直接在界面上显示
|
|
|
- handleChatRequestionException({
|
|
|
- message: `code: ${chatResult.code} message: ${chatResult.data}`
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- // 处理错误
|
|
|
- handleChatRequestionException({
|
|
|
- message: e.message
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // TODO:若后续有文件上传,这里需要处理上传文件的内容
|
|
|
- // TODO: sse接口所需参数需要这在里全部获取到
|
|
|
-
|
|
|
- // 组装sse参数,调用sse接口
|
|
|
- // const query_params = {
|
|
|
- // session_id: session_id.value,
|
|
|
- // stream:true,
|
|
|
- // delta:true,
|
|
|
- // trace:false,
|
|
|
- // message:{
|
|
|
- // text:ask_text,
|
|
|
- // metadata:{},
|
|
|
- // attachments:[]
|
|
|
- // }
|
|
|
- // };
|
|
|
- const username = await getUserName();
|
|
|
- // if (chat_type.value == 'znwd') {
|
|
|
- const query_params = {
|
|
|
- app_id: window.APP_ID,
|
|
|
- conversation_id: BD_session.value.conversation_id,
|
|
|
- query: ask_text,
|
|
|
- stream: true,
|
|
|
- file_ids: [],
|
|
|
- user_id: convertToLowerCase(username)
|
|
|
- };
|
|
|
- startStream(query_params, sseOnMessage);
|
|
|
- // }
|
|
|
- }
|
|
|
- if (chat_type.value == 'bgsc') {
|
|
|
- if (!AL_session.value.conversation_id) {
|
|
|
- try {
|
|
|
- const chatResult = await getDialogSessionId_AL({
|
|
|
- app_id: window.APP_ID_AL,
|
|
|
- app_version: window.APP_VERSION_AL
|
|
|
- });
|
|
|
- if (chatResult.code / 1 === 200) {
|
|
|
- AL_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;
|
|
|
- }
|
|
|
- }
|
|
|
- const username = await getUserName();
|
|
|
- // const query_params = {
|
|
|
- // stream: true,
|
|
|
- // conversation_id: AL_session.value.conversation_id,
|
|
|
- // start_date: rangeValue.value[0],
|
|
|
- // end_date: rangeValue.value[1],
|
|
|
- // user_id: convertToLowerCase(username),
|
|
|
- // query: ask_text
|
|
|
- // }
|
|
|
- const query_params = {
|
|
|
- conversation_id: AL_session.value.conversation_id,
|
|
|
- user_id: convertToLowerCase(username),
|
|
|
- query: ask_text,
|
|
|
- app_id: window.APP_ID_AL
|
|
|
- };
|
|
|
- startReportStream(query_params, sseOnMessageReport);
|
|
|
- return;
|
|
|
- }
|
|
|
- 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;
|
|
|
- }
|
|
|
- }
|
|
|
- const username = await getUserName();
|
|
|
- const query_params = {
|
|
|
- conversation_id: WS_session.value.conversation_id,
|
|
|
- user_id: convertToLowerCase(username),
|
|
|
- query: ask_text,
|
|
|
- app_id: window.APP_ID_AL_WS
|
|
|
- };
|
|
|
- startZnwsStream(query_params, sseOnMessageZnws);
|
|
|
- return;
|
|
|
- }
|
|
|
- /**
|
|
|
- * 表格处理情况特殊,需要自定义问题和展示文件列表
|
|
|
- * */
|
|
|
- if (chat_type.value == 'bgcl') {
|
|
|
- let fileLength = ask_files.length;
|
|
|
- bgclOnMessage(event_id, fileLength);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 处理sse返回内容的函数
|
|
|
- *
|
|
|
- * */
|
|
|
-const sseOnMessage = (event) => {
|
|
|
- const res_data = JSON.parse(event.data);
|
|
|
-
|
|
|
- if (res_data.result && res_data.result.is_completion) {
|
|
|
- stopResponse();
|
|
|
- }
|
|
|
- if (res_data.code && res_data.code === 'chatError') {
|
|
|
- handleChatRequestionException({
|
|
|
- message: `code: ${res_data.code} message: ${res_data.message}`
|
|
|
- });
|
|
|
- }
|
|
|
- // TODO: 将返回数据填充到页面
|
|
|
-
|
|
|
- // 获取当前对话中最后一个对话数据
|
|
|
- // 最后一个对话数据为当前正在进行的对话
|
|
|
- const last_msg = chat_new_list.value[chat_new_list.value.length - 1];
|
|
|
- /**
|
|
|
- * 整理返回的数据
|
|
|
- *
|
|
|
- */
|
|
|
- const currentChat = formatDialogAnswerFromSseReceiveMessage(res_data, last_msg);
|
|
|
- const chat_status = currentChat.status;
|
|
|
-
|
|
|
- // 处理对话数据
|
|
|
- const handleChatData = () => {
|
|
|
- const chat_data = currentChat.data; // 对话相关的数据项
|
|
|
- console.log(chat_data, 99);
|
|
|
- // 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');
|
|
|
- // console.log(11111111111111111)
|
|
|
- // let conversation_id = BD_session.value.conversation_id
|
|
|
- // console.log(conversation_id, chat_type.value, 999)
|
|
|
-
|
|
|
- // router.replace({
|
|
|
- // path: `/conversation/${conversation_id}`,
|
|
|
- // query: {
|
|
|
- // id: chat_type.value
|
|
|
- // }
|
|
|
- // }).then(() => {
|
|
|
- // console.log('执行了')
|
|
|
- // }).catch(err => {
|
|
|
- // console.log(err)
|
|
|
- // })
|
|
|
- }
|
|
|
-
|
|
|
- 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 processQueue = async () => {
|
|
|
- // 若队列为空,停止处理
|
|
|
- if (report_message_queue.length === 0) {
|
|
|
- isProcessingQueue = false
|
|
|
- return
|
|
|
- }
|
|
|
- isProcessingQueue = true
|
|
|
- // 从队头拿取一条数据
|
|
|
- const data = report_message_queue.shift()
|
|
|
-
|
|
|
- try {
|
|
|
- // 处理单条消息
|
|
|
- await processSingleMessage(data);
|
|
|
- } catch (e) {
|
|
|
- console.error('处理消息出错:', e);
|
|
|
- }
|
|
|
-
|
|
|
- // 定时处理下一条消息
|
|
|
- setTimeout(processQueue, PROCESS_INTERVAL);
|
|
|
-}
|
|
|
-const processSingleMessage = async () => {
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 解析返回数据中是否有图表数据,有则截取出来,没有则返回false
|
|
|
- * 服务于报告生成
|
|
|
- * */
|
|
|
-function processInputString(input) {
|
|
|
- // 定义用于匹配 <table/> 和 </table> 标签的正则表达式
|
|
|
- const tableStartRegex = /<\/table>/;
|
|
|
- const tableEndRegex = /<table\/>/;
|
|
|
-
|
|
|
- // 检查字符串中是否同时存在开始和结束标签
|
|
|
- const hasTableStart = tableStartRegex.test(input);
|
|
|
- const hasTableEnd = tableEndRegex.test(input);
|
|
|
-
|
|
|
- if (hasTableStart && hasTableEnd) {
|
|
|
- // 提取 </table> 和 <table/> 之间的内容
|
|
|
- const startIndex = input.indexOf('</table>') + '</table>'.length;
|
|
|
- const endIndex = input.indexOf('<table/>');
|
|
|
- if (startIndex < endIndex) {
|
|
|
- return '"' + input.substring(startIndex, endIndex).trim() + '"';
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//报告生成sse返回内容
|
|
|
-const sseOnMessageReport = async (event) => {
|
|
|
- let res_data;
|
|
|
- let is_end;
|
|
|
- let is_download;
|
|
|
- let res_attachments;
|
|
|
- try {
|
|
|
- const res_echart = processInputString(event.data);
|
|
|
- if (res_echart) {
|
|
|
- res_data = JSON.parse(JSON.parse(res_echart));
|
|
|
- console.log(res_data, 5555);
|
|
|
- } else {
|
|
|
- const res = JSON.parse(event.data);
|
|
|
- res_data = res.content.data;
|
|
|
- res_attachments = res.references || [];
|
|
|
- is_end = res.end;
|
|
|
- is_download = res.is_download;
|
|
|
- AL_session.value.record_id = res.id;
|
|
|
- // console.log(res_data)
|
|
|
- }
|
|
|
- // res_data = JSON.parse(event.data)
|
|
|
- // console.log(res_data)
|
|
|
- } catch (e) {
|
|
|
- console.log(e);
|
|
|
- }
|
|
|
-
|
|
|
- // console.log(res_data)
|
|
|
- const last_msg = chat_new_list.value[chat_new_list.value.length - 1];
|
|
|
- /**
|
|
|
- * 整理返回的数据
|
|
|
- *
|
|
|
- */
|
|
|
- const currentChat = formatDialogAnswerFromSseReceiveMessageReport(res_data, last_msg, res_attachments, is_end);
|
|
|
- console.log(currentChat, 212121);
|
|
|
- const chat_status = currentChat.status;
|
|
|
- // console.log(chat_status)
|
|
|
-
|
|
|
- // // 处理对话数据
|
|
|
- const handleChatData = () => {
|
|
|
- const chat_data = currentChat.data; // 对话相关的数据项
|
|
|
- // TODO: 为演示使用,判断是报告生成,新增两个字段一个是否有图标,另一个是文档数据
|
|
|
- if (chat_type.value === 'bgsc' && is_download) {
|
|
|
- const has_echarts = true;
|
|
|
- const report_files = {
|
|
|
- file_name: '国网四川省电力公司配网运营分析周报.docx',
|
|
|
- file_type: 'docx',
|
|
|
- file_size: '12.2KB',
|
|
|
- record_id: AL_session.value.record_id
|
|
|
- };
|
|
|
- const report_excels = {
|
|
|
- file_name: '附件:国网四川省电力公司配网运营分析周报.xlsx',
|
|
|
- file_type: 'xlsx',
|
|
|
- file_size: '12.2KB',
|
|
|
- record_id: AL_session.value.conversation_id
|
|
|
- };
|
|
|
- chat_data.has_echarts = has_echarts;
|
|
|
- chat_data.report_files = report_files;
|
|
|
- chat_data.report_excels = report_excels;
|
|
|
- }
|
|
|
-
|
|
|
- // 原来的最后一项弹出
|
|
|
- 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;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-//智能问数sse返回内容
|
|
|
-const sseOnMessageZnws = (event) => {
|
|
|
- const res_data = JSON.parse(event.data);
|
|
|
- console.log(res_data);
|
|
|
- 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}`
|
|
|
- });
|
|
|
- }
|
|
|
- // TODO: 将返回数据填充到页面
|
|
|
-
|
|
|
- // 获取当前对话中最后一个对话数据
|
|
|
- // 最后一个对话数据为当前正在进行的对话
|
|
|
- const last_msg = chat_new_list.value[chat_new_list.value.length - 1];
|
|
|
- console.log(last_msg, 555);
|
|
|
- /**
|
|
|
- * 整理返回的数据
|
|
|
- *
|
|
|
- */
|
|
|
- const currentChat = formatDialogAnswerFromSseReceiveMessageZnws(
|
|
|
- res_data?.content,
|
|
|
- last_msg,
|
|
|
- res_data.end,
|
|
|
- res_data.metadata
|
|
|
- );
|
|
|
- const chat_status = currentChat.status;
|
|
|
-
|
|
|
- // 处理对话数据
|
|
|
- const handleChatData = () => {
|
|
|
- const chat_data = currentChat.data; // 对话相关的数据项
|
|
|
- console.log(chat_data, 99);
|
|
|
- // 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');
|
|
|
- // console.log(11111111111111111)
|
|
|
- // let conversation_id = BD_session.value.conversation_id
|
|
|
- // console.log(conversation_id, chat_type.value, 999)
|
|
|
-
|
|
|
- // router.replace({
|
|
|
- // path: `/conversation/${conversation_id}`,
|
|
|
- // query: {
|
|
|
- // id: chat_type.value
|
|
|
- // }
|
|
|
- // }).then(() => {
|
|
|
- // console.log('执行了')
|
|
|
- // }).catch(err => {
|
|
|
- // console.log(err)
|
|
|
- // })
|
|
|
- }
|
|
|
-
|
|
|
- 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 bgclOnMessage = (event_id, length) => {
|
|
|
- let last_msg;
|
|
|
- let fileLength = 0;
|
|
|
- const idx_new = chat_new_list.value.findIndex((item) => item.is_analyze);
|
|
|
- // const idx_log = chat_log_list.value.findIndex(item => item.is_analyze)
|
|
|
- if (idx_new !== -1) {
|
|
|
- last_msg = chat_new_list.value.find((item) => item.is_analyze);
|
|
|
- chat_new_list.value.splice(idx_new, 1);
|
|
|
- chat_new_list.value.splice(chat_new_list.value.length - 1, 1);
|
|
|
- chat_new_list.value.push(last_msg);
|
|
|
- } else {
|
|
|
- last_msg = chat_new_list.value[chat_new_list.value.length - 1];
|
|
|
- }
|
|
|
-
|
|
|
- chat_new_list.value.forEach((item) => {
|
|
|
- if (item.client_custom_upload_file_list) {
|
|
|
- fileLength += item.client_custom_upload_file_list.length;
|
|
|
- }
|
|
|
- });
|
|
|
- chat_log_list.value.forEach((item) => {
|
|
|
- if (item.client_custom_upload_file_list) {
|
|
|
- fileLength += item.client_custom_upload_file_list.length;
|
|
|
- }
|
|
|
- });
|
|
|
- console.log(fileLength, 2222);
|
|
|
-
|
|
|
- last_msg.is_analyze = true; //解析完成
|
|
|
- last_msg.status = 1; //正在进行
|
|
|
- last_msg.event_id = event_id;
|
|
|
- last_msg.analyzeContent = window.bgcl_content;
|
|
|
- last_msg.fileLength = fileLength;
|
|
|
- last_msg.client_custom_item_type = 'a';
|
|
|
- last_msg.client_custom_config_rule_disabled = false;
|
|
|
- // chat_new_list.value.pop()
|
|
|
- // chat_new_list.value.push(last_msg)
|
|
|
- let chat_status = last_msg.status;
|
|
|
-
|
|
|
- // 处理对话数据
|
|
|
- const handleChatData = () => {
|
|
|
- const chat_data = last_msg; // 对话相关的数据项
|
|
|
- console.log(chat_data, 99);
|
|
|
- // 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;
|
|
|
- input_ing.value = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (chat_status === 2) {
|
|
|
- // 此轮对话已结束
|
|
|
- handleChatData();
|
|
|
-
|
|
|
- // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
- input_disabled.value = false;
|
|
|
- input_ing.value = false;
|
|
|
- show_stop_sse.value = false;
|
|
|
- // emit('updateHistory');
|
|
|
- }
|
|
|
- // 对话区域滚动到底部
|
|
|
- scroll2ListBottom();
|
|
|
-};
|
|
|
-// 停止响应
|
|
|
-const stopResponse = () => {
|
|
|
- if (chat_type.value == 'znwd') {
|
|
|
- stopStream();
|
|
|
- } else if (chat_type.value == 'bgsc') {
|
|
|
- stopReportStream();
|
|
|
- } else if (chat_type.value == 'znws') {
|
|
|
- stopZnwsStream();
|
|
|
- }
|
|
|
-
|
|
|
- show_stop_sse.value = false;
|
|
|
- input_disabled.value = false;
|
|
|
- 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);
|
|
|
- }
|
|
|
- emit('updateHistory');
|
|
|
-
|
|
|
- scroll2ListBottom();
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 异常处理
|
|
|
- * 异常处理过程是一个会话模拟的过程)
|
|
|
- * 先在界面上显示加载动画,然后紧接着显示错误提示
|
|
|
- * 让用户感知到智能体有处理数据的过程
|
|
|
- * 所以在异常处理阶段,有一些需要处理的关键点,比如欢迎界面的显示(如果在显示,则需要隐藏,否则对话显示不了)
|
|
|
- * @param exceptionInfo
|
|
|
- */
|
|
|
-const handleChatRequestionException = (exceptionInfo) => {
|
|
|
- // 已结束
|
|
|
- const answerData = formatDialogAnswerForException(exceptionInfo);
|
|
|
-
|
|
|
- // 原来的最后一项弹出
|
|
|
- chat_new_list.value.pop();
|
|
|
- // 添加新的最后一项
|
|
|
- chat_new_list.value.push(answerData);
|
|
|
-
|
|
|
- // 对话已结束:文件上传、文本输入区域放开使用
|
|
|
- input_disabled.value = false;
|
|
|
- input_ing.value = false;
|
|
|
- // 对话区域滚动到底部
|
|
|
- scroll2ListBottom();
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 根据输入框中是否上传文件而动态调整主页中输入框高度和主窗口高度
|
|
|
- * */
|
|
|
-const changeFooterStyle = (is_change) => {
|
|
|
- is_change_footer_height.value = is_change;
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 开启新会话
|
|
|
- * */
|
|
|
-const newChat = () => {
|
|
|
- toInitData();
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 初始化所有参数
|
|
|
- * */
|
|
|
-const toInitData = () => {
|
|
|
- stopResponse();
|
|
|
-
|
|
|
- chat_log_list.value = [];
|
|
|
- chat_new_list.value = [];
|
|
|
- history_item_params.value = {
|
|
|
- page_size: 10,
|
|
|
- page_index: 1,
|
|
|
- total: 0,
|
|
|
- conversation_id: ''
|
|
|
- };
|
|
|
- BD_session.value = {
|
|
|
- conversation_id: '',
|
|
|
- message_id: ''
|
|
|
- };
|
|
|
- AL_session.value = {
|
|
|
- conversation_id: '',
|
|
|
- record_id: ''
|
|
|
- };
|
|
|
- WS_session.value = {
|
|
|
- conversation_id: '',
|
|
|
- record_id: ''
|
|
|
- };
|
|
|
- // 清空用户输入框
|
|
|
- inputClearFn1();
|
|
|
- // 清空用户提问数据
|
|
|
- chat_new_question.value = null;
|
|
|
- history_detail_loading.value = false;
|
|
|
-};
|
|
|
-
|
|
|
-const getDialogHistoryDetailFun = async () => {
|
|
|
- // 记录加载前的滚动位置和内容高度
|
|
|
- const scrollTopBeforeLoading = list_scroller.value ? list_scroller.value.scrollTop : 0;
|
|
|
- const scrollHeightBeforeLoading = list_scroller.value ? list_scroller.value.scrollHeight : 0;
|
|
|
-
|
|
|
- if (history_item_params.value.page_index === 1) {
|
|
|
- history_detail_loading.value = true;
|
|
|
- chat_log_list.value = [];
|
|
|
- } else {
|
|
|
- is_loading_more.value = true;
|
|
|
- }
|
|
|
- const res = await getDialogHistoryDetail(history_item_params.value);
|
|
|
- if (res.code / 1 === 200) {
|
|
|
- let detail_list;
|
|
|
- if (chat_type.value == 'znwd') {
|
|
|
- detail_list = formatDialogHistoryMessages(res.data.rows, '1');
|
|
|
- } else if (chat_type.value == 'bgsc') {
|
|
|
- // console.log(res.data.rows)
|
|
|
- detail_list = formatDialogHistoryMessages(res.data.rows, '2');
|
|
|
- } else if (chat_type.value == 'znws') {
|
|
|
- detail_list = formatDialogHistoryMessages(res.data.rows, '3');
|
|
|
- } else if (chat_type.value == 'bgcl') {
|
|
|
- detail_list = formatDialogHistoryMessages(res.data.rows, '4');
|
|
|
- console.log(detail_list, chat_log_list.value, 8888);
|
|
|
- history_item_params.value.total = res.data.total;
|
|
|
- detail_list?.forEach((item) => {
|
|
|
- console.log(item, 123123);
|
|
|
- if (item.is_analyze) {
|
|
|
- chat_new_list.value.push(item);
|
|
|
- // 保证chat_log_list数量和total能对应上
|
|
|
- const norgin_item = {
|
|
|
- ...item,
|
|
|
- client_custom_item_type: 'ignore'
|
|
|
- };
|
|
|
- chat_log_list.value.unshift(norgin_item);
|
|
|
- } else {
|
|
|
- chat_log_list.value.unshift(item);
|
|
|
- }
|
|
|
- });
|
|
|
- console.log(detail_list, 55555);
|
|
|
- // 当请求历史记录第一页时,若最后一条数据是对应的来源是user且request_id为merge则设置最后一条数据为合并中状态
|
|
|
- if (
|
|
|
- history_item_params.value.page_index / 1 === 1 &&
|
|
|
- detail_list &&
|
|
|
- detail_list.length &&
|
|
|
- detail_list[0].request_id == 'merge'
|
|
|
- ) {
|
|
|
- let fileLength = 0;
|
|
|
- detail_list.forEach((item) => {
|
|
|
- if (item.client_custom_upload_file_list && item.client_custom_upload_file_list.length) {
|
|
|
- fileLength += item.client_custom_upload_file_list.length;
|
|
|
- }
|
|
|
- });
|
|
|
- let mergeContent = `本次共处理${fileLength}个Excel文件,数据已合并为统一表并导出为 merged_result.xlsx,合并过程中系统自动完成异常值扫描,以下为检测到的异常值情况:`;
|
|
|
- const merge_item = {
|
|
|
- mergeContent,
|
|
|
- client_custom_unique_id: generateClientUniqueId(mergeContent + Date.now()),
|
|
|
- status: 1,
|
|
|
- is_merge: true, //控制区分解析和合并消息
|
|
|
- client_custom_item_type: 'a',
|
|
|
- event_id: detail_list[0].conversation_id,
|
|
|
- fileLength: fileLength
|
|
|
- };
|
|
|
- chat_new_list.value.push(merge_item);
|
|
|
- chat_new_list.value.forEach((item) => {
|
|
|
- if (item.is_analyze) {
|
|
|
- item.client_custom_config_rule_disabled = true;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- if (chat_type.value !== 'bgcl') {
|
|
|
- chat_log_list.value.push(...detail_list.reverse());
|
|
|
- }
|
|
|
-
|
|
|
- history_detail_loading.value = false;
|
|
|
- // 获取异常表格数据
|
|
|
- const filterItems = chat_log_list.value.filter((item) => item.origin === 'history');
|
|
|
- // console.log(filterItems, 5555);
|
|
|
- for (const item of filterItems) {
|
|
|
- item.client_loading_warning_table = true;
|
|
|
- const res = await getCheckedErrorListFun({
|
|
|
- event_id: item.event_id,
|
|
|
- filename: item.waring_filename,
|
|
|
- page_size: 10,
|
|
|
- page_index: 1
|
|
|
- });
|
|
|
- if (res.code === 200) {
|
|
|
- item.client_custom_bgcl_table_data = res.data.rows;
|
|
|
- item.client_custom_bgcl_table_total = res.data.total;
|
|
|
- }
|
|
|
- item.client_loading_warning_table = false;
|
|
|
- }
|
|
|
- console.log(detail_list, 555);
|
|
|
- }
|
|
|
-
|
|
|
- // 计算内容高度变化量
|
|
|
- await nextTick(() => {
|
|
|
- if (list_scroller.value) {
|
|
|
- const newScrollHeight = list_scroller.value.scrollHeight;
|
|
|
- const heightDiff = newScrollHeight - scrollHeightBeforeLoading;
|
|
|
-
|
|
|
- // 恢复滚动位置,保持可视区域不变
|
|
|
- list_scroller.value.scrollTop = scrollTopBeforeLoading + heightDiff;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (history_item_params.value.page_index === 1) {
|
|
|
- scroll2ListBottom();
|
|
|
- }
|
|
|
-
|
|
|
- history_detail_loading.value = false;
|
|
|
- is_loading_more.value = false;
|
|
|
-};
|
|
|
-
|
|
|
-const toQueryHistoryDetail = () => {
|
|
|
- if (history_item_params.value.total > chat_log_list.value.length) {
|
|
|
- history_item_params.value.page_index += 1;
|
|
|
- getDialogHistoryDetailFun();
|
|
|
- }
|
|
|
-};
|
|
|
-/**
|
|
|
- * 滚动到顶部
|
|
|
- * */
|
|
|
-const scrollHandler = (e) => {
|
|
|
- if (e.target.scrollTop <= 0) {
|
|
|
- if (!is_loading_more.value) {
|
|
|
- toQueryHistoryDetail();
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-// 当前智能体的头像
|
|
|
-const target_agent_icon = ref('');
|
|
|
-// 全部智能体头像数据
|
|
|
-const all_agent_icons = ref({});
|
|
|
-const agent_icon_map = {
|
|
|
- znwd: '01',
|
|
|
- bgsc: '02',
|
|
|
- znws: '03'
|
|
|
-};
|
|
|
-//获取头像
|
|
|
-const getAgentIconsFun = async () => {
|
|
|
- const username = await getUserName();
|
|
|
- target_agent_icon.value = '';
|
|
|
- const res = await getAgentIcons({ username });
|
|
|
- if (!Object.keys(res.data.user_icon).length) {
|
|
|
- await updateAgentIconsFun({
|
|
|
- username,
|
|
|
- user_icon: 'icon_1',
|
|
|
- icon_type: '01',
|
|
|
- icon_id: ''
|
|
|
- });
|
|
|
- await updateAgentIconsFun({
|
|
|
- username,
|
|
|
- user_icon: 'icon_4',
|
|
|
- icon_type: '02',
|
|
|
- icon_id: ''
|
|
|
- });
|
|
|
- await updateAgentIconsFun({
|
|
|
- username,
|
|
|
- user_icon: 'icon_5',
|
|
|
- icon_type: '03',
|
|
|
- icon_id: ''
|
|
|
- });
|
|
|
- getAgentIconsFun();
|
|
|
- } else {
|
|
|
- all_agent_icons.value = res.data.user_icon;
|
|
|
- target_agent_icon.value = res.data.user_icon[agent_icon_map[chat_type.value]]?.user_icon;
|
|
|
- // console.log(target_agent_icon.value, all_agent_icons.value)
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-// 修改头像
|
|
|
-const updateAgentIconsFun = async ({ username, user_icon, icon_type, icon_id }) => {
|
|
|
- const res = await updateAgentIcons({ username, user_icon, icon_type, icon_id });
|
|
|
- return res;
|
|
|
-};
|
|
|
-// 修改当前智能体头像
|
|
|
-const handleUpdate = async (icon) => {
|
|
|
- target_agent_icon.value = icon;
|
|
|
- const username = await getUserName();
|
|
|
- // console.log(all_agent_icons.value[agent_icon_map[chat_type.value]], agent_icon_map[chat_type.value])
|
|
|
- const res = await updateAgentIconsFun({
|
|
|
- username,
|
|
|
- user_icon: target_agent_icon.value,
|
|
|
- icon_type: agent_icon_map[chat_type.value],
|
|
|
- icon_id: all_agent_icons.value[agent_icon_map[chat_type.value]]?.icon_id || ''
|
|
|
- });
|
|
|
- if (res.code / 1 === 200) {
|
|
|
- Message.success('修改成功');
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-// 表格处理合并
|
|
|
-const toMerge = async (data) => {
|
|
|
- await mergeInfo();
|
|
|
- const params = {
|
|
|
- event_id: data.event_id
|
|
|
- };
|
|
|
- // 正在合并时,修改配置规则按钮状态为禁用
|
|
|
- chat_new_list.value.forEach((item) => {
|
|
|
- if (item.is_analyze) {
|
|
|
- item.client_custom_config_rule_disabled = true;
|
|
|
- }
|
|
|
- });
|
|
|
- is_merge_table.value = true; //正在合并,下方输入框均不可上传和发送
|
|
|
- try {
|
|
|
- const res = await mergeTableDataFun(params);
|
|
|
- if (res.code / 1 === 200) {
|
|
|
- const lastItem = chat_new_list.value.pop();
|
|
|
- lastItem.file_name = res.data.file_name;
|
|
|
- lastItem.file_size = getFileSize(res.data.size) || res.data.size;
|
|
|
- lastItem.client_show_merge_file = false;
|
|
|
- chat_new_list.value.push(lastItem);
|
|
|
- const params = {
|
|
|
- event_id: data.event_id,
|
|
|
- filename: res.data.waring_filename,
|
|
|
- page_index: 1,
|
|
|
- page_size: 10
|
|
|
- };
|
|
|
- // 对话区域滚动到底部
|
|
|
- scroll2ListBottom();
|
|
|
- const res_inner = await getCheckedErrorListFun(params);
|
|
|
- if (res_inner.code / 1 === 200) {
|
|
|
- const lastItem = chat_new_list.value.pop();
|
|
|
- lastItem.client_custom_bgcl_table_data = res_inner.data.rows;
|
|
|
- lastItem.client_custom_bgcl_table_total = res_inner.data.total;
|
|
|
- lastItem.event_id = data.event_id;
|
|
|
- lastItem.waring_filename = res.data.waring_filename;
|
|
|
- lastItem.client_show_merge_file = true;
|
|
|
- lastItem.status = 2;
|
|
|
- chat_new_list.value.push(lastItem);
|
|
|
- // 将分析,规则配置按钮项放在最底部
|
|
|
- }
|
|
|
- } else {
|
|
|
- const lastItem = chat_new_list.value.pop();
|
|
|
- lastItem.error_content = window.bgcl_error_content;
|
|
|
- lastItem.status = 2;
|
|
|
- lastItem.client_show_merge_file = false;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- const lastItem = chat_new_list.value.pop();
|
|
|
- lastItem.error_content = window.bgcl_error_content;
|
|
|
- lastItem.status = 2;
|
|
|
- lastItem.client_show_merge_file = false;
|
|
|
- console.log(e);
|
|
|
- } finally {
|
|
|
- // 合并完成后,取消禁用
|
|
|
- chat_new_list.value.forEach((item) => {
|
|
|
- if (item.is_analyze) {
|
|
|
- item.client_custom_config_rule_disabled = false;
|
|
|
- }
|
|
|
- });
|
|
|
- // 存在在历史记录中问答的情况,需要在历史记录中查到配置按钮项移入到新会话中的最末尾一项
|
|
|
- const idx = chat_new_list.value.findIndex((item) => item.is_analyze);
|
|
|
- // const idx_log = chat_log_list.value.findIndex(item => item.is_analyze)
|
|
|
- if (idx !== -1) {
|
|
|
- const filterItem = chat_new_list.value.find((item) => item.is_analyze);
|
|
|
- chat_new_list.value.splice(idx, 1);
|
|
|
- chat_new_list.value.push(filterItem);
|
|
|
- }
|
|
|
- // 对话区域滚动到底部
|
|
|
- scroll2ListBottom();
|
|
|
- is_merge_table.value = false;
|
|
|
- emit('updateHistory');
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const mergeInfo = () => {
|
|
|
- const lastItem = chat_display_list.value[chat_display_list.value.length - 1];
|
|
|
- // let mergeContent = `本次数据处理共处理了${lastItem.fileLength} 个Excel文件,文件格式包括 .xls 和 .xlsx。所有文件的数据已成功合并到一个统一的表格中,并保存为 merged_result.xlsx.在合并过程中,系统对数据进行了异常值检测,以下是检测到的异常值情况:`
|
|
|
- let mergeContent = `本次共处理${lastItem.fileLength}个Excel文件,数据已合并为统一表并导出为 merged_result.xlsx,合并过程中系统自动完成异常值扫描,以下为检测到的异常值情况:`;
|
|
|
- const newItem = {
|
|
|
- mergeContent,
|
|
|
- client_custom_unique_id: generateClientUniqueId(mergeContent + Date.now()),
|
|
|
- status: 1,
|
|
|
- is_merge: true, //控制区分解析和合并消息
|
|
|
- client_custom_item_type: 'a',
|
|
|
- event_id: lastItem.event_id,
|
|
|
- fileLength: lastItem.fileLength
|
|
|
- };
|
|
|
- chat_new_list.value.push(newItem);
|
|
|
- // 对话区域滚动到底部
|
|
|
- scroll2ListBottom();
|
|
|
-};
|
|
|
-const mergeTableDataFun = async (data) => {
|
|
|
- const res = await mergeTableData(data);
|
|
|
- return res;
|
|
|
-};
|
|
|
-const getCheckedErrorListFun = async (data) => {
|
|
|
- const res = await getCheckedErrorList(data);
|
|
|
- return res;
|
|
|
-};
|
|
|
-watch(
|
|
|
- () => route.params.conversation_id,
|
|
|
- () => {
|
|
|
- toInitData();
|
|
|
- history_item_params.value.conversation_id = route.params.conversation_id;
|
|
|
- if (history_item_params.value.conversation_id) {
|
|
|
- getDialogHistoryDetailFun();
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- deep: true,
|
|
|
- immediate: true
|
|
|
- }
|
|
|
-);
|
|
|
-watch(
|
|
|
- () => route.query.id,
|
|
|
- () => {
|
|
|
- if (route.query.id) {
|
|
|
- chat_type.value = route.query.id;
|
|
|
- } else {
|
|
|
- chat_type.value = 'znwd';
|
|
|
- }
|
|
|
- if (props.chatType) {
|
|
|
- // console.log(props.chatType, 9090)
|
|
|
- chat_type.value = props.chatType;
|
|
|
- }
|
|
|
- BD_session.value.conversation_id = '';
|
|
|
- AL_session.value.conversation_id = '';
|
|
|
- }
|
|
|
-);
|
|
|
-
|
|
|
-const registerChatComponent = inject('registerChatComponent');
|
|
|
-
|
|
|
-onMounted(async () => {
|
|
|
- // downloadReport({ record_id: 11111111 }).then(res => {
|
|
|
- // console.log(res)
|
|
|
- // })
|
|
|
- chat_type.value = route.query.id || 'znwd';
|
|
|
- await getAgentIconsFun();
|
|
|
- list_scroller.value?.addEventListener('scroll', funcThrottle(scrollHandler, 500));
|
|
|
- if (registerChatComponent) {
|
|
|
- registerChatComponent({ newChat });
|
|
|
- }
|
|
|
-});
|
|
|
-onUnmounted(() => {
|
|
|
- list_scroller.value?.removeEventListener('scroll', funcThrottle(scrollHandler, 500));
|
|
|
-});
|
|
|
-defineExpose({
|
|
|
- newChat
|
|
|
-});
|
|
|
-</script>
|
|
|
-<style scoped lang="css">
|
|
|
-.conversation-container {
|
|
|
- height: 100%;
|
|
|
- position: relative;
|
|
|
- background: linear-gradient(180deg, rgba(10, 129, 126, 0) 1%, rgba(10, 129, 126, 0.06) 98%);
|
|
|
-}
|
|
|
-
|
|
|
-.conversation-container-top {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: flex-start;
|
|
|
- width: 80%;
|
|
|
- margin: 0 auto;
|
|
|
- height: 100px;
|
|
|
- gap: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.conversation-container-top .icon {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- width: 50px;
|
|
|
- height: 50px;
|
|
|
- /* background-color: var(--primary-default); */
|
|
|
- border-radius: 10px;
|
|
|
- gap: 30px;
|
|
|
-}
|
|
|
-
|
|
|
-.icon-robot {
|
|
|
- width: 100%;
|
|
|
- cursor: pointer;
|
|
|
- /* color: #fff; */
|
|
|
-
|
|
|
- /* font-size: 40px; */
|
|
|
-}
|
|
|
-
|
|
|
-.conversation-container-top .name {
|
|
|
- font-size: 24px;
|
|
|
- font-weight: 600;
|
|
|
-}
|
|
|
-
|
|
|
-.main-conversation-container {
|
|
|
- position: relative;
|
|
|
- width: 100%;
|
|
|
- height: calc(100% - 160px - 100px - 25px - 40px);
|
|
|
- overflow-y: auto;
|
|
|
- z-index: 10;
|
|
|
-}
|
|
|
-
|
|
|
-.loading-more {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- gap: 10px;
|
|
|
- color: var(--primary-default);
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.loading-more .arco-spin .arco-spin-icon) {
|
|
|
- color: var(--primary-default);
|
|
|
-}
|
|
|
-
|
|
|
-.main-conversation-container::-webkit-scrollbar {
|
|
|
- display: none;
|
|
|
-}
|
|
|
-
|
|
|
-.main-container-1 {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- height: calc(100% - 120px - 180px);
|
|
|
- /* padding-top: 120px; */
|
|
|
- width: 80%;
|
|
|
- margin: 0 auto;
|
|
|
-}
|
|
|
-
|
|
|
-.main-container-2 {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- width: 80%;
|
|
|
- margin: 0 auto;
|
|
|
-}
|
|
|
-
|
|
|
-.loading {
|
|
|
- width: 80%;
|
|
|
- margin: 0 auto;
|
|
|
- margin-top: 100px;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.main-footer {
|
|
|
- height: 160px;
|
|
|
- width: 80%;
|
|
|
- margin: 0 auto;
|
|
|
- margin-top: 25px;
|
|
|
-}
|
|
|
-
|
|
|
-.bg-aside {
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- height: 100%;
|
|
|
- z-index: 0;
|
|
|
-}
|
|
|
-
|
|
|
-.bg-left-footer {
|
|
|
- position: absolute;
|
|
|
- left: -18px;
|
|
|
- bottom: 0;
|
|
|
- width: 349px;
|
|
|
- height: 337px;
|
|
|
- z-index: 0;
|
|
|
-}
|
|
|
-
|
|
|
-.bg-right-footer {
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- width: 389px;
|
|
|
- height: 597px;
|
|
|
- z-index: 0;
|
|
|
-}
|
|
|
-</style>
|