| | |
| | | package com.ruoyi.web.controller.product; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.page.TableDataInfo; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.im.comm.Result; |
| | | import com.ruoyi.im.service.InsuranceProductService; |
| | | import com.ruoyi.im.service.MedicalInsuranceAccountService; |
| | | import com.ruoyi.system.domain.MedicalInsuranceAccount; |
| | | import com.ruoyi.system.domain.UserAccount; |
| | | import com.ruoyi.system.domain.UserPolicy; |
| | | import com.ruoyi.im.service.impl.InsurancePositionServiceImpl; |
| | | import com.ruoyi.im.util.RedisDistributedLock; |
| | | import com.ruoyi.im.util.UserPolicyUtils; |
| | | import com.ruoyi.system.domain.*; |
| | | import com.ruoyi.system.domain.dto.UserPolicyDto; |
| | | import com.ruoyi.im.service.UserPolicyService; |
| | | import com.ruoyi.system.service.UserAccountService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.validation.Valid; |
| | |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.UUID; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RestController |
| | | @RequestMapping("/userPolicy") |
| | | public class UserPolicyController { |
| | | public class UserPolicyController extends BaseController { |
| | | |
| | | @Autowired |
| | | UserPolicyService userPolicyService; |
| | |
| | | @Autowired |
| | | UserAccountService userAccountService; |
| | | |
| | | @Autowired |
| | | InsurancePositionServiceImpl insurancePositionService; |
| | | |
| | | @Autowired |
| | | private RedisDistributedLock redisDistributedLock; |
| | | |
| | | @Autowired |
| | | InsuranceProductService insuranceProductService; |
| | | |
| | | /** |
| | | * 保险购买申请 |
| | | */ |
| | | @PostMapping("/purchaseApplication") |
| | | public Result purchaseApplication(UserPolicyDto dto) { |
| | | // 生成锁的key:基于用户ID和产品ID,防止同一用户同时购买同一产品 |
| | | String lockKey = redisDistributedLock.generateLockKey(dto.getAccount(), dto.getProductId()); |
| | | |
| | | boolean lockAcquired = false; |
| | | try { |
| | | // 尝试获取分布式锁:等待10秒,锁过期30秒 |
| | | lockAcquired = redisDistributedLock.tryLock(lockKey, 30L, 10L); |
| | | |
| | | if (!lockAcquired) { |
| | | return Result.error("操作过于频繁,请稍后重试"); |
| | | } |
| | | |
| | | // 执行购买逻辑 |
| | | return userPolicyService.purchaseApplication(dto); |
| | | }catch (Exception e){ |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return Result.error("购买失败"); |
| | | } finally { |
| | | // 释放锁 |
| | | if (lockAcquired) { |
| | | redisDistributedLock.releaseLock(lockKey); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 根据用户id查询保单 |
| | |
| | | return Result.error("查询失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 保单列表 |
| | | */ |
| | | @GetMapping("/list") |
| | | public TableDataInfo list(@RequestParam(value = "account",required = false) String account, |
| | | @RequestParam(value = "state",defaultValue = "0") Integer state, |
| | | @RequestParam(value = "productName",required = false) String productName) { |
| | | startPage(); |
| | | |
| | | LambdaQueryWrapper<UserPolicy> wrapper = new LambdaQueryWrapper<>(); |
| | | |
| | | // 产品名称模糊查询 |
| | | if (org.apache.commons.lang3.StringUtils.isNotBlank(account)) { |
| | | wrapper.like(UserPolicy::getAccount, account); |
| | | } |
| | | |
| | | // 产品代码模糊查询 |
| | | if (org.apache.commons.lang3.StringUtils.isNotBlank(productName)) { |
| | | wrapper.like(UserPolicy::getProductName, productName); |
| | | } |
| | | |
| | | // 审批状态 |
| | | if (state != null && state == 3) { |
| | | wrapper.ne(UserPolicy::getApprovalStatus, 0); |
| | | }else{ |
| | | wrapper.eq(UserPolicy::getApprovalStatus, 0); |
| | | } |
| | | |
| | | // 按创建时间倒序排列 |
| | | wrapper.orderByDesc(UserPolicy::getCreatedAt); |
| | | |
| | | List<UserPolicy> list = userPolicyService.list(wrapper); |
| | | return getDataTable(list); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 保单审批 |
| | |
| | | if(approvalStatus == 2 && StringUtils.isEmpty(message)){ |
| | | return AjaxResult.error("驳回理由不能为空!"); |
| | | } |
| | | UserAccount userAccount = userAccountService.getById(userPolicy.getUserId()); |
| | | if(approvalStatus == 2){ |
| | | userPolicy.setApprovalStatus(approvalStatus); |
| | | userPolicy.setMessage(message); |
| | | userPolicy.setUpdatedAt(new Date()); |
| | | userPolicyService.updateById(userPolicy); |
| | | |
| | | userAccount.setBalance(userAccount.getBalance().add(userPolicy.getPremium())); |
| | | userAccountService.updateById(userAccount); |
| | | return AjaxResult.success("审批成功"); |
| | | } |
| | | |
| | | //计算到期时间 |
| | | LocalDate expirationTime = calculateInsuranceEndDate(LocalDate.now(), userPolicy.getTerm()); |
| | | LocalDate expirationTime = calculateInsuranceEndDateToDay(LocalDate.now(), userPolicy.getTerm()); |
| | | |
| | | userPolicy.setApprovalStatus(approvalStatus); |
| | | userPolicy.setMessage(message); |
| | |
| | | medicalInsuranceAccount.setCreatedAt(new Date()); |
| | | medicalInsuranceAccount.setUpdatedAt(new Date()); |
| | | medicalInsuranceAccountService.save(medicalInsuranceAccount); |
| | | |
| | | //判断上级用户职位达成 |
| | | if(approvalStatus == 1){ |
| | | if(StringUtils.isNotEmpty(userAccount.getInvitationAccount())){ |
| | | //上级 |
| | | UserAccount superiorUser = userAccountService.getOne(new LambdaQueryWrapper<UserAccount>() |
| | | .eq(UserAccount::getAccount, userAccount.getInvitationAccount()) |
| | | ); |
| | | //查询上级的所有下级 |
| | | List<UserAccount> userAccountList = userAccountService.list(new LambdaQueryWrapper<UserAccount>() |
| | | .eq(UserAccount::getInvitationAccount, superiorUser.getAccount()) |
| | | ); |
| | | if(userAccountList.size() == 0){ |
| | | return AjaxResult.success("审批成功"); |
| | | } |
| | | List<Integer> idList = userAccountList.stream() |
| | | .map(UserAccount::getId) |
| | | .collect(Collectors.toList()); |
| | | //查询下级的保单 |
| | | List<UserPolicy> userPolicyList = userPolicyService.list(new LambdaQueryWrapper<>(UserPolicy.class) |
| | | .in(UserPolicy::getUserId, idList) |
| | | ); |
| | | // 手动将当前审批的保单加入到列表中(因为事务隔离可能查不到) |
| | | userPolicyList.add(userPolicy); |
| | | if(userPolicyList.size() == 0){ |
| | | return AjaxResult.success("审批成功"); |
| | | } |
| | | //生效保单数量 |
| | | long activePolicies = UserPolicyUtils.countActivePolicies(userPolicyList); |
| | | //查询所有职位 |
| | | List<InsurancePosition> positions = insurancePositionService.list(); |
| | | positions.forEach(f->{ |
| | | if(activePolicies >= f.getNumberPeople()){ |
| | | superiorUser.setPosition(f.getPosition()); |
| | | superiorUser.setAgreedTime(LocalDate.now()); |
| | | } |
| | | }); |
| | | userAccountService.updateById(superiorUser); |
| | | } |
| | | return AjaxResult.success("审批成功"); |
| | | } |
| | | return AjaxResult.success("审批成功"); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | |
| | | /** |
| | | * 计算保险到期日 |
| | | * @param startDate 保险开始日期 |
| | | * @param termDays 保险天数 |
| | | * @return 保险到期日期 |
| | | */ |
| | | public static LocalDate calculateInsuranceEndDateToDay(LocalDate startDate, int termDays) { |
| | | return calculateDateAfterDays(startDate, termDays); |
| | | } |
| | | |
| | | /** |
| | | * 计算指定天数后的日期 |
| | | * @param startDate 开始日期 |
| | | * @param daysToAdd 要添加的天数 |
| | | * @return 计算后的日期 |
| | | */ |
| | | public static LocalDate calculateDateAfterDays(LocalDate startDate, int daysToAdd) { |
| | | if (startDate == null) { |
| | | throw new IllegalArgumentException("开始日期不能为空"); |
| | | } |
| | | return startDate.plusDays(daysToAdd); |
| | | } |
| | | |
| | | /** |
| | | * 计算保险到期日 |
| | | * @param startDate 保险开始日期 |
| | | * @param termYears 保险年限 |
| | | * @return 保险到期日期 |
| | | */ |