@pisell/pisellos 2.2.277 → 2.2.279

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  2. package/dist/modules/BaseModule.d.ts +1 -0
  3. package/dist/modules/BaseModule.js +24 -28
  4. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  5. package/dist/modules/BookingContext/utils/productExtend.js +5 -9
  6. package/dist/modules/BookingContext/utils/timeSlices.js +24 -3
  7. package/dist/modules/Customer/index.d.ts +4 -0
  8. package/dist/modules/Customer/index.js +91 -59
  9. package/dist/modules/Customer/types.d.ts +2 -0
  10. package/dist/modules/Discount/index.d.ts +1 -0
  11. package/dist/modules/Discount/index.js +40 -11
  12. package/dist/modules/Discount/types.d.ts +1 -0
  13. package/dist/modules/Holder/index.d.ts +48 -0
  14. package/dist/modules/Holder/index.js +640 -0
  15. package/dist/modules/Holder/types.d.ts +123 -0
  16. package/dist/modules/Holder/types.js +1 -0
  17. package/dist/modules/Holder/utils.d.ts +13 -0
  18. package/dist/modules/Holder/utils.js +34 -0
  19. package/dist/modules/OpenData/index.js +2 -2
  20. package/dist/modules/Order/index.d.ts +32 -4
  21. package/dist/modules/Order/index.js +868 -675
  22. package/dist/modules/Order/types.d.ts +22 -1
  23. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  24. package/dist/modules/Order/utils/discountProductLineIdentity.js +227 -0
  25. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  26. package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
  27. package/dist/modules/Order/utils.d.ts +10 -0
  28. package/dist/modules/Order/utils.js +71 -34
  29. package/dist/modules/Payment/index.d.ts +4 -0
  30. package/dist/modules/Payment/index.js +14 -4
  31. package/dist/modules/Payment/walletpass.js +48 -13
  32. package/dist/modules/Product/types.d.ts +1 -0
  33. package/dist/modules/ProductList/index.js +33 -13
  34. package/dist/modules/Quotation/index.d.ts +1 -1
  35. package/dist/modules/Quotation/index.js +2 -2
  36. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  37. package/dist/modules/ResourcePlanner/index.js +181 -0
  38. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  39. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  40. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  41. package/dist/modules/ResourcePlanner/types.js +1 -0
  42. package/dist/modules/Rules/index.js +153 -56
  43. package/dist/modules/SalesSummary/index.js +12 -13
  44. package/dist/modules/ScanOrderLogger/index.d.ts +2 -0
  45. package/dist/modules/ScanOrderLogger/index.js +15 -2
  46. package/dist/modules/ScanOrderLogger/providers/feishu.js +45 -27
  47. package/dist/modules/ScanOrderLogger/types.d.ts +1 -0
  48. package/dist/modules/Schedule/index.d.ts +3 -1
  49. package/dist/modules/Schedule/index.js +21 -16
  50. package/dist/modules/Summary/utils.js +38 -13
  51. package/dist/modules/index.d.ts +2 -0
  52. package/dist/modules/index.js +3 -1
  53. package/dist/plugins/window.d.ts +1 -0
  54. package/dist/server/index.d.ts +20 -0
  55. package/dist/server/index.js +1101 -909
  56. package/dist/server/modules/order/index.d.ts +2 -0
  57. package/dist/server/modules/order/index.js +261 -96
  58. package/dist/server/modules/order/types.d.ts +1 -1
  59. package/dist/server/utils/small-ticket.js +2 -1
  60. package/dist/solution/BaseSales/index.d.ts +10 -1
  61. package/dist/solution/BaseSales/index.js +201 -148
  62. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -1
  63. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  64. package/dist/solution/BaseSales/utils.js +31 -20
  65. package/dist/solution/BookingByStep/index.d.ts +16 -1
  66. package/dist/solution/BookingByStep/index.js +294 -215
  67. package/dist/solution/BookingByStep/types.d.ts +2 -1
  68. package/dist/solution/BookingByStep/types.js +3 -1
  69. package/dist/solution/BookingByStep/utils/capacity.js +17 -1
  70. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  71. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  72. package/dist/solution/BookingTicket/index.d.ts +6 -2
  73. package/dist/solution/BookingTicket/index.js +125 -77
  74. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  75. package/dist/solution/BookingTicket/utils/scan/handleScan.js +10 -2
  76. package/dist/solution/ScanOrder/index.d.ts +26 -14
  77. package/dist/solution/ScanOrder/index.js +1142 -739
  78. package/dist/solution/ScanOrder/types.d.ts +21 -1
  79. package/dist/solution/ScanOrder/utils.d.ts +8 -0
  80. package/dist/solution/ScanOrder/utils.js +97 -45
  81. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  82. package/dist/solution/ShopDiscount/index.js +125 -87
  83. package/dist/solution/UnifiedBookingSales/index.d.ts +204 -0
  84. package/dist/solution/UnifiedBookingSales/index.js +2211 -0
  85. package/dist/solution/UnifiedBookingSales/types.d.ts +150 -0
  86. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  87. package/dist/solution/VenueBooking/index.d.ts +39 -11
  88. package/dist/solution/VenueBooking/index.js +1167 -841
  89. package/dist/solution/VenueBooking/types.d.ts +3 -0
  90. package/dist/solution/VenueBooking/utils/resource.js +1 -0
  91. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  92. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -5
  93. package/dist/solution/index.d.ts +1 -0
  94. package/dist/solution/index.js +2 -1
  95. package/dist/types/index.d.ts +1 -0
  96. package/lib/model/strategy/adapter/promotion/index.js +51 -0
  97. package/lib/modules/BaseModule.d.ts +1 -0
  98. package/lib/modules/BaseModule.js +24 -37
  99. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  100. package/lib/modules/BookingContext/utils/productExtend.js +4 -3
  101. package/lib/modules/BookingContext/utils/timeSlices.js +18 -3
  102. package/lib/modules/Customer/index.d.ts +4 -0
  103. package/lib/modules/Customer/index.js +11 -0
  104. package/lib/modules/Customer/types.d.ts +2 -0
  105. package/lib/modules/Discount/index.d.ts +1 -0
  106. package/lib/modules/Discount/index.js +9 -0
  107. package/lib/modules/Discount/types.d.ts +1 -0
  108. package/lib/modules/Holder/index.d.ts +48 -0
  109. package/lib/modules/Holder/index.js +402 -0
  110. package/lib/modules/Holder/types.d.ts +123 -0
  111. package/lib/modules/Holder/types.js +17 -0
  112. package/lib/modules/Holder/utils.d.ts +13 -0
  113. package/lib/modules/Holder/utils.js +71 -0
  114. package/lib/modules/OpenData/index.js +1 -1
  115. package/lib/modules/Order/index.d.ts +32 -4
  116. package/lib/modules/Order/index.js +372 -156
  117. package/lib/modules/Order/types.d.ts +22 -1
  118. package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  119. package/lib/modules/Order/utils/discountProductLineIdentity.js +170 -0
  120. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  121. package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
  122. package/lib/modules/Order/utils.d.ts +10 -0
  123. package/lib/modules/Order/utils.js +39 -6
  124. package/lib/modules/Payment/index.d.ts +4 -0
  125. package/lib/modules/Payment/index.js +7 -0
  126. package/lib/modules/Payment/walletpass.js +27 -1
  127. package/lib/modules/Product/types.d.ts +1 -0
  128. package/lib/modules/ProductList/index.js +49 -31
  129. package/lib/modules/Quotation/index.d.ts +1 -1
  130. package/lib/modules/Quotation/index.js +2 -2
  131. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  132. package/lib/modules/ResourcePlanner/index.js +148 -0
  133. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  134. package/lib/modules/ResourcePlanner/planner.js +933 -0
  135. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  136. package/lib/modules/ResourcePlanner/types.js +17 -0
  137. package/lib/modules/Rules/index.js +117 -25
  138. package/lib/modules/SalesSummary/index.js +6 -7
  139. package/lib/modules/ScanOrderLogger/index.d.ts +2 -0
  140. package/lib/modules/ScanOrderLogger/index.js +13 -1
  141. package/lib/modules/ScanOrderLogger/providers/feishu.js +15 -6
  142. package/lib/modules/ScanOrderLogger/types.d.ts +1 -0
  143. package/lib/modules/Schedule/index.d.ts +3 -1
  144. package/lib/modules/Schedule/index.js +10 -8
  145. package/lib/modules/Summary/utils.js +21 -1
  146. package/lib/modules/index.d.ts +2 -0
  147. package/lib/modules/index.js +5 -1
  148. package/lib/plugins/window.d.ts +1 -0
  149. package/lib/server/index.d.ts +20 -0
  150. package/lib/server/index.js +124 -19
  151. package/lib/server/modules/order/index.d.ts +2 -0
  152. package/lib/server/modules/order/index.js +75 -5
  153. package/lib/server/modules/order/types.d.ts +1 -1
  154. package/lib/server/utils/small-ticket.js +1 -1
  155. package/lib/solution/BaseSales/index.d.ts +10 -1
  156. package/lib/solution/BaseSales/index.js +73 -29
  157. package/lib/solution/BaseSales/utils/cartPromotion.js +18 -0
  158. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -0
  159. package/lib/solution/BaseSales/utils.js +29 -18
  160. package/lib/solution/BookingByStep/index.d.ts +16 -1
  161. package/lib/solution/BookingByStep/index.js +60 -18
  162. package/lib/solution/BookingByStep/types.d.ts +2 -1
  163. package/lib/solution/BookingByStep/types.js +5 -0
  164. package/lib/solution/BookingByStep/utils/capacity.js +20 -1
  165. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  166. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  167. package/lib/solution/BookingTicket/index.d.ts +6 -2
  168. package/lib/solution/BookingTicket/index.js +63 -16
  169. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  170. package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -2
  171. package/lib/solution/ScanOrder/index.d.ts +26 -14
  172. package/lib/solution/ScanOrder/index.js +449 -182
  173. package/lib/solution/ScanOrder/types.d.ts +21 -1
  174. package/lib/solution/ScanOrder/utils.d.ts +8 -0
  175. package/lib/solution/ScanOrder/utils.js +60 -18
  176. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  177. package/lib/solution/ShopDiscount/index.js +14 -0
  178. package/lib/solution/UnifiedBookingSales/index.d.ts +204 -0
  179. package/lib/solution/UnifiedBookingSales/index.js +1273 -0
  180. package/lib/solution/UnifiedBookingSales/types.d.ts +150 -0
  181. package/lib/solution/UnifiedBookingSales/types.js +33 -0
  182. package/lib/solution/VenueBooking/index.d.ts +39 -11
  183. package/lib/solution/VenueBooking/index.js +322 -110
  184. package/lib/solution/VenueBooking/types.d.ts +3 -0
  185. package/lib/solution/VenueBooking/utils/resource.js +1 -0
  186. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  187. package/lib/solution/VenueBooking/utils/slotMerge.js +6 -4
  188. package/lib/solution/index.d.ts +1 -0
  189. package/lib/solution/index.js +3 -1
  190. package/lib/types/index.d.ts +1 -0
  191. package/package.json +1 -1
