209 lines
8.5 KiB
Java
209 lines
8.5 KiB
Java
package com.designhub.service;
|
||
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.designhub.entity.Achievement;
|
||
import com.designhub.entity.UserAchievement;
|
||
import com.designhub.mapper.AchievementMapper;
|
||
import com.designhub.mapper.UserAchievementMapper;
|
||
import lombok.RequiredArgsConstructor;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import java.time.LocalDateTime;
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 成就系统Service
|
||
*/
|
||
@Slf4j
|
||
@Service
|
||
@RequiredArgsConstructor
|
||
public class AchievementService {
|
||
|
||
private final AchievementMapper achievementMapper;
|
||
private final UserAchievementMapper userAchievementMapper;
|
||
private final NotificationService notificationService;
|
||
|
||
/**
|
||
* 获取所有成就列表
|
||
*/
|
||
public List<Achievement> getAllAchievements() {
|
||
return achievementMapper.selectList(
|
||
new LambdaQueryWrapper<Achievement>()
|
||
.eq(Achievement::getStatus, 1)
|
||
.orderByAsc(Achievement::getSortOrder)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 获取用户已达成的成就列表
|
||
*/
|
||
public List<UserAchievement> getUserAchievements(Long userId) {
|
||
return userAchievementMapper.selectList(
|
||
new LambdaQueryWrapper<UserAchievement>()
|
||
.eq(UserAchievement::getUserId, userId)
|
||
.orderByDesc(UserAchievement::getAchievedTime)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 检查并解锁成就
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public List<Achievement> checkAndUnlockAchievements(Long userId, String achievementType, Integer currentValue) {
|
||
List<Achievement> unlockedAchievements = new ArrayList<>();
|
||
|
||
// 获取该类型的所有成就
|
||
List<Achievement> achievements = achievementMapper.selectList(
|
||
new LambdaQueryWrapper<Achievement>()
|
||
.eq(Achievement::getAchievementType, achievementType)
|
||
.eq(Achievement::getStatus, 1)
|
||
);
|
||
|
||
for (Achievement achievement : achievements) {
|
||
// 检查用户是否已获得该成就
|
||
long count = userAchievementMapper.selectCount(
|
||
new LambdaQueryWrapper<UserAchievement>()
|
||
.eq(UserAchievement::getUserId, userId)
|
||
.eq(UserAchievement::getAchievementId, achievement.getId())
|
||
);
|
||
|
||
if (count == 0) {
|
||
// 简单的条件判断(实际应该解析JSON条件)
|
||
// 这里假设condition格式为:{"type":"task_count","value":100}
|
||
if (checkAchievementCondition(achievement, currentValue)) {
|
||
// 解锁成就
|
||
UserAchievement userAchievement = new UserAchievement();
|
||
userAchievement.setUserId(userId);
|
||
userAchievement.setAchievementId(achievement.getId());
|
||
userAchievement.setAchievedTime(LocalDateTime.now());
|
||
userAchievement.setProgressValue(currentValue);
|
||
userAchievement.setRewardClaimed(0);
|
||
userAchievementMapper.insert(userAchievement);
|
||
|
||
unlockedAchievements.add(achievement);
|
||
|
||
// 发送通知
|
||
notificationService.sendSystemNotification(
|
||
userId,
|
||
"🎉 恭喜解锁新成就",
|
||
"您已解锁成就:" + achievement.getAchievementName() +
|
||
",奖励积分:" + achievement.getRewardScore(),
|
||
"high"
|
||
);
|
||
|
||
log.info("用户解锁成就: userId={}, achievement={}", userId, achievement.getAchievementName());
|
||
}
|
||
}
|
||
}
|
||
|
||
return unlockedAchievements;
|
||
}
|
||
|
||
/**
|
||
* 领取成就奖励
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public boolean claimAchievementReward(Long userId, Long achievementId) {
|
||
// 查询用户成就记录
|
||
UserAchievement userAchievement = userAchievementMapper.selectOne(
|
||
new LambdaQueryWrapper<UserAchievement>()
|
||
.eq(UserAchievement::getUserId, userId)
|
||
.eq(UserAchievement::getAchievementId, achievementId)
|
||
);
|
||
|
||
if (userAchievement != null && userAchievement.getRewardClaimed() == 0) {
|
||
// 标记为已领取
|
||
userAchievement.setRewardClaimed(1);
|
||
userAchievement.setClaimTime(LocalDateTime.now());
|
||
userAchievementMapper.updateById(userAchievement);
|
||
|
||
// TODO: 实际发放积分奖励
|
||
Achievement achievement = achievementMapper.selectById(achievementId);
|
||
if (achievement != null && achievement.getRewardScore() != null && achievement.getRewardScore() > 0) {
|
||
// 这里应该调用积分服务发放奖励
|
||
log.info("发放成就奖励: userId={}, score={}", userId, achievement.getRewardScore());
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 初始化默认成就
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public void initDefaultAchievements() {
|
||
// 任务类成就
|
||
createAchievementIfNotExists("TASK_10", "初出茅庐", "完成10个任务", "task", 10, 50, "bronze");
|
||
createAchievementIfNotExists("TASK_50", "驾轻就熟", "完成50个任务", "task", 50, 200, "silver");
|
||
createAchievementIfNotExists("TASK_100", "百里挑一", "完成100个任务", "task", 100, 500, "gold");
|
||
createAchievementIfNotExists("TASK_500", "业界大拿", "完成500个任务", "task", 500, 2000, "diamond");
|
||
|
||
// 积分类成就
|
||
createAchievementIfNotExists("SCORE_1000", "积分新秀", "累计获得1000积分", "score", 1000, 100, "bronze");
|
||
createAchievementIfNotExists("SCORE_5000", "积分高手", "累计获得5000积分", "score", 5000, 500, "silver");
|
||
createAchievementIfNotExists("SCORE_10000", "积分大师", "累计获得10000积分", "score", 10000, 1000, "gold");
|
||
|
||
// 质量类成就
|
||
createAchievementIfNotExists("QUALITY_10", "好评如潮", "获得10个五星好评", "quality", 10, 100, "silver");
|
||
createAchievementIfNotExists("QUALITY_50", "完美主义", "获得50个五星好评", "quality", 50, 500, "gold");
|
||
|
||
// 速度类成就
|
||
createAchievementIfNotExists("SPEED_10", "闪电侠", "提前完成任务10次", "speed", 10, 100, "silver");
|
||
|
||
log.info("默认成就初始化完成");
|
||
}
|
||
|
||
/**
|
||
* 如果不存在则创建成就
|
||
*/
|
||
private void createAchievementIfNotExists(String code, String name, String description,
|
||
String type, Integer conditionValue,
|
||
Integer rewardScore, String level) {
|
||
long count = achievementMapper.selectCount(
|
||
new LambdaQueryWrapper<Achievement>()
|
||
.eq(Achievement::getAchievementCode, code)
|
||
);
|
||
|
||
if (count == 0) {
|
||
Achievement achievement = new Achievement();
|
||
achievement.setAchievementCode(code);
|
||
achievement.setAchievementName(name);
|
||
achievement.setDescription(description);
|
||
achievement.setAchievementType(type);
|
||
achievement.setCondition("{\"type\":\"" + type + "_count\",\"value\":" + conditionValue + "}");
|
||
achievement.setRewardScore(rewardScore);
|
||
achievement.setLevel(level);
|
||
achievement.setSortOrder(0);
|
||
achievement.setStatus(1);
|
||
achievementMapper.insert(achievement);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查成就条件是否满足
|
||
*/
|
||
private boolean checkAchievementCondition(Achievement achievement, Integer currentValue) {
|
||
// 简化版本:从condition中提取value进行比较
|
||
// 实际应该解析JSON
|
||
String condition = achievement.getCondition();
|
||
if (condition != null && condition.contains("\"value\":")) {
|
||
try {
|
||
String valueStr = condition.substring(condition.indexOf("\"value\":") + 8);
|
||
valueStr = valueStr.substring(0, valueStr.indexOf("}"));
|
||
int requiredValue = Integer.parseInt(valueStr.trim());
|
||
return currentValue >= requiredValue;
|
||
} catch (Exception e) {
|
||
log.error("解析成就条件失败: {}", condition, e);
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|