176 lines
3.3 KiB
Vue
176 lines
3.3 KiB
Vue
<template>
|
|
<main class="center-chat">
|
|
<!-- 消息列表 -->
|
|
<div class="message-list">
|
|
<CenterMessageItem
|
|
v-for="msg in messages"
|
|
:key="msg.id"
|
|
:message="msg"
|
|
/>
|
|
</div>
|
|
<!-- 输入区域 -->
|
|
<div class="input-area">
|
|
<!-- 选项框 -->
|
|
<div class="input-options">
|
|
<select v-model="sendOptions.role" class="option-select">
|
|
<option value="user">用户</option>
|
|
<option value="assistant">AI</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- 输入框 -->
|
|
<textarea
|
|
v-model="inputMessage"
|
|
class="message-input"
|
|
placeholder="输入消息..."
|
|
@keydown.enter.ctrl="sendMessage"
|
|
></textarea>
|
|
|
|
<!-- 发送/停止按钮 -->
|
|
<button
|
|
:class="['send-btn', { sending: isSending }]"
|
|
@click="isSending ? stopGeneration() : sendMessage()"
|
|
>
|
|
{{ isSending ? '⏹ 停止' : '📤 发送' }}
|
|
</button>
|
|
</div>
|
|
</main>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import CenterMessageItem from '../features/center/MessageItem.vue';
|
|
|
|
interface Message {
|
|
id: string;
|
|
senderName: string;
|
|
senderRole: 'user' | 'assistant' | 'system';
|
|
mes: string;
|
|
timestamp: Date;
|
|
}
|
|
|
|
const messages = ref<Message[]>([
|
|
{
|
|
id: '1',
|
|
senderName: 'Assistant',
|
|
senderRole: 'assistant',
|
|
mes: '你好!有什么可以帮助你的吗?',
|
|
timestamp: new Date(),
|
|
},
|
|
]);
|
|
|
|
const inputMessage = ref('');
|
|
const isSending = ref(false);
|
|
const sendOptions = ref({
|
|
role: 'user' as 'user' | 'assistant',
|
|
});
|
|
|
|
function sendMessage() {
|
|
if (!inputMessage.value.trim()) return;
|
|
|
|
const newMessage: Message = {
|
|
id: Date.now().toString(),
|
|
senderName: sendOptions.value.role === 'user' ? 'User' : 'Assistant',
|
|
senderRole: sendOptions.value.role,
|
|
mes: inputMessage.value,
|
|
timestamp: new Date(),
|
|
};
|
|
|
|
messages.value.push(newMessage);
|
|
inputMessage.value = '';
|
|
isSending.value = true;
|
|
|
|
// 模拟 AI 回复
|
|
setTimeout(() => {
|
|
isSending.value = false;
|
|
}, 2000);
|
|
}
|
|
|
|
function stopGeneration() {
|
|
isSending.value = false;
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.center-chat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
background: #ffffff;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.message-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.input-area {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
gap: 8px;
|
|
padding: 16px;
|
|
background: #f8f9fa;
|
|
border-top: 2px solid #dee2e6;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.input-options {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.option-select {
|
|
padding: 8px;
|
|
border: 1px solid #ced4da;
|
|
border-radius: 4px;
|
|
background: white;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.message-input {
|
|
flex: 1;
|
|
padding: 12px;
|
|
border: 1px solid #ced4da;
|
|
border-radius: 4px;
|
|
resize: none;
|
|
font-size: 14px;
|
|
min-height: 60px;
|
|
max-height: 200px;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.message-input:focus {
|
|
outline: none;
|
|
border-color: #3498db;
|
|
}
|
|
|
|
.send-btn {
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: #3498db;
|
|
color: white;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
transition: background 0.2s;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.send-btn:hover {
|
|
background: #2980b9;
|
|
}
|
|
|
|
.send-btn.sending {
|
|
background: #e74c3c;
|
|
}
|
|
|
|
.send-btn.sending:hover {
|
|
background: #c0392b;
|
|
}
|
|
</style>
|