UnifiedOrderTab.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package com.ruoyi.app.unifiedorder;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.ruoyi.system.domain.PosOrder;
  4. import com.ruoyi.system.domain.flash.FlashDeliveryOrder;
  5. import com.ruoyi.system.domain.flash.FlashDeliveryStatus;
  6. import java.util.List;
  7. import java.util.Objects;
  8. /**
  9. * 统一订单列表 tab 枚举:SQL 条件构造与内存判定共用同一组常量,是归类语义的唯一事实源。
  10. * 外卖条件照抄用户端订单列表现行实现(UserOrderController.orderList);
  11. * 空值字段不匹配任何受限 tab(与 SQL NULL 比较语义一致),all 不过滤。
  12. */
  13. public enum UnifiedOrderTab {
  14. /** 全部:不过滤。 */
  15. ALL("all"),
  16. /** 待付款:仅在线支付未付(货到付款创建即视为已付,不在此列)。 */
  17. UNPAID("unpaid"),
  18. /** 进行中:外卖履约中且无售后;闪送非终态。 */
  19. ACTIVE("active"),
  20. /** 已完成:外卖 state=3 且无售后;闪送 COMPLETED。 */
  21. COMPLETED("completed"),
  22. /** 已取消:外卖 state=4 且无售后;闪送 CANCELLED。 */
  23. CANCELLED("cancelled"),
  24. /** 退款·售后:外卖售后标记大于 0;闪送恒空。 */
  25. REFUND("refund");
  26. /** 在线支付方式(OMG、LINE Pay),待付款 tab 仅认这两种。 */
  27. private static final List<String> ONLINE_PAY_TYPES = List.of("2", "3");
  28. /** 货到付款支付方式标记。 */
  29. private static final String CASH_PAY_TYPE = "1";
  30. /** 货到付款可线下收款的订单类型:自取、堂食。 */
  31. private static final List<Long> CASH_PAYABLE_TYPES = List.of(1L, 2L);
  32. /** 进行中的外卖订单状态:待处理、已接单、已出餐。 */
  33. private static final List<Long> ACTIVE_STATES = List.of(0L, 1L, 2L);
  34. /** 已完成的外卖订单状态。 */
  35. private static final long COMPLETED_STATE = 3L;
  36. /** 已取消的外卖订单状态。 */
  37. private static final long CANCELLED_STATE = 4L;
  38. /** 无售后标记。 */
  39. private static final long NO_AFTER_SALE = 0L;
  40. /** 已支付的支付状态。 */
  41. private static final long PAID = 1L;
  42. /** 未支付的支付状态。 */
  43. private static final long UNPAID_STATUS = 0L;
  44. /** 进行中的闪送状态:非终态四枚举。 */
  45. private static final List<String> FLASH_ACTIVE_STATUSES = List.of(
  46. FlashDeliveryStatus.WAITING_ACCEPTANCE, FlashDeliveryStatus.ACCEPTED,
  47. FlashDeliveryStatus.PICKED_UP, FlashDeliveryStatus.DELIVERED);
  48. private final String code;
  49. UnifiedOrderTab(String code) {
  50. this.code = code;
  51. }
  52. /** 前端契约中的 tab 编码。 */
  53. public String code() {
  54. return code;
  55. }
  56. /** 按契约编码解析;空值默认 all,非法值返回 null 由 Controller 统一转参数错误。 */
  57. public static UnifiedOrderTab fromCode(String code) {
  58. if (code == null || code.isBlank()) {
  59. return ALL;
  60. }
  61. for (UnifiedOrderTab tab : values()) {
  62. if (tab.code.equals(code)) {
  63. return tab;
  64. }
  65. }
  66. return null;
  67. }
  68. /** 待付款与退款·售后 tab 闪送侧恒空,查询层应直接跳过闪送路。 */
  69. public boolean queriesFlash() {
  70. return this != UNPAID && this != REFUND;
  71. }
  72. /** 构造外卖 tab 条件(仅 tab 谓词,不含用户、游标与排序,由查询层追加)。 */
  73. public LambdaQueryWrapper<PosOrder> posOrderWrapper() {
  74. LambdaQueryWrapper<PosOrder> wrapper = new LambdaQueryWrapper<>();
  75. switch (this) {
  76. case UNPAID:
  77. wrapper.eq(PosOrder::getPayStatus, UNPAID_STATUS)
  78. .in(PosOrder::getPayType, ONLINE_PAY_TYPES)
  79. .ne(PosOrder::getState, CANCELLED_STATE)
  80. .eq(PosOrder::getAfterSaleStatus, NO_AFTER_SALE);
  81. break;
  82. case ACTIVE:
  83. wrapper.in(PosOrder::getState, ACTIVE_STATES)
  84. .eq(PosOrder::getAfterSaleStatus, NO_AFTER_SALE)
  85. // 现金自取/堂食可以线下收款;在线订单必须已付款才能履约。
  86. .and(w -> w.eq(PosOrder::getPayStatus, PAID)
  87. .or(cash -> cash.eq(PosOrder::getPayType, CASH_PAY_TYPE)
  88. .in(PosOrder::getType, CASH_PAYABLE_TYPES)));
  89. break;
  90. case COMPLETED:
  91. wrapper.eq(PosOrder::getState, COMPLETED_STATE)
  92. .eq(PosOrder::getAfterSaleStatus, NO_AFTER_SALE);
  93. break;
  94. case CANCELLED:
  95. wrapper.eq(PosOrder::getState, CANCELLED_STATE)
  96. .eq(PosOrder::getAfterSaleStatus, NO_AFTER_SALE);
  97. break;
  98. case REFUND:
  99. wrapper.gt(PosOrder::getAfterSaleStatus, NO_AFTER_SALE);
  100. break;
  101. case ALL:
  102. default:
  103. break;
  104. }
  105. return wrapper;
  106. }
  107. /** 外卖订单内存判定,与 posOrderWrapper 的 SQL 条件同源同语义。 */
  108. public boolean matches(PosOrder order) {
  109. switch (this) {
  110. case UNPAID:
  111. return longEq(order.getPayStatus(), UNPAID_STATUS)
  112. && order.getPayType() != null && ONLINE_PAY_TYPES.contains(order.getPayType())
  113. && longNotEq(order.getState(), CANCELLED_STATE)
  114. && longEq(order.getAfterSaleStatus(), NO_AFTER_SALE);
  115. case ACTIVE:
  116. return order.getState() != null && ACTIVE_STATES.contains(order.getState())
  117. && longEq(order.getAfterSaleStatus(), NO_AFTER_SALE)
  118. && (longEq(order.getPayStatus(), PAID)
  119. || (CASH_PAY_TYPE.equals(order.getPayType())
  120. && order.getType() != null && CASH_PAYABLE_TYPES.contains(order.getType())));
  121. case COMPLETED:
  122. return longEq(order.getState(), COMPLETED_STATE)
  123. && longEq(order.getAfterSaleStatus(), NO_AFTER_SALE);
  124. case CANCELLED:
  125. return longEq(order.getState(), CANCELLED_STATE)
  126. && longEq(order.getAfterSaleStatus(), NO_AFTER_SALE);
  127. case REFUND:
  128. return order.getAfterSaleStatus() != null && order.getAfterSaleStatus() > NO_AFTER_SALE;
  129. case ALL:
  130. default:
  131. return true;
  132. }
  133. }
  134. /** 构造闪送 tab 条件;待付款与退款·售后闪送侧恒空,调用即视为程序错误。 */
  135. public LambdaQueryWrapper<FlashDeliveryOrder> flashWrapper() {
  136. if (!queriesFlash()) {
  137. throw new IllegalStateException("闪送无 " + code + " tab,查询层应跳过闪送路");
  138. }
  139. LambdaQueryWrapper<FlashDeliveryOrder> wrapper = new LambdaQueryWrapper<>();
  140. switch (this) {
  141. case ACTIVE:
  142. wrapper.in(FlashDeliveryOrder::getStatus, FLASH_ACTIVE_STATUSES);
  143. break;
  144. case COMPLETED:
  145. wrapper.eq(FlashDeliveryOrder::getStatus, FlashDeliveryStatus.COMPLETED);
  146. break;
  147. case CANCELLED:
  148. wrapper.eq(FlashDeliveryOrder::getStatus, FlashDeliveryStatus.CANCELLED);
  149. break;
  150. case ALL:
  151. default:
  152. break;
  153. }
  154. return wrapper;
  155. }
  156. /** 闪送订单内存判定,与 flashWrapper 的 SQL 条件同源同语义。 */
  157. public boolean matches(FlashDeliveryOrder order) {
  158. switch (this) {
  159. case ACTIVE:
  160. return order.getStatus() != null && FLASH_ACTIVE_STATUSES.contains(order.getStatus());
  161. case COMPLETED:
  162. return Objects.equals(order.getStatus(), FlashDeliveryStatus.COMPLETED);
  163. case CANCELLED:
  164. return Objects.equals(order.getStatus(), FlashDeliveryStatus.CANCELLED);
  165. case UNPAID:
  166. case REFUND:
  167. return false;
  168. case ALL:
  169. default:
  170. return true;
  171. }
  172. }
  173. private static boolean longEq(Long value, long expected) {
  174. return value != null && value == expected;
  175. }
  176. private static boolean longNotEq(Long value, long unexpected) {
  177. return value != null && value != unexpected;
  178. }
  179. }