209 lines
8.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}