ai界面可用

main
勿妄 1 month ago
parent dbbbcc9e13
commit 943cee36ec

@ -9,32 +9,57 @@
<aside class="sidebar"> <aside class="sidebar">
<h2 class="sidebar-title">历史对话</h2> <h2 class="sidebar-title">历史对话</h2>
<ul class="history-list"> <ul class="history-list">
<li class="history-item" v-for="(item, index) in historyItems" :key="index"> <li class="history-item"
<span class="history-text">{{ item.text }}</span> v-for="conversation in conversations"
:key="conversation.id"
@click="selectConversation(conversation)">
<span class="history-text">{{ conversation.title }}</span>
<div class="history-actions"> <div class="history-actions">
<!-- 编辑按钮 --> <button class="action-btn" title="编辑" @click.stop="editConversationTitle(conversation)">
<button class="action-btn" title="编辑" @click.stop="editItem(item)">
<img src="@/assets/images/edit.png" alt="编辑" /> <img src="@/assets/images/edit.png" alt="编辑" />
</button> </button>
<!-- 删除按钮 --> <button class="action-btn" title="删除" @click.stop="deleteConversation(conversation)">
<button class="action-btn" title="删除" @click.stop="deleteItem(item)">
<img src="@/assets/images/delete.png" alt="删除" /> <img src="@/assets/images/delete.png" alt="删除" />
</button> </button>
</div> </div>
</li> </li>
</ul> </ul>
<!-- 新建对话按钮 -->
<button class="new-chat-btn" @click="createNewChat">
<span>新建对话</span>
</button>
</aside> </aside>
<!-- 聊天区域 --> <!-- 聊天区域 -->
<main class="chat-area"> <main class="chat-area">
<div class="chat-content"> <div class="chat-content">
<!-- 欢迎消息始终显示在最上方 -->
<div class="welcome-message"> <div class="welcome-message">
<!-- 机器人头像 -->
<div class="bot-avatar"> <div class="bot-avatar">
<img src="@/assets/images/aiRobot.png" alt="机器人头像" /> <img src="@/assets/images/aiRobot.png" alt="机器人头像" />
</div> </div>
<div class="welcome-text">我可以回答各种问题欢迎提问</div> <div class="welcome-text">我可以回答各种问题欢迎提问</div>
</div> </div>
<!-- 对话消息 -->
<template v-if="currentConversation">
<div v-for="message in currentConversation.messages"
:key="message.id"
:class="message.isUser ? 'user-message' : 'bot-message'">
<template v-if="message.isUser">
<div class="message-text">{{ message.text }}</div>
<div class="user-avatar">
<img src="@/assets/images/aiRobot.png" alt="用户头像" />
</div>
</template>
<template v-else>
<div class="bot-avatar">
<img src="@/assets/images/aiRobot.png" alt="机器人头像" />
</div>
<div class="message-text">{{ message.text }}</div>
</template>
</div>
</template>
</div> </div>
<!-- 输入区域 --> <!-- 输入区域 -->
@ -59,6 +84,21 @@
text: string; // text: string; //
} }
//
interface Message {
id: number;
text: string;
isUser: boolean; // true false
}
//
interface Conversation {
id: number;
title: string; // 20
messages: Message[]; //
timestamp: number; //
}
// //
const historyItems = ref<HistoryItem[]>([ const historyItems = ref<HistoryItem[]>([
{ id: 1, text: '这是一个历史对话' }, { id: 1, text: '这是一个历史对话' },
@ -68,30 +108,115 @@ const historyItems = ref<HistoryItem[]>([
// //
const message = ref(''); const message = ref('');
//
const chatMessages = ref<HistoryItem[]>([]);
// //
const sendMessage = () => { const sendMessage = async () => {
const msg = message.value.trim(); const msg = message.value.trim();
if (msg) { if (!msg) return;
const newItem: HistoryItem = {
id: Date.now(), // 使 //
text: msg, if (!currentConversation.value) {
currentConversation.value = {
id: Date.now(),
title: msg.slice(0, 20) + (msg.length > 20 ? '...' : ''),
messages: [],
timestamp: Date.now()
}; };
historyItems.value.push(newItem); // conversations.value.push(currentConversation.value);
message.value = ''; // }
//
const userMessage: Message = {
id: Date.now(),
text: msg,
isUser: true
};
currentConversation.value.messages.push(userMessage);
//
message.value = '';
//
try {
// TODO: AI
const botResponse = await mockBotResponse(msg);
const botMessage: Message = {
id: Date.now(),
text: botResponse,
isUser: false
};
currentConversation.value.messages.push(botMessage);
} catch (error) {
console.error('发送消息失败:', error);
} }
}; };
// //
const editItem = (item: HistoryItem) => { const editItem = (item: HistoryItem) => {
const newText = prompt('编辑对话内容:', item.text); const newText = prompt('编辑对话内容:', item.text);
if (newText !== null) { if (newText !== null) {
item.text = newText.trim(); item.text = newText.trim();
const chatItem = chatMessages.value.find((chat) => chat.id === item.id);
if (chatItem) {
chatItem.text = newText.trim(); //
}
} }
}; };
// //
const deleteItem = (item: HistoryItem) => { const deleteItem = (item: HistoryItem) => {
historyItems.value = historyItems.value.filter((history) => history.id !== item.id); historyItems.value = historyItems.value.filter((history) => history.id !== item.id);
chatMessages.value = chatMessages.value.filter((chat) => chat.id !== item.id); //
};
//
const conversations = ref<Conversation[]>([]);
//
const currentConversation = ref<Conversation | null>(null);
//
const selectConversation = (conversation: Conversation) => {
currentConversation.value = conversation;
};
//
const deleteConversation = (conversation: Conversation) => {
conversations.value = conversations.value.filter(c => c.id !== conversation.id);
if (currentConversation.value?.id === conversation.id) {
currentConversation.value = null;
}
};
//
const createNewChat = () => {
const newConversation: Conversation = {
id: Date.now(),
title: '新对话',
messages: [],
timestamp: Date.now()
};
conversations.value.push(newConversation);
currentConversation.value = newConversation;
};
//
const editConversationTitle = (conversation: Conversation) => {
const newTitle = prompt('编辑对话标题:', conversation.title);
if (newTitle !== null && newTitle.trim() !== '') {
conversation.title = newTitle.trim();
}
};
//
const mockBotResponse = async (msg: string): Promise<string> => {
return new Promise(resolve => {
setTimeout(() => {
resolve(`这是对 "${msg}" 的回复`);
}, 1000);
});
}; };
</script> </script>
@ -195,6 +320,29 @@ const deleteItem = (item: HistoryItem) => {
color: #9c88ff; color: #9c88ff;
} }
.new-chat-btn {
width: 100%;
padding: 12px 16px;
background: linear-gradient(45deg, #9c88ff, #ff6b9d);
color: white;
border: none;
border-radius: 8px;
font-size: 18px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
text-align: center;
margin-top: 20px;
}
.new-chat-btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(156, 136, 255, 0.3);
}
.new-chat-btn:active {
transform: translateY(0);
}
/* 聊天区域 */ /* 聊天区域 */
.chat-area { .chat-area {
display: flex; display: flex;
@ -214,8 +362,7 @@ const deleteItem = (item: HistoryItem) => {
overflow-y: auto; overflow-y: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; /* 垂直方向上靠上 */ gap: 16px;
align-items: flex-start; /* 水平方向上靠左 */
} }
.welcome-message { .welcome-message {
@ -226,6 +373,8 @@ const deleteItem = (item: HistoryItem) => {
border-radius: 20px; border-radius: 20px;
padding: 16px 24px; padding: 16px 24px;
box-shadow: 0 4px 20px rgba(156, 136, 255, 0.1); box-shadow: 0 4px 20px rgba(156, 136, 255, 0.1);
max-width: 60%;
margin-bottom: 16px;
} }
.bot-avatar { .bot-avatar {
@ -238,6 +387,7 @@ const deleteItem = (item: HistoryItem) => {
justify-content: center; justify-content: center;
font-size: 18px; font-size: 18px;
color: white; color: white;
margin-right: 16px;
} }
.bot-avatar img { .bot-avatar img {
@ -251,6 +401,62 @@ const deleteItem = (item: HistoryItem) => {
color: #333; color: #333;
} }
.user-message {
display: flex;
align-items: center;
justify-content: flex-end;
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(200, 180, 255, 0.3);
border-radius: 20px;
padding: 16px 24px;
box-shadow: 0 4px 20px rgba(156, 136, 255, 0.1);
max-width: 60%;
margin-bottom: 16px;
align-self: flex-end;
}
.user-text {
font-size: 16px;
color: #333;
margin-right: 16px;
}
.user-avatar {
width: 40px;
height: 40px;
background: transparent;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.user-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.bot-message {
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(200, 180, 255, 0.3);
border-radius: 20px;
padding: 16px 24px;
box-shadow: 0 4px 20px rgba(156, 136, 255, 0.1);
max-width: 60%;
margin-bottom: 16px;
align-self: flex-start;
}
.message-text {
font-size: 16px;
color: #333;
margin: 0 16px;
}
/* 输入区域 */ /* 输入区域 */
.input-area { .input-area {
padding: 30px; padding: 30px;
@ -370,4 +576,3 @@ const deleteItem = (item: HistoryItem) => {
background: rgba(156, 136, 255, 0.5); background: rgba(156, 136, 255, 0.5);
} }
</style> </style>
Loading…
Cancel
Save