修正消息中心不显示

This commit is contained in:
2025-11-22 16:01:36 +08:00
parent f3a9926caf
commit 12592c5a24
15 changed files with 331 additions and 380 deletions

View File

@@ -1,331 +0,0 @@
# 成就模块迁移指南
## 📝 迁移概述
成就相关功能已从 `usercenter` 模块迁移到独立的 `achievement` 模块。
### 迁移日期
2025-10-24
### 迁移原因
-**模块职责分离** - usercenter负责用户中心achievement专注于成就系统
-**更好的可维护性** - 独立模块易于管理和扩展
-**清晰的依赖关系** - 减少模块间的耦合
-**可扩展性** - 便于添加新的成就类型和功能
## 🔄 包路径变更
### API接口变更
**旧路径(已删除):**
```java
org.xyzh.api.usercenter.achievement.UserAchievementService
```
**新路径:**
```java
org.xyzh.api.achievement.AchievementService
```
### 服务实现变更
**旧路径(已删除):**
```java
org.xyzh.usercenter.service.UCUserAchievementService
org.xyzh.usercenter.service.impl.UCUserAchievementServiceImpl
```
**新路径:**
```java
org.xyzh.api.achievement.AchievementService
org.xyzh.achievement.service.impl.ACHAchievementServiceImpl
```
### Mapper变更
**旧路径(已删除):**
```java
org.xyzh.usercenter.mapper.AchievementMapper
org.xyzh.usercenter.mapper.UserAchievementMapper
```
**新路径:**
```java
org.xyzh.achievement.mapper.AchievementMapper
org.xyzh.achievement.mapper.UserAchievementMapper
org.xyzh.achievement.mapper.UserAchievementProgressMapper // 新增
```
### Controller变更
**旧路径(已删除):**
```java
org.xyzh.usercenter.controller.UserAchievementController
```
**新路径:**
```java
org.xyzh.achievement.controller.AchievementController
```
## 📦 依赖变更
### 如果你的模块之前依赖了成就功能
#### 旧的依赖配置(需要删除):
```xml
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>api-usercenter</artifactId> <!-- 包含成就接口 -->
<version>1.0.0</version>
</dependency>
```
#### 新的依赖配置(需要添加):
```xml
<!-- API接口依赖 -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>api-achievement</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 如果需要使用实现类通常不需要使用Dubbo远程调用 -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>achievement</artifactId>
<version>1.0.0</version>
</dependency>
```
## 🔧 代码迁移步骤
### 1. 更新导入语句
**旧代码:**
```java
import org.xyzh.api.usercenter.achievement.UserAchievementService;
```
**新代码:**
```java
import org.xyzh.api.achievement.AchievementService;
```
### 2. 更新服务注入
**旧代码:**
```java
@Autowired
private UserAchievementService userAchievementService;
```
**新代码:**
```java
@Autowired
private AchievementService achievementService;
```
### 3. 更新方法调用
大部分方法签名保持不变,只需更新服务名称:
**旧代码:**
```java
ResultDomain<TbUserAchievement> result = userAchievementService.getUserAchievements(userID, type);
```
**新代码:**
```java
ResultDomain<TbUserAchievement> result = achievementService.getUserAchievements(userID, type);
```
### 4. 新增功能调用
新的成就系统增加了事件驱动机制:
```java
// 发布成就事件
AchievementEvent event = AchievementEvent.builder(userID, AchievementEventType.COURSE_COMPLETED)
.value(1)
.build();
// 方式1使用Spring事件发布推荐
eventPublisher.publishEvent(event);
// 方式2直接调用服务
achievementService.processAchievementEvent(event);
```
## 🗄️ 数据库变更
### 新增表
```sql
-- 用户成就进度表(新增)
CREATE TABLE tb_user_achievement_progress (
id VARCHAR(32) NOT NULL,
user_id VARCHAR(32) NOT NULL,
achievement_id VARCHAR(32) NOT NULL,
current_value INT DEFAULT 0,
target_value INT DEFAULT 0,
progress_percentage INT DEFAULT 0,
completed TINYINT(1) DEFAULT 0,
last_update_time DATETIME,
create_time DATETIME,
PRIMARY KEY (id),
UNIQUE KEY uk_user_achievement_progress (user_id, achievement_id)
);
```
### 已有表
`tb_achievement``tb_user_achievement` 表结构保持不变,无需迁移数据。
## 🌐 REST API变更
### 接口路径变更
**旧路径:**
```
/usercenter/achievement/*
```
**新路径:**
```
/achievement/*
```
### 具体接口映射
| 功能 | 旧接口 | 新接口 | 变化 |
|-----|-------|-------|-----|
| 获取所有成就 | GET /usercenter/achievement/list | GET /achievement/list | 路径变更 |
| 获取用户成就 | GET /usercenter/achievement/user/{userID} | GET /achievement/user/{userID} | 路径变更 |
| 获取我的成就 | - | GET /achievement/my | **新增** |
| 授予成就 | POST /usercenter/achievement/grant | POST /achievement/grant | 路径变更 |
| 检查条件 | GET /usercenter/achievement/condition/{userID}/{achievementID} | GET /achievement/condition/check/{userID}/{achievementID} | 路径变更 |
| 获取进度 | - | GET /achievement/progress/{userID} | **新增** |
| 处理事件 | - | POST /achievement/event/process | **新增** |
| 获取统计 | - | GET /achievement/statistics/{userID} | **新增** |
| 排行榜 | - | GET /achievement/ranking | **新增** |
## ✨ 新增功能
### 1. 事件驱动机制
```java
// 自动监听业务事件并触发成就检测
@Autowired
private ApplicationEventPublisher eventPublisher;
AchievementEvent event = AchievementEvent.builder(userID, eventType)
.value(value)
.build();
eventPublisher.publishEvent(event);
```
### 2. 成就进度追踪
```java
// 查询用户的成就进度
ResultDomain<TbUserAchievementProgress> result =
achievementService.getMyAchievementProgress(achievementID);
```
### 3. 策略模式检测器
- 可扩展的成就检测器
- 支持多种成就类型
- 易于添加新的成就类型
### 4. 统计和排行榜
```java
// 获取用户统计
ResultDomain<Map<String, Object>> stats =
achievementService.getUserAchievementStatistics(userID);
// 获取排行榜
ResultDomain<Map<String, Object>> ranking =
achievementService.getAchievementRanking(10);
```
## 🚨 注意事项
### 1. 破坏性变更
#### ❌ 已删除的类(不再可用)
- `org.xyzh.api.usercenter.achievement.UserAchievementService`
- `org.xyzh.usercenter.service.UCUserAchievementService`
- `org.xyzh.usercenter.mapper.AchievementMapper`
- `org.xyzh.usercenter.controller.UserAchievementController`
#### ✅ 对应的新类
- `org.xyzh.api.achievement.AchievementService`
- `org.xyzh.achievement.service.impl.ACHAchievementServiceImpl`
- `org.xyzh.achievement.mapper.AchievementMapper`
- `org.xyzh.achievement.controller.AchievementController`
### 2. 接口变化
新的 `AchievementService` 接口方法更多、更完善:
- ✅ 所有旧方法都有对应的新方法
- ✅ 新增了事件处理、进度查询、统计等功能
- ✅ 方法签名大部分保持兼容
### 3. 前端调用
如果你的前端代码调用了成就相关API需要
1. 更新API路径`/usercenter/achievement/*``/achievement/*`
2. 检查返回数据格式(大部分保持兼容)
3. 利用新增的API进度、统计、排行榜等
## 📋 迁移检查清单
迁移时请检查以下项目:
- [ ] 更新 pom.xml 依赖
- [ ] 更新 import 语句
- [ ] 更新服务注入
- [ ] 更新方法调用
- [ ] 测试成就创建功能
- [ ] 测试成就授予功能
- [ ] 测试成就查询功能
- [ ] 测试事件触发功能(如有)
- [ ] 更新前端API路径如有
- [ ] 更新相关文档
- [ ] 执行集成测试
## 🆘 常见问题
### Q1: 编译报错找不到 UserAchievementService
**A:** 更新 import 语句为:
```java
import org.xyzh.api.achievement.AchievementService;
```
### Q2: 旧的成就数据会丢失吗?
**A:** 不会。数据库表结构保持不变,所有数据完整保留。
### Q3: 需要修改数据库吗?
**A:** 需要执行新表创建SQL`tb_user_achievement_progress`),见 `.bin/mysql/sql/createTableAchievement.sql`
### Q4: 如何使用新的事件驱动功能?
**A:** 参考 `README.md` 中的"使用方法"章节。
### Q5: admin模块已经自动配置好了吗
**A:** 是的admin模块的pom.xml已自动添加achievement依赖。
## 📚 相关文档
- [成就系统使用文档](../README.md)
- [数据库建表SQL](../../.bin/mysql/sql/createTableAchievement.sql)
## 👥 联系支持
如果在迁移过程中遇到问题,请联系:
- 开发者yslg
- 创建Issue或PR
---
**迁移完成日期**: 2025-10-24
**版本**: 1.0.0

