## 项目实训(1)AI 模拟面试->脚踏实地,先从搭个聊天框开始吧

166 阅读3分钟

项目实训(1)AI 模拟面试->脚踏实地,先从搭个聊天框开始吧

挺酷的一个功能。 用户写完简历,直接就能让 AI 扮演面试官,针对简历内容或者某个职位进行模拟面试。还能有针对单个项目经历的“深挖”模式。听起来是那么回事儿。

但说实话,AI 这东西,之前没接触过, 做起来还得多摸索;;;

初步的思路拆解:

  1. 用户界面 (UI): 这个肯定得是个聊天界面。用户输入,AI 回复。这个我熟,Vue + Ant Design Vue 应该能搞定。
  2. AI 对接: 这块最虚。听后端大佬说,他们会提供一个内部的 DeepSeek 模型接口,我只管调就行,URL 和模型名称他们会给。听起来好像不用我操心太多底层的 AI 逻辑?但愿如此。跨域问题他们也说会处理好,前端无感。嗯,这个好。
  3. 交互逻辑:
    • 经历深挖模式: 用户选择简历里的一个项目或工作经历,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 #前端菜鸟的日常