# 情绪博物馆后端功能模块技术规范说明 ## 1. 项目概述 ### 1.1 项目基本信息 - **项目名称**: 情绪博物馆后端服务 (emotion-single) - **技术架构**: Spring Boot 2.7.18 单体架构 - **Java版本**: JDK 17 - **服务端口**: 19089 - **API前缀**: /api - **项目类型**: 情感记录与AI对话平台 ### 1.2 核心功能模块 - **用户认证系统**: 登录、注册、JWT认证 - **AI对话系统**: 基于Coze平台的智能对话 - **情绪日记系统**: 日记发布、AI点评、社交分享 - **WebSocket实时通信**: 实时聊天、消息推送 - **数据分析系统**: 情绪分析、用户统计 - **社区互动系统**: 评论、点赞、分享 - **成就奖励系统**: 用户成长、奖励机制 ## 2. 技术架构设计 ### 2.1 技术栈选型 #### 2.1.1 核心框架 ```xml 2.7.18 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-websocket org.springframework.boot spring-boot-starter-data-redis ``` #### 2.1.2 数据存储 ```xml mysql mysql-connector-java 8.0.33 com.baomidou mybatis-plus-boot-starter 3.5.3.1 ``` #### 2.1.3 安全认证 ```xml io.jsonwebtoken jjwt-api 0.11.5 ``` ### 2.2 项目结构设计 ``` src/main/java/com/emotion/ ├── EmotionSimpleApplication.java # 启动类 ├── config/ # 配置类 │ ├── AsyncConfig.java # 异步配置 │ ├── MybatisPlusConfig.java # MyBatis-Plus配置 │ ├── RedisConfig.java # Redis配置 │ ├── WebSocketConfig.java # WebSocket配置 │ ├── SecurityConfig.java # Spring Security配置 │ ├── IdGeneratorConfig.java # ID生成器配置 │ └── WebMvcConfig.java # Web MVC配置 ├── controller/ # 控制器层 (24个控制器) │ ├── AuthController.java # 认证控制器 │ ├── AiChatController.java # AI聊天控制器 │ ├── DiaryPostController.java # 日记控制器 │ ├── UserController.java # 用户控制器 │ ├── WebSocketController.java # WebSocket控制器 │ ├── MessageController.java # 消息控制器 │ ├── ConversationController.java # 会话控制器 │ ├── EmotionAnalysisController.java # 情绪分析控制器 │ ├── CommunityPostController.java # 社区帖子控制器 │ ├── CommentController.java # 评论控制器 │ ├── AchievementController.java # 成就控制器 │ ├── UserStatsController.java # 用户统计控制器 │ ├── RewardController.java # 奖励控制器 │ ├── GuestUserController.java # 访客用户控制器 │ ├── CozeApiCallController.java # Coze API调用控制器 │ ├── EmotionRecordController.java # 情绪记录控制器 │ ├── TopicInteractionController.java # 话题互动控制器 │ ├── GrowthTopicController.java # 成长话题控制器 │ ├── DiaryCommentController.java # 日记评论控制器 │ ├── EmotionSummaryController.java # 情绪总结控制器 │ ├── TokenController.java # Token控制器 │ ├── ChatWebSocketController.java # 聊天WebSocket控制器 │ └── HealthController.java # 健康检查控制器 ├── service/ # 服务层 (20个服务) │ ├── AuthService.java # 认证服务 │ ├── AiChatService.java # AI聊天服务 │ ├── DiaryPostService.java # 日记服务 │ ├── UserService.java # 用户服务 │ ├── WebSocketService.java # WebSocket服务 │ ├── MessageService.java # 消息服务 │ ├── ConversationService.java # 会话服务 │ ├── EmotionAnalysisService.java # 情绪分析服务 │ ├── CommunityPostService.java # 社区帖子服务 │ ├── CommentService.java # 评论服务 │ ├── AchievementService.java # 成就服务 │ ├── UserStatsService.java # 用户统计服务 │ ├── RewardService.java # 奖励服务 │ ├── GuestUserService.java # 访客用户服务 │ ├── CozeApiCallService.java # Coze API调用服务 │ ├── EmotionRecordService.java # 情绪记录服务 │ ├── TopicInteractionService.java # 话题互动服务 │ ├── GrowthTopicService.java # 成长话题服务 │ ├── DiaryCommentService.java # 日记评论服务 │ └── TokenService.java # Token服务 ├── mapper/ # 数据访问层 ├── entity/ # 实体类 (19个实体) │ ├── User.java # 用户实体 │ ├── DiaryPost.java # 日记实体 │ ├── Message.java # 消息实体 │ ├── Conversation.java # 会话实体 │ ├── Comment.java # 评论实体 │ ├── CommunityPost.java # 社区帖子实体 │ ├── Achievement.java # 成就实体 │ ├── Reward.java # 奖励实体 │ ├── GuestUser.java # 访客用户实体 │ ├── EmotionRecord.java # 情绪记录实体 │ ├── EmotionAnalysis.java # 情绪分析实体 │ ├── UserStats.java # 用户统计实体 │ ├── GrowthTopic.java # 成长话题实体 │ ├── TopicInteraction.java # 话题互动实体 │ ├── LocationPin.java # 位置标记实体 │ ├── DiaryComment.java # 日记评论实体 │ └── CozeApiCall.java # Coze API调用记录实体 ├── dto/ # 数据传输对象 │ ├── request/ # 请求对象 │ └── response/ # 响应对象 ├── common/ # 公共组件 │ ├── BaseEntity.java # 基础实体 │ ├── BasePageRequest.java # 基础分页请求 │ ├── PageResult.java # 分页结果 │ └── Result.java # 统一返回结果 ├── config/ # 配置类 ├── interceptor/ # 拦截器 ├── handler/ # 处理器 ├── exception/ # 异常处理 └── util/ # 工具类 ``` ## 3. 核心功能模块详解 ### 3.1 用户认证系统 (AuthController) #### 3.1.1 功能概述 提供完整的用户认证服务,包括登录、注册、Token管理、验证码等功能。 #### 3.1.2 核心接口 ```java @RestController @RequestMapping("/auth") public class AuthController { // 用户登录 @PostMapping("/login") public Result login(@Valid @RequestBody LoginRequest request) // 用户注册 @PostMapping("/register") public Result register(@Valid @RequestBody RegisterRequest request) // 获取当前用户信息 @GetMapping("/user/info") public Result getCurrentUserInfo(HttpServletRequest request) // 生成验证码 @GetMapping("/captcha") public Result generateCaptcha() // 用户登出 @PostMapping("/logout") public Result logout(HttpServletRequest request) // 刷新访问令牌 @PostMapping("/refresh") public Result refreshToken(@Valid @RequestBody RefreshTokenRequest request) // 验证访问令牌 @GetMapping("/validate") public Result validateToken(HttpServletRequest request) // 检查账号是否存在 @GetMapping("/check-account") public Result checkAccount(@RequestParam String account) // 检查邮箱是否存在 @GetMapping("/check-email") public Result checkEmail(@RequestParam String email) // 检查手机号是否存在 @GetMapping("/check-phone") public Result checkPhone(@RequestParam String phone) } ``` #### 3.1.3 技术特点 - **JWT认证**: 使用JWT进行无状态认证 - **验证码支持**: 图形验证码生成和验证 - **Token刷新**: 支持访问令牌自动刷新 - **参数校验**: 使用@Valid进行请求参数校验 - **统一返回**: 使用Result统一返回格式 ### 3.2 AI对话系统 (AiChatController) #### 3.2.1 功能概述 基于Coze平台的AI对话服务,支持智能聊天、对话总结、访客聊天等功能。 #### 3.2.2 核心接口 ```java @RestController @RequestMapping("/ai") public class AiChatController { // 发送聊天消息 @PostMapping("/chat") public Result sendChatMessage(@Valid @RequestBody AiChatRequest request) // 生成对话总结 @PostMapping("/summary") public Result generateSummary(@Valid @RequestBody AiSummaryRequest request) // 获取AI服务状态 @GetMapping("/status") public Result getServiceStatus() // 获取聊天统计 @GetMapping("/stats") public Result getChatStats(@RequestParam(required = false) String userId, @RequestParam(required = false) String conversationId) // 访客聊天 @PostMapping("/guest/chat") public Result guestChat(@Valid @RequestBody GuestChatRequest request, HttpServletRequest httpRequest) // 获取访客用户信息 @GetMapping("/guest/user/info") public Result getGuestUserInfo(HttpServletRequest request) // 创建会话 @PostMapping("/conversation/create") public Result createConversation(@Valid @RequestBody ConversationCreateRequest request, HttpServletRequest httpRequest) } ``` #### 3.2.3 技术特点 - **Coze集成**: 集成Coze AI平台进行智能对话 - **会话管理**: 支持多会话管理和历史记录 - **访客支持**: 支持未登录用户的AI对话 - **异步处理**: 支持异步AI调用和响应 - **统计分析**: 提供聊天数据统计分析 ### 3.3 情绪日记系统 (DiaryPostController) #### 3.3.1 功能概述 用户情绪日记的发布、管理、AI点评、社交分享等完整功能。 #### 3.3.2 核心接口 ```java @RestController @RequestMapping("/diary-post") public class DiaryPostController { // 分页查询日记 @GetMapping("/page") public Result> getPage(@Validated BasePageRequest request) // 根据用户ID分页查询日记 @GetMapping("/user/{userId}/page") public Result> getPageByUserId(@PathVariable String userId, @Validated BasePageRequest request) // 根据用户ID查询公开日记 @GetMapping("/user/{userId}/public/page") public Result> getPublicPageByUserId(@PathVariable String userId, @Validated BasePageRequest request) // 查询精选日记 @GetMapping("/featured/page") public Result> getFeaturedPage(@Validated BasePageRequest request) // 根据ID查询日记 @GetMapping("/{id}") public Result getById(@PathVariable String id) // 创建日记 @PostMapping public Result create(@Valid @RequestBody DiaryPostCreateRequest request) // 发布日记 @PostMapping("/publish") public Result publish(@Valid @RequestBody DiaryPostCreateRequest request) // 更新日记 @PutMapping("/{id}") public Result update(@PathVariable String id, @Valid @RequestBody DiaryPostUpdateRequest request) // 删除日记 @DeleteMapping("/{id}") public Result delete(@PathVariable String id) // 软删除日记 @DeleteMapping("/{id}/soft") public Result softDelete(@PathVariable String id) // 恢复日记 @PutMapping("/{id}/restore") public Result restore(@PathVariable String id) // 点赞日记 @PostMapping("/{id}/like") public Result like(@PathVariable String id) // 取消点赞 @DeleteMapping("/{id}/like") public Result unlike(@PathVariable String id) // 分享日记 @PostMapping("/{id}/share") public Result share(@PathVariable String id) // 设置精选状态 @PutMapping("/{id}/featured/{featured}") public Result setFeatured(@PathVariable String id, @PathVariable Integer featured) // 设置优先级 @PutMapping("/{id}/priority/{priority}") public Result setPriority(@PathVariable String id, @PathVariable Integer priority) // 统计用户日记数量 @GetMapping("/user/{userId}/count") public Result countByUserId(@PathVariable String userId) // 统计用户公开日记数量 @GetMapping("/user/{userId}/public/count") public Result countPublicByUserId(@PathVariable String userId) // 统计精选日记数量 @GetMapping("/featured/count") public Result countFeatured() } ``` #### 3.3.3 技术特点 - **分页查询**: 支持灵活的分页查询 - **软删除**: 支持数据软删除和恢复 - **权限控制**: 支持公开/私密日记管理 - **社交功能**: 支持点赞、分享等社交功能 - **AI点评**: 集成AI自动点评功能 - **数据统计**: 提供丰富的统计功能 ### 3.4 WebSocket实时通信系统 #### 3.4.1 功能概述 基于Spring WebSocket的实时通信系统,支持AI对话、消息推送、在线状态管理。 #### 3.4.2 核心组件 ```java // WebSocket配置 @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic", "/queue", "/user"); config.setApplicationDestinationPrefixes("/app"); config.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws/chat") .setAllowedOriginPatterns("*") .withSockJS(); registry.addEndpoint("/ws/chat") .setAllowedOriginPatterns("*"); } @Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.interceptors(webSocketAuthInterceptor); } } ``` #### 3.4.3 技术特点 - **STOMP协议**: 使用STOMP消息协议 - **Token认证**: 支持WebSocket连接时的Token认证 - **消息路由**: 支持点对点和广播消息 - **会话管理**: 支持用户会话隔离 - **心跳检测**: 支持连接心跳检测 ### 3.5 数据分析系统 #### 3.5.1 情绪分析 (EmotionAnalysisController) ```java @RestController @RequestMapping("/emotion-analysis") public class EmotionAnalysisController { // 分析用户情绪趋势 @GetMapping("/user/{userId}/trend") public Result analyzeUserEmotionTrend(@PathVariable String userId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) // 分析日记情绪 @PostMapping("/diary") public Result analyzeDiaryEmotion(@Valid @RequestBody DiaryEmotionAnalysisRequest request) // 获取情绪统计 @GetMapping("/user/{userId}/stats") public Result getEmotionStats(@PathVariable String userId) } ``` #### 3.5.2 用户统计 (UserStatsController) ```java @RestController @RequestMapping("/user-stats") public class UserStatsController { // 获取用户成长数据 @GetMapping("/user/{userId}/growth") public Result getUserGrowth(@PathVariable String userId) // 获取用户活跃度 @GetMapping("/user/{userId}/activity") public Result getUserActivity(@PathVariable String userId) // 获取用户成就统计 @GetMapping("/user/{userId}/achievements") public Result getUserAchievements(@PathVariable String userId) } ``` ## 4. 数据模型设计 ### 4.1 核心实体关系 #### 4.1.1 用户相关实体 ```java // 用户实体 @Entity public class User { private String id; // 用户ID private String username; // 用户名 private String email; // 邮箱 private String phone; // 手机号 private String avatar; // 头像 private String nickname; // 昵称 private Integer status; // 状态 private LocalDateTime createTime; // 创建时间 private LocalDateTime updateTime; // 更新时间 } // 访客用户实体 @Entity public class GuestUser { private String id; // 访客ID private String sessionId; // 会话ID private String ipAddress; // IP地址 private String userAgent; // 用户代理 private LocalDateTime createTime; // 创建时间 private LocalDateTime lastActiveTime; // 最后活跃时间 } ``` #### 4.1.2 内容相关实体 ```java // 日记实体 @Entity public class DiaryPost { private String id; // 日记ID private String userId; // 用户ID private String title; // 标题 private String content; // 内容 private String aiComment; // AI点评 private Integer visibility; // 可见性 private Integer featured; // 精选状态 private Integer priority; // 优先级 private Integer likeCount; // 点赞数 private Integer shareCount; // 分享数 private LocalDateTime createTime; // 创建时间 private LocalDateTime updateTime; // 更新时间 } // 会话实体 @Entity public class Conversation { private String id; // 会话ID private String userId; // 用户ID private String title; // 会话标题 private String summary; // 会话总结 private Integer messageCount; // 消息数量 private LocalDateTime createTime; // 创建时间 private LocalDateTime updateTime; // 更新时间 } // 消息实体 @Entity public class Message { private String id; // 消息ID private String conversationId; // 会话ID private String senderId; // 发送者ID private String senderType; // 发送者类型 private String content; // 消息内容 private String messageType; // 消息类型 private Integer status; // 消息状态 private LocalDateTime createTime; // 创建时间 } ``` #### 4.1.3 社交相关实体 ```java // 社区帖子实体 @Entity public class CommunityPost { private String id; // 帖子ID private String userId; // 用户ID private String title; // 标题 private String content; // 内容 private String category; // 分类 private Integer likeCount; // 点赞数 private Integer commentCount; // 评论数 private Integer shareCount; // 分享数 private LocalDateTime createTime; // 创建时间 } // 评论实体 @Entity public class Comment { private String id; // 评论ID private String userId; // 用户ID private String targetId; // 目标ID private String targetType; // 目标类型 private String content; // 评论内容 private String parentId; // 父评论ID private Integer likeCount; // 点赞数 private LocalDateTime createTime; // 创建时间 } ``` ### 4.2 数据访问层设计 #### 4.2.1 MyBatis Plus配置 ```java @Configuration @MapperScan("com.emotion.mapper") public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } } ``` #### 4.2.2 基础实体设计 ```java @MappedSuperclass @Data public abstract class BaseEntity { @TableId(type = IdType.ASSIGN_ID) private String id; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableLogic @TableField(fill = FieldFill.INSERT) private Integer isDeleted; } ``` ## 5. 安全认证设计 ### 5.1 JWT认证机制 #### 5.1.1 JWT配置 ```yaml # application.yml emotion: jwt: secret: EmotionMuseumJWTSecretKey2025ForAuthenticationAndAuthorizationSecureEnoughForHS512Algorithm expiration: 86400000 # 24小时 header: Authorization prefix: "Bearer " ``` #### 5.1.2 JWT工具类 ```java @Component public class JwtUtil { @Value("${emotion.jwt.secret}") private String secret; @Value("${emotion.jwt.expiration}") private Long expiration; // 生成Token public String generateToken(String userId, String username) { return Jwts.builder() .setSubject(userId) .claim("username", username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expiration)) .signWith(SignatureAlgorithm.HS512, secret) .compact(); } // 验证Token public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(secret).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } // 从Token中获取用户ID public String getUserIdFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); return claims.getSubject(); } } ``` ### 5.2 Spring Security配置 #### 5.2.1 安全配置 ```java @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .cors().and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/auth/**", "/health/**", "/actuator/**").permitAll() .antMatchers("/ai/guest/**").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } } ``` #### 5.2.2 JWT认证过滤器 ```java @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = extractTokenFromRequest(request); if (StringUtils.hasText(token) && jwtUtil.validateToken(token)) { String userId = jwtUtil.getUserIdFromToken(token); String username = jwtUtil.getUsernameFromToken(token); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userId, null, Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))); SecurityContextHolder.getContext().setAuthentication(authentication); } filterChain.doFilter(request, response); } } ``` ## 6. 缓存设计 ### 6.1 Redis配置 ```java @Configuration @EnableCaching public class RedisConfig { @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(factory); // 设置序列化器 Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); serializer.setObjectMapper(mapper); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(serializer); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(serializer); template.afterPropertiesSet(); return template; } } ``` ### 6.2 缓存策略 - **用户信息缓存**: 用户基本信息缓存,TTL 30分钟 - **会话缓存**: 用户会话信息缓存,TTL 24小时 - **验证码缓存**: 验证码缓存,TTL 5分钟 - **热点数据缓存**: 热门日记、评论等缓存,TTL 1小时 ## 7. 异步处理设计 ### 7.1 异步配置 ```java @Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(50); executor.setQueueCapacity(200); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("emotion-async-"); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new SimpleAsyncUncaughtExceptionHandler(); } } ``` ### 7.2 异步应用场景 - **AI调用**: AI对话和总结生成 - **消息推送**: 实时消息推送 - **数据统计**: 用户行为统计分析 - **文件处理**: 图片上传和处理 ## 8. 统一返回结果设计 ### 8.1 返回结果封装 ```java @Data @AllArgsConstructor @NoArgsConstructor public class Result { private Integer code; // 状态码 private String message; // 消息 private T data; // 数据 private Long timestamp; // 时间戳 public static Result success() { return new Result<>(200, "操作成功", null, System.currentTimeMillis()); } public static Result success(T data) { return new Result<>(200, "操作成功", data, System.currentTimeMillis()); } public static Result success(String message, T data) { return new Result<>(200, message, data, System.currentTimeMillis()); } public static Result error(Integer code, String message) { return new Result<>(code, message, null, System.currentTimeMillis()); } } ``` ### 8.2 分页结果封装 ```java @Data @AllArgsConstructor @NoArgsConstructor public class PageResult { private Long current; // 当前页 private Long size; // 页大小 private Long total; // 总记录数 private Long pages; // 总页数 private List records; // 数据列表 } ``` ## 9. 异常处理设计 ### 9.1 全局异常处理器 ```java @RestControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(BusinessException.class) public Result handleBusinessException(BusinessExceptio