项目实训(1)AI 模拟面试->脚踏实地,先从搭个聊天框开始吧
挺酷的一个功能。 用户写完简历,直接就能让 AI 扮演面试官,针对简历内容或者某个职位进行模拟面试。还能有针对单个项目经历的“深挖”模式。听起来是那么回事儿。
但说实话,AI 这东西,之前没接触过, 做起来还得多摸索;;;
初步的思路拆解:
- 用户界面 (UI): 这个肯定得是个聊天界面。用户输入,AI 回复。这个我熟,Vue + Ant Design Vue 应该能搞定。
- AI 对接: 这块最虚。听后端大佬说,他们会提供一个内部的 DeepSeek 模型接口,我只管调就行,URL 和模型名称他们会给。听起来好像不用我操心太多底层的 AI 逻辑?但愿如此。跨域问题他们也说会处理好,前端无感。嗯,这个好。
- 交互逻辑:
- 经历深挖模式: 用户选择简历里的一个项目或工作经历,AI 针对这个点提问。
- 模拟面试模式: 可能是基于整个简历,或者用户输入一个目标职位描述,AI 来扮演面试官。
- 对话得有上下文吧?AI 不能问了上句忘了下句。
感觉千头万绪。算了,不想那么多,先把最基础的聊天界面搭出来再说。饭要一口一口吃。
今天的成果:一个简陋的聊天窗口
用 Ant Design Vue 的 List, Input.TextArea, Button 简单糊了一个。
// AIChatWindow.vue (大概长这样)
<template>
<div class="ai-chat-container">
<div class="message-list-wrapper">
<a-list
item-layout="horizontal"
:data-source="messages"
class="message-list"
>
<template #renderItem="{ item }">
<a-list-item :class="['message-item', item.sender === 'user' ? 'user-message' : 'ai-message']">
<a-list-item-meta>
<template #avatar>
<a-avatar>{{ item.sender === 'user' ? '我' : 'AI' }}</a-avatar>
</template>
<template #title>
<span>{{ item.sender === 'user' ? 'You' : 'AI Interviewer' }}</span>
</template>
<template #description>
<p>{{ item.text }}</p> <!-- 后面这里可能要支持markdown或者富文本 -->
</template>
</a-list-item-meta>
</a-list-item>
</template>
</a-list>
</div>
<div class="input-area">
<a-textarea
v-model:value="userInput"
placeholder="输入你的回答..."
:auto-size="{ minRows: 2, maxRows: 5 }"
@pressEnter="sendMessage"
/>
<a-button type="primary" @click="sendMessage" :loading="isLoading">发送</a-button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
interface Message {
id: string;
text: string;
sender: 'user' | 'ai';
timestamp: Date;
}
const userInput = ref('');
const messages = ref<Message[]>([]);
const isLoading = ref(false); // 发送消息时的加载状态
const sendMessage = () => {
if (!userInput.value.trim()) return;
const newMessage: Message = {
id: Date.now().toString(), // 简陋的id
text: userInput.value,
sender: 'user',
timestamp: new Date(),
};
messages.value.push(newMessage);
userInput.value = '';
// TODO: 调用AI接口,获取回复
// mockAIReply(newMessage.text);
};
// 模拟AI回复,后面要换成真实API调用
// const mockAIReply = (inputText: string) => {
// isLoading.value = true;
// setTimeout(() => {
// const aiResponse: Message = {
// id: Date.now().toString(),
// text: `关于你说的 "${inputText}",我觉得可以深入聊聊...(我是假的AI回复)`,
// sender: 'ai',
// timestamp: new Date(),
// };
// messages.value.push(aiResponse);
// isLoading.value = false;
// }, 1500);
// };
</script>
<style scoped>
.ai-chat-container {
display: flex;
flex-direction: column;
height: 500px; /* 或者根据父容器调整 */
border: 1px solid #d9d9d9;
border-radius: 4px;
}
.message-list-wrapper {
flex-grow: 1;
overflow-y: auto;
padding: 16px;
}
.message-item p {
margin-bottom: 0; /* antd list item自带了一些样式,调整下 */
white-space: pre-wrap; /* 保留换行和空格 */
}
.user-message {
/* 用户消息靠右?或者不同背景色?先简单点 */
text-align: right; /* 这个直接text-align好像不行,要改布局 */
}
.user-message .ant-list-item-meta {
flex-direction: row-reverse; /* antd specific for avatar on right */
}
.user-message .ant-list-item-meta-content {
text-align: right;
}
.ai-message {
/* AI消息靠左 */
}
.input-area {
display: flex;
padding: 8px;
border-top: 1px solid #d9d9d9;
}
.input-area .ant-btn {
margin-left: 8px;
}
</style>
样式还很丑,消息左右区分也不完美,但起码能打字,能看到消息列表了。
user-message 那里用 flex-direction: row-reverse; 来让头像和内容反向,算是 antd list 的一个小技巧。
今天先这样,明天研究下怎么正经地调后端给的 DeepSeek 接口。希望顺利。
#AI面试 #项目启动 #Vue3 #AntDesignVue #聊天UI #前端菜鸟的日常