package com.cyksj.service.coin.impl; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.constant.PointsRecordConst; import com.cyksj.mapper.OrderDonGalaxyCoinRecordMapper; import com.cyksj.mapper.UserGalaxyCoinRecordMapper; import com.cyksj.mapper.UserMapper; import com.cyksj.model.entity.OrderDonGalaxyCoinRecord; import com.cyksj.model.entity.User; import com.cyksj.model.entity.UserGalaxyCoinRecord; import com.cyksj.service.coin.UserGalaxyCoinService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * 项目名: yhlxj * 文件名: UserGalaxyCoinServiceImpl * 创建者: JavaZou * 创建时间:2025/7/1 15:29 */ @Service @RequiredArgsConstructor @Slf4j public class UserGalaxyCoinServiceImpl implements UserGalaxyCoinService { private final UserGalaxyCoinRecordMapper userGalaxyCoinRecordMapper; private final UserMapper userMapper; private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper; @Override public void sendGalaxyCoinRecord(Long userId, Integer galaxyCoin, String remark, Boolean isLottery) { if (!isLottery) { sendGalaxyCoinHandle(userId, null, galaxyCoin, remark, true, true, null); } } /** * @param isRecord 是否记录 * @param available 该笔银河币是否可用 */ public void sendGalaxyCoinHandle(Long userId, Long orderId, Integer galaxyCoin, String remark, Boolean isRecord, Boolean available, OrderDonGalaxyCoinRecord.Source source) { //银河币为0不处理 if (galaxyCoin == 0) { return; } while (true) { User user = userMapper.selectById(userId); if (user == null) { log.error("用户:{}不存在,无法发送银河币", userId); break; } BigDecimal userGalaxyCoin = user.getGalaxyCoin(); if (galaxyCoin < 0 && userGalaxyCoin.compareTo(BigDecimal.ZERO) == 0) { log.info("用户:{}银河币数量为0,无法扣除", userId); break; } BigDecimal needHandleGalaxyCoin = userGalaxyCoin.add(BigDecimal.valueOf(galaxyCoin)); BigDecimal finalRecordGalaxyCoin = BigDecimal.valueOf(galaxyCoin); //不足部分 只扣除用户已有的银河币 if (needHandleGalaxyCoin.compareTo(BigDecimal.ZERO) < 0) { needHandleGalaxyCoin = BigDecimal.ZERO; //记录该笔银河币 if (finalRecordGalaxyCoin.compareTo(BigDecimal.ZERO) < 0) { finalRecordGalaxyCoin = userGalaxyCoin.negate(); } else finalRecordGalaxyCoin = userGalaxyCoin; } int update = userMapper.update(null, Wrappers.lambdaUpdate(User.class) .set(User::getGalaxyCoin, needHandleGalaxyCoin) .eq(User::getId, user.getId()) .eq(User::getGalaxyCoin, userGalaxyCoin)); if (update == 1) { if (isRecord) { recordUseRecord(orderId, userId, finalRecordGalaxyCoin, remark, available, source); } break; } } } /** * 记录银河币详情 */ @Override public void recordUseRecord(Long orderId, Long userId, BigDecimal galaxyCoin, String remark, Boolean available, OrderDonGalaxyCoinRecord.Source source) { UserGalaxyCoinRecord userGalaxyCoinRecord = new UserGalaxyCoinRecord(); userGalaxyCoinRecord.setOrderId(orderId); userGalaxyCoinRecord.setUserId(userId); userGalaxyCoinRecord.setGalaxyCoin(galaxyCoin); userGalaxyCoinRecord.setRemainGalaxyCoin(userGalaxyCoinRecord.getGalaxyCoin()); //退款类型 if (StrUtil.equals(PointsRecordConst.ORDER_REFUND, remark)) { //90天 userGalaxyCoinRecord.setExpiryTime(DateUtil.offsetDay(DateTime.now(), 90)); } else { //年底失效 userGalaxyCoinRecord.setExpiryTime(DateUtil.endOfYear(DateTime.now())); } //下单 标记该笔银河币记录为已使用 //该银河币是否可用 if (!available) { userGalaxyCoinRecord.setIsUsed(Boolean.TRUE); //下单时,剩余是0 userGalaxyCoinRecord.setRemainGalaxyCoin(BigDecimal.ZERO); } if (source != null) { userGalaxyCoinRecord.setSource(source.ordinal()); } userGalaxyCoinRecord.setRemark(remark); userGalaxyCoinRecordMapper.insert(userGalaxyCoinRecord); } @Override public void recordOrderRefundGalaxyCoinIfValid(Long orderId, Long userId, BigDecimal galaxyCoin, OrderDonGalaxyCoinRecord.Source source) { UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class) .eq(UserGalaxyCoinRecord::getOrderId, orderId) .eq(UserGalaxyCoinRecord::getRemark, PointsRecordConst.ORDER) .last("limit 1")); if (userGalaxyCoinRecord == null) { log.info("订单:{}银河币使用记录不存在", orderId); return; } if (userGalaxyCoinRecord.getExpiryTime().compareTo(DateTime.now()) < 0) { log.info("该笔订单:{}银河币有效期:{}已过", orderId, userGalaxyCoinRecord.getExpiryTime()); return; } //发送银河币 sendGalaxyCoinHandle(userId, orderId, galaxyCoin.intValue(), PointsRecordConst.ORDER_REFUND, true, true, source); } @Override public void subOrderGenerateGalaxyCoin(Long orderId, OrderDonGalaxyCoinRecord.Source source) { UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class) .eq(UserGalaxyCoinRecord::getOrderId, orderId) .eq(UserGalaxyCoinRecord::getSource, source.ordinal()) .eq(UserGalaxyCoinRecord::getRemark, PointsRecordConst.ORDER_CASHBACK) .last("limit 1")); if (userGalaxyCoinRecord != null) { BigDecimal galaxyCoin = userGalaxyCoinRecord.getGalaxyCoin(); //扣除记录 对应的银河币不可用 log.info("订单退款,扣除该笔订单oid:{}返现的银河币", orderId); sendGalaxyCoinHandle(userGalaxyCoinRecord.getUserId(), orderId, galaxyCoin.negate().intValue(), PointsRecordConst.ORDER_REFUND_SUB, true, false, source); userGalaxyCoinRecord.setIsUsed(Boolean.TRUE); userGalaxyCoinRecordMapper.updateById(userGalaxyCoinRecord); } } /** * 订单回调时,扣除已使用的银河币 并记录使用记录 */ @Override public void handleUserGalaxyCoinOrderNotify(Long orderId, Long userId, String orderNo, OrderDonGalaxyCoinRecord.Source source) { //银河币使用记录 OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class) .eq(OrderDonGalaxyCoinRecord::getOrderNo, orderNo) .eq(OrderDonGalaxyCoinRecord::getSource, source.ordinal()) .last("limit 1")); if (orderDonGalaxyCoinRecord != null) { //使用记录 recordUseRecord(orderId, userId, orderDonGalaxyCoinRecord.getGalaxyCoin().negate(), PointsRecordConst.ORDER, false, source); orderDonGalaxyCoinRecord.setRefundGalaxyCoin(orderDonGalaxyCoinRecord.getGalaxyCoin()); orderDonGalaxyCoinRecord.setOrderId(orderId); orderDonGalaxyCoinRecordMapper.updateById(orderDonGalaxyCoinRecord); } } /** * 订单支付成功 返银河币 */ @Override public void sendOrderCashback(Long orderId, Long userId, Integer galaxyCoin, String remark, OrderDonGalaxyCoinRecord.Source source) { sendGalaxyCoinHandle(userId, orderId, galaxyCoin, remark, true, true, source); } public void sendOrderGalaxyCloseOrder(Long orderId, Long userId, BigDecimal galaxyCoin, OrderDonGalaxyCoinRecord.Source source) { sendGalaxyCoinHandle(userId, orderId, galaxyCoin.intValue(), PointsRecordConst.ORDER_CLOSE, true, true, source); } }