package com.ruoyi.system.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.gson.JsonArray; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.BaseModel; import com.ruoyi.common.core.domain.BasePage; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.system.dto.EquipmentDto; import com.ruoyi.system.dto.TMissionUserDto; import com.ruoyi.system.mapper.TAppUserEquipmentMapper; import com.ruoyi.system.mapper.TMissionAssignRuleMapper; import com.ruoyi.system.mapper.TMissionMapper; import com.ruoyi.system.mapper.TMissionUserMapper; import com.ruoyi.system.model.TAppUserEquipment; import com.ruoyi.system.model.TMission; import com.ruoyi.system.model.TMissionAssignRule; import com.ruoyi.system.model.TMissionUser; import com.ruoyi.system.query.TMissionQuery; import com.ruoyi.system.service.TMissionService; import com.ruoyi.system.vo.MissionTotalVo; import com.ruoyi.system.vo.TMissionReassignVO; import com.ruoyi.system.vo.TMissionVO; import com.ruoyi.system.vo.TotalHistoryVo; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.text.SimpleDateFormat; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; import java.util.stream.Collectors; /** *

* 任务管理 服务实现类 *

* * @author xiaochen * @since 2025-09-28 */ @Service public class TMissionServiceImpl extends ServiceImpl implements TMissionService { @Resource private TMissionUserMapper missionUserMapper; @Resource private RedisCache redisCache; @Resource private TAppUserEquipmentMapper appUserEquipmentMapper; @Resource private TMissionAssignRuleMapper missionAssignRuleMapper; @Override public PageInfo pageListAssigned(TMissionQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageListAssigned(query, pageInfo); if (CollectionUtils.isEmpty(list)) { return pageInfo; } // 计算时间差 for (TMissionVO tMissionVO : list) { if (Objects.nonNull(tMissionVO.getAssignTime())) { if (Objects.nonNull(tMissionVO.getReceiveTime())) { // 计算LocalDateTime两个时间相差秒数 Duration duration = Duration.between(tMissionVO.getAssignTime(), tMissionVO.getReceiveTime()); tMissionVO.setResponseTimePoor(duration.getSeconds()); } if (Objects.nonNull(tMissionVO.getFinishTime())) { // 计算LocalDateTime两个时间相差小时 Duration duration = Duration.between(tMissionVO.getReceiveTime(), tMissionVO.getFinishTime()); double minutes = (double) duration.toMinutes(); minutes = minutes / 60; tMissionVO.setFinishTimePoor(minutes); } } } pageInfo.setRecords(list); return pageInfo; } @Override public PageInfo pageListReassignAudit(TMissionQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageListReassignAudit(query, pageInfo); pageInfo.setRecords(list); return pageInfo; } @Override public PageInfo pageListMissionPool(TMissionQuery query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageListMissionPool(query, pageInfo); if (CollectionUtils.isEmpty(list)) { return pageInfo; } // 计算时间差 for (TMissionVO tMissionVO : list) { if (Objects.nonNull(tMissionVO.getAssignTime())) { if (Objects.nonNull(tMissionVO.getReceiveTime())) { // 计算LocalDateTime两个时间相差秒数 Duration duration = Duration.between(tMissionVO.getAssignTime(), tMissionVO.getReceiveTime()); tMissionVO.setResponseTimePoor(duration.getSeconds()); } if (Objects.nonNull(tMissionVO.getFinishTime())) { // 计算LocalDateTime两个时间相差小时 Duration duration = Duration.between(tMissionVO.getReceiveTime(), tMissionVO.getFinishTime()); double minutes = (double) duration.toMinutes(); minutes = minutes / 60; tMissionVO.setFinishTimePoor(minutes); } } } pageInfo.setRecords(list); return pageInfo; } @Override public TotalHistoryVo totalHistory(String userId) { TotalHistoryVo totalHistoryVo = new TotalHistoryVo(); List tMissionUsers = missionUserMapper.selectList(new LambdaQueryWrapper().eq(TMissionUser::getAppUserId, userId)); if (tMissionUsers.isEmpty()) { return totalHistoryVo; } long count = tMissionUsers.stream().filter(e -> e.getStatus() == 1).count(); BigDecimal successRate = new BigDecimal(count).divide(new BigDecimal(tMissionUsers.size()), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)); totalHistoryVo.setSuccessRate(successRate); long count1 = tMissionUsers.stream().filter(e -> e.getStatus() == 2).count(); BigDecimal failRate = new BigDecimal(count1).divide(new BigDecimal(tMissionUsers.size()), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)); totalHistoryVo.setFailRate(failRate); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM"); // 查询当前时间的年月日 String now = LocalDate.now().toString(); List todayMissionUsers = tMissionUsers.stream().filter(e -> now.equals(simpleDateFormat.format(e.getSuccessTime()))).collect(Collectors.toList()); totalHistoryVo.setTodaySuccessNum(todayMissionUsers.size()); // 查询当前时间的年月 String firstDayOfMonth = LocalDate.now().withDayOfMonth(1).toString().substring(0, 7); List monthMissionUsers = tMissionUsers.stream().filter(e -> firstDayOfMonth.equals(simpleDateFormat1.format(e.getSuccessTime()))).collect(Collectors.toList()); totalHistoryVo.setMonthSuccessNum(monthMissionUsers.size()); return totalHistoryVo; } @Override public void successMission(TMissionUserDto dto, String userId) { TMissionUser user = missionUserMapper.selectById(dto.getId()); user.setSuccessTime(new Date()); BeanUtils.copyProperties(dto, user); missionUserMapper.updateById(user); // 判断这个任务还有正在执行的不 Long l = missionUserMapper.selectCount(new LambdaQueryWrapper().eq(TMissionUser::getMissionId, user.getMissionId()).eq(TMissionUser::getStatus, 0)); if (l == 0){ // 全部执行完 任务完成 this.update(new LambdaUpdateWrapper().eq(TMission::getId, user.getMissionId()).set(TMission::getStatus, 4)); } // 更新装备 TAppUserEquipment tAppUserEquipment = appUserEquipmentMapper.selectOne(new LambdaQueryWrapper().eq(TAppUserEquipment::getAppUserId, userId).eq(TAppUserEquipment::getAppUserId, userId)); if (Objects.nonNull(tAppUserEquipment)) { String lossText = dto.getLossText(); String victoryText = dto.getVictoryText(); List victoryTextDtos = JSONArray.parseArray(victoryText, EquipmentDto.class); List lossTextDtos = JSONArray.parseArray(lossText, EquipmentDto.class); EquipmentDto equipmentDto = victoryTextDtos.stream().filter(e -> e.getId().equals("0")).findFirst().orElse(null); EquipmentDto lossEquipmentDto = lossTextDtos.stream().filter(e -> e.getId().equals("0")).findFirst().orElse(null); int count = equipmentDto.getCount() - lossEquipmentDto.getCount(); tAppUserEquipment.setPersonCount(count); for (EquipmentDto victoryTextDto : victoryTextDtos) { for (EquipmentDto lossTextDto : lossTextDtos) { if (victoryTextDto.getId().equals(lossTextDto.getId())) { victoryTextDto.setCount(victoryTextDto.getCount() - lossTextDto.getCount()); } } } String equipmentCount = tAppUserEquipment.getEquipmentCount(); // 目前的装备 List EquipmentDtoList = JSONArray.parseArray(equipmentCount, EquipmentDto.class); List ids = EquipmentDtoList.stream().map(EquipmentDto::getId).collect(Collectors.toList()); List haveEquipment = victoryTextDtos.stream().filter(e -> ids.contains(e.getId())).collect(Collectors.toList()); List notHaveEquipment = victoryTextDtos.stream().filter(e -> !ids.contains(e.getId())).collect(Collectors.toList()); for (EquipmentDto equipmentDto1 : EquipmentDtoList) { EquipmentDto equipmentDto2 = haveEquipment.stream().filter(e -> e.getId().equals(equipmentDto1.getId())).findFirst().get(); equipmentDto1.setCount(equipmentDto1.getCount() + equipmentDto2.getCount()); } EquipmentDtoList.addAll(notHaveEquipment); tAppUserEquipment.setEquipmentCount(JSON.toJSONString(EquipmentDtoList)); appUserEquipmentMapper.updateById(tAppUserEquipment); } else { tAppUserEquipment = new TAppUserEquipment(); tAppUserEquipment.setAppUserId(userId); String lossText = dto.getLossText(); String victoryText = dto.getVictoryText(); List victoryTextDtos = JSONArray.parseArray(victoryText, EquipmentDto.class); List lossTextDtos = JSONArray.parseArray(lossText, EquipmentDto.class); EquipmentDto equipmentDto = victoryTextDtos.stream().filter(e -> e.getId().equals("0")).findFirst().orElse(null); EquipmentDto lossEquipmentDto = lossTextDtos.stream().filter(e -> e.getId().equals("0")).findFirst().orElse(null); int count = equipmentDto.getCount() - lossEquipmentDto.getCount(); tAppUserEquipment.setPersonCount(count); for (EquipmentDto victoryTextDto : victoryTextDtos) { for (EquipmentDto lossTextDto : lossTextDtos) { if (victoryTextDto.getId().equals(lossTextDto.getId())) { victoryTextDto.setCount(victoryTextDto.getCount() - lossTextDto.getCount()); } } } tAppUserEquipment.setEquipmentCount(JSON.toJSONString(victoryTextDtos)); appUserEquipmentMapper.insert(tAppUserEquipment); } } @Override public PageInfo pageList(TMissionQuery query) { return null; } @Override public MissionTotalVo missionTotal(String userId) { MissionTotalVo missionTotalVo = new MissionTotalVo(); List tMissionUsers = missionUserMapper.selectList(new LambdaQueryWrapper().eq(TMissionUser::getAppUserId, userId).eq(TMissionUser::getStatus, 0)); if (tMissionUsers.isEmpty()) { return missionTotalVo; } List missionIds = tMissionUsers.stream().map(TMissionUser::getMissionId).collect(Collectors.toList()); List tMissions = this.baseMapper.selectBatchIds(missionIds); long count = tMissions.stream().filter(e -> e.getStatus() == 2).count(); missionTotalVo.setNowNum((int) count); missionTotalVo.setWaitNum(tMissions.size() - missionTotalVo.getNowNum()); List collect = tMissionUsers.stream().filter(e -> e.getStatus() == 1).collect(Collectors.toList()); missionTotalVo.setRate(new BigDecimal(collect.size()).divide(new BigDecimal(tMissionUsers.size()), 2, RoundingMode.HALF_UP)); return missionTotalVo; } @Override public String grabMission(String missionId, String userId) { try { boolean b = redisCache.trylockLoop(missionId, UUID.randomUUID().toString(), 30); if (b) { TMission tMission = this.baseMapper.selectById(missionId); tMission.setStatus(2); this.baseMapper.updateById(tMission); TMissionUser tMissionUser = new TMissionUser(); tMissionUser.setAppUserId(userId); tMissionUser.setMissionId(missionId); tMissionUser.setStatus(0); tMissionUser.setUserType(1); missionUserMapper.insert(tMissionUser); return tMissionUser.getMissionId(); } } finally { redisCache.unlock(missionId, UUID.randomUUID().toString()); } return null; } @Override public PageInfo pageNowList(BasePage query, String userId) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageNowList(pageInfo, userId); if(!list.isEmpty()){ List tMissionAssignRules = missionAssignRuleMapper.selectBatchIds(list.stream().map(TMission::getMissionTypeId).collect(Collectors.toList())); list.forEach(e -> { TMissionAssignRule tMissionAssignRule = tMissionAssignRules.stream().filter(rule -> rule.getId().equals(e.getMissionTypeId())).findFirst().orElse(null); if(tMissionAssignRule != null){ e.setMissionType(tMissionAssignRule.getTypeName()); } }); } pageInfo.setRecords(list); return pageInfo; } @Override public PageInfo pageGrabList(BasePage query) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); PageInfo tMissionPageInfo = this.baseMapper.selectPage(pageInfo, new LambdaQueryWrapper().eq(TMission::getStatus, 1).eq(TMission::getIsMissionPool, 1).orderByDesc(BaseModel::getCreateTime)); List records = tMissionPageInfo.getRecords(); if(!records.isEmpty()){ List tMissionAssignRules = missionAssignRuleMapper.selectBatchIds(records.stream().map(TMission::getMissionTypeId).collect(Collectors.toList())); records.forEach(e -> { TMissionAssignRule tMissionAssignRule = tMissionAssignRules.stream().filter(rule -> rule.getId().equals(e.getMissionTypeId())).findFirst().orElse(null); if(tMissionAssignRule != null){ e.setMissionType(tMissionAssignRule.getTypeName()); } }); } return tMissionPageInfo; } @Override public PageInfo pageHistoryList(BasePage query, String userId) { PageInfo pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List list = this.baseMapper.pageHistoryList(pageInfo, userId); if(!list.isEmpty()){ List tMissionAssignRules = missionAssignRuleMapper.selectBatchIds(list.stream().map(TMission::getMissionTypeId).collect(Collectors.toList())); list.forEach(e -> { TMissionAssignRule tMissionAssignRule = tMissionAssignRules.stream().filter(rule -> rule.getId().equals(e.getMissionTypeId())).findFirst().orElse(null); if(tMissionAssignRule != null){ e.setMissionType(tMissionAssignRule.getTypeName()); } }); } pageInfo.setRecords(list); return pageInfo; } }