856 lines
29 KiB
Markdown
856 lines
29 KiB
Markdown
# 情绪博物馆后端功能模块技术规范说明
|
|
|
|
## 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
|
|
<!-- Spring Boot 2.7.18 -->
|
|
<spring-boot.version>2.7.18</spring-boot.version>
|
|
|
|
<!-- 核心依赖 -->
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-web</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-security</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
</dependency>
|
|
```
|
|
|
|
#### 2.1.2 数据存储
|
|
```xml
|
|
<!-- MySQL 8.0 -->
|
|
<dependency>
|
|
<groupId>mysql</groupId>
|
|
<artifactId>mysql-connector-java</artifactId>
|
|
<version>8.0.33</version>
|
|
</dependency>
|
|
|
|
<!-- MyBatis Plus 3.5.3.1 -->
|
|
<dependency>
|
|
<groupId>com.baomidou</groupId>
|
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
|
<version>3.5.3.1</version>
|
|
</dependency>
|
|
```
|
|
|
|
#### 2.1.3 安全认证
|
|
```xml
|
|
<!-- JWT 0.11.5 -->
|
|
<dependency>
|
|
<groupId>io.jsonwebtoken</groupId>
|
|
<artifactId>jjwt-api</artifactId>
|
|
<version>0.11.5</version>
|
|
</dependency>
|
|
```
|
|
|
|
### 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<AuthResponse> login(@Valid @RequestBody LoginRequest request)
|
|
|
|
// 用户注册
|
|
@PostMapping("/register")
|
|
public Result<AuthResponse> register(@Valid @RequestBody RegisterRequest request)
|
|
|
|
// 获取当前用户信息
|
|
@GetMapping("/user/info")
|
|
public Result<UserInfoResponse> getCurrentUserInfo(HttpServletRequest request)
|
|
|
|
// 生成验证码
|
|
@GetMapping("/captcha")
|
|
public Result<CaptchaResponse> generateCaptcha()
|
|
|
|
// 用户登出
|
|
@PostMapping("/logout")
|
|
public Result<Void> logout(HttpServletRequest request)
|
|
|
|
// 刷新访问令牌
|
|
@PostMapping("/refresh")
|
|
public Result<AuthResponse> refreshToken(@Valid @RequestBody RefreshTokenRequest request)
|
|
|
|
// 验证访问令牌
|
|
@GetMapping("/validate")
|
|
public Result<Boolean> validateToken(HttpServletRequest request)
|
|
|
|
// 检查账号是否存在
|
|
@GetMapping("/check-account")
|
|
public Result<Boolean> checkAccount(@RequestParam String account)
|
|
|
|
// 检查邮箱是否存在
|
|
@GetMapping("/check-email")
|
|
public Result<Boolean> checkEmail(@RequestParam String email)
|
|
|
|
// 检查手机号是否存在
|
|
@GetMapping("/check-phone")
|
|
public Result<Boolean> checkPhone(@RequestParam String phone)
|
|
}
|
|
```
|
|
|
|
#### 3.1.3 技术特点
|
|
- **JWT认证**: 使用JWT进行无状态认证
|
|
- **验证码支持**: 图形验证码生成和验证
|
|
- **Token刷新**: 支持访问令牌自动刷新
|
|
- **参数校验**: 使用@Valid进行请求参数校验
|
|
- **统一返回**: 使用Result<T>统一返回格式
|
|
|
|
### 3.2 AI对话系统 (AiChatController)
|
|
|
|
#### 3.2.1 功能概述
|
|
基于Coze平台的AI对话服务,支持智能聊天、对话总结、访客聊天等功能。
|
|
|
|
#### 3.2.2 核心接口
|
|
```java
|
|
@RestController
|
|
@RequestMapping("/ai")
|
|
public class AiChatController {
|
|
|
|
// 发送聊天消息
|
|
@PostMapping("/chat")
|
|
public Result<AiChatResponse> sendChatMessage(@Valid @RequestBody AiChatRequest request)
|
|
|
|
// 生成对话总结
|
|
@PostMapping("/summary")
|
|
public Result<AiSummaryResponse> generateSummary(@Valid @RequestBody AiSummaryRequest request)
|
|
|
|
// 获取AI服务状态
|
|
@GetMapping("/status")
|
|
public Result<AiStatusResponse> getServiceStatus()
|
|
|
|
// 获取聊天统计
|
|
@GetMapping("/stats")
|
|
public Result<ChatStatsResponse> getChatStats(@RequestParam(required = false) String userId,
|
|
@RequestParam(required = false) String conversationId)
|
|
|
|
// 访客聊天
|
|
@PostMapping("/guest/chat")
|
|
public Result<GuestChatResponse> guestChat(@Valid @RequestBody GuestChatRequest request,
|
|
HttpServletRequest httpRequest)
|
|
|
|
// 获取访客用户信息
|
|
@GetMapping("/guest/user/info")
|
|
public Result<GuestUserInfoResponse> getGuestUserInfo(HttpServletRequest request)
|
|
|
|
// 创建会话
|
|
@PostMapping("/conversation/create")
|
|
public Result<ConversationResponse> 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<PageResult<DiaryPostResponse>> getPage(@Validated BasePageRequest request)
|
|
|
|
// 根据用户ID分页查询日记
|
|
@GetMapping("/user/{userId}/page")
|
|
public Result<PageResult<DiaryPostResponse>> getPageByUserId(@PathVariable String userId,
|
|
@Validated BasePageRequest request)
|
|
|
|
// 根据用户ID查询公开日记
|
|
@GetMapping("/user/{userId}/public/page")
|
|
public Result<PageResult<DiaryPostResponse>> getPublicPageByUserId(@PathVariable String userId,
|
|
@Validated BasePageRequest request)
|
|
|
|
// 查询精选日记
|
|
@GetMapping("/featured/page")
|
|
public Result<PageResult<DiaryPostResponse>> getFeaturedPage(@Validated BasePageRequest request)
|
|
|
|
// 根据ID查询日记
|
|
@GetMapping("/{id}")
|
|
public Result<DiaryPostResponse> getById(@PathVariable String id)
|
|
|
|
// 创建日记
|
|
@PostMapping
|
|
public Result<DiaryPostResponse> create(@Valid @RequestBody DiaryPostCreateRequest request)
|
|
|
|
// 发布日记
|
|
@PostMapping("/publish")
|
|
public Result<DiaryPostResponse> publish(@Valid @RequestBody DiaryPostCreateRequest request)
|
|
|
|
// 更新日记
|
|
@PutMapping("/{id}")
|
|
public Result<DiaryPostResponse> update(@PathVariable String id, @Valid @RequestBody DiaryPostUpdateRequest request)
|
|
|
|
// 删除日记
|
|
@DeleteMapping("/{id}")
|
|
public Result<Void> delete(@PathVariable String id)
|
|
|
|
// 软删除日记
|
|
@DeleteMapping("/{id}/soft")
|
|
public Result<Void> softDelete(@PathVariable String id)
|
|
|
|
// 恢复日记
|
|
@PutMapping("/{id}/restore")
|
|
public Result<Void> restore(@PathVariable String id)
|
|
|
|
// 点赞日记
|
|
@PostMapping("/{id}/like")
|
|
public Result<Void> like(@PathVariable String id)
|
|
|
|
// 取消点赞
|
|
@DeleteMapping("/{id}/like")
|
|
public Result<Void> unlike(@PathVariable String id)
|
|
|
|
// 分享日记
|
|
@PostMapping("/{id}/share")
|
|
public Result<Void> share(@PathVariable String id)
|
|
|
|
// 设置精选状态
|
|
@PutMapping("/{id}/featured/{featured}")
|
|
public Result<Void> setFeatured(@PathVariable String id, @PathVariable Integer featured)
|
|
|
|
// 设置优先级
|
|
@PutMapping("/{id}/priority/{priority}")
|
|
public Result<Void> setPriority(@PathVariable String id, @PathVariable Integer priority)
|
|
|
|
// 统计用户日记数量
|
|
@GetMapping("/user/{userId}/count")
|
|
public Result<Long> countByUserId(@PathVariable String userId)
|
|
|
|
// 统计用户公开日记数量
|
|
@GetMapping("/user/{userId}/public/count")
|
|
public Result<Long> countPublicByUserId(@PathVariable String userId)
|
|
|
|
// 统计精选日记数量
|
|
@GetMapping("/featured/count")
|
|
public Result<Long> 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<EmotionTrendResponse> analyzeUserEmotionTrend(@PathVariable String userId,
|
|
@RequestParam(required = false) String startDate,
|
|
@RequestParam(required = false) String endDate)
|
|
|
|
// 分析日记情绪
|
|
@PostMapping("/diary")
|
|
public Result<EmotionAnalysisResponse> analyzeDiaryEmotion(@Valid @RequestBody DiaryEmotionAnalysisRequest request)
|
|
|
|
// 获取情绪统计
|
|
@GetMapping("/user/{userId}/stats")
|
|
public Result<EmotionStatsResponse> getEmotionStats(@PathVariable String userId)
|
|
}
|
|
```
|
|
|
|
#### 3.5.2 用户统计 (UserStatsController)
|
|
```java
|
|
@RestController
|
|
@RequestMapping("/user-stats")
|
|
public class UserStatsController {
|
|
|
|
// 获取用户成长数据
|
|
@GetMapping("/user/{userId}/growth")
|
|
public Result<UserGrowthResponse> getUserGrowth(@PathVariable String userId)
|
|
|
|
// 获取用户活跃度
|
|
@GetMapping("/user/{userId}/activity")
|
|
public Result<UserActivityResponse> getUserActivity(@PathVariable String userId)
|
|
|
|
// 获取用户成就统计
|
|
@GetMapping("/user/{userId}/achievements")
|
|
public Result<UserAchievementsResponse> 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<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
|
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
|
template.setConnectionFactory(factory);
|
|
|
|
// 设置序列化器
|
|
Jackson2JsonRedisSerializer<Object> 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<T> {
|
|
private Integer code; // 状态码
|
|
private String message; // 消息
|
|
private T data; // 数据
|
|
private Long timestamp; // 时间戳
|
|
|
|
public static <T> Result<T> success() {
|
|
return new Result<>(200, "操作成功", null, System.currentTimeMillis());
|
|
}
|
|
|
|
public static <T> Result<T> success(T data) {
|
|
return new Result<>(200, "操作成功", data, System.currentTimeMillis());
|
|
}
|
|
|
|
public static <T> Result<T> success(String message, T data) {
|
|
return new Result<>(200, message, data, System.currentTimeMillis());
|
|
}
|
|
|
|
public static <T> Result<T> error(Integer code, String message) {
|
|
return new Result<>(code, message, null, System.currentTimeMillis());
|
|
}
|
|
}
|
|
```
|
|
|
|
### 8.2 分页结果封装
|
|
```java
|
|
@Data
|
|
@AllArgsConstructor
|
|
@NoArgsConstructor
|
|
public class PageResult<T> {
|
|
private Long current; // 当前页
|
|
private Long size; // 页大小
|
|
private Long total; // 总记录数
|
|
private Long pages; // 总页数
|
|
private List<T> records; // 数据列表
|
|
}
|
|
```
|
|
|
|
## 9. 异常处理设计
|
|
|
|
### 9.1 全局异常处理器
|
|
```java
|
|
@RestControllerAdvice
|
|
@Slf4j
|
|
public class GlobalExceptionHandler {
|
|
|
|
@ExceptionHandler(BusinessException.class)
|
|
public Result<Void> handleBusinessException(BusinessExceptio |