package com.ruoyi.im.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil; import com.alibaba.druid.support.json.JSONUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.im.comm.Result; import com.ruoyi.im.service.InsuranceProductService; import com.ruoyi.im.service.UserPolicyService; import com.ruoyi.im.util.PayService; import com.ruoyi.im.util.ValidatorUtil; import com.ruoyi.system.domain.InsuranceProduct; import com.ruoyi.system.domain.UserAccount; import com.ruoyi.system.domain.UserPolicy; import com.ruoyi.system.domain.dto.UserPolicyDto; import com.ruoyi.system.mapper.UserPolicyMapper; import com.ruoyi.system.service.UserAccountService; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.text.ParseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.Map; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; @Service public class UserPolicyServiceImpl extends ServiceImpl implements UserPolicyService { @Autowired InsuranceProductService insuranceProductService; @Autowired UserAccountService userAccountService; @Autowired private PayService payService; @Override @Transactional(rollbackFor = Exception.class) public Result purchaseApplication(UserPolicyDto dto) throws ParseException { UserAccount userAccount = userAccountService.getOne(new LambdaQueryWrapper() .eq(UserAccount::getAccount,dto.getAccount())); if(ObjectUtil.isEmpty(userAccount)){ return Result.error("请重新登录,未查询到你的信息!"); } if(userAccount.getKycStatus() == 2){ return Result.error("请先实名认证"); }else if(userAccount.getKycStatus() == 0){ return Result.error("实名认证审核中,请耐心等等"); } // 验证手机号 boolean isPhoneValid = ValidatorUtil.isValidPhone(dto.getPhone()); if(!isPhoneValid){ return Result.error("手机号格式不正确!"); } long count = count(new LambdaQueryWrapper() .eq(UserPolicy::getUserId, userAccount.getId()) .eq(UserPolicy::getProductId,dto.getProductId()) .eq(UserPolicy::getPolicyStatus, UserPolicy.PolicyStatus.PENDING) .and(a-> a.eq(UserPolicy::getApprovalStatus, 0) .or() .eq(UserPolicy::getApprovalStatus, 1)) ); if(count > 0){ return Result.error("你已申购此保险,请勿重复申购"); } InsuranceProduct insuranceProduct = insuranceProductService.getById(dto.getProductId()); if(ObjectUtil.isEmpty(insuranceProduct)){ return Result.error("该产品停止购买或已下架!"); } if(userAccount.getBalance().compareTo(insuranceProduct.getPremium()) < 0){ String orderNo = generateOrderNo(); String payOrder = payService.createOrder(insuranceProduct.getPremium().multiply(new BigDecimal("100")), orderNo,dto.getPayProductId()); Map parse = (Map) JSONUtils.parse(payOrder); if("0014".equals(parse.get("errCode"))){ return Result.error("当前支付不可用,请更换其他支付方式!"); } if("FAIL".equals(parse.get("retCode"))){ return Result.error("获取支付通道失败!"); } userAccountService.updateById(userAccount); UserPolicy userPolicy = new UserPolicy(); userPolicy.setAccount(userAccount.getAccount()); userPolicy.setProductName(insuranceProduct.getProductName()); userPolicy.setUserId(userAccount.getId()); userPolicy.setProductId(insuranceProduct.getId()); userPolicy.setCoverageAmount(insuranceProduct.getCoverageAmount()); userPolicy.setPremium(insuranceProduct.getPremium()); userPolicy.setTerm(insuranceProduct.getTerm()); userPolicy.setName(dto.getName()); userPolicy.setGender(dto.getGender()); userPolicy.setPayStatus(0); userPolicy.setOrderNo(orderNo); userPolicy.setBirthDate(LocalDate.parse(dto.getBirthDate())); userPolicy.setOccupation(dto.getOccupation()); userPolicy.setIdCard(dto.getIdCard()); userPolicy.setPhone(dto.getPhone()); userPolicy.setPolicyNumber(generatePolicyNumber()); userPolicy.setPolicyStatus(UserPolicy.PolicyStatus.PENDING); userPolicy.setCreatedAt(new Date()); userPolicy.setUpdatedAt(new Date()); userPolicy.setApprovalStatus(0); userPolicy.setIsLifelong(insuranceProduct.getTerm() == 0 ? 0 : 1); save(userPolicy); // 获取 payUrl Object payParamsObj = parse.get("payParams"); if (payParamsObj instanceof Map) { Map payParamsMap = (Map) payParamsObj; String payUrl = (String) payParamsMap.get("payUrl"); if (payUrl != null && !payUrl.trim().isEmpty()) { return Result.success(payUrl); } } return Result.error("支付链接获取失败,请联系客服!"); }else{ userAccount.setBalance(userAccount.getBalance().subtract(insuranceProduct.getPremium())); userAccountService.updateById(userAccount); String orderNo = generateOrderNo(); UserPolicy userPolicy = new UserPolicy(); userPolicy.setAccount(userAccount.getAccount()); userPolicy.setProductName(insuranceProduct.getProductName()); userPolicy.setUserId(userAccount.getId()); userPolicy.setProductId(insuranceProduct.getId()); userPolicy.setCoverageAmount(insuranceProduct.getCoverageAmount()); userPolicy.setPremium(insuranceProduct.getPremium()); userPolicy.setTerm(insuranceProduct.getTerm()); userPolicy.setName(dto.getName()); userPolicy.setGender(dto.getGender()); userPolicy.setPayStatus(2); userPolicy.setOrderNo(orderNo); userPolicy.setBirthDate(LocalDate.parse(dto.getBirthDate())); userPolicy.setOccupation(dto.getOccupation()); userPolicy.setIdCard(dto.getIdCard()); userPolicy.setPhone(dto.getPhone()); userPolicy.setPolicyNumber(generatePolicyNumber()); userPolicy.setPolicyStatus(UserPolicy.PolicyStatus.PENDING); userPolicy.setCreatedAt(new Date()); userPolicy.setUpdatedAt(new Date()); userPolicy.setApprovalStatus(0); userPolicy.setIsLifelong(insuranceProduct.getTerm() == 0 ? 0 : 1); save(userPolicy); return Result.success(); } } private final Random random = new Random(); /** * 生成随机订单号 (格式: 时间戳 + 6位随机数) */ public String generateOrderNo() { long timestamp = System.currentTimeMillis(); int randomNum = random.nextInt(900000) + 100000; // 6位随机数 return "ORDER" + timestamp + randomNum; } /** * 处理支付结果 - 这里您自己实现业务逻辑 */ private void verifySign(String orderNo, String status, String amount, Map params) { // TODO: 在这里实现您的具体业务逻辑 if ("2".equals(status)) { // 支付成功 System.out.println("=== 支付成功 ==="); System.out.println("订单号: " + orderNo); System.out.println("金额: " + amount); System.out.println("================="); // 示例业务逻辑: // 1. 更新订单状态为已支付 // 2. 记录支付时间 // 3. 发放商品或服务 // 4. 发送通知等 } else if ("3".equals(status)) { // 业务处理完成 System.out.println("订单 " + orderNo + " 业务处理完成"); } else { System.out.println("订单 " + orderNo + " 状态: " + status); } } // 使用原子长整型确保线程安全 private static final AtomicLong lastTimestamp = new AtomicLong(0); private static final String PREFIX = "POL"; /** * 基于时间毫秒生成唯一保单号 * 格式: POL + 时间戳 + 随机数 * 示例: POL16973512345671234 */ public String generatePolicyNumber() { long currentTimestamp = System.currentTimeMillis(); long lastTime = lastTimestamp.get(); // 如果时间戳相同,增加序列号 if (currentTimestamp == lastTime) { // 等待下一毫秒 while (currentTimestamp <= lastTime) { currentTimestamp = System.currentTimeMillis(); } } lastTimestamp.set(currentTimestamp); // 生成4位随机数 int randomNum = random.nextInt(10000); String randomStr = String.format("%04d", randomNum); return PREFIX + currentTimestamp + randomStr; } }