VppContractStatusHelper.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package com.usky.vpp.util;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.usky.vpp.domain.VppContract;
  4. import java.time.LocalDate;
  5. import java.util.Arrays;
  6. import java.util.HashSet;
  7. import java.util.Set;
  8. /**
  9. * 合同状态工具:根据生效/到期日期自动解析生命周期状态
  10. */
  11. public final class VppContractStatusHelper {
  12. public static final int DRAFT = 0;
  13. public static final int AUDITING = 1;
  14. public static final int PENDING = 2;
  15. public static final int EFFECTIVE = 3;
  16. public static final int REJECTED = 4;
  17. public static final int EXPIRED = 5;
  18. public static final int TERMINATED = 6;
  19. /** 查询专用:即将到期(近三个月内过期,非落库状态) */
  20. public static final int UPCOMING_EXPIRE = 7;
  21. private static final Set<Integer> MANUAL_STATUSES = new HashSet<>(Arrays.asList(
  22. DRAFT, AUDITING, REJECTED, TERMINATED
  23. ));
  24. private VppContractStatusHelper() {
  25. }
  26. /**
  27. * 根据生效/到期日期解析合同状态;草稿、审核中、已驳回、已终止保持原状态不变。
  28. */
  29. public static Integer resolve(Integer storedStatus, LocalDate effectiveDate, LocalDate expireDate) {
  30. if (storedStatus != null && MANUAL_STATUSES.contains(storedStatus)) {
  31. return storedStatus;
  32. }
  33. return resolveByDates(effectiveDate, expireDate, storedStatus);
  34. }
  35. /**
  36. * 创建/更新时根据日期计算应写入的状态;未提供日期时回退为待生效。
  37. */
  38. public static Integer resolveForPersist(Integer requestedStatus, LocalDate effectiveDate, LocalDate expireDate) {
  39. if (requestedStatus != null && MANUAL_STATUSES.contains(requestedStatus)) {
  40. return requestedStatus;
  41. }
  42. Integer resolved = resolveByDates(effectiveDate, expireDate, requestedStatus);
  43. return resolved != null ? resolved : PENDING;
  44. }
  45. private static Integer resolveByDates(LocalDate effectiveDate, LocalDate expireDate, Integer fallback) {
  46. LocalDate today = LocalDate.now();
  47. if (expireDate != null && today.isAfter(expireDate)) {
  48. return EXPIRED;
  49. }
  50. if (effectiveDate != null) {
  51. return today.isBefore(effectiveDate) ? PENDING : EFFECTIVE;
  52. }
  53. return fallback;
  54. }
  55. /**
  56. * 分页筛选:将生命周期状态(待生效/已生效/已到期/即将到期)转换为日期条件。
  57. * <p>其中 {@link #UPCOMING_EXPIRE} 仅用于查询,不会写入数据库。</p>
  58. */
  59. public static void applyStatusFilter(LambdaQueryWrapper<VppContract> wrapper, Integer contractStatus) {
  60. if (contractStatus == null) {
  61. return;
  62. }
  63. LocalDate today = LocalDate.now();
  64. if (contractStatus == PENDING) {
  65. wrapper.and(w -> w.in(VppContract::getContractStatus, PENDING, EFFECTIVE, EXPIRED)
  66. .gt(VppContract::getEffectiveDate, today)
  67. .and(inner -> inner.isNull(VppContract::getExpireDate)
  68. .or().ge(VppContract::getExpireDate, today)));
  69. return;
  70. }
  71. if (contractStatus == EFFECTIVE) {
  72. wrapper.and(w -> w.in(VppContract::getContractStatus, PENDING, EFFECTIVE, EXPIRED)
  73. .le(VppContract::getEffectiveDate, today)
  74. .and(inner -> inner.isNull(VppContract::getExpireDate)
  75. .or().ge(VppContract::getExpireDate, today)));
  76. return;
  77. }
  78. if (contractStatus == EXPIRED) {
  79. wrapper.and(w -> w.in(VppContract::getContractStatus, PENDING, EFFECTIVE, EXPIRED)
  80. .lt(VppContract::getExpireDate, today));
  81. return;
  82. }
  83. if (contractStatus == UPCOMING_EXPIRE) {
  84. LocalDate upcomingDeadline = today.plusMonths(3);
  85. wrapper.and(w -> w.in(VppContract::getContractStatus, PENDING, EFFECTIVE, EXPIRED)
  86. .ge(VppContract::getExpireDate, today)
  87. .le(VppContract::getExpireDate, upcomingDeadline));
  88. return;
  89. }
  90. wrapper.eq(VppContract::getContractStatus, contractStatus);
  91. }
  92. }