Files
nianxx-h5/src/pages/home/components/ChatInputArea/index.vue
duanshuwen ce1dac077e chore(chat-input-area): remove voice input support
Remove all voice input related UI elements, speech recognition logic, and external RecordingWaveBtn dependency from the chat input area, simplifying the component to only support text input.
2026-05-29 23:20:35 +08:00

155 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="input-area-wrapper" @touchend="handleVoiceTouchEndFromContainer"
@touchcancel="handleVoiceTouchEndFromContainer">
<div
class="mx-[8px] mb-[6px] flex min-h-[42px] items-center rounded-[21px] bg-white px-[8px] py-[6px] shadow-[0_2px_12px_rgba(18,39,75,0.06)]">
<div class="flex h-[30px] w-[30px] shrink-0 items-center justify-center">
<img class="h-[22px] w-[22px]" src="https://oss.nianxx.cn/mp/static/version_101/home/input_keyboard_icon.png" />
</div>
<!-- 输入框 -->
<div class="flex min-h-[30px] min-w-0 flex-1 items-center">
<textarea ref="textareaRef" v-model="inputMessage" rows="1" maxlength="300" :placeholder="placeholder"
class="block h-[22px] max-h-[92px] min-h-[22px] w-full resize-none overflow-x-hidden overflow-y-auto border-0 bg-transparent p-0 text-[14px] leading-[22px] text-[#333] outline-none appearance-none placeholder:text-[#A5AAB4] scrollbar-none [&::-webkit-scrollbar]:hidden"
@input="adjustTextareaHeight" @focus="handleFocus" @blur="handleBlur" @touchstart="handleTouchStart"
@touchend="handleTouchEnd" />
</div>
<div class="flex h-[30px] w-[34px] shrink-0 items-center justify-end">
<div
class="flex h-[30px] w-[30px] items-center justify-center rounded-full [background:radial-gradient(39%_39%_at_97%_81%,#79dffb_0%,rgba(138,227,252,0)_100%),radial-gradient(54%_54%_at_3%_70%,#8afcf8_0%,rgba(138,252,248,0)_100%),#0CCD58] shadow-[0_4px_10px_rgba(12,205,88,0.22)]"
@click="sendMessage">
<div v-if="isSessionActive" class="h-[10px] w-[10px] rounded-[3px] bg-white"> </div>
<img v-else class="h-[20px] w-[20px]"
src="https://oss.nianxx.cn/mp/static/version_101/home/input_send_icon.png" />
</div>
</div>
</div>
<div class="text-center text-[9px] leading-[12px] text-[#A5AAB4] pb-[6px]">
内容由AI大模型生成请仔细鉴别
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, nextTick, onMounted, defineExpose, onUnmounted } from "vue";
const props = defineProps({
modelValue: String,
holdKeyboard: Boolean,
isSessionActive: Boolean,
stopRequest: Function,
});
const emit = defineEmits([
"update:modelValue",
"send",
"noHideKeyboard",
"keyboardShow",
"keyboardHide",
]);
const textareaRef = ref(null);
const placeholder = ref("快告诉小七您在想什么~");
const inputMessage = ref(props.modelValue || "");
const maxTextareaHeight = 92;
const isFocused = ref(false);
const keyboardHeight = ref(0);
const adjustTextareaHeight = () => {
const textarea = textareaRef.value;
if (!textarea) return;
textarea.style.height = "22px";
textarea.style.height = `${Math.min(textarea.scrollHeight, maxTextareaHeight)}px`;
};
// 保持和父组件同步
watch(
() => props.modelValue,
(val) => {
inputMessage.value = val;
nextTick(adjustTextareaHeight);
}
);
// 当子组件的 inputMessage 变化时,通知父组件(但要避免循环更新)
watch(inputMessage, (val) => {
// 只有当值真正不同时才emit避免循环更新
if (val !== props.modelValue) {
emit("update:modelValue", val);
}
nextTick(adjustTextareaHeight);
});
// 监听键盘高度变化
onMounted(() => {
nextTick(adjustTextareaHeight);
});
const hideKeyboardAfterSend = () => {
isFocused.value = false;
const textarea = textareaRef.value;
if (textarea && typeof textarea.blur === "function") {
textarea.blur();
}
};
const sendMessage = () => {
if (props.isSessionActive) {
// 如果会话进行中,调用停止请求函数
if (props.stopRequest) {
props.stopRequest();
}
hideKeyboardAfterSend();
} else {
// 否则发送新消息
if (!inputMessage.value.trim()) return;
emit("send", inputMessage.value);
hideKeyboardAfterSend();
}
};
const handleFocus = () => {
isFocused.value = true;
emit("noHideKeyboard");
};
const handleBlur = () => {
isFocused.value = false;
};
const handleTouchStart = () => {
emit("noHideKeyboard");
};
const handleTouchEnd = () => {
emit("noHideKeyboard");
};
// 手动聚焦输入框
const focusInput = () => {
isFocused.value = true;
nextTick(() => {
const textarea = textareaRef.value;
if (textarea && typeof textarea.focus === "function") {
textarea.focus();
}
});
};
// 手动失焦输入框
const blurInput = () => {
isFocused.value = false;
const textarea = textareaRef.value;
if (textarea && typeof textarea.blur === "function") {
textarea.blur();
}
};
// 暴露方法给父组件
defineExpose({ focusInput, blurInput });
</script>