import { orderBy } from 'lodash-es';
|
import type { ChatContent, ChatMessage, StepItem } from '../model/types';
|
import { AnswerType, MultiChatType, RoleEnum, StepEnum } from '../model/types';
|
import { GetHistoryAnswer } from '/@/api/ai/chat';
|
import moment from 'moment';
|
import type { Attach } from '../components/playBar/hook/useAttach';
|
import {
|
getFileGroupType,
|
getFileSuffix,
|
getIconByGroupType,
|
getIconClassByGroupType,
|
} from '../components/playBar/hook/useUploadFile';
|
export const useLoadData = () => {
|
const parseExtraContent = (res) => {
|
if (!res) return {};
|
const askMoreList = orderBy(res.context_history, [(item) => Number(item.radio)], ['desc']);
|
const errCode = res?.err_code;
|
const errMsg = res?.json_msg;
|
const origin = res;
|
|
return {
|
askMoreList,
|
errCode,
|
errMsg,
|
origin,
|
};
|
};
|
const parseContent = (res, reportIsShow = false, extraContent?) => {
|
if (!res) return null;
|
let content: ChatContent = {
|
type: AnswerType.Text,
|
values: '解析失败!',
|
};
|
if (res.type) {
|
res.answer_type = res.type;
|
}
|
const curExtraContent = parseExtraContent(res);
|
|
switch (res.answer_type) {
|
case AnswerType.RecordSet:
|
content = {
|
type: AnswerType.RecordSet,
|
values: res.values,
|
};
|
break;
|
case AnswerType.Text:
|
content = {
|
type: AnswerType.Text,
|
values: res.values ?? res.answer,
|
};
|
break;
|
case AnswerType.Script:
|
content = {
|
type: AnswerType.Script,
|
values: res,
|
};
|
break;
|
|
case AnswerType.Knowledge:
|
content = {
|
type: AnswerType.Knowledge,
|
values: res.knowledge,
|
};
|
|
break;
|
case AnswerType.Report:
|
content = {
|
type: AnswerType.Report,
|
values: (res?.reports ?? []).map((item) => ({
|
content: parseContent(item, reportIsShow, { origin: item, conclusion: item.conclusion ?? [] }),
|
})),
|
};
|
break;
|
|
case AnswerType.Summary:
|
content = {
|
type: AnswerType.Summary,
|
values: res.summary?.map((item) => {
|
item.reportIsShow = reportIsShow;
|
return item;
|
}),
|
};
|
break;
|
case AnswerType.Url:
|
content = {
|
type: AnswerType.Url,
|
values: res.url,
|
};
|
break;
|
case AnswerType.Map:
|
content = {
|
type: AnswerType.Map,
|
values: res.values,
|
};
|
break;
|
default:
|
content = {
|
type: AnswerType.Text,
|
values: '解析失败!',
|
};
|
break;
|
}
|
if (!extraContent) {
|
content = {
|
...content,
|
...curExtraContent,
|
};
|
} else {
|
content = {
|
...content,
|
...extraContent,
|
};
|
}
|
|
return content;
|
};
|
|
/**
|
* 获取步骤组列表
|
* @param reports
|
* @returns
|
*/
|
const getStepGroupList = (reports: any[]) => {
|
const stepGroupList = (reports ?? []).map((item) => ({
|
value: convertProcessToStep(item?.exec_process),
|
isShow: false,
|
}));
|
/** @description 全部放到第一个 */
|
stepGroupList.map((item, index) => {
|
if (index !== 0) {
|
stepGroupList[0].value.push(...item.value);
|
item.value = [];
|
}
|
});
|
return stepGroupList;
|
};
|
const formatShowTimeYear = (str: string) => {
|
const date = moment(str);
|
const now = moment();
|
|
// 计算日期差,使用clone()避免修改原始时间
|
const diffDays = now.clone().startOf('day').diff(date.clone().startOf('day'), 'days');
|
|
if (diffDays === 0) {
|
return `今天 ${date.format('HH:mm:ss')}`;
|
} else if (diffDays === 1) {
|
return `昨天 ${date.format('HH:mm:ss')}`;
|
} else if (diffDays === 2) {
|
return `前天 ${date.format('HH:mm:ss')}`;
|
}
|
|
if (date.year() === now.year()) {
|
return date.format('MM月DD日 HH:mm:ss');
|
} else {
|
return date.format('YYYY年MM月DD日 HH:mm:ss');
|
}
|
};
|
const getAnswerById = async (historyId: string) => {
|
return await GetHistoryAnswer({
|
history_id: historyId,
|
});
|
};
|
|
const convertAttach = (userValues: any): Attach[] => {
|
const attachList: Attach[] = [];
|
if (userValues?.attach_tables) {
|
userValues.attach_tables.forEach((item: any) => {
|
attachList.push({
|
title: item.title,
|
type: 'table',
|
model: item,
|
icon: 'biaoge',
|
iconClass: 'ywicon-biaoge text-[#c5e0ff]',
|
});
|
});
|
}
|
|
if (userValues?.attach_metrics) {
|
userValues.attach_metrics.forEach((item: any) => {
|
attachList.push({
|
title: item.title,
|
type: 'metric',
|
model: item,
|
icon: 'zhibiao',
|
iconClass: 'ywicon-zhibiao text-[#c5e0ff]',
|
});
|
});
|
}
|
|
if (userValues?.attach_files) {
|
userValues.attach_files.forEach((item: any) => {
|
const suffix = getFileSuffix(item.file_name);
|
const groupType = getFileGroupType(suffix);
|
attachList.push({
|
title: item.file_name,
|
type: 'file',
|
model: item,
|
icon: getIconByGroupType(groupType),
|
iconClass: getIconClassByGroupType(groupType),
|
});
|
});
|
}
|
return attachList;
|
};
|
/**
|
* 获取用户回复数据,并插入到对话当中去
|
*/
|
const loadReplyData = async (userMsg: any[]) => {
|
const userItemIdMap = new Map();
|
// 用户消息
|
const tmpMessageList: ChatMessage[] = userMsg.map((item) => {
|
return {
|
historyId: item.history_id,
|
createTime: item.create_time,
|
role: RoleEnum.user,
|
content: {
|
type: AnswerType.Text,
|
values: item.question,
|
},
|
isChecked: false,
|
} as ChatMessage;
|
});
|
const resList = await Promise.all(
|
(userMsg ?? []).map((item, index) => {
|
userItemIdMap.set(index, item);
|
return getAnswerById(item.history_id);
|
})
|
);
|
let i = 0;
|
resList.map((item, index) => {
|
const insertIndex = index + 1 + i;
|
const currentUserMsg = tmpMessageList[insertIndex - 1];
|
currentUserMsg.content.values = item?.answer?.question ?? currentUserMsg.content.values;
|
const attachList = convertAttach(item?.answer);
|
currentUserMsg.attachList = attachList;
|
const mapUser = userItemIdMap.get(index);
|
const historyId = mapUser?.history_id;
|
|
const answerTime = formatShowTimeYear(mapUser?.create_time);
|
|
tmpMessageList.splice(
|
insertIndex,
|
0,
|
item.answer === null
|
? null
|
: {
|
historyId: historyId,
|
role: RoleEnum.assistant,
|
content: parseContent(item?.answer),
|
state: item.answer_state,
|
createTime: answerTime,
|
isStopMsg: false,
|
// stepGroup: (item?.answer?.reports ?? []).map((item) => ({
|
// value: convertProcessToStep(item?.exec_process),
|
// isShow: false,
|
// }))
|
stepGroup: getStepGroupList(item?.answer?.reports ?? []),
|
|
conclusion: item?.answer?.conclusion ?? [],
|
isChecked: false,
|
}
|
);
|
i++;
|
});
|
|
return tmpMessageList;
|
};
|
const convertProcessItem = (processItem: any) => {
|
switch (processItem.mode) {
|
case 'begin':
|
break;
|
case 'end':
|
break;
|
}
|
return {
|
status: StepEnum.Success,
|
title: processItem.value,
|
} as StepItem;
|
};
|
const convertProcessToStep = (process: any[], isHistory = true) => {
|
let streamIsStart = false;
|
|
const stepList = (process ?? []).reduce((preVal, curVal) => {
|
if (curVal.mode === 'question') {
|
if (isHistory) return preVal;
|
const last = preVal.at(-1);
|
if (!last.subStep) {
|
last.subStep = [];
|
}
|
const sub = {
|
data: curVal.value,
|
type: MultiChatType.Select,
|
};
|
last.subStep.push(sub);
|
} else if (curVal.mode === 'begin_stream') {
|
streamIsStart = true;
|
const cur = convertProcessItem(curVal);
|
preVal.push(cur);
|
} else if (curVal.mode === 'end_stream') {
|
streamIsStart = false;
|
} else if (streamIsStart) {
|
const last = preVal.at(-1);
|
last.title += curVal.value;
|
} else {
|
const cur = convertProcessItem(curVal);
|
preVal.push(cur);
|
}
|
return preVal;
|
}, []);
|
return stepList;
|
};
|
return {
|
loadReplyData,
|
parseContent,
|
parseExtraContent,
|
convertProcessToStep,
|
convertProcessItem,
|
formatShowTimeYear,
|
getStepGroupList,
|
convertAttach,
|
};
|
};
|