当前位置: 首页 > news >正文

【React+TypeScript+DeepSeek】穿越时空对话机

引言

在这个数字化的时代,历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里,我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来?如何让历史学习变得生动有趣?带着这些思考,我们开发了一个简单的"穿越时空对话机"。

源码已经放在最后啦!


人物选择界面:
人物选择界面
聊天界面:
在这里插入图片描述


1. 项目背景

1.1 创意起源

在传统的历史学习中,学生们往往需要通过记忆大量的史实和年代来了解历史。这种学习方式不仅枯燥,而且难以激发学习兴趣。我们注意到:

  • 学生对历史人物的故事最感兴趣
  • 互动式学习效果最好
  • AI技术为教育带来新可能

基于这些观察,我萌生了开发一个能让用户直接与历史人物"对话"的应用的想法。

1.2 项目目标

  1. 教育价值

    • 让历史学习变得生动有趣
    • 深入理解历史人物的思想
    • 培养历史思维能力
  2. 技术创新

    • 运用先进的AI对话技术
    • 打造流畅的用户体验
    • 实现智能的角色扮演
  3. 文化传承

    • 弘扬优秀传统文化
    • 促进文化交流
    • 连接古今智慧

2. 核心功能概述

2.1 人物库设计

我们精心挑选了来自不同时期、不同领域的历史名人:

  1. 中国古代名人

    • 孔子:儒家思想的代表,强调仁义礼智信
    • 诸葛亮:军事谋略家,智慧与忠诚的化身
    • 李白:浪漫主义诗人,豪放不羁的文学天才
    • 苏轼:文学艺术全才,豁达乐观的人生导师
    • 李时珍:医学大师,严谨求实的科学精神
  2. 世界名人

    • 达芬奇:文艺复兴全才,艺术与科学的完美结合
    • 爱因斯坦:现代物理学家,创新思维的代表
    • 莎士比亚:戏剧大师,人性洞察的大师
    • 莫扎特:音乐天才,艺术激情的化身

每个人物都经过精心设计,包括:

  • 详细的背景故事
  • 独特的性格特征
  • 专业领域知识
  • 语言表达风格
  • 典型的思维方式

2.2 对话系统

基于DeepSeek API构建的智能对话系统具有以下特点:

  1. 角色准确性

    • 准确还原历史人物性格
    • 保持语言风格一致性
    • 符合历史背景
  2. 对话智能性

    • 上下文理解能力
    • 灵活的问题处理
    • 深度的知识储备
  3. 交互自然性

    • 流畅的对话节奏
    • 自然的语言表达
    • 适当的情感表现

3. 技术架构

3.1 技术栈选择

我们采用了现代化的技术栈:

  1. 前端技术

    - React 18
    - TypeScript 4.x
    - Vite
    - CSS Modules
    
  2. AI对话引擎

    - DeepSeek API
    - WebSocket
    - Axios
    
  3. 数据存储

    - LocalStorage
    

3.2 系统架构

采用清晰的分层架构:

  1. 表现层

    • 角色选择界面
    • 对话交互界面
    • 用户反馈组件
  2. 业务层

    • 对话管理
    • 角色控制
    • 会话处理
  3. 数据层

    • API通信
    • 本地存储
    • 状态管理

3.3 数据流设计

实现了清晰的单向数据流:

用户输入
状态更新
API请求
响应处理
界面更新

4. DeepSeek API集成

4.1 API配置

const api = axios.create({baseURL: 'https://api.deepseek.com/v1',headers: {'Authorization': `Bearer ${API_KEY}`,'Content-Type': 'application/json',},
});

4.2 对话生成

export const generateResponse = async (messages: ChatMessage[]) => {const response = await api.post('/chat/completions', {model: 'deepseek-chat',messages,temperature: 0.7,max_tokens: 1000,});return response.data.choices[0].message.content;
};

4.3 提示词系统

为每个历史人物设计了专门的提示词模板:

interface HistoricalFigurePrompt {id: string;name: string;period: string;description: string;avatar: string;systemPrompt: string;sampleQuestions: string[];personality: string;background: string;
}

5. 开发规范

5.1 代码规范

  • 使用ESLint进行代码检查
  • 使用Prettier进行代码格式化
  • 遵循TypeScript严格模式
  • 采用函数式编程范式

5.2 命名规范

  • 组件采用大驼峰命名
  • 函数采用小驼峰命名
  • 常量使用大写下划线
  • CSS类名采用kebab-case

5.3 文件组织

