package com.ruoyi.im.service.impl; import cn.hutool.core.util.ObjectUtil; 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.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.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.text.ParseException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; @Service public class UserPolicyServiceImpl extends ServiceImpl implements UserPolicyService { @Autowired InsuranceProductService insuranceProductService; @Autowired UserAccountService userAccountService; @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.ACTIVE) .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){ return Result.error("余额不足!"); } userAccount.setBalance(userAccount.getBalance().subtract(insuranceProduct.getPremium())); 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.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 static final AtomicLong lastTimestamp = new AtomicLong(0); private static final Random random = new Random(); private static final String PREFIX = "POL"; /** * 基于时间毫秒生成唯一保单号 * 格式: POL + 时间戳 + 随机数 * 示例: POL16973512345671234 */ public static 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; } }