@@ -0,0 +1,227 @@
1
+ export type ResourcePlannerMode = 'appointment' | 'scan_order' | 'venue_grid';
2
+ export type ResourcePlannerProductKind = 'normal' | 'duration' | 'session' | 'venue_slot';
3
+ export type ResourcePlannerResourceType = 'single' | 'multiple' | 'capacity';
4
+ export type ResourcePlannerStatus = 'available' | 'limited' | 'full' | 'conflict' | 'unavailable' | 'past';
5
+ export interface ResourcePlannerTimeRange {
6
+ start_at: string;
7
+ end_at: string;
8
+ }
9
+ export interface ResourcePlannerEvent extends ResourcePlannerTimeRange {
10
+ resourceId?: number | string;
11
+ resource_id?: number | string;
12
+ pax?: number;
13
+ product_uid?: string;
14
+ source?: 'remote' | 'cart' | 'selection';
15
+ [key: string]: any;
16
+ }
17
+ export interface ResourcePlannerResourceRequirement {
18
+ formId?: number | string;
19
+ resourceIds?: Array<number | string>;
20
+ resourceType?: ResourcePlannerResourceType;
21
+ capacityRequired?: number;
22
+ required?: boolean;
23
+ }
24
+ export interface ResourcePlannerProduct {
25
+ id: number | string;
26
+ title?: string;
27
+ kind: ResourcePlannerProductKind;
28
+ durationMinutes?: number;
29
+ schedule?: ResourcePlannerTimeRange[];
30
+ resourceRequirements?: ResourcePlannerResourceRequirement[];
31
+ capacityRequired?: number;
32
+ quantity?: number;
33
+ price?: string | number | null;
34
+ raw?: Record<string, any>;
35
+ }
36
+ export interface ResourcePlannerResource {
37
+ id: number | string;
38
+ formId?: number | string;
39
+ name?: string;
40
+ resourceType: ResourcePlannerResourceType;
41
+ capacity: number;
42
+ times: Array<ResourcePlannerTimeRange & {
43
+ event_list?: ResourcePlannerEvent[];
44
+ [key: string]: any;
45
+ }>;
46
+ childResourceIds?: Array<number | string>;
47
+ raw?: Record<string, any>;
48
+ }
49
+ export interface ResourcePlannerContextInput {
50
+ products?: ResourcePlannerProduct[];
51
+ resources?: ResourcePlannerResource[];
52
+ externalEvents?: ResourcePlannerEvent[];
53
+ slotDurationMinutes?: number;
54
+ businessStartTime?: string;
55
+ businessEndTime?: string;
56
+ }
57
+ export interface ResourcePlannerQuery {
58
+ mode?: ResourcePlannerMode;
59
+ productIds?: Array<number | string>;
60
+ date?: string;
61
+ dateRange?: {
62
+ start: string;
63
+ end: string;
64
+ };
65
+ startTime?: string;
66
+ endTime?: string;
67
+ resourceIds?: Array<number | string>;
68
+ serviceObjectIds?: Array<number | string>;
69
+ holderIds?: Array<number | string>;
70
+ pax?: number;
71
+ slotDurationMinutes?: number;
72
+ }
73
+ export interface ResourcePlannerSelection {
74
+ productIds: Array<number | string>;
75
+ date?: string;
76
+ startTime?: string;
77
+ endTime?: string;
78
+ resourceIds: Array<number | string>;
79
+ assignments: ResourcePlannerAssignment[];
80
+ mode?: ResourcePlannerMode;
81
+ }
82
+ export interface ResourcePlannerSelectionPatch extends Partial<ResourcePlannerSelection> {
83
+ replaceAssignments?: boolean;
84
+ }
85
+ export interface ResourcePlannerDemandInterval {
86
+ id: string;
87
+ productId: number | string;
88
+ source: Extract<ResourcePlannerProductKind, 'duration' | 'session' | 'venue_slot'>;
89
+ date: string;
90
+ start_at: string;
91
+ end_at: string;
92
+ durationMinutes: number;
93
+ quantity: number;
94
+ capacityRequired: number;
95
+ resourceRequirements: ResourcePlannerResourceRequirement[];
96
+ }
97
+ export interface ResourcePlannerConflict {
98
+ type: 'outside_resource_time' | 'remote_event_overlap' | 'cart_overlap' | 'capacity_full' | 'missing_time' | 'missing_resource' | 'missing_assignment' | 'past';
99
+ message: string;
100
+ event?: ResourcePlannerEvent;
101
+ resourceId?: number | string;
102
+ productId?: number | string;
103
+ }
104
+ export interface ResourcePlannerAvailabilityCell {
105
+ key: string;
106
+ productId: number | string;
107
+ resourceId?: number | string;
108
+ date?: string;
109
+ start_at: string;
110
+ end_at: string;
111
+ startTime?: string;
112
+ endTime?: string;
113
+ durationMinutes?: number;
114
+ cellType: 'availability_range' | 'fixed_interval' | 'unavailable';
115
+ status: ResourcePlannerStatus;
116
+ remainingCapacity?: number;
117
+ maxCapacity?: number;
118
+ reasonCodes: string[];
119
+ conflicts: ResourcePlannerConflict[];
120
+ }
121
+ export interface ResourcePlannerProductOption {
122
+ productId: number | string;
123
+ title?: string;
124
+ status: ResourcePlannerStatus;
125
+ reasonCodes: string[];
126
+ }
127
+ export interface ResourcePlannerResourceOption {
128
+ resourceId: number | string;
129
+ resourceName?: string;
130
+ resourceFormId?: number | string;
131
+ resourceType: ResourcePlannerResourceType;
132
+ status: ResourcePlannerStatus;
133
+ remainingCapacity?: number;
134
+ maxCapacity?: number;
135
+ reasonCodes: string[];
136
+ }
137
+ export interface ResourcePlannerDateSummary {
138
+ date: string;
139
+ status: ResourcePlannerStatus;
140
+ availableCount: number;
141
+ totalCount: number;
142
+ }
143
+ export interface ResourcePlannerTimeSlot {
144
+ startTime: string;
145
+ endTime: string;
146
+ status: ResourcePlannerStatus;
147
+ resourceId: number | string;
148
+ productId?: number | string;
149
+ remainingCapacity?: number;
150
+ maxCapacity?: number;
151
+ reasonCodes: string[];
152
+ }
153
+ export interface ResourcePlannerTimeGridRow {
154
+ resourceId: number | string;
155
+ resourceName?: string;
156
+ resourceFormId?: number | string;
157
+ slots: ResourcePlannerTimeSlot[];
158
+ }
159
+ export interface ResourcePlannerTimeGrid {
160
+ date?: string;
161
+ timeLabels: string[];
162
+ resources: ResourcePlannerTimeGridRow[];
163
+ }
164
+ export interface ResourcePlannerProjection {
165
+ query: ResourcePlannerQuery;
166
+ demandIntervals: ResourcePlannerDemandInterval[];
167
+ productOptions: ResourcePlannerProductOption[];
168
+ resourceOptions: ResourcePlannerResourceOption[];
169
+ dateSummary: ResourcePlannerDateSummary[];
170
+ timeGrid: ResourcePlannerTimeGrid;
171
+ cells: ResourcePlannerAvailabilityCell[];
172
+ }
173
+ export interface ResourcePlannerAssignment {
174
+ productId: number | string;
175
+ resourceId: number | string;
176
+ start_at: string;
177
+ end_at: string;
178
+ capacityRequired?: number;
179
+ }
180
+ export interface ResourcePlannerAssignableSlotResource {
181
+ resourceId: number | string;
182
+ resourceName?: string;
183
+ resourceFormId?: number | string;
184
+ resourceType?: ResourcePlannerResourceType;
185
+ capacityRequired?: number;
186
+ remainingCapacity?: number;
187
+ maxCapacity?: number;
188
+ }
189
+ export interface ResourcePlannerAssignableSlot {
190
+ key: string;
191
+ productId: number | string;
192
+ date: string;
193
+ start_at: string;
194
+ end_at: string;
195
+ startTime: string;
196
+ endTime: string;
197
+ durationMinutes: number;
198
+ status: ResourcePlannerStatus;
199
+ resources: ResourcePlannerAssignableSlotResource[];
200
+ assignments: ResourcePlannerAssignment[];
201
+ conflicts: ResourcePlannerConflict[];
202
+ }
203
+ export interface ResourcePlannerAssignableSlotResult {
204
+ projection: ResourcePlannerProjection;
205
+ slots: ResourcePlannerAssignableSlot[];
206
+ conflicts: ResourcePlannerConflict[];
207
+ }
208
+ export interface ResourcePlannerAssignmentResult {
209
+ assignments: ResourcePlannerAssignment[];
210
+ conflicts: ResourcePlannerConflict[];
211
+ }
212
+ export interface ResourcePlannerValidationResult {
213
+ ok: boolean;
214
+ conflicts: ResourcePlannerConflict[];
215
+ }
216
+ export interface ResourcePlannerSnapshot {
217
+ context: Required<ResourcePlannerContextInput>;
218
+ selection: ResourcePlannerSelection;
219
+ projection: ResourcePlannerProjection | null;
220
+ version: number;
221
+ }
222
+ export interface ResourcePlannerState {
223
+ context: Required<ResourcePlannerContextInput>;
224
+ selection: ResourcePlannerSelection;
225
+ projection: ResourcePlannerProjection | null;
226
+ version: number;
227
+ }
@@ -0,0 +1,17 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+
15
+ // src/modules/ResourcePlanner/types.ts
16
+ var types_exports = {};
17
+ module.exports = __toCommonJS(types_exports);
@@ -305,7 +305,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
305
305
  _id: product._id,
