From 2b0b64182263d922b946ec898070e59b602382dc Mon Sep 17 00:00:00 2001 From: Bang Hu <hu_bang@hotmail.com> Date: 星期四, 11 九月 2025 18:38:09 +0800 Subject: [PATCH] 交易审批多节点问题处理完善 --- src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java | 356 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 295 insertions(+), 61 deletions(-) diff --git a/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java b/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java index 8cdf5be..c09eb66 100644 --- a/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java +++ b/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; @@ -40,9 +44,13 @@ @Resource private PointsRuleService pointsRuleService; + @Resource + private PointsTransactionMapper pointsTransactionMapper; + + @Override public PageResult<PointsFlow> getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO) { - if (queryDTO.getUserId() == null) { + if (!StringUtils.hasText(queryDTO.getUserId())) { throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖"); } @@ -123,68 +131,118 @@ throw new BusinessException("鍙傛暟涓嶈兘涓虹┖"); } - Long userId = addPointsFlowDTO.getUserId(); - Long unitId = addPointsFlowDTO.getUnitId(); + String userId = addPointsFlowDTO.getUserId(); + String providerId = addPointsFlowDTO.getProviderId(); + String unitId = addPointsFlowDTO.getUnitId(); Integer ruleType = addPointsFlowDTO.getRuleType(); String category = addPointsFlowDTO.getCategory(); String ruleNameCode = addPointsFlowDTO.getRuleNameCode(); Integer count = addPointsFlowDTO.getCount() != null ? addPointsFlowDTO.getCount() : 1; - // 鏍规嵁ruleType銆乺uleNameCode銆乧ategory鏌ヨ鐢熸晥鏃堕棿鏈�鏂扮殑绉垎瑙勫垯 - PointsRule pointsRule = getLatestEffectiveRule(ruleType, ruleNameCode, category); - if (pointsRule == null) { - throw new BusinessException("绉垎瑙勫垯涓嶅瓨鍦ㄦ垨鏈惎鐢�: ruleType=" + ruleType + ", ruleNameCode=" + ruleNameCode + ", category=" + category); + boolean applyUser = StringUtils.hasText(userId) ; + boolean applyProvider = StringUtils.hasText(providerId) ;; + if (!applyUser && !applyProvider) { + throw new BusinessException("userId 涓� providerId 涓嶈兘鍚屾椂涓虹┖"); } - // 楠岃瘉瑙勫垯绫诲瀷鏄惁鍖归厤 - if (!ruleType.equals(pointsRule.getRuleType())) { - throw new BusinessException("瑙勫垯绫诲瀷涓嶅尮閰嶏紝鏈熸湜: " + pointsRule.getRuleType() + "锛屽疄闄�: " + ruleType); + // 鍒嗗埆鑾峰彇鐢ㄦ埛渚�/鎻愪緵鑰呬晶鏈�鏂扮敓鏁堣鍒欙紙鎸� points_winner 杩囨护锛�1鐢ㄦ埛銆�0鎻愪緵鑰咃級 + PointsRule userRule = null; + PointsRule providerRule = null; + if (applyUser) { + userRule = getLatestEffectiveRule(ruleType, ruleNameCode, category, 1); + if (userRule == null) { + throw new BusinessException("鏈壘鍒扮敤鎴蜂晶鐢熸晥瑙勫垯: ruleType=" + ruleType + ", ruleNameCode=" + ruleNameCode + ", category=" + category + ", points_winner=1"); + } + if (!ruleType.equals(userRule.getRuleType())) { + throw new BusinessException("鐢ㄦ埛渚ц鍒欑被鍨嬩笉鍖归厤锛屾湡鏈�: " + userRule.getRuleType() + "锛屽疄闄�: " + ruleType); + } + } + if (applyProvider) { + providerRule = getLatestEffectiveRule(ruleType, ruleNameCode, category, 0); + if (providerRule == null) { + throw new BusinessException("鏈壘鍒版彁渚涜�呬晶鐢熸晥瑙勫垯: ruleType=" + ruleType + ", ruleNameCode=" + ruleNameCode + ", category=" + category + ", points_winner=0"); + } + if (!ruleType.equals(providerRule.getRuleType())) { + throw new BusinessException("鎻愪緵鑰呬晶瑙勫垯绫诲瀷涓嶅尮閰嶏紝鏈熸湜: " + providerRule.getRuleType() + "锛屽疄闄�: " + ruleType); + } } - // 璁$畻绉垎鍊� - Integer basePoints = pointsRule.getPointsValue() != null ? pointsRule.getPointsValue() : 0; - Integer totalPoints = basePoints * count; - - // 濡傛灉鏄秷璐圭被鍨嬶紝绉垎涓鸿礋鏁� - if (ruleType == RuleTypeEnum.CONSUME.getCode()) { // 1琛ㄧず娑堣垂绫诲瀷 - totalPoints = -totalPoints; + // 璁$畻涓や晶绉垎鍙樺寲锛堝悇鑷寜瑙勫垯璁$畻锛� + int userPointsChange = 0; + int providerPointsChange = 0; + if (applyUser) { + int base = userRule.getPointsValue() != null ? userRule.getPointsValue() : 0; + int amount = base * count; + userPointsChange = (ruleType == RuleTypeEnum.CONSUME.getCode()) ? -Math.abs(amount) : Math.abs(amount); + } + if (applyProvider) { + int base = providerRule.getPointsValue() != null ? providerRule.getPointsValue() : 0; + int amount = base * count; + providerPointsChange = (ruleType == RuleTypeEnum.CONSUME.getCode()) ? -Math.abs(amount) : Math.abs(amount); } - // 妫�鏌ユ瘡鏃ョН鍒嗕笂闄� - if (pointsRule.getIsLimit() != null && pointsRule.getIsLimit() == 0) { // 0琛ㄧず鏈夋瘡鏃ヤ笂闄� - checkDailyLimitByRule(userId, unitId, pointsRule, totalPoints); + // 姣忔棩涓婇檺鏍¢獙锛堝垎鍒牎楠岋級 + if (applyUser && userRule.getIsLimit() != null && userRule.getIsLimit() == 1) { + checkDailyLimitByRule(userId, unitId, userRule, userPointsChange); + } + if (applyProvider && providerRule.getIsLimit() != null && providerRule.getIsLimit() == 1) { + checkDailyLimitByRule(providerId, null, providerRule, providerPointsChange); } - // 濡傛灉鏄墸绉垎鎿嶄綔锛屽厛妫�鏌ヤ綑棰濇槸鍚﹁冻澶� - if (totalPoints < 0) { - checkBalanceSufficient(userId, unitId, Math.abs(totalPoints)); + // 浣欓鏍¢獙锛堜粎鍦ㄦ墸鍑忔椂锛� + if (applyUser && userPointsChange < 0) { + checkBalanceSufficient(userId, unitId, Math.abs(userPointsChange)); + } + if (applyProvider && providerPointsChange < 0) { + checkBalanceSufficient(providerId, providerId, Math.abs(providerPointsChange)); } - // 鍒涘缓绉垎娴佹按璁板綍 - PointsFlow pointsFlow = new PointsFlow(); - pointsFlow.setUserId(userId); - pointsFlow.setUnitId(unitId); - pointsFlow.setDataType(ruleType); - pointsFlow.setDataCategory(addPointsFlowDTO.getCategory()); - pointsFlow.setPoints(totalPoints); - pointsFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : pointsRule.getRuleDescription()); - pointsFlow.setFlowTime(LocalDateTime.now()); - pointsFlow.setRlueId(pointsRule.getId()); + // 鐢熸垚鐢ㄦ埛渚ф祦姘村苟鏇存柊璐︽埛 + if (applyUser && userPointsChange != 0) { + PointsFlow pointsFlow = new PointsFlow(); + pointsFlow.setUserId(userId); + pointsFlow.setUnitId(unitId); + pointsFlow.setDataType(ruleType); + pointsFlow.setDataCategory(addPointsFlowDTO.getCategory()); + pointsFlow.setPoints(userPointsChange); + pointsFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : userRule.getRuleDescription()); + pointsFlow.setFlowTime(LocalDateTime.now()); + pointsFlow.setRlueId(userRule.getId()); - boolean saved = save(pointsFlow); - if (!saved) { - throw new BusinessException("淇濆瓨绉垎娴佹按澶辫触"); + boolean saved = save(pointsFlow); + if (!saved) { + throw new BusinessException("淇濆瓨绉垎娴佹按澶辫触"); + } + + updateUserPointsByRule(userId, unitId, userPointsChange); } - // 鏇存柊鐢ㄦ埛绉垎璐︽埛 - updateUserPointsByRule(userId, unitId, totalPoints); + // 鐢熸垚鎻愪緵鑰呬晶娴佹按骞舵洿鏂拌处鎴� + if (applyProvider && providerPointsChange != 0) { + PointsFlow providerFlow = new PointsFlow(); + providerFlow.setUserId(providerId); + providerFlow.setUnitId(null); + providerFlow.setDataType(ruleType); + providerFlow.setDataCategory(addPointsFlowDTO.getCategory()); + providerFlow.setPoints(providerPointsChange); + providerFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : providerRule.getRuleDescription()); + providerFlow.setFlowTime(LocalDateTime.now()); + providerFlow.setRlueId(providerRule.getId()); + + boolean providerSaved = save(providerFlow); + if (!providerSaved) { + throw new BusinessException("淇濆瓨鎻愪緵鑰呯Н鍒嗘祦姘村け璐�"); + } + updateUserPointsByRule(providerId, null, userPointsChange); + // updateProviderUnitPoints(providerId, providerPointsChange); + } return true; } @Override - public UserPoints getUserPointsTotal(Long userId) { - if (userId == null) { + public UserPoints getUserPointsTotal(String userId) { + if (!StringUtils.hasText(userId)) { throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓簄ull"); } @@ -272,9 +330,24 @@ } /** + * 鏍规嵁ruleType銆乺uleNameCode銆乧ategory銆乸oints_winner鏌ヨ鐢熸晥鏃堕棿鏈�鏂扮殑绉垎瑙勫垯 + */ + private PointsRule getLatestEffectiveRule(Integer ruleType, String ruleNameCode, String category, Integer pointsWinner) { + QueryWrapper<PointsRule> wrapper = new QueryWrapper<>(); + wrapper.eq("is_enabled", 0) + .eq("rule_type", ruleType) + .eq("rule_name_code", ruleNameCode) + .eq("category", category) + .eq(pointsWinner != null, "points_winner", pointsWinner) + .orderByDesc("created_at") + .last("LIMIT 1"); + return pointsRuleService.getOne(wrapper); + } + + /** * 妫�鏌ユ瘡鏃ョН鍒嗕笂闄愶紙鍩轰簬瑙勫垯锛� */ - private void checkDailyLimitByRule(Long userId, Long unitId, PointsRule pointsRule, Integer currentPoints) { + private void checkDailyLimitByRule(String userId, String unitId, PointsRule pointsRule, Integer currentPoints) { // 鑾峰彇浠婃棩寮�濮嬪拰缁撴潫鏃堕棿 LocalDate today = LocalDate.now(); LocalDateTime startOfDay = today.atStartOfDay(); @@ -284,11 +357,14 @@ QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", userId) - .eq("unit_id", unitId) // .eq("data_category", pointsRule.getRuleName()) .eq("rule_id",pointsRule.getId()) + // .eq("data_type", 0) .ge("flow_time", startOfDay) .le("flow_time", endOfDay); + if(StringUtils.hasText(unitId)){ + wrapper.eq("unit_id", unitId); + } List<PointsFlow> todayFlows = list(wrapper); @@ -301,22 +377,22 @@ Integer dailyLimit = pointsRule.getDailyLimit(); if (dailyLimit != null && dailyLimit > 0) { // 濡傛灉浠婃棩绱绉垎瓒呰繃姣忔棩涓婇檺锛屽垯鎶涘嚭寮傚父 - if (Math.abs(todayTotal) >= dailyLimit) { + if (Math.abs(todayTotal) > dailyLimit) { throw new BusinessException("浠婃棩璇ヨ鍒欑Н鍒嗗凡杈句笂闄�: " + dailyLimit); } // 濡傛灉鍔犱笂褰撳墠绉垎浼氳秴杩囨瘡鏃ヤ笂闄愶紝鍒欐姏鍑哄紓甯� - if (Math.abs(todayTotal + currentPoints) > dailyLimit) { - throw new BusinessException("鏈绉垎鎿嶄綔灏嗚秴杩囨瘡鏃ヤ笂闄�: " + dailyLimit + "锛屽綋鍓嶅凡绱: " + Math.abs(todayTotal)); - } +// if (Math.abs(todayTotal + currentPoints) > dailyLimit) { +// throw new BusinessException("鏈绉垎鎿嶄綔灏嗚秴杩囨瘡鏃ヤ笂闄�: " + dailyLimit + "锛屽綋鍓嶅凡绱: " + Math.abs(todayTotal)); +// } } } /** * 妫�鏌ョН鍒嗕綑棰濇槸鍚﹁冻澶� */ - private void checkBalanceSufficient(Long userId, Long unitId, Integer requiredPoints) { - // 妫�鏌ヤ釜浜虹Н鍒嗕綑棰� + private void checkBalanceSufficient(String userId, String unitId, Integer requiredPoints) { + // 浠呮鏌ヤ釜浜虹Н鍒嗕綑棰濓紙绉婚櫎鍗曚綅浣欓鍒ゅ畾锛� QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) .eq("user_id", userId); @@ -326,15 +402,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); - } + // 鍘熷崟浣嶄綑棰濇牎楠屽凡绉婚櫎 } /** @@ -371,7 +439,7 @@ /** * 鏇存柊鐢ㄦ埛绉垎 */ - private void updateUserPoints(Long userId, Long unitId, Integer pointsValue) { + private void updateUserPoints(String userId, String unitId, Integer pointsValue) { // 鏇存柊涓汉绉垎 QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) @@ -412,7 +480,7 @@ /** * 鏍规嵁瑙勫垯鏇存柊鐢ㄦ埛绉垎璐︽埛 */ - private void updateUserPointsByRule(Long userId, Long unitId, Integer pointsValue) { + private void updateUserPointsByRule(String userId, String unitId, Integer pointsValue) { // 鏇存柊涓汉绉垎璐︽埛 QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) @@ -427,7 +495,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); @@ -457,7 +527,7 @@ } // 鏇存柊鍗曚綅绉垎璐︽埛 - QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>(); + /* QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>(); unitWrapper.eq("deleted", 0) .eq("unit_id", unitId); @@ -497,6 +567,170 @@ unitPoints.setUpdateTime(LocalDateTime.now()); userPointsMapper.updateById(unitPoints); + } */ + } + + /** + * 鎵e噺鐢ㄦ埛绉垎 + */ + @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("鎵e噺绉垎鏁伴噺蹇呴』澶т簬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); // 璐熸暟琛ㄧず鎵e噺 + pointsFlow.setName(remark != null ? remark : "绉垎鎵e噺"); // name瀛楁瀛樺偍remark鍐呭 + pointsFlow.setFlowTime(LocalDateTime.now()); + pointsFlow.setRlueId(null); // 鐩存帴鎵e噺锛屼笉鍏宠仈瑙勫垯 + + 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噺鐢ㄦ埛绉垎澶辫触", e); + throw new BusinessException("鎵e噺鐢ㄦ埛绉垎澶辫触锛�" + e.getMessage()); + } + } + + /** + * 浠呮洿鏂版彁渚涜�咃紙鍗曚綅锛夌Н鍒嗚处鎴� + */ + private void updateProviderUnitPoints(String providerUnitId, Integer pointsValue) { + QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>(); + unitWrapper.eq("deleted", 0) + .eq("unit_id", providerUnitId); + + UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper); + if (unitPoints == null) { + if (pointsValue < 0) { + throw new BusinessException("鎻愪緵鑰呯Н鍒嗕綑棰濅笉瓒筹紝鏃犳硶鎵i櫎绉垎"); + } + + unitPoints = new UserPoints(); + unitPoints.setUserId(null); + unitPoints.setUnitId(providerUnitId); + unitPoints.setBalance(pointsValue); + unitPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0); + unitPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0); + userPointsMapper.insert(unitPoints); + } else { + if (pointsValue < 0 && unitPoints.getBalance() + pointsValue < 0) { + throw new BusinessException("鎻愪緵鑰呯Н鍒嗕綑棰濅笉瓒筹紝褰撳墠浣欓: " + unitPoints.getBalance() + "锛岄渶瑕佹墸闄�: " + Math.abs(pointsValue)); + } + + 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); + } + } + + /** + * 浠呮洿鏂颁釜浜虹Н鍒嗚处鎴凤紙涓嶆搷浣滃崟浣嶈处鎴凤級 + */ + 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); } } } -- Gitblit v1.8.0