p-honggang.li
9 天以前 c8a179a0bdbc7bdc987788e129efce16d467889f
src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java
@@ -7,6 +7,7 @@
import com.webmanage.common.BusinessException;
import com.webmanage.common.PageResult;
import com.webmanage.dto.AddPointsFlowDTO;
import com.webmanage.dto.DeductUserPointsDTO;
import com.webmanage.dto.PointsFlowQueryDTO;
import com.webmanage.emun.RuleTypeEnum;
import com.webmanage.entity.PointsFlow;
@@ -14,6 +15,9 @@
import com.webmanage.entity.UserPoints;
import com.webmanage.mapper.PointsFlowMapper;
import com.webmanage.mapper.UserPointsMapper;
import com.webmanage.mapper.PointsTransactionMapper;
import com.webmanage.entity.PointsTransaction;
import com.webmanage.service.OrderInfoService;
import com.webmanage.service.PointsFlowService;
import com.webmanage.service.PointsRuleService;
import lombok.extern.slf4j.Slf4j;
@@ -39,6 +43,10 @@
    @Resource
    private PointsRuleService pointsRuleService;
    @Resource
    private PointsTransactionMapper pointsTransactionMapper;
    @Override
    public PageResult<PointsFlow> getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO) {
@@ -213,7 +221,7 @@
        if (applyProvider && providerPointsChange != 0) {
            PointsFlow providerFlow = new PointsFlow();
            providerFlow.setUserId(providerId);
            providerFlow.setUnitId(providerId);
            providerFlow.setUnitId(null);
            providerFlow.setDataType(ruleType);
            providerFlow.setDataCategory(addPointsFlowDTO.getCategory());
            providerFlow.setPoints(providerPointsChange);
@@ -225,8 +233,8 @@
            if (!providerSaved) {
                throw new BusinessException("保存提供者积分流水失败");
            }
            updateProviderUnitPoints(providerId, providerPointsChange);
            updateUserPointsByRule(providerId, null, userPointsChange);
            // updateProviderUnitPoints(providerId, providerPointsChange);
        }
        return true;
@@ -326,11 +334,10 @@
     */
    private PointsRule getLatestEffectiveRule(Integer ruleType, String ruleNameCode, String category, Integer pointsWinner) {
        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", 0)
               .eq("is_enabled", 0)
        wrapper.eq("is_enabled", 0)
               .eq("rule_type", ruleType)
               .eq("rule_name_code", ruleNameCode)
               .eq("data_category", category)
               .eq("category", category)
               .eq(pointsWinner != null, "points_winner", pointsWinner)
               .orderByDesc("created_at")
               .last("LIMIT 1");
@@ -382,7 +389,7 @@
     * 检查积分余额是否足够
     */
    private void checkBalanceSufficient(String userId, String unitId, Integer requiredPoints) {
        // 检查个人积分余额
        // 仅检查个人积分余额(移除单位余额判定)
        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
        userWrapper.eq("deleted", 0)
                  .eq("user_id", userId);
@@ -392,15 +399,7 @@
            throw new BusinessException("个人积分余额不足,当前余额: " + (userPoints != null ? userPoints.getBalance() : 0) + ",需要扣除: " + requiredPoints);
        }
        // 检查单位积分余额
        QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>();
        unitWrapper.eq("deleted", 0)
                  .eq("unit_id", unitId);
        UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper);
        if (unitPoints == null || unitPoints.getBalance() < requiredPoints) {
            throw new BusinessException("单位积分余额不足,当前余额: " + (unitPoints != null ? unitPoints.getBalance() : 0) + ",需要扣除: " + requiredPoints);
        }
        // 原单位余额校验已移除
    }
    /**
@@ -493,7 +492,9 @@
            
            userPoints = new UserPoints();
            userPoints.setUserId(userId);
            userPoints.setUnitId(unitId);
            if(StringUtils.hasText(unitId)){
                userPoints.setUnitId(unitId);
            }
            userPoints.setBalance(pointsValue);
            userPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0);
            userPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0);
@@ -523,7 +524,7 @@
        }
        // 更新单位积分账户
        QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>();
         /* QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>();
        unitWrapper.eq("deleted", 0)
                  .eq("unit_id", unitId);
        
@@ -563,6 +564,92 @@
            
            unitPoints.setUpdateTime(LocalDateTime.now());
            userPointsMapper.updateById(unitPoints);
        } */
    }
    /**
     * 扣减用户积分
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deductUserPoints(DeductUserPointsDTO deductDTO) {
        try {
            String userId = deductDTO.getUserId();
            String providerId = deductDTO.getProviderId();
            String unitId = deductDTO.getUnitId();
            Integer points = deductDTO.getPoints();
            String orderId = deductDTO.getOrderId();
            String remark = deductDTO.getRemark();
            String dataCategory = deductDTO.getDataCategory();
            Integer dataType = deductDTO.getDataType();
            if (!StringUtils.hasText(userId)) {
                throw new BusinessException("用户ID不能为空");
            }
            if (points == null || points <= 0) {
                throw new BusinessException("扣减积分数量必须大于0");
            }
            // 检查用户积分余额是否充足
            checkBalanceSufficient(userId, unitId, points);
            // 创建积分流水记录
            PointsFlow pointsFlow = new PointsFlow();
            pointsFlow.setUserId(userId);
            pointsFlow.setUnitId(unitId);
            pointsFlow.setDataCategory(dataCategory != null ? dataCategory : "积分交易");
            pointsFlow.setDataType(dataType != null ? dataType : 1);
            pointsFlow.setPoints(-points); // 负数表示扣减
            pointsFlow.setName(remark != null ? remark : "积分扣减"); // name字段存储remark内容
            pointsFlow.setFlowTime(LocalDateTime.now());
            pointsFlow.setRlueId(null); // 直接扣减,不关联规则
            boolean saved = save(pointsFlow);
            if (!saved) {
                throw new BusinessException("保存积分流水失败");
            }
            // 更新用户积分账户
            updateUserPointsOnly(userId, -points);
            // 新增积分交易记录(与流水同事务)
            PointsTransaction trans = new PointsTransaction();
            // tb_points_transaction 的 chk_data_category 仅允许 '用户参与'、'其他'
            // 这里将业务类目映射为数据库允许的值
            trans.setDataCategory("用户参与");
            trans.setTransactionName(pointsFlow.getName());
            trans.setTransactionTime(LocalDateTime.now());
            trans.setPointsChange(-points);
            trans.setRuleType("消耗");
            try {
                trans.setUserId(Long.valueOf(userId));
            } catch (Exception ignore) {}
            try {
                if (StringUtils.hasText(unitId)) trans.setUnitId(Long.valueOf(unitId));
            } catch (Exception ignore) {}
            trans.setUserType("个人用户");
            trans.setRuleId(null);
            trans.setDetailId(null);
            trans.setCreatedAt(LocalDateTime.now());
            trans.setDeleted(0);
            int inserted = pointsTransactionMapper.insert(trans);
            log.info("Points transaction inserted rows={}, id={}", inserted, trans.getId());
            if (inserted <= 0 || trans.getId() == null) {
                throw new BusinessException("保存积分交易记录失败");
            }
            // 为提供者新增积分
            AddPointsFlowDTO addPointsFlowDTO = new AddPointsFlowDTO();
            addPointsFlowDTO.setCategory("资源交易");
            addPointsFlowDTO.setCount(1);
            addPointsFlowDTO.setProviderId(providerId);
            addPointsFlowDTO.setRuleType(0);
            addPointsFlowDTO.setRuleNameCode("digital_product_transaction");
            addPointsFlowDTO.setDescription("产品交易");
            addPointsFlowByRule(addPointsFlowDTO);
            return true;
        } catch (Exception e) {
            log.error("扣减用户积分失败", e);
            throw new BusinessException("扣减用户积分失败:" + e.getMessage());
        }
    }
@@ -607,4 +694,40 @@
            userPointsMapper.updateById(unitPoints);
        }
    }
    /**
     * 仅更新个人积分账户(不操作单位账户)
     */
    private void updateUserPointsOnly(String userId, Integer pointsValue) {
        // 更新个人积分账户
        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
        userWrapper.eq("deleted", 0)
                  .eq("user_id", userId);
        UserPoints userPoints = userPointsMapper.selectOne(userWrapper);
        if (userPoints == null) {
            if (pointsValue < 0) {
                throw new BusinessException("个人积分余额不足,无法扣除积分");
            }
            userPoints = new UserPoints();
            userPoints.setUserId(userId);
            userPoints.setUnitId(null);
            userPoints.setBalance(pointsValue);
            userPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0);
            userPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0);
            userPointsMapper.insert(userPoints);
        } else {
            if (pointsValue < 0 && userPoints.getBalance() + pointsValue < 0) {
                throw new BusinessException("个人积分余额不足,当前余额: " + userPoints.getBalance() + ",需要扣除: " + Math.abs(pointsValue));
            }
            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);
        }
    }
}