1
dd
2025-10-21 8dcc757d17dd3bed804167a0aa640a978f10022c
ruoyi-admin/src/main/java/com/ruoyi/web/controller/product/UserPolicyController.java
@@ -18,10 +18,15 @@
import com.ruoyi.im.util.UserPolicyUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.dto.PayCallbackDTO;
import com.ruoyi.system.domain.dto.SubordinateInformationDto;
import com.ruoyi.system.domain.dto.UserPolicyDto;
import com.ruoyi.im.service.UserPolicyService;
import com.ruoyi.system.domain.out.UserTeamAndPositionOut;
import com.ruoyi.system.service.FundsLogService;
import com.ruoyi.system.service.PaymentRecordService;
import com.ruoyi.system.service.UserAccountService;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
@@ -62,8 +67,12 @@
    @Autowired
    InsuranceProductService insuranceProductService;
    @Autowired
    private PayService payService;
    PaymentRecordService paymentRecordService;
    @Autowired
    FundsLogService fundsLogService;
    @Value("${pay.key}")
    private String key;
@@ -73,33 +82,54 @@
     */
    @PostMapping("/purchaseApplication")
    public Result purchaseApplication(UserPolicyDto dto) {
        // 生成锁的key:基于用户ID和产品ID,防止同一用户同时购买同一产品
        String lockKey = redisDistributedLock.generateLockKey(dto.getAccount(), dto.getProductId());
        synchronized (dto.getAccount()) {
            // 生成锁的key:基于用户ID和产品ID,防止同一用户同时购买同一产品
            String lockKey = redisDistributedLock.generateLockKey(dto.getAccount(), dto.getProductId());
        boolean lockAcquired = false;
        try {
            // 尝试获取分布式锁:等待10秒,锁过期30秒
            lockAcquired = redisDistributedLock.tryLock(lockKey, 30L, 10L);
            boolean lockAcquired = false;
            try {
                // 尝试获取分布式锁:等待10秒,锁过期30秒
                lockAcquired = redisDistributedLock.tryLock(lockKey, 30L, 10L);
            if (!lockAcquired) {
                return Result.error("操作过于频繁,请稍后重试");
            }
                if (!lockAcquired) {
                    return Result.error("操作过于频繁,请稍后重试");
                }
            // 执行购买逻辑
            return userPolicyService.purchaseApplication(dto);
                // 执行购买逻辑
                return userPolicyService.purchaseApplication(dto);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("购买失败");
        } finally {
            // 释放锁
            if (lockAcquired) {
                redisDistributedLock.releaseLock(lockKey);
            } catch (Exception e) {
                e.printStackTrace();
                return Result.error("购买失败");
            } finally {
                // 释放锁
                if (lockAcquired) {
                    redisDistributedLock.releaseLock(lockKey);
                }
            }
        }
    }
    /**
     * 根据用户id查询保单
     */
    @GetMapping("/updateGender")
    public AjaxResult updateGender(@RequestParam(value = "id") Integer id,@RequestParam(value = "gender") UserPolicy.Gender gender) {
        try {
            UserPolicy userPolicy = userPolicyService.getById(id);
            if(ObjectUtil.isEmpty(userPolicy)){
                AjaxResult.error("保单不存在!");
            }
            userPolicy.setGender(gender);
            userPolicyService.updateById(userPolicy);
            return AjaxResult.success("修改成功");
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error("修改失败!");
        }
    }
    /**
     * 根据用户id查询保单
@@ -112,6 +142,7 @@
            List<UserPolicy> list = userPolicyService.list(new LambdaQueryWrapper<UserPolicy>()
                    .eq(UserPolicy::getUserId, userAccount.getId())
                    .eq(UserPolicy::getPayStatus,2)
                    .eq(UserPolicy::getApprovalStatus,1)
            );
            return Result.success(list);
        }catch (Exception e){
@@ -158,6 +189,34 @@
    /**
     * 支付记录列表
     */
    @GetMapping("/PaymentRecordList")
    public TableDataInfo PaymentRecordList( @RequestParam(value = "account",required = false)  String account,
            @RequestParam(value = "payOrdeNo",required = false)  String payOrdeNo,
                                           @RequestParam(value = "paymentStatus",required = false)  Integer paymentStatus) {
        startPage();
        LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(account)) {
            wrapper.eq(PaymentRecord::getAccount, account);
        }
        // 产品名称模糊查询
        if (StringUtils.isNotEmpty(payOrdeNo)) {
            wrapper.eq(PaymentRecord::getPayOrdeNo, payOrdeNo);
        }
        if (paymentStatus != null) {
            wrapper.eq(PaymentRecord::getPaymentStatus, paymentStatus);
        }
        // 按创建时间倒序排列
        wrapper.orderByDesc(PaymentRecord::getCreateTime);
        List<PaymentRecord> list = paymentRecordService.list(wrapper);
        return getDataTable(list);
    }
    /**
     * 保单审批
     */
    @GetMapping("/examine")
@@ -188,16 +247,21 @@
                userAccount.setBalance(userAccount.getBalance().add(userPolicy.getPremium()));
                userAccountService.updateById(userAccount);
                fundsLogService.addLog(userAccount.getId(), userAccount.getAccount(), userPolicy.getPremium(), OperationType.REFUND);
                return AjaxResult.success("审批成功");
            }
            //计算到期时间
            LocalDate expirationTime = calculateInsuranceEndDateToDay(LocalDate.now(), userPolicy.getTerm());
            LocalDate expirationTime = calculateInsuranceEndDate(LocalDate.now(), userPolicy.getTerm());
            //保险金领取到期时间
            LocalDate insuranceBenefitExpiryDate = calculateInsuranceEndDateToDay(LocalDate.now(), userPolicy.getNumberDays());
            userPolicy.setApprovalStatus(approvalStatus);
            userPolicy.setMessage(message);
            userPolicy.setStartDate(LocalDate.now());
            userPolicy.setEndDate(expirationTime);
            userPolicy.setEndDate(expirationTime.minusDays(1));
            userPolicy.setInsuranceBenefitExpiryDate(insuranceBenefitExpiryDate);
            userPolicy.setPolicyStatus(UserPolicy.PolicyStatus.ACTIVE);
            userPolicy.setUpdatedAt(new Date());
            userPolicyService.updateById(userPolicy);
