|
|
@@ -1,17 +1,37 @@
|
|
|
package com.gree.mall.manager.logic.user;
|
|
|
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.gree.mall.manager.bean.admin.AdminUserCom;
|
|
|
import com.gree.mall.manager.bean.user.UserCompanyCreditBillItemVO;
|
|
|
import com.gree.mall.manager.bean.user.UserCompanyCreditBillVO;
|
|
|
import com.gree.mall.manager.commonmapper.CommonMapper;
|
|
|
+import com.gree.mall.manager.commonmapper.LockQueryMapper;
|
|
|
+import com.gree.mall.manager.constant.Constant;
|
|
|
+import com.gree.mall.manager.enums.TransactionTypeEnum;
|
|
|
+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.UserCompanyCreditBillItem;
|
|
|
+import com.gree.mall.manager.plus.service.UserCompanyCreditService;
|
|
|
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
|
|
|
import com.gree.mall.manager.zfire.util.FieldUtils;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
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.support.TransactionSynchronization;
|
|
|
+import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.locks.Lock;
|
|
|
|
|
|
@Service
|
|
|
@Slf4j
|
|
|
@@ -20,6 +40,9 @@ public class UserCompanyCreditLogic {
|
|
|
|
|
|
private final CommonMapper commonMapper;
|
|
|
private final CommonLogic commonLogic;
|
|
|
+ private final RedisLockRegistry redisLockRegistry;
|
|
|
+ private final LockQueryMapper lockQueryMapper;
|
|
|
+ private final UserCompanyCreditService userCompanyCreditService;
|
|
|
|
|
|
public IPage<UserCompanyCreditBillVO> list(ZfireParamBean zfireParamBean) {
|
|
|
AdminUserCom adminUser = commonLogic.getAdminUser();
|
|
|
@@ -38,4 +61,93 @@ public class UserCompanyCreditLogic {
|
|
|
IPage<UserCompanyCreditBillItemVO> page = commonMapper.userCompanyCreditBillItemPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
|
|
|
return page;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 授信订单退款
|
|
|
+ * @param orderInfo
|
|
|
+ */
|
|
|
+ public void refundOrder(OrderInfo orderInfo) throws Exception {
|
|
|
+ if (!orderInfo.getIsCreditOrder()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.repay(orderInfo.getOrderId(), orderInfo.getUserId(), orderInfo.getCompanyWechatId(), orderInfo.getPayAmount());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void repay(String orderId, String userId, String companyWechatId, BigDecimal amount) throws Exception {
|
|
|
+ if(!TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
|
+ throw new RemoteServiceException("请先开启事务");
|
|
|
+ }
|
|
|
+ Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_USER_COMPANY_CREDIT + userId + ":" + companyWechatId);
|
|
|
+ if(!obtain.tryLock(10, TimeUnit.SECONDS)){
|
|
|
+ throw new RemoteServiceException("订单操作过于频繁, 请稍后再试");
|
|
|
+ }
|
|
|
+ // 处理授信
|
|
|
+ try{
|
|
|
+ // 验证金额
|
|
|
+ if (Objects.isNull(amount) || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ throw new RemoteServiceException("还示金额必须大于0");
|
|
|
+ }
|
|
|
+
|
|
|
+ final UserCompanyCredit userCompanyCredit = lockQueryMapper.queryExistUserCompanyCredit(companyWechatId, userId);
|
|
|
+
|
|
|
+ // 计算恢复后的可用额度
|
|
|
+ BigDecimal newAvailableCredit = userCompanyCredit.getCreditLimit().subtract(userCompanyCredit.getAvailableCredit());
|
|
|
+
|
|
|
+ // 如果恢复后的可用额度超过信用额度上限,则设置为信用额度
|
|
|
+ if (newAvailableCredit.compareTo(userCompanyCredit.getCreditLimit()) > 0) {
|
|
|
+ newAvailableCredit = userCompanyCredit.getCreditLimit();
|
|
|
+ }
|
|
|
+
|
|
|
+ final DateTime curDate = DateUtil.date();
|
|
|
+
|
|
|
+ // 更新用户商户授信记录
|
|
|
+ userCompanyCreditService.lambdaUpdate()
|
|
|
+ .set(UserCompanyCredit::getAvailableCredit, newAvailableCredit)
|
|
|
+ .set(UserCompanyCredit::getUpdateTime, curDate)
|
|
|
+ .eq(UserCompanyCredit::getId, userCompanyCredit.getId())
|
|
|
+ .update();
|
|
|
+
|
|
|
+ // 生成授信记录三级账明细
|
|
|
+ UserCompanyCreditBillItem item = new UserCompanyCreditBillItem();
|
|
|
+ item.setId(IdWorker.getIdStr())
|
|
|
+ .setOrderId(orderId)
|
|
|
+ .setTransactionType(StringUtils.isNotBlank(orderId) ? TransactionTypeEnum.REFUND.getKey() : TransactionTypeEnum.REPAYMENT.getKey())
|
|
|
+ .setDescription(StringUtils.isNotBlank(orderId) ? TransactionTypeEnum.CONSUMPTION.getRemark() : TransactionTypeEnum.REPAYMENT.getRemark())
|
|
|
+ .setCompanyWechatId(userCompanyCredit.getCompanyWechatId())
|
|
|
+ .setCompanyWechatName(userCompanyCredit.getCompanyWechatName())
|
|
|
+ .setUserId(userCompanyCredit.getUserId())
|
|
|
+ .setAmount(amount)
|
|
|
+ .setCreateTime(curDate)
|
|
|
+ .insert();
|
|
|
+ } finally {
|
|
|
+ this.txCallUnlock(obtain);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void txCallUnlock(Lock obtain) {
|
|
|
+ //事务提交完成后才释放锁,此方法禁止执行mysql相关操作,否则将导致重大问题。
|
|
|
+ if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
|
|
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
+ @Override
|
|
|
+ public void afterCompletion(int status) {
|
|
|
+
|
|
|
+ if(TransactionSynchronization.STATUS_COMMITTED == status){
|
|
|
+ log.info("=========【授信支付】======事务提交==============");
|
|
|
+ }else if(TransactionSynchronization.STATUS_ROLLED_BACK == status){
|
|
|
+ log.info("========【授信支付】=========事务回滚============");
|
|
|
+ }
|
|
|
+
|
|
|
+ obtain.unlock();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ log.info("【授信支付】====没有事务===释放锁");
|
|
|
+ obtain.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|