Pārlūkot izejas kodu

增加用户商户还款接口

FengChaoYu 1 nedēļu atpakaļ
vecāks
revīzija
76ede6a1b1

+ 28 - 4
mall-server-api/src/main/java/com/gree/mall/manager/controller/member/UserCompanyCreditController.java

@@ -6,21 +6,25 @@ import com.gree.mall.manager.annotation.ZfireList;
 import com.gree.mall.manager.bean.listvo.UserCustomerVO;
 import com.gree.mall.manager.bean.user.UserCompanyCreditBillItemVO;
 import com.gree.mall.manager.bean.user.UserCompanyCreditBillVO;
+import com.gree.mall.manager.constant.Constant;
 import com.gree.mall.manager.helper.ResponseHelper;
 import com.gree.mall.manager.logic.user.UserCompanyCreditLogic;
+import com.gree.mall.manager.plus.entity.Storage;
 import com.gree.mall.manager.zfire.bean.ZfireParamBean;
 import com.gree.mall.manager.zfire.util.FieldUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.integration.redis.util.RedisLockRegistry;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
 
 @Slf4j
 @RestController
@@ -30,6 +34,8 @@ public class UserCompanyCreditController {
 
     @Resource
     UserCompanyCreditLogic userCompanyCreditLogic;
+    @Resource
+    RedisLockRegistry redisLockRegistry;
 
     @ZfireList
     @PostMapping("/list")
@@ -76,4 +82,22 @@ public class UserCompanyCreditController {
         //3.导出
         FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
     }
+
+
+    @PostMapping("/repay")
+    @ApiOperation(value = "恢复商户授信额度")
+    public ResponseHelper repay(
+            @ApiParam(value = "账单", required = true) @RequestParam String billId,
+            @ApiParam(value = "还款金额", required = true) @RequestParam BigDecimal amount) throws Exception {
+        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_COMMON + billId);
+        if(!obtain.tryLock(10, TimeUnit.SECONDS)){
+            return ResponseHelper.error("系统繁忙,请稍后再试");
+        }
+        try {
+            userCompanyCreditLogic.billRepay(billId, amount);
+            return ResponseHelper.success();
+        }finally {
+            obtain.unlock();
+        }
+    }
 }

+ 40 - 3
mall-server-api/src/main/java/com/gree/mall/manager/logic/user/UserCompanyCreditLogic.java

@@ -16,7 +16,9 @@ import com.gree.mall.manager.exception.RemoteServiceException;
 import com.gree.mall.manager.logic.common.CommonLogic;
 import com.gree.mall.manager.plus.entity.OrderInfo;
 import com.gree.mall.manager.plus.entity.UserCompanyCredit;
+import com.gree.mall.manager.plus.entity.UserCompanyCreditBill;
 import com.gree.mall.manager.plus.entity.UserCompanyCreditBillItem;
+import com.gree.mall.manager.plus.service.UserCompanyCreditBillService;
 import com.gree.mall.manager.plus.service.UserCompanyCreditService;
 import com.gree.mall.manager.zfire.bean.ZfireParamBean;
 import com.gree.mall.manager.zfire.util.FieldUtils;
@@ -25,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.integration.redis.util.RedisLockRegistry;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
 import org.springframework.transaction.support.TransactionSynchronizationManager;
 
@@ -43,6 +46,7 @@ public class UserCompanyCreditLogic {
     private final RedisLockRegistry redisLockRegistry;
     private final LockQueryMapper lockQueryMapper;
     private final UserCompanyCreditService userCompanyCreditService;
+    private final UserCompanyCreditBillService userCompanyCreditBillService;
 
     public IPage<UserCompanyCreditBillVO> list(ZfireParamBean zfireParamBean) {
         AdminUserCom adminUser = commonLogic.getAdminUser();
@@ -63,6 +67,40 @@ public class UserCompanyCreditLogic {
     }
 
     /**
+     * 账单还款
+     * @param billId
+     * @param amount
+     */
+    @Transactional
+    public void billRepay(String billId, BigDecimal amount) throws Exception {
+        AdminUserCom adminUser = commonLogic.getAdminUser();
+        UserCompanyCreditBill creditBill = userCompanyCreditBillService.getById(billId);
+        if (!creditBill.getCompanyWechatId().equals(adminUser.getCompanyWechatId())) {
+            throw new RemoteServiceException("请使用商户账号");
+        }
+        if (creditBill.getIsPaid()) {
+            throw new RemoteServiceException(billId + "账单已还款");
+        }
+
+        // 判断还款金额是否大于剩余未还
+        if (amount.compareTo(creditBill.getRemainingAmount()) > 0) {
+            throw new RemoteServiceException("还款金额不能大于剩余未还金额");
+        }
+
+        // 剩余未还金额 - 还款金额 = (新)剩余未还金额
+        final BigDecimal newRemainingAmount = creditBill.getRemainingAmount().subtract(amount);
+
+        // 恢复使用额度
+        this.repay(null, creditBill.getUserId(), creditBill.getCompanyWechatId(), amount);
+
+        // 更新账单
+        creditBill.setIsPaid(newRemainingAmount.compareTo(BigDecimal.ZERO) == 0)
+                .setRemainingAmount(newRemainingAmount)
+                .updateById();
+
+    }
+
+    /**
      * 授信订单退款
      * @param orderInfo
      */
@@ -80,13 +118,13 @@ public class UserCompanyCreditLogic {
         }
         Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_USER_COMPANY_CREDIT + userId + ":" + companyWechatId);
         if(!obtain.tryLock(10, TimeUnit.SECONDS)){
-            throw new RemoteServiceException("订单操作过于频繁, 请稍后再试");
+            throw new RemoteServiceException("操作过于频繁, 请稍后再试");
         }
         // 处理授信
         try{
             // 验证金额
             if (Objects.isNull(amount) || amount.compareTo(BigDecimal.ZERO) <= 0) {
-                throw new RemoteServiceException("还示金额必须大于0");
+                throw new RemoteServiceException(StringUtils.isBlank(orderId) ? "还款" : "退款" + "金额必须大于0");
             }
 
             final UserCompanyCredit userCompanyCredit = lockQueryMapper.queryExistUserCompanyCredit(companyWechatId, userId);
@@ -149,5 +187,4 @@ public class UserCompanyCreditLogic {
         }
     }
 
-
 }

+ 46 - 0
mall-server-api/src/main/java/com/gree/mall/manager/schedule/UserCompanyCreditBillSchedule.java

@@ -0,0 +1,46 @@
+package com.gree.mall.manager.schedule;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.gree.mall.manager.enums.workorder.OrderBaseStatusEnum;
+import com.gree.mall.manager.plus.entity.PgOrderBase;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户商户授信账单相关定时任务
+ * @author :fengcy
+ * @description:TODO
+ * @date :2025/10/21 17:30
+ */
+@ConditionalOnProperty(name = "schedule.enable", havingValue = "true", matchIfMissing = true)
+@Component
+@Slf4j
+public class UserCompanyCreditBillSchedule {
+
+    /**
+     * 每日凌晨1点执行,检查是否有用户需要在当天生成账单
+     */
+    @Transactional
+    @Scheduled(cron = "0 0 1 * * ?")
+    public void generateBillsOnBillingDay(){
+        DateTime curDate = DateUtil.date();
+        int currentDay = curDate.dayOfMonth();
+
+        // 处理月末特殊情况
+        if (currentDay == DateUtil.endOfMonth(curDate).dayOfMonth()) {
+            currentDay = 29;
+        }
+
+        // 获取账单日为今天的所有用户商户授信关系
+
+    }
+}