Files
happy-life-star/server/src/main/java/com/emotion/service/impl/AchievementServiceImpl.java
T

440 lines
17 KiB
Java

package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.PageResult;
import com.emotion.dto.request.achievement.AchievementCreateRequest;
import com.emotion.dto.request.achievement.AchievementPageRequest;
import com.emotion.dto.request.achievement.AchievementUpdateRequest;
import com.emotion.dto.response.achievement.AchievementResponse;
import com.emotion.entity.Achievement;
import com.emotion.mapper.AchievementMapper;
import com.emotion.service.AchievementService;
import com.emotion.util.SnowflakeIdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 成就服务实现类
*
* @author huazhongmin
* @date 2025-09-08
*/
@Service
public class AchievementServiceImpl extends ServiceImpl<AchievementMapper, Achievement> implements AchievementService {
@Autowired
private SnowflakeIdGenerator snowflakeIdGenerator;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public IPage<Achievement> getPage(AchievementPageRequest request) {
Page<Achievement> page = new Page<>(request.getCurrent(), request.getSize());
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
// 关键词搜索
if (StringUtils.hasText(request.getKeyword())) {
wrapper.and(w -> w.like(Achievement::getTitle, request.getKeyword())
.or().like(Achievement::getDescription, request.getKeyword()));
}
// 分类筛选
if (StringUtils.hasText(request.getCategory())) {
wrapper.eq(Achievement::getCategory, request.getCategory());
}
// 稀有度筛选
if (StringUtils.hasText(request.getRarity())) {
wrapper.eq(Achievement::getRarity, request.getRarity());
}
// 解锁状态筛选
if (request.getUnlocked() != null) {
if (request.getUnlocked()) {
wrapper.isNotNull(Achievement::getUnlockedTime);
} else {
wrapper.isNull(Achievement::getUnlockedTime);
}
}
// 隐藏状态筛选
if (request.getHidden() != null) {
wrapper.eq(Achievement::getIsHidden, request.getHidden() ? 1 : 0);
}
wrapper.eq(Achievement::getIsDeleted, 0);
// 排序
if (StringUtils.hasText(request.getOrderBy())) {
if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
wrapper.orderByAsc(Achievement::getCreateTime);
} else {
wrapper.orderByDesc(Achievement::getCreateTime);
}
} else {
wrapper.orderByDesc(Achievement::getCreateTime);
}
return this.page(page, wrapper);
}
@Override
public List<Achievement> getByCategory(String category) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getCategory, category)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getByRarity(String rarity) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getRarity, rarity)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getByConditionType(String conditionType) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getConditionType, conditionType)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getUnlockedAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.isNotNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getUnlockedTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getLockedAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getHiddenAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getIsHidden, 1)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getVisibleAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getIsHidden, 0)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public List<Achievement> getByProgressRange(Double minProgress, Double maxProgress) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.between(Achievement::getProgress, minProgress, maxProgress)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getProgress);
return this.list(wrapper);
}
@Override
public List<Achievement> getByUnlockTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.between(Achievement::getUnlockedTime, startTime, endTime)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getUnlockedTime);
return this.list(wrapper);
}
@Override
public Long countUnlockedAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.isNotNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Long countLockedAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.isNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Long countByCategory(String category) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getCategory, category)
.eq(Achievement::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Long countByRarity(String rarity) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getRarity, rarity)
.eq(Achievement::getIsDeleted, 0);
return this.count(wrapper);
}
@Override
public Double getAvgProgress() {
List<Achievement> achievements = this.list(new LambdaQueryWrapper<Achievement>()
.eq(Achievement::getIsDeleted, 0)
.isNotNull(Achievement::getProgress));
return achievements.stream()
.mapToDouble(a -> a.getProgress() != null ? a.getProgress().doubleValue() : 0.0)
.average()
.orElse(0.0);
}
@Override
public Double getAvgProgressByCategory(String category) {
List<Achievement> achievements = this.list(new LambdaQueryWrapper<Achievement>()
.eq(Achievement::getCategory, category)
.eq(Achievement::getIsDeleted, 0)
.isNotNull(Achievement::getProgress));
return achievements.stream()
.mapToDouble(a -> a.getProgress() != null ? a.getProgress().doubleValue() : 0.0)
.average()
.orElse(0.0);
}
@Override
public List<Achievement> getRecentlyUnlocked(Integer limit) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.isNotNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getUnlockedTime)
.last("LIMIT " + limit);
return this.list(wrapper);
}
@Override
public List<Achievement> getNearCompletion() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(Achievement::getProgress, 80)
.isNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getProgress);
return this.list(wrapper);
}
@Override
public List<Achievement> getRareAchievements() {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.in(Achievement::getRarity, "legendary", "epic")
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime);
return this.list(wrapper);
}
@Override
public boolean unlockAchievement(String id, LocalDateTime unlockedTime) {
LambdaUpdateWrapper<Achievement> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Achievement::getId, id)
.set(Achievement::getUnlockedTime, unlockedTime)
.set(Achievement::getProgress, 100)
.set(Achievement::getUpdateTime, LocalDateTime.now());
return this.update(wrapper);
}
@Override
public boolean updateProgress(String id, Double progress) {
LambdaUpdateWrapper<Achievement> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Achievement::getId, id)
.set(Achievement::getProgress, progress)
.set(Achievement::getUpdateTime, LocalDateTime.now());
return this.update(wrapper);
}
@Override
public boolean updateHiddenStatus(String id, Integer isHidden) {
LambdaUpdateWrapper<Achievement> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Achievement::getId, id)
.set(Achievement::getIsHidden, isHidden)
.set(Achievement::getUpdateTime, LocalDateTime.now());
return this.update(wrapper);
}
@Override
public List<Achievement> getRecommendedAchievements(String category, String rarity, Integer limit) {
LambdaQueryWrapper<Achievement> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Achievement::getCategory, category)
.eq(Achievement::getRarity, rarity)
.isNull(Achievement::getUnlockedTime)
.eq(Achievement::getIsHidden, 0)
.eq(Achievement::getIsDeleted, 0)
.orderByDesc(Achievement::getCreateTime)
.last("LIMIT " + limit);
return this.list(wrapper);
}
// 新增的Response相关方法实现
@Override
public PageResult<AchievementResponse> getPageWithResponse(AchievementPageRequest request) {
IPage<Achievement> page = getPage(request);
List<AchievementResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<AchievementResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return pageResult;
}
@Override
public AchievementResponse getAchievementResponseById(String id) {
Achievement achievement = this.getById(id);
if (achievement == null) {
return null;
}
return convertToResponse(achievement);
}
@Override
public AchievementResponse createAchievementWithResponse(AchievementCreateRequest request) {
Achievement achievement = new Achievement();
org.springframework.beans.BeanUtils.copyProperties(request, achievement);
achievement.setId(snowflakeIdGenerator.nextIdAsString());
boolean saved = this.save(achievement);
if (!saved) {
return null;
}
return convertToResponse(achievement);
}
@Override
public AchievementResponse updateAchievementWithResponse(AchievementUpdateRequest request) {
Achievement achievement = this.getById(request.getId());
if (achievement == null) {
return null;
}
// 更新非空字段
if (request.getTitle() != null) {
achievement.setTitle(request.getTitle());
}
if (request.getDescription() != null) {
achievement.setDescription(request.getDescription());
}
if (request.getCategory() != null) {
achievement.setCategory(request.getCategory());
}
if (request.getIcon() != null) {
achievement.setIcon(request.getIcon());
}
if (request.getRarity() != null) {
achievement.setRarity(request.getRarity());
}
if (request.getConditionType() != null) {
achievement.setConditionType(request.getConditionType());
}
if (request.getConditionValue() != null) {
achievement.setConditionValue(request.getConditionValue());
}
if (request.getRewards() != null) {
achievement.setRewards(request.getRewards());
}
if (request.getIsHidden() != null) {
achievement.setIsHidden(request.getIsHidden());
}
achievement.setUpdateTime(LocalDateTime.now());
boolean updated = this.updateById(achievement);
if (!updated) {
return null;
}
return convertToResponse(achievement);
}
@Override
public List<AchievementResponse> getByCategoryWithResponse(String category) {
List<Achievement> achievements = getByCategory(category);
return achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
}
@Override
public List<AchievementResponse> getByRarityWithResponse(String rarity) {
List<Achievement> achievements = getByRarity(rarity);
return achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
}
@Override
public List<AchievementResponse> getUnlockedAchievementsWithResponse() {
List<Achievement> achievements = getUnlockedAchievements();
return achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
}
@Override
public List<AchievementResponse> getLockedAchievementsWithResponse() {
List<Achievement> achievements = getLockedAchievements();
return achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
}
@Override
public List<AchievementResponse> getRecentlyUnlockedWithResponse(Integer limit) {
List<Achievement> achievements = getRecentlyUnlocked(limit);
return achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
}
/**
* 转换为响应对象
*/
private AchievementResponse convertToResponse(Achievement achievement) {
AchievementResponse response = new AchievementResponse();
org.springframework.beans.BeanUtils.copyProperties(achievement, response);
response.setId(achievement.getId());
if (achievement.getCreateTime() != null) {
response.setCreateTime(achievement.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (achievement.getUpdateTime() != null) {
response.setUpdateTime(achievement.getUpdateTime().format(DATE_TIME_FORMATTER));
}
if (achievement.getUnlockedTime() != null) {
response.setUnlockedTime(achievement.getUnlockedTime().format(DATE_TIME_FORMATTER));
}
return response;
}
}