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.UserKycService;
|
import com.ruoyi.im.service.UserPolicyService;
|
import com.ruoyi.im.util.PayService;
|
import com.ruoyi.im.util.ValidatorUtil;
|
import com.ruoyi.imenum.PaymentMode;
|
import com.ruoyi.system.domain.*;
|
import com.ruoyi.system.domain.dto.UserPolicyDto;
|
import com.ruoyi.system.mapper.UserPolicyMapper;
|
import com.ruoyi.system.service.FundsLogService;
|
import com.ruoyi.system.service.GroupWelcomeConfigService;
|
import com.ruoyi.system.service.PaymentRecordService;
|
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<UserPolicyMapper, UserPolicy> implements UserPolicyService {
|
|
@Autowired
|
InsuranceProductService insuranceProductService;
|
@Autowired
|
UserAccountService userAccountService;
|
@Autowired
|
private PayService payService;
|
@Autowired
|
private PaymentRecordService paymentRecordService;
|
@Autowired
|
private UserKycService userKycService;
|
@Autowired
|
private GroupWelcomeConfigService groupWelcomeConfigService;
|
@Autowired
|
private FundsLogService fundsLogService;
|
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result purchaseApplication(UserPolicyDto dto) throws ParseException {
|
UserAccount userAccount = userAccountService.getOne(new LambdaQueryWrapper<UserAccount>()
|
.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<UserPolicy>()
|
.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::getPayStatus, 1))
|
|
);
|
if(count > 0){
|
return Result.error("请勿重复提交,如未支付请3-5分钟重新提交申请");
|
}
|
InsuranceProduct insuranceProduct = insuranceProductService.getById(dto.getProductId());
|
if(ObjectUtil.isEmpty(insuranceProduct)){
|
return Result.error("该产品停止购买或已下架!");
|
}
|
|
if(!dto.getPayProductId().equals("0")){
|
|
GroupWelcomeConfig groupWelcomeConfig = groupWelcomeConfigService.getOne(new LambdaQueryWrapper<>(GroupWelcomeConfig.class)
|
.eq(GroupWelcomeConfig::getConfigurationName, "IM-BASICS").last(" limit 1"));
|
if(ObjectUtil.isNotEmpty(groupWelcomeConfig) && ObjectUtil.isNotEmpty(groupWelcomeConfig.getPaymentSwitch()) && !groupWelcomeConfig.getPaymentSwitch()){
|
return Result.error("无可用支付方式!");
|
}
|
|
String orderNo = generateOrderNo();
|
String payOrder = payService.createOrder(
|
insuranceProduct.getPremium(),
|
orderNo,
|
dto.getPayProductId()
|
);
|
|
Map<String, Object> parse = (Map<String, Object>) JSONUtils.parse(payOrder);
|
Integer code = (Integer) parse.get("code");
|
if (code == null) {
|
return Result.error("支付系统返回异常");
|
}
|
String payUrl;
|
switch (code) {
|
case 200:
|
// 成功,获取支付链接
|
payUrl = (String) parse.get("result");
|
|
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(1);
|
userPolicy.setOrderNo(orderNo);
|
userPolicy.setBirthDate(LocalDate.parse(dto.getBirthDate()));
|
userPolicy.setNumberDays(insuranceProduct.getNumberDays());
|
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);
|
PaymentMode payment = PaymentMode.getByCode(dto.getPayProductId());
|
if (payment != null) {
|
userPolicy.setModePayment(payment.getMode());
|
} else {
|
// 处理未知支付方式
|
userPolicy.setModePayment(0);
|
}
|
userPolicy.setIsLifelong(insuranceProduct.getTerm() == 0 ? 0 : 1);
|
|
save(userPolicy);
|
extracted(userAccount, userPolicy.getId(), orderNo,PaymentRecord.PaymentStatus.PENDING.getCode(),userPolicy.getProductId(),userPolicy.getProductName(),userPolicy.getModePayment());
|
return Result.success(payUrl);
|
case 401:
|
extracted(userAccount, null, orderNo,PaymentRecord.PaymentStatus.FAILED.getCode(),null,"获取支付通道失败",0);
|
return Result.error("未授权访问支付系统");
|
case 403:
|
extracted(userAccount, null, orderNo,PaymentRecord.PaymentStatus.FAILED.getCode(),null,"获取支付通道失败",0);
|
return Result.error("禁止访问支付系统");
|
case 404:
|
extracted(userAccount, null, orderNo,PaymentRecord.PaymentStatus.FAILED.getCode(),null,"获取支付通道失败",0);
|
return Result.error("支付接口不存在");
|
case 0014: // 注意:0014可能是字符串,需要根据实际情况处理
|
extracted(userAccount, null, orderNo,PaymentRecord.PaymentStatus.FAILED.getCode(),null,"获取支付通道失败",0);
|
return Result.error("当前支付不可用,请更换其他支付方式!");
|
default:
|
extracted(userAccount, null, orderNo,PaymentRecord.PaymentStatus.FAILED.getCode(),null,"获取支付通道失败",0);
|
// 其他错误码
|
String message = (String) parse.get("message");
|
if (message != null && !message.isEmpty()) {
|
return Result.error("支付失败: " + message);
|
} else {
|
return Result.error("获取支付通道失败!");
|
}
|
}
|
}else{
|
if(userAccount.getBalance().compareTo(insuranceProduct.getPremium()) < 0){
|
return Result.error("余额不足!");
|
}
|
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.setNumberDays(insuranceProduct.getNumberDays());
|
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.setModePayment(3);
|
userPolicy.setIsLifelong(insuranceProduct.getTerm() == 0 ? 0 : 1);
|
|
save(userPolicy);
|
|
UserKyc userKyc = userKycService.getOne(new LambdaQueryWrapper<UserKyc>()
|
.eq(UserKyc::getAccount, userAccount.getAccount())
|
);
|
PaymentRecord paymentRecord = new PaymentRecord();
|
paymentRecord.setUserId(userAccount.getId());
|
paymentRecord.setPaymentStatus(PaymentRecord.PaymentStatus.PAID.getCode());
|
paymentRecord.setProductId(userPolicy.getProductId());
|
paymentRecord.setOrderId(userPolicy.getId());
|
paymentRecord.setPayOrdeNo(orderNo);
|
paymentRecord.setAccount(userAccount.getAccount());
|
paymentRecord.setName(userKyc.getName());
|
paymentRecord.setInvitationCode(userAccount.getInvitationCode());
|
paymentRecord.setProductName(insuranceProduct.getProductName());
|
paymentRecord.setModePayment(3);
|
paymentRecordService.save(paymentRecord);
|
|
fundsLogService.addLog(userAccount.getId(), userAccount.getAccount(), insuranceProduct.getPremium(), OperationType.USER_ORDER);
|
// 生成资金日志
|
return Result.success();
|
}
|
}
|
|
|
private void extracted(UserAccount userAccount, Integer userPolicyId,
|
String orderNo,Integer payCode,Integer productId,String productName,Integer modePayment) {
|
UserKyc userKyc = userKycService.getOne(new LambdaQueryWrapper<UserKyc>()
|
.eq(UserKyc::getAccount, userAccount.getAccount())
|
);
|
PaymentRecord paymentRecord = new PaymentRecord();
|
paymentRecord.setUserId(userAccount.getId());
|
paymentRecord.setAccount(userAccount.getAccount());
|
paymentRecord.setName(userKyc.getName());
|
paymentRecord.setInvitationCode(userAccount.getInvitationCode());
|
paymentRecord.setProductName(productName);
|
paymentRecord.setPaymentStatus(payCode);
|
if(userPolicyId != null){
|
paymentRecord.setOrderId(userPolicyId);
|
}
|
if(userPolicyId != null){
|
paymentRecord.setOrderId(userPolicyId);
|
}
|
paymentRecord.setProductId(productId);
|
|
paymentRecord.setPayOrdeNo(orderNo);
|
paymentRecord.setModePayment(modePayment);
|
paymentRecordService.save(paymentRecord);
|
}
|
|
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<String, String> 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;
|
}
|
}
|