customer_list/common/static/fonts/ywiconfont/iconfont.css | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
customer_list/common/static/fonts/ywiconfont/iconfont.ttf | 补丁 | 查看 | 原始文档 | blame | 历史 | |
customer_list/common/static/fonts/ywiconfont/iconfont.woff | 补丁 | 查看 | 原始文档 | blame | 历史 | |
customer_list/common/static/fonts/ywiconfont/iconfont.woff2 | 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/api/ai/chat.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/Chat.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/chat/components/playBar/PlayBar.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/utils/setIconfont.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
customer_list/common/static/fonts/ywiconfont/iconfont.css
@@ -1,8 +1,8 @@ @font-face { font-family: "ywifont"; /* Project id 4655417 */ src: url('iconfont.woff2?t=1732599381749') format('woff2'), url('iconfont.woff?t=1732599381749') format('woff'), url('iconfont.ttf?t=1732599381749') format('truetype'); src: url('iconfont.woff2?t=1733131882550') format('woff2'), url('iconfont.woff?t=1733131882550') format('woff'), url('iconfont.ttf?t=1733131882550') format('truetype'); } .ywifont { @@ -385,11 +385,11 @@ content: "\e695"; } .ywicon-weibiaoti517:before { .ywicon-jieshu:before { content: "\e61d"; } .ywicon-bofang:before { .ywicon-kaishi:before { content: "\e68a"; } customer_list/common/static/fonts/ywiconfont/iconfont.ttfBinary files differ
customer_list/common/static/fonts/ywiconfont/iconfont.woffBinary files differ
customer_list/common/static/fonts/ywiconfont/iconfont.woff2Binary files differ
src/api/ai/chat.ts
@@ -1,4 +1,3 @@ import request from '/@/utils/request'; import request, { streamReq } from '/@/utils/request'; const GET_SECTION_SAMPLE_API = '/scene/get_scene_group_sample'; const GET_SECTION_A_LIST_API = '/scene/get_scene_group_tree'; @@ -260,7 +259,7 @@ * @description 流式大模型对话 * @param {FormData} params **/ export const questionStreamByPost = (params, callback: (chunkRes) => void) => export const questionStreamByPost = (params, callback: (chunkRes) => void, extraData: any = {}) => streamReq( { url: `/chat/question_stream`, @@ -270,6 +269,7 @@ headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, ...extraData, }, callback ); @@ -502,5 +502,3 @@ 'Content-Type': 'application/x-www-form-urlencoded', }, }); src/components/chat/Chat.vue
@@ -40,7 +40,7 @@ :class="{ group: item.role === RoleEnum.user }" > <div class="flex flex-col" v-if="item?.stepList?.length > 0"> <div class="flex items-center "> <div class="flex items-center"> <span class="mr-2">意图分析:</span> <div @click="toggleStepList(item)" @@ -267,6 +267,7 @@ v-model="messageContent.values" @sendClick="sendClick" @showUpChatClick="showUpChatClick" @stopGenClick="stopGenClick" @showDownChatClick="showDownChatClick" :style="{ width: chatWidth }" :setCommonQuestionInfo="setCommonQuestionInfo" @@ -318,10 +319,10 @@ isSharePage, roomConfig, } from '/@/stores/chatRoom'; import { getCurrentPosition } from '/@/utils/brower'; import emitter from '/@/utils/mitt'; import { ErrorCode } from '/@/utils/request'; import { toMyFixed } from '/@/utils/util'; import axios, { CancelTokenSource } from 'axios'; const chatWidth = '75%'; const voicePageIsShow = ref(false); let isTalking = ref(false); @@ -439,6 +440,8 @@ let questionRes = null; let position = null; let finalCalcSectionAId = null; let lastAxiosSource: CancelTokenSource = null; const questionAi = async (text) => { let judgeParams = null; if (!preQuestion.value) { @@ -503,44 +506,52 @@ let res = null; let lastTimestamp = new Date().getTime(); const resultP = new Promise(async (resolve, reject) => { await questionStreamByPost(params, (chunkRes) => { Logger.info('chunk response:\n\n' + JSON.stringify(chunkRes)); if (chunkRes.mode === 'result') { res = chunkRes.value; resolve(res); chunkRes.value = '准备数据分析'; } const currentSource = axios.CancelToken.source(); lastAxiosSource = currentSource; await questionStreamByPost( params, (chunkRes) => { Logger.info('chunk response:\n\n' + JSON.stringify(chunkRes)); if (chunkRes.mode === 'result') { res = chunkRes.value; resolve(res); chunkRes.value = '准备数据分析'; } if (chunkRes.mode === 'conclusion') { computedMessageList.value.at(-1).conclusion = chunkRes.value; chunkRes.value = '分析结束'; } const stepList = computedMessageList.value.at(-1).stepList; const currentTimeStamp = new Date().getTime(); const ms = toMyFixed(currentTimeStamp - lastTimestamp, 2) + ' ms'; if (chunkRes.mode === 'finish') { stepList.at(-1).ms = ms; if (chunkRes.mode === 'conclusion') { computedMessageList.value.at(-1).conclusion = chunkRes.value; chunkRes.value = '分析结束'; } const stepList = computedMessageList.value.at(-1).stepList; const currentTimeStamp = new Date().getTime(); const ms = toMyFixed(currentTimeStamp - lastTimestamp, 2) + ' ms'; if (chunkRes.mode === 'finish') { stepList.at(-1).ms = ms; isTalking.value = false; return; } isTalking.value = false; return; } if (stepList?.length >= 1) { stepList.at(-1).ms = ms; } lastTimestamp = currentTimeStamp; if (stepList?.length >= 1) { stepList.at(-1).ms = ms; } lastTimestamp = currentTimeStamp; const stepItem = convertProcessItem(chunkRes); stepList.push(stepItem); scrollToBottom(); }) const stepItem = convertProcessItem(chunkRes); stepList.push(stepItem); scrollToBottom(); }, { cancelToken: currentSource.token, } ) .catch((err) => { throw err; }) .finally(() => { isTalking.value = false; computedMessageList.value.at(-1).stepIsShow = false; resetStep(); }); }); @@ -560,6 +571,15 @@ let currentLLMId = null; const stopGenClick = () => { lastAxiosSource?.cancel(); isTalking.value = false; chatListLoading.value = false; resetStep(); computedMessageList.value.at(-1).stepIsShow = false; }; const sendChatMessage = async (content: ChatContent = messageContent.value, cb?: any, isCallExtParams?: any) => { if (!content?.values) { return; src/components/chat/components/playBar/PlayBar.vue
@@ -104,10 +104,18 @@ v-if="inputValue" > </el-button> <el-button title="发送" class="cursor-pointer" link @click="emits('sendClick')"> <div class="send"> <img src="/static/images/wave/QueryImg.png" /> </div> <el-button class="cursor-pointer" link > <el-tooltip v-if="isTalking" placement="top" content="停止生成"> <div class="size-[36px] rounded-full flex-center border-2 border-solid border-black text-black" @click="emits('stopGenClick')"> <span class="ywifont ywicon-jieshu"></span> </div> </el-tooltip> <el-tooltip v-else placement="top" content="发送"> <div class="size-[36px] rounded-full bg-black flex-center" @click="emits('sendClick')"> <img src="/static/images/wave/QueryImg.png" /> </div> </el-tooltip> </el-button> </div> </div> @@ -141,7 +149,7 @@ import VoicePage from './voicePage/VoicePage.vue'; import { getMetricsNames, querySimilarityHistory } from '/@/api/ai/chat'; import { activeGroupType, groupTypeList, groupTypeMapIcon } from '/@/stores/chatRoom'; const emits = defineEmits(['sendClick', 'showUpChatClick', 'showDownChatClick']); const emits = defineEmits(['sendClick', 'showUpChatClick', 'showDownChatClick','stopGenClick']); const props = defineProps({ isTalking: Boolean, isHome: Boolean, src/utils/setIconfont.ts
@@ -1,7 +1,7 @@ // 字体图标 url const cssCdnUrlList: Array<string> = [ './static/fonts/iconfont/iconfont.css', './static/fonts/ywiconfont/iconfont.css?v=2233334', './static/fonts/ywiconfont/iconfont.css?v=214', './static/fonts/fontawesome/fontawesome.min.css', ]; // 第三方 js url