src/
├── components/     # 通用组件
├── pages/         # 页面组件
├── services/      # 服务层
├── styles/        # 样式文件

6. 用户界面设计理念

6.1 设计原则

在设计用户界面时,我们遵循以下核心原则:

  1. 简约而不简单

    • 清晰的视觉层次
    • 重点内容突出
    • 减少视觉干扰
  2. 沉浸式体验

    • 符合历史氛围
    • 富有时代特色
    • 细节打造意境
  3. 交互友好

    • 操作直观
    • 反馈及时
    • 引导清晰

6.2 视觉风格

我们采用了现代简约与古典元素相结合的设计风格:

  1. 配色方案

    :root {--primary-color: #4A90E2;--secondary-color: #F5A623;--text-color: #2C3E50;--background-color: #F8F9FA;--border-color: #E2E8F0;
    }
    
  2. 字体选择

    • 中文:思源宋体
    • 英文:Roboto
    • 代码:JetBrains Mono
  3. 布局网格

    • 基础单位:8px
    • 内容区域最大宽度:1200px
    • 响应式断点:576px、768px、992px、1200px

7. 角色选择页面

7.1 布局设计

角色选择页面采用卡片式布局:

const CharacterSelect: React.FC = () => {return (<div className="character-select"><header className="header"><h1>穿越时空</h1><p>与历史对话</p></header><div className="character-grid">{historicalFigures.map(figure => (<CharacterCardkey={figure.id}figure={figure}onClick={() => handleSelect(figure)}/>))}</div></div>);
};

7.2 角色卡片设计

每个角色卡片包含:

  1. 视觉元素

    • 头像/形象
    • 姓名/时代
    • 特色标签
    • 简介文字
  2. 交互效果

    .character-card {transition: transform 0.3s ease;&:hover {transform: translateY(-5px);box-shadow: 0 10px 20px rgba(0,0,0,0.1);}
    }
    
  3. 信息展示

    const CharacterCard: React.FC<Props> = ({ figure }) => (<div className="character-card"><div className="avatar">{figure.avatar}</div><h3>{figure.name}</h3><p className="period">{figure.period}</p><p className="description">{figure.description}</p><div className="personality-tags">{figure.personality.split(',').map(tag => (<span className="tag">{tag}</span>))}</div></div>
    );
    

8. 对话界面实现

8.1 整体布局

对话界面分为三个主要部分:

  1. 顶部导航

    • 返回按钮
    • 当前角色信息
    • 功能按钮
  2. 对话区域

    • 消息气泡
    • 打字机效果
    • 滚动加载
  3. 输入区域

    • 消息输入框
    • 发送按钮
    • 快捷操作

8.2 消息展示

实现了富有特色的消息气泡:

const MessageBubble: React.FC<Props> = ({ message, isUser }) => (<div className={`message ${isUser ? 'user' : 'assistant'}`}><div className="avatar">{isUser ? '👤' : selectedFigure.avatar}</div><div className="content"><div className="bubble">{message.content}</div><div className="time">{formatTime(message.timestamp)}</div></div></div>
);

8.3 打字机效果

实现了自然的打字机效果:

const simulateTyping = async (content: string) => {await new Promise(resolve => setTimeout(resolve, 500 + Math.random() * 1000));return content;
};

8.4 历史记录功能

实现了完整的对话历史管理:

interface ChatHistory {characterId: string;messages: ChatMessage[];lastUpdated: string;
}export const saveChatHistory = (characterId: string, messages: ChatMessage[]) => {try {const existingHistory = localStorage.getItem(CHAT_HISTORY_KEY);const history = existingHistory ? JSON.parse(existingHistory) : {};history[characterId] = {characterId,messages,lastUpdated: new Date().toISOString()};localStorage.setItem(CHAT_HISTORY_KEY, JSON.stringify(history));} catch (error) {console.error('Failed to save chat history:', error);}
};

9. 动画效果

9.1 过渡动画

使用CSS transitions实现平滑过渡:

.fade-enter {opacity: 0;transform: translateY(20px);
}.fade-enter-active {opacity: 1;transform: translateY(0);transition: opacity 300ms, transform 300ms;
}.fade-exit {opacity: 1;
}.fade-exit-active {opacity: 0;transition: opacity 300ms;
}

9.2 加载动画

实现了优雅的加载效果:

.typing-indicator {display: flex;gap: 4px;padding: 8px 12px;.dot {width: 8px;height: 8px;background: var(--primary-color);border-radius: 50%;animation: bounce 1.4s infinite ease-in-out;&:nth-child(1) { animation-delay: -0.32s; }&:nth-child(2) { animation-delay: -0.16s; }}
}@keyframes bounce {0%, 80%, 100% { transform: scale(0); }40% { transform: scale(1); }
}

