package com.webmanage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.webmanage.common.BusinessException; import com.webmanage.common.PageResult; import com.webmanage.dto.AddPointsFlowDTO; import com.webmanage.dto.PointsFlowQueryDTO; import com.webmanage.entity.PointsFlow; import com.webmanage.entity.PointsRule; import com.webmanage.entity.UserPoints; import com.webmanage.mapper.PointsFlowMapper; import com.webmanage.mapper.UserPointsMapper; import com.webmanage.service.PointsFlowService; import com.webmanage.service.PointsRuleService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; /** * 积分流水Service实现类 */ @Slf4j @Service public class PointsFlowServiceImpl extends ServiceImpl implements PointsFlowService { @Resource private UserPointsMapper userPointsMapper; @Resource private PointsRuleService pointsRuleService; @Override public PageResult getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO) { if (queryDTO.getUserId() == null) { throw new BusinessException("用户ID不能为空"); } Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", queryDTO.getUserId()); buildQueryWrapper(wrapper, queryDTO); IPage result = page(page, wrapper); return new PageResult( result.getRecords(), result.getTotal(), queryDTO.getPageNum().longValue(), queryDTO.getPageSize().longValue(), result.getPages() ); } @Override public PageResult getUnitPointsFlowPage(PointsFlowQueryDTO queryDTO) { if (queryDTO.getUnitId() == null) { throw new BusinessException("单位ID不能为空"); } Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("unit_id", queryDTO.getUnitId()); buildQueryWrapper(wrapper, queryDTO); IPage result = page(page, wrapper); return new PageResult( result.getRecords(), result.getTotal(), queryDTO.getPageNum().longValue(), queryDTO.getPageSize().longValue(), result.getPages() ); } @Override public List getPointsFlowByUserId(Long userId) { if (userId == null) { throw new BusinessException("用户ID不能为空"); } QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", userId) .orderByDesc("created_at"); return list(wrapper); } @Override public List getPointsFlowByUnitId(Long unitId) { if (unitId == null) { throw new BusinessException("单位ID不能为空"); } QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("unit_id", unitId) .orderByDesc("created_at"); return list(wrapper); } @Override @Transactional(rollbackFor = Exception.class) public boolean recordPointsFlow(Long userId, Long unitId, String flowType, String pointsSource, Integer pointsValue, String orderId, String description) { if (userId == null || unitId == null || !StringUtils.hasText(flowType) || !StringUtils.hasText(pointsSource) || pointsValue == null) { throw new BusinessException("参数不完整"); } // 创建积分流水记录 PointsFlow pointsFlow = new PointsFlow(); pointsFlow.setUserId(userId); pointsFlow.setUnitId(unitId); pointsFlow.setDataType(flowType); pointsFlow.setDataCategory(pointsSource); pointsFlow.setPoints(pointsValue); pointsFlow.setName(description); pointsFlow.setFlowTime(LocalDateTime.now()); boolean saved = save(pointsFlow); if (!saved) { throw new BusinessException("保存积分流水失败"); } // 更新用户积分 updateUserPoints(userId, unitId, pointsValue); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean addPointsFlowByRule(AddPointsFlowDTO addPointsFlowDTO) { if (addPointsFlowDTO == null) { throw new BusinessException("参数不能为空"); } Long userId = addPointsFlowDTO.getUserId(); Long unitId = addPointsFlowDTO.getUnitId(); String ruleType = addPointsFlowDTO.getRuleType(); String ruleName = addPointsFlowDTO.getRuleName(); Integer count = addPointsFlowDTO.getCount() != null ? addPointsFlowDTO.getCount() : 1; // 查询积分规则 PointsRule pointsRule = pointsRuleService.getRuleByTriggerCondition(ruleName); if (pointsRule == null) { throw new BusinessException("积分规则不存在或未启用: " + ruleName); } // 验证规则类型是否匹配 if (!ruleType.equals(pointsRule.getRuleType())) { throw new BusinessException("规则类型不匹配,期望: " + pointsRule.getRuleType() + ",实际: " + ruleType); } // 计算积分值 Integer basePoints = pointsRule.getPointsValue() != null ? pointsRule.getPointsValue() : 0; Integer totalPoints = basePoints * count; // 如果是消费类型,积分为负数 if ("消费".equals(ruleType)) { totalPoints = -totalPoints; } // 检查每日积分上限 if (basePoints > 0 && pointsRule.getPriority() != null && pointsRule.getPriority() > 0) { checkDailyLimit(userId, unitId, ruleName, totalPoints, pointsRule.getPriority()); } // 创建积分流水记录 PointsFlow pointsFlow = new PointsFlow(); pointsFlow.setUserId(userId); pointsFlow.setUnitId(unitId); pointsFlow.setDataType(ruleType); pointsFlow.setDataCategory(ruleName); pointsFlow.setPoints(totalPoints); pointsFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : pointsRule.getRuleDescription()); pointsFlow.setFlowTime(LocalDateTime.now()); boolean saved = save(pointsFlow); if (!saved) { throw new BusinessException("保存积分流水失败"); } // 更新用户积分账户 updateUserPointsByRule(userId, unitId, totalPoints, ruleType); return true; } @Override public Integer getUserPointsTotal(Long userId) { if (userId == null) { return 0; } QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", userId); UserPoints userPoints = userPointsMapper.selectOne(wrapper); return userPoints != null ? userPoints.getBalance() : 0; } @Override public Integer getUnitPointsTotal(Long unitId) { if (unitId == null) { return 0; } QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("unit_id", unitId); UserPoints userPoints = userPointsMapper.selectOne(wrapper); return userPoints != null ? userPoints.getBalance() : 0; } /** * 构建查询条件 */ private void buildQueryWrapper(QueryWrapper wrapper, PointsFlowQueryDTO queryDTO) { if (StringUtils.hasText(queryDTO.getFlowType())) { wrapper.eq("flow_type", queryDTO.getFlowType()); } if (StringUtils.hasText(queryDTO.getPointsSource())) { wrapper.eq("points_source", queryDTO.getPointsSource()); } if (StringUtils.hasText(queryDTO.getOrderId())) { wrapper.eq("order_id", queryDTO.getOrderId()); } if (queryDTO.getStartTime() != null) { wrapper.ge("flow_time", queryDTO.getStartTime()); } if (queryDTO.getEndTime() != null) { wrapper.le("flow_time", queryDTO.getEndTime()); } wrapper.orderByDesc("flow_time"); } /** * 检查每日积分上限 */ private void checkDailyLimit(Long userId, Long unitId, String ruleName, Integer currentPoints, Integer priority) { // 获取今日开始和结束时间 LocalDate today = LocalDate.now(); LocalDateTime startOfDay = today.atStartOfDay(); LocalDateTime endOfDay = today.atTime(23, 59, 59); // 查询今日该规则的积分流水 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", userId) .eq("unit_id", unitId) .eq("data_category", ruleName) .ge("flow_time", startOfDay) .le("flow_time", endOfDay); List todayFlows = list(wrapper); // 计算今日累计积分 int todayTotal = todayFlows.stream() .mapToInt(flow -> flow.getPoints() != null ? flow.getPoints() : 0) .sum(); // 如果今日累计积分超过优先级限制,则抛出异常 if (Math.abs(todayTotal) >= priority) { throw new BusinessException("今日该规则积分已达上限: " + priority); } } /** * 更新用户积分 */ private void updateUserPoints(Long userId, Long unitId, Integer pointsValue) { // 更新个人积分 QueryWrapper userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) .eq("user_id", userId); UserPoints userPoints = userPointsMapper.selectOne(userWrapper); if (userPoints == null) { userPoints = new UserPoints(); userPoints.setUserId(userId); userPoints.setUnitId(unitId); userPoints.setBalance(pointsValue); userPointsMapper.insert(userPoints); } else { userPoints.setBalance(userPoints.getBalance() + pointsValue); userPoints.setUpdateTime(LocalDateTime.now()); userPointsMapper.updateById(userPoints); } // 更新单位积分 QueryWrapper unitWrapper = new QueryWrapper<>(); unitWrapper.eq("deleted", 0) .eq("unit_id", unitId); UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper); if (unitPoints == null) { unitPoints = new UserPoints(); unitPoints.setUserId(userId); unitPoints.setUnitId(unitId); unitPoints.setBalance(pointsValue); userPointsMapper.insert(unitPoints); } else { unitPoints.setBalance(unitPoints.getBalance() + pointsValue); unitPoints.setUpdateTime(LocalDateTime.now()); userPointsMapper.updateById(unitPoints); } } /** * 根据规则更新用户积分账户 */ private void updateUserPointsByRule(Long userId, Long unitId, Integer pointsValue, String ruleType) { // 更新个人积分账户 QueryWrapper userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) .eq("user_id", userId); UserPoints userPoints = userPointsMapper.selectOne(userWrapper); if (userPoints == null) { userPoints = new UserPoints(); userPoints.setUserId(userId); userPoints.setUnitId(unitId); userPoints.setBalance(pointsValue); userPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0); userPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0); userPointsMapper.insert(userPoints); } else { userPoints.setBalance(userPoints.getBalance() + pointsValue); // 更新累计获取积分 if (pointsValue > 0) { userPoints.setTotalEarned(userPoints.getTotalEarned() != null ? userPoints.getTotalEarned() + pointsValue : pointsValue); } // 更新累计消耗积分 if (pointsValue < 0) { userPoints.setTotalConsumed(userPoints.getTotalConsumed() != null ? userPoints.getTotalConsumed() + Math.abs(pointsValue) : Math.abs(pointsValue)); } userPoints.setUpdateTime(LocalDateTime.now()); userPointsMapper.updateById(userPoints); } // 更新单位积分账户 QueryWrapper unitWrapper = new QueryWrapper<>(); unitWrapper.eq("deleted", 0) .eq("unit_id", unitId); UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper); if (unitPoints == null) { unitPoints = new UserPoints(); unitPoints.setUserId(userId); unitPoints.setUnitId(unitId); unitPoints.setBalance(pointsValue); unitPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0); unitPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0); userPointsMapper.insert(unitPoints); } else { unitPoints.setBalance(unitPoints.getBalance() + pointsValue); // 更新累计获取积分 if (pointsValue > 0) { unitPoints.setTotalEarned(unitPoints.getTotalEarned() != null ? unitPoints.getTotalEarned() + pointsValue : pointsValue); } // 更新累计消耗积分 if (pointsValue < 0) { unitPoints.setTotalConsumed(unitPoints.getTotalConsumed() != null ? unitPoints.getTotalConsumed() + Math.abs(pointsValue) : Math.abs(pointsValue)); } unitPoints.setUpdateTime(LocalDateTime.now()); userPointsMapper.updateById(unitPoints); } } }