| | |
| | | /> |
| | | </template> |
| | | <template #content> |
| | | <div :class="{ chartUserText: theme === 'light' }" |
| | | >{{ sessionDetail.content }} |
| | | <div :class="{ chartUserText: theme === 'light' }"> |
| | | {{ sessionDetail.content }} |
| | | <!-- <a-input |
| | | :style="{ width: '100%' }" |
| | | v-model="sessionDetail.content" |
| | | v-if="isEdit" |
| | | /> |
| | | |
| | | <div v-else> |
| | | {{ sessionDetail.content }} |
| | | </div> --> |
| | | </div> |
| | | <!-- <div v-if="!isEdit"> |
| | | <span |
| | | class="action" |
| | | v-if="index != 0" |
| | | @click="copy(sessionDetail.content)" |
| | | > |
| | | <icon-copy /> 复制 |
| | | </span> |
| | | <span class="action" @click="edit()"> |
| | | <icon-pen /> 编辑 |
| | | </span> |
| | | </div> |
| | | <a-space v-else> |
| | | <a-button type="outline" size="mini" @click="cancelEdit(1)" |
| | | >取消</a-button |
| | | > |
| | | <a-button type="primary" size="mini" @click="cancelEdit(2)" |
| | | >确定</a-button |
| | | > |
| | | </a-space> --> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment v-else-if="sessionDetail.role === 'assistant'"> |
| | |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none;" |
| | | v-for="(breakContent, breakIndex) in breakLine(sessionDetail.content)" |
| | | style="border: none" |
| | | v-for="(breakContent, breakIndex) in breakLine( |
| | | sessionDetail.content |
| | | )" |
| | | > |
| | | <div |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none;" |
| | | v-if="isExistTip(breakContent)"> |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | v-if="isExistTip(breakContent)" |
| | | > |
| | | <div |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none;" |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | v-for="(item, tipIndex) in tipMatch(breakContent)" |
| | | > |
| | | <span v-if="tipIndex == 0"> |
| | | {{ breakContent.substring(0, item.index) }} |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | </span> |
| | | <span v-else-if ="tipIndex == item.len - 1"> |
| | | {{ |
| | | <span v-if="tipIndex == 0"> |
| | | {{ breakContent.substring(0, item.index) }} |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | </span> |
| | | <span v-else-if="tipIndex == item.len - 1"> |
| | | {{ |
| | | breakContent.substring( |
| | | item.preIndex + item.item.length, |
| | | item.index |
| | | ) |
| | | }} |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | {{ |
| | | breakContent.substring(item.index+5) |
| | | }} |
| | | </span> |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | {{ breakContent.substring(item.index + 5) }} |
| | | </span> |
| | | <span v-else> |
| | | {{ |
| | | {{ |
| | | breakContent.substring( |
| | | item.preIndex + item.item.length, |
| | | item.index |
| | | ) |
| | | }} |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | </span> |
| | | <a-tooltip |
| | | background-color="#3491FA" |
| | | :content=" |
| | | getTipContent(messagenList.reference, index) |
| | | " |
| | | > |
| | | <img |
| | | style="width: 20px; height: 20px" |
| | | :src="tipImage" |
| | | /> |
| | | </a-tooltip> |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div v-else> |
| | |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="sessionDetail.content" |
| | | :default-value="chartText(sessionDetail.content)" |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | > |
| | | </a-textarea> |
| | | </a-card> |
| | | <!-- <div class="prompt"> |
| | | <ul> |
| | | <li class="prompt-item" @click="copyText('43234')"> |
| | | <span> |
| | | 344343klsdjkjksdjkjksdjk就开始大家看数据库登记卡受打击凯撒登记卡受打击凯撒登记卡受打击凯撒的43</span |
| | | > |
| | | <span style="margin-left: 20px"> |
| | | <icon-right /> |
| | | </span> |
| | | </li> |
| | | </ul> |
| | | </div> --> |
| | | </template> |
| | | <!-- <div>{{ sessionDetail.role === 'assistant' }}</div> --> |
| | | <template #actions> |
| | |
| | | > |
| | | <icon-refresh /> 重新生成 |
| | | </span> |
| | | <!-- <span class="action"><icon-to-bottom />下载 </span> --> |
| | | </template> |
| | | </a-comment> |
| | | <a-comment v-else-if="sessionDetail.role === 'last'"> |
| | |
| | | /> |
| | | </template> |
| | | <template #content> |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="displayedText" |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | > |
| | | </a-textarea> |
| | | <a-spin :loading="chartLoading" dot style="width: 100%"> |
| | | <a-textarea |
| | | readonly |
| | | auto-size |
| | | v-model="displayedText" |
| | | :class="{ chatItemAnswer: theme === 'light' }" |
| | | :style="{ |
| | | backgroundColor: |
| | | theme === 'light' ? '#ffffff' : '#000000', |
| | | }" |
| | | style="border: none" |
| | | > |
| | | </a-textarea> |
| | | </a-spin> |
| | | </template> |
| | | |
| | | <template #actions> |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | " |
| | | class="uploadFileDis" |
| | | > |
| | | <updataFile |
| | | ref="fileInput" |
| | | :sessionId="activeSessionId" |
| | | @selectFileCallback="selectFileCallback" |
| | | ></updataFile> |
| | | <!-- <uploadFile |
| | | ref="fileInput" |
| | | :handleRemove="handleRemove" |
| | | :typeXLse="false" |
| | | @selectFileCallback="selectFileCallback" |
| | | ></uploadFile> --> |
| | | |
| | | <a-button |
| | | :disabled="chatDis" |
| | | @click="sentClick" |
| | |
| | | ></smartAi> |
| | | </div> |
| | | </a-col> |
| | | <a-col :span="23" v-show="agentType == '5'"> |
| | | <div class="center"> |
| | | <seniorAgentSession :modalObj="agentObj"></seniorAgentSession> |
| | | </div> |
| | | </a-col> |
| | | </a-row> |
| | | <a-modal title=" " v-model:visible="fileVisible" :footer="false" fullscreen> |
| | | <!-- <docx previewSrc="http://192.168.20.116:1080/v1/document/get/405c3efa4d8c11ef97560242ac120006"></docx>--> |
| | |
| | | import chatMenu from '@/views/sessionManager/components/chatMenu.vue'; |
| | | import AddSession from '@/views/sessionManager/components/addSession.vue'; |
| | | import agentSession from '@/views/sessionManager/components/agentSession.vue'; |
| | | import seniorAgentSession from '@/views/sessionManager/components/seniorAgentSession.vue'; |
| | | import historySession from '@/views/sessionManager/components/historySession.vue'; |
| | | import smartAi from '@/views/sessionManager/components/smartAi.vue'; |
| | | import updataFile from '@/views/sessionManager/components/updataFile.vue'; |
| | | |
| | | import EventBus from '@/utils/EventBus'; |
| | | import { |
| | | addSessionApi, |
| | |
| | | getSessionDetailsApi, |
| | | sessionListApi, |
| | | uploadWithoutKb, |
| | | uploadAndParse, |
| | | chatInfos, |
| | | chatRm, |
| | | } from '@/api/session'; |
| | | import { getAuthorization } from '@/utils/auth'; |
| | | import { queryCanvasList } from '@/api/Agent'; |
| | |
| | | import docx from '@/views/dmx/knowledgeLib/components/docx.vue'; |
| | | import excel from '@/views/dmx/knowledgeLib/components/excel.vue'; |
| | | import txtPdf from '@/views/dmx/knowledgeLib/components/txtPdf.vue'; |
| | | import { is } from "immutable"; |
| | | import { is } from 'immutable'; |
| | | import uploadFile from './components/uploadFile.vue'; |
| | | |
| | | // const url = ref('../../assets/session/PDF.png'); |
| | | |
| | |
| | | const modalObj = reactive({ add: false }); |
| | | const dialogId = ref(''); |
| | | const chatDis = ref(false); |
| | | const chartLoading = ref(false); |
| | | const loading = ref(false); |
| | | const agentType = ref('1'); |
| | | const agentTitle = ref('未命名会话'); |
| | |
| | | const uploadRef = ref(); |
| | | const files = ref([]); |
| | | const file = ref(''); |
| | | const fileInput = ref(null); |
| | | const fileInput = ref(); |
| | | const chatDataMeg = reactive({}); |
| | | const visible = ref(false); |
| | | const fileVisible = ref(false); |
| | |
| | | const breakLine = (message: string): string[] => { |
| | | //按\n分割字符串 |
| | | let arr = message.split('\n'); |
| | | return arr |
| | | } |
| | | return arr; |
| | | }; |
| | | |
| | | const chartText = (message: string): string => { |
| | | //去除所有的#和** |
| | | let arr = message.replace(/\*\*|\#\#\#/g, ''); |
| | | return arr; |
| | | }; |
| | | |
| | | const tipMatch = (msg: string): any[] => { |
| | | //match session.content中的##[0-9]$$的索引 |
| | | |
| | | let indexs: any[] = []; |
| | | let preTip = 0; |
| | | let matches=msg.match(/##([0-9]+)\$\$/g) |
| | | let matches = msg.match(/##([0-9]+)\$\$/g); |
| | | matches?.map((item) => { |
| | | let i = msg.indexOf(item); |
| | | indexs.push({ index: i, item: item, preIndex: preTip, len: matches.length }); |
| | | indexs.push({ |
| | | index: i, |
| | | item: item, |
| | | preIndex: preTip, |
| | | len: matches.length, |
| | | }); |
| | | preTip = i; |
| | | }); |
| | | return indexs; |
| | |
| | | // formRef.value.resetFields(); |
| | | }; |
| | | |
| | | const selectFileCallback = (data) => { |
| | | console.log(data, 'selectFileCallback'); |
| | | const selectFileCallback = (data,conversation_id) => { |
| | | uploaditemList.value = [...uploaditemList.value, ...data]; |
| | | activeSessionId.value = conversation_id; |
| | | }; |
| | | |
| | | //上传 |
| | | // const selectFileCallback = async (resData, file) => { |
| | | // console.log(111); |
| | | // try { |
| | | // const formData = new FormData(); |
| | | // uploaditemList.value = resData; |
| | | // uploaditemList.value.map((item) => { |
| | | // if (item.name == file[0].file.name) { |
| | | // item.onFileSelectedLoading = true; |
| | | // item.textName = '上传中'; |
| | | // } |
| | | // return item; |
| | | // }); |
| | | // debugger; |
| | | // if (!activeSessionId.value) { |
| | | // await createSession(resData); |
| | | // } |
| | | |
| | | // // onFileSelectedLoading.value = true; |
| | | // // textName.value = '上传中'; |
| | | |
| | | // formData.append('files', file[0].file); |
| | | // formData.append('conversation_id', activeSessionId.value); |
| | | |
| | | // console.log(formData, 'formData'); |
| | | // const { data, code } = await uploadAndParse(formData); |
| | | // if (code === 200) { |
| | | // uploaditemList.value.map((item: any) => { |
| | | // item.onFileSelectedLoading = false; |
| | | // item.textName = '上传成功'; |
| | | // return item; |
| | | // }); |
| | | // getInfo(data); |
| | | // // onFileSelectedLoading.value = false; |
| | | // // textName.value = '上传成功'; |
| | | // } |
| | | // } catch (err) { |
| | | // uploaditemList.value.map((item: any) => { |
| | | // item.onFileSelectedLoading = false; |
| | | // item.textName = '上传失败'; |
| | | // return item; |
| | | // }); |
| | | // // onFileSelectedLoading.value = false; |
| | | // // textName.value = '上传失败'; |
| | | // Message.error('上传失败'); |
| | | // } |
| | | // }; |
| | | |
| | | //上传成功解析getinfo |
| | | const getInfo = async (id) => { |
| | | const { code, data } = await chatInfos({ |
| | | doc_ids: activeSessionId.value, |
| | | }); |
| | | if (code === 200) { |
| | | uploaditemList.value = data; |
| | | } |
| | | }; |
| | | //删除上传文档 |
| | | const deleteUpload = async (id) => { |
| | | const { code, data } = await chatRm({ |
| | | doc_id: id, |
| | | }); |
| | | if (code === 200) { |
| | | getInfo(); |
| | | } |
| | | }; |
| | | |
| | | let onFileSelectedLoading = ref(false); |
| | |
| | | const deleteFile = (item) => { |
| | | console.log(uploaditemList.value); |
| | | uploaditemList.value.splice(item.index, 1); |
| | | // EventBus.emit('queryAgent', item); |
| | | }; |
| | | |
| | | const { toClipboard } = useClipboard(); |
| | | const copy = async (text) => { |
| | | await toClipboard(text); //参数为要复制的文本 |
| | | }; |
| | | |
| | | const isEdit = ref(false); |
| | | const edit = () => { |
| | | isEdit.value = !isEdit.value; |
| | | }; |
| | | const cancelEdit = (val) => { |
| | | if (val == 1) { |
| | | isEdit.value = !isEdit.value; |
| | | } else { |
| | | //编辑保存 |
| | | isEdit.value = !isEdit.value; |
| | | } |
| | | }; |
| | | |
| | | const DialogList = async () => { |
| | |
| | | console.log(name, '新建会话名称'); |
| | | |
| | | const res = await addSessionApi({ |
| | | dialog_id: id, |
| | | dialog_id: '', |
| | | conversation_desc: name, |
| | | }); |
| | | // console.log(res, "res"); |
| | |
| | | const startChat = async (valMsg) => { |
| | | chatDis.value = true; |
| | | loading.value = true; |
| | | chartLoading.value = true; |
| | | toStop = false; |
| | | sessionDetailList.value.push({ |
| | | content: valMsg, |
| | |
| | | if (typeof d !== 'boolean') { |
| | | // console.info("data:", d); |
| | | streamStr.value = d.content; |
| | | chartLoading.value = false; |
| | | startDisplayStr(); |
| | | } |
| | | } catch (e) { |
| | |
| | | if (done) { |
| | | console.info('done'); |
| | | displayedText.value = ''; |
| | | chartLoading.value = false; |
| | | if (isStopChat.value) { |
| | | setChatDataMeg(chatDataMeg); |
| | | } else { |
| | |
| | | activeSessionId.value = ''; |
| | | }); |
| | | onMounted(() => { |
| | | document.getElementsByTagName; |
| | | let container = document.getElementById('container'); |
| | | container.addEventListener('click', () => { |
| | | fileInput.value.cancel(); |
| | | // fileInput.value.cancel(); |
| | | }); |
| | | EventBus.on('newChat', () => { |
| | | agentType.value = '1'; |
| | |
| | | font-size: 12px; |
| | | padding-left: 10px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // .uploadFileDis { |
| | | // :deep(.arco-upload-list-type-text) { |
| | | // display: none; |
| | | // } |
| | | // } |
| | | .prompt { |
| | | ul { |
| | | margin: 0; |
| | | padding: 0; |
| | | display: flex; |
| | | } |
| | | ul > li { |
| | | list-style-type: none; |
| | | } |
| | | .prompt-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | background-color: #fff; |
| | | cursor: pointer; |
| | | border-radius: 8px; |
| | | padding: 10px; |
| | | border: #e5e5e5; |
| | | &:hover { |
| | | background-color: #eee; |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | .uploadFileDis { |
| | | :deep(.arco-upload-list-type-text) { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | .chat-item { |
| | | padding: 10px 0; |
| | |
| | | font-size: 14px; |
| | | color: #333; |
| | | margin-top: 4px; |
| | | } |
| | | :deep(.arco-card-body) { |
| | | padding: 0; |
| | | border-radius: 10px; |
| | | } |
| | | :deep(.arco-textarea) { |
| | | padding-top: 10px !important; |
| | | } |
| | | :deep(.arco-comment-inner-content) { |
| | | border-radius: 10px; |
| | | } |
| | | :deep(.arco-card-bordered) { |
| | | border-radius: 10px; |
| | | } |
| | | |
| | | .icon-user-jpg { |
| | |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | :deep(.arco-spin-loading .arco-spin-mask-icon) { |
| | | left: 10%; |
| | | } |
| | | } |
| | | |
| | | .right { |