UserGalaxyCoinServiceImpl.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package com.cyksj.service.coin.impl;
  2. import cn.hutool.core.date.DateTime;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  6. import com.cyksj.common.constant.PointsRecordConst;
  7. import com.cyksj.mapper.OrderDonGalaxyCoinRecordMapper;
  8. import com.cyksj.mapper.UserGalaxyCoinRecordMapper;
  9. import com.cyksj.mapper.UserMapper;
  10. import com.cyksj.model.entity.OrderDonGalaxyCoinRecord;
  11. import com.cyksj.model.entity.User;
  12. import com.cyksj.model.entity.UserGalaxyCoinRecord;
  13. import com.cyksj.service.coin.UserGalaxyCoinService;
  14. import lombok.RequiredArgsConstructor;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.springframework.stereotype.Service;
  17. import java.math.BigDecimal;
  18. /**
  19. * 项目名: yhlxj
  20. * 文件名: UserGalaxyCoinServiceImpl
  21. * 创建者: JavaZou
  22. * 创建时间:2025/7/1 15:29
  23. */
  24. @Service
  25. @RequiredArgsConstructor
  26. @Slf4j
  27. public class UserGalaxyCoinServiceImpl implements UserGalaxyCoinService {
  28. private final UserGalaxyCoinRecordMapper userGalaxyCoinRecordMapper;
  29. private final UserMapper userMapper;
  30. private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper;
  31. @Override
  32. public void sendGalaxyCoinRecord(Long userId, Integer galaxyCoin, String remark, Boolean isLottery) {
  33. if (!isLottery) {
  34. sendGalaxyCoinHandle(userId, null, galaxyCoin, remark, true, true, null);
  35. }
  36. }
  37. /**
  38. * @param isRecord 是否记录
  39. * @param available 该笔银河币是否可用
  40. */
  41. public void sendGalaxyCoinHandle(Long userId, Long orderId, Integer galaxyCoin, String remark, Boolean isRecord, Boolean available, OrderDonGalaxyCoinRecord.Source source) {
  42. //银河币为0不处理
  43. if (galaxyCoin == 0) {
  44. return;
  45. }
  46. while (true) {
  47. User user = userMapper.selectById(userId);
  48. if (user == null) {
  49. log.error("用户:{}不存在,无法发送银河币", userId);
  50. break;
  51. }
  52. BigDecimal userGalaxyCoin = user.getGalaxyCoin();
  53. if (galaxyCoin < 0 && userGalaxyCoin.compareTo(BigDecimal.ZERO) == 0) {
  54. log.info("用户:{}银河币数量为0,无法扣除", userId);
  55. break;
  56. }
  57. BigDecimal needHandleGalaxyCoin = userGalaxyCoin.add(BigDecimal.valueOf(galaxyCoin));
  58. BigDecimal finalRecordGalaxyCoin = BigDecimal.valueOf(galaxyCoin);
  59. //不足部分 只扣除用户已有的银河币
  60. if (needHandleGalaxyCoin.compareTo(BigDecimal.ZERO) < 0) {
  61. needHandleGalaxyCoin = BigDecimal.ZERO;
  62. //记录该笔银河币
  63. if (finalRecordGalaxyCoin.compareTo(BigDecimal.ZERO) < 0) {
  64. finalRecordGalaxyCoin = userGalaxyCoin.negate();
  65. } else finalRecordGalaxyCoin = userGalaxyCoin;
  66. }
  67. int update = userMapper.update(null, Wrappers.lambdaUpdate(User.class)
  68. .set(User::getGalaxyCoin, needHandleGalaxyCoin)
  69. .eq(User::getId, user.getId())
  70. .eq(User::getGalaxyCoin, userGalaxyCoin));
  71. if (update == 1) {
  72. if (isRecord) {
  73. recordUseRecord(orderId, userId, finalRecordGalaxyCoin, remark, available, source);
  74. }
  75. break;
  76. }
  77. }
  78. }
  79. /**
  80. * 记录银河币详情
  81. */
  82. @Override
  83. public void recordUseRecord(Long orderId, Long userId, BigDecimal galaxyCoin, String remark, Boolean available, OrderDonGalaxyCoinRecord.Source source) {
  84. UserGalaxyCoinRecord userGalaxyCoinRecord = new UserGalaxyCoinRecord();
  85. userGalaxyCoinRecord.setOrderId(orderId);
  86. userGalaxyCoinRecord.setUserId(userId);
  87. userGalaxyCoinRecord.setGalaxyCoin(galaxyCoin);
  88. userGalaxyCoinRecord.setRemainGalaxyCoin(userGalaxyCoinRecord.getGalaxyCoin());
  89. //退款类型
  90. if (StrUtil.equals(PointsRecordConst.ORDER_REFUND, remark)) {
  91. //90天
  92. userGalaxyCoinRecord.setExpiryTime(DateUtil.offsetDay(DateTime.now(), 90));
  93. } else {
  94. //年底失效
  95. userGalaxyCoinRecord.setExpiryTime(DateUtil.endOfYear(DateTime.now()));
  96. }
  97. //下单 标记该笔银河币记录为已使用
  98. //该银河币是否可用
  99. if (!available) {
  100. userGalaxyCoinRecord.setIsUsed(Boolean.TRUE);
  101. //下单时,剩余是0
  102. userGalaxyCoinRecord.setRemainGalaxyCoin(BigDecimal.ZERO);
  103. }
  104. if (source != null) {
  105. userGalaxyCoinRecord.setSource(source.ordinal());
  106. }
  107. userGalaxyCoinRecord.setRemark(remark);
  108. userGalaxyCoinRecordMapper.insert(userGalaxyCoinRecord);
  109. }
  110. @Override
  111. public void recordOrderRefundGalaxyCoinIfValid(Long orderId, Long userId, BigDecimal galaxyCoin, OrderDonGalaxyCoinRecord.Source source) {
  112. UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
  113. .eq(UserGalaxyCoinRecord::getOrderId, orderId)
  114. .eq(UserGalaxyCoinRecord::getRemark, PointsRecordConst.ORDER)
  115. .last("limit 1"));
  116. if (userGalaxyCoinRecord == null) {
  117. log.info("订单:{}银河币使用记录不存在", orderId);
  118. return;
  119. }
  120. if (userGalaxyCoinRecord.getExpiryTime().compareTo(DateTime.now()) < 0) {
  121. log.info("该笔订单:{}银河币有效期:{}已过", orderId, userGalaxyCoinRecord.getExpiryTime());
  122. return;
  123. }
  124. //发送银河币
  125. sendGalaxyCoinHandle(userId, orderId, galaxyCoin.intValue(), PointsRecordConst.ORDER_REFUND, true, true, source);
  126. }
  127. @Override
  128. public void subOrderGenerateGalaxyCoin(Long orderId, OrderDonGalaxyCoinRecord.Source source) {
  129. UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
  130. .eq(UserGalaxyCoinRecord::getOrderId, orderId)
  131. .eq(UserGalaxyCoinRecord::getSource, source.ordinal())
  132. .eq(UserGalaxyCoinRecord::getRemark, PointsRecordConst.ORDER_CASHBACK)
  133. .last("limit 1"));
  134. if (userGalaxyCoinRecord != null) {
  135. BigDecimal galaxyCoin = userGalaxyCoinRecord.getGalaxyCoin();
  136. //扣除记录 对应的银河币不可用
  137. log.info("订单退款,扣除该笔订单oid:{}返现的银河币", orderId);
  138. sendGalaxyCoinHandle(userGalaxyCoinRecord.getUserId(), orderId, galaxyCoin.negate().intValue(), PointsRecordConst.ORDER_REFUND_SUB, true, false, source);
  139. userGalaxyCoinRecord.setIsUsed(Boolean.TRUE);
  140. userGalaxyCoinRecordMapper.updateById(userGalaxyCoinRecord);
  141. }
  142. }
  143. /**
  144. * 订单回调时,扣除已使用的银河币 并记录使用记录
  145. */
  146. @Override
  147. public void handleUserGalaxyCoinOrderNotify(Long orderId, Long userId, String orderNo, OrderDonGalaxyCoinRecord.Source source) {
  148. //银河币使用记录
  149. OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class)
  150. .eq(OrderDonGalaxyCoinRecord::getOrderNo, orderNo)
  151. .eq(OrderDonGalaxyCoinRecord::getSource, source.ordinal())
  152. .last("limit 1"));
  153. if (orderDonGalaxyCoinRecord != null) {
  154. //使用记录
  155. recordUseRecord(orderId, userId, orderDonGalaxyCoinRecord.getGalaxyCoin().negate(), PointsRecordConst.ORDER, false, source);
  156. orderDonGalaxyCoinRecord.setRefundGalaxyCoin(orderDonGalaxyCoinRecord.getGalaxyCoin());
  157. orderDonGalaxyCoinRecord.setOrderId(orderId);
  158. orderDonGalaxyCoinRecordMapper.updateById(orderDonGalaxyCoinRecord);
  159. }
  160. }
  161. /**
  162. * 订单支付成功 返银河币
  163. */
  164. @Override
  165. public void sendOrderCashback(Long orderId, Long userId, Integer galaxyCoin, String remark, OrderDonGalaxyCoinRecord.Source source) {
  166. sendGalaxyCoinHandle(userId, orderId, galaxyCoin, remark, true, true, source);
  167. }
  168. public void sendOrderGalaxyCloseOrder(Long orderId, Long userId, BigDecimal galaxyCoin, OrderDonGalaxyCoinRecord.Source source) {
  169. sendGalaxyCoinHandle(userId, orderId, galaxyCoin.intValue(), PointsRecordConst.ORDER_CLOSE, true, true, source);
  170. }
  171. }