package com.ylx.point.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ylx.common.exception.base.BaseException; import com.ylx.common.utils.DateUtils; import com.ylx.point.domain.PointActivity; import com.ylx.point.domain.PointActivityTask; import com.ylx.point.domain.PointSignReward; import com.ylx.point.domain.PointSignTask; import com.ylx.point.domain.dto.*; import com.ylx.point.domain.vo.*; import com.ylx.point.enums.PointActivityExpirePolicyEnum; import com.ylx.point.enums.PointActivityStatusEnum; import com.ylx.point.enums.PointActivityTypeEnum; import com.ylx.point.mapper.PointActivityMapper; import com.ylx.point.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.DateTimeException; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; /** * 积分活动主Service业务层处理 * * @author wzj * @date 2026-03-25 */ @Service public class PointActivityServiceImpl extends ServiceImpl implements IPointActivityService { @Autowired private PointActivityMapper pointActivityMapper; @Autowired private IPointActivityTaskService pointActivityTaskService; @Autowired private IPointSignTaskService pointSignTaskService; @Autowired private IPointSignRewardService pointSignRewardService; @Autowired private IPointUserActivityTaskCompletionService pointUserActivityTaskCompletionService; @Override public List list(PointActivityPageDTO dto) { return pointActivityMapper.list(dto); } @Override public PointActivityDetailsVo getDetailsInfo(Long id) { PointActivity pointActivity = this.pointActivityMapper.selectPointActivityById(id); if (ObjectUtil.isNull(pointActivity)) { throw new BaseException("参数有误,活动不存在"); } Integer activityType = pointActivity.getActivityType(); if (PointActivityTypeEnum.SIGN_TASK.getCode().equals(activityType)) { PointSignTaskVo vo = this.pointSignTaskService.selectPointSignTaskByActivityId(pointActivity.getId()); BeanUtil.copyProperties(pointActivity, vo); return PointActivityDetailsVo.of(activityType, vo); } else { PointActivityTaskVo vo = new PointActivityTaskVo(); BeanUtil.copyProperties(pointActivity, vo); List activityTaskList = this.pointActivityTaskService.selectPointActivityTaskByActivityId(pointActivity.getId()); vo.setActivityTaskList(activityTaskList); return PointActivityDetailsVo.of(activityType, vo); } } @Override @Transactional(rollbackFor = Exception.class) public void add(PointActivityDTO dto) { // 校验参数 validateActivityDTO(dto); // 保存活动信息 PointActivity entity = createActivityEntity(dto); saveActivity(entity); // 保存活动详情信息 saveActivityDetails(dto, entity.getId()); } @Override @Transactional(rollbackFor = Exception.class) public void edit(PointActivityDTO dto) { // 校验参数 Long id = dto.getId(); if (ObjectUtil.isNull(id)) { throw new BaseException("活动主键id不能为空"); } // 根据id获取活动详情 PointActivity entity = this.pointActivityMapper.selectPointActivityById(id); if (ObjectUtil.isNull(entity)) { throw new BaseException("参数有误,活动不存在"); } // 校验活动状态 if (PointActivityStatusEnum.IN_PROGRESS.getCode().equals(entity.getStatus())) { throw new BaseException("活动进行中,不可编辑"); } // 更新活动信息 BeanUtil.copyProperties(dto, entity); updateActivity(entity); // 更新活动详情信息 updateActivityDetails(dto, id); } @Override public PointActivityStatVo getStatInfo(Long id) { // 根据id获取活动详情 PointActivity entity = this.pointActivityMapper.selectPointActivityById(id); if (ObjectUtil.isNull(entity)) { throw new BaseException("参数有误,活动不存在"); } PointActivityStatVo vo = new PointActivityStatVo(); BeanUtil.copyProperties(entity, vo); // 数据总览 PointActivityOverviewVO dataOverview = this.pointUserActivityTaskCompletionService.getPointActivityOverviewByActivityId(id); vo.setDataOverview(dataOverview); // 数据详情 List taskDetailList = pointActivityMapper.getTaskDetailListById(id); vo.setTaskDetailList(taskDetailList); return vo; } @Override @Transactional(rollbackFor = Exception.class) public void editValidity(PointActivityValidityDTO dto) { // 根据dto中activityType获取全部的活动list LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(PointActivity::getActivityType, dto.getActivityType()); PointActivity pointActivity = new PointActivity(); pointActivity.setActivityType(dto.getActivityType()); List activityList = pointActivityMapper.selectPointActivityList(pointActivity); if (CollectionUtil.isEmpty(activityList)) { throw new BaseException("该类型的活动不存在,设置失败"); } // 判断活动list中只要有活动的状态为"进行中",修改就失败 boolean hasOngoingActivity = activityList.stream() .anyMatch(activity -> PointActivityStatusEnum.IN_PROGRESS.getCode().equals(activity.getStatus())); if (hasOngoingActivity) { throw new BaseException("存在进行中的活动,无法修改有效期"); } // 批量更新活动的有效期策略 batchUpdateExpirePolicy(activityList, dto); } private void validateActivityDTO(PointActivityDTO dto) { if (ObjectUtil.isNull(dto)) { throw new BaseException("活动信息不能为空"); } PointActivityDTO.ActivityTimeConfig timeConfig = dto.getTimeConfig(); if (ObjectUtil.isNull(timeConfig) || (StrUtil.equals(timeConfig.getIsPermanent(), "1") && (ObjectUtil.isNull(timeConfig.getStartTime()) || ObjectUtil.isNull(timeConfig.getEndTime())))) { throw new BaseException("活动时间配置不能为空"); } } private PointActivity createActivityEntity(PointActivityDTO dto) { // 创建基础实体 PointActivity entity = new PointActivity(); BeanUtil.copyProperties(dto, entity); // 处理时间配置 PointActivityDTO.ActivityTimeConfig timeConfig = dto.getTimeConfig(); entity.setStartTime(DateUtil.beginOfDay(timeConfig.getStartTime())); entity.setEndTime(processEndTime(timeConfig.getEndTime())); entity.setIsPermanent(timeConfig.getIsPermanent()); // 处理状态 if (PointActivityStatusEnum.PUBLISHED.getCode().equals(dto.getStatus())) { entity.setStatus(determineActivityStatus( entity.getStartTime(), entity.getEndTime(), timeConfig.getIsPermanent() )); } return entity; } private void saveActivity(PointActivity entity) { int affectedRows = pointActivityMapper.insertPointActivity(entity); if (affectedRows <= 0) { throw new BaseException("保存积分活动失败"); } } private void updateActivity(PointActivity entity) { int affectedRows = pointActivityMapper.updatePointActivity(entity); if (affectedRows <= 0) { throw new BaseException("更新积分活动失败"); } } private void saveActivityDetails(PointActivityDTO dto, Long activityId) { if (PointActivityTypeEnum.SIGN_TASK.getCode().equals(dto.getActivityType())) { saveSignTaskDetails(dto, activityId); } else { saveActivityTaskDetails(dto, activityId); } } private void updateActivityDetails(PointActivityDTO dto, Long activityId) { if (PointActivityTypeEnum.SIGN_TASK.getCode().equals(dto.getActivityType())) { updateSignTaskDetails(dto, activityId); } else { updateActivityTaskDetails(dto, activityId); } } private void saveSignTaskDetails(PointActivityDTO dto, Long activityId) { PointSignTaskDTO signTaskDTO = dto.getSignTaskDTO(); if (ObjectUtil.isNull(signTaskDTO)) { throw new BaseException("签到任务配置不能为空"); } PointSignTask pointSignTask = new PointSignTask(); pointSignTask.setActivityId(activityId); pointSignTask.setBasePoints(signTaskDTO.getBasePoints()); pointSignTask.setBreakRule(signTaskDTO.getBreakRule()); pointSignTask.setCreateTime(new Date()); pointSignTask.setUpdateTime(pointSignTask.getCreateTime()); pointSignTask.setIsDeleted(0); int affectedRows = pointSignTaskService.insertPointSignTask(pointSignTask); if (affectedRows <= 0) { throw new BaseException("保存积分签到任务规则失败"); } saveSignRewards(signTaskDTO.getSignRewardList(), pointSignTask.getId()); } private void saveSignRewards(List rewardList, Long taskId) { if (CollectionUtil.isEmpty(rewardList)) { return; } List rewards = rewardList.stream() .map(dto -> { PointSignReward reward = new PointSignReward(); reward.setRewardPoints(dto.getRewardPoints()); reward.setContinueDays(dto.getContinueDays()); reward.setCreateTime(new Date()); reward.setUpdateTime(reward.getCreateTime()); reward.setIsDeleted(0); reward.setSignTaskId(taskId); return reward; }) .collect(Collectors.toList()); pointSignRewardService.batchInsertPointSignReward(rewards); } private void saveActivityTaskDetails(PointActivityDTO dto, Long activityId) { List tasks = dto.getTasks(); if (CollectionUtil.isEmpty(tasks)) { return; } List activityTasks = tasks.stream() .map(task -> { PointActivityTask activityTask = new PointActivityTask(); BeanUtil.copyProperties(task, activityTask); activityTask.setActivityId(activityId); activityTask.setIsDeleted(0); activityTask.setCreateTime(new Date()); activityTask.setUpdateTime(activityTask.getCreateTime()); return activityTask; }) .collect(Collectors.toList()); pointActivityTaskService.batchInsertPointActivityTask(activityTasks); } /** * 处理结束时间,设置为当天的23:59:59 */ private Date processEndTime(Date endTime) { if (endTime == null) { return null; } try { LocalDateTime localDateTime = LocalDateTime.ofInstant( endTime.toInstant(), ZoneId.systemDefault() ); LocalDateTime endOfDay = localDateTime.with( java.time.LocalTime.of(23, 59, 59)); return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()); } catch (DateTimeException e) { throw new IllegalArgumentException("Invalid end time", e); } } /** * 确定活动状态 */ private Integer determineActivityStatus(Date startTime, Date endTime, String isPermanent) { if (StrUtil.equals(isPermanent, "1")) { return PointActivityStatusEnum.IN_PROGRESS.getCode(); } Date now = DateUtils.getNowDate(); if (startTime.after(now)) { return PointActivityStatusEnum.NOT_START.getCode(); } else if (endTime != null && endTime.before(now)) { return PointActivityStatusEnum.FINISHED.getCode(); } else { return PointActivityStatusEnum.IN_PROGRESS.getCode(); } } /** * 更新签到任务详情 */ private void updateSignTaskDetails(PointActivityDTO dto, Long activityId) { PointSignTaskDTO signTaskDTO = dto.getSignTaskDTO(); if (ObjectUtil.isNull(signTaskDTO)) { throw new BaseException("签到任务配置不能为空"); } // 获取现有的签到任务 PointSignTaskVo existingTask = pointSignTaskService.selectPointSignTaskByActivityId(activityId); // 更新签到任务基本信息 PointSignTask pointSignTask = new PointSignTask(); pointSignTask.setId(existingTask.getSignTaskId()); pointSignTask.setBasePoints(signTaskDTO.getBasePoints()); pointSignTask.setBreakRule(signTaskDTO.getBreakRule()); // 更新签到任务 int affectedRows = pointSignTaskService.updatePointSignTask(pointSignTask); if (affectedRows <= 0) { throw new BaseException("更新积分签到任务规则失败"); } // 更新签到奖励配置 updateSignRewards(signTaskDTO.getSignRewardList(), pointSignTask.getId()); } /** * 更新签到奖励配置 */ private void updateSignRewards(List rewardList, Long taskId) { // 先删除原有的奖励配置 PointSignReward query = new PointSignReward(); query.setSignTaskId(taskId); List existingRewards = pointSignRewardService.selectPointSignRewardList(query); if (CollectionUtil.isNotEmpty(existingRewards)) { String[] ids = existingRewards.stream() .map(reward -> String.valueOf(reward.getId())) .toArray(String[]::new); pointSignRewardService.deletePointSignRewardByIds(ids); } // 重新插入新的奖励配置 if (CollectionUtil.isEmpty(rewardList)) { return; } List rewards = rewardList.stream() .map(dto -> { PointSignReward reward = new PointSignReward(); reward.setRewardPoints(dto.getRewardPoints()); reward.setContinueDays(dto.getContinueDays()); reward.setCreateTime(new Date()); reward.setUpdateTime(reward.getCreateTime()); reward.setIsDeleted(0); reward.setSignTaskId(taskId); return reward; }) .collect(Collectors.toList()); pointSignRewardService.batchInsertPointSignReward(rewards); } /** * 更新活动任务详情 */ private void updateActivityTaskDetails(PointActivityDTO dto, Long activityId) { // 先删除原有的活动任务 pointActivityTaskService.deletePointActivityTaskByActivityId(activityId); // 重新插入新的活动任务 List tasks = dto.getTasks(); if (CollectionUtil.isEmpty(tasks)) { return; } List activityTasks = tasks.stream() .map(task -> { PointActivityTask activityTask = new PointActivityTask(); BeanUtil.copyProperties(task, activityTask); activityTask.setActivityId(activityId); activityTask.setIsDeleted(0); activityTask.setCreateTime(new Date()); activityTask.setUpdateTime(activityTask.getCreateTime()); return activityTask; }) .collect(Collectors.toList()); pointActivityTaskService.batchInsertPointActivityTask(activityTasks); } private void batchUpdateExpirePolicy(List activityList, PointActivityValidityDTO dto) { Integer expirePolicy = dto.getExpirePolicy(); // 使用Stream处理活动列表 List updateList = activityList.stream() .peek(activity -> { activity.setExpirePolicy(expirePolicy); // 根据策略设置不同的过期时间字段 if (PointActivityExpirePolicyEnum.TRANSACTION_EXPIRE.getCode().equals(expirePolicy)) { activity.setExpireDays(dto.getExpireDays()); activity.setExpireYear(null); } else if (PointActivityExpirePolicyEnum.YEARLY_EXPIRE.getCode().equals(expirePolicy)) { activity.setExpireYear(dto.getExpireYear()); activity.setExpireDays(null); } else { activity.setExpireDays(null); activity.setExpireYear(null); } }) .collect(Collectors.toList()); // 批量更新数据库 if (CollectionUtil.isNotEmpty(updateList)) { super.updateBatchById(updateList); } } }