flat:AI+
This commit is contained in:
291
stores/userChatGroupStore.js
Normal file
291
stores/userChatGroupStore.js
Normal file
@@ -0,0 +1,291 @@
|
||||
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); // 先占位
|
||||
|
||||
let fullText = ''; // 存储完整的响应内容
|
||||
|
||||
function handleUnload() {
|
||||
newMsg.text = fullText
|
||||
newMsg.parentGroupId = chatSessionID.value
|
||||
baseDB.db.add(massageName.value, newMsg);
|
||||
}
|
||||
// 添加事件监听
|
||||
window.addEventListener("unload", handleUnload);
|
||||
|
||||
// 实时数据渲染
|
||||
function onDataReceived(data) {
|
||||
// const parsedData = safeParseJSON(data);
|
||||
fullText += data; // 累积完整内容
|
||||
newMsg.displayText += data; // 逐步更新 UI
|
||||
messages.value[index] = {
|
||||
...newMsg
|
||||
}; // 触发视图更新
|
||||
progress && progress()
|
||||
}
|
||||
|
||||
// 异常处理
|
||||
function onError(error) {
|
||||
console.error('请求异常:', error);
|
||||
msg('服务响应异常')
|
||||
reject(error);
|
||||
}
|
||||
|
||||
// 完成处理
|
||||
function onComplete() {
|
||||
newMsg.text = fullText; // 保存完整响应
|
||||
messages.value[index] = {
|
||||
...newMsg
|
||||
};
|
||||
toggleTyping(false);
|
||||
window.removeEventListener("unload", handleUnload);
|
||||
handleUnload()
|
||||
resolve && 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)
|
||||
}
|
||||
}
|
||||
arr.push({
|
||||
parentGroupId: sessionId,
|
||||
displayText: text,
|
||||
self: self,
|
||||
text: text,
|
||||
dataId: element.dataId,
|
||||
files,
|
||||
})
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
return {
|
||||
messages,
|
||||
isTyping,
|
||||
textInput,
|
||||
chatSessionID,
|
||||
addMessage,
|
||||
tabeList,
|
||||
init,
|
||||
initMessage,
|
||||
toggleTyping,
|
||||
addTabel,
|
||||
addNewDialogue,
|
||||
changeDialogue,
|
||||
getStearm,
|
||||
getHistory,
|
||||
};
|
||||
});
|
||||
|
||||
function safeParseJSON(data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch {
|
||||
return null; // 解析失败,返回 null
|
||||
}
|
||||
}
|
||||
|
||||
export default useChatGroupDBStore
|
Reference in New Issue
Block a user