前端统一接口响应处理,注册/登录/验证码逻辑修正,兼容后端标准出参格式

This commit is contained in:
2025-07-24 16:05:38 +08:00
parent e554a287f9
commit 6560e66959
10 changed files with 334 additions and 2028 deletions
@@ -1,169 +0,0 @@
# AiChatServiceImpl Coze API 配置优化
## 优化概述
根据 `application.yml` 中的 Coze API 配置信息,对 `AiChatServiceImpl` 进行了全面优化,使其能够正确使用配置文件中定义的参数。
## 主要优化内容
### 1. 配置参数更新
#### 1.1 配置路径修正
- **之前**: 使用 `${coze.api.*}` 配置路径
- **现在**: 使用 `${emotion.coze.api.*}` 配置路径,与 `application.yml` 保持一致
#### 1.2 新增配置参数
```java
// 基础配置
@Value("${emotion.coze.api.token:}")
private String cozeApiToken;
@Value("${emotion.coze.api.base-url:https://api.coze.cn}")
private String cozeBaseUrl;
// 聊天功能配置
@Value("${emotion.coze.api.chat.talk.bot-id:}")
private String chatBotId;
@Value("${emotion.coze.api.chat.talk.workflow-id:}")
private String chatWorkflowId;
// 总结功能配置
@Value("${emotion.coze.api.chat.summary.bot-id:}")
private String summaryBotId;
@Value("${emotion.coze.api.chat.summary.workflow-id:}")
private String summaryWorkflowId;
// 超时和重试配置
@Value("${emotion.coze.api.timeout:30000}")
private int timeout;
@Value("${emotion.coze.api.retry-count:3}")
private int retryCount;
@Value("${emotion.coze.api.retry-delay:1000}")
private int retryDelay;
```
### 2. 功能分离优化
#### 2.1 聊天和总结功能分离
- **聊天功能**: 使用 `chatBotId``chatWorkflowId`
- **总结功能**: 使用 `summaryBotId``summaryWorkflowId`
#### 2.2 新增专用方法
```java
// 聊天消息发送
private Map<String, Object> buildCozeRequest(String conversationId, String userMessage, String userId)
// 总结消息发送
private String sendSummaryMessage(String conversationId, String userMessage, String userId)
private Map<String, Object> buildSummaryRequest(String conversationId, String userMessage, String userId)
```
### 3. API URL 构建优化
#### 3.1 动态URL构建
```java
// 之前: 硬编码的URL
private String cozeApiUrl = "https://www.coze.cn/api/message";
// 现在: 基于配置的动态构建
String cozeApiUrl = cozeBaseUrl + "/api/message";
```
#### 3.2 健康检查URL优化
```java
// 之前
cozeApiUrl.replace("/api/message", "/v1/bot/get_online_info?bot_id=" + cozeBotId)
// 现在
cozeBaseUrl + "/v1/bot/get_online_info?bot_id=" + chatBotId
```
### 4. 配置参数对应关系
| 配置文件路径 | 代码变量 | 用途 |
|-------------|---------|------|
| `emotion.coze.api.token` | `cozeApiToken` | API认证令牌 |
| `emotion.coze.api.base-url` | `cozeBaseUrl` | API基础URL |
| `emotion.coze.api.chat.talk.bot-id` | `chatBotId` | 聊天机器人ID |
| `emotion.coze.api.chat.talk.workflow-id` | `chatWorkflowId` | 聊天工作流ID |
| `emotion.coze.api.chat.summary.bot-id` | `summaryBotId` | 总结机器人ID |
| `emotion.coze.api.chat.summary.workflow-id` | `summaryWorkflowId` | 总结工作流ID |
| `emotion.coze.api.timeout` | `timeout` | 请求超时时间 |
| `emotion.coze.api.retry-count` | `retryCount` | 重试次数 |
| `emotion.coze.api.retry-delay` | `retryDelay` | 重试延迟 |
### 5. 实际配置值
根据 `application.yml` 中的配置:
```yaml
emotion:
coze:
api:
token: pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO
base-url: https://api.coze.cn
chat:
talk:
bot-id: 7523042446285439016
workflow-id: 7523047462895796287
summary:
bot-id: 7529062814150295595
workflow-id: 7523047462895796287
timeout: 30000
retry-count: 3
retry-delay: 1000
```
### 6. 优化效果
#### 6.1 配置管理
- ✅ 统一配置管理,所有参数从 `application.yml` 读取
- ✅ 支持环境变量覆盖
- ✅ 配置参数类型安全
#### 6.2 功能分离
- ✅ 聊天和总结功能使用不同的bot和workflow
- ✅ 代码结构更清晰,职责分离明确
- ✅ 便于后续功能扩展
#### 6.3 错误处理
- ✅ 配置缺失时的默认值处理
- ✅ 服务可用性检查优化
- ✅ 详细的日志记录
#### 6.4 性能优化
- ✅ 支持超时配置
- ✅ 支持重试机制
- ✅ 减少硬编码,提高可维护性
### 7. 使用示例
#### 7.1 普通聊天
```java
// 使用 chatBotId 和 chatWorkflowId
String reply = aiChatService.sendChatMessage(conversationId, message, userId);
```
#### 7.2 对话总结
```java
// 使用 summaryBotId 和 summaryWorkflowId
String summary = aiChatService.generateConversationSummary(conversationId, userId);
```
### 8. 注意事项
1. **配置验证**: 确保 `application.yml` 中的配置值正确
2. **环境变量**: 可以通过环境变量覆盖配置值
3. **错误处理**: 配置缺失时会使用默认值
4. **日志监控**: 关注API调用的日志输出
---
**优化完成时间**: 2025-07-24
**优化状态**: ✅ 完成
**编译状态**: ✅ 成功
**配置状态**: ✅ 与application.yml一致
-205
View File
@@ -1,205 +0,0 @@
# Entity BaseEntity 继承情况审计报告
## 审计概述
根据 `mysql_emotion_museum_final.sql` 建表语句,对所有entity对象进行了全面核对,确保它们都正确继承了 `BaseEntity` 来管理公共字段。
## 审计结果
### ✅ 已正确继承BaseEntity的Entity
| Entity类 | 继承状态 | 备注 |
|---------|---------|------|
| User | ✅ 正确 | 继承BaseEntity,字段完整 |
| Conversation | ✅ 正确 | 继承BaseEntity,已修复重复字段 |
| Message | ✅ 正确 | 继承BaseEntity,字段完整 |
| EmotionAnalysis | ✅ 正确 | 继承BaseEntity,字段完整 |
| EmotionRecord | ✅ 正确 | 继承BaseEntity,字段完整 |
| GrowthTopic | ✅ 正确 | 继承BaseEntity,字段完整 |
| TopicInteraction | ✅ 正确 | 继承BaseEntity,字段完整 |
| LocationPin | ✅ 正确 | 继承BaseEntity,字段完整 |
| CommunityPost | ✅ 正确 | 继承BaseEntity,字段完整 |
| Comment | ✅ 正确 | 继承BaseEntity,字段完整 |
| Achievement | ✅ 正确 | 继承BaseEntity,字段完整 |
| Reward | ✅ 正确 | 继承BaseEntity,字段完整 |
| GuestUser | ✅ 正确 | 继承BaseEntity,字段完整 |
| UserStats | ✅ 正确 | 继承BaseEntity,字段完整 |
### 🔧 已修复的Entity
| Entity类 | 修复内容 | 状态 |
|---------|---------|------|
| CozeApiCall | 添加BaseEntity继承,删除重复字段 | ✅ 已修复 |
| Conversation | 删除重复的remarks字段,添加start_time字段 | ✅ 已修复 |
## 修复详情
### 1. CozeApiCall 实体类修复
**问题**: 没有继承BaseEntity,手动定义了公共字段
**修复内容**:
- 添加 `extends BaseEntity`
- 添加 `@EqualsAndHashCode(callSuper = true)`
- 删除重复的公共字段定义:
- `id` (主键)
- `createBy` (创建人)
- `createTime` (创建时间)
- `updateBy` (更新人)
- `updateTime` (更新时间)
- `isDeleted` (是否删除)
- `remarks` (备注)
**修复前**:
```java
public class CozeApiCall {
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
// ... 其他字段
@TableField("create_by")
private String createBy;
// ... 其他公共字段
}
```
**修复后**:
```java
public class CozeApiCall extends BaseEntity {
// 只保留业务字段,公共字段由BaseEntity提供
}
```
### 2. Conversation 实体类修复
**问题**: 重复定义了remarks字段,缺少start_time字段
**修复内容**:
- 删除重复的remarks字段定义
- 添加start_time字段(根据SQL建表语句)
**修复前**:
```java
@TableField("metadata")
private String metadata;
@TableField("remarks") // 重复定义
private String remarks;
```
**修复后**:
```java
@TableField("metadata")
private String metadata;
@TableField("start_time") // 新增字段
private LocalDateTime startTime;
```
## BaseEntity 公共字段
所有entity现在都通过继承 `BaseEntity` 获得以下公共字段:
```java
public class BaseEntity implements Serializable {
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 创建人
*/
@TableField(value = "create_by", fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 更新人
*/
@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
/**
* 是否删除:0-未删除,1-已删除
*/
@TableField("is_deleted")
@TableLogic
private Integer isDeleted;
/**
* 备注
*/
@TableField("remarks")
private String remarks;
}
```
## 字段映射验证
### SQL建表语句与Entity字段对照
| 表名 | Entity类 | 字段完整性 | 状态 |
|------|---------|-----------|------|
| user | User | ✅ 完整 | 通过 |
| conversation | Conversation | ✅ 完整 | 通过 |
| message | Message | ✅ 完整 | 通过 |
| coze_api_call | CozeApiCall | ✅ 完整 | 通过 |
| emotion_analysis | EmotionAnalysis | ✅ 完整 | 通过 |
| emotion_record | EmotionRecord | ✅ 完整 | 通过 |
| growth_topic | GrowthTopic | ✅ 完整 | 通过 |
| topic_interaction | TopicInteraction | ✅ 完整 | 通过 |
| location_pin | LocationPin | ✅ 完整 | 通过 |
| community_post | CommunityPost | ✅ 完整 | 通过 |
| comment | Comment | ✅ 完整 | 通过 |
| achievement | Achievement | ✅ 完整 | 通过 |
| reward | Reward | ✅ 完整 | 通过 |
| guest_user | GuestUser | ✅ 完整 | 通过 |
| user_stats | UserStats | ✅ 完整 | 通过 |
## 编译验证
**编译状态**: 成功
**字段映射**: 完整
**BaseEntity继承**: 100%覆盖
**代码质量**: 通过检查
## 最佳实践
### 1. Entity类规范
- 所有entity类必须继承 `BaseEntity`
- 使用 `@EqualsAndHashCode(callSuper = true)` 注解
- 不要重复定义BaseEntity中的公共字段
### 2. 字段映射规范
- 使用 `@TableField` 注解明确指定数据库字段名
- 字段类型要与数据库类型匹配
- 遵循驼峰命名转下划线命名规则
### 3. 注解使用规范
- 使用 `@TableName` 指定表名
- 使用 `@Data` 生成getter/setter
- 使用 `@Builder` 支持建造者模式
- 使用 `@NoArgsConstructor``@AllArgsConstructor`
## 总结
经过全面审计和修复,所有15个entity类现在都正确继承了 `BaseEntity`,实现了公共字段的统一管理。代码结构更加规范,维护性得到显著提升。
---
**审计完成时间**: 2025-07-24
**审计状态**: ✅ 完成
**修复状态**: ✅ 完成
**编译状态**: ✅ 成功
-194
View File
@@ -1,194 +0,0 @@
# Mapper层和Service层审计报告
## 审计概述
根据所有entity对象,对mapper层和service层进行了全面核对,确保每个entity都有对应的mapper和service实现,并按照当前项目规范进行了补充。
## 审计结果
### ✅ Entity与Mapper对应关系
| Entity类 | Mapper类 | 状态 | 备注 |
|---------|---------|------|------|
| User | UserMapper | ✅ 存在 | 继承BaseMapper |
| Conversation | ConversationMapper | ✅ 存在 | 继承BaseMapper |
| Message | MessageMapper | ✅ 存在 | 继承BaseMapper |
| CozeApiCall | CozeApiCallMapper | ✅ 存在 | 继承BaseMapper |
| EmotionAnalysis | EmotionAnalysisMapper | ✅ 存在 | 继承BaseMapper |
| EmotionRecord | EmotionRecordMapper | ✅ 存在 | 继承BaseMapper |
| GrowthTopic | GrowthTopicMapper | ✅ 存在 | 继承BaseMapper |
| TopicInteraction | TopicInteractionMapper | ✅ 存在 | 继承BaseMapper |
| LocationPin | LocationPinMapper | ✅ 存在 | 继承BaseMapper |
| CommunityPost | CommunityPostMapper | ✅ 存在 | 继承BaseMapper |
| Comment | CommentMapper | ✅ 存在 | 继承BaseMapper |
| Achievement | AchievementMapper | ✅ 存在 | 继承BaseMapper |
| Reward | RewardMapper | ✅ 已创建 | 继承BaseMapper |
| GuestUser | GuestUserMapper | ✅ 存在 | 继承BaseMapper |
| UserStats | UserStatsMapper | ✅ 存在 | 继承BaseMapper |
### ✅ Service接口与实现类对应关系
| Service接口 | ServiceImpl实现类 | 状态 | 备注 |
|------------|------------------|------|------|
| AIChatService | AiChatServiceImpl | ✅ 存在 | 已实现 |
| AuthService | AuthServiceImpl | ✅ 存在 | 已实现 |
| TokenService | TokenServiceImpl | ✅ 存在 | 已实现 |
| AchievementService | AchievementServiceImpl | ✅ 存在 | 已实现 |
| CozeApiCallService | CozeApiCallServiceImpl | ✅ 存在 | 已实现 |
| RewardService | RewardServiceImpl | ✅ 已创建 | 已实现 |
| UserService | UserServiceImpl | ✅ 已创建 | 已实现 |
| GrowthTopicService | - | ❌ 缺失 | 需要创建 |
| EmotionAnalysisService | - | ❌ 缺失 | 需要创建 |
| MessageService | - | ❌ 缺失 | 需要创建 |
| CommentService | - | ❌ 缺失 | 需要创建 |
| CommunityPostService | - | ❌ 缺失 | 需要创建 |
| GuestUserService | - | ❌ 缺失 | 需要创建 |
| UserStatsService | - | ❌ 缺失 | 需要创建 |
| EmotionRecordService | - | ❌ 缺失 | 需要创建 |
| ConversationService | - | ❌ 缺失 | 需要创建 |
| TopicInteractionService | - | ❌ 缺失 | 需要创建 |
## 已完成的修复工作
### 1. 创建缺失的Mapper
#### RewardMapper.java
```java
package com.emotion.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.emotion.entity.Reward;
import org.apache.ibatis.annotations.Mapper;
/**
* 奖励Mapper接口
*
* @author emotion-museum
* @date 2025-07-24
*/
@Mapper
public interface RewardMapper extends BaseMapper<Reward> {
}
```
### 2. 创建缺失的Service实现类
#### RewardServiceImpl.java
- 实现了RewardService接口的所有方法
- 使用MyBatis Plus的ServiceImpl基类
- 包含分页查询、条件查询、统计等功能
- 处理了Java 8兼容性问题(使用Collections.emptyList()替代List.of()
#### UserServiceImpl.java
- 实现了UserService接口的所有方法
- 包含用户认证、密码加密等功能
- 使用PasswordEncoder进行密码加密和验证
- 实现了完整的用户管理功能
## Mapper层规范
### 1. 标准Mapper接口结构
```java
package com.emotion.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.emotion.entity.EntityName;
import org.apache.ibatis.annotations.Mapper;
/**
* EntityName Mapper接口
*
* @author emotion-museum
* @date 2025-07-24
*/
@Mapper
public interface EntityNameMapper extends BaseMapper<EntityName> {
}
```
### 2. 特点
- 所有Mapper都继承MyBatis Plus的BaseMapper
- 使用@Mapper注解标记
- 不需要XML映射文件,使用注解方式
- 提供基础的CRUD操作
## Service层规范
### 1. 标准Service实现类结构
```java
@Service
public class EntityNameServiceImpl extends ServiceImpl<EntityNameMapper, EntityName> implements EntityNameService {
@Override
public IPage<EntityName> getPage(BasePageRequest request) {
// 分页查询实现
}
// 其他业务方法实现
}
```
### 2. 特点
- 继承ServiceImpl基类,获得基础CRUD功能
- 实现对应的Service接口
- 使用@Service注解标记
- 包含分页查询、条件查询、统计等业务方法
## 编译验证
**编译状态**: 成功
**Mapper完整性**: 100%覆盖
**Service实现**: 部分完成(2/15
**代码质量**: 通过检查
## 待完成工作
### 需要创建的Service实现类
1. GrowthTopicServiceImpl
2. EmotionAnalysisServiceImpl
3. MessageServiceImpl
4. CommentServiceImpl
5. CommunityPostServiceImpl
6. GuestUserServiceImpl
7. UserStatsServiceImpl
8. EmotionRecordServiceImpl
9. ConversationServiceImpl
10. TopicInteractionServiceImpl
### 建议的创建顺序
1. 优先创建核心业务相关的Service实现类
2. 按照依赖关系创建(如ConversationService依赖MessageService
3. 确保每个实现类都遵循项目规范
## 最佳实践
### 1. Mapper层
- 保持简洁,只继承BaseMapper
- 如需自定义SQL,使用@Select@Insert等注解
- 避免在Mapper中写复杂业务逻辑
### 2. Service层
- 实现所有接口方法
- 使用LambdaQueryWrapper构建查询条件
- 正确处理软删除(isDeleted字段)
- 添加适当的日志记录
### 3. 代码规范
- 统一的包结构和命名规范
- 完整的JavaDoc注释
- 合理的异常处理
- 遵循项目的时间格式规范
## 总结
经过审计和修复,mapper层已经100%完整,每个entity都有对应的mapper。service层部分完成,已创建了RewardServiceImpl和UserServiceImpl两个实现类,还需要继续创建其他10个service实现类。
整体代码结构规范,遵循了MyBatis Plus的最佳实践,为后续的业务开发奠定了良好的基础。
---
**审计完成时间**: 2025-07-24
**审计状态**: ✅ 完成
**Mapper完整性**: ✅ 100%
**Service实现**: 🔄 进行中 (2/15)
**编译状态**: ✅ 成功
-139
View File
@@ -1,139 +0,0 @@
# 后端优化总结
## 已完成的工作
### 1. 新增Request和Response包结构
**已创建的Request类:**
- `AiChatRequest` - AI聊天请求
- `AiSummaryRequest` - AI总结请求
- `ChatStatsRequest` - 聊天统计请求
- `UserUpdateRequest` - 用户更新请求
- `RefreshTokenRequest` - 刷新令牌请求
- `MessageCreateRequest` - 消息创建请求
- `ConversationCreateRequest` - 对话创建请求
**已创建的Response类:**
- `AiChatResponse` - AI聊天响应
- `AiSummaryResponse` - AI总结响应
- `AiStatusResponse` - AI状态响应
- `ChatStatsResponse` - 聊天统计响应
- `MessageResponse` - 消息响应
- `ConversationResponse` - 对话响应
### 2. Controller优化
**已优化的Controller**
- `AiChatController` - 移除try-catch,使用专门的request/response类
- `UserController` - 使用专门的request类,优化参数验证
- `AuthController` - 使用专门的request类,优化参数验证
- `MessageController` - 移除内部类,使用独立的request/response类
- `ConversationController` - 移除内部类,使用独立的request/response类
### 3. 代码规范优化
**已实现的优化:**
- 所有Controller使用 `@Valid` 注解进行参数验证
- 移除所有try-catch块,依赖全局异常处理机制
- 业务逻辑保持在Controller层简洁,复杂逻辑移到Service层
- 统一的request/response类结构,继承BaseRequest/BaseResponse
- 使用Lombok注解简化代码
## 当前问题
### 1. Lombok注解处理器问题
**主要问题:**
- 实体类缺少getter/setter方法
- 服务类缺少getter/setter方法
- Builder模式没有正确生成
- 导致大量编译错误
### 2. 缺失的类和接口
**缺失的类:**
- `LocationPinService` 接口文件有问题
- `RewardMapper` 类缺失
- 各种Service接口不完整
### 3. 方法签名不匹配
**方法调用问题:**
- Service接口与实现类方法签名不匹配
- Controller中调用的方法在Service中不存在
## 优化效果
### 1. 代码结构改进
**改进点:**
- 清晰的request/response包结构
- 统一的参数验证机制
- 规范的异常处理
- 更好的代码可读性
### 2. 接口规范
**规范点:**
- 所有接口都有明确的入参和出参定义
- 参数验证使用JSR-303注解
- 响应格式统一使用Result包装
- 错误处理统一使用全局异常机制
### 3. 业务逻辑分离
**分离效果:**
- Controller只负责参数验证和结果返回
- 业务逻辑集中在Service层
- 数据访问逻辑在Mapper层
- 清晰的层次结构
## 下一步建议
### 1. 立即需要解决的问题
🔧 **优先级高:**
- 修复Lombok配置问题
- 补充缺失的Service接口
- 修复方法签名不匹配问题
- 确保所有实体类有正确的getter/setter方法
### 2. 继续优化的工作
🔧 **优先级中:**
- 优化其他ControllerEmotionRecordController、RewardController等)
- 完善Service层的业务逻辑
- 添加更多的参数验证规则
- 优化异常处理机制
### 3. 长期改进计划
🔧 **优先级低:**
- 添加单元测试
- 完善API文档
- 性能优化
- 代码重构
## 技术债务
### 1. 当前技术债务
⚠️ **需要注意:**
- Lombok配置问题需要彻底解决
- 部分Service接口需要重新设计
- 实体类字段与数据库结构需要对齐
- 部分业务逻辑需要重构
### 2. 建议的解决方案
💡 **解决方案:**
- 检查Lombok版本和配置
- 重新生成所有实体类的getter/setter方法
- 统一Service接口设计
- 完善数据库脚本与实体类的对应关系
## 总结
本次优化已经完成了基础的request/response包结构创建和主要Controller的优化,代码结构更加规范,接口定义更加清晰。但由于Lombok配置问题导致编译失败,需要先解决这个技术问题才能继续后续的优化工作。
建议优先解决Lombok问题,然后继续完成其他Controller的优化,最终实现一个结构清晰、代码规范的后端服务。
-139
View File
@@ -1,139 +0,0 @@
# 情绪博物馆后端重构总结
## 重构进度总览
**重构开始时间**: 2025-07-24
**重构状态**: 🔄 进行中
**总体完成度**: 85%
### 各层完成情况
**Entity审计**: ✅ 完成 (100%继承BaseEntity)
**Mapper审计**: ✅ 完成 (100%覆盖)
**Service审计**: ✅ 完成 (17/17实现类)
**Controller重构**: 🔄 进行中
**DTO层重构**: 🔄 进行中
## 详细进度
### ✅ Entity层 (100%完成)
- **审计状态**: ✅ 完成
- **BaseEntity继承**: 15/15 (100%)
- **字段一致性**: ✅ 通过检查
- **注解完整性**: ✅ 通过检查
### ✅ Mapper层 (100%完成)
- **审计状态**: ✅ 完成
- **Mapper接口**: 15/15 (100%)
- **BaseMapper继承**: ✅ 全部正确
- **@Mapper注解**: ✅ 全部正确
### ✅ Service层 (100%完成)
- **审计状态**: ✅ 完成
- **Service接口**: 17个
- **Service实现类**: 17个 (100%)
- **编译状态**: ✅ 成功
**已完成的Service实现类**:
1. AchievementServiceImpl
2. AiChatServiceImpl
3. AuthServiceImpl
4. CommentServiceImpl
5. CommunityPostServiceImpl
6. ConversationServiceImpl
7. CozeApiCallServiceImpl
8. EmotionAnalysisServiceImpl
9. EmotionRecordServiceImpl
10. GrowthTopicServiceImpl
11. GuestUserServiceImpl
12. MessageServiceImpl
13. RewardServiceImpl
14. TokenServiceImpl
15. TopicInteractionServiceImpl
16. UserServiceImpl
17. UserStatsServiceImpl
### 🔄 Controller层 (进行中)
- **重构状态**: 🔄 进行中
- **DTO封装**: 部分完成
- **异常处理**: 全局异常处理已配置
- **业务逻辑**: 已迁移到Service层
### 🔄 DTO层 (进行中)
- **Request封装**: 部分完成
- **Response封装**: 部分完成
- **验证注解**: 部分完成
## 技术规范
### 1. 项目结构规范
```
src/main/java/com/emotion/
├── common/ # 公共组件
├── config/ # 配置类
├── controller/ # 控制器层
├── dto/ # 数据传输对象
│ ├── request/ # 请求DTO
│ └── response/ # 响应DTO
├── entity/ # 实体类
├── mapper/ # 数据访问层
├── service/ # 业务逻辑层
│ └── impl/ # 业务逻辑实现
└── vo/ # 视图对象
```
### 2. 代码规范
- **Controller层**: 只负责参数验证和结果返回,业务逻辑在Service层
- **Service层**: 实现业务逻辑,使用ServiceImpl基类
- **Entity层**: 继承BaseEntity,使用Lombok注解
- **Mapper层**: 继承BaseMapper,使用@Mapper注解
- **DTO层**: 使用@Valid注解进行参数验证
### 3. 异常处理
- 使用全局异常处理机制
- Controller层移除try-catch
- 统一返回Result格式
## 编译状态
**当前编译状态**: 成功
**测试状态**: 待测试
**代码质量**: 通过检查
## 下一步计划
1. **完成Controller层重构**
- 完善所有Controller的DTO封装
- 移除try-catch,使用全局异常处理
- 确保业务逻辑在Service层
2. **完善DTO层**
- 补充缺失的Request/Response类
- 添加参数验证注解
- 统一返回格式
3. **集成测试**
- 编写单元测试
- 进行集成测试
- 性能测试
4. **文档完善**
- API文档更新
- 部署文档
- 使用说明
## 总结
经过系统性的重构,项目的架构更加清晰,代码质量显著提升。Entity、Mapper、Service三层已全部完成审计和重构,为后续的业务开发奠定了坚实的基础。
**重构成果**:
- ✅ 100%的Entity继承BaseEntity
- ✅ 100%的Mapper接口覆盖
- ✅ 100%的Service实现类完成
- ✅ 项目编译成功
- ✅ 代码规范统一
-66
View File
@@ -1,66 +0,0 @@
# Service层审计报告
**审计完成时间**: 2025-07-24
**审计状态**: ✅ 完成
**Service实现**: 17/17 (100%)
**编译状态**: ✅ 成功(所有实现类)
## 审计结果
### Service接口与实现类对应关系
| Service接口 | 实现类 | 状态 | 备注 |
|------------|--------|------|------|
| AchievementService | AchievementServiceImpl | ✅ 已创建 | 已实现 |
| AIChatService | AiChatServiceImpl | ✅ 已创建 | 已实现 |
| AuthService | AuthServiceImpl | ✅ 已创建 | 已实现 |
| CommentService | CommentServiceImpl | ✅ 已创建 | 已实现 |
| CommunityPostService | CommunityPostServiceImpl | ✅ 已创建 | 已实现 |
| ConversationService | ConversationServiceImpl | ✅ 已创建 | 已实现 |
| CozeApiCallService | CozeApiCallServiceImpl | ✅ 已创建 | 已实现 |
| EmotionAnalysisService | EmotionAnalysisServiceImpl | ✅ 已创建 | 已实现 |
| EmotionRecordService | EmotionRecordServiceImpl | ✅ 已创建 | 已实现 |
| GrowthTopicService | GrowthTopicServiceImpl | ✅ 已创建 | 已实现 |
| GuestUserService | GuestUserServiceImpl | ✅ 已创建 | 已实现 |
| MessageService | MessageServiceImpl | ✅ 已创建 | 已实现 |
| RewardService | RewardServiceImpl | ✅ 已创建 | 已实现 |
| TokenService | TokenServiceImpl | ✅ 已创建 | 已实现 |
| TopicInteractionService | TopicInteractionServiceImpl | ✅ 已创建 | 已实现 |
| UserService | UserServiceImpl | ✅ 已创建 | 已实现 |
| UserStatsService | UserStatsServiceImpl | ✅ 已创建 | 已实现 |
### 特殊说明
- **WebSocketService**: 这是一个已实现的Service类,不是接口,直接使用@Service注解
- **LocationPinService**: 已删除空文件
## 已完成的修复工作
**编译状态**: 成功(所有实现类)
**Service实现**: 全部完成(17/17
**代码质量**: 通过检查
### 需要创建的Service实现类
✅ 所有Service实现类已创建完成!
### 创建注意事项
1. **逐个创建**: 严格按照一个一个创建的方式,确保每个实现类都能正确编译
2. **接口方法完整性**: 确保实现所有接口方法
3. **字段匹配**: 根据实际entity字段进行适配
4. **类型转换**: 正确处理不同数据类型(如BigDecimal)
5. **软删除**: 正确处理isDeleted字段
6. **Java 8兼容**: 使用Collections.emptyList()替代List.of()
7. **缺失字段处理**: 对于实体中不存在的字段,提供合理的默认实现
## 总结
经过审计和修复,已成功创建了所有17个service实现类,Service层审计工作全部完成。
所有已创建的实现类都遵循了项目规范,通过了编译检查,为后续的业务开发奠定了良好的基础。
**最终统计**:
- Service接口: 17个
- Service实现类: 17个
- 覆盖率: 100%
- 编译状态: ✅ 成功
-22
View File
@@ -1,22 +0,0 @@
#!/bin/bash
# 简化版单体服务构建脚本
# 作者: emotion-museum
# 日期: 2025-07-21
set -e
echo "🚀 开始构建emotion-single简化版..."
# 清理并构建
mvn clean package -DskipTests
if [ -f "target/emotion-single-1.0.0.jar" ]; then
echo "✅ 构建成功: target/emotion-single-1.0.0.jar"
ls -lh target/emotion-single-1.0.0.jar
else
echo "❌ 构建失败"
exit 1
fi
echo "🎉 构建完成!"
-132
View File
@@ -1,132 +0,0 @@
#!/bin/bash
# 单体服务构建脚本
# 作者: emotion-museum
# 日期: 2025-07-21
set -e
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# 检查Java环境
check_java() {
log_info "检查Java环境..."
if command -v java >/dev/null 2>&1; then
JAVA_VERSION=$(java -version 2>&1 | head -1 | cut -d'"' -f2)
log_success "Java版本: $JAVA_VERSION"
else
log_error "Java未安装或未配置环境变量"
exit 1
fi
}
# 检查Maven环境
check_maven() {
log_info "检查Maven环境..."
if command -v mvn >/dev/null 2>&1; then
MAVEN_VERSION=$(mvn -version | head -1 | awk '{print $3}')
log_success "Maven版本: $MAVEN_VERSION"
else
log_error "Maven未安装或未配置环境变量"
exit 1
fi
}
# 清理项目
clean_project() {
log_info "清理项目..."
mvn clean
log_success "项目清理完成"
}
# 编译项目
compile_project() {
log_info "编译项目..."
mvn compile
if [ $? -eq 0 ]; then
log_success "项目编译成功"
else
log_error "项目编译失败"
exit 1
fi
}
# 运行测试
run_tests() {
log_info "运行测试..."
mvn test
if [ $? -eq 0 ]; then
log_success "测试通过"
else
log_warning "测试失败,但继续构建"
fi
}
# 打包项目
package_project() {
log_info "打包项目..."
mvn package -DskipTests
if [ $? -eq 0 ]; then
log_success "项目打包成功"
else
log_error "项目打包失败"
exit 1
fi
}
# 验证构建结果
verify_build() {
log_info "验证构建结果..."
JAR_FILE="target/emotion-single-1.0.0.jar"
if [ -f "$JAR_FILE" ]; then
JAR_SIZE=$(du -h "$JAR_FILE" | cut -f1)
log_success "JAR文件生成成功: $JAR_FILE (大小: $JAR_SIZE)"
else
log_error "JAR文件未生成"
exit 1
fi
}
# 主函数
main() {
log_info "🚀 开始构建emotion-single项目..."
check_java
check_maven
clean_project
compile_project
run_tests
package_project
verify_build
log_success "🎉 构建完成!"
echo ""
echo "📋 构建结果:"
echo " JAR文件: target/emotion-single-1.0.0.jar"
echo " 下一步: 运行 ./deploy.sh 部署到服务器"
}
# 执行主函数
main "$@"
-628
View File
@@ -1,628 +0,0 @@
#!/bin/bash
# 创建剩余的Service实现类
echo "开始创建剩余的Service实现类..."
# 1. MessageServiceImpl
cat > src/main/java/com/emotion/service/impl/MessageServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.Message;
import com.emotion.mapper.MessageMapper;
import com.emotion.service.MessageService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
@Override
public IPage<Message> getPage(BasePageRequest request) {
Page<Message> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(Message::getContent, request.getKeyword());
}
wrapper.eq(Message::getIsDeleted, 0).orderByDesc(Message::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<Message> getByConversationId(String conversationId) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getConversationId, conversationId)
.eq(Message::getIsDeleted, 0)
.orderByAsc(Message::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Message> getBySender(String sender) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getSender, sender)
.eq(Message::getIsDeleted, 0)
.orderByDesc(Message::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Message> getByType(String type) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getType, type)
.eq(Message::getIsDeleted, 0)
.orderByDesc(Message::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Message> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.between(Message::getCreateTime, startTime, endTime)
.eq(Message::getIsDeleted, 0)
.orderByDesc(Message::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByConversationId(String conversationId) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getConversationId, conversationId)
.eq(Message::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Long countBySender(String sender) {
LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Message::getSender, sender)
.eq(Message::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public boolean updateReadStatus(String id, Integer isRead) {
Message message = new Message();
message.setId(id);
message.setIsRead(isRead);
return this.updateById(message);
}
@Override
public Message createMessage(String conversationId, String content, String sender, String type) {
Message message = new Message();
message.setConversationId(conversationId);
message.setContent(content);
message.setSender(sender);
message.setType(type);
message.setIsRead(0);
this.save(message);
return message;
}
}
EOF
# 2. CommentServiceImpl
cat > src/main/java/com/emotion/service/impl/CommentServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.Comment;
import com.emotion.mapper.CommentMapper;
import com.emotion.service.CommentService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
@Override
public IPage<Comment> getPage(BasePageRequest request) {
Page<Comment> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(Comment::getContent, request.getKeyword());
}
wrapper.eq(Comment::getIsDeleted, 0).orderByDesc(Comment::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<Comment> getByPostId(String postId) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getPostId, postId)
.eq(Comment::getIsDeleted, 0)
.orderByAsc(Comment::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Comment> getByUserId(String userId) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getCreateBy, userId)
.eq(Comment::getIsDeleted, 0)
.orderByDesc(Comment::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByPostId(String postId) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getPostId, postId)
.eq(Comment::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Comment createComment(String postId, String content, String userId) {
Comment comment = new Comment();
comment.setPostId(postId);
comment.setContent(content);
comment.setCreateBy(userId);
this.save(comment);
return comment;
}
}
EOF
# 3. CommunityPostServiceImpl
cat > src/main/java/com/emotion/service/impl/CommunityPostServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.CommunityPost;
import com.emotion.mapper.CommunityPostMapper;
import com.emotion.service.CommunityPostService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class CommunityPostServiceImpl extends ServiceImpl<CommunityPostMapper, CommunityPost> implements CommunityPostService {
@Override
public IPage<CommunityPost> getPage(BasePageRequest request) {
Page<CommunityPost> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<CommunityPost> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.and(w -> w.like(CommunityPost::getTitle, request.getKeyword())
.or().like(CommunityPost::getContent, request.getKeyword()));
}
wrapper.eq(CommunityPost::getIsDeleted, 0).orderByDesc(CommunityPost::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<CommunityPost> getByUserId(String userId) {
LambdaQueryWrapper<CommunityPost> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CommunityPost::getCreateBy, userId)
.eq(CommunityPost::getIsDeleted, 0)
.orderByDesc(CommunityPost::getCreateTime);
return this.list(wrapper);
}
@Override
public List<CommunityPost> getByCategory(String category) {
LambdaQueryWrapper<CommunityPost> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CommunityPost::getCategory, category)
.eq(CommunityPost::getIsDeleted, 0)
.orderByDesc(CommunityPost::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByUserId(String userId) {
LambdaQueryWrapper<CommunityPost> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CommunityPost::getCreateBy, userId)
.eq(CommunityPost::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public CommunityPost createPost(String title, String content, String category, String userId) {
CommunityPost post = new CommunityPost();
post.setTitle(title);
post.setContent(content);
post.setCategory(category);
post.setCreateBy(userId);
post.setLikeCount(0);
post.setCommentCount(0);
this.save(post);
return post;
}
}
EOF
# 4. GuestUserServiceImpl
cat > src/main/java/com/emotion/service/impl/GuestUserServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.GuestUser;
import com.emotion.mapper.GuestUserMapper;
import com.emotion.service.GuestUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class GuestUserServiceImpl extends ServiceImpl<GuestUserMapper, GuestUser> implements GuestUserService {
@Override
public IPage<GuestUser> getPage(BasePageRequest request) {
Page<GuestUser> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(GuestUser::getNickname, request.getKeyword());
}
wrapper.eq(GuestUser::getIsDeleted, 0).orderByDesc(GuestUser::getCreateTime);
return this.page(page, wrapper);
}
@Override
public GuestUser getByClientIp(String clientIp) {
LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(GuestUser::getClientIp, clientIp)
.eq(GuestUser::getIsDeleted, 0);
return this.getOne(wrapper);
}
@Override
public List<GuestUser> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
wrapper.between(GuestUser::getCreateTime, startTime, endTime)
.eq(GuestUser::getIsDeleted, 0)
.orderByDesc(GuestUser::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<GuestUser> wrapper = new LambdaQueryWrapper<>();
wrapper.between(GuestUser::getCreateTime, startTime, endTime)
.eq(GuestUser::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public GuestUser createGuestUser(String clientIp, String userAgent) {
GuestUser guestUser = new GuestUser();
guestUser.setClientIp(clientIp);
guestUser.setUserAgent(userAgent);
guestUser.setNickname("访客用户");
guestUser.setLastActiveTime(LocalDateTime.now());
this.save(guestUser);
return guestUser;
}
}
EOF
# 5. UserStatsServiceImpl
cat > src/main/java/com/emotion/service/impl/UserStatsServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.UserStats;
import com.emotion.mapper.UserStatsMapper;
import com.emotion.service.UserStatsService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class UserStatsServiceImpl extends ServiceImpl<UserStatsMapper, UserStats> implements UserStatsService {
@Override
public IPage<UserStats> getPage(BasePageRequest request) {
Page<UserStats> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<UserStats> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(UserStats::getUserId, request.getKeyword());
}
wrapper.eq(UserStats::getIsDeleted, 0).orderByDesc(UserStats::getCreateTime);
return this.page(page, wrapper);
}
@Override
public UserStats getByUserId(String userId) {
LambdaQueryWrapper<UserStats> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(UserStats::getUserId, userId)
.eq(UserStats::getIsDeleted, 0);
return this.getOne(wrapper);
}
@Override
public List<UserStats> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<UserStats> wrapper = new LambdaQueryWrapper<>();
wrapper.between(UserStats::getCreateTime, startTime, endTime)
.eq(UserStats::getIsDeleted, 0)
.orderByDesc(UserStats::getCreateTime);
return this.list(wrapper);
}
@Override
public UserStats createUserStats(String userId) {
UserStats userStats = new UserStats();
userStats.setUserId(userId);
userStats.setTotalConversations(0);
userStats.setTotalMessages(0);
userStats.setTotalEmotionRecords(0);
userStats.setTotalAchievements(0);
this.save(userStats);
return userStats;
}
}
EOF
# 6. EmotionRecordServiceImpl
cat > src/main/java/com/emotion/service/impl/EmotionRecordServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.EmotionRecord;
import com.emotion.mapper.EmotionRecordMapper;
import com.emotion.service.EmotionRecordService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class EmotionRecordServiceImpl extends ServiceImpl<EmotionRecordMapper, EmotionRecord> implements EmotionRecordService {
@Override
public IPage<EmotionRecord> getPage(BasePageRequest request) {
Page<EmotionRecord> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<EmotionRecord> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(EmotionRecord::getDescription, request.getKeyword());
}
wrapper.eq(EmotionRecord::getIsDeleted, 0).orderByDesc(EmotionRecord::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<EmotionRecord> getByUserId(String userId) {
LambdaQueryWrapper<EmotionRecord> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(EmotionRecord::getCreateBy, userId)
.eq(EmotionRecord::getIsDeleted, 0)
.orderByDesc(EmotionRecord::getCreateTime);
return this.list(wrapper);
}
@Override
public List<EmotionRecord> getByEmotionType(String emotionType) {
LambdaQueryWrapper<EmotionRecord> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(EmotionRecord::getEmotionType, emotionType)
.eq(EmotionRecord::getIsDeleted, 0)
.orderByDesc(EmotionRecord::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByUserId(String userId) {
LambdaQueryWrapper<EmotionRecord> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(EmotionRecord::getCreateBy, userId)
.eq(EmotionRecord::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public EmotionRecord createEmotionRecord(String userId, String emotionType, String description) {
EmotionRecord record = new EmotionRecord();
record.setCreateBy(userId);
record.setEmotionType(emotionType);
record.setDescription(description);
record.setRecordTime(LocalDateTime.now());
this.save(record);
return record;
}
}
EOF
# 7. ConversationServiceImpl
cat > src/main/java/com/emotion/service/impl/ConversationServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.Conversation;
import com.emotion.mapper.ConversationMapper;
import com.emotion.service.ConversationService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class ConversationServiceImpl extends ServiceImpl<ConversationMapper, Conversation> implements ConversationService {
@Override
public IPage<Conversation> getPage(BasePageRequest request) {
Page<Conversation> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(Conversation::getTitle, request.getKeyword());
}
wrapper.eq(Conversation::getIsDeleted, 0).orderByDesc(Conversation::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<Conversation> getByUserId(String userId) {
LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Conversation::getCreateBy, userId)
.eq(Conversation::getIsDeleted, 0)
.orderByDesc(Conversation::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Conversation> getByStatus(String status) {
LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Conversation::getStatus, status)
.eq(Conversation::getIsDeleted, 0)
.orderByDesc(Conversation::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByUserId(String userId) {
LambdaQueryWrapper<Conversation> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Conversation::getCreateBy, userId)
.eq(Conversation::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Conversation createConversation(String userId, String title, String type) {
Conversation conversation = new Conversation();
conversation.setCreateBy(userId);
conversation.setTitle(title);
conversation.setType(type);
conversation.setStatus("active");
conversation.setMessageCount(0);
this.save(conversation);
return conversation;
}
}
EOF
# 8. TopicInteractionServiceImpl
cat > src/main/java/com/emotion/service/impl/TopicInteractionServiceImpl.java << 'EOF'
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.BasePageRequest;
import com.emotion.entity.TopicInteraction;
import com.emotion.mapper.TopicInteractionMapper;
import com.emotion.service.TopicInteractionService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class TopicInteractionServiceImpl extends ServiceImpl<TopicInteractionMapper, TopicInteraction> implements TopicInteractionService {
@Override
public IPage<TopicInteraction> getPage(BasePageRequest request) {
Page<TopicInteraction> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<TopicInteraction> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.hasText(request.getKeyword())) {
wrapper.like(TopicInteraction::getUserId, request.getKeyword());
}
wrapper.eq(TopicInteraction::getIsDeleted, 0).orderByDesc(TopicInteraction::getCreateTime);
return this.page(page, wrapper);
}
@Override
public List<TopicInteraction> getByUserId(String userId) {
LambdaQueryWrapper<TopicInteraction> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TopicInteraction::getUserId, userId)
.eq(TopicInteraction::getIsDeleted, 0)
.orderByDesc(TopicInteraction::getCreateTime);
return this.list(wrapper);
}
@Override
public List<TopicInteraction> getByTopicId(String topicId) {
LambdaQueryWrapper<TopicInteraction> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TopicInteraction::getTopicId, topicId)
.eq(TopicInteraction::getIsDeleted, 0)
.orderByDesc(TopicInteraction::getCreateTime);
return this.list(wrapper);
}
@Override
public Long countByUserId(String userId) {
LambdaQueryWrapper<TopicInteraction> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TopicInteraction::getUserId, userId)
.eq(TopicInteraction::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public TopicInteraction createInteraction(String userId, String topicId, String interactionType) {
TopicInteraction interaction = new TopicInteraction();
interaction.setUserId(userId);
interaction.setTopicId(topicId);
interaction.setInteractionType(interactionType);
interaction.setInteractionTime(LocalDateTime.now());
this.save(interaction);
return interaction;
}
}
EOF
echo "所有Service实现类创建完成!"
@@ -22,11 +22,11 @@ SET
time_zone = "+00:00";
-- 创建数据库
CREATE DATABASE IF NOT EXISTS emotion_museum DEFAULT CHARACTER
SET
CREATE DATABASE IF NOT EXISTS emotion DEFAULT CHARACTER
SET
utf8mb4 COLLATE utf8mb4_unicode_ci;
USE emotion_museum;
USE emotion;
-- ============================================================================
-- 数据库设计原则
@@ -74,39 +74,39 @@ DROP TABLE IF EXISTS user;
-- 1. 用户表 (user)
-- ============================================================================
CREATE TABLE user (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
account VARCHAR(50) NOT NULL UNIQUE, -- 账号
password VARCHAR(255) NOT NULL, -- 密码(加密后)
username VARCHAR(50) NOT NULL UNIQUE, -- 用户名
email VARCHAR(100) NOT NULL UNIQUE, -- 邮箱
phone VARCHAR(20) UNIQUE, -- 手机号
avatar VARCHAR(500), -- 头像URL
nickname VARCHAR(50) NOT NULL, -- 昵称
birth_date DATE, -- 生日
location VARCHAR(100), -- 所在地
bio TEXT, -- 个人简介
member_level VARCHAR(20) NOT NULL DEFAULT 'free', -- 会员等级
total_days INT NOT NULL DEFAULT 0, -- 使用天数
id VARCHAR(36) PRIMARY KEY, -- UUID主键
account VARCHAR(50) UNIQUE, -- 账号
password VARCHAR(255) , -- 密码(加密后)
username VARCHAR(50) UNIQUE, -- 用户名
email VARCHAR(100) UNIQUE, -- 邮箱
phone VARCHAR(20) UNIQUE, -- 手机号
avatar VARCHAR(500), -- 头像URL
nickname VARCHAR(50) , -- 昵称
birth_date DATE, -- 生日
location VARCHAR(100), -- 所在地
bio TEXT, -- 个人简介
member_level VARCHAR(20) DEFAULT 'free', -- 会员等级
total_days INT DEFAULT 0, -- 使用天数
-- 成长数据
self_awareness DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 自我感知
emotional_resilience DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 情绪韧性
action_power DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 行动力
empathy DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 共情力
life_enthusiasm DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 生活热度
self_awareness DECIMAL(5, 2) DEFAULT 50.00, -- 自我感知
emotional_resilience DECIMAL(5, 2) DEFAULT 50.00, -- 情绪韧性
action_power DECIMAL(5, 2) DEFAULT 50.00, -- 行动力
empathy DECIMAL(5, 2) DEFAULT 50.00, -- 共情力
life_enthusiasm DECIMAL(5, 2) DEFAULT 50.00, -- 生活热度
-- 状态字段
status TINYINT NOT NULL DEFAULT 1, -- 状态: 0-禁用, 1-正常
is_verified TINYINT NOT NULL DEFAULT 0, -- 是否已验证: 0-未验证, 1-已验证
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
status TINYINT DEFAULT 1, -- 状态: 0-禁用, 1-正常
is_verified TINYINT DEFAULT 0, -- 是否已验证: 0-未验证, 1-已验证
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
-- 第三方登录字段
third_party_id VARCHAR(128), -- 第三方平台ID
third_party_type VARCHAR(32), -- 第三方平台类型: wechat, qq, wechat-mp
third_party_id VARCHAR(128), -- 第三方平台ID
third_party_type VARCHAR(32), -- 第三方平台类型: wechat, qq, wechat-mp
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表';
-- ============================================================================
@@ -114,41 +114,41 @@ CREATE TABLE user (
-- 关联说明: user_id 关联 user.id,通过代码逻辑维护关联关系
-- ============================================================================
CREATE TABLE conversation (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) NOT NULL, -- 用户ID (关联user.id)
user_type VARCHAR(20) NOT NULL DEFAULT 'registered', -- 用户类型: registered-注册用户, guest-访客用户
title VARCHAR(200), -- 对话标题
type VARCHAR(50) NOT NULL DEFAULT 'emotion_chat', -- 对话类型
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态: active-活跃, ended-结束, archived-归档
coze_conversation_id VARCHAR(100), -- Coze对话ID
bot_id VARCHAR(50), -- 使用的Bot ID
workflow_id VARCHAR(50), -- 使用的Workflow ID
initial_message TEXT, -- 初始消息
context TEXT, -- 上下文信息
primary_emotion VARCHAR(50), -- 主要情绪
emotion_intensity DECIMAL(3, 2), -- 情绪强度
emotion_trend VARCHAR(50), -- 情绪趋势
keywords JSON, -- 关键词
ai_insights TEXT, -- AI洞察
confidence DECIMAL(3, 2), -- 分析置信度
start_time DATETIME, -- 开始时间
end_time DATETIME, -- 结束时间
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
message_count INT NOT NULL DEFAULT 0, -- 消息数量
total_tokens INT DEFAULT 0, -- 总Token使用量
total_cost DECIMAL(10, 4) DEFAULT 0.0000, -- 总费用
client_ip VARCHAR(45), -- 客户端IP地址 (支持IPv6)
user_agent TEXT, -- 用户代理信息
summary TEXT, -- 对话摘要
tags JSON, -- 标签
metadata JSON, -- 扩展元数据
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) , -- 用户ID (关联user.id)
user_type VARCHAR(20) DEFAULT 'registered', -- 用户类型: registered-注册用户, guest-访客用户
title VARCHAR(200), -- 对话标题
type VARCHAR(50) DEFAULT 'emotion_chat', -- 对话类型
status VARCHAR(20) DEFAULT 'active', -- 状态: active-活跃, ended-结束, archived-归档
coze_conversation_id VARCHAR(100), -- Coze对话ID
bot_id VARCHAR(50), -- 使用的Bot ID
workflow_id VARCHAR(50), -- 使用的Workflow ID
initial_message TEXT, -- 初始消息
context TEXT, -- 上下文信息
primary_emotion VARCHAR(50), -- 主要情绪
emotion_intensity DECIMAL(3, 2), -- 情绪强度
emotion_trend VARCHAR(50), -- 情绪趋势
keywords JSON, -- 关键词
ai_insights TEXT, -- AI洞察
confidence DECIMAL(3, 2), -- 分析置信度
start_time DATETIME, -- 开始时间
end_time DATETIME, -- 结束时间
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
message_count INT DEFAULT 0, -- 消息数量
total_tokens INT DEFAULT 0, -- 总Token使用量
total_cost DECIMAL(10, 4) DEFAULT 0.0000, -- 总费用
client_ip VARCHAR(45), -- 客户端IP地址 (支持IPv6)
user_agent TEXT, -- 用户代理信息
summary TEXT, -- 对话摘要
tags JSON, -- 标签
metadata JSON, -- 扩展元数据
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '对话表';
-- ============================================================================
@@ -156,368 +156,368 @@ CREATE TABLE conversation (
-- 关联说明: conversation_id 关联 conversation.id,通过代码逻辑维护关联关系
-- ============================================================================
CREATE TABLE message (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
conversation_id VARCHAR(36) NOT NULL, -- 对话ID (关联conversation.id)
content TEXT NOT NULL, -- 消息内容
type VARCHAR(50) NOT NULL DEFAULT 'text', -- 消息类型
sender VARCHAR(20) NOT NULL, -- 发送者: user-用户, assistant-AI助手
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 消息时间戳
coze_chat_id VARCHAR(50), -- Coze平台的聊天ID
coze_message_id VARCHAR(50), -- Coze平台的消息ID
status VARCHAR(20) DEFAULT 'sent', -- 消息状态: sending/sent/failed/processing
error_message TEXT, -- 错误信息
emotion_score DECIMAL(3, 2), -- 情绪评分
emotion_type VARCHAR(50), -- 情绪类型
emotion_confidence DECIMAL(3, 2), -- 情绪分析置信度
prompt_tokens INT DEFAULT 0, -- 输入Token数
completion_tokens INT DEFAULT 0, -- 输出Token数
total_tokens INT DEFAULT 0, -- 总Token数
api_cost DECIMAL(10, 6) DEFAULT 0.000000, -- API调用费用
is_read TINYINT NOT NULL DEFAULT 0, -- 是否已读: 0-未读, 1-已读
parent_message_id VARCHAR(36), -- 父消息ID(用于回复链)
emotion_analysis JSON, -- 情绪分析结果
metadata JSON, -- 扩展元数据
id VARCHAR(36) PRIMARY KEY, -- UUID主键
conversation_id VARCHAR(36) , -- 对话ID (关联conversation.id)
content TEXT , -- 消息内容
type VARCHAR(50) DEFAULT 'text', -- 消息类型
sender VARCHAR(20) , -- 发送者: user-用户, assistant-AI助手
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, -- 消息时间戳
coze_chat_id VARCHAR(50), -- Coze平台的聊天ID
coze_message_id VARCHAR(50), -- Coze平台的消息ID
status VARCHAR(20) DEFAULT 'sent', -- 消息状态: sending/sent/failed/processing
error_message TEXT, -- 错误信息
emotion_score DECIMAL(3, 2), -- 情绪评分
emotion_type VARCHAR(50), -- 情绪类型
emotion_confidence DECIMAL(3, 2), -- 情绪分析置信度
prompt_tokens INT DEFAULT 0, -- 输入Token数
completion_tokens INT DEFAULT 0, -- 输出Token数
total_tokens INT DEFAULT 0, -- 总Token数
api_cost DECIMAL(10, 6) DEFAULT 0.000000, -- API调用费用
is_read TINYINT DEFAULT 0, -- 是否已读: 0-未读, 1-已读
parent_message_id VARCHAR(36), -- 父消息ID(用于回复链)
emotion_analysis JSON, -- 情绪分析结果
metadata JSON, -- 扩展元数据
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息表';
-- ============================================================================
-- 4. Coze API调用记录表 (coze_api_call) - 优化版本
-- ============================================================================
CREATE TABLE coze_api_call (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
conversation_id VARCHAR(36), -- 对话ID
message_id VARCHAR(36), -- 消息ID
id VARCHAR(36) PRIMARY KEY, -- UUID主键
conversation_id VARCHAR(36), -- 对话ID
message_id VARCHAR(36), -- 消息ID
-- Coze API 信息
coze_chat_id VARCHAR(50), -- Coze聊天ID
coze_conversation_id VARCHAR(50), -- Coze对话ID
bot_id VARCHAR(50) NOT NULL, -- Bot ID
workflow_id VARCHAR(50), -- Workflow ID
user_id VARCHAR(36) NOT NULL, -- 用户ID
coze_chat_id VARCHAR(50), -- Coze聊天ID
coze_conversation_id VARCHAR(50), -- Coze对话ID
bot_id VARCHAR(50) , -- Bot ID
workflow_id VARCHAR(50), -- Workflow ID
user_id VARCHAR(36) , -- 用户ID
-- 请求信息
request_type VARCHAR(20) NOT NULL, -- 请求类型: chat/stream/retrieve/messages
request_url VARCHAR(500), -- 请求URL
request_body JSON, -- 请求体
request_headers JSON, -- 请求头
request_type VARCHAR(20) , -- 请求类型: chat/stream/retrieve/messages
request_url VARCHAR(500), -- 请求URL
request_body JSON, -- 请求体
request_headers JSON, -- 请求头
-- 用户消息内容
user_message TEXT, -- 用户输入的消息内容
user_message_type VARCHAR(20) DEFAULT 'text', -- 用户消息类型: text/image/file
user_message TEXT, -- 用户输入的消息内容
user_message_type VARCHAR(20) DEFAULT 'text', -- 用户消息类型: text/image/file
-- AI回复内容
ai_reply TEXT, -- AI回复的消息内容
ai_reply_type VARCHAR(20) DEFAULT 'text', -- AI回复类型: text/image/file
ai_reply TEXT, -- AI回复的消息内容
ai_reply_type VARCHAR(20) DEFAULT 'text', -- AI回复类型: text/image/file
-- 响应信息
response_status INT, -- HTTP状态码
response_body JSON, -- 响应体
response_headers JSON, -- 响应头
response_status INT, -- HTTP状态码
response_body JSON, -- 响应体
response_headers JSON, -- 响应头
-- 轮询信息
poll_count INT DEFAULT 0, -- 轮询次数
poll_start_time DATETIME, -- 轮询开始时间
poll_end_time DATETIME, -- 轮询结束时间
final_status VARCHAR(20), -- 最终状态: completed/failed/timeout
poll_count INT DEFAULT 0, -- 轮询次数
poll_start_time DATETIME, -- 轮询开始时间
poll_end_time DATETIME, -- 轮询结束时间
final_status VARCHAR(20), -- 最终状态: completed/failed/timeout
-- 状态和时间
status VARCHAR(20) NOT NULL, -- 调用状态: pending/success/failed/timeout
start_time DATETIME NOT NULL, -- 开始时间
end_time DATETIME, -- 结束时间
duration_ms INT, -- 耗时(毫秒)
status VARCHAR(20) , -- 调用状态: pending/success/failed/timeout
start_time DATETIME , -- 开始时间
end_time DATETIME, -- 结束时间
duration_ms INT, -- 耗时(毫秒)
-- 使用统计
prompt_tokens INT DEFAULT 0, -- 输入Token数
completion_tokens INT DEFAULT 0, -- 输出Token数
total_tokens INT DEFAULT 0, -- 总Token数
cost DECIMAL(10, 6) DEFAULT 0.000000, -- 费用
prompt_tokens INT DEFAULT 0, -- 输入Token数
completion_tokens INT DEFAULT 0, -- 输出Token数
total_tokens INT DEFAULT 0, -- 总Token数
cost DECIMAL(10, 6) DEFAULT 0.000000, -- 费用
-- 功能调用信息
function_calls JSON, -- 函数调用记录
function_results JSON, -- 函数调用结果
function_calls JSON, -- 函数调用记录
function_results JSON, -- 函数调用结果
-- 错误信息
error_code VARCHAR(50), -- 错误代码
error_message TEXT, -- 错误信息
error_code VARCHAR(50), -- 错误代码
error_message TEXT, -- 错误信息
-- 扩展信息
client_ip VARCHAR(45), -- 客户端IP
user_agent TEXT, -- 用户代理
session_id VARCHAR(100), -- 会话ID
trace_id VARCHAR(100), -- 追踪ID
metadata JSON, -- 扩展元数据
client_ip VARCHAR(45), -- 客户端IP
user_agent TEXT, -- 用户代理
session_id VARCHAR(100), -- 会话ID
trace_id VARCHAR(100), -- 追踪ID
metadata JSON, -- 扩展元数据
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Coze API调用记录表 - 完整版本';
-- ============================================================================
-- 5. 情绪分析表 (emotion_analysis)
-- ============================================================================
CREATE TABLE emotion_analysis (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) NOT NULL, -- 用户ID
message_id VARCHAR(36), -- 关联消息ID
text TEXT NOT NULL, -- 分析文本
primary_emotion VARCHAR(50), -- 主要情绪
intensity DECIMAL(3, 2), -- 情绪强度
polarity VARCHAR(20), -- 情绪极性: positive-积极, negative-消极, neutral-中性
confidence DECIMAL(3, 2), -- 置信度
emotions JSON, -- 情绪分布详情
keywords JSON, -- 关键词列表
suggestion TEXT, -- 建议
analysis_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 分析时间
metadata JSON, -- 扩展元数据
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) , -- 用户ID
message_id VARCHAR(36), -- 关联消息ID
text TEXT , -- 分析文本
primary_emotion VARCHAR(50), -- 主要情绪
intensity DECIMAL(3, 2), -- 情绪强度
polarity VARCHAR(20), -- 情绪极性: positive-积极, negative-消极, neutral-中性
confidence DECIMAL(3, 2), -- 置信度
emotions JSON, -- 情绪分布详情
keywords JSON, -- 关键词列表
suggestion TEXT, -- 建议
analysis_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 分析时间
metadata JSON, -- 扩展元数据
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪分析表';
-- ============================================================================
-- 6. 情绪记录表 (emotion_record)
-- ============================================================================
CREATE TABLE emotion_record (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) NOT NULL, -- 用户ID
record_date DATE NOT NULL, -- 记录日期
emotion_type VARCHAR(50) NOT NULL, -- 情绪类型
intensity DECIMAL(3, 2) NOT NULL, -- 情绪强度
triggers TEXT, -- 触发因素
description TEXT, -- 描述
tags JSON, -- 标签
weather VARCHAR(50), -- 天气
location VARCHAR(100), -- 地点
activity VARCHAR(100), -- 活动
people VARCHAR(200), -- 相关人物
notes TEXT, -- 备注
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) , -- 用户ID
record_date DATE , -- 记录日期
emotion_type VARCHAR(50) , -- 情绪类型
intensity DECIMAL(3, 2) , -- 情绪强度
triggers TEXT, -- 触发因素
description TEXT, -- 描述
tags JSON, -- 标签
weather VARCHAR(50), -- 天气
location VARCHAR(100), -- 地点
activity VARCHAR(100), -- 活动
people VARCHAR(200), -- 相关人物
notes TEXT, -- 备注
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪记录表';
-- ============================================================================
-- 7. 成长课题表 (growth_topic)
-- ============================================================================
CREATE TABLE growth_topic (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
title VARCHAR(100) NOT NULL, -- 课题标题
category VARCHAR(50) NOT NULL, -- 分类
difficulty VARCHAR(20) NOT NULL, -- 难度: easy-简单, medium-中等, hard-困难
description TEXT, -- 描述
content TEXT, -- 内容
duration_days INT, -- 持续天数
unlock_conditions JSON, -- 解锁条件
is_unlocked TINYINT NOT NULL DEFAULT 1, -- 是否解锁
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度百分比
completed_time DATETIME, -- 完成时间
rewards JSON, -- 奖励
id VARCHAR(36) PRIMARY KEY, -- UUID主键
title VARCHAR(100) , -- 课题标题
category VARCHAR(50) , -- 分类
difficulty VARCHAR(20) , -- 难度: easy-简单, medium-中等, hard-困难
description TEXT, -- 描述
content TEXT, -- 内容
duration_days INT, -- 持续天数
unlock_conditions JSON, -- 解锁条件
is_unlocked TINYINT DEFAULT 1, -- 是否解锁
progress DECIMAL(5, 2) DEFAULT 0.00, -- 进度百分比
completed_time DATETIME, -- 完成时间
rewards JSON, -- 奖励
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成长课题表';
-- ============================================================================
-- 8. 课题互动表 (topic_interaction)
-- ============================================================================
CREATE TABLE topic_interaction (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
topic_id VARCHAR(36) NOT NULL, -- 课题ID
type VARCHAR(50) NOT NULL, -- 互动类型
content TEXT, -- 内容
user_input TEXT, -- 用户输入
ai_response TEXT, -- AI回应
rating INT, -- 评分
feedback TEXT, -- 反馈
completed_time DATETIME, -- 完成时间
id VARCHAR(36) PRIMARY KEY, -- UUID主键
topic_id VARCHAR(36) , -- 课题ID
type VARCHAR(50) , -- 互动类型
content TEXT, -- 内容
user_input TEXT, -- 用户输入
ai_response TEXT, -- AI回应
rating INT, -- 评分
feedback TEXT, -- 反馈
completed_time DATETIME, -- 完成时间
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '课题互动表';
-- ============================================================================
-- 9. 地点标记表 (location_pin)
-- ============================================================================
CREATE TABLE location_pin (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
name VARCHAR(100) NOT NULL, -- 地点名称
type VARCHAR(50) NOT NULL, -- 地点类型
category VARCHAR(50), -- 地点分类
latitude DECIMAL(10, 8) NOT NULL, -- 纬度
longitude DECIMAL(11, 8) NOT NULL, -- 经度
address VARCHAR(200), -- 地址
description TEXT, -- 描述
created_by VARCHAR(36), -- 创建者
likes INT NOT NULL DEFAULT 0, -- 点赞数
visits INT NOT NULL DEFAULT 0, -- 访问数
is_bookmarked TINYINT NOT NULL DEFAULT 0, -- 是否收藏
last_visit_time DATETIME, -- 最后访问时间
id VARCHAR(36) PRIMARY KEY, -- UUID主键
name VARCHAR(100) , -- 地点名称
type VARCHAR(50) , -- 地点类型
category VARCHAR(50), -- 地点分类
latitude DECIMAL(10, 8) , -- 纬度
longitude DECIMAL(11, 8) , -- 经度
address VARCHAR(200), -- 地址
description TEXT, -- 描述
created_by VARCHAR(36), -- 创建者
likes INT DEFAULT 0, -- 点赞数
visits INT DEFAULT 0, -- 访问数
is_bookmarked TINYINT DEFAULT 0, -- 是否收藏
last_visit_time DATETIME, -- 最后访问时间
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '地点标记表';
-- ============================================================================
-- 10. 社区帖子表 (community_post)
-- ============================================================================
CREATE TABLE community_post (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) NOT NULL, -- 用户ID
location_id VARCHAR(36), -- 地点ID
title VARCHAR(200), -- 标题
content TEXT NOT NULL, -- 内容
type VARCHAR(50) NOT NULL, -- 帖子类型
images JSON, -- 图片列表
tags JSON, -- 标签
likes INT NOT NULL DEFAULT 0, -- 点赞数
view_count INT NOT NULL DEFAULT 0, -- 浏览数
comment_count INT NOT NULL DEFAULT 0, -- 评论数
is_private TINYINT NOT NULL DEFAULT 0, -- 是否私密
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) , -- 用户ID
location_id VARCHAR(36), -- 地点ID
title VARCHAR(200), -- 标题
content TEXT , -- 内容
type VARCHAR(50) , -- 帖子类型
images JSON, -- 图片列表
tags JSON, -- 标签
likes INT DEFAULT 0, -- 点赞数
view_count INT DEFAULT 0, -- 浏览数
comment_count INT DEFAULT 0, -- 评论数
is_private TINYINT DEFAULT 0, -- 是否私密
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社区帖子表';
-- ============================================================================
-- 11. 评论表 (comment)
-- ============================================================================
CREATE TABLE comment (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
post_id VARCHAR(36) NOT NULL, -- 帖子ID
user_id VARCHAR(36) NOT NULL, -- 用户ID
content TEXT NOT NULL, -- 评论内容
reply_to_id VARCHAR(36), -- 回复的评论ID
likes INT NOT NULL DEFAULT 0, -- 点赞数
id VARCHAR(36) PRIMARY KEY, -- UUID主键
post_id VARCHAR(36) , -- 帖子ID
user_id VARCHAR(36) , -- 用户ID
content TEXT , -- 评论内容
reply_to_id VARCHAR(36), -- 回复的评论ID
likes INT DEFAULT 0, -- 点赞数
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '评论表';
-- ============================================================================
-- 12. 成就表 (achievement)
-- ============================================================================
CREATE TABLE achievement (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
title VARCHAR(100) NOT NULL, -- 成就标题
description TEXT, -- 描述
category VARCHAR(50) NOT NULL, -- 分类
icon VARCHAR(200), -- 图标
rarity VARCHAR(20) NOT NULL, -- 稀有度
condition_type VARCHAR(50), -- 条件类型
condition_value JSON, -- 条件值
rewards JSON, -- 奖励
unlocked_time DATETIME, -- 解锁时间
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度
is_hidden TINYINT NOT NULL DEFAULT 0, -- 是否隐藏
id VARCHAR(36) PRIMARY KEY, -- UUID主键
title VARCHAR(100) , -- 成就标题
description TEXT, -- 描述
category VARCHAR(50) , -- 分类
icon VARCHAR(200), -- 图标
rarity VARCHAR(20) , -- 稀有度
condition_type VARCHAR(50), -- 条件类型
condition_value JSON, -- 条件值
rewards JSON, -- 奖励
unlocked_time DATETIME, -- 解锁时间
progress DECIMAL(5, 2) DEFAULT 0.00, -- 进度
is_hidden TINYINT DEFAULT 0, -- 是否隐藏
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成就表';
-- ============================================================================
-- 13. 奖励表 (reward)
-- ============================================================================
CREATE TABLE reward (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
topic_id VARCHAR(36), -- 课题ID
achievement_id VARCHAR(36), -- 成就ID
type VARCHAR(50) NOT NULL, -- 奖励类型
name VARCHAR(100) NOT NULL, -- 奖励名称
description TEXT, -- 描述
icon VARCHAR(200), -- 图标
rarity VARCHAR(20), -- 稀有度
value JSON, -- 奖励值
earned_time DATETIME, -- 获得时间
is_new TINYINT NOT NULL DEFAULT 1, -- 是否新获得
id VARCHAR(36) PRIMARY KEY, -- UUID主键
topic_id VARCHAR(36), -- 课题ID
achievement_id VARCHAR(36), -- 成就ID
type VARCHAR(50) , -- 奖励类型
name VARCHAR(100) , -- 奖励名称
description TEXT, -- 描述
icon VARCHAR(200), -- 图标
rarity VARCHAR(20), -- 稀有度
value JSON, -- 奖励值
earned_time DATETIME, -- 获得时间
is_new TINYINT DEFAULT 1, -- 是否新获得
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '奖励表';
-- ============================================================================
-- 14. 访客用户表 (guest_user)
-- ============================================================================
CREATE TABLE guest_user (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
guest_user_id VARCHAR(50) NOT NULL UNIQUE, -- 访客用户ID (格式: guest_xxx)
ip_address VARCHAR(45) NOT NULL, -- 客户端IP地址 (支持IPv6)
user_agent TEXT, -- 用户代理信息
nickname VARCHAR(50), -- 访客昵称
avatar VARCHAR(500), -- 访客头像
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
conversation_count INT NOT NULL DEFAULT 0, -- 会话数量
message_count INT NOT NULL DEFAULT 0, -- 消息数量
location VARCHAR(100), -- IP地址的地理位置信息
device_info VARCHAR(200), -- 设备信息
id VARCHAR(36) PRIMARY KEY, -- UUID主键
guest_user_id VARCHAR(50) UNIQUE, -- 访客用户ID (格式: guest_xxx)
ip_address VARCHAR(45) , -- 客户端IP地址 (支持IPv6)
user_agent TEXT, -- 用户代理信息
nickname VARCHAR(50), -- 访客昵称
avatar VARCHAR(500), -- 访客头像
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
conversation_count INT DEFAULT 0, -- 会话数量
message_count INT DEFAULT 0, -- 消息数量
location VARCHAR(100), -- IP地址的地理位置信息
device_info VARCHAR(200), -- 设备信息
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '访客用户表';
-- ============================================================================
-- 15. 用户统计表 (user_stats)
-- ============================================================================
CREATE TABLE user_stats (
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) NOT NULL UNIQUE, -- 用户ID
total_conversations INT NOT NULL DEFAULT 0, -- 总对话数
total_messages INT NOT NULL DEFAULT 0, -- 总消息数
total_emotions_recorded INT NOT NULL DEFAULT 0, -- 总情绪记录数
topics_completed INT NOT NULL DEFAULT 0, -- 完成的课题数
achievements_unlocked INT NOT NULL DEFAULT 0, -- 解锁的成就数
total_points INT NOT NULL DEFAULT 0, -- 总积分
consecutive_days INT NOT NULL DEFAULT 0, -- 连续使用天数
max_consecutive_days INT NOT NULL DEFAULT 0, -- 最大连续天数
locations_visited INT NOT NULL DEFAULT 0, -- 访问的地点数
posts_created INT NOT NULL DEFAULT 0, -- 创建的帖子数
comments_made INT NOT NULL DEFAULT 0, -- 评论数
likes_received INT NOT NULL DEFAULT 0, -- 收到的点赞数
social_interactions INT NOT NULL DEFAULT 0, -- 社交互动数
id VARCHAR(36) PRIMARY KEY, -- UUID主键
user_id VARCHAR(36) UNIQUE, -- 用户ID
total_conversations INT DEFAULT 0, -- 总对话数
total_messages INT DEFAULT 0, -- 总消息数
total_emotions_recorded INT DEFAULT 0, -- 总情绪记录数
topics_completed INT DEFAULT 0, -- 完成的课题数
achievements_unlocked INT DEFAULT 0, -- 解锁的成就数
total_points INT DEFAULT 0, -- 总积分
consecutive_days INT DEFAULT 0, -- 连续使用天数
max_consecutive_days INT DEFAULT 0, -- 最大连续天数
locations_visited INT DEFAULT 0, -- 访问的地点数
posts_created INT DEFAULT 0, -- 创建的帖子数
comments_made INT DEFAULT 0, -- 评论数
likes_received INT DEFAULT 0, -- 收到的点赞数
social_interactions INT DEFAULT 0, -- 社交互动数
-- 公共字段
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
create_by VARCHAR(36), -- 创建人ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 创建时间
update_by VARCHAR(36), -- 更新人ID
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
is_deleted TINYINT DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
remarks VARCHAR(500) -- 备注
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户统计表';
-- ============================================================================
@@ -836,7 +836,7 @@ SELECT
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_SCHEMA = 'emotion_museum';
TABLE_SCHEMA = 'emotion';
-- 显示创建的表
SELECT
@@ -846,7 +846,7 @@ SELECT
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_SCHEMA = 'emotion_museum'
TABLE_SCHEMA = 'emotion'
ORDER BY
TABLE_NAME;