| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- package com.ylx.giftCard.service.impl;
- import cn.hutool.core.util.ObjectUtil;
- import cn.hutool.core.util.RandomUtil;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
- import com.ylx.common.core.domain.model.WxLoginUser;
- import com.ylx.common.exception.ServiceException;
- import com.ylx.common.utils.DateUtils;
- import com.ylx.giftCard.domain.GiftCard;
- import com.ylx.giftCard.domain.GiftCardOrder;
- import com.ylx.giftCard.enums.GiftCardOrderStatusEnum;
- import com.ylx.giftCard.mapper.GiftCardOrderMapper;
- import com.ylx.giftCard.service.IGiftCardOrderService;
- import com.ylx.massage.domain.TJs;
- import com.ylx.massage.domain.TWxUser;
- import com.ylx.massage.service.TJsService;
- import com.ylx.massage.service.TWxUserService;
- import com.ylx.shopingfundsdetail.domain.vo.ShoppingFundsDetailAddDto;
- import com.ylx.shopingfundsdetail.enums.ShoppingFundsExpenseTypeEnum;
- import com.ylx.shopingfundsdetail.service.ShoppingFundsDetailService;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import javax.annotation.Resource;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- @Slf4j // 添加日志注解
- @Service
- public class GiftCardOrderServiceImpl extends ServiceImpl<GiftCardOrderMapper, GiftCardOrder> implements IGiftCardOrderService {
- @Resource
- private TJsService jsService;
- @Resource
- private TWxUserService wxUserService;
- @Resource
- private ShoppingFundsDetailService shoppingFundsDetailService;
- @Override
- @Transactional(rollbackFor = Exception.class)
- public GiftCardOrder buildOrder(GiftCard card, Integer quantity, String merchantId, WxLoginUser wxLoginUser) {
- // 1. 参数校验
- if (ObjectUtil.isNull(card)) {
- throw new ServiceException("购物卡信息不能为空");
- }
- if (ObjectUtil.isNull(quantity) || quantity <= 0) {
- throw new ServiceException("购买数量必须大于0");
- }
- // 2. 创建订单对象
- GiftCardOrder order = new GiftCardOrder();
- // 4. 生成唯一订单号(使用更安全的方式)
- String orderNo = generateUniqueOrderNo();
- order.setOrderNo(orderNo);
- // 5. 设置购物卡信息
- setGiftCardInfo(order, card);
- // 6. 设置用户信息
- setUserInfo(order, wxLoginUser);
- // 7. 设置商户信息
- setMerchantInfo(order, merchantId);
- // 8. 计算金额
- calculateAmount(order, card, quantity);
- order.setPurchaseQuantity(quantity);
- // 9. 设置订单状态和时间
- order.setStatus(GiftCardOrderStatusEnum.WAIT_PAY.getCode()); // 待支付
- order.setCreateTime(DateUtils.getNowDate());
- order.setUpdateTime(order.getCreateTime());
- int rowsAffected = this.baseMapper.insert(order);
- if (rowsAffected <= 0) {
- log.warn("购物卡订单创建失败,购物卡ID: {},下单人ID: {}", card.getId(), wxLoginUser.getId());
- return null;
- }
- return order;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public void cancelOrder(Long id) {
- // 1. 查询订单
- GiftCardOrder order = this.getById(id);
- if (ObjectUtil.isNull(order)) {
- throw new ServiceException("订单不存在");
- }
- // 仅待支付订单可取消
- if (!GiftCardOrderStatusEnum.PAID.getCode().equals(order.getStatus())) {
- throw new ServiceException("当前订单状态不支持取消");
- }
- // 2. 修改订单状态为已取消
- order.setStatus(GiftCardOrderStatusEnum.CANCEL.getCode());
- order.setUpdateTime(DateUtils.getNowDate());
- boolean update = this.updateById(order);
- if (!update) {
- log.error("订单取消失败,订单号:{}", order.getOrderNo());
- throw new ServiceException("订单取消失败");
- }
- log.info("订单取消成功,订单号:{},购物卡ID:{}", order.getOrderNo(), order.getGiftCardId());
- }
- @Transactional(rollbackFor = Exception.class)
- public void processGiftCardPayment(WxPayOrderNotifyV3Result.DecryptNotifyResult result, TWxUser wxUser,GiftCardOrder cardOrder) {
- // 更新订单状态
- this.lambdaUpdate()
- .set(GiftCardOrder::getStatus, GiftCardOrderStatusEnum.PAID.getCode())
- .eq(GiftCardOrder::getId, cardOrder.getId())
- .update();
- // 计算充值金额
- Integer totalCent = result.getAmount().getTotal();
- BigDecimal payAmount = new BigDecimal(totalCent).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
- // 更新用户余额
- BigDecimal oldBalance = wxUser.getdBalance();
- BigDecimal newBalance = oldBalance.add(payAmount);
- this.wxUserService.lambdaUpdate()
- .set(TWxUser::getdBalance, newBalance)
- .eq(TWxUser::getId, wxUser.getId())
- .update();
- // 记录购物金明细
- ShoppingFundsDetailAddDto dto = new ShoppingFundsDetailAddDto();
- dto.setUserId(wxUser.getId());
- dto.setAmount(payAmount);
- dto.setOrderNo(result.getOutTradeNo());
- dto.setExpenseType(ShoppingFundsExpenseTypeEnum.RECHARGE.getCode());
- dto.setBalance(newBalance);
- dto.setGiftCardId(cardOrder.getGiftCardId());
- shoppingFundsDetailService.addShoppingFundsDetail(dto);
- }
- /**
- * 生成唯一订单号
- */
- private String generateUniqueOrderNo() {
- // 使用时间戳 + 随机数 + 更多信息避免冲突
- long timestamp = System.currentTimeMillis();
- String randomNum = RandomUtil.randomNumbers(6);
- // 可以加入用户ID后几位、线程ID等进一步降低冲突概率
- String suffix = String.valueOf(timestamp % 1000000).substring(0, 3); // 取时间戳后3位
- return "GC" + timestamp + randomNum + suffix;
- }
- /**
- * 设置购物卡信息
- */
- private void setGiftCardInfo(GiftCardOrder order, GiftCard card) {
- order.setGiftCardId(card.getId());
- order.setGiftCardName(card.getName());
- order.setGiftCardAmount(card.getAmount());
- order.setCommissionRate(card.getCommissionRate());
- }
- /**
- * 设置用户信息
- */
- private void setUserInfo(GiftCardOrder order, WxLoginUser wxLoginUser) {
- order.setUserId(wxLoginUser.getId());
- order.setUserName(wxLoginUser.getUsername());
- order.setUserPhone(wxLoginUser.getCPhone());
- }
- /**
- * 设置商户信息
- */
- private void setMerchantInfo(GiftCardOrder order, String merchantId) {
- if (StrUtil.isEmpty(merchantId)) {
- log.warn("商户ID为空,跳过商户信息查询");
- return;
- }
- TJs merchant = this.jsService.getById(merchantId);
- if (ObjectUtil.isNotNull(merchant)) {
- order.setMerchantId(merchantId);
- order.setMerchantName(merchant.getcName());
- order.setMerchantNickName(merchant.getcNickName());
- // 注意:如果 TJs 表有收款账号字段,可以在这里设置
- // order.setMerchantAccount(merchant.getAccount());
- }
- }
- /**
- * 计算金额
- */
- private void calculateAmount(GiftCardOrder order, GiftCard card, Integer quantity) {
- BigDecimal payAmount = card.getAmount()
- .multiply(new BigDecimal(quantity))
- .setScale(2, RoundingMode.HALF_UP); // 保留两位小数
- order.setPayAmount(payAmount);
- BigDecimal commissionAmount = payAmount
- .multiply(card.getCommissionRate())
- .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
- order.setCommissionAmount(commissionAmount);
- }
- }
|