10. 响应式设计

10.1 媒体查询

实现了完整的响应式布局:

/* 移动端 */
@media (max-width: 576px) {.character-grid {grid-template-columns: 1fr;}
}/* 平板 */
@media (min-width: 577px) and (max-width: 992px) {.character-grid {grid-template-columns: repeat(2, 1fr);}
}/* 桌面端 */
@media (min-width: 993px) {.character-grid {grid-template-columns: repeat(3, 1fr);}
}

10.2 弹性布局

使用Flexbox实现灵活的布局:

.chat-container {display: flex;flex-direction: column;height: 100vh;.chat-messages {flex: 1;overflow-y: auto;}.chat-input {padding: 1rem;border-top: 1px solid var(--border-color);}
}

11. 性能优化

11.1 虚拟滚动

实现了消息列表的虚拟滚动:

import { FixedSizeList } from 'react-window';const MessageList: React.FC<Props> = ({ messages }) => (<FixedSizeListheight={600}itemCount={messages.length}itemSize={80}width="100%">{({ index, style }) => (<MessageItemmessage={messages[index]}style={style}/>)}</FixedSizeList>
);

11.2 防抖处理

对输入和滚动事件进行防抖处理:

const debouncedScroll = debounce(() => {const { scrollTop, scrollHeight, clientHeight } = messagesRef.current;if (scrollHeight - scrollTop === clientHeight) {loadMoreMessages();}
}, 200);

11.3 懒加载

实现了图片和组件的懒加载:

const LazyCharacterCard = React.lazy(() => import('./CharacterCard'));const CharacterGrid = () => (<Suspense fallback={<Skeleton />}>{figures.map(figure => (<LazyCharacterCardkey={figure.id}figure={figure}/>))}</Suspense>
);

12. 性能优化策略

12.1 代码层面优化

12.1.1 React优化
  1. 组件优化
// 使用React.memo避免不必要的重渲染
const MessageBubble = React.memo<Props>(({ message, isUser }) => {return (<div className={`message ${isUser ? 'user' : 'assistant'}`}>{/* 消息内容 */}</div>);
});// 使用useCallback优化事件处理函数
const handleSendMessage = useCallback(() => {// 处理发送消息
}, [dependencies]);
  1. 状态管理优化
// 使用useReducer处理复杂状态
const [state, dispatch] = useReducer(chatReducer, initialState);// 分离状态逻辑
const chatReducer = (state, action) => {switch (action.type) {case 'ADD_MESSAGE':return {...state,messages: [...state.messages, action.payload]};case 'CLEAR_HISTORY':return {...state,messages: []};default:return state;}
};
12.1.2 资源加载优化
  1. 代码分割
// 路由级别的代码分割
const ChatInterface = lazy(() => import('./pages/ChatInterface'));
const CharacterSelect = lazy(() => import('./pages/CharacterSelect'));// 组件级别的代码分割
const MarkdownRenderer = lazy(() => import('./components/MarkdownRenderer'));
  1. 资源预加载
// 预加载关键资源
const prefetchResources = () => {const links = [{ rel: 'prefetch', href: '/assets/fonts/main.woff2' },{ rel: 'preload', href: '/assets/images/sprites.png', as: 'image' }];links.forEach(link => {const linkElement = document.createElement('link');Object.assign(linkElement, link);document.head.appendChild(linkElement);});
};

12.2 网络优化

12.2.1 API请求优化
  1. 请求缓存
const cache = new Map();const cachedFetch = async (url: string) => {if (cache.has(url)) {return cache.get(url);}const response = await fetch(url);const data = await response.json();cache.set(url, data);return data;
};
  1. 请求合并
