From a656cfbcd0fea1048a633434f1e530fe40d4e3a0 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期三, 25 九月 2024 11:07:10 +0800
Subject: [PATCH] Merge branch 'test' of http://47.103.154.90:83/r/WI/Web.V1.0 into test

---
 src/components/chat/components/playBar/PlayBar.vue |  152 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 136 insertions(+), 16 deletions(-)

diff --git a/src/components/chat/components/playBar/PlayBar.vue b/src/components/chat/components/playBar/PlayBar.vue
index 8275d47..620da7d 100644
--- a/src/components/chat/components/playBar/PlayBar.vue
+++ b/src/components/chat/components/playBar/PlayBar.vue
@@ -6,26 +6,51 @@
 			</el-button>
 		</div>
 		<div class="set-input">
+			<!-- @input="inputText" -->
+
 			<el-input
+				ref="inputRef"
 				class="relative align-bottom set-inputAnswer"
 				type="textarea"
 				resize="none"
 				:autosize="{ minRows: 1, maxRows: 8 }"
 				v-elInputFocus
-				@keydown="enterInput"
+				@keydown="keydownInput"
+				@input="inputText"
 				v-model="inputValue"
 				placeholder="鍦ㄨ繖閲岃緭鍏ユ偍鐨勯棶棰樺紑濮嬪拰AI瀵硅瘽"
-			/>
+			>
+			</el-input>
+			<div
+				v-show="tipIsShow"
+				ref="tipEleRef"
+				class="absolute rounded-md bg-white border border-solid border-gray-400 py-2 z-10"
+				:style="{ left: popUpPosition.left + 'px', bottom: popUpPosition.bottom + 'px' }"
+			>
+				<div class="font-bold text-sm text-nowrap overflow-hidden text-ellipsis max-w-80 mb-1 px-2">Ctrl+鏁板瓧蹇嵎杈撳叆</div>
+				<div class="text-gray-400 text-sm text-nowrap overflow-hidden text-ellipsis max-w-80 mb-1 px-2">{{ inputValue }}</div>
+				<div class="max-w-96 flex flex-col">
+					<div
+						class="hover:bg-gray-300 py-2 cursor-pointer px-5 text-nowrap overflow-hidden text-ellipsis"
+						v-for="(item, index) in similarList"
+						:key="index"
+						@click="similarClick(item)"
+					>
+						<span class="text-sm text-gray-500 pr-1.5">{{ index + 1 }}</span>
+						<span> {{ item?.question }} </span>
+					</div>
+				</div>
+			</div>
 		</div>
 		<div class="h100 flex items-center">
 			<div class="upload_img space-y">
 				<div class="imgbox cursor-pointer flex items-center">
-					<el-button title="AI鐪嬪浘" class="cursor-pointer" link style="margin-left: unset">
+					<!-- <el-button title="AI鐪嬪浘" class="cursor-pointer" link style="margin-left: unset">
 						<img src="/static/images/wave/LookImg.png" class="set-img-icon box-border" />
-					</el-button>
-					<el-button title="AI璇煶瀵硅瘽" class="cursor-pointer" link style="margin-left: unset">
+					</el-button> -->
+					<!-- <el-button title="AI璇煶瀵硅瘽" class="cursor-pointer" link style="margin-left: unset" @click="audioChangeWord">
 						<img src="/static/images/wave/HeadImg.png" class="set-img-icon box-border" />
-					</el-button>
+					</el-button> -->
 
 					<el-button title="鍙戦��" :disabled="isTalking" class="cursor-pointer" link @click="emits('sendClick')">
 						<div class="send">
@@ -35,29 +60,125 @@
 				</div>
 			</div>
 		</div>
+		<VoicePage
+			v-model:isShow="voicePageIsShow"
+			v-show="voicePageIsShow"
+			@submit="(cb) => emits('sendClick', cb)"
+			@updateInputValue="updateInputValue"
+			:isHome="isHome"
+		/>
 	</div>
 </template>
 
 <script setup lang="ts">
-import { reactive } from 'vue';
+import type { InputInstance } from 'element-plus';
+import { ElMessage } from 'element-plus';
+import getCaretCoordinates from 'textarea-caret';
+import { computed, nextTick, ref } from 'vue';
+import VoicePage from './voicePage/VoicePage.vue';
+import { querySimilarityHistory } from '/@/api/ai/chat';
+import { useClickOther } from '/@/hooks/useClickOther';
 
