diff --git a/backend/src/main/java/com/designhub/service/TeamScorePoolService.java b/backend/src/main/java/com/designhub/service/TeamScorePoolService.java index 5e571fd..be66141 100644 --- a/backend/src/main/java/com/designhub/service/TeamScorePoolService.java +++ b/backend/src/main/java/com/designhub/service/TeamScorePoolService.java @@ -27,8 +27,18 @@ public class TeamScorePoolService { /** * 根据部门ID获取积分池 * 使用 dept_id 关联部门(team_id 为遗留字段)。若当前部门无积分池且存在父部门,则向上查找父部门积分池(三级部门共享二级)。 + * 如果当前部门有积分池但余额为0且从未充值,也向上查找父部门积分池(支持子部门共享上级积分)。 */ public TeamScorePool getByDeptId(Long deptId) { + return getByDeptIdInternal(deptId, true); + } + + /** + * 内部方法:根据部门ID获取积分池 + * @param deptId 部门ID + * @param allowShareParent 是否允许共享父部门积分池 + */ + private TeamScorePool getByDeptIdInternal(Long deptId, boolean allowShareParent) { // 使用 selectList + findFirst 避免重复数据导致的 TooManyResultsException TeamScorePool pool = teamScorePoolMapper.selectList( new LambdaQueryWrapper() @@ -37,16 +47,52 @@ public class TeamScorePoolService { .last("LIMIT 1") ).stream().findFirst().orElse(null); + // 判断是否需要向上查找父部门积分池 + boolean shouldFindParent = false; + if (pool == null) { + // 情况1:当前部门没有积分池记录 + shouldFindParent = true; + log.debug("部门{}没有积分池记录,尝试查找父部门积分池", deptId); + } else if (allowShareParent && isPoolEmptyAndNeverRecharged(pool)) { + // 情况2:当前部门有积分池但余额为0且从未充值(说明是系统自动创建的空记录) + shouldFindParent = true; + log.debug("部门{}的积分池余额为0且从未充值,尝试查找父部门共享积分池", deptId); + } + + if (shouldFindParent) { Department department = departmentMapper.selectById(deptId); if (department != null && department.getParentId() != null && department.getParentId() > 0) { - log.debug("部门{}没有积分池,查找父部门{}的积分池", deptId, department.getParentId()); - return getByDeptId(department.getParentId()); + TeamScorePool parentPool = getByDeptIdInternal(department.getParentId(), true); + if (parentPool != null && parentPool.getBalance() > 0) { + log.info("部门{}将使用父部门{}的共享积分池(余额:{})", deptId, parentPool.getDeptId(), parentPool.getBalance()); + return parentPool; + } } } return pool; } + + /** + * 判断积分池是否为空且从未充值(系统自动创建的空记录) + */ + private boolean isPoolEmptyAndNeverRecharged(TeamScorePool pool) { + if (pool == null) { + return true; + } + Integer balance = pool.getBalance() != null ? pool.getBalance() : 0; + Integer totalRecharge = pool.getTotalRecharge() != null ? pool.getTotalRecharge() : 0; + // 余额为0且从未充值过,说明是系统自动创建的空记录 + return balance == 0 && totalRecharge == 0; + } + + /** + * 根据部门ID获取自己的积分池(不向上查找,用于充值等场景) + */ + public TeamScorePool getOwnPoolByDeptId(Long deptId) { + return getByDeptIdInternal(deptId, false); + } /** * 检查积分是否足够 @@ -171,13 +217,20 @@ public class TeamScorePoolService { } /** - * 充值积分 + * 充值积分(充值到自己的积分池,不使用共享的父部门积分池) */ @Transactional(rollbackFor = Exception.class) public void rechargeScore(Long deptId, Integer score) { - TeamScorePool pool = getByDeptId(deptId); + // 充值时使用自己的积分池,不向上查找 + TeamScorePool pool = getOwnPoolByDeptId(deptId); if (pool == null) { - throw new BusinessException("部门积分池不存在"); + // 如果没有自己的积分池,创建一个 + Department department = departmentMapper.selectById(deptId); + if (department != null) { + pool = upsertPoolForSelf(deptId, department.getDeptName()); + } else { + throw new BusinessException("部门不存在"); + } } pool.setBalance(pool.getBalance() + score); @@ -260,6 +313,40 @@ public class TeamScorePoolService { } return pool; } + + /** + * 更新或创建自己的积分池(不向上查找,用于充值等需要操作自己积分池的场景) + */ + @Transactional(rollbackFor = Exception.class) + public TeamScorePool upsertPoolForSelf(Long deptId, String deptName) { + // 直接查询自己的积分池,不向上查找 + TeamScorePool pool = teamScorePoolMapper.selectList( + new LambdaQueryWrapper() + .eq(TeamScorePool::getDeptId, deptId) + .orderByAsc(TeamScorePool::getId) + .last("LIMIT 1") + ).stream().findFirst().orElse(null); + + if (pool == null) { + pool = new TeamScorePool(); + pool.setDeptId(deptId); + pool.setDeptName(deptName); + pool.setBalance(0); + pool.setTotalRecharge(0); + pool.setTotalConsume(0); + pool.setTotalEarn(0); + pool.setLimitEnabled(0); + pool.setAlertThreshold(80); + pool.setPeriodUsed(0); + pool.setPeriodLimit(0); + pool.setPeriodStartTime(LocalDateTime.now()); + createPool(pool); + } else if (deptName != null && !deptName.equals(pool.getDeptName())) { + pool.setDeptName(deptName); + teamScorePoolMapper.updateById(pool); + } + return pool; + } /** * 更新积分池配置