const batchRequest = async (requests: Request[]) => {const batchId = generateBatchId();return await api.post('/batch', {batchId,requests});
};
12.2.2 WebSocket优化
class WebSocketManager {private ws: WebSocket;private reconnectAttempts = 0;private maxReconnectAttempts = 5;constructor(url: string) {this.ws = new WebSocket(url);this.setupEventHandlers();}private setupEventHandlers() {this.ws.onclose = () => {if (this.reconnectAttempts < this.maxReconnectAttempts) {setTimeout(() => this.reconnect(), 1000 * Math.pow(2, this.reconnectAttempts));}};}private reconnect() {this.reconnectAttempts++;// 重新连接逻辑}
}

12.3 存储优化

12.3.1 本地存储优化
  1. 数据压缩
import { compress, decompress } from 'lz-string';const saveCompressedData = (key: string, data: any) => {const compressed = compress(JSON.stringify(data));localStorage.setItem(key, compressed);
};const loadCompressedData = (key: string) => {const compressed = localStorage.getItem(key);if (!compressed) return null;return JSON.parse(decompress(compressed));
};
  1. 存储管理
class StorageManager {private maxSize = 5 * 1024 * 1024; // 5MBasync cleanup() {const items = { ...localStorage };const totalSize = Object.values(items).reduce((size, item) => size + item.length, 0);if (totalSize > this.maxSize) {// 清理最旧的数据const oldestKey = this.findOldestKey();localStorage.removeItem(oldestKey);}}
}

13. 用户体验优化

13.1 交互优化

13.1.1 输入优化
  1. 智能提示
const AutoComplete: React.FC<Props> = ({ suggestions, onSelect }) => {return (<div className="autocomplete">{suggestions.map(suggestion => (<divkey={suggestion.id}className="suggestion"onClick={() => onSelect(suggestion)}>{suggestion.text}</div>))}</div>);
};
  1. 输入防抖
const useDebounce = (value: string, delay: number) => {const [debouncedValue, setDebouncedValue] = useState(value);useEffect(() => {const handler = setTimeout(() => {setDebouncedValue(value);}, delay);return () => {clearTimeout(handler);};}, [value, delay]);return debouncedValue;
};

13.2 动画优化

13.2.1 性能优化的动画
.optimized-animation {will-change: transform;transform: translateZ(0);backface-visibility: hidden;
}@keyframes smooth-entrance {from {opacity: 0;transform: translateY(20px);}to {opacity: 1;transform: translateY(0);}
}
13.2.2 动画管理
class AnimationManager {private animations: Map<string, Animation> = new Map();register(id: string, animation: Animation) {this.animations.set(id, animation);}play(id: string) {const animation = this.animations.get(id);if (animation) {animation.play();}}pause(id: string) {const animation = this.animations.get(id);if (animation) {animation.pause();}}
}

结语

"穿越时空对话机"探索了如何将先进的AI技术与教育需求相结合的可能性。通过这个项目,我们不仅实现了有趣的历史对话功能,也积累了宝贵的技术经验。

未来,我们将继续优化和扩展这个项目,让更多人能够通过这种创新的方式学习历史、感受文化。我们相信,技术的进步将为教育带来更多可能性。


Gitee源码

http://www.lryc.cn/news/515474.html

相关文章:

  • 公共数据授权运营系统建设手册(附下载)
  • 基于HTML和CSS的旅游小程序
  • maven之插件调试
  • SQL Sever 数据库损坏,只有.mdf文件,如何恢复?
  • 【AWS SDK PHP】This operation requests `sigv4a` auth schemes 问题处理
  • primevue的<Menu>组件
  • 利用Deeplearning4j进行 图像识别
  • 练习题:37
  • Unity热更文件比较工具类
  • 【hustoj注意事项】函数返回值问题
  • 实现一个通用的树形结构构建工具
  • 数势科技:解锁数据分析 Agent 的智能密码(14/30)
  • 机器学习之过采样和下采样调整不均衡样本的逻辑回归模型
  • 解决 ssh connect to host github.com port 22 Connection timed out
  • mybatis/mybatis-plus中mysql报错
  • 在ros2 jazzy和gazebo harmonic下的建图导航(cartographer和navigation)实现(基本)
  • 《Rust权威指南》学习笔记(五)
  • GitHub的简单操作
  • 「Mac畅玩鸿蒙与硬件54」UI互动应用篇31 - 滑动解锁屏幕功能
  • SMMU软件指南之系统架构考虑
  • 使用高云小蜜蜂GW1N-2实现MIPI到LVDS(DVP)转换案例分享
  • 「C++笔记」unordered_map:哈希化的无序映射函数(键值对)
  • Linux 安装jdk
  • asp.net core 发布到iis后,一直500.19,IIS设置没问题,安装了sdk,文件夹权限都有,还是报错
  • 【Go】运行自己的第一个Go程序
  • qt qss文件的使用
  • 【管道——二分+区间合并】
  • 宽带、光猫、路由器、WiFi、光纤之间的关系
  • 如何排查 Apache Doris 中 “Failed to commit txn“ 导入失败问题?
  • 回归预测 | MATLAB实现CNN-GRU卷积门控循环单元多输入单输出回归预测