- 优化Chat组件交互体验 - 修复智能体选择逻辑 - 新增chat页面样式和脚本 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74 lines
3.2 KiB
Vue
74 lines
3.2 KiB
Vue
<script setup lang="ts">
|
||
const props = defineProps<{
|
||
modelValue: string
|
||
loading: boolean
|
||
}>()
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'update:modelValue', value: string): void
|
||
(e: 'send'): void
|
||
}>()
|
||
|
||
const handleKeydown = (e: KeyboardEvent) => {
|
||
if (e.key === 'Enter' && !e.shiftKey) {
|
||
e.preventDefault()
|
||
emit('send')
|
||
}
|
||
}
|
||
|
||
const autoResize = (e: Event) => {
|
||
const target = e.target as HTMLTextAreaElement
|
||
target.style.height = 'auto'
|
||
target.style.height = Math.min(target.scrollHeight, 160) + 'px'
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="p-5 border-t border-white/[0.06] bg-[#0c0c0f]/60 backdrop-blur-xl">
|
||
<div class="max-w-3xl mx-auto">
|
||
<div class="relative bg-[#12121a] rounded-2xl border border-white/[0.08] focus-within:border-orange-500/40 focus-within:shadow-[0_0_30px_rgba(249,115,22,0.08)] transition-all duration-300">
|
||
<!-- 附件按钮 -->
|
||
<button class="absolute left-4 top-1/2 -translate-y-1/2 text-white/25 hover:text-orange-400 transition-colors p-1">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path>
|
||
</svg>
|
||
</button>
|
||
|
||
<!-- 输入框 -->
|
||
<textarea
|
||
:value="modelValue"
|
||
@input="emit('update:modelValue', ($event.target as HTMLTextAreaElement).value); autoResize($event)"
|
||
@keydown="handleKeydown"
|
||
placeholder="发送消息..."
|
||
rows="1"
|
||
class="chat-input-textarea w-full bg-transparent text-white placeholder-white/25 py-4 pl-12 pr-28 resize-none focus:outline-none text-[15px]"
|
||
></textarea>
|
||
|
||
<!-- 发送按钮 -->
|
||
<button
|
||
@click="emit('send')"
|
||
:disabled="!modelValue.trim() || loading"
|
||
class="absolute right-2 top-1/2 -translate-y-1/2 w-9 h-9 rounded-lg flex items-center justify-center transition-all duration-200 disabled:opacity-30 disabled:cursor-not-allowed"
|
||
:class="modelValue.trim() && !loading
|
||
? 'bg-orange-500 hover:bg-orange-400 shadow-lg shadow-orange-500/30 active:scale-90'
|
||
: 'bg-white/10'"
|
||
>
|
||
<svg v-if="!loading" class="w-4 h-4 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
|
||
</svg>
|
||
<svg v-else class="w-4 h-4 text-white animate-spin" fill="none" viewBox="0 0 24 24">
|
||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 字符计数 -->
|
||
<div class="flex justify-between items-center mt-2 px-1">
|
||
<span class="text-[10px] text-white/20 tracking-wide">AI 可能会产生错误信息,请核实重要内容</span>
|
||
<span class="text-[10px] text-white/20">{{ modelValue.length }}/4000</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|