+import { onClickOutside } from '@vueuse/core'
 const emits = defineEmits(['sendClick']);
-
-const props = defineProps(['isTalking']);
-
+const props = defineProps(['isTalking', 'isHome']);
+const voicePageIsShow = defineModel('voicePageIsShow', {
+	type: Boolean,
+	default: false,
+});
 const inputValue = defineModel({
 	type: String,
 });
 
-const enterInput = (e) => {
+const tipIsShow = computed(() => !!inputValue.value.trim() && similarList.value?.length > 0 && triggerShow.value);
+const triggerShow = ref(false);
+const inputRef = ref<InputInstance>(null);
+
+const updateInputValue = (val) => {
+	inputValue.value = val;
+};
+const keydownInput = (e) => {
 	if (props.isTalking) return;
-	if (!e.shiftKey && e.keyCode == 13) {
+	const isEnterInput = !e.shiftKey && e.key == 'Enter';
+	const isDigitalInput = e.ctrlKey && e.code.startsWith('Digit') && tipIsShow.value;
+	if (isEnterInput || isDigitalInput) {
 		e.cancelBubble = true; //ie闃绘鍐掓场琛屼负
 		e.stopPropagation(); //Firefox闃绘鍐掓场琛屼负
 		e.preventDefault(); //鍙栨秷浜嬩欢鐨勯粯璁ゅ姩浣�*鎹㈣
-		//浠ヤ笅澶勭悊鍙戦�佹秷鎭唬鐮�
-		emits('sendClick');
+		if (isEnterInput) {
+			//浠ヤ笅澶勭悊鍙戦�佹秷鎭唬鐮�
+			emits('sendClick');
+		} else if (isDigitalInput) {
+			const num = Number(e.code.replace('Digit', ''));
+			const mapValue = similarList.value[num - 1]?.question;
+			if (mapValue) {
+				inputValue.value = mapValue;
+				triggerShow.value = false;
+			}
+		}
 	}
+};
+
+const similarClick = (item) => {
+	if (item.question) {
+		inputValue.value = item.question;
+		triggerShow.value = false;
+	}
+};
+
+const tipEleRef = ref<HTMLDivElement>(null);
+
+const popUpPosition = ref({
+	left: null,
+	bottom: null,
+});
+
+onClickOutside(tipEleRef,()=>{
+	triggerShow.value = true
+})
+const inputText = (text) => {
+	nextTick(() => {
+		setTimeout(() => {
+			const container = inputRef.value.$el;
+
+			const textAreaEl = inputRef.value.$el.firstElementChild;
+			const caret = getCaretCoordinates(textAreaEl, textAreaEl.selectionEnd);
+
+			const bottomOffset = 10;
+			const leftOffset = 9;
+			popUpPosition.value.left = caret.left + leftOffset;
+			popUpPosition.value.bottom = container.offsetHeight + bottomOffset;
+			triggerShow.value = true;
+			if (lastIsFinish) {
+				querySimilarityApi(text);
+			}
+		}, 0);
+	});
+};
+
+const similarList = ref([]);
+let lastIsFinish = true;
+const querySimilarityApi = async (text: string) => {
+	if (!text) return;
+	lastIsFinish = false;
+	const res = await querySimilarityHistory({
+		question: text,
+	});
+	lastIsFinish = true;
+	const handleValues = res?.values ?? [];
+
+	similarList.value = props.isHome ? handleValues.slice(0, 3) : handleValues;
+};
+const audioChangeWord = () => {
+	navigator.getUserMedia(
+		{ audio: true },
+		function onSuccess(stream) {
+			voicePageIsShow.value = true;
+		},
+		function onError(error) {
+			ElMessage.warning('璇锋墦寮�楹﹀厠椋庢潈闄�');
+		}
+	);
 };
 </script>
 <style scoped lang="scss">
@@ -147,14 +268,13 @@
 		display: inline-block;
 		width: 100%;
 		.set-inputAnswer {
-		
 			padding: 3px 0;
 			line-height: 20px;
 			border: none;
 			background-color: transparent;
 			color: #333;
 			font-size: 15px;
-			:deep(.el-textarea__inner){
+			:deep(.el-textarea__inner) {
 				// 鍘婚櫎绾�
 				box-shadow: none;
 			}

--
Gitblit v1.9.3