From e62bef04a3d74afffd47cc8bbff5f8addfda7b0b Mon Sep 17 00:00:00 2001
From: Mero
Date: Thu, 15 May 2025 16:09:17 +0800
Subject: [PATCH] =?UTF-8?q?format:=20conversation.ts=E9=87=8D=E6=9E=84/?=
=?UTF-8?q?=E5=8F=AF=E8=AF=BB=E6=80=A7=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/apis/tools.ts | 2 +-
src/store/conversation.ts | 1039 ++++++++++++++++-------------------
src/views/dialogue/types.ts | 2 +-
3 files changed, 487 insertions(+), 556 deletions(-)
diff --git a/src/apis/tools.ts b/src/apis/tools.ts
index c0096f68..2a2c9c5f 100644
--- a/src/apis/tools.ts
+++ b/src/apis/tools.ts
@@ -19,7 +19,7 @@ import type {
import { storeToRefs } from 'pinia';
import i18n from 'src/i18n';
-function getCookie(name: string) {
+export function getCookie(name: string) {
const matches = document.cookie.match(
new RegExp(
'(?:^|; )' + name.replace(/([.$?*|{}()[]\\\/\+^])/g, '\\$1') + '=([^;]*)',
diff --git a/src/store/conversation.ts b/src/store/conversation.ts
index 1a2d988a..a869e0fd 100644
--- a/src/store/conversation.ts
+++ b/src/store/conversation.ts
@@ -9,14 +9,19 @@
// See the Mulan PSL v2 for more details.
import { defineStore } from 'pinia';
import { ref } from 'vue';
-import { useHistorySessionStore, useLangStore } from 'src/store';
+import { fetchEventSource } from '@microsoft/fetch-event-source';
+
+import {
+ useHistorySessionStore,
+ useLangStore,
+} from 'src/store';
import {
AppShowType,
FlowDataType,
MessageArray,
type ConversationItem,
type RobotConversationItem,
- type UserConversationItem,
+ type UserConversationItem, FlowType,
} from 'src/views/dialogue/types';
import { api } from 'src/apis';
import { successMsg } from 'src/components/Message';
@@ -24,30 +29,19 @@ import i18n from 'src/i18n';
import { Application } from 'src/apis/paths/type';
import { handleAuthorize } from 'src/apis/tools';
import $bus from 'src/bus/index';
-import { fetchEventSource } from '@microsoft/fetch-event-source';
+import { useScrollBottom } from '@/hooks/useScrollBottom';
+import { getCookie } from "@/apis/tools";
import { getBaseProxyUrl } from 'src/utils/tools';
-let controller = new AbortController();
-export const txt2imgPath = ref('');
export const echartsObj = ref({});
-export const echartsHas = ref(false);
+
+let controller = new AbortController();
const excelPath = ref('');
-const resp = ref();
const features = {
max_tokens: 2048,
context_num: 2,
};
-function getCookie(name: string) {
- const matches = document.cookie.match(
- new RegExp(
- '(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + '=([^;]*)',
- ),
- );
- return matches ? decodeURIComponent(matches[1]) : undefined;
-}
-
-import { useScrollBottom } from '@/hooks/useScrollBottom';
export const useSessionStore = defineStore('conversation', () => {
// #region ----------------------------------------< scroll >--------------------------------------
// 会话窗口容器
@@ -58,6 +52,9 @@ export const useSessionStore = defineStore('conversation', () => {
});
// #endregion
+
+ const { language } = useLangStore();
+
// 是否暂停回答
const isPaused = ref(false);
// 会话列表
@@ -68,11 +65,350 @@ export const useSessionStore = defineStore('conversation', () => {
});
const appList = ref();
// ai回复是否还在生成中
- const isAnswerGenerating = ref(false);
+ const isAnswerGenerating = ref(false);
+
+ // 方法集合 - 用于处理不同类型的event message
+ const dataTransfers = {
+ textAdd: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ scrollToBottom();
+ const content = (message.content || {}) as Record;
+ const contentText: string = content.text || '';
+ //向message添加值
+ conversationItem.message[conversationItem.currentInd] += contentText;
+ //向messageList添加值
+ const items = conversationItem.messageList.getAllItems();
+ items[conversationItem.currentInd].message += contentText;
+ },
+ documentAdd: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ conversationItem.message[conversationItem.currentInd] += message.content;
+ conversationItem.files = [
+ ...conversationItem.files,
+ message.content
+ ];
+ },
+ suggestionFunc: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ if (conversationItem.search_suggestions) {
+ conversationItem.search_suggestions.push(
+ Object(message.content),
+ );
+ } else {
+ conversationItem.search_suggestions = [
+ Object(message.content),
+ ];
+ }
+ },
+ flowStart: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ const flow = (message.flow || {}) as Record;
+ conversationItem.flowdata = {
+ id: `${flow.stepId || ''}`,
+ title: i18n.global.t('flow.flow_start'),
+ // 工作流这里stepName代替step_progress,为不影响首页对话暂且用||
+ progress: flow.stepProgress || '',
+ status: 'running',
+ display: true,
+ flowId: `${flow.stepId || ''}`,
+ data: [[]],
+ };
+ },
+ stepInput: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ const flow = (message.flow || {}) as Record;
+ conversationItem.flowdata?.data[0].push({
+ id: flow.stepId,
+ title: flow.stepName,
+ status: flow.stepStatus,
+ data: {
+ input: message.content,
+ },
+ });
+ if (conversationItem.flowdata) {
+ conversationItem.flowdata.progress = flow.stepProgress;
+ conversationItem.flowdata.status = flow.stepStatus;
+ }
+ },
+ stepOutput: (
+ conversationItem: RobotConversationItem,
+ message: Record
+ ) => {
+ const flow = (message.flow || {}) as Record;
+ const metadata = (message.metadata || {}) as Record;
+ const target = conversationItem.flowdata?.data[0].find(
+ (item) => item.id === flow.stepId,
+ );
+ if (target) {
+ target.data.output = message.content;
+ target.status = flow.stepStatus;
+ // 工作流添加每阶段的时间耗时
+ target['costTime'] = metadata.timeCost;
+ if (
+ flow.step_status === 'error' &&
+ conversationItem.flowdata
+ ) {
+ conversationItem.flowdata.status = flow.stepStatus;
+ }
+ }
+ },
+ flowStop: (
+ conversationItem: RobotConversationItem,
+ message: Record,
+ isFlowDebug: boolean
+ ) => {
+ const content = (message.content || {}) as Record;
+ const contentFlow = (content.flow || {}) as Record;
+ const messageFlow = (message.flow || {}) as Record;
+ if (isFlowDebug) {
+ // 如果是工作流的调试功能-添加status/data
+ conversationItem.flowdata = {
+ id: contentFlow.stepId,
+ title: i18n.global.t('flow.flow_end'),
+ progress: contentFlow.stepProgress,
+ status: messageFlow.stepStatus,
+ display: true,
+ data: conversationItem?.flowdata?.data,
+ };
+ } else if (content.type !== 'schema' && conversationItem.flowdata) {
+ // 删除 end 逻辑
+ conversationItem.flowdata = {
+ id: contentFlow.stepId,
+ title: i18n.global.t('flow.flow_end'),
+ progress: contentFlow.stepProgress,
+ status: 'success',
+ display: true,
+ data: conversationItem.flowdata.data,
+ };
+ } else {
+ conversationItem.paramsList = content.data;
+ if (conversationItem.flowdata) {
+ conversationItem.flowdata.title = i18n.global.t(
+ 'flow.flow_params_error',
+ );
+ conversationItem.flowdata.status = 'error';
+ conversationItem.paramsList = content.data;
+ }
+ }
+ },
+ dataDone: (
+ conversationItem: RobotConversationItem,
+ isFlowDebug: boolean
+ ) => {
+ if (excelPath.value.length > 0) {
+ conversationItem.message[conversationItem.currentInd] +=
+ `
下载地址:${excelPath.value}`;
+ }
+ conversationItem.isFinish = true;
+ isAnswerGenerating.value = false;
+ // 如果是工作流的调试功能-调试对话结束时-发送调试对话结束
+ if (isFlowDebug) {
+ $bus.emit('debugChatEnd');
+ }
+ }
+ }
+
+ // chat message回调
+ const handleMsgDataShow = (
+ params: Record,
+ msgData: Record,
+ conversationItem: RobotConversationItem
+ ) => {
+ if (isPaused.value) {
+ // 手动暂停输出
+ isAnswerGenerating.value = false;
+ return;
+ }
+ const rawMsgData = msgData.data as string;
+ if (rawMsgData === '[DONE]') {
+ dataTransfers.dataDone(conversationItem, !!params.type);
+ return;
+ }
+
+ // 同一时间戳传来的decodeValue是含有三条信息的合并,so需要分割
+ // 这里json解析
+ const message = JSON.parse(rawMsgData || '{}');
+ const eventType = message['event'];
+ if ('metadata' in message) {
+ conversationItem.metadata = message.metadata;
+ }
+ if ('event' in message) {
+ switch (eventType) {
+ case 'text.add':
+ dataTransfers.textAdd(conversationItem, message);
+ break;
+ case 'heartbeat':
+ break;
+ case 'graph':
+ conversationItem.echartsObj = message.content.option;
+ break;
+ case 'document.add':
+ dataTransfers.documentAdd(conversationItem, message);
+ break;
+ case 'Suggestion':
+ dataTransfers.suggestionFunc(conversationItem, message);
+ break;
+ case 'init':
+ //初始化获取 metadata
+ conversationItem.metadata = message.metadata;
+ conversationItem.createdAt = message.content.created_at;
+ conversationItem.groupId = message.groupId;
+ break;
+ case 'flow.start':
+ //事件流开始--后续验证对话无下拉连接后则完全替换
+ dataTransfers.flowStart(conversationItem, message);
+ break;
+ case 'step.input':
+ dataTransfers.stepInput(conversationItem, message);
+ break;
+ case 'step.output':
+ dataTransfers.stepOutput(conversationItem, message);
+ break;
+ case 'flow.stop':
+ //时间流结束
+ dataTransfers.flowStop(conversationItem, message, !!params.type);
+ break;
+ default:
+ break;
+ }
+ }
+ // 将lines传递给workflow-以更新工作流节点的状态
+ if (params.user_selected_flow && params.user_selected_app) {
+ $bus.emit('getNodesStatue', { data: message });
+ }
+ };
+
+ // 方法集合 - 用于区分fetch时的请求
+ const funcFetch = {
+ fetchHistory: async (
+ url: string,
+ params: Record,
+ innerParams: Record,
+ fetchParams: Record
+ ) => {
+ if (!params.type) {
+ await fetchEventSource(
+ url,
+ {
+ ...fetchParams,
+ body: JSON.stringify({
+ app: {
+ appId: (params.user_selected_app as unknown[])[0],
+ auth: {},
+ flowId: params.user_selected_flow,
+ params: innerParams,
+ },
+ conversationId: params.conversationId,
+ features: features,
+ groupId: params.groupId,
+ language,
+ question: params.question,
+ // record_id: params.qaRecordId,
+ })
+ }
+ );
+ return;
+ }
+ // 新的工作流调试记录
+ await fetchEventSource(
+ url,
+ {
+ ...fetchParams,
+ body: JSON.stringify({
+ app: {
+ appId: (params.user_selected_app as unknown[])[0],
+ flowId: params.user_selected_flow,
+ params: {},
+ },
+ conversationId: params.conversationId,
+ debug: true,
+ question: params.question,
+ })
+ }
+ );
+ },
+ fetchAppNew: async (
+ url: string,
+ params: Record,
+ innerParams: Record,
+ fetchParams: Record
+ ) => {
+ await fetchEventSource(
+ url,
+ {
+ ...fetchParams,
+ body: JSON.stringify({
+ app: {
+ appId: (params.user_selected_app as unknown[])[0],
+ auth: {},
+ flowId: '',
+ params: innerParams,
+ },
+ conversationId: params.conversationId,
+ features: features,
+ language,
+ groupId: params.groupId,
+ question: params.question,
+ record_id: params.qaRecordId,
+ })
+ }
+ );
+ },
+ fetchDefault: async (
+ url: string,
+ params: Record,
+ innerParams: Record,
+ fetchParams: Record
+ ) => {
+ await fetchEventSource(
+ url,
+ {
+ ...fetchParams,
+ body: JSON.stringify({
+ app: {
+ appId: '',
+ flowId: '',
+ params: {},
+ auth: {},
+ },
+ conversationId: params.conversationId,
+ features: features,
+ groupId: params.groupId,
+ language,
+ question: params.question,
+ record_id: params.qaRecordId,
+ })
+ }
+ );
+ }
+ }
+
+ const judgeResp = async (resp) => {
+ const isServiceOk = await handleServiceStatus(resp.status);
+ if (!isServiceOk) {
+ return false;
+ }
+ if (!resp.ok) {
+ throw new Error(`HTTP error! status: ${resp.status}`);
+ }
+ if (!resp.body) {
+ throw new Error(`HTTP error, body not exits`);
+ }
+ return true;
+ }
+
/**
* 请求流式数据
- * @param params
- * {
**/
const getStream = async (
params: {
@@ -87,388 +423,81 @@ export const useSessionStore = defineStore('conversation', () => {
},
ind?: number,
): Promise => {
- const { language } = useLangStore();
+
const { currentSelectedSession } = useHistorySessionStore();
params.conversationId = currentSelectedSession;
- // 当前问答在整个问答记录中的索引 openouler有什么ai特性
+ // 当前问答在整个问答记录中的索引 openEuler有什么ai特性
const answerIndex = ind ?? conversationList.value.length - 1;
- const conversationItem = conversationList.value[
- answerIndex
- ] as RobotConversationItem;
+ const conversationItem =
+ conversationList.value[answerIndex] as RobotConversationItem;
controller = new AbortController();
- const headers = {
- user: JSON.stringify({ userName: 'openEuler' }),
- };
- headers['Content-Type'] = 'application/json; charset=UTF-8';
- headers['X-CSRF-Token'] = getCookie('_csrf_tk');
- // 从 localStorage 获取 ECSESSION 并设置 Authorization
- const token = localStorage.getItem('ECSESSION');
- if (token) {
- headers['Authorization'] = `Bearer ${token}`;
- }
+
try {
- let pp = {};
+ let pp;
if (params.params && typeof params.params === 'object') {
pp = params.params;
} else if (params.params && typeof params.params === 'string') {
pp = Object(JSON.parse(params.params));
- } else {
- pp = {};
}
isPaused.value = false;
excelPath.value = '';
echartsObj.value = {};
- txt2imgPath.value = '';
- const handelMsgDataShow = (msgData) => {
- if (isPaused.value) {
- // 手动暂停输出
- isAnswerGenerating.value = false;
- return;
- }
- if (msgData.data === '[DONE]') {
- if (excelPath.value.length > 0) {
- conversationItem.message[conversationItem.currentInd] +=
- `
下载地址:${excelPath.value}`;
- }
- conversationItem.isFinish = true;
- isAnswerGenerating.value = false;
- // 如果是工作流的调试功能-调试对话结束时-发送调试对话结束
- if (params.type) {
- $bus.emit('debugChatEnd');
- }
- return;
- }
+ // txt2imgPath.value = '';
- // 同一时间戳传来的decodeValue是含有三条信息的合并,so需要分割
- // 这里json解析
- const message = JSON.parse(msgData.data || '{}');
- const eventType = message['event'];
- if ('metadata' in message) {
- conversationItem.metadata = message.metadata;
- }
- if ('event' in message) {
- switch (eventType) {
- case 'text.add':
- {
- scrollToBottom();
- //向message添加值
- conversationItem.message[conversationItem.currentInd] +=
- message.content.text;
- //向messageList添加值
- conversationItem.messageList.getAllItems()[
- conversationItem.currentInd
- ].message += message.content.text;
- }
- break;
- case 'heartbeat':
- break;
- case 'graph':
- {
- conversationItem.echartsObj = message.content.option;
- }
- break;
- case 'ducument.add':
- {
- conversationItem.message[conversationItem.currentInd] +=
- message.content;
- conversationItem.files = [
- ...conversationItem.files,
- message.content,
- ];
- }
- break;
- case 'Suggestion':
- {
- if (conversationItem.search_suggestions) {
- conversationItem.search_suggestions.push(
- Object(message.content),
- );
- } else {
- conversationItem.search_suggestions = [
- Object(message.content),
- ];
- }
- }
- break;
- case 'init':
- {
- //初始化获取 metadata
- conversationItem.metadata = message.metadata;
- conversationItem.createdAt = message.content.created_at;
- conversationItem.groupId = message.groupId;
- }
- break;
- case 'flow.start':
- {
- //事件流开始--后续验证对话无下拉连接后则完全替换
- const flow = message.flow;
- conversationItem.flowdata = {
- id: flow?.stepId || '',
- title: i18n.global.t('flow.flow_start'),
- // 工作流这里stepName代替step_progresss,为不影响首页对话暂且用||
- progress: flow?.stepProgress || '',
- status: 'running',
- display: true,
- flowId: flow?.flowId || '',
- data: [[]],
- };
- }
- break;
- case 'step.input':
- {
- conversationItem.flowdata?.data[0].push({
- id: message.flow?.stepId,
- title: message.flow?.stepName,
- status: message.flow?.stepStatus,
- data: {
- input: message.content,
- },
- });
- if (conversationItem.flowdata) {
- conversationItem.flowdata.progress =
- message.flow?.stepProgress;
- conversationItem.flowdata.status = message.flow?.stepStatus;
- }
- }
- break;
- case 'step.output':
- {
- const target = conversationItem.flowdata?.data[0].find(
- (item) => item.id === message.flow?.stepId,
- );
- if (target) {
- target.data.output = message.content;
- target.status = message.flow?.stepStatus;
- // 工作流添加每阶段的时间耗时
- target['costTime'] = message.metadata?.timeCost;
- if (
- message.flow.step_status === 'error' &&
- conversationItem.flowdata
- ) {
- conversationItem.flowdata.status = message.flow?.stepStatus;
- }
- }
- }
- break;
- case 'flow.stop':
- //时间流结束
- {
- const flow = message.content.flow;
- if (params.type) {
- // 如果是工作流的调试功能-添加status/data
- conversationItem.flowdata = {
- id: flow?.stepId,
- title: i18n.global.t('flow.flow_end'),
- progress: flow?.stepProgress,
- status: message.flow?.stepStatus,
- display: true,
- data: conversationItem?.flowdata?.data,
- };
- } else if (
- message.content.type !== 'schema' &&
- conversationItem.flowdata
- ) {
- // 删除 end 逻辑
- conversationItem.flowdata = {
- id: flow?.stepId,
- title: i18n.global.t('flow.flow_end'),
- progress: flow?.stepProgress,
- status: 'success',
- display: true,
- data: conversationItem.flowdata.data,
- };
- } else {
- conversationItem.paramsList = message.content.data;
- if (conversationItem.flowdata) {
- conversationItem.flowdata.title = i18n.global.t(
- 'flow.flow_params_error',
- );
- conversationItem.flowdata.status = 'error';
- conversationItem.paramsList = message.content.data;
- }
- }
- }
- break;
- default:
- break;
- }
- }
- // 将lines传递给workflow-以更新工作流节点的状态
- if (params.user_selected_flow && params.user_selected_app) {
- $bus.emit('getNodesStatue', { data: message });
- }
- };
+ let resp = {} as Response;
const baseProxyUrl = await getBaseProxyUrl();
const streamUrl = baseProxyUrl + '/api/chat';
+ const localEc = window.localStorage?.getItem('ECSESSION');
+ const fetchParams = {
+ signal: controller.signal,
+ keepalive: true,
+ method: 'POST',
+ headers: {
+ user: JSON.stringify({ userName: 'openEuler' }),
+ 'Content-Type': 'application/json; charset=UTF-8',
+ 'X-CSRF-Token': getCookie('_csrf_tk') || '',
+ // 从 localStorage 获取 ECSESSION 并设置 Authorization
+ ...(localEc ? {'Authorization': `Bearer ${localEc}`} : {})
+ },
+ body: {},
+ onopen: async (response) => {
+ resp = response;
+ },
+ onmessage: async (ev) => {
+ handleMsgDataShow(params, ev, conversationItem);
+ }
+ }
+
if (params.user_selected_flow) {
// 之前的对话历史记录
- if (!params.type) {
- await fetchEventSource(streamUrl, {
- signal: controller.signal,
- keepalive: true,
- method: 'POST',
- headers: headers,
- body: JSON.stringify({
- question: params.question,
- language,
- conversationId: params.conversationId,
- groupId: params.groupId,
- // record_id: params.qaRecordId,
- app: {
- appId: params.user_selected_app[0],
- flowId: params.user_selected_flow,
- params: pp,
- auth: {},
- },
- features: features,
- }),
- async onopen(response) {
- resp.value = response;
- },
- async onmessage(ev) {
- handelMsgDataShow(ev);
- },
- });
- } else {
- // 新的工作流调试记录
- await fetchEventSource(streamUrl, {
- signal: controller.signal,
- keepalive: true,
- method: 'POST',
- headers: headers,
- body: JSON.stringify({
- app: {
- params: {},
- appId: params.user_selected_app[0],
- flowId: params.user_selected_flow,
- },
- question: params.question,
- conversationId: params.conversationId,
- debug: true,
- }),
- async onopen(response) {
- resp.value = response;
- },
- async onmessage(ev) {
- handelMsgDataShow(ev);
- },
- });
- }
+ await funcFetch.fetchHistory(streamUrl, params, pp, fetchParams);
} else if (params.user_selected_app) {
// 新的工作流调试记录
- await fetchEventSource(streamUrl, {
- signal: controller.signal,
- keepalive: true,
- method: 'POST',
- headers: headers,
- body: JSON.stringify({
- question: params.question,
- conversationId: params.conversationId,
- record_id: params.qaRecordId,
- language,
- groupId: params.groupId,
- // record_id: params.qaRecordId,
- app: {
- appId: params.user_selected_app[0],
- flowId: '',
- params: pp,
- auth: {},
- },
- features: features,
- }),
- async onopen(response) {
- resp.value = response;
- },
- async onmessage(ev) {
- handelMsgDataShow(ev);
- },
- });
- } else if (false) {
- //写传参数情况
+ await funcFetch.fetchAppNew(streamUrl, params, pp, fetchParams);
+ // } else if (false) {
+ // //写传参数情况
} else {
- await fetchEventSource(streamUrl, {
- signal: controller.signal,
- keepalive: true,
- method: 'POST',
- headers: headers,
- body: JSON.stringify({
- question: params.question,
- conversationId: params.conversationId,
- record_id: params.qaRecordId,
- language,
- groupId: params.groupId,
- // record_id: params.qaRecordId,
- app: {
- appId: '',
- flowId: '',
- params: {},
- auth: {},
- },
- features: features,
- }),
- async onopen(response) {
- resp.value = response;
- },
- async onmessage(ev) {
- handelMsgDataShow(ev);
- },
- });
- }
- const isServiceOk = await handleServiceStatus(resp.value.status);
- if (!isServiceOk) {
- return;
- }
- if (!resp.value.ok) {
- throw new Error(`HTTP error! status: ${resp.value.status}`);
- }
- if (!resp.value.body) {
- throw new Error(`HTTP error, body not exits`);
+ await funcFetch.fetchDefault(streamUrl, params, pp, fetchParams);
}
+
+ await judgeResp(resp);
} catch (err: any) {
isPaused.value = true;
isAnswerGenerating.value = false;
- (conversationList.value[answerIndex] as RobotConversationItem).isFinish =
- true;
+ const targetItem = conversationList.value[answerIndex] as RobotConversationItem;
+ targetItem.isFinish = true;
if (err.name === 'AbortError') {
successMsg(i18n.global.t('feedback.stopSuccessful'));
- (
- conversationList.value[answerIndex] as RobotConversationItem
- ).isFinish = true;
+ // targetItem.isFinish = true;
} else {
- (conversationList.value[answerIndex] as RobotConversationItem).message[
- (
- conversationList.value[answerIndex] as RobotConversationItem
- ).currentInd
- ] += i18n.global.t('feedback.systemBusy');
+ targetItem.message[targetItem.currentInd] += i18n.global.t('feedback.systemBusy');
}
}
};
- /**
- * 解析图表格式的文本
- */
- const extractAttributesFromMarker = (
- str: string,
- ): { title: string; link: string } | null => {
- const regex = /<<<[^>]*title="([^"]+)"[^>]*link="([^"]+)"[^>]*>>>/;
-
- const match = str.match(regex);
-
- if (match) {
- return {
- title: match[1],
- link: match[2],
- };
- } else {
- return null;
- }
- };
-
/**
* 处理服务状态
* @param status
- * @param params
- * @param ind
*/
const handleServiceStatus = async (status: number): Promise => {
if (status === 401 || status === 403) {
@@ -482,47 +511,16 @@ export const useSessionStore = defineStore('conversation', () => {
}
};
- /**
- * 处理不合法信息
- * @param ind 当前问答对索引
- */
- const judgeMessage = (ind: number, msg: string): boolean => {
- let errorMsg = '';
- if (msg.includes('[SENSITIVE]')) {
- errorMsg = i18n.global.t('feedback.onlySupport');
- }
- //error没加限制
- if (msg.includes('[ERROR]')) {
- errorMsg = i18n.global.t('feedback.systemBusy');
- const answerIndex = ind ?? conversationList.value.length - 1;
- const conversationItem = conversationList.value[
- answerIndex
- ] as RobotConversationItem;
- if (conversationItem.flowdata) {
- conversationItem.flowdata.status = 'error';
- }
- }
- if (
- errorMsg &&
- !(conversationList.value[ind] as RobotConversationItem).message[
- (conversationList.value[ind] as RobotConversationItem).currentInd
- ]
- ) {
- (conversationList.value[ind] as RobotConversationItem).message[
- (conversationList.value[ind] as RobotConversationItem).currentInd
- ] = errorMsg;
- (conversationList.value[ind] as RobotConversationItem).isFinish = true;
- isAnswerGenerating.value = false;
- scrollToBottom();
- return false;
- }
- scrollToBottom();
- return true;
- };
/**
* 发送问题
+ * @param groupId
* @param question 问题
+ * @param user_selected_app
* @param regenerateInd 重新生成的回答索引
+ * @param qaRecordId
+ * @param user_selected_flow
+ * @param params
+ * @param type
*/
const sendQuestion = async (
groupId: string | undefined,
@@ -537,35 +535,28 @@ export const useSessionStore = defineStore('conversation', () => {
const { updateSessionTitle, currentSelectedSession } =
useHistorySessionStore();
if (conversationList.value.length === 0) {
- // 如果当前还没有对话记录,将第一个问题的questtion作为对话标题
+ // 如果当前还没有对话记录,将第一个问题的question作为对话标题
await updateSessionTitle({
conversationId: currentSelectedSession,
title: question.slice(0, 20),
});
}
if (regenerateInd) {
+ const targetItem = conversationList.value[regenerateInd] as RobotConversationItem;
// 重新生成,指定某个回答,修改默认索引
- (
- conversationList.value[regenerateInd] as RobotConversationItem
- ).message.push(''); //123
+ targetItem.message.push(''); //123
// 重新生成,指定某个回答,修改默认索引
- (
- conversationList.value[regenerateInd] as RobotConversationItem
- ).messageList.push({
+ targetItem.messageList.push({
message: '',
- record_id: qaRecordId,
+ record_id: qaRecordId || '',
comment: 'none',
});
- (
- conversationList.value[regenerateInd] as RobotConversationItem
- ).currentInd =
- (conversationList.value[regenerateInd] as RobotConversationItem).message
- .length - 1; //123
+ targetItem.currentInd = targetItem.message.length - 1; //123
} else {
// 初次生成 ,创建一个问题和一个回答
const ind = conversationList.value.length - 1;
- const a = new MessageArray();
- a.addItem('', '', 'none');
+ const messageList = new MessageArray();
+ messageList.addItem('', '', 'none');
conversationList.value.push(
{
cid: ind + 1,
@@ -577,7 +568,7 @@ export const useSessionStore = defineStore('conversation', () => {
cid: ind + 2,
belong: 'robot',
message: [''],
- messageList: a,
+ messageList,
currentInd: 0,
isFinish: false,
recordId: '',
@@ -589,63 +580,55 @@ export const useSessionStore = defineStore('conversation', () => {
}
isAnswerGenerating.value = true;
scrollToBottom(true);
+
+ let getStreamParams: Parameters[0] = {
+ question,
+ qaRecordId,
+ groupId
+ };
if (user_selected_flow && user_selected_app) {
- await getStream(
- {
- question,
- qaRecordId,
- user_selected_app: [...user_selected_app],
- user_selected_flow,
- groupId: groupId,
- params: params || undefined,
- type: type,
- },
- regenerateInd ?? undefined,
- );
+ getStreamParams = {
+ ...getStreamParams,
+ user_selected_app: [...user_selected_app],
+ user_selected_flow,
+ params: params || undefined,
+ type: type
+ }
} else if (user_selected_app?.length) {
- await getStream(
- {
- question,
- qaRecordId,
- user_selected_app: [...user_selected_app],
- groupId: groupId,
- params: params || undefined,
- },
- regenerateInd ?? undefined,
- );
- } else {
- await getStream(
- {
- question,
- qaRecordId,
- groupId: groupId,
- },
- regenerateInd ?? undefined,
- );
+ getStreamParams = {
+ ...getStreamParams,
+ user_selected_app: [...user_selected_app],
+ params: params || undefined,
+ }
}
+ await getStream(
+ getStreamParams,
+ regenerateInd ?? undefined,
+ );
};
+
/**
* 暂停流式返回
*/
const pausedStream = async (cid?: number): Promise => {
- const answerIndex =
- conversationList.value.findIndex((val) => val.cid === cid) !== -1
- ? conversationList.value.findIndex((val) => val.cid === cid)
- : conversationList.value.length - 1;
+ let answerIdx = conversationList.value.findIndex((val) => val.cid === cid);
+ if (answerIdx === -1) {
+ answerIdx = conversationList.value.length - 1;
+ }
+
isPaused.value = true;
- (conversationList.value[answerIndex] as RobotConversationItem).message[0] +=
- '暂停生成';
- (conversationList.value[answerIndex] as RobotConversationItem).isFinish =
- true;
+ const targetItem = conversationList.value[answerIdx] as RobotConversationItem;
+ targetItem.message[0] += '暂停生成';
+ targetItem.isFinish = true;
cancel();
const resp = await api.stopGeneration();
if (resp?.[1]?.code === 200) {
isAnswerGenerating.value = false;
}
};
+
/**
* 重新生成回答
- * @param cid
*/
const reGenerateAnswer = (
cid: number,
@@ -655,64 +638,54 @@ export const useSessionStore = defineStore('conversation', () => {
const answerInd = conversationList.value.findIndex(
(val) => val.cid === cid,
);
+ const answerItem = conversationList.value[answerInd] as RobotConversationItem;
const question = (
conversationList.value[answerInd - 1] as UserConversationItem
).message;
- const recordId = (
- conversationList.value[answerInd] as RobotConversationItem
- ).recordId;
+ const recordId = answerItem.recordId;
let groupId: string | undefined;
if (type && type === 'params') {
groupId = undefined;
} else {
- groupId = (conversationList.value[answerInd] as RobotConversationItem)
- .groupId
- ? (conversationList.value[answerInd] as RobotConversationItem).groupId
- : '';
+ groupId = answerItem.groupId || '';
}
- (conversationList.value[answerInd] as RobotConversationItem).isFinish =
- false;
+ answerItem.isFinish = false;
if (!question) {
return;
}
sendQuestion(groupId, question, user_selected_app, answerInd, recordId, '');
};
- // #region ----------------------------------------< pagenation >--------------------------------------
+ // #region ----------------------------------------< pagination >--------------------------------------
/**
* 上一条
* @param cid
*/
const prePage = (cid: number): void => {
- const answerInd = conversationList.value.findIndex(
+ const answerItem = conversationList.value.find(
(val) => val.cid === cid,
- );
- if (
- (conversationList.value[answerInd] as RobotConversationItem)
- .currentInd === 0
- ) {
+ ) as RobotConversationItem;
+ if (!answerItem || answerItem.currentInd === 0) {
return;
}
- (conversationList.value[answerInd] as RobotConversationItem).currentInd -=
- 1;
+ answerItem.currentInd -= 1;
};
+
/**
* 下一条
* @param cid
*/
const nextPage = (cid: number): void => {
- const answerInd = conversationList.value.findIndex(
+ const answerItem = conversationList.value.find(
(val) => val.cid === cid,
- );
-
- if (
- conversationList.value[answerInd].message.length - 1 ===
- (conversationList.value[answerInd] as RobotConversationItem).currentInd
- ) {
+ ) as RobotConversationItem;
+ if (!answerItem) {
+ return;
+ }
+ if (answerItem.message.length - 1 === answerItem.currentInd) {
return;
}
- (conversationList.value[answerInd] as RobotConversationItem).currentInd +=
- 1;
+ answerItem.currentInd += 1;
};
// #endregion
@@ -721,34 +694,28 @@ export const useSessionStore = defineStore('conversation', () => {
* @param conversationId
*/
const getConversation = async (conversationId: string): Promise => {
- const [_, res] = await api.getHistoryConversation(conversationId);
- if (!_ && res) {
+ const [err, res] = await api.getHistoryConversation(conversationId);
+ if (!err && res) {
conversationList.value = [];
+ const cList = conversationList.value as RobotConversationItem[];
res.result.records.forEach((record) => {
- if (
- (conversationList.value as RobotConversationItem[]).find(
- (i) => i.groupId === record.groupId,
- )
- ) {
- const re = (conversationList.value as RobotConversationItem[]).find(
- (i) => i.groupId === record.groupId,
+ const targetRecord = cList.find(i => i.groupId === record.groupId);
+ if (targetRecord) {
+ // 这里用groupId找到的targetRecord中的message必为array(为string的情况不存在groupId)
+ targetRecord.message.push(record.content.answer);
+ targetRecord.messageList.addItem(
+ record.content.answer,
+ record.id,
+ // is_like字段改为 comment = "liked", "disliked", "none"
+ record.comment,
);
- re?.message.push(record.content.answer);
- if (typeof re?.message !== 'string') {
- re?.messageList.addItem(
- record.content.answer,
- record.id,
- // is_like字段改为 comment = "liked", "disliked", "none"
- record.comment,
- );
- if (re?.currentInd !== undefined) {
- re.currentInd = re.currentInd + 1;
- }
+ if (targetRecord.currentInd !== undefined) {
+ targetRecord.currentInd ++;
}
return;
}
- const a = new MessageArray();
- a.addItem(
+ const messageList = new MessageArray();
+ messageList.addItem(
record.content.answer,
record.id,
// is_like字段改为 comment = "liked", "disliked", "none"
@@ -765,7 +732,7 @@ export const useSessionStore = defineStore('conversation', () => {
cid: conversationList.value.length + 2,
belong: 'robot',
message: [record.content.answer],
- messageList: a,
+ messageList,
currentInd: 0,
isAgainst: false,
isSupport: false,
@@ -774,25 +741,16 @@ export const useSessionStore = defineStore('conversation', () => {
conversationId: record.conversationId,
groupId: record.groupId,
metadata: record.metadata,
- flowdata: record?.flow
- ? (GenerateFlowData(record.flow) as {
- id: number;
- title: string;
- status: string;
- data: any;
- display: boolean;
- progress: string;
- flowId?: string;
- })
- : undefined,
+ flowdata: record?.flow ? (generateFlowData(record.flow) as FlowType) : undefined,
},
);
scrollToBottom();
});
}
};
+
//将获取到的 flow 数据结构转换
- const GenerateFlowData = (record: any): object => {
+ const generateFlowData = (record: any): FlowDataType => {
const flowData = {
id: record.recordId,
title: record.id,
@@ -812,12 +770,7 @@ export const useSessionStore = defineStore('conversation', () => {
},
});
}
- return flowData as FlowDataType;
- };
-
- const comment = (cid: number, isSupport: boolean, index: number): void => {
- const ind = conversationList.value.find((item) => item.cid === cid);
- // ind.message.items[index].is_like = isSupport;
+ return flowData;
};
/**
@@ -827,8 +780,8 @@ export const useSessionStore = defineStore('conversation', () => {
isPaused.value = true;
(
conversationList.value[
- conversationList.value.length - 1
- ] as RobotConversationItem
+ conversationList.value.length - 1
+ ] as RobotConversationItem
).isFinish = true;
cancel();
const resp = await api.stopGeneration();
@@ -837,31 +790,10 @@ export const useSessionStore = defineStore('conversation', () => {
}
};
- // 判断string是否是json对象
- const judgeJson = (str) => {
- if (!str) {
- return false;
- }
- if (str.length < 8) {
- return false;
- }
- const str3 = str.substr(6, str.length - 1);
- try {
- const obj = JSON.parse('"' + str3);
- if (typeof obj === 'object' && obj) {
- return true;
- } else {
- return false;
- }
- } catch (err) {
- console.error('An error occurred:', err);
- return false;
- }
- };
-
const cancel = () => {
controller.abort();
};
+
return {
isPaused,
conversationList,
@@ -876,7 +808,6 @@ export const useSessionStore = defineStore('conversation', () => {
nextPage,
reGenerateAnswer,
getConversation,
- comment,
- cancel,
+ cancel
};
});
diff --git a/src/views/dialogue/types.ts b/src/views/dialogue/types.ts
index a0ebcf71..14df2eed 100644
--- a/src/views/dialogue/types.ts
+++ b/src/views/dialogue/types.ts
@@ -53,7 +53,7 @@ export interface UserConversationItem {
}
export interface FlowType {
- id: number;
+ id: string;
title: string;
status: string;
data: any;
--
Gitee