From 8aa7ffddc511138d61d64029157c11cfccc5431d Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期四, 10 四月 2025 13:30:25 +0800 Subject: [PATCH] VITE_OUTPUT_DIR --- src/components/chat/components/playBar/PlayBar.vue | 144 +++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 135 insertions(+), 9 deletions(-) diff --git a/src/components/chat/components/playBar/PlayBar.vue b/src/components/chat/components/playBar/PlayBar.vue index ee2192a..93aa6f6 100644 --- a/src/components/chat/components/playBar/PlayBar.vue +++ b/src/components/chat/components/playBar/PlayBar.vue @@ -9,8 +9,30 @@ </div> </div> </div> - - <SceneSwitch class="ml-5" :isHome="isHome" @change="groupTypeChange" /> + <div class="flex items-center justify-between mx-6"> + <SceneSwitch :isHome="isHome" @change="groupTypeChange" /> + <div class="flex items-center gap-2"> + <div + class="flex-items-center gap-1 border border-gray-400 border-solid text-sm px-3 py-1 rounded cursor-pointer" + :class="[ + sidebarIsShow + ? 'bg-[#1d86ff] text-white hover:bg-[#1d86ff]/80 active:bg-[#1d86ff]/60' + : 'hover:bg-[#1d86ff] hover:text-white', + ]" + @click="toggleSidebar" + > + <span class="ywifont ywicon-lishi"></span> + <span>鍘嗗彶璁板綍</span> + </div> + <div + class="flex-items-center gap-1 border border-gray-400 border-solid text-sm text-white bg-[#1d86ff] px-3 py-1 rounded cursor-pointer hover:bg-[#1d86ff]/80 active:bg-[#1d86ff]/60" + @click="newChatRoomClick" + > + <span class="ywifont ywicon-jia"></span> + <span>鏂板缓瀵硅瘽</span> + </div> + </div> + </div> <div class="playInput hl_input rounded-[22px] input-border input-shadow w-full"> <!-- 涓诲満鏅� --> @@ -31,7 +53,7 @@ v-for="(item, index) in attachList" :key="index" class="flex items-center gap-2 bg-[#f5f5f5] px-2 py-3 rounded-lg w-[220px] relative group" - :class="{ 'cursor-pointer': item.type === 'table' }" + :class="{ 'cursor-pointer': item.type === 'table' || item.type === 'metric' }" @click="openAttachPreview(item)" > <template v-if="item.type === 'file'"> @@ -56,6 +78,13 @@ <div class="text-info text-sm over-ellipsis w-full">{{ `涓氬姟琛ㄦ牸锛�${item.model.values?.length} 鏉¤褰昤 }}</div> </div> </template> + <template v-if="item.type === 'metric'"> + <div class="ywifont !text-[24px] flex-0" :class="[`ywicon-${item.icon}`, item.iconClass]"></div> + <div class="flex flex-col gap-0.5 w-full flex-auto"> + <div class="font-bold over-ellipsis w-full">{{ item.title }}</div> + <div class="text-info text-sm over-ellipsis w-full">{{ `鎸囨爣鏁版嵁锛�${item.model.values?.length} 鏉¤褰昤 }}</div> + </div> + </template> <div class="group-hover:visible invisible absolute right-0.5 top-0.5 bg-red-500 flex-center rounded-full p-0.5 cursor-pointer" @click.stop="deleteAttachInIndex(index)" @@ -70,7 +99,7 @@ type="textarea" resize="none" maxlength="1024" - :autosize="{ minRows: 1, maxRows: 8 }" + :autosize="{ minRows: 3, maxRows: 8 }" v-elInputFocus show-word-limit @keydown="keydownInput" @@ -96,6 +125,12 @@ > </el-button> <div class="flex-items-center gap-2"> + <el-tooltip placement="top" content="鍏宠仈鎸囨爣"> + <div class="cursor-pointer size-[24px] relative !z-10 rounded flex-center hover:bg-[#f2f2f2]" @click="openMetric"> + <span class="ywifont ywicon-zhibiao !text-[19px]"></span> + </div> + </el-tooltip> + <el-tooltip placement="top" content="鍏宠仈涓氬姟琛ㄦ牸"> <div class="cursor-pointer size-[24px] relative !z-10 rounded flex-center hover:bg-[#f2f2f2]" @@ -104,12 +139,26 @@ <span class="ywifont ywicon-biaoge !text-[19px]"></span> </div> </el-tooltip> + <el-tooltip placement="top" content="涓婁紶闄勪欢"> <div class="cursor-pointer size-[24px] relative !z-10 rounded flex-center hover:bg-[#f2f2f2]" @click="openFileClick"> <span class="ywifont ywicon-fujian !text-[20px] font-bold"></span> </div> </el-tooltip> + + <el-tooltip v-if="isSupportSpeech" placement="top" :content="recordState.isRecording ? '鍋滄璇煶杈撳叆' : '璇煶杈撳叆'"> + <div class="cursor-pointer size-[24px] relative !z-10 rounded flex-center hover:bg-[#f2f2f2]" @click="speechClick"> + <div v-if="recordState.isRecording" class="cursor-pointer flex items-center space-x-[1px]"> + <div class="w-[2px] h-[6px] bg-[#0284ff] animate-[soundWave_1.5s_ease-in-out_infinite]"></div> + <div class="w-[2px] h-[9px] bg-[#0284ff] animate-[soundWave_1.5s_ease-in-out_infinite_0.1s]"></div> + <div class="w-[2px] h-[12px] bg-[#0284ff] animate-[soundWave_1.5s_ease-in-out_infinite_0.2s]"></div> + <div class="w-[2px] h-[9px] bg-[#0284ff] animate-[soundWave_1.5s_ease-in-out_infinite_0.3s]"></div> + <div class="w-[2px] h-[6px] bg-[#0284ff] animate-[soundWave_1.5s_ease-in-out_infinite_0.4s]"></div> + </div> + <span v-else class="ywifont ywicon-maikefeng !text-[20px]"></span> + </div> + </el-tooltip> <el-tooltip placement="top" content="鍋滄鐢熸垚" v-if="isTalking"> <div class="cursor-pointer !ml-0 size-[38px] bg-[#1d86ff] relative !z-10 rounded-full flex-center" link> <div @@ -121,7 +170,7 @@ </div> </el-tooltip> <el-tooltip v-else placement="top" content="鍙戦��"> - <div class="size-[38px] rounded-full bg-black flex-center" @click="emits('sendClick')"> + <div class="size-[38px] rounded-full bg-black flex-center" @click="sendClick"> <img src="/static/images/wave/QueryImg.png" /> </div> </el-tooltip> @@ -145,6 +194,9 @@ /> <BusinessTable v-model="businessTableIsShow" @submit="submitBusinessTable" /> <BusinessTablePreview :data="attachPreviewData" v-model="attachPreviewIsShow" /> + <MetricValues v-model="metricIsShow" @submit="submitMetricValues" /> + + <MetricValuesPreview v-model="metricPreviewIsShow" :data="metricPreviewData" /> </div> </div> </template> @@ -164,6 +216,12 @@ import VoicePage from './voicePage/VoicePage.vue'; import { useCompRef } from '/@/utils/types'; import emitter from '/@/utils/mitt'; +import MetricValues from './metricValues/MetricValues.vue'; +import { newChatRoomClick, sidebarIsShow, toggleSidebar } from '/@/stores/chatRoom'; + +import MetricValuesPreview from './metricValues/MetricValuesPreview.vue'; +import { useSpeech } from './hook/useSpeech'; +import { useDigitalHuman } from './hook/useDigitalHuman'; const emits = defineEmits(['sendClick', 'stopGenClick']); const props = defineProps({ @@ -171,6 +229,13 @@ isHome: Boolean, msgList: Array, }); + +const sendClick = () => { + if (recordState.isRecording) { + cancelRecording(); + } + emits('sendClick'); +}; const voicePageIsShow = defineModel('voicePageIsShow', { type: Boolean, @@ -193,7 +258,9 @@ inputValue: inputValue, inputRef: inputRef, }); - +const { openDigitalHuman, isHumanTalking, digitalHumanIsShow } = useDigitalHuman({ + container: '.duix-container', +}); const clearTextarea = () => { inputValue.value = ''; }; @@ -202,6 +269,18 @@ inputRef.value.focus(); commonPhraseRef.value.updatePhrase(); }; + +const speechClick = () => { + if (recordState.isRecording) { + stopRecording(); + } else { + startRecording(); + } +}; + +const { isSupportSpeech, startRecording, stopRecording, recordState, cancelRecording } = useSpeech({ + inputText: inputValue, +}); //#region ====================== 甯哥敤璇姛鑳� ====================== const commonPhraseRef = useCompRef(CommonPhrases); @@ -249,6 +328,7 @@ pastTarget: inputRef as any, attachFileList: attachList, }); + const deleteAttachInIndex = (index: number) => { const attach = attachList.value[index]; if (attach.type === 'file') { @@ -259,6 +339,15 @@ const checkTableAttachExist = (data: any) => { const dataStr = JSON.stringify(data); const exist = attachList.value.find((item) => item.type === 'table' && JSON.stringify(item.model) === dataStr); + if (exist) { + return true; + } + return false; +}; + +const checkMetricAttachExist = (data: any) => { + const dataStr = JSON.stringify(data); + const exist = attachList.value.find((item) => item.type === 'metric' && JSON.stringify(item.model) === dataStr); if (exist) { return true; } @@ -280,6 +369,21 @@ ); }; +const submitMetricValues = (data) => { + attachList.value.push( + ...data + .filter((item) => !checkMetricAttachExist(item)) + .map((item) => { + return { + title: item.title, + type: 'metric', + model: item, + icon: 'zhibiao', + iconClass: 'ywicon-zhibiao text-[#c5e0ff]', + }; + }) + ); +}; //#region ====================== 涓氬姟琛ㄦ牸 ====================== const businessTableIsShow = ref(false); const openBusinessTable = () => { @@ -292,13 +396,35 @@ const attachPreviewData = ref<Attach>(); const openAttachPreview = (item: Attach) => { if (item.type === 'file') return; - attachPreviewIsShow.value = true; - attachPreviewData.value = item; + if (item.type === 'table') { + attachPreviewIsShow.value = true; + attachPreviewData.value = item; + } else if (item.type === 'metric') { + metricPreviewIsShow.value = true; + metricPreviewData.value = item; + } }; //#endregion +//#region ====================== 鎸囨爣闄勪欢 ====================== +const metricIsShow = ref(false); +const openMetric = () => { + metricIsShow.value = true; +}; +//#endregion + +//#region ====================== 鎸囨爣闄勪欢棰勮 ====================== +const metricPreviewIsShow = ref(false); +const metricPreviewData = ref<Attach>(); + +//#endregion + const quoteAttach = (item: Attach) => { - submitBusinessTable([item.model]); + if (item.type === 'table') { + submitBusinessTable([item.model]); + } else if (item.type === 'metric') { + submitMetricValues([item.model]); + } }; onActivated(() => { emitter.on('quoteAttach', quoteAttach); -- Gitblit v1.9.3