修复:子部门共享上级部门积分池 - 余额为0且未充值时自动向上查找

This commit is contained in:
Your Name 2026-01-24 09:59:01 +08:00
parent 2cb38df288
commit e3cb59539f

View File

@ -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<TeamScorePool>()
@ -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<TeamScorePool>()
.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;
}
/**
* 更新积分池配置