// 消息数组 import { ref, reactive, nextTick, inject } from 'vue' import { storeToRefs } from 'pinia' import avator from '@/public/icon/32.png' import moment from 'moment' import { cloneDeep } from 'lodash' import { getFormKey, hepl, formatMessage, sendMessage } from '../utils/ai-service.js' import { ElMessage } from 'element-plus' import { getPageInfo, getFileValue } from '../utils/index.js' import { mockData, mockData2 } from '../mock' import { useMsgStore } from '@/store/modules/msg' import { FunctionList } from '../mock' export function useMsg(scrollbar?: any) { const { messages, msgUuid } = storeToRefs(useMsgStore()) const indexTemp = ref(0) const taklToHtml = ref(false) const sendLoading = ref(false) const pageInfo = ref({}) const type = ref(FunctionList.File_Operation) const formMap = ref([]) // 获取父组件提供的 Hook 实例 const { useStore } = inject('indexedDBHook') as any const getFormKeyAndValue = async (file: any, form?: any) => { // const obj = reactive({ // id: moment(), // username: '用户1', // rawContent: '', // content: '解析文件中', // timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), // isSelf: false, // avatar: avator, // addToHistory: !taklToHtml.value // }) try { sendLoading.value = true // messages.value.push(obj) const response = await getFormKey({ body: form, input_data: file }) return response } catch (error) { // obj.content = '解析出错' } finally { sendLoading.value = false } } // 发送消息 // const handleSend = async (msg: any) => { // if ( msg?.startsWith('/')) { // if (!taklToHtml.value) // return messages.value.push({ // id: messages.value.length + 1, // username: '用户1', // content: '请打开与页面对话!', // rawContent: '请打开与页面对话!', // timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), // isSelf: false, // avatar: avator, // addToHistory: false // }) // indexTemp.value = 0 // fetchRes(msg) // } // } async function awaitFindForm(obj: any) { return await new Promise((res, rej) => { chrome.runtime.sendMessage( { type: 'FROM_SIDE_PANEL_TO_GET_PAGE_FORM' }, ({ status, data }) => { if (status === 'error') { obj.content = '当前页面未找到表单' res({ status }) } if (status === 'ok') { obj.content = '请上传数据' res({ status, data }) } if (status === 'select') { obj.content = '检测到左侧页面中有多个表单,请选择要填写的表单。' function handle(message, sender, sendResponse) { if (message.type === 'TO_SIDE_PANEL_FORM_INFO') { console.log('收到一次性消息:', message.data) res({ status: 'ok', data: message.data }) obj.content = '请上传数据' console.log(565656) // 销毁监听器(确保只触发一次) chrome.runtime.onMessage.removeListener(handle) } } chrome.runtime.onMessage.addListener(handle) } } ) }) } const fetchRes = async (msg: any) => { indexTemp.value = 0 sendLoading.value = true const obj: any = reactive({ id: messages.value.length + 1, username: '用户1', content: '', timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), isSelf: false, avatar: avator, addToHistory: !taklToHtml.value }) messages.value.push(obj) msg = msg.split('/智能填表')[1] nextTick(() => scrollbar.value?.setScrollTop(99999)) if (!msg) { sendLoading.value = false const res = await awaitFindForm(obj) return res } try { const res = await fetchDataAndProcess(msg, obj) sendLoading.value = false if (res.status === 'ok') { await new Promise((res: any) => setTimeout(() => { res() }, 2000) ) const res = await awaitFindForm(obj) console.log(res,34444); return res } } catch (error) { obj.content = '流程链执行出错' return {status: 'error'} } finally { sendLoading.value = false } } let str = '' async function fetchDataAndProcess(input: any, obj: any) { str = input console.log(str) const pageInfo = await getPageInfo() await new Promise((res: any) => setTimeout(() => { res() }, 2000) ) // const res = await hepl({ // input_data: input, // body: pageInfo.content.mainContent // }) const res: any = await new Promise((resolve, reject) => { setTimeout(() => { resolve({ data: pageInfo.title === '智能招采' ? mockData[indexTemp.value] : mockData2[indexTemp.value] }) }, 1000) }) if (!res.data.tag || res.data.tag === 'undefined') { ElMessage({ message: '未找到标签,请重试', type: 'error', duration: 4 * 1000, grouping: true }) obj.content = '未找到标签,请重试' return { status: 'error' } } await new Promise((resolve) => setTimeout(resolve, 2000)) obj.content = `点击${res.data.tag}元素` const res2 = await new Promise((resolve, rej) => { chrome.runtime.sendMessage( { type: 'FROM_SIDE_PANEL_TO_ACTION', data: res.data }, async ({ data, status }) => { if (chrome.runtime.lastError) { console.error('消息发送错误:', chrome.runtime.lastError) } else { if (status === 'error') { obj.content = data resolve({ data, status }) console.log(222); } if (res.data.next === '是') { const arr = str.split(',') arr.shift() str = arr.join(',') indexTemp.value++ const res = await fetchDataAndProcess(str, obj) resolve(res) } else resolve({ status: 'ok' }) } } ) }) return res2 } /** * * @param addHtml 是否添加页面信息 */ const streamRes = async (addHtml: any = false) => { pageInfo.value = await getPageInfo() sendLoading.value = true const obj = reactive({ id: messages.value.length + 1, username: '用户1', content: '', type: '', // form 用于展示抽取的内容 rawContent: '', // 存储原始内容 timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), isSelf: false, avatar: avator, addToHistory: !taklToHtml.value }) let history = [] if (taklToHtml.value) { if (addHtml) { history.push({ role: 'user', content: `页面主要内容${pageInfo.value.content.mainContent}` }) } history.push({ role: 'user', content: messages.value[messages.value.length - 1].rawContent }) } else { history = messages.value .filter((item: any) => item.addToHistory) .slice(-20) .map((item: any) => ({ role: item.isSelf ? 'user' : 'system', content: item.rawContent })) } messages.value.push(obj) nextTick(() => { scrollbar.value?.setScrollTop(99999) }) try { const iterator = await sendMessage(history) for await (const chunk of iterator) { if (chunk) { const decodedChunk = chunk.choices[0].delta.content if (decodedChunk) { // 保存原始内容 obj.rawContent += decodedChunk // 实时格式化显示内容 obj.content = formatMessage(obj.rawContent) } } scrollbar.value?.setScrollTop(99999) } if (type.value === FunctionList.Intelligent_Form_filling) { obj.type = 'form' // } return {rawContent:obj.rawContent,status:'ok'} } catch (error) { obj.content = '网络出错' return { rawContent: obj.rawContent, status: 'error' } } finally { //添加到存储历史 useStore(msgUuid.value).add(cloneDeep(obj)) // 处理最终内容 sendLoading.value = false nextTick(() => { scrollbar.value?.setScrollTop(99999) }) } } /** * @param data 输入数据 * @returns true 成功 * @returns false 失败 * **/ async function requestFlowFn(data: any[]) { sendLoading.value = true const obj = reactive({ id: messages.value.length + 1, username: '用户1', content: '', rawContent: '', // 存储原始内容 timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), isSelf: false, avatar: avator, addToHistory: !taklToHtml.value }) messages.value.push(obj) scrollbar.value?.setScrollTop(99999) const iterator = await sendMessage(data) if (iterator.error) { // 实时格式化显示内容 obj.content = iterator.error sendLoading.value = false return false } else { for await (const chunk of iterator) { if (chunk) { const decodedChunk = chunk.choices[0].delta.content if (decodedChunk) { // 保存原始内容 obj.rawContent += decodedChunk // 实时格式化显示内容 obj.content = formatMessage(obj.rawContent) } } scrollbar.value?.setScrollTop(99999) } } //添加到存储历史 useStore(msgUuid.value).add(cloneDeep(obj)) // 处理最终内容 sendLoading.value = false await nextTick(() => { scrollbar.value?.setScrollTop(99999) }) return true } return { indexTemp, taklToHtml, sendLoading, type, fetchRes, streamRes, getFormKeyAndValue, requestFlowFn } }