View File

@@ -18,6 +18,7 @@ import org.xyzh.common.core.event.AchievementEvent;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.user.TbSysUserInfo;
import org.xyzh.common.dto.usercenter.TbAchievement;
import org.xyzh.common.dto.usercenter.TbUserAchievement;
import org.xyzh.common.dto.usercenter.TbUserAchievementProgress;
@@ -26,6 +27,7 @@ import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.AchievementVO;
import org.xyzh.system.utils.LoginUtil;
import org.xyzh.api.system.permission.ResourcePermissionService;
import org.xyzh.system.mapper.UserInfoMapper;
import org.xyzh.common.vo.UserDeptRoleVO;
import org.xyzh.common.core.enums.ResourceType;
@@ -62,6 +64,9 @@ public class ACHAchievementServiceImpl implements AchievementService {
@Autowired
private RedisService redisService;
@Autowired
private UserInfoMapper userInfoMapper;
// ==================== 成就定义管理 ====================
@@ -551,7 +556,7 @@ public class ACHAchievementServiceImpl implements AchievementService {
// 检查是否达成
if (checker.check(event, achievement, currentProgress)) {
TbUserAchievement userAchievement = grantAchievementInternal(event.getUserID(), achievement.getAchievementID());
TbUserAchievement userAchievement = grantAchievementInternal(event.getUserID(), achievement);
if (userAchievement != null) {
newAchievements.add(userAchievement);
logger.info("用户 {} 通过事件 {} 获得成就: {}", event.getUserID(), event.getEventType(), achievement.getName());
@@ -748,17 +753,21 @@ public class ACHAchievementServiceImpl implements AchievementService {
/**
* 内部授予成就方法(不检查是否已获得)
*/
private TbUserAchievement grantAchievementInternal(String userID, String achievementID) {
private TbUserAchievement grantAchievementInternal(String userID, TbAchievement achievement) {
try {
TbUserAchievement userAchievement = new TbUserAchievement();
userAchievement.setID(IDUtils.generateID());
userAchievement.setUserID(userID);
userAchievement.setAchievementID(achievementID);
userAchievement.setAchievementID(achievement.getAchievementID());
userAchievement.setObtainTime(new Date());
int result = userAchievementMapper.insertUserAchievement(userAchievement);
if (result > 0) {
updateProgressToCompleted(userID, achievementID);
updateProgressToCompleted(userID, achievement.getAchievementID());
// 检查是否需要更新用户等级learning_time开头的成就
updateUserLevelIfNeeded(userID, achievement);
return userAchievement;
}
return null;
@@ -824,5 +833,56 @@ public class ACHAchievementServiceImpl implements AchievementService {
}
return null;
}
/**
* 检查并更新用户等级仅针对learning_time开头的成就
* @param userID 用户ID
* @param achievement 成就对象
*/
private void updateUserLevelIfNeeded(String userID, TbAchievement achievement) {
try {
// 检查成就ID是否以learning_time开头
if (achievement == null || achievement.getAchievementID() == null ||
!achievement.getAchievementID().startsWith("learning_time")) {
return;
}
// 检查成就是否有等级信息
if (achievement.getLevel() == null) {
logger.warn("成就没有等级信息: {}", achievement.getAchievementID());
return;
}
// 获取用户当前信息
TbSysUserInfo userInfo = userInfoMapper.selectById(userID);
if (userInfo == null) {
logger.warn("用户信息不存在: {}", userID);
return;
}
// 检查是否需要更新等级(只有当成就等级高于当前用户等级时才更新)
Integer currentLevel = userInfo.getLevel() != null ? userInfo.getLevel() : 0;
Integer achievementLevel = achievement.getLevel();
if (achievementLevel > currentLevel) {
userInfo.setLevel(achievementLevel);
int updateResult = userInfoMapper.updateUserInfo(userInfo);
if (updateResult > 0) {
logger.info("用户 {} 通过成就 {} 等级从 {} 提升到 {}",
userID, achievement.getAchievementID(), currentLevel, achievementLevel);
} else {
logger.error("更新用户等级失败: userID={}, achievementID={}", userID, achievement.getAchievementID());
}
} else {
logger.debug("用户 {} 当前等级 {} 已达到或超过成就等级 {},无需更新",
userID, currentLevel, achievementLevel);
}
} catch (Exception e) {
logger.error("更新用户等级时发生异常: userID={}, achievementID={}, error={}",
userID, achievement.getAchievementID(), e.getMessage(), e);
}
}
}