Files
ks-app-employment-service/stores/userChatGroupStore.js
2025-04-07 09:10:55 +08:00

317 lines
9.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
defineStore
} from 'pinia';
import {
reactive,
ref
} from 'vue'
import IndexedDBHelper from '@/common/IndexedDBHelper.js'
import baseDB from './BaseDBStore';
import {
msg,
CloneDeep,
$api,
formatDate,
insertSortData
} from '../common/globalFunction';
import {
UUID
} from '../lib/uuid-min';
import config from '../config';
const useChatGroupDBStore = defineStore("messageGroup", () => {
const tableName = ref('messageGroup')
const massageName = ref('messages')
const messages = ref([]) // 消息列表
const isTyping = ref(false) // 是否正在输入
const textInput = ref('')
// tabel
const tabeList = ref([])
const chatSessionID = ref('')
const lastDateRef = ref('')
// const groupPages = reactive({
// page: 0,
// total: 0,
// maxPage: 2,
// pageSize: 50,
// })
async function init() {
// 获取所有数据
setTimeout(async () => {
if (!baseDB.isDBReady) await baseDB.initDB();
const result = await baseDB.db.getAll(tableName.value);
// 1、判断是否有数据没数据请求服务器
if (result.length) {
console.warn('本地数据库存在数据')
const list = result.reverse()
const [table, lastData] = insertSortData(list)
tabeList.value = table
const tabelRow = list[0]
chatSessionID.value = tabelRow.sessionId
initMessage(tabelRow.sessionId)
} else {
console.warn('本地数据库存在数据')
// getHistory('refresh')
}
}, 1000)
}
async function initMessage(sessionId) {
if (!baseDB.isDBReady) await baseDB.initDB();
chatSessionID.value = sessionId
const list = await baseDB.db.queryByField(massageName.value, 'parentGroupId', sessionId);
if (list.length) {
console.log('本地数据库存在该对话数据', list)
messages.value = list
} else {
console.log('本地数据库不存在该对话数据')
getHistoryRecord('refresh')
}
}
async function addMessage(payload) {
if (!chatSessionID.value) {
return msg('请创建对话')
}
const params = {
...payload,
parentGroupId: chatSessionID.value,
files: payload.files || [],
}
messages.value.push(params);
addMessageIndexdb(params)
}
function toggleTyping(status) {
isTyping.value = status
}
async function addTabel(text) {
if (!baseDB.isDBReady) await baseDB.initDB();
const uuid = UUID.generate() // 对话sessionId
let payload = {
title: text,
createTime: formatDate(Date.now()),
sessionId: uuid
}
const id = await baseDB.db.add(tableName.value, payload);
const list = await baseDB.db.getAll(tableName.value);
chatSessionID.value = uuid
const [result, lastData] = insertSortData(list)
tabeList.value = result
return id
}
async function addMessageIndexdb(payload) {
console.log(payload)
return await baseDB.db.add(massageName.value, payload);
}
async function getStearm(text, fileUrls = [], progress) {
return new Promise((resolve, reject) => {
try {
toggleTyping(true);
const params = {
data: text,
sessionId: chatSessionID.value,
};
if (fileUrls && fileUrls.length) {
params['fileUrl'] = fileUrls.map((item) => item.url);
}
const newMsg = {
text: [], // 存储原始结构化内容
self: false,
displayText: '' // 用于流式渲染展示
};
const index = messages.value.length;
messages.value.push(newMsg);
const rawParts = Array.isArray(text) ? text : [text]; // 统一处理
// 用于追加每个部分的流式数据
let partIndex = 0;
function handleUnload() {
newMsg.parentGroupId = chatSessionID.value;
baseDB.db.add(massageName.value, newMsg);
}
window.addEventListener("unload", handleUnload);
function renderPart(part) {
if (typeof part === 'string') {
newMsg.displayText += part;
} else if (typeof part === 'object' && part.type === 'highlight') {
consol.log('自定义样式')
newMsg.displayText += `<span class="highlight">${part.content}</span>`;
} else {
newMsg.displayText += String(part); // 兜底
}
}
function onDataReceived(data) {
let parsed;
try {
parsed = JSON.parse(data);
} catch {
parsed = data;
}
// 支持追加多个部分
if (Array.isArray(parsed)) {
parsed.forEach((part) => {
newMsg.text.push(part); // 存结构
renderPart(part); // 渲染显示
});
} else {
newMsg.text.push(parsed);
renderPart(parsed);
}
messages.value[index] = {
...newMsg
};
progress && progress();
}
function onError(error) {
msg('服务响应异常');
reject(error);
}
function onComplete() {
messages.value[index] = {
...newMsg
};
toggleTyping(false);
window.removeEventListener("unload", handleUnload);
handleUnload();
resolve();
}
$api.streamRequest('/chat', params, onDataReceived, onError, onComplete);
} catch (err) {
console.log(err);
reject(err);
}
});
}
// 状态控制
function addNewDialogue() {
chatSessionID.value = ''
messages.value = []
}
function changeDialogue(item) {
chatSessionID.value = item.sessionId
initMessage(item.sessionId)
}
// 云端数据
function getHistory() {
$api.chatRequest('/getHistory').then((res) => {
if (!res.data.list.length) return
let tabel = parseHistory(res.data.list)
if (tabel && tabel.length) {
const tabelRow = tabel[0] // 默认第一个
const [result, lastData] = insertSortData(tabel)
// console.log('getHistory insertSortData', result, lastData)
chatSessionID.value = tabelRow.sessionId
tabeList.value = result
getHistoryRecord(false)
baseDB.db.add(tableName.value, tabel);
lastDateRef.value = lastData
}
})
}
function getHistoryRecord(loading = true) {
const params = {
sessionId: chatSessionID.value
}
$api.chatRequest('/detail', params, 'GET', loading).then((res) => {
console.log('detail', res.data)
let list = parseHistoryDetail(res.data.list, chatSessionID.value)
if (list.length) {
messages.value = list
baseDB.db.add(massageName.value, list);
}
console.log('解析后:', list)
}).catch(() => {
msg('请求出现异常,请联系工作人员')
})
}
// 解析器
function parseHistory(list) {
return list.map((item) => ({
title: item.title,
createTime: item.updateTime,
sessionId: item.chatId
}))
}
function parseHistoryDetail(list, sessionId) {
const arr = []
for (let i = 0; i < list.length; i++) {
const element = list[i];
const self = element.obj !== 'AI'
let text = ''
let files = []
for (let j = 0; j < element.value.length; j++) {
const obj = element.value[j];
if (obj.type === 'text') {
text += obj.text.content
}
if (obj.type === 'file') {
files.push(obj.file)
}
if (obj.type === 'tool') {
console.log(obj)
}
}
arr.push({
parentGroupId: sessionId,
displayText: text,
self: self,
text: text,
dataId: element.dataId,
files,
})
}
return arr
}
return {
messages,
isTyping,
textInput,
chatSessionID,
addMessage,
tabeList,
init,
toggleTyping,
addTabel,
addNewDialogue,
changeDialogue,
getStearm,
getHistory,
};
});
function safeParseJSON(data) {
try {
return JSON.parse(data);
} catch {
return null; // 解析失败,返回 null
}
}
export default useChatGroupDBStore