# noteSystem **Repository Path**: phoenix-cities/note-system ## Basic Information - **Project Name**: noteSystem - **Description**: 这是一个智能笔记本系统用来完成毕设。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-08 - **Last Updated**: 2026-05-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 智能笔记系统 一个基于Spring Boot 3.x + Vue 3的智能个人笔记管理系统,集成了Spring AI提供智能辅助功能,支持跨设备同步、标签分类、版本管理等高级特性。 ## 技术栈 ### 后端技术 - **Spring Boot 3.2.6** - 核心框架 - **Spring Security** - 安全认证与授权 - **Spring Data JPA** - 数据持久化 - **MyBatis** - SQL映射框架 - **Spring AI 1.0.0-M6** - AI功能集成 - **MySQL 8.0+** - 关系型数据库 - **Redis** - 缓存与分布式锁 - **JWT** - Token认证 - **Spring Mail** - 邮件服务 ### 前端技术 - **Vue 3** - 前端框架 - **Element Plus** - UI组件库 - **Axios** - HTTP客户端 - **Pinia** - 状态管理 - **Vue Router** - 路由管理 ### Python搜索服务 - **Python 3.8+** - 编程语言 - **Flask** - 轻量级Web框架 - **SQLite** - 索引存储数据库 - **Whoosh** - 全文搜索引擎 ## 快速开始 ### 环境要求 - JDK 21+ - Node.js 18+ - Python 3.8+ - MySQL 8.0+ - Maven 3.8+ ### 启动步骤 #### 1. 启动后端服务 ```bash # 进入项目根目录 cd noteDemo # 编译项目 mvn clean compile # 运行后端服务 mvn spring-boot:run ``` 后端服务将在 `http://localhost:8080` 启动。 #### 2. 启动Python搜索服务 ```bash # 进入项目根目录 cd noteDemo # 安装依赖(首次运行) pip install flask whoosh # 启动搜索服务 python search_service.py ``` 搜索服务将在 `http://localhost:5000` 启动。 #### 3. 启动前端服务 ```bash # 进入前端目录 cd noteDemo/frontend # 安装依赖(首次运行) npm install # 启动开发服务器 npm run dev ``` 前端服务将在 `http://localhost:5173` 启动(端口可能因配置而异)。 ### 启动顺序 **正确的启动顺序:** 1. 后端服务(Spring Boot) 2. Python搜索服务 3. 前端服务 ### 停止服务 按 `Ctrl+C` 在各自终端停止服务。 ## 项目结构 ``` noteDemo/ ├── src/main/java/org/example/notedemo/ │ ├── common/ # 通用响应类 │ ├── config/ # 配置类 │ ├── controller/ # 控制器层 │ ├── dto/ # 数据传输对象 │ ├── entity/ # 实体类 │ ├── exception/ # 异常处理 │ ├── mapper/ # MyBatis Mapper │ ├── repository/ # JPA Repository │ ├── security/ # 安全配置 │ ├── service/ # 业务逻辑层 │ └── util/ # 工具类 ├── frontend/ # 前端项目 │ ├── src/ │ │ ├── router/ # 路由配置 │ │ ├── stores/ # 状态管理 │ │ ├── utils/ # 工具函数 │ │ └── views/ # 页面组件 │ └── package.json └── pom.xml ``` ## 功能实现详解 ### 1. 注册功能实现 #### 功能概述 支持用户注册,包含邮箱验证码验证、密码加密存储、用户信息完整性校验等功能。 #### 核心实现 **前端实现** ([Register.vue](frontend/src/views/Register.vue)) - 表单字段:用户名、密码、确认密码、昵称、邮箱、验证码、手机号 - 实时表单验证:用户名唯一性、邮箱格式、密码强度检查 - 验证码发送:60秒倒计时,防止重复发送 - 注册成功后自动登录并跳转到首页 **后端实现** ([AuthController.java](src/main/java/org/example/notedemo/controller/AuthController.java)) - 发送验证码接口:`POST /api/auth/send-code` - 注册接口:`POST /api/auth/register` **业务逻辑** ([UserService.java](src/main/java/org/example/notedemo/service/UserService.java)) ```java @Transactional public UserInfoDTO register(RegisterRequest request) { // 1. 检查用户名是否已存在 if (userRepository.existsByUsername(request.getUsername())) { throw new BusinessException("用户名已存在"); } // 2. 验证邮箱必填 if (request.getEmail() == null || request.getEmail().isBlank()) { throw new BusinessException("邮箱不能为空"); } // 3. 检查邮箱是否已被注册 if (userRepository.existsByEmail(request.getEmail())) { throw new BusinessException("邮箱已被注册"); } // 4. 验证验证码 verificationCodeService.verifyCode(request.getEmail(), request.getVerificationCode(), TYPE_REGISTER); // 5. 检查手机号(如果提供) if (request.getPhone() != null && !request.getPhone().isBlank() && userRepository.existsByPhone(request.getPhone())) { throw new BusinessException("手机号已被注册"); } // 6. 创建用户(密码BCrypt加密) SysUser user = SysUser.builder() .username(request.getUsername()) .password(passwordEncoder.encode(request.getPassword())) .nickname(request.getNickname()) .email(request.getEmail()) .phone(request.getPhone()) .status(1) .build(); user = userRepository.save(user); return toUserInfoDTO(user); } ``` **验证码服务** ([VerificationCodeService.java](src/main/java/org/example/notedemo/service/VerificationCodeService.java)) - 防重复发送检查(60秒限制) - 生成6位数字验证码 - Redis存储(5分钟过期)+ 数据库备份 - 邮件发送失败时回滚 **安全特性** - BCrypt密码加密 - 验证码机制防止恶意注册 - 参数校验(@Valid注解) - 事务管理保证数据一致性 --- ### 2. 登录功能实现 #### 功能概述 支持用户名/邮箱登录、记住我功能、JWT Token认证、登录状态持久化。 #### 核心实现 **前端实现** ([Login.vue](frontend/src/views/Login.vue)) - 支持用户名或邮箱登录 - 记住我选项(7天有效期) - 登录成功后存储Token到localStorage - 自动跳转到首页 **后端实现** ([AuthController.java](src/main/java/org/example/notedemo/controller/AuthController.java)) - 登录接口:`POST /api/auth/login` - 登出接口:`POST /api/auth/logout` **认证流程** 1. 用户提交登录信息 2. CustomUserDetailsService加载用户详情 3. BCrypt密码验证 4. JwtTokenProvider生成JWT Token 5. 返回用户信息和Token **JWT配置** ([JwtTokenProvider.java](src/main/java/org/example/notedemo/security/JwtTokenProvider.java)) - Token有效期:24小时(默认)/ 7天(记住我) - Secret密钥配置 - Token解析与验证 **安全过滤器** ([JwtAuthenticationFilter.java](src/main/java/org/example/notedemo/security/JwtAuthenticationFilter.java)) - 拦截所有请求(除登录、注册等公开接口) - 从请求头提取Token - 验证Token有效性 - 设置用户认证信息到SecurityContext --- ### 3. 用户个人信息管理功能实现 #### 功能概述 支持用户查看和修改个人信息、修改密码、上传头像等功能。 #### 核心实现 **前端实现** ([Profile.vue](frontend/src/views/Profile.vue)) - 个人信息表单:用户名(只读)、邮箱、昵称、个人简介 - 密码修改表单:当前密码、新密码、确认密码 - 表单验证:邮箱格式、密码长度、密码确认 - 实时更新用户信息到Pinia Store **后端接口** - 获取当前用户信息:`GET /api/auth/me` - 更新个人信息:`PUT /api/auth/profile` - 修改密码:`PUT /api/auth/password` **业务逻辑** ([UserService.java](src/main/java/org/example/notedemo/service/UserService.java)) **更新个人信息** ```java @Transactional public UserInfoDTO updateProfile(UpdateProfileRequest request) { Long userId = SecurityUtils.getCurrentUserId(); SysUser user = userRepository.findById(userId) .orElseThrow(() -> new BusinessException("用户不存在")); if (request.getNickname() != null && !request.getNickname().isBlank()) { user.setNickname(request.getNickname().trim()); } if (request.getEmail() != null && !request.getEmail().isBlank()) { if (userRepository.existsByEmailAndIdNot(request.getEmail(), userId)) { throw new BusinessException("邮箱已被其他用户使用"); } user.setEmail(request.getEmail().trim()); } if (request.getPhone() != null && !request.getPhone().isBlank()) { if (userRepository.existsByPhoneAndIdNot(request.getPhone(), userId)) { throw new BusinessException("手机号已被其他用户使用"); } user.setPhone(request.getPhone().trim()); } if (request.getAvatar() != null) { user.setAvatar(request.getAvatar()); } user = userRepository.save(user); return toUserInfoDTO(user); } ``` **修改密码** ```java @Transactional public void changePassword(ChangePasswordRequest request) { Long userId = SecurityUtils.getCurrentUserId(); SysUser user = userRepository.findById(userId) .orElseThrow(() -> new BusinessException("用户不存在")); if (!passwordEncoder.matches(request.getOldPassword(), user.getPassword())) { throw new BusinessException("当前密码错误"); } if (request.getOldPassword().equals(request.getNewPassword())) { throw new BusinessException("新密码不能与当前密码相同"); } user.setPassword(passwordEncoder.encode(request.getNewPassword())); userRepository.save(user); } ``` **密码重置流程** 1. 用户请求重置密码(提供邮箱) 2. 系统生成重置Token并发送邮件 3. 用户点击邮件中的重置链接 4. 验证Token有效性 5. 用户输入新密码完成重置 --- ### 4. 记事本基础功能实现(内容增、删、改、查) #### 功能概述 支持笔记的创建、查询、更新、删除(软删除)、置顶、收藏、版本回滚等功能。 #### 核心实现 **前端实现** - [Notebooks.vue](frontend/src/views/Notebooks.vue) - 记事本列表 - [Notes.vue](frontend/src/views/Notes.vue) - 笔记列表 - [NoteDetail.vue](frontend/src/views/NoteDetail.vue) - 笔记详情与编辑 **后端接口** ([NoteController.java](src/main/java/org/example/notedemo/controller/NoteController.java)) - 分页查询记事本下的笔记:`GET /api/notes?bookId={bookId}` - 分页查询所有笔记:`GET /api/notes/all` - 获取笔记详情:`GET /api/notes/{id}` - 创建笔记:`POST /api/notes` - 更新笔记:`PUT /api/notes/{id}` - 软删除笔记:`DELETE /api/notes/{id}` - 恢复笔记:`PUT /api/notes/{id}/restore` - 永久删除笔记:`DELETE /api/notes/{id}/permanent` - 置顶/取消置顶:`PUT /api/notes/{id}/pin` - 收藏/取消收藏:`PUT /api/notes/{id}/star` - 获取笔记修改历史:`GET /api/notes/{id}/history` - 版本回滚:`POST /api/notes/{id}/rollback` **业务逻辑** ([NoteContentService.java](src/main/java/org/example/notedemo/service/NoteContentService.java)) **创建笔记** ```java @Transactional public NoteDTO createNote(NoteCreateRequest request) { Long userId = SecurityUtils.getCurrentUserId(); ensureBookBelongsToUser(request.getBookId(), userId); String content = request.getContent() != null ? request.getContent() : ""; String plainContent = HtmlUtils.extractPlainText(content); NoteContent note = NoteContent.builder() .bookId(request.getBookId()) .title(request.getTitle() != null ? request.getTitle().trim() : "无标题") .content(content) .plainContent(plainContent) .build(); note = noteContentRepository.save(note); saveHistory(note); return toDTO(note); } ``` **更新笔记** ```java @Transactional public NoteDTO updateNote(Long id, NoteUpdateRequest request) { Long userId = SecurityUtils.getCurrentUserId(); NoteContent note = noteContentRepository.findByIdAndUserId(id, userId) .orElseThrow(() -> new BusinessException("笔记不存在")); if (note.getDeleteFlag() == 1) { throw new BusinessException("笔记已删除"); } boolean contentChanged = false; if (request.getTitle() != null) { note.setTitle(request.getTitle().trim().isEmpty() ? "无标题" : request.getTitle().trim()); } if (request.getContent() != null) { note.setContent(request.getContent()); note.setPlainContent(HtmlUtils.extractPlainText(request.getContent())); contentChanged = true; } if (request.getBookId() != null && !request.getBookId().equals(note.getBookId())) { ensureBookBelongsToUser(request.getBookId(), userId); note.setBookId(request.getBookId()); } if (request.getIsStar() != null) { note.setIsStar(request.getIsStar() ? 1 : 0); } if (request.getIsPinned() != null) { note.setIsPinned(request.getIsPinned() ? 1 : 0); } note = noteContentRepository.save(note); if (contentChanged) { saveHistory(note); } return toDTO(note); } ``` **软删除与恢复** - 软删除:设置deleteFlag=1,笔记移至回收站 - 恢复:设置deleteFlag=0,笔记恢复正常 - 永久删除:仅对已软删除的笔记有效,彻底删除数据 **版本管理** - 每次修改笔记内容时自动保存历史版本 - 最多保留20个历史版本 - 支持回滚到任意历史版本 - 历史版本包含标题和内容快照 --- ### 5. 记事本分类与标签管理功能实现 #### 功能概述 支持创建和管理记事本(分类)、创建和管理标签、为笔记绑定标签、按标签筛选笔记、统计功能等。 #### 核心实现 **前端实现** - [Notebooks.vue](frontend/src/views/Notebooks.vue) - 记事本管理 - [Notes.vue](frontend/src/views/Notes.vue) - 标签筛选与笔记展示 **后端接口** **记事本管理** ([NoteBookController.java](src/main/java/org/example/notedemo/controller/NoteBookController.java)) - 获取所有记事本:`GET /api/notebooks` - 创建记事本:`POST /api/notebooks` - 更新记事本:`PUT /api/notebooks/{id}` - 删除记事本:`DELETE /api/notebooks/{id}` - 排序记事本:`PUT /api/notebooks/sort` **标签管理** ([TagController.java](src/main/java/org/example/notedemo/controller/TagController.java)) - 获取所有标签:`GET /api/tags` - 创建标签:`POST /api/tags` - 更新标签:`PUT /api/tags/{id}` - 删除标签:`DELETE /api/tags/{id}` - 获取笔记的标签:`GET /api/tags/note/{noteId}` - 绑定标签到笔记:`POST /api/tags/bind` - 按标签筛选笔记:`GET /api/tags/{tagId}/notes` - 获取统计信息:`GET /api/tags/stats` **业务逻辑** ([TagService.java](src/main/java/org/example/notedemo/service/TagService.java)) **创建标签** ```java @Transactional public TagDTO createTag(TagCreateRequest request) { Long userId = SecurityUtils.getCurrentUserId(); String name = request.getTagName().trim(); if (noteTagRepository.existsByUserIdAndTagName(userId, name)) { throw new BusinessException("标签名称已存在"); } String color = request.getTagColor() != null ? request.getTagColor() : "#333333"; NoteTag tag = NoteTag.builder() .userId(userId) .tagName(name) .tagColor(color) .build(); tag = noteTagRepository.save(tag); return toTagDTO(tag); } ``` **绑定标签到笔记** ```java @Transactional public void bindTagsToNote(TagBindRequest request) { Long userId = SecurityUtils.getCurrentUserId(); NoteContent note = noteContentRepository.findByIdAndUserId(request.getNoteId(), userId) .orElseThrow(() -> new BusinessException("笔记不存在")); if (note.getDeleteFlag() == 1) { throw new BusinessException("笔记已删除"); } relationRepository.deleteByNoteId(request.getNoteId()); if (request.getTagIds() != null && !request.getTagIds().isEmpty()) { for (Long tagId : request.getTagIds()) { noteTagRepository.findByIdAndUserId(tagId, userId) .orElseThrow(() -> new BusinessException("标签不存在: " + tagId)); if (!relationRepository.existsByNoteIdAndTagId(request.getNoteId(), tagId)) { relationRepository.save(NoteTagRelation.builder() .noteId(request.getNoteId()) .tagId(tagId) .build()); } } } } ``` **统计功能** - 按标签统计笔记数量 - 按记事本统计笔记数量 - 返回标签和记事本的分布情况 **数据模型** - note_book:记事本表,支持排序、封面图片、描述等 - note_tag:标签表,支持自定义颜色 - note_tag_relation:笔记-标签关联表,多对多关系 --- ### 6. 数据备份与跨设备同步功能实现 #### 功能概述 支持数据备份记录、跨设备同步、同步状态跟踪、错误处理等功能。 #### 核心实现 **数据模型** ([SyncRecord.java](src/main/java/org/example/notedemo/entity/SyncRecord.java)) ```java @Entity @Table(name = "sync_record") public class SyncRecord { private Long id; private Long userId; private String deviceId; // 设备唯一标识 private String syncType; // 同步类型:create/update/delete private String syncTable; // 同步的数据表 private Long recordId; // 同步记录的ID private LocalDateTime syncTime; // 同步时间 private Integer syncStatus; // 同步状态:1-成功,0-失败 private String errorMsg; // 错误信息 } ``` **数据访问层** ([SyncRecordMapper.java](src/main/java/org/example/notedemo/mapper/SyncRecordMapper.java)) 提供了丰富的查询方法: - 按用户ID查询同步记录 - 按设备ID查询同步记录 - 按同步类型查询 - 按同步状态查询 - 按时间范围查询 - 分页查询 - 统计查询 **同步流程设计** 1. 用户在设备A上创建/修改/删除笔记 2. 系统记录同步操作到sync_record表 3. 设备B请求同步数据 4. 系统返回该用户的所有同步记录 5. 设备B根据同步记录更新本地数据 6. 更新同步状态为成功 **同步记录示例** ```sql -- 创建笔记的同步记录 INSERT INTO sync_record (user_id, device_id, sync_type, sync_table, record_id, sync_time, sync_status) VALUES (1, 'device-uuid-001', 'create', 'note_content', 100, NOW(), 1); -- 更新笔记的同步记录 INSERT INTO sync_record (user_id, device_id, sync_type, sync_table, record_id, sync_time, sync_status) VALUES (1, 'device-uuid-001', 'update', 'note_content', 100, NOW(), 1); -- 删除笔记的同步记录 INSERT INTO sync_record (user_id, device_id, sync_type, sync_table, record_id, sync_time, sync_status) VALUES (1, 'device-uuid-001', 'delete', 'note_content', 100, NOW(), 1); ``` **错误处理** - 同步失败时记录错误信息 - 支持查询失败的同步记录 - 支持重试失败的同步操作 **数据清理** - 定期清理过期的同步记录 - 保留最近30天的同步记录 --- ### 7. Spring AI 智能功能集成与实现(文本纠错、智能摘要、内容润色) #### 功能概述 集成Spring AI框架,提供文本纠错、智能摘要、内容润色等AI辅助功能,提升笔记质量和效率。 #### 核心实现 **AI配置** ([ChatClientConfig.java](src/main/java/org/example/notedemo/config/ChatClientConfig.java)) ```java @Configuration public class ChatClientConfig { @Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder.build(); } } ``` **配置文件** ([application.yml](src/main/resources/application.yml)) ```yaml spring: ai: openai: api-key: your_api_key base-url: https://api.deepseek.com chat: options: model: deepseek-chat temperature: 0.7 ``` **AI服务** ([ChatService.java](src/main/java/org/example/notedemo/service/ChatService.java)) ```java @Service public class ChatService { private final ChatClient chatClient; public String chat(String message) { return chatClient.prompt(message).call().content(); } } ``` **AI接口** ([ChatController.java](src/main/java/org/example/notedemo/controller/ChatController.java)) ```java @RestController @RequestMapping("/api/chat") public class ChatController { private final ChatService chatService; @PostMapping("/send") public String sendMessage(@RequestBody String message) { return chatService.chat(message); } } ``` **AI功能实现** **文本纠错** ```java public String correctText(String text) { String prompt = "请帮我纠正以下文本中的语法和拼写错误,只返回纠正后的文本:\n" + text; return chatService.chat(prompt); } ``` **智能摘要** ```java public String generateSummary(String content) { String prompt = "请为以下内容生成一个简洁的摘要(100字以内):\n" + content; return chatService.chat(prompt); } ``` **内容润色** ```java public String polishContent(String content) { String prompt = "请帮我润色以下内容,使其更加流畅和专业:\n" + content; return chatService.chat(prompt); } ``` **AI调用日志** ([AiCallLog.java](src/main/java/org/example/notedemo/entity/AiCallLog.java)) 记录每次AI调用的详细信息: - 用户ID - 关联笔记ID - AI功能类型(summary/correct/polish/search) - 输入内容 - 输出内容 - 调用状态 - 错误信息 - 调用时间 - 消耗时间 - Token消耗 **数据访问层** ([AiCallLogMapper.java](src/main/java/org/example/notedemo/mapper/AiCallLogMapper.java)) 提供了丰富的查询和统计方法: - 按用户查询AI调用记录 - 按AI功能类型查询 - 按调用状态查询 - 按时间范围查询 - 统计调用次数 - 统计消耗时间 - 查询最耗时/最省时的调用 **前端集成** ([Chat.vue](frontend/src/views/Chat.vue)) - AI对话界面 - 文本纠错功能 - 智能摘要生成 - 内容润色功能 - 调用历史查看 **使用示例** ```javascript // 文本纠错 const correctText = async (text) => { const response = await axios.post('/api/chat/send', `请帮我纠正以下文本中的语法和拼写错误:\n${text}` ); return response.data; }; // 生成摘要 const generateSummary = async (content) => { const response = await axios.post('/api/chat/send', `请为以下内容生成一个简洁的摘要:\n${content}` ); return response.data; }; // 内容润色 const polishContent = async (content) => { const response = await axios.post('/api/chat/send', `请帮我润色以下内容:\n${content}` ); return response.data; }; ``` --- ### 8. 记事本内容检索功能实现(基础检索 + AI 辅助精准检索) #### 功能概述 支持基础关键词检索和AI辅助的语义检索,提供更精准的搜索结果。 #### 核心实现 **基础检索** **前端实现** ([Notes.vue](frontend/src/views/Notes.vue)) ```javascript const searchNotes = async (keyword) => { const response = await axios.get('/api/notes/search', { params: { keyword } }); return response.data; }; ``` **后端实现** ```java @GetMapping("/search") public Result> searchNotes( @RequestParam String keyword, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { return Result.success(noteContentService.searchNotes(keyword, page, size)); } ``` **业务逻辑** ```java public Page searchNotes(String keyword, int page, int size) { Long userId = SecurityUtils.getCurrentUserId(); Pageable pageable = PageRequest.of(page, size); return noteContentRepository.findByUserIdAndKeyword(userId, keyword, pageable) .map(this::toDTO); } ``` **数据库查询** ```sql -- 使用LIKE进行模糊匹配 SELECT * FROM note_content WHERE user_id = ? AND delete_flag = 0 AND (title LIKE ? OR plain_content LIKE ?) ORDER BY update_time DESC LIMIT ? OFFSET ?; ``` **AI辅助精准检索** **实现思路** 1. 用户输入搜索关键词 2. 使用AI理解用户意图 3. AI生成优化后的搜索关键词 4. 使用优化后的关键词进行检索 5. 返回更精准的结果 **AI辅助搜索** ```java public Page aiSearchNotes(String keyword, int page, int size) { Long userId = SecurityUtils.getCurrentUserId(); // 使用AI优化搜索关键词 String optimizedKeyword = optimizeSearchKeyword(keyword); // 使用优化后的关键词进行搜索 Pageable pageable = PageRequest.of(page, size); return noteContentRepository.findByUserIdAndKeyword(userId, optimizedKeyword, pageable) .map(this::toDTO); } private String optimizeSearchKeyword(String keyword) { String prompt = "请帮我优化以下搜索关键词,使其更加精准,只返回优化后的关键词:\n" + keyword; return chatService.chat(prompt); } ``` **语义搜索** ```java public Page semanticSearch(String query, int page, int size) { Long userId = SecurityUtils.getCurrentUserId(); // 使用AI理解查询意图 String intent = understandQueryIntent(query); // 根据意图生成多个相关关键词 List keywords = generateRelatedKeywords(intent); // 使用多个关键词进行搜索 Page results = searchByKeywords(userId, keywords, page, size); // 使用AI对结果进行排序和过滤 return rankAndFilterResults(results, query); } private String understandQueryIntent(String query) { String prompt = "请分析以下查询的意图,返回简洁的意图描述:\n" + query; return chatService.chat(prompt); } private List generateRelatedKeywords(String intent) { String prompt = "请为以下意图生成5个相关的搜索关键词,用逗号分隔:\n" + intent; String response = chatService.chat(prompt); return Arrays.asList(response.split(",")); } ``` **搜索历史记录** - 记录用户的搜索历史 - 支持查看历史搜索 - 支持删除历史搜索 **搜索建议** - 根据用户输入提供搜索建议 - 基于历史搜索记录 - 基于热门搜索 --- ### 9. 系统设置功能实现(隐私设置、智能功能参数配置) #### 功能概述 支持用户自定义系统设置,包括AI功能开关、隐私设置、主题设置、同步间隔等。 #### 核心实现 **数据模型** ([SysSetting.java](src/main/java/org/example/notedemo/entity/SysSetting.java)) ```java @Entity @Table(name = "sys_setting") public class SysSetting { private Long id; private Long userId; // AI功能设置 private Integer aiSwitch; // AI功能总开关 private Integer aiSummarySwitch; // 智能摘要开关 private Integer aiCorrectSwitch; // 文本纠错开关 private Integer aiPolishSwitch; // 内容润色开关 // 隐私设置 private Integer privacySetting; // 0-仅自己可见,1-部分可见 // 其他设置 private String theme; // 系统主题 private Integer syncInterval; // 自动同步间隔(分钟) private LocalDateTime createTime; private LocalDateTime updateTime; } ``` **数据访问层** ([SysSettingMapper.java](src/main/java/org/example/notedemo/mapper/SysSettingMapper.java)) ```java @Mapper public interface SysSettingMapper { @Select("SELECT * FROM sys_setting WHERE user_id = #{userId}") Optional findByUserId(Long userId); @Insert("INSERT INTO sys_setting (user_id, ai_switch, ai_summary_switch, ai_correct_switch, ai_polish_switch, privacy_setting, theme, sync_interval) " + "VALUES (#{userId}, #{aiSwitch}, #{aiSummarySwitch}, #{aiCorrectSwitch}, #{aiPolishSwitch}, #{privacySetting}, #{theme}, #{syncInterval})") @Options(useGeneratedKeys = true, keyProperty = "id") int insert(SysSetting sysSetting); @Update("UPDATE sys_setting SET ai_switch = #{aiSwitch}, ai_summary_switch = #{aiSummarySwitch}, ai_correct_switch = #{aiCorrectSwitch}, " + "ai_polish_switch = #{aiPolishSwitch}, privacy_setting = #{privacySetting}, theme = #{theme}, sync_interval = #{syncInterval} " + "WHERE user_id = #{userId}") int updateByUserId(SysSetting sysSetting); } ``` **业务逻辑** **获取用户设置** ```java public SysSetting getUserSettings(Long userId) { return sysSettingMapper.findByUserId(userId) .orElseGet(() -> { SysSetting defaultSettings = SysSetting.builder() .userId(userId) .aiSwitch(1) .aiSummarySwitch(1) .aiCorrectSwitch(1) .aiPolishSwitch(1) .privacySetting(0) .theme("default") .syncInterval(30) .build(); sysSettingMapper.insert(defaultSettings); return defaultSettings; }); } ``` **更新用户设置** ```java @Transactional public void updateUserSettings(Long userId, SysSetting settings) { SysSetting existing = sysSettingMapper.findByUserId(userId) .orElseThrow(() -> new BusinessException("设置不存在")); if (settings.getAiSwitch() != null) { existing.setAiSwitch(settings.getAiSwitch()); } if (settings.getAiSummarySwitch() != null) { existing.setAiSummarySwitch(settings.getAiSummarySwitch()); } if (settings.getAiCorrectSwitch() != null) { existing.setAiCorrectSwitch(settings.getAiCorrectSwitch()); } if (settings.getAiPolishSwitch() != null) { existing.setAiPolishSwitch(settings.getAiPolishSwitch()); } if (settings.getPrivacySetting() != null) { existing.setPrivacySetting(settings.getPrivacySetting()); } if (settings.getTheme() != null) { existing.setTheme(settings.getTheme()); } if (settings.getSyncInterval() != null) { existing.setSyncInterval(settings.getSyncInterval()); } sysSettingMapper.updateByUserId(existing); } ``` **AI功能开关控制** ```java public boolean isAiFunctionEnabled(Long userId, String functionType) { SysSetting settings = getUserSettings(userId); if (settings.getAiSwitch() == 0) { return false; } switch (functionType) { case "summary": return settings.getAiSummarySwitch() == 1; case "correct": return settings.getAiCorrectSwitch() == 1; case "polish": return settings.getAiPolishSwitch() == 1; default: return false; } } ``` **前端实现** **设置页面** - AI功能开关(总开关、摘要开关、纠错开关、润色开关) - 隐私设置(可见性设置) - 主题设置(选择系统主题) - 同步设置(自动同步间隔) **API调用** ```javascript // 获取用户设置 const getUserSettings = async () => { const response = await axios.get('/api/settings'); return response.data; }; // 更新用户设置 const updateUserSettings = async (settings) => { const response = await axios.put('/api/settings', settings); return response.data; }; ``` **设置项说明** **AI功能设置** - aiSwitch:AI功能总开关,关闭后所有AI功能不可用 - aiSummarySwitch:智能摘要开关,控制是否自动生成笔记摘要 - aiCorrectSwitch:文本纠错开关,控制是否启用文本纠错功能 - aiPolishSwitch:内容润色开关,控制是否启用内容润色功能 **隐私设置** - privacySetting:0-仅自己可见,1-部分可见 **其他设置** - theme:系统主题,支持多种主题切换 - syncInterval:自动同步间隔,单位为分钟 --- ## 数据库设计 ### 核心表结构 **用户表** (sys_user) - 存储用户基本信息 - 支持用户名、邮箱、手机号登录 - BCrypt密码加密存储 **记事本表** (note_book) - 存储记事本(分类)信息 - 支持排序、封面图片、描述 - 每个用户可以有多个记事本 **笔记内容表** (note_content) - 存储笔记的详细内容 - 支持富文本内容 - 支持置顶、收藏、软删除 - 自动提取纯文本用于检索 **笔记历史表** (note_history) - 存储笔记的修改历史 - 支持版本回滚 - 最多保留20个历史版本 **标签表** (note_tag) - 存储用户自定义标签 - 支持自定义标签颜色 **笔记-标签关联表** (note_tag_relation) - 实现笔记与标签的多对多关系 - 确保一个笔记不能重复关联同一标签 **验证码表** (verification_code) - 存储邮箱/手机验证码 - 支持注册、密码重置等场景 - 验证后标记为已使用 **密码重置令牌表** (password_reset_token) - 存储密码重置令牌 - 支持令牌过期机制 **数据同步记录表** (sync_record) - 记录跨设备同步操作 - 支持同步状态跟踪 - 支持错误信息记录 **系统设置表** (sys_setting) - 存储用户个性化设置 - 支持AI功能开关 - 支持隐私设置 **AI调用日志表** (ai_call_log) - 记录所有AI调用 - 支持调用统计和分析 - 支持成本计算 完整的数据库脚本请参考:[note_management_system.sql](note_management_system.sql) --- ## 安装与部署 ### 环境要求 - JDK 17+ - MySQL 8.0+ - Redis 6.0+ - Node.js 16+ ### 后端部署 1. **克隆项目** ```bash git clone cd noteDemo ``` 2. **配置数据库** ```bash # 创建数据库 mysql -u root -p < note_management_system.sql ``` 3. **修改配置文件** 编辑 `src/main/resources/application.yml`: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/note_management_system username: your_username password: your_password data: redis: host: localhost port: 6379 ai: openai: api-key: your_api_key base-url: https://api.deepseek.com jwt: secret: your_jwt_secret_key ``` 4. **启动项目** ```bash mvn spring-boot:run ``` ### 前端部署 1. **安装依赖** ```bash cd frontend npm install ``` 2. **配置代理** 编辑 `vite.config.js`: ```javascript export default defineConfig({ server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }) ``` 3. **启动开发服务器** ```bash npm run dev ``` 4. **构建生产版本** ```bash npm run build ``` --- ## API文档 ### 认证相关 - `POST /api/auth/register` - 用户注册 - `POST /api/auth/login` - 用户登录 - `POST /api/auth/logout` - 用户登出 - `GET /api/auth/me` - 获取当前用户信息 - `POST /api/auth/send-code` - 发送验证码 - `PUT /api/auth/profile` - 更新个人信息 - `PUT /api/auth/password` - 修改密码 ### 记事本相关 - `GET /api/notebooks` - 获取所有记事本 - `POST /api/notebooks` - 创建记事本 - `PUT /api/notebooks/{id}` - 更新记事本 - `DELETE /api/notebooks/{id}` - 删除记事本 - `PUT /api/notebooks/sort` - 排序记事本 ### 笔记相关 - `GET /api/notes` - 分页查询笔记 - `GET /api/notes/all` - 查询所有笔记 - `GET /api/notes/{id}` - 获取笔记详情 - `POST /api/notes` - 创建笔记 - `PUT /api/notes/{id}` - 更新笔记 - `DELETE /api/notes/{id}` - 软删除笔记 - `PUT /api/notes/{id}/restore` - 恢复笔记 - `DELETE /api/notes/{id}/permanent` - 永久删除笔记 - `PUT /api/notes/{id}/pin` - 置顶/取消置顶 - `PUT /api/notes/{id}/star` - 收藏/取消收藏 - `GET /api/notes/{id}/history` - 获取修改历史 - `POST /api/notes/{id}/rollback` - 版本回滚 ### 标签相关 - `GET /api/tags` - 获取所有标签 - `POST /api/tags` - 创建标签 - `PUT /api/tags/{id}` - 更新标签 - `DELETE /api/tags/{id}` - 删除标签 - `GET /api/tags/note/{noteId}` - 获取笔记的标签 - `POST /api/tags/bind` - 绑定标签到笔记 - `GET /api/tags/{tagId}/notes` - 按标签筛选笔记 - `GET /api/tags/stats` - 获取统计信息 ### AI相关 - `POST /api/chat/send` - AI对话 - `POST /api/ai/correct` - 文本纠错 - `POST /api/ai/summary` - 生成摘要 - `POST /api/ai/polish` - 内容润色 ### 设置相关 - `GET /api/settings` - 获取用户设置 - `PUT /api/settings` - 更新用户设置 --- ## 安全特性 1. **密码安全** - BCrypt加密存储 - 密码强度验证 - 密码重置Token机制 2. **认证授权** - JWT Token认证 - Token过期机制 - 记住我功能 3. **数据安全** - 用户数据隔离 - SQL注入防护 - XSS攻击防护 4. **接口安全** - 请求频率限制 - 参数校验 - 异常处理 --- ## 性能优化 1. **数据库优化** - 索引优化 - 查询优化 - 分页查询 2. **缓存策略** - Redis缓存验证码 - 缓存用户信息 - 缓存热点数据 3. **异步处理** - 邮件发送异步化 - AI调用异步化 - 日志记录异步化 --- ## 日志管理 所有Service层方法都添加了详细的日志记录: - 操作开始日志(info级别) - 参数信息日志(debug级别) - 业务异常日志(warn级别) - 系统异常日志(error级别) - 操作成功日志(info级别) --- ## 开发规范 1. **代码风格** - 遵循阿里巴巴Java开发手册 - 使用Lombok简化代码 - 统一异常处理 2. **命名规范** - 类名使用大驼峰 - 方法名使用小驼峰 - 常量使用全大写下划线分隔 3. **注释规范** - 类注释说明功能 - 方法注释说明参数和返回值 - 复杂逻辑添加行内注释 --- ## 常见问题 ### 1. Redis连接失败 检查Redis服务是否启动,配置文件中的Redis地址和端口是否正确。 ### 2. AI功能不可用 检查AI API Key是否配置正确,网络是否可以访问AI服务。 ### 3. 邮件发送失败 检查邮件服务器配置是否正确,SMTP端口是否开放。 ### 4. 数据库连接失败 检查MySQL服务是否启动,数据库用户名密码是否正确。 --- ## 贡献指南 欢迎提交Issue和Pull Request! 1. Fork本仓库 2. 创建特性分支 3. 提交代码 4. 发起Pull Request --- ## 许可证 本项目采用MIT许可证。 --- ## 联系方式 如有问题,请提交Issue或联系开发者。 --- ## 更新日志 ### v1.0.0 (2024-03-15) - 完成基础功能开发 - 集成Spring AI - 实现跨设备同步 - 完善文档 --- ## 致谢 感谢所有为本项目做出贡献的开发者!