123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- <!-- Chat.vue -->
- <template>
- <div class="chat-container items-center">
- <div v-if="!messages.length && !msgLoading" class="message-list">
- <pageMask />
- </div>
- <!-- 消息列表 -->
- <div class="message-list w-full" v-else>
- <el-scrollbar ref="scrollbar" @scroll="handleScroll" v-loading="msgLoading">
- <!-- 加载更多指示器 -->
- <div v-if="isLoadingMore" class="loading-more-indicator">
- <div class="loading-spinner"></div>
- <span>加载更多消息...</span>
- </div>
- <div class="messages" ref="messagesContainer">
- <div v-for="(message, index) in messages" :key="index"
- :class="['message-item', message.role === 'user' ? 'self' : 'other']">
- <el-avatar :size="32" :src="message.role === 'user' ? userAvatar : avatar" />
- <div class="message-content">
- <div class="content" v-if="message.role === 'system'"
- :class="{ 'loading-content': message.content === '' }">
- <formTable v-if="message.type === 'form'" :content="message.rawContent" />
- <div v-else>
- <div v-html="compiledMarkdown(message.rawContent)" class="markdown-body"
- style="font-size: small"></div>
- <!-- <link rel="stylesheet" href="/node_modules/github-markdown-css/github-markdown-dark.css"> -->
- </div>
- <span class="loading-indicator" v-if="sendLoading && index === messages.length - 1">
- <span class="dot"></span>
- <span class="dot"></span>
- <span class="dot"></span>
- </span>
- </div>
- <document v-else-if="message.type === 'document' && message.role === 'user'" :content="message.content"
- :rawContent="message.rawContent" />
- <div v-else class="content">
- <span v-if="message.type === ''">{{ message.content }}</span>
- <span class="loading-indicator" v-if="sendLoading && index === messages.length - 1">
- <span class="dot"></span>
- <span class="dot"></span>
- <span class="dot"></span>
- </span>
- </div>
- <div class="timestamp ">{{ moment(message.sortKey).format('MM-DD HH:mm') }}
- <!-- <span v-if="message.add" style="cursor: pointer;" @click="handleInput">填充</span> -->
- </div>
- </div>
- </div>
- </div>
- </el-scrollbar>
- <ScrollToBottom :target="scrollbar" ref="scrollToBottomRef" />
- </div>
- <Tools :disHistory="sendLoading" :upload="type === FunctionList.File_Operation || !!formInfo"
- @read-click="readClick" @upload-file="(file) => createFileObj(file)" @handle-capture="handleCapture"
- @his-records="hisRecords"
- @add-new-dialogue="addNewDialogue" @handle-current-change="handleCurrentChange"
- @handel-intelligent-filling-click="handelIntelligentFillingClick" />
- <div class="w-full max-w-[720px] p-[0_12px_12px]">
- <!-- 输入区域 -->
- <div class="input-area w-full">
- <el-icon class="closeShow" :style="{ display: isShowPage ? 'block' : 'none' }" size="16px" color="#909399"
- @click="closePageInfo">
- <CircleClose />
- </el-icon>
- <div v-show="isShowPage" style="border-bottom: 1px solid #F0F0F0;">
- <div class="card_list">
- <template v-for="(v, i) in pageInfoList" :key="i">
- <div class="card_image " v-if="v.type === 'image'">
- <el-image v-loading="v.isUpload" class="w-full h-full p-0.5 object-cover" :src="v.url" :zoom-rate="1.2"
- :max-scale="7" :min-scale="0.2" :preview-src-list="[v.url]" :initial-index="4" fit="cover" />
- <el-icon class="closeIcon" size="16px" color="#909399" @click="deletePageInfo(i)">
- <CircleClose />
- </el-icon>
- </div>
- <div v-else :class="`card-content ${pageInfoList.length > 1 ? 'card_width' : ''}`">
- <div class="loading-more-indicator" v-if="v.loading">
- <div class="loading-spinner"></div>
- </div>
- <img v-else :src="v?.favIconUrl" style="width: 24px;display: block" />
- <div class="title-wrapper">
- <span class="els title-scroller">{{ v?.title }}</span>
- <span class="els url-scroller">{{ v.loading ? v?.state : v?.url }}</span>
- </div>
- <el-icon class="closeIcon" size="16px" color="#909399" @click="deletePageInfo(i)">
- <CircleClose />
- </el-icon>
- </div>
- </template>
- <div v-show="!pageInfoList.length && type === FunctionList.Intelligent_Form_filling">智能填表</div>
- </div>
- <div class="card-btn">
- <el-tooltip content="总结" placement="top">
- <el-button :disabled="disabledBtn" v-if="type !== FunctionList.Intelligent_Form_filling" round
- @click="handleSummary">总结
- </el-button>
- </el-tooltip>
- <el-tooltip content="抽取表单信息" placement="top">
- <el-button :disabled="disabledBtn"
- v-if="type === FunctionList.Intelligent_Form_filling && pageInfoList.length" round
- @click="handleSummaryFile">抽取
- </el-button>
- </el-tooltip>
- </div>
- </div>
- <el-input ref="textareaRef" v-model="inputMessage" type="textarea" :rows="3" placeholder="输入消息..."
- @keyup.enter="() => handleAsk()" />
- <div class="chat_area_op">
- <el-button v-if="sendLoading" style="background-color:#ffffff;border:2px solid rgb(134 143 153);" circle
- @click="handleStopAsk">
- <svg-icon icon-class="stop" color="red" />
- </el-button>
- <el-button
- v-else
- :style="`background-color:${inputMessage.trim() ? '#4d6bfe' : '#d6dee8'};border-color:${inputMessage.trim() ? '#4d6bfe' : '#d6dee8'}`"
- type="primary" circle @click="() => handleAsk()"
- :disabled="disSend">
- <svg-icon icon-class="send" color="#000000" />
- </el-button>
- </div>
- </div>
- </div>
- <!-- 历史记录 -->
- <historyComponent :msgUuid="msgUuid" ref="historyComponentRef" @currentData="(e) => handleCurrentData(e)" />
- </div>
- </template>
- <script setup>
- import { ref, onMounted, nextTick, inject, useTemplateRef, reactive, onBeforeMount } from 'vue'
- import { ElScrollbar, ElAvatar, ElInput, ElButton } from 'element-plus'
- import moment from 'moment'
- import fileLogo from '@/assets/svg/file.svg'
- import {
- getFileContent,
- buildObjPrompt,
- controllerList,
- formatMessage
- } from '@/entrypoints/sidepanel/utils/ai-service.js'
- import { storeToRefs } from 'pinia'
- import { ElMessage } from 'element-plus'
- import { useMsg } from '@/entrypoints/sidepanel/hook/useMsg.ts'
- import Tools from '@/entrypoints/sidepanel/component/tools.vue'
- import historyComponent from '@/entrypoints/sidepanel/component/historyComponent.vue'
- import document from '@/entrypoints/sidepanel/component/document.vue'
- import pageMask from '@/entrypoints/sidepanel/component/pageMask.vue'
- import ScrollToBottom from '@/entrypoints/sidepanel/component/ScrollToBottom.vue'
- import formTable from '@/entrypoints/sidepanel/component/formTable.vue'
- import userAvatar from '@/assets/images/user.png'
- import avatar from '@/public/icon/icon.png'
- import { FunctionList } from '@/entrypoints/sidepanel/mock'
- import { useAutoResizeTextarea } from '@/entrypoints/sidepanel/hook/useAutoResizeTextarea.ts'
- import { getPageInfo, getPageInfoClean, handleInput, downloadFile } from './utils/index.js'
- import { useMsgStore } from '@/store/modules/msg.ts'
- import { useUserStore } from '@/store/modules/user'
- import { putChat, uploadFile } from "@/api/index.js";
- import {askQues,getFormKey} from '@/api/model.js'
- import { debounce } from 'lodash'
- import { renderMarkdown } from './utils/markdown.js'
- import 'github-markdown-css'
- // import "/node_modules/github-markdown-css/github-markdown-dark.css"
- const userStore = useUserStore()
- // 在其他状态变量附近添加
- const isLoadingMore = ref(false)
- import { v4 as uuidv4 } from 'uuid'
- import { browser } from 'wxt/browser'
- // 滚动条引用
- const scrollbar = ref(null)
- const scrollToBottomRef = ref(null)
- const xlsxData = ref({})
- const isShowPage = ref(false)
- const tareRef = useTemplateRef('textareaRef')
- const drawerRef = useTemplateRef('historyComponentRef')
- const disSend = computed(() => {
- if (pageInfoList.value.length && type.value === FunctionList.Intelligent_Form_filling) return true
- if (sendLoading.value) return true
- if (inputMessage.value.trim()) return false
- return true
- })
- // 获取父组件提供的 Hook 实例
- const msgStore = useMsgStore()
- const { pageInfoList, messages, msgUuid, AIModel, page, hasNext, msgLoading, selectModal } = storeToRefs(useMsgStore())
- const formInfo = ref('')
- const {
- taklToHtml,
- sendLoading,
- type,
- fetchRes
- } = useMsg(scrollbar)
- const inputMessage = ref('')
- const pageInfo = ref('')
- const summaryHtml = ref(false)
- const compiledMarkdown = computed(() => {
- return (val) => {
- return renderMarkdown(val)
- }
- })
- function handleStopAsk() {
- inputMessage.value = ''
- pageInfoList.value = []
- isShowPage.value = false
- taklToHtml.value = false
- type.value = FunctionList.File_Operation
- controllerList.value[0]?.abort()
- controllerList.value = []
- sendLoading.value = false
- formInfo.value = null
- }
- function handleScroll(a) {
- const { wrapRef } = scrollbar.value
- const { scrollHeight, clientHeight } = wrapRef
- scrollToBottomRef.value.showButton = scrollHeight - a.scrollTop - clientHeight >= 350
- // 检测是否滚动到顶部
- if (a.scrollTop <= 10 && hasNext.value) {
- handleScrollToTop()
- }
- }
- const messagesContainer = ref(null)
- let innerText = ''
- // 处理滚动到顶部的事件
- const handleScrollToTop = debounce(async function() {
- console.log('滚动到顶部,可以加载更多历史消息')
- if (!sendLoading.value && !isLoadingMore.value) {
- isLoadingMore.value = true
- try {
- // 记录当前第一条消息的位置
- const firstMessage = messagesContainer.value?.firstElementChild.querySelector('.timestamp')
- innerText = firstMessage.innerText
- const oldHeight = firstMessage?.offsetTop || 0
- await msgStore.changePage()
- setTimeout(() => {
- if (firstMessage) {
- console.log([...messagesContainer.value.querySelectorAll('.timestamp')].find(_ => _.innerText === innerText).offsetTop, innerText, 778)
- const newHeight = [...messagesContainer.value.querySelectorAll('.timestamp')].find(_ => _.innerText === innerText).offsetTop
- const scrollOffset = newHeight - oldHeight
- scrollbar.value?.setScrollTop(scrollOffset)
- }
- }, 400)
- // 恢复滚动位置
- } finally {
- isLoadingMore.value = false
- }
- }
- }, 500, { leading: false, trailing: true })
- /**
- * @param {string} msg
- * @param {string} raw
- * @param {string} type 发送的类型 document 、text
- * **/
- async function addMessage(msg, raw, type) {
- const newMessage = reactive({
- id: +new Date(),
- type: type || '',
- rawContent: raw ?? msg,
- senderId: userStore.userInfo.id,
- receiverId: -1, //大模型
- content: msg,
- sortKey: moment().valueOf(),
- role: 'user',
- conversationId: msgUuid.value,
- addToHistory: `${!taklToHtml.value}`,
- redisKey: undefined,
- fileId: undefined
- })
- if (type === 'document') {
- newMessage.content = msg
- newMessage.rawContent = raw
- }
- if (!msg) return
- messages.value.push(newMessage)
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- return newMessage
- }
- const handleSummary = async () => {
- if (sendLoading.value) return
- handleAsk(`请帮我总结当前${summaryHtml.value ? '页面' : '文件'}`)
- summaryHtml.value = false
- }
- const handleSummaryFile = async () => {
- if (sendLoading.value) return
- try {
- sendLoading.value = true
- const userMsg = await addMessage(JSON.stringify([...pageInfoList.value, {
- type: 'text',
- value: '抽取表单'
- }]), '抽取表单', 'document')
- userMsg.fileId = pageInfoList.value[0].fileId
- userMsg.redisKey = pageInfoList.value[0].redisKey
- await putChat(userMsg)
- createWS(userMsg)
- formInfo.value = ''
- // const msg = reactive({
- // type: '',
- // rawContent: '',
- // senderId: -1,
- // receiverId: userStore.userInfo.id, //大模型
- // content: '',
- // sortKey: moment().valueOf(),
- // role: 'system',
- // conversationId: msgUuid.value,
- // })
- // messages.value.push(msg)
- // isShowPage.value = false
- pageInfoList.value = []
- // const resForm = await askQues({
- // conversationId: msgUuid.value,
- // modelName: '通义千问-Max',
- // question: buildObjPrompt(xlsxData.value,formInfo.value),
- // id: '699637194561691650',
- // // redisKey:msg.redisKey
- // })
- // return console.log(resForm);
- } catch (error) {
- console.log(error)
- } finally {
- // sendLoading.value = false
- // type.value = FunctionList.File_Operation
- }
- }
- async function handelIntelligentFillingClick() {
- handleInput()
- isShowPage.value = true
- // taklToHtml.value = true
- // const tempPageInfo = await getPageInfo()
- // pageInfo.value = tempPageInfo
- // pageInfoList.value = [tempPageInfo]
- inputMessage.value = '/智能填表 '
- type.value = FunctionList.Intelligent_Form_filling
- }
- function handleCurrentChange(e) {
- msgStore.updateAIModel(e)
- }
- async function handleCurrentData(e) {
- drawerRef.value.drawer = false
- isShowPage.value = false
- if (!e) {
- addNewDialogue()
- return
- }
- messages.value = []
- page.value = 1
- msgUuid.value = e
- chrome.storage.local.set({ msgUuid: msgUuid.value })
- await msgStore.initMsg()
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- }
- let SystemMsg = null
- watchEffect(() => {
- console.log(isShowPage.value)
- if (!isShowPage.value) {
- summaryHtml.value = false
- type.value = FunctionList.File_Operation
- SystemMsg = null
- inputMessage.value = ''
- }
- })
- const htmlIcon = ref('')
- async function readClick() {
- if (type.value === FunctionList.Intelligent_Form_filling) {
- pageInfoList.value = []
- type.value = FunctionList.File_Operation
- }
- summaryHtml.value = true
- isShowPage.value = true
- taklToHtml.value = true
- if (pageInfoList.value.length >= Number(import.meta.env.VITE_MAX_FILE_NUMBER)) {
- ElMessage.warning(`最多添加${import.meta.env.VITE_MAX_FILE_NUMBER}个文件`)
- return
- }
- const tempPageInfo = await getPageInfo()
- htmlIcon.value = tempPageInfo.favIconUrl
- const blob = new Blob([tempPageInfo.content.mainContent], { type: 'text/plain' })
- const file = new File([blob], '页面' + '.txt', { type: 'text/plain' })
- // console.log(file);
- // 下载文件到本地
- // downloadFile(file);
- console.log(tempPageInfo)
- await createFileObj(file)
- // await handleUpload(file,tempPageInfo.title + '.txt')
- }
- // 添加下载文件的函数
- function deletePageInfo(i) {
- pageInfoList.value.splice(i, 1)
- if (pageInfoList.value.length === 0) {
- if (type.value === FunctionList.Intelligent_Form_filling) {
- inputMessage.value = ''
- SystemMsg.content = '智能填表流程中断'
- SystemMsg.rawContent = '智能填表流程中断'
- putChat({
- ...SystemMsg,
- content: ''
- })
- }
- handleStopAsk()
- }
- }
- function addNewDialogue() {
- if (messages.value.length === 0) {
- ElMessage.warning('已经是新对话')
- return
- }
- summaryHtml.value = false
- type.value = FunctionList.File_Operation
- isShowPage.value = false
- taklToHtml.value = false
- messages.value = []
- page.value = 1
- pageInfoList.value = []
- msgUuid.value = uuidv4()
- hasNext.value = false
- chrome.storage.local.set({ msgUuid: msgUuid.value })
- }
- const disabledBtn = computed(() => {
- return !!(pageInfoList.value.find(_ => _.loading))
- })
- function closePageInfo() {
- pageInfoList.value = []
- if (type.value === FunctionList.Intelligent_Form_filling && SystemMsg) {
- SystemMsg.content = '智能填表流程中断'
- SystemMsg.rawContent = '智能填表流程中断'
- putChat({
- ...SystemMsg,
- content: ''
- })
- }
- handleStopAsk()
- }
- async function handleAsk(value) {
- if (sendLoading.value) return
- const str = value ?? inputMessage.value.trim()
- inputMessage.value = ''
- if (type.value === FunctionList.Intelligent_Form_filling) {
- const msg = await addMessage(str)
- await putChat(msg)
- const [res, obj] = await fetchRes(str)
- if (res.status === 'ok') {
- console.log(obj)
- formInfo.value = res.data
- SystemMsg = obj
- } else {
- type.value = FunctionList.File_Operation
- isShowPage.value = false
- }
- return
- }
- if (sendLoading.value) return
- let msg = null
- if (pageInfoList.value.length) {
- msg = await addMessage(JSON.stringify([...pageInfoList.value, { type: 'text', value: str }]), str, 'document')
- msg.fileId = pageInfoList.value[0].fileId
- msg.redisKey = pageInfoList.value[0].redisKey
- } else msg = await addMessage(str)
- pageInfoList.value = []
- isShowPage.value = false
- await putChat(msg)
- createWS(msg)
- }
- /**
- *
- * @param msg 用户消息对象,调用askQues时需要
- */
- async function createWS(msg) {
- sendLoading.value = true
- const obj = reactive({
- type: type.value === FunctionList.Intelligent_Form_filling ? 'form' : '',
- rawContent: '',
- senderId: -1,
- receiverId: userStore.userInfo.id, //大模型
- content: '',
- sortKey: moment().valueOf(),
- role: 'system',
- conversationId: msgUuid.value
- })
- try {
- messages.value.push(obj)
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- const websocketId = uuidv4()
- const wsUrl = `${import.meta.env.VITE_API_WS_URL}/webSocket/clue/${websocketId}`
- const socket = new WebSocket(wsUrl)
- console.log(selectModal.value)
- askQues({
- conversationId: msgUuid.value,
- websocketId,
- modelName: selectModal.value.modelName,
- question: type.value === FunctionList.File_Operation ? msg.rawContent : buildObjPrompt(xlsxData.value, formInfo.value),
- id: selectModal.value.id,
- redisKey: msg.redisKey
- }).catch(res => {
- obj.rawContent = '接口出错,请重试。'
- obj.content = '接口出错,请重试。'
- socket.close()
- })
- socket.onmessage = (event) => {
- try {
- if (event.data === '') {
- console.log(23223)
- socket.close()
- if (type.value === FunctionList.Intelligent_Form_filling) {
- const formResult = obj.rawContent
- let form = null
- if (formResult.includes('json')) form = JSON.parse(formResult.split('json')[1].split('```')[0])
- else form = JSON.parse(formResult)
- sendLoading.value = false
- console.log(xlsxData.value, form)
- handleInput(xlsxData.value, form)
- }
- isShowPage.value = false
- } else {
- obj.rawContent += event.data
- obj.content = obj.type === 'form' ? obj.rawContent : formatMessage(obj.rawContent)
- // 滚动到底部
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- }
- } catch (error) {
- console.error('解析消息出错:', error)
- }
- }
- socket.onerror = (error) => {
- console.error('WebSocket 错误:', error)
- socket.close()
- }
- socket.onclose = () => {
- console.log('WebSocket 连接已关闭')
- sendLoading.value = false
- putChat({
- ...obj,
- content: ''
- })
- sendLoading.value = false
- controllerList.value = []
- type.value = FunctionList.File_Operation
- }
- // 添加到控制器列表,以便可以在需要时中断连接
- controllerList.value.push({
- abort: () => {
- socket.close()
- }
- })
- } catch (error) {
- console.error(error)
- sendLoading.value = false
- // 显示错误消息
- obj.content = '连接失败,请重试'
- putChat({
- ...obj,
- content: ''
- })
- } finally {
- }
- }
- function handleCapture() {
- browser.tabs.query({ active: true, currentWindow: true }).then(tabs => {
- if (tabs.length === 0) {
- ElMessage.warning('请先打开一个页面')
- return
- }
- // sendMessage('SCREENSHOT', { t: 'Start taking screenshots' }, `content-script@${tabs[0].id}`)
- })
- // chrome.runtime.sendMessage({
- // type: 'SCREENSHOT',
- // data: 'Start taking screenshots'
- // }, (response) => {
- // if (response.status === 'ok') {
- // isShowPage.value = true
- // pageInfoList.value.unshift({
- // isUpload: false,
- // fileId: '',
- // type: 'image',
- // url: response.data
- // })
- // // console.log(response);
- // // console.log(response, pageInfoList.value)
- // }
- // })
- }
- function hisRecords() {
- drawerRef.value.drawer = true
- console.log(123)
- }
- const createFileObj = async (file) => {
- handleUpload(file)
- }
- const handleUpload = async (file) => {
- const obj = reactive({
- title: summaryHtml.value ? file.name.split('.')[0] : file.name,
- state: '上传中...',
- favIconUrl: fileLogo,
- loading: true,
- url: '',
- fileId: '',
- redisKey: '',
- content: {
- mainContent: ''
- }
- })
- if (type.value === FunctionList.Intelligent_Form_filling) {
- pageInfoList.value = []
- }
- if (summaryHtml.value) obj.favIconUrl = htmlIcon.value
- isShowPage.value = true
- // const obj = reactive({
- // title: file.name,
- // state: '上传中...',
- // favIconUrl: fileLogo,
- // loading: true,
- // url:'',
- // fileId: '',
- // redisKey:'',
- // content: {
- // mainContent: ''
- // }
- // })
- pageInfoList.value = [obj]
- try {
- let formData = new FormData()
- formData.append('avatarFile', file)
- const res = await uploadFile(formData)
- if (type.value === FunctionList.Intelligent_Form_filling) {
- obj.state = '解析中...'
- obj.redisKey = res.data.redisKey
- obj.id = res.data.file.id
- obj.url = res.data.file.url
- // const fileExtension = file.name.split('.').pop().toLowerCase()
- const result = await getFormKey({
- body: formInfo.value,
- input_data: res.data.data
- })
- xlsxData.value = JSON.parse(result.data)
- // if (fileExtension === 'xlsx') {
- // const readData = await getXlsxValue(file)
- // readData[0].forEach((header, i) => {
- // // if (!xlsxData.value[header]) xlsxData.value[header] = []
- // xlsxData.value[header] = readData[1][i]
- // })
- // } else {
- // const result = await getFormKey({
- // body: formInfo.value,
- // input_data:res.data.data
- // })
- // xlsxData.value = JSON.parse(result.data)
- // }
- }
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- if (type.value === FunctionList.File_Operation) {
- obj.loading = false
- obj.url = res.data.url
- obj.redisKey = res.data.redisKey
- obj.fileId = res.data.file.id
- obj.url = res.data.file.url
- }
- obj.loading = false
- console.log(SystemMsg)
- } catch (error) {
- if (SystemMsg) {
- SystemMsg.content = '数据上传出错,请重试'
- SystemMsg.rawContent = '数据上传出错,请重试'
- }
- console.log(error)
- ElMessage.error('上传出错')
- pageInfoList.value = []
- isShowPage.value = false
- } finally {
- SystemMsg && putChat({
- ...SystemMsg,
- content: ''
- })
- SystemMsg = null
- }
- }
- async function getFileValue(file) {
- let formData = new FormData()
- formData.append('file', file)
- const res = await getFileContent(formData)
- return res.data
- }
- let a = null
- // 组件挂载时滚动到底部
- onBeforeMount(async () => {
- await msgStore.initMsg()
- await msgStore.initModal()
- })
- onMounted(async () => {
- useAutoResizeTextarea(tareRef, inputMessage)
- chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
- if (message.type === 'TO_SIDE_PANEL_PAGE_INFO') {
- pageInfo.value = message.data
- // 转发到 content.js
- chrome.tabs.sendMessage(sender.tab.id, {
- type: 'TO_CONTENT_SCRIPT',
- data: message.data
- })
- }
- if (message.type === 'TO_SIDE_PANEL_PAGE_CHANGE') {
- pageInfo.value = message.data
- }
- })
- nextTick(() => {
- if (scrollbar.value && scrollbar.value.wrapRef) {
- scrollbar.value.setScrollTop(scrollbar.value.wrapRef.scrollHeight)
- }
- })
- })
- </script>
- <style lang="scss" scoped>
- @use '@/entrypoints/sidepanel/css/chat.scss';
- @use '@/entrypoints/sidepanel/css/markdown.scss';
- .loading-more-indicator {
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 10px 0;
- color: #909399;
- font-size: 14px;
- .loading-spinner {
- width: 20px;
- height: 20px;
- margin-right: 8px;
- border: 2px solid #e6e6e6;
- border-top-color: #4d6bfe;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- }
- }
- @keyframes spin {
- to {
- transform: rotate(360deg);
- }
- }
- </style>
|