| | |
| | | import com.ruoyi.im.service.MedicalInsuranceAccountService; |
| | | import com.ruoyi.system.domain.MedicalInsuranceAccount; |
| | | import com.ruoyi.system.domain.MedicalInsuranceDailyClaim; |
| | | import com.ruoyi.system.domain.UserAccount; |
| | | import com.ruoyi.system.mapper.MedicalInsuranceAccountMapper; |
| | | import com.ruoyi.system.mapper.MedicalInsuranceDailyClaimMapper; |
| | | import com.ruoyi.system.service.UserAccountService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | |
| | | import javax.xml.crypto.Data; |
| | | import java.math.BigDecimal; |
| | |
| | | private MedicalInsuranceDailyClaimMapper medicalInsuranceDailyClaimMapper; |
| | | |
| | | // 使用本地锁避免数据库锁竞争 |
| | | private final ConcurrentHashMap<Integer, ReentrantLock> accountLocks = new ConcurrentHashMap<>(); |
| | | private final ConcurrentHashMap<String, ReentrantLock> accountLocks = new ConcurrentHashMap<>(); |
| | | |
| | | @Autowired |
| | | UserAccountService userAccountService; |
| | | |
| | | @Override |
| | | public Result getInsuranceBenefit(Integer userId) { |
| | | synchronized (userId) { |
| | | public Result getInsuranceBenefit(String account) { |
| | | synchronized (account) { |
| | | // 获取账户本地锁 |
| | | ReentrantLock accountLock = accountLocks.computeIfAbsent(userId, k -> new ReentrantLock()); |
| | | ReentrantLock accountLock = accountLocks.computeIfAbsent(account, k -> new ReentrantLock()); |
| | | accountLock.lock(); |
| | | |
| | | UserAccount userAccount = userAccountService.getOne(new LambdaQueryWrapper<UserAccount>() |
| | | .eq(UserAccount::getAccount,account)); |
| | | try { |
| | | MedicalInsuranceAccount account = medicalInsuranceAccountMapper.selectOne(new LambdaQueryWrapper<MedicalInsuranceAccount>() |
| | | .eq(MedicalInsuranceAccount::getUserId, userId) |
| | | MedicalInsuranceAccount medicalInsuranceAccount = medicalInsuranceAccountMapper.selectOne(new LambdaQueryWrapper<MedicalInsuranceAccount>() |
| | | .eq(MedicalInsuranceAccount::getUserId, userAccount.getId()) |
| | | .eq(MedicalInsuranceAccount::getAccountStatus, MedicalInsuranceAccount.AccountStatus.ACTIVE) |
| | | ); |
| | | if (account == null) { |
| | | if (medicalInsuranceAccount == null) { |
| | | return Result.error("医保账户不存在"); |
| | | } |
| | | |
| | | // 检查账户状态 |
| | | if (!"ACTIVE".equals(account.getAccountStatus())) { |
| | | if (!"ACTIVE".equals(medicalInsuranceAccount.getAccountStatus().name())) { |
| | | return Result.error("保单已失效"); |
| | | } |
| | | |
| | | // 检查账户有效期 |
| | | LocalDate now = LocalDate.now(); |
| | | if (now.isBefore(account.getEffectiveDate()) || |
| | | now.isAfter(account.getExpiryDate())) { |
| | | if (now.isBefore(medicalInsuranceAccount.getEffectiveDate()) || |
| | | now.isAfter(medicalInsuranceAccount.getExpiryDate())) { |
| | | return Result.error("已过保单日期"); |
| | | } |
| | | // 检查今天是否已经领取 |
| | | LocalDate today = LocalDate.now(); |
| | | Long todayCount = medicalInsuranceDailyClaimMapper.selectCount(new LambdaQueryWrapper<MedicalInsuranceDailyClaim>() |
| | | .eq(MedicalInsuranceDailyClaim::getUserId, userId) |
| | | .eq(MedicalInsuranceDailyClaim::getAccountId, account.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getUserId, userAccount.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getAccountId, medicalInsuranceAccount.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getClaimDate, today) |
| | | ); |
| | | if (todayCount > 0) { |
| | | return Result.error("今日已领取过金额"); |
| | | } |
| | | |
| | | if (account.getTotalQuota().compareTo(account.getAlreadyReceived()) == 0) { |
| | | if (medicalInsuranceAccount.getTotalQuota().compareTo(medicalInsuranceAccount.getAlreadyReceived()) == 0) { |
| | | return Result.error("你的保险额度已领取完!"); |
| | | } |
| | | |
| | | // 计算剩余天数 |
| | | long remainingDays = ChronoUnit.DAYS.between(now, account.getExpiryDate()) + 1; |
| | | |
| | | // 计算每日金额 |
| | | BigDecimal dailyAmount = calculateDailyAmount( |
| | | account.getTotalQuota(), (int) remainingDays); |
| | | |
| | | // 如果账户余额不足,则领取剩余全部金额 |
| | | if (account.getAmountClaimed().compareTo(dailyAmount) < 0) { |
| | | dailyAmount = account.getAmountClaimed(); |
| | | } |
| | | |
| | | // 更新待领金额 |
| | | account.setAmountClaimed(account.getAmountClaimed().subtract(dailyAmount)); |
| | | // // 计算剩余天数 |
| | | // long remainingDays = ChronoUnit.DAYS.between(now, medicalInsuranceAccount.getExpiryDate()) + 1; |
| | | // |
| | | // // 计算每日金额 |
| | | // BigDecimal dailyAmount = calculateDailyAmount( |
| | | // medicalInsuranceAccount.getTotalQuota(), (int) remainingDays); |
| | | // |
| | | // // 如果账户余额不足,则领取剩余全部金额 |
| | | // if (medicalInsuranceAccount.getAmountClaimed().compareTo(dailyAmount) < 0) { |
| | | // dailyAmount = medicalInsuranceAccount.getAmountClaimed(); |
| | | // } |
| | | // |
| | | // // 更新待领金额 |
| | | // medicalInsuranceAccount.setAmountClaimed(medicalInsuranceAccount.getAmountClaimed().subtract(dailyAmount)); |
| | | |
| | | // 更新已领取金额 |
| | | BigDecimal currentAmountReceived = account.getAlreadyReceived() != null ? |
| | | account.getAlreadyReceived(): BigDecimal.ZERO; |
| | | account.setAlreadyReceived(currentAmountReceived.add(dailyAmount)); |
| | | BigDecimal currentAmountReceived = medicalInsuranceAccount.getAlreadyReceived() != null ? |
| | | medicalInsuranceAccount.getAlreadyReceived(): BigDecimal.ZERO; |
| | | medicalInsuranceAccount.setAlreadyReceived(currentAmountReceived.add(medicalInsuranceAccount.getAmountClaimed())); |
| | | |
| | | medicalInsuranceAccountMapper.updateById(account); |
| | | medicalInsuranceAccountMapper.updateById(medicalInsuranceAccount); |
| | | |
| | | // 创建领取记录 |
| | | MedicalInsuranceDailyClaim claim = new MedicalInsuranceDailyClaim(); |
| | | claim.setAccountId(account.getId()); |
| | | claim.setUserId(userId); |
| | | claim.setAccountId(medicalInsuranceAccount.getId()); |
| | | claim.setUserId(userAccount.getId()); |
| | | claim.setClaimDate(today); |
| | | claim.setClaimAmount(dailyAmount); |
| | | claim.setClaimAmount(medicalInsuranceAccount.getAmountClaimed()); |
| | | claim.setCreatedAt(new Date()); |
| | | medicalInsuranceDailyClaimMapper.insert(claim); |
| | | return Result.success("领取成功"); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | log.error("领取保险金出错:"+e.getMessage()); |
| | | }finally { |
| | | accountLock.unlock(); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Result getReceiveStatus(Integer userId) { |
| | | MedicalInsuranceAccount account = medicalInsuranceAccountMapper.selectOne(new LambdaQueryWrapper<MedicalInsuranceAccount>() |
| | | .eq(MedicalInsuranceAccount::getUserId, userId) |
| | | public Result getReceiveStatus(String account) { |
| | | UserAccount userAccount = userAccountService.getOne(new LambdaQueryWrapper<UserAccount>() |
| | | .eq(UserAccount::getAccount,account)); |
| | | MedicalInsuranceAccount medicalInsuranceAccount = medicalInsuranceAccountMapper.selectOne(new LambdaQueryWrapper<MedicalInsuranceAccount>() |
| | | .eq(MedicalInsuranceAccount::getUserId, userAccount.getId()) |
| | | .eq(MedicalInsuranceAccount::getAccountStatus, MedicalInsuranceAccount.AccountStatus.ACTIVE) |
| | | ); |
| | | if (account == null) { |
| | | if (medicalInsuranceAccount == null) { |
| | | return Result.success(false); |
| | | } |
| | | // 检查账户状态 |
| | | if (!"ACTIVE".equals(account.getAccountStatus())) { |
| | | if (!"ACTIVE".equals(medicalInsuranceAccount.getAccountStatus().name())) { |
| | | return Result.success(false); |
| | | } |
| | | // 检查账户有效期 |
| | | LocalDate now = LocalDate.now(); |
| | | if (now.isBefore(account.getEffectiveDate()) || |
| | | now.isAfter(account.getExpiryDate())) { |
| | | if (now.isBefore(medicalInsuranceAccount.getEffectiveDate()) || |
| | | now.isAfter(medicalInsuranceAccount.getExpiryDate())) { |
| | | return Result.success(false); |
| | | } |
| | | // 检查今天是否已经领取 |
| | | LocalDate today = LocalDate.now(); |
| | | Long todayCount = medicalInsuranceDailyClaimMapper.selectCount(new LambdaQueryWrapper<MedicalInsuranceDailyClaim>() |
| | | .eq(MedicalInsuranceDailyClaim::getUserId, userId) |
| | | .eq(MedicalInsuranceDailyClaim::getAccountId, account.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getUserId, userAccount.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getAccountId, medicalInsuranceAccount.getId()) |
| | | .eq(MedicalInsuranceDailyClaim::getClaimDate, today) |
| | | ); |
| | | if (todayCount > 0) { |