306
306
  parentId: product._id,
307
307
  quantity: product.quantity,
308
- num: product.num
308
+ num: product.num,
309
+ booking_id: product.booking_id
309
310
  });
310
311
  if (product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0) {
311
312
  product.bundle.forEach((bundleItem, bundleIndex) => {
@@ -329,7 +330,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
329
330
  origin_total: new import_decimal.default(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
330
331
  original_price: bundleItem.original_price,
331
332
  // 继承主商品属性
332
- booking_id: product.booking_id,
333
+ booking_id: bundleItem.booking_id,
333
334
  discount_list: bundleItem.discount_list || []
334
335
  });
335
336
  });
@@ -691,7 +692,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
691
692
  discount_product_id: discount.product_id
692
693
  },
693
694
  metadata: {
694
- num
695
+ num,
696
+ discount_rule_uncheck_flag: discount == null ? void 0 : discount.discount_rule_uncheck_flag
695
697
  }
696
698
  };
697
699
  applicableProducts.push(productData);
@@ -856,15 +858,46 @@ var RulesModule = class extends import_BaseModule.BaseModule {
856
858
  }
857
859
  return false;
858
860
  });
859
- const explicitlySelectedDiscountCard = (options == null ? void 0 : options.isSelected) === true && options.discountId !== void 0 ? applicableDiscounts.find((discount) => {
861
+ const explicitlySelectedDiscount = (options == null ? void 0 : options.isSelected) === true && options.discountId !== void 0 ? applicableDiscounts.find((discount) => {
860
862
  const discountType = discount.tag || discount.type;
861
- return String(discount.id) === String(options.discountId) && ["discount_card", "product_discount_card"].includes(discountType);
863
+ return String(discount.id) === String(options.discountId) && ["good_pass", "discount_card", "product_discount_card"].includes(
864
+ discountType
865
+ );
862
866
  }) : void 0;
867
+ const explicitlySelectedDiscountCard = explicitlySelectedDiscount && (explicitlySelectedDiscount.tag || explicitlySelectedDiscount.type) !== "good_pass" ? explicitlySelectedDiscount : void 0;
868
+ const appliedDiscountCardIds = new Set(
869
+ (product.discount_list || []).filter(
870
+ (item) => ["discount_card", "product_discount_card"].includes(
871
+ (item == null ? void 0 : item.tag) || (item == null ? void 0 : item.type)
872
+ )
873
+ ).map(
874
+ (item) => {
875
+ var _a3;
876
+ return ((_a3 = item == null ? void 0 : item.discount) == null ? void 0 : _a3.resource_id) ?? (item == null ? void 0 : item.resource_id) ?? (item == null ? void 0 : item.id);
877
+ }
878
+ ).filter((id) => id !== void 0 && id !== null).map(String)
879
+ );
880
+ const appliedDiscountCard = (options == null ? void 0 : options.scan) ? void 0 : applicableDiscounts.find((discount) => {
881
+ const discountType = discount.tag || discount.type;
882
+ return discount.isSelected === true && ["discount_card", "product_discount_card"].includes(discountType) && appliedDiscountCardIds.has(String(discount.id));
883
+ });
863
884
  const scannedSelectedDiscountCard = applicableDiscounts.find(
864
885
  (n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
865
886
  );
866
- const selectedDiscountCard = explicitlySelectedDiscountCard || scannedSelectedDiscountCard;
867
- const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
887
+ const selectedDiscountCard = explicitlySelectedDiscountCard || appliedDiscountCard || scannedSelectedDiscountCard;
888
+ const selectedDiscount = explicitlySelectedDiscount || selectedDiscountCard || applicableDiscounts[0];
889
+ const prioritizedApplicableDiscounts = explicitlySelectedDiscount && (explicitlySelectedDiscount.tag || explicitlySelectedDiscount.type) === "good_pass" ? [
890
+ explicitlySelectedDiscount,
891
+ ...applicableDiscounts.filter(
892
+ (discount) => {
893
+ const discountType = discount.tag || discount.type;
894
+ return discountType === "good_pass" && String(discount.id) !== String(explicitlySelectedDiscount.id);
895
+ }
896
+ ),
897
+ ...applicableDiscounts.filter(
898
+ (discount) => (discount.tag || discount.type) !== "good_pass"
899
+ )
900
+ ] : applicableDiscounts;
868
901
  let isManualDiscount = false;
869
902
  let isItemRewardProductDiscount = false;
870
903
  if (flatItem.type === "main") {
@@ -1043,21 +1076,65 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1043
1076
  const arr = [];
1044
1077
  if (flatItem.type === "main") {
1045
1078
  if (splitCount < totalQuantity && isNeedSplit) {
1079
+ const remainingQuantity = totalQuantity - splitCount;
1080
+ const applicableNonGoodPassById = new Map(
1081
+ applicableDiscounts.filter((discount) => (discount.tag || discount.type) !== "good_pass").map((discount) => [String(discount.id), discount])
1082
+ );
1083
+ const remainderDiscountList = (product.discount_list || []).filter((discount) => {
1084
+ var _a3;
1085
+ const discountType = discount.tag || discount.type;
1086
+ if (discountType === "promotion")
1087
+ return true;
1088
+ if (discountType === "good_pass")
1089
+ return false;
1090
+ const resourceId = ((_a3 = discount.discount) == null ? void 0 : _a3.resource_id) ?? discount.id;
1091
+ return resourceId !== void 0 && resourceId !== null && applicableNonGoodPassById.has(String(resourceId));
1092
+ }).map((discount) => {
1093
+ var _a3;
1094
+ if ((discount.tag || discount.type) === "promotion")
1095
+ return discount;
1096
+ const resourceId = ((_a3 = discount.discount) == null ? void 0 : _a3.resource_id) ?? discount.id;
1097
+ const matchedDiscount = applicableNonGoodPassById.get(String(resourceId));
1098
+ if (matchedDiscount) {
1099
+ usedDiscounts.set(matchedDiscount.id, true);
1100
+ const appliedProducts = appliedDiscountProducts.get(matchedDiscount.id) || [];
1101
+ appliedProducts.push({
1102
+ ...discount,
1103
+ _num: remainingQuantity
1104
+ });
1105
+ appliedDiscountProducts.set(matchedDiscount.id, appliedProducts);
1106
+ }
1107
+ return {
1108
+ ...discount,
1109
+ // _num 是 Rules 运行态的行数量;Order 写回 tempOrder 时会裁剪该字段。
1110
+ _num: remainingQuantity
1111
+ };
1112
+ });
1113
+ const hasRetainedWalletDiscount = remainderDiscountList.some(
1114
+ (discount) => !["promotion", "good_pass"].includes(discount.tag || discount.type)
1115
+ );
1046
1116
  let total = product.origin_total ?? product.total;
1047
1117
  if ((product.discount_list || []).some((item) => item.type === "promotion")) {
1048
1118
  total = product.total ?? product.origin_total;
1049
1119
  }
1050
1120
  arr.push(
1051
1121
  this.hooks.setProduct(originProduct, {
1052
- discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
1053
- quantity: totalQuantity - splitCount,
1122
+ // 商品券只替换被拆出的 splitCount 件。余量行原本仍有效的折扣卡
1123
+ // 不能随 good_pass 拆分一起清除;已取消或已失效的折扣不会进入此列表。
1124
+ discount_list: remainderDiscountList,
1125
+ quantity: remainingQuantity,
1054
1126
  _id: product._id.split("___")[0],
1055
- total
1127
+ total,
1128
+ // 保留余量行当前的折后主价;Order.applyProductDiscountPrices 随后会基于
1129
+ // source_product_price + discount_list 再归一化,避免出现重复折扣。
1130
+ ...hasRetainedWalletDiscount ? {
1131
+ main_product_selling_price: product.main_product_selling_price ?? product.price
1132
+ } : {}
1056
1133
  })
1057
1134
  );
1058
1135
  }
1059
1136
  for (let i = 0; i < splitCount; i++) {
1060
- const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
1137
+ const selectedDiscount2 = isNeedSplit ? prioritizedApplicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[i];
1061
1138
  usedDiscounts.set(selectedDiscount2.id, true);
1062
1139
  if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
1063
1140
  const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
@@ -1132,6 +1209,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1132
1209
  config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config,
1133
1210
  metadata: {
1134
1211
  num: 1,
1212
+ discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1135
1213
  // 🔥 order_level 分摊差值
1136
1214
  ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference },
1137
1215
  /** 仅主商品上的优惠金额(不含 option) */
@@ -1183,7 +1261,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1183
1261
  const discountNum = splitCount;
1184
1262
  const normalNum = totalQuantity - discountNum;
1185
1263
  for (let i = 0; i < discountNum; i++) {
1186
- const selectedDiscount2 = applicableDiscounts[i];
1264
+ const selectedDiscount2 = prioritizedApplicableDiscounts[i];
1187
1265
  usedDiscounts.set(selectedDiscount2.id, true);
1188
1266
  if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
1189
1267
  const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
@@ -1212,6 +1290,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1212
1290
  metadata: {
1213
1291
  // 🔥 使用拆分后的唯一 _id
1214
1292
  custom_product_bundle_map_id: uniqueId,
1293
+ discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1215
1294
  num: 1
1216
1295
  },
1217
1296
  _num: 1,
@@ -1241,7 +1320,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1241
1320
  _id: `${flatItem._id}_split_rest`,
1242
1321
  num: normalNum,
1243
1322
  quantity: normalNum,
1244
- discount_list: [],
1323
+ discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion"),
1245
1324
  processed: true
1246
1325
  });
1247
1326
  }
@@ -1299,6 +1378,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1299
1378
  metadata: {
1300
1379
  // 🔥 使用唯一的 _id
1301
1380
  custom_product_bundle_map_id: uniqueId,
1381
+ discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1302
1382
  num: product.num || 1,
1303
1383
  // 🔥 order_level 分摊差值
1304
1384
  ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
@@ -1313,7 +1393,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1313
1393
  ...flatItem,
1314
1394
  total: targetProductTotal,
1315
1395
  price: new import_decimal.default(productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
1316
- discount_list: [discountDetail],
1396
+ discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion").concat([discountDetail]),
1317
1397
  processed: true
1318
1398
  });
1319
1399
  }
@@ -1734,7 +1814,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1734
1814
  * @returns 是否可用
1735
1815
  */
1736
1816
  checkPackageSubItemUsageRules(discount, flatItem) {
1737
- var _a, _b, _c, _d, _e, _f, _g;
1817
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1738
1818
  const limitedData = discount.limited_relation_product_data;
1739
1819
  const usageRules = limitedData == null ? void 0 : limitedData.package_sub_item_usage_rules;
1740
1820
  const rules = ["original_price", ...(usageRules == null ? void 0 : usageRules.rules) || []];
@@ -1746,6 +1826,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1746
1826
  const { type: scopeType, exclude_bundle_product_ids = [], include_bundle_product_ids = [], filter = 0 } = packageScope || {};
1747
1827
  const isMainProduct = flatItem.type === "main";
1748
1828
  const isBundleItem = flatItem.type === "bundle";
1829
+ const bundleMainProductId = (_a = flatItem.product) == null ? void 0 : _a.product_id;
1749
1830
  if (isMainProduct) {
1750
1831
  return true;
1751
1832
  }
@@ -1754,9 +1835,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1754
1835
  return true;
1755
1836
  }
1756
1837
  if (isBundleItem) {
1757
- const priceType = (_a = flatItem.bundleItem) == null ? void 0 : _a.price_type;
1758
- const priceTypeExt = (_b = flatItem.bundleItem) == null ? void 0 : _b.price_type_ext;
1759
- const mainProductId = ((_d = (_c = flatItem == null ? void 0 : flatItem.originProduct) == null ? void 0 : _c._productOrigin) == null ? void 0 : _d.id) || ((_e = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _e.id) || 0;
1838
+ const priceType = (_b = flatItem.bundleItem) == null ? void 0 : _b.price_type;
1839
+ const priceTypeExt = (_c = flatItem.bundleItem) == null ? void 0 : _c.price_type_ext;
1840
+ const mainProductId = ((_e = (_d = flatItem == null ? void 0 : flatItem.originProduct) == null ? void 0 : _d._productOrigin) == null ? void 0 : _e.id) || ((_f = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _f.id) || 0;
1760
1841
  const isOriginalPrice = priceType === "markup" && priceTypeExt === "product_price";
1761
1842
  const isMarkupPrice = priceType === "markup" && (priceTypeExt === "" || !priceTypeExt);
1762
1843
  if (rules.length > 0) {
@@ -1768,11 +1849,11 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1768
1849
  if (!filter) {
1769
1850
  isScopeValid = true;
1770
1851
  } else {
1771
- isScopeValid = !exclude_bundle_product_ids.includes(Number(mainProductId));
1852
+ isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
1772
1853
  }
1773
1854
  }
1774
1855
  if (scopeType === "specific_packages" || scopeType === "products") {
1775
- isScopeValid = include_bundle_product_ids.includes(Number(mainProductId));
1856
+ isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
1776
1857
  }
1777
1858
  if (isPriceValid && isScopeValid) {
1778
1859
  return true;
@@ -1788,15 +1869,26 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1788
1869
  return false;
1789
1870
  }
1790
1871
  if (isBundleItem) {
1791
- const priceType = (_f = flatItem.bundleItem) == null ? void 0 : _f.price_type;
1792
- const priceTypeExt = (_g = flatItem.bundleItem) == null ? void 0 : _g.price_type_ext;
1872
+ const priceType = (_g = flatItem.bundleItem) == null ? void 0 : _g.price_type;
1873
+ const priceTypeExt = (_h = flatItem.bundleItem) == null ? void 0 : _h.price_type_ext;
1793
1874
  const isOriginalPrice = priceType === "markup" && priceTypeExt === "product_price";
1794
1875
  const isMarkupPrice = priceType === "markup" && (priceTypeExt === "" || !priceTypeExt);
1795
1876
  if (rules.length > 0) {
1796
- if (isOriginalPrice && rules.includes("original_price")) {
1797
- return true;
1877
+ const _isOriginalPrice = isOriginalPrice && rules.includes("original_price");
1878
+ const _isMarkupPrice = isMarkupPrice && rules.includes("markup_price");
1879
+ const isPriceValid = _isOriginalPrice || _isMarkupPrice;
1880
+ let isScopeValid = false;
1881
+ if (scopeType === "all_packages" || scopeType === "product_all") {
1882
+ if (!filter) {
1883
+ isScopeValid = true;
1884
+ } else {
1885
+ isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
1886
+ }
1887
+ }
1888
+ if (scopeType === "specific_packages" || scopeType === "products") {
1889
+ isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
1798
1890
  }
1799
- if (isMarkupPrice && rules.includes("markup_price")) {
1891
+ if (isPriceValid && isScopeValid) {
1800
1892
  return true;
1801
1893
  }
1802
1894
  return false;
@@ -53,9 +53,6 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
53
53
  this.store.surchargeList = ((_a = options.initialState) == null ? void 0 : _a.surchargeList) || [];
54
54
  this.store.summary = ((_b = options.initialState) == null ? void 0 : _b.summary) || (0, import_utils.createEmptySalesSummary)();
55
55
  this.surchargeListModuleName = ((_c = this.otherParams) == null ? void 0 : _c.surchargeListModuleName) || "surchargeList";
56
- if (!this.appPlugin) {
57
- throw new Error("SalesSummaryModule 需要 app 插件支持");
58
- }
59
56
  if (!this.request) {
60
57
  throw new Error("SalesSummaryModule 需要 request 插件支持");
61
58
  }
@@ -109,12 +106,14 @@ var SalesSummaryModule = class extends import_BaseModule.BaseModule {
109
106
  }
110
107
  }
111
108
  getAppData(key) {
112
- var _a, _b, _c, _d, _e, _f;
113
- const getData = (_b = (_a = this.appPlugin).getData) == null ? void 0 : _b.call(_a);
109
+ var _a, _b, _c, _d, _e, _f, _g, _h;
110
+ const getData = (_b = (_a = this.appPlugin) == null ? void 0 : _a.getData) == null ? void 0 : _b.call(_a);
114
111
  if (typeof getData === "function")
115
112
  return getData(key);
116
- const app = this.appPlugin.getApp();
117
- const coreData = (_f = (_d = (_c = app == null ? void 0 : app.models) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core", "core");
113
+ const app = (_d = (_c = this.appPlugin) == null ? void 0 : _c.getApp) == null ? void 0 : _d.call(_c);
114
+ if (!app)
115
+ return void 0;
116
+ const coreData = (_h = (_f = (_e = app == null ? void 0 : app.models) == null ? void 0 : _e.getStore) == null ? void 0 : (_g = _f.call(_e)).getDataByModel) == null ? void 0 : _h.call(_g, "core", "core");
118
117
  return coreData == null ? void 0 : coreData[key];
119
118
  }
120
119
  getTaxConfig() {
@@ -11,10 +11,12 @@ export declare class ScanOrderLoggerModule extends BaseModule implements Module,
11
11
  protected defaultName: string;
12
12
  protected defaultVersion: string;
13
13
  private store;
14
+ private window?;
14
15
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
15
16
  setContext(context: ScanOrderLoggerContext): void;
16
17
  setProvider(provider: ScanOrderLoggerProviderType): void;
17
18
  setProviderConfig(providerConfig: ScanOrderLoggerProviderConfig): void;
19
+ private getCurrentHost;
18
20
  private buildRecord;
19
21
  addLog(params: ScanOrderLogInput): Promise<void>;
20
22
  }
@@ -60,6 +60,7 @@ var ScanOrderLoggerModule = class extends import_BaseModule.BaseModule {
60
60
  var _a, _b, _c;
61
61
  this.core = core;
62
62
  this.store = options.store;
63
+ this.window = core.getPlugin("window") || void 0;
63
64
  const provider = ((_a = options.otherParams) == null ? void 0 : _a.provider) || "feishu";
64
65
  const providerConfig = ((_b = options.otherParams) == null ? void 0 : _b.providerConfig) || {};
65
66
  const context = ((_c = options.otherParams) == null ? void 0 : _c.context) || {};
@@ -101,14 +102,25 @@ var ScanOrderLoggerModule = class extends import_BaseModule.BaseModule {
101
102
  }
102
103
  };
103
104
  }
105
+ getCurrentHost() {
106
+ var _a, _b;
107
+ const host = (_b = (_a = this.window) == null ? void 0 : _a.location) == null ? void 0 : _b.host;
108
+ if (typeof host === "string" && host.length > 0)
109
+ return host;
110
+ return void 0;
111
+ }
104
112
  buildRecord(params) {
113
+ const host = this.getCurrentHost();
105
114
  return {
106
115
  level: params.level || "info",
107
116
  title: params.title,
108
117
  timestamp: params.timestamp || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
109
118
  payload: params.payload || {},
110
119
  extra: params.extra || {},
111
- context: this.store.context || {}
120
+ context: {
121
+ ...this.store.context || {},
122
+ ...host ? { host } : {}
123
+ }
112
124
  };
113
125
  }
114
126
  async addLog(params) {
@@ -112,20 +112,29 @@ async function flushQueue() {
112
112
  }
113
113
  var feishuLoggerProvider = {
114
114
  async send(payload) {
115
- var _a, _b, _c, _d;
115
+ var _a, _b, _c, _d, _e, _f;
116
116
  cachedProviderConfig = payload.providerConfig;
117
117
  const webhook = (_b = (_a = payload.providerConfig) == null ? void 0 : _a.feishu) == null ? void 0 : _b.webhook;
118
+ const errorHook = (_d = (_c = payload.providerConfig) == null ? void 0 : _c.feishu) == null ? void 0 : _d.errorHook;
119
+ if (typeof fetch !== "function") {
120
+ console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报");
121
+ return;
122
+ }
123
+ if (payload.record.level === "error" && isWebhookUsable(errorHook)) {
124
+ try {
125
+ await postToFeishu(errorHook, buildFeishuBody([payload.record]));
126
+ } catch (error) {
127
+ console.warn("[ScanOrderLogger] Feishu errorHook 上报失败", error);
128
+ }
129
+ return;
130
+ }
118
131
  if (!webhook) {
119
132
  console.warn("[ScanOrderLogger] Feishu webhook 未配置,跳过日志上报");
120
133
  return;
121
134
  }
122
135
  if (!isWebhookUsable(webhook))
123
136
  return;
124
- if (typeof fetch !== "function") {
125
- console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报");
126
- return;
127
- }
128
- const throttleMs = ((_d = (_c = payload.providerConfig) == null ? void 0 : _c.feishu) == null ? void 0 : _d.throttleMs) ?? DEFAULT_THROTTLE_MS;
137
+ const throttleMs = ((_f = (_e = payload.providerConfig) == null ? void 0 : _e.feishu) == null ? void 0 : _f.throttleMs) ?? DEFAULT_THROTTLE_MS;
129
138
  if (throttleMs <= 0) {
130
139
  try {
131
140
  await postToFeishu(webhook, buildFeishuBody([payload.record]));
@@ -2,6 +2,7 @@ export type ScanOrderLogLevel = 'info' | 'warning' | 'error' | 'debug';
2
2
  export type ScanOrderLoggerProviderType = 'feishu' | 'grafana';
3
3
  export interface ScanOrderLoggerProviderFeishuConfig {
4
4
  webhook?: string;
5
+ errorHook?: string;
5
6
  /**
6
7
  * 节流窗口毫秒数,默认 3000ms
7
8
  * - >0:首条日志进入队列并启动定时器,窗口结束后合并成一条 Feishu post 统一发送
@@ -24,7 +24,9 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
24
24
  *
25
25
  * @memberof ScheduleModule
26
26
  */
27
- loadAllSchedule(): Promise<void>;
27
+ loadAllSchedule(options?: {
28
+ useCache?: boolean;
29
+ }): Promise<void>;
28
30
  setScheduleList(list: ScheduleItem[]): void;
29
31
  private syncScheduleMap;
30
32
  getScheduleList(): ScheduleItem[];