@@ -205,7 +269,7 @@
            //每天可领
            BigDecimal amountClaimed = userPolicy.getCoverageAmount()
                    .divide(new BigDecimal(userPolicy.getTerm()), 4, RoundingMode.HALF_UP);
                    .divide(new BigDecimal(userPolicy.getNumberDays()), 4, RoundingMode.HALF_UP);
            MedicalInsuranceAccount medicalInsuranceAccount = new MedicalInsuranceAccount();
            medicalInsuranceAccount.setUserId(userPolicy.getUserId());
@@ -217,6 +281,7 @@
            medicalInsuranceAccount.setAlreadyReceived(BigDecimal.ZERO);
            medicalInsuranceAccount.setAmountAlreadyUsed(BigDecimal.ZERO);
            medicalInsuranceAccount.setEffectiveDate(userPolicy.getStartDate());
            medicalInsuranceAccount.setInsuranceBenefitExpiryDate(userPolicy.getInsuranceBenefitExpiryDate());
            medicalInsuranceAccount.setExpiryDate(userPolicy.getEndDate());
            medicalInsuranceAccount.setAccountStatus(MedicalInsuranceAccount.AccountStatus.ACTIVE);
            medicalInsuranceAccount.setCreatedAt(new Date());
@@ -273,7 +338,7 @@
    }
    /**
     * 计算保险到期日
     * 计算保险到期日按天
     * @param startDate 保险开始日期
     * @param termDays 保险天数
     * @return 保险到期日期
@@ -427,7 +492,13 @@
        userPolicy.setUpdatedAt(new Date());
        boolean updateResult = userPolicyService.updateById(userPolicy);
        PaymentRecord paymentRecord = paymentRecordService.getOne(new LambdaQueryWrapper<PaymentRecord>()
                .eq(PaymentRecord::getPayOrdeNo, callbackDTO.getOrderId())
        );
        if(ObjectUtil.isNotEmpty(paymentRecord)){
            paymentRecord.setPaymentStatus(PaymentRecord.PaymentStatus.PAID.getCode());
            paymentRecordService.updateById(paymentRecord);
        }
        if (updateResult) {
            log.info("支付成功处理完成: {}", callbackDTO.getOrderId());
            return true;
@@ -443,7 +514,13 @@
        userPolicy.setUpdatedAt(new Date());
        boolean updateResult = userPolicyService.updateById(userPolicy);
        PaymentRecord paymentRecord = paymentRecordService.getOne(new LambdaQueryWrapper<PaymentRecord>()
                .eq(PaymentRecord::getPayOrdeNo, callbackDTO.getOrderId())
        );
        if(ObjectUtil.isNotEmpty(paymentRecord)){
            paymentRecord.setPaymentStatus(PaymentRecord.PaymentStatus.EXPIRED.getCode());
            paymentRecordService.updateById(paymentRecord);
        }
        if (updateResult) {
            log.info("支付超时处理完成: {}", callbackDTO.getOrderId());
            return true;
@@ -471,4 +548,50 @@
            throw new RuntimeException("MD5加密失败", e);
        }
    }
    /**
     * 保单列表
     */
    @GetMapping("/deleteRecordById")
    public AjaxResult PaymentRecordList(@RequestParam(value = "id",required = false)  Integer id) {
        // 查询所有创建时间超过5分钟且状态为待支付的订单
        PaymentRecord byId = paymentRecordService.getById(id);
        if(ObjectUtil.isEmpty(byId)){
            return AjaxResult.error("订单不存在!");
        }
        if(byId.getPaymentStatus() == 2){
            return AjaxResult.error("订单已支付,禁止删除");
        }
        UserPolicy userPolicy = userPolicyService.getById(byId.getOrderId());
        if(ObjectUtil.isEmpty(userPolicy)){
            return AjaxResult.error("保单不存在!");
        }
        if(userPolicy.getPayStatus() == 2){
            return AjaxResult.error("订单已支付,禁止删除");
        }
        paymentRecordService.removeById(byId);
        userPolicyService.removeById(userPolicy);
        return AjaxResult.success("删除成功");
    }
    /**
     * 保单列表
     */
    @GetMapping("/getFundsLogList")
    public TableDataInfo getFundsLogList(@RequestParam(value = "account",required = false)  String account,@RequestParam(value = "operationType",required = false)  Integer operationType) {
        startPage();
        LambdaQueryWrapper<FundsLog> wrapper = new LambdaQueryWrapper<>();
       if(StringUtils.isNotEmpty(account)){
           wrapper.eq(FundsLog::getAccount,account);
       }
       if (ObjectUtil.isNotEmpty(operationType)){
           wrapper.eq(FundsLog::getOperationType,operationType);
       }
        wrapper.orderByDesc(FundsLog::getCreateTime);
        List<FundsLog> list = fundsLogService.list(wrapper);
        return getDataTable(list);
    }
}