@pisell/pisellos 2.3.39 → 2.3.41

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 (226) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.js +7 -0
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +99 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  10. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
  12. package/dist/model/strategy/adapter/promotion/type.js +45 -0
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -3
  14. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +6 -3
  15. package/dist/modules/Discount/index.d.ts +0 -1
  16. package/dist/modules/Discount/index.js +11 -40
  17. package/dist/modules/Discount/types.d.ts +0 -1
  18. package/dist/modules/OpenData/index.d.ts +2 -0
  19. package/dist/modules/OpenData/index.js +10 -2
  20. package/dist/modules/Order/index.d.ts +29 -12
  21. package/dist/modules/Order/index.js +750 -509
  22. package/dist/modules/Order/payment-utils.d.ts +26 -0
  23. package/dist/modules/Order/payment-utils.js +225 -0
  24. package/dist/modules/Order/types.d.ts +33 -10
  25. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  26. package/dist/modules/Order/utils.d.ts +0 -10
  27. package/dist/modules/Order/utils.js +13 -41
  28. package/dist/modules/Payment/index.d.ts +2 -0
  29. package/dist/modules/Payment/index.js +79 -50
  30. package/dist/modules/Payment/types.d.ts +99 -28
  31. package/dist/modules/Payment/types.js +20 -3
  32. package/dist/modules/Payment/walletpass.d.ts +25 -1
  33. package/dist/modules/Payment/walletpass.js +707 -157
  34. package/dist/modules/Product/types.d.ts +0 -1
  35. package/dist/modules/ProductList/index.js +14 -33
  36. package/dist/modules/Quotation/index.d.ts +1 -1
  37. package/dist/modules/Quotation/index.js +2 -2
  38. package/dist/modules/Rules/index.d.ts +1 -0
  39. package/dist/modules/Rules/index.js +89 -96
  40. package/dist/modules/SalesSummary/index.js +13 -12
  41. package/dist/modules/ScanOrderLogger/index.d.ts +0 -2
  42. package/dist/modules/ScanOrderLogger/index.js +2 -15
  43. package/dist/modules/ScanOrderLogger/providers/feishu.js +27 -45
  44. package/dist/modules/ScanOrderLogger/types.d.ts +0 -1
  45. package/dist/modules/Schedule/index.d.ts +1 -3
  46. package/dist/modules/Schedule/index.js +16 -21
  47. package/dist/modules/Summary/utils.js +13 -38
  48. package/dist/modules/index.d.ts +0 -2
  49. package/dist/modules/index.js +1 -3
  50. package/dist/plugins/window.d.ts +0 -1
  51. package/dist/server/index.d.ts +16 -14
  52. package/dist/server/index.js +1925 -1143
  53. package/dist/server/modules/order/index.d.ts +54 -4
  54. package/dist/server/modules/order/index.js +1600 -700
  55. package/dist/server/modules/order/types.d.ts +11 -3
  56. package/dist/server/modules/order/types.js +1 -1
  57. package/dist/solution/BaseSales/index.d.ts +109 -20
  58. package/dist/solution/BaseSales/index.js +1800 -480
  59. package/dist/solution/BaseSales/types.d.ts +52 -0
  60. package/dist/solution/BaseSales/types.js +2 -1
  61. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  62. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  63. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  64. package/dist/solution/BookingByStep/index.d.ts +2 -17
  65. package/dist/solution/BookingByStep/index.js +215 -294
  66. package/dist/solution/BookingByStep/types.d.ts +1 -2
  67. package/dist/solution/BookingByStep/types.js +1 -3
  68. package/dist/solution/BookingByStep/utils/capacity.js +1 -17
  69. package/dist/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  70. package/dist/solution/BookingByStep/utils/timeslots.js +12 -19
  71. package/dist/solution/BookingTicket/index.d.ts +7 -3
  72. package/dist/solution/BookingTicket/index.js +132 -49
  73. package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -0
  74. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  75. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +172 -82
  76. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  77. package/dist/solution/BookingTicket/utils/weighingProductSku.js +45 -0
  78. package/dist/solution/Sales/index.d.ts +1 -0
  79. package/dist/solution/Sales/index.js +10 -2
  80. package/dist/solution/ScanOrder/index.d.ts +14 -26
  81. package/dist/solution/ScanOrder/index.js +756 -1148
  82. package/dist/solution/ScanOrder/types.d.ts +1 -21
  83. package/dist/solution/ScanOrder/utils.d.ts +0 -8
  84. package/dist/solution/ScanOrder/utils.js +25 -66
  85. package/dist/solution/ShopDiscount/index.d.ts +0 -1
  86. package/dist/solution/ShopDiscount/index.js +87 -125
  87. package/dist/solution/VenueBooking/index.d.ts +11 -39
  88. package/dist/solution/VenueBooking/index.js +860 -1176
  89. package/dist/solution/VenueBooking/types.d.ts +0 -3
  90. package/dist/solution/VenueBooking/utils/resource.js +0 -1
  91. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  92. package/dist/solution/VenueBooking/utils/slotMerge.js +5 -10
  93. package/dist/solution/index.d.ts +0 -1
  94. package/dist/solution/index.js +1 -2
  95. package/dist/types/index.d.ts +1 -1
  96. package/dist/utils/payment-number.d.ts +9 -0
  97. package/dist/utils/payment-number.js +69 -0
  98. package/lib/core/index.d.ts +2 -0
  99. package/lib/core/index.js +4 -0
  100. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  101. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  102. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  103. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  104. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  105. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  106. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  107. package/lib/model/strategy/adapter/promotion/index.js +51 -0
  108. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  109. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  110. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  111. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  112. package/lib/modules/Discount/index.d.ts +0 -1
  113. package/lib/modules/Discount/index.js +0 -9
  114. package/lib/modules/Discount/types.d.ts +0 -1
  115. package/lib/modules/OpenData/index.d.ts +2 -0
  116. package/lib/modules/OpenData/index.js +6 -1
  117. package/lib/modules/Order/index.d.ts +29 -12
  118. package/lib/modules/Order/index.js +196 -86
  119. package/lib/modules/Order/payment-utils.d.ts +26 -0
  120. package/lib/modules/Order/payment-utils.js +224 -0
  121. package/lib/modules/Order/types.d.ts +33 -10
  122. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  123. package/lib/modules/Order/utils.d.ts +0 -10
  124. package/lib/modules/Order/utils.js +16 -40
  125. package/lib/modules/Payment/index.d.ts +2 -0
  126. package/lib/modules/Payment/index.js +34 -13
  127. package/lib/modules/Payment/types.d.ts +99 -28
  128. package/lib/modules/Payment/types.js +4 -3
  129. package/lib/modules/Payment/walletpass.d.ts +25 -1
  130. package/lib/modules/Payment/walletpass.js +470 -21
  131. package/lib/modules/Product/types.d.ts +0 -1
  132. package/lib/modules/ProductList/index.js +31 -40
  133. package/lib/modules/Quotation/index.d.ts +1 -1
  134. package/lib/modules/Quotation/index.js +2 -2
  135. package/lib/modules/Rules/index.d.ts +1 -0
  136. package/lib/modules/Rules/index.js +47 -40
  137. package/lib/modules/SalesSummary/index.js +7 -6
  138. package/lib/modules/ScanOrderLogger/index.d.ts +0 -2
  139. package/lib/modules/ScanOrderLogger/index.js +1 -13
  140. package/lib/modules/ScanOrderLogger/providers/feishu.js +6 -15
  141. package/lib/modules/ScanOrderLogger/types.d.ts +0 -1
  142. package/lib/modules/Schedule/index.d.ts +1 -3
  143. package/lib/modules/Schedule/index.js +8 -10
  144. package/lib/modules/Summary/utils.js +1 -21
  145. package/lib/modules/index.d.ts +0 -2
  146. package/lib/modules/index.js +1 -5
  147. package/lib/plugins/window.d.ts +0 -1
  148. package/lib/server/index.d.ts +16 -14
  149. package/lib/server/index.js +675 -83
  150. package/lib/server/modules/order/index.d.ts +54 -4
  151. package/lib/server/modules/order/index.js +679 -66
  152. package/lib/server/modules/order/types.d.ts +11 -3
  153. package/lib/solution/BaseSales/index.d.ts +109 -20
  154. package/lib/solution/BaseSales/index.js +883 -70
  155. package/lib/solution/BaseSales/types.d.ts +52 -0
  156. package/lib/solution/BaseSales/types.js +2 -1
  157. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  158. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  159. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  160. package/lib/solution/BookingByStep/index.d.ts +2 -17
  161. package/lib/solution/BookingByStep/index.js +18 -60
  162. package/lib/solution/BookingByStep/types.d.ts +1 -2
  163. package/lib/solution/BookingByStep/types.js +0 -5
  164. package/lib/solution/BookingByStep/utils/capacity.js +1 -20
  165. package/lib/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  166. package/lib/solution/BookingByStep/utils/timeslots.js +11 -19
  167. package/lib/solution/BookingTicket/index.d.ts +7 -3
  168. package/lib/solution/BookingTicket/index.js +62 -9
  169. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -0
  170. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  171. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +36 -4
  172. package/lib/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  173. package/lib/solution/BookingTicket/utils/weighingProductSku.js +63 -0
  174. package/lib/solution/Sales/index.d.ts +1 -0
  175. package/lib/solution/Sales/index.js +5 -3
  176. package/lib/solution/ScanOrder/index.d.ts +14 -26
  177. package/lib/solution/ScanOrder/index.js +190 -449
  178. package/lib/solution/ScanOrder/types.d.ts +1 -21
  179. package/lib/solution/ScanOrder/utils.d.ts +0 -8
  180. package/lib/solution/ScanOrder/utils.js +0 -31
  181. package/lib/solution/ShopDiscount/index.d.ts +0 -1
  182. package/lib/solution/ShopDiscount/index.js +0 -14
  183. package/lib/solution/VenueBooking/index.d.ts +11 -39
  184. package/lib/solution/VenueBooking/index.js +123 -328
  185. package/lib/solution/VenueBooking/types.d.ts +0 -3
  186. package/lib/solution/VenueBooking/utils/resource.js +0 -1
  187. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  188. package/lib/solution/VenueBooking/utils/slotMerge.js +4 -6
  189. package/lib/solution/index.d.ts +0 -1
  190. package/lib/solution/index.js +1 -3
  191. package/lib/types/index.d.ts +1 -1
  192. package/lib/utils/payment-number.d.ts +9 -0
  193. package/lib/utils/payment-number.js +64 -0
  194. package/package.json +1 -1
  195. package/dist/modules/Holder/index.d.ts +0 -48
  196. package/dist/modules/Holder/index.js +0 -640
  197. package/dist/modules/Holder/types.d.ts +0 -123
  198. package/dist/modules/Holder/types.js +0 -1
  199. package/dist/modules/Holder/utils.d.ts +0 -13
  200. package/dist/modules/Holder/utils.js +0 -34
  201. package/dist/modules/ResourcePlanner/index.d.ts +0 -24
  202. package/dist/modules/ResourcePlanner/index.js +0 -181
  203. package/dist/modules/ResourcePlanner/planner.d.ts +0 -14
  204. package/dist/modules/ResourcePlanner/planner.js +0 -1069
  205. package/dist/modules/ResourcePlanner/types.d.ts +0 -227
  206. package/dist/modules/ResourcePlanner/types.js +0 -1
  207. package/dist/solution/UnifiedBookingSales/index.d.ts +0 -183
  208. package/dist/solution/UnifiedBookingSales/index.js +0 -1871
  209. package/dist/solution/UnifiedBookingSales/types.d.ts +0 -143
  210. package/dist/solution/UnifiedBookingSales/types.js +0 -11
  211. package/lib/modules/Holder/index.d.ts +0 -48
  212. package/lib/modules/Holder/index.js +0 -402
  213. package/lib/modules/Holder/types.d.ts +0 -123
  214. package/lib/modules/Holder/types.js +0 -17
  215. package/lib/modules/Holder/utils.d.ts +0 -13
  216. package/lib/modules/Holder/utils.js +0 -71
  217. package/lib/modules/ResourcePlanner/index.d.ts +0 -24
  218. package/lib/modules/ResourcePlanner/index.js +0 -148
  219. package/lib/modules/ResourcePlanner/planner.d.ts +0 -14
  220. package/lib/modules/ResourcePlanner/planner.js +0 -933
  221. package/lib/modules/ResourcePlanner/types.d.ts +0 -227
  222. package/lib/modules/ResourcePlanner/types.js +0 -17
  223. package/lib/solution/UnifiedBookingSales/index.d.ts +0 -183
  224. package/lib/solution/UnifiedBookingSales/index.js +0 -1076
  225. package/lib/solution/UnifiedBookingSales/types.d.ts +0 -143
  226. package/lib/solution/UnifiedBookingSales/types.js +0 -33
@@ -77,15 +77,10 @@ function calculateResourceAvailableTime({
77
77
  function findFastestAvailableResource({
78
78
  resources,
79
79
  currentCapacity = 1,
80
- countMap = {},
81
- targetDate,
82
- durationMinutes = 30
80
+ countMap = {}
83
81
  }) {
84
82
  var _a, _b, _c;
85
83
  const currentTime = (0, import_dayjs.default)();
86
- const resolvedDuration = durationMinutes > 0 ? durationMinutes : 30;
87
- const targetDay = targetDate ? (0, import_dayjs.default)(targetDate) : currentTime;
88
- const isTargetDayToday = targetDay.isSame(currentTime, "day");
89
84
  let fastestTime = null;
90
85
  let fastestResources = [];
91
86
  console.log("[TimeslotUtils] 查找最快可用资源:", {
@@ -95,22 +90,19 @@ function findFastestAvailableResource({
95
90
  countMap
96
91
  });
97
92
  for (const resource of resources) {
98
- const targetDayTimes = resource.times.filter((time) => {
99
- const isSameTargetDay = (0, import_dayjs.default)(time.start_at).isSame(targetDay, "day");
100
- if (!isSameTargetDay)
101
- return false;
102
- if (!isTargetDayToday)
103
- return true;
104
- return (0, import_dayjs.default)(time.end_at).isAfter(currentTime);
93
+ const todayTimes = resource.times.filter((time) => {
94
+ const isToday = (0, import_dayjs.default)(time.start_at).isSame(currentTime, "day");
95
+ const isStillWorking = (0, import_dayjs.default)(time.end_at).isAfter(currentTime);
96
+ return isToday && isStillWorking;
105
97
  });
106
- if (targetDayTimes.length === 0) {
98
+ if (todayTimes.length === 0) {
107
99
  console.log(`[TimeslotUtils] 资源 ${resource.id}(${resource.main_field}) 今日无可用时间段`);
108
100
  continue;
109
101
  }
110
- for (const time of targetDayTimes) {
102
+ for (const time of todayTimes) {
111
103
  const workStartTime = (0, import_dayjs.default)(time.start_at);
112
104
  const workEndTime = (0, import_dayjs.default)(time.end_at);
113
- let nextAvailableTime = isTargetDayToday && currentTime.isAfter(workStartTime) ? currentTime : workStartTime;
105
+ let nextAvailableTime = currentTime.isBefore(workStartTime) ? workStartTime : currentTime;
114
106
  console.log(`[TimeslotUtils] 检查资源 ${resource.id}(${resource.main_field}):`, {
115
107
  workTime: `${workStartTime.format("HH:mm")}-${workEndTime.format("HH:mm")}`,
116
108
  checkStartTime: nextAvailableTime.format("HH:mm:ss"),
@@ -134,7 +126,7 @@ function findFastestAvailableResource({
134
126
  pax: event.pax || 1
135
127
  });
136
128
  if (resource.resourceType === "single" || (resource.capacity || 1) === 1) {
137
- if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(resolvedDuration, "minute"))) {
129
+ if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(30, "minute"))) {
138
130
  finalAvailableTime = eventEnd;
139
131
  console.log(`[TimeslotUtils] 发现时间冲突,调整到: ${finalAvailableTime.format("HH:mm:ss")}`);
140
132
  }
@@ -142,7 +134,7 @@ function findFastestAvailableResource({
142
134
  const totalCapacity = resource.capacity || 0;
143
135
  const currentUsedCapacity = countMap[resource.id] || 0;
144
136
  const eventUsedCapacity = event.pax || 1;
145
- if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(resolvedDuration, "minute"))) {
137
+ if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(30, "minute"))) {
146
138
  const totalRequiredCapacity = currentUsedCapacity + currentCapacity + eventUsedCapacity;
147
139
  if (totalRequiredCapacity > totalCapacity) {
148
140
  finalAvailableTime = eventEnd;
@@ -151,7 +143,7 @@ function findFastestAvailableResource({
151
143
  }
152
144
  }
153
145
  }
154
- if (finalAvailableTime.add(resolvedDuration, "minute").isAfter(workEndTime)) {
146
+ if (finalAvailableTime.isAfter(workEndTime)) {
155
147
  console.log(`[TimeslotUtils] 资源 ${resource.id} 可用时间超出工作时间,跳过`);
156
148
  continue;
157
149
  }
@@ -46,6 +46,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
46
46
  private getIdGeneratorPlugin;
47
47
  private loadOpenDataConfig;
48
48
  getOpenData(): Promise<OpenDataConfig | null>;
49
+ /** 清除店铺级 OpenData;下一次 getOpenData 时会重新拉取。 */
50
+ clearOpenDataCache(): void;
49
51
  private getShortNumberOrDeviceId;
50
52
  private configureIdGeneratorFromOpenData;
51
53
  private normalizePositiveInteger;
@@ -189,10 +191,12 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
189
191
  */
190
192
  getCustomer(): ICustomer | null;
191
193
  /**
192
- * 通过 ids 获取商品列表(不加载到模块中)
193
- * @returns 商品列表
194
+ * 通过 ids 获取商品列表;默认只读取内存,显式开启 loadMissing 时按当前订单上下文补查缺失商品。
195
+ * 补查直接写入 ProductList,不更新 BookingTicket.productCatalog,避免当前商品列表被查询子集覆盖。
194
196
  */
195
- getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
197
+ getProductByIds(ids: number[], options?: {
198
+ loadMissing?: boolean;
199
+ }): Promise<ProductData[]>;
196
200
  /**
197
201
  * 获取日程时间段点
198
202
  * @param params 参数
@@ -219,8 +219,14 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
219
219
  }
220
220
  }
221
221
  async getOpenData() {
222
+ return this.loadOpenDataConfig();
223
+ }
224
+ /** 清除店铺级 OpenData;下一次 getOpenData 时会重新拉取。 */
225
+ clearOpenDataCache() {
222
226
  var _a;
223
- return (_a = this.store.openData) == null ? void 0 : _a.getOpenData();
227
+ this.loadOpenDataConfigInFlight = null;
228
+ this.otherParams.openData = null;
229
+ (_a = this.store.openData) == null ? void 0 : _a.clearCache();
224
230
  }
225
231
  async getShortNumberOrDeviceId() {
226
232
  const getAsyncIotDeviceInfo = this.getAppData("async_iot_device_info");
@@ -233,6 +239,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
233
239
  return String(this.getAppData("device_id") || 0).slice(-2);
234
240
  }
235
241
  async configureIdGeneratorFromOpenData() {
242
+ this.setPaymentNumberDevicePrefix(null);
236
243
  let openDataConfig = null;
237
244
  try {
238
245
  openDataConfig = await this.loadOpenDataConfig();
@@ -264,6 +271,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
264
271
  const resetReceiptSequenceDaily = typeof (openDataConfig == null ? void 0 : openDataConfig["sale.short_number_daily_reset"]) === "boolean" ? openDataConfig == null ? void 0 : openDataConfig["sale.short_number_daily_reset"] : false;
265
272
  const operatingDayBoundary = this.getAppData("operating_day_boundary");
266
273
  const deviceId = await this.getShortNumberOrDeviceId();
274
+ this.setPaymentNumberDevicePrefix(deviceId);
267
275
  const businessCode = this.getBookingTicketBusinessCode();
268
276
  if (!businessCode) {
269
277
  console.warn("[BookingTicket] businessCode 缺失,跳过 idGenerator 配置");
@@ -714,11 +722,53 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
714
722
  return this.getOrderCustomerSnapshot();
715
723
  }
716
724
  /**
717
- * 通过 ids 获取商品列表(不加载到模块中)
718
- * @returns 商品列表
725
+ * 通过 ids 获取商品列表;默认只读取内存,显式开启 loadMissing 时按当前订单上下文补查缺失商品。
726
+ * 补查直接写入 ProductList,不更新 BookingTicket.productCatalog,避免当前商品列表被查询子集覆盖。
719
727
  */
720
- async getProductByIds(ids) {
721
- return this.store.products.getProductByIds(ids);
728
+ async getProductByIds(ids, options) {
729
+ var _a, _b;
730
+ const normalizedIds = Array.from(
731
+ new Set(
732
+ (ids || []).map((id) => Number(id)).filter((id) => Number.isFinite(id))
733
+ )
734
+ );
735
+ const localProducts = await this.store.products.getProductByIds(normalizedIds) || [];
736
+ if (!(options == null ? void 0 : options.loadMissing)) {
737
+ return localProducts;
738
+ }
739
+ const localProductIds = new Set(
740
+ localProducts.map((product) => Number(product.id))
741
+ );
742
+ const missingIds = normalizedIds.filter(
743
+ (id) => !localProductIds.has(id)
744
+ );
745
+ if (!missingIds.length) {
746
+ return localProducts;
747
+ }
748
+ const rawBookingDate = this.getBookingDate();
749
+ const bookingDate = rawBookingDate && (0, import_dayjs.default)(rawBookingDate).isValid() ? (0, import_dayjs.default)(rawBookingDate) : null;
750
+ const customerId = Number(
751
+ ((_a = this.getOrderCustomerSnapshot()) == null ? void 0 : _a.id) ?? ((_b = this.getOrderCustomer()) == null ? void 0 : _b.customer_id)
752
+ );
753
+ const loadedProducts = await this.store.products.loadProducts({
754
+ product_ids: missingIds,
755
+ with_count: ["bundleGroup", "optionGroup"],
756
+ with_schedule: 1,
757
+ cacheId: this.cacheId,
758
+ ...bookingDate ? {
759
+ schedule_date: bookingDate.format("YYYY-MM-DD"),
760
+ schedule_datetime: bookingDate.format("YYYY-MM-DD HH:mm:ss")
761
+ } : {},
762
+ ...Number.isFinite(customerId) && customerId > 0 ? { customer_id: customerId } : {}
763
+ });
764
+ const productById = /* @__PURE__ */ new Map();
765
+ [...localProducts, ...loadedProducts || []].forEach((product) => {
766
+ const productId = Number(product.id);
767
+ if (Number.isFinite(productId)) {
768
+ productById.set(productId, product);
769
+ }
770
+ });
771
+ return normalizedIds.map((id) => productById.get(id)).filter((product) => Boolean(product));
722
772
  }
723
773
  /**
724
774
  * 获取日程时间段点
@@ -1153,7 +1203,8 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1153
1203
  }
1154
1204
  /** 读取当前 booking config。 */
1155
1205
  getBookingConfig() {
1156
- return this.store.bookingContext.getBookingConfig();
1206
+ var _a;
1207
+ return (_a = this.store.bookingContext) == null ? void 0 : _a.getBookingConfig();
1157
1208
  }
1158
1209
  /** 写入资源全集(来源:`/form/schedule`),同步派生 resourcesOriginMap。 */
1159
1210
  setResources(resources) {
@@ -1389,7 +1440,9 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1389
1440
  decideAddProduct: (item, options) => this.decideAddProduct(item, options),
1390
1441
  decideAfterDetail: (cacheItem, options) => this.decideAfterDetail(cacheItem, options),
1391
1442
  transformDetailToProductAndBooking: (input) => this.transformDetailToProductAndBooking(input),
1392
- addProductToOrder: (product, booking) => this.addProductToOrder(product, booking)
1443
+ addProductToOrder: (product, booking) => this.addProductToOrder(product, booking),
1444
+ refreshWalletAssets: (params) => this.refreshWalletAssets(params),
1445
+ scanWalletAsset: (scanCode) => this.scanWalletAsset(scanCode)
1393
1446
  },
1394
1447
  formatted,
1395
1448
  bridge
@@ -1526,8 +1579,8 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1526
1579
  return result;
1527
1580
  }
1528
1581
  async setOtherParams(params, { cover = false } = {}) {
1529
- super.setOtherParams(params, { cover });
1530
- if (params == null ? void 0 : params.businessCode) {
1582
+ await super.setOtherParams(params, { cover });
1583
+ if ((params == null ? void 0 : params.businessCode) !== void 0 || (params == null ? void 0 : params.business_code) !== void 0) {
1531
1584
  await this.configureIdGeneratorFromOpenData();
1532
1585
  }
1533
1586
  }
@@ -44,6 +44,7 @@ module.exports = __toCommonJS(addProductDecision_exports);
44
44
  var import_dayjs = __toESM(require("dayjs"));
45
45
  var import_BookingContext = require("../../../modules/BookingContext");
46
46
  var import_transformBaseProductToOrderProduct = require("../../BaseSales/utils/transformBaseProductToOrderProduct");
47
+ var import_weighingProductSku = require("./weighingProductSku");
47
48
  function needsSpecDetailModal(item) {
48
49
  if (item == null ? void 0 : item.open_sold_weight)
49
50
  return true;
@@ -281,11 +282,14 @@ function buildBasePayloadFromCacheItem(cacheItem, ctx) {
281
282
  const quantity = (ctx == null ? void 0 : ctx.quantity) != null && ctx.quantity > 0 ? ctx.quantity : ((_b = cacheItem == null ? void 0 : cacheItem._extend) == null ? void 0 : _b.quantity) ?? 1;
282
283
  const resolvedPid = (cacheItem == null ? void 0 : cacheItem.product_id) ?? (cacheItem == null ? void 0 : cacheItem.id);
283
284
  const extend = (cacheItem == null ? void 0 : cacheItem._extend) || {};
285
+ const productSku = (0, import_weighingProductSku.buildProductSkuFromCacheItem)(cacheItem);
284
286
  return {
285
287
  id: (cacheItem == null ? void 0 : cacheItem.id) ?? (cacheItem == null ? void 0 : cacheItem.product_id),
286
288
  product_id: resolvedPid,
287
289
  variant_id: (other == null ? void 0 : other.product_variant_id) ?? (other == null ? void 0 : other.variant_id) ?? 0,
288
290
  quantity,
291
+ // 规格弹窗本次选择是 option 权威源,避免目录/旧订单里的空 option 覆盖它。
292
+ product_sku: productSku ? { ...productSku, option: (other == null ? void 0 : other.option) || [] } : void 0,
289
293
  option: (other == null ? void 0 : other.option) || [],
290
294
  bundle: (other == null ? void 0 : other.bundle) || ((_c = extend == null ? void 0 : extend.skuValue) == null ? void 0 : _c.bundle) || ((_d = extend == null ? void 0 : extend._skuValue) == null ? void 0 : _d.bundle) || [],
291
295
  unique: other == null ? void 0 : other.unique,
@@ -24,6 +24,14 @@ export interface GlobalScanApplyHost {
24
24
  cacheItem: any;
25
25
  };
26
26
  addProductToOrder(product: any, booking?: any): Promise<any>;
27
+ refreshWalletAssets?(params?: {
28
+ preserveSelection?: boolean;
29
+ }): Promise<any>;
30
+ scanWalletAsset?(code: string): Promise<{
31
+ type: 'walletCode' | 'normalCode';
32
+ asset?: any;
33
+ selected: boolean;
34
+ }>;
27
35
  }
28
36
  /**
29
37
  * 应用全局扫码格式化结果:设客户 / 加车 / 开单 / 弹窗链。
@@ -101,13 +101,32 @@ async function applyGlobalScan(host, formatted, bridge) {
101
101
  return { status: "success", kind: "customer" };
102
102
  }
103
103
  if (searchType === "walletPass") {
104
- if (!data) {
105
- (_c = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _c.call(bridge, "fail", "pisell2.text.scan-global-failed");
106
- return { status: "failed", reason: "invalid_data" };
107
- }
108
104
  const snapshot = host.getOrderCustomerSnapshot();
109
105
  const scannedCustomerIsWalkIn = (0, import_cartView.isWalkInCustomer)(data);
106
+ const trySelectWalletAsset = async () => {
107
+ var _a2, _b2;
108
+ if (!host.scanWalletAsset)
109
+ return null;
110
+ const walletResult = await host.scanWalletAsset(scanCode).catch((error) => {
111
+ console.warn("[GlobalScan] Wallet asset lookup failed", error);
112
+ return null;
113
+ });
114
+ if (!walletResult)
115
+ return null;
116
+ if (walletResult.type !== "normalCode" || !walletResult.asset) {
117
+ return null;
118
+ }
119
+ if (walletResult.selected) {
120
+ (_a2 = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _a2.call(bridge, "success");
121
+ return { status: "success", kind: "promotion" };
122
+ }
123
+ (_b2 = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _b2.call(bridge, "fail", "pisell2.text.goodpass.code-invalid-cart");
124
+ return { status: "failed", reason: "invalid_data" };
125
+ };
110
126
  if ((0, import_cartView.isWalkInCustomer)(snapshot) || scannedCustomerIsWalkIn) {
127
+ const walletSelection2 = await trySelectWalletAsset();
128
+ if (walletSelection2)
129
+ return walletSelection2;
111
130
  if (!(bridge == null ? void 0 : bridge.applyPromotionCode)) {
112
131
  return { status: "failed", reason: "no_bridge" };
113
132
  }
@@ -118,6 +137,19 @@ async function applyGlobalScan(host, formatted, bridge) {
118
137
  return { status: "failed", reason: "invalid_data" };
119
138
  }
120
139
  host.setOrderCustomer(data);
140
+ await ((_c = host.refreshWalletAssets) == null ? void 0 : _c.call(host, { preserveSelection: false }));
141
+ const walletSelection = await trySelectWalletAsset();
142
+ if (walletSelection)
143
+ return walletSelection;
144
+ if (bridge == null ? void 0 : bridge.applyPromotionCode) {
145
+ const promotionResult = await bridge.applyPromotionCode(
146
+ scanCode,
147
+ Number((data == null ? void 0 : data.id) ?? (data == null ? void 0 : data.customer_id)) || void 0
148
+ );
149
+ if (promotionResult == null ? void 0 : promotionResult.isAvailable) {
150
+ return { status: "success", kind: "promotion" };
151
+ }
152
+ }
121
153
  (_d = bridge == null ? void 0 : bridge.onNotify) == null ? void 0 : _d.call(bridge, "success", "pisell2.text.add-client-success");
122
154
  return { status: "success", kind: "customer" };
123
155
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 将规格弹窗的称重结果写入订单行权威字段 product_sku。
3
+ * 商品目录已有的 SKU 字段会保留,本次称重结果只覆盖运行态称重字段。
4
+ */
5
+ export declare function buildProductSkuFromCacheItem(cacheItem: Record<string, any> | null | undefined): Record<string, any> | undefined;
@@ -0,0 +1,63 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/solution/BookingTicket/utils/weighingProductSku.ts
20
+ var weighingProductSku_exports = {};
21
+ __export(weighingProductSku_exports, {
22
+ buildProductSkuFromCacheItem: () => buildProductSkuFromCacheItem
23
+ });
24
+ module.exports = __toCommonJS(weighingProductSku_exports);
25
+ var WEIGHT_UNIT_MAP = {
26
+ KILOGRAMS: "kg",
27
+ GRAMS: "g",
28
+ POUNDS: "lb",
29
+ OUNCES: "oz"
30
+ };
31
+ function isRecord(value) {
32
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
33
+ }
34
+ function buildProductSkuFromCacheItem(cacheItem) {
35
+ var _a, _b, _c, _d;
36
+ const currentSku = isRecord(cacheItem == null ? void 0 : cacheItem.product_sku) ? cacheItem.product_sku : void 0;
37
+ const weighing = isRecord((_a = cacheItem == null ? void 0 : cacheItem._extend) == null ? void 0 : _a.weighing) ? (_b = cacheItem == null ? void 0 : cacheItem._extend) == null ? void 0 : _b.weighing : void 0;
38
+ const hasRuntimeWeighingSku = Number((currentSku == null ? void 0 : currentSku.open_sold_weight) || 0) === 1 && ((currentSku == null ? void 0 : currentSku.weight) !== void 0 || (currentSku == null ? void 0 : currentSku.net_weight) !== void 0 || (currentSku == null ? void 0 : currentSku.weight_source) !== void 0);
39
+ const isWeighingSku = Number((currentSku == null ? void 0 : currentSku.open_sold_weight) || 0) === 1;
40
+ if (!isWeighingSku && !weighing)
41
+ return void 0;
42
+ if (hasRuntimeWeighingSku)
43
+ return { ...currentSku };
44
+ if (!weighing)
45
+ return currentSku ? { ...currentSku } : void 0;
46
+ return {
47
+ ...currentSku || {},
48
+ open_sold_weight: 1,
49
+ unit_data_snapshot: weighing.scalePriceProduct,
50
+ unit: WEIGHT_UNIT_MAP[String(weighing.unit)] || weighing.unit,
51
+ unit_weight: weighing.unit_weight ?? "1.000",
52
+ unit_price: weighing.unit_price,
53
+ weight_source: weighing.mode,
54
+ tare_name: ((_c = weighing.tare) == null ? void 0 : _c.label) ?? "",
55
+ tare_weight: ((_d = weighing.tare) == null ? void 0 : _d.value) ?? 0,
56
+ weight: weighing.weight ?? 0,
57
+ net_weight: weighing.net_weight ?? 0
58
+ };
59
+ }
60
+ // Annotate the CommonJS export names for ESM import in node:
61
+ 0 && (module.exports = {
62
+ buildProductSkuFromCacheItem
63
+ });
@@ -83,6 +83,7 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
83
83
  private getBookingAppointmentStatus;
84
84
  private isBookingIncludedInStats;
85
85
  private getBookingOrderPaymentStatus;
86
+ private isUnpaidBooking;
86
87
  private countBookingOrders;
87
88
  private countCompletedBookings;
88
89
  private groupBookingsByResource;
@@ -39,6 +39,7 @@ var import_dayjs = __toESM(require("dayjs"));
39
39
  var import_BaseModule = require("../../modules/BaseModule");
40
40
  var import_types = require("./types");
41
41
  __reExport(Sales_exports, require("./types"), module.exports);
42
+ var UNPAID_PAYMENT_STATUSES = /* @__PURE__ */ new Set(["unpaid", "partially_paid", "payment_processing"]);
42
43
  var SalesImpl = class extends import_BaseModule.BaseModule {
43
44
  // LoggerManager 实例
44
45
  constructor(name, version) {
@@ -258,6 +259,9 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
258
259
  var _a;
259
260
  return String(((_a = booking.order) == null ? void 0 : _a.payment_status) ?? "");
260
261
  }
262
+ isUnpaidBooking(booking) {
263
+ return UNPAID_PAYMENT_STATUSES.has(this.getBookingOrderPaymentStatus(booking));
264
+ }
261
265
  countBookingOrders(bookings) {
262
266
  const orderIds = /* @__PURE__ */ new Set();
263
267
  bookings.forEach((booking) => {
@@ -631,9 +635,7 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
631
635
  const completedBookingList = matchedBookingList.filter(
632
636
  (booking) => this.getBookingAppointmentStatus(booking) === "completed"
633
637
  );
634
- const unpaidBookingList = matchedBookingList.filter(
635
- (booking) => this.getBookingOrderPaymentStatus(booking) === "unpaid" || this.getBookingOrderPaymentStatus(booking) === "payment_processing"
636
- );
638
+ const unpaidBookingList = matchedBookingList.filter((booking) => this.isUnpaidBooking(booking));
637
639
  const bookings = this.pickBookingsForCurrentPoint(
638
640
  current,
639
641
  this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
@@ -1,9 +1,8 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
- import { BaseSalesImpl } from '../BaseSales';
3
- import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderAllowAddItemsInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderReservationResourceSelectInfo, ScanOrderState, ScanOrderScanCodeResult, ScanOrderSyncAdditionalOrderResult } from './types';
2
+ import { BaseModule } from '../../modules/BaseModule';
3
+ import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderScanCodeResult } from './types';
4
4
  import type { UpdateOrderProductParams } from '../../modules/Order/types';
5
5
  import type { Discount } from '../../modules/Discount/types';
6
- import { RequestPlugin, WindowPlugin } from '../../plugins';
7
6
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
8
7
  import type { StrategyConfig } from '../../model/strategy/type';
9
8
  import type { ProductData } from '../../modules/Product/types';
@@ -16,16 +15,16 @@ interface ScanOrderItemRuleRuntimeConfig {
16
15
  submissionIndex?: number;
17
16
  custom?: Record<string, any>;
18
17
  }
19
- export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
18
+ export declare class ScanOrderImpl extends BaseModule implements Module {
20
19
  protected defaultName: string;
21
20
  protected defaultVersion: string;
22
21
  isSolution: boolean;
23
- protected initializeOptions: ModuleOptions;
24
- protected store: ScanOrderState;
25
- protected otherParams: Record<string, any>;
26
- protected cacheId: string | undefined;
27
- window: WindowPlugin;
28
- request: RequestPlugin;
22
+ private initializeOptions;
23
+ private store;
24
+ private otherParams;
25
+ private cacheId;
26
+ private window;
27
+ private request;
29
28
  private itemRuleEvaluator;
30
29
  private itemRuleConfigs;
31
30
  private itemRuleConfigsPromise;
@@ -54,10 +53,9 @@ export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
54
53
  private registerCustomerLoginListeners;
55
54
  private refreshOrderMarketingAfterLogin;
56
55
  constructor(name?: string, version?: string);
57
- protected getRegisteredModuleNames(): readonly string[];
58
- protected createSubModule(moduleName: string): Module | null;
59
56
  /** 与 `otherParams.cacheId` 一致,供宿主在 URL 变化时判断是否需要重新注册模块 */
60
57
  getCacheId(): string | undefined;
58
+ private destroyRegisteredChildModules;
61
59
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
62
60
  destroy(): Promise<void>;
63
61
  retryInit(): Promise<void>;
@@ -73,14 +71,12 @@ export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
73
71
  };
74
72
  getTempOrder(): import("../../modules/Order/types").OrderTempOrder | null;
75
73
  updateTempOrderNote(note: string): string;
76
- updateTempOrderNote(note: string, sync: true): Promise<string>;
77
- updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
78
74
  setPickupReferenceMode(mode: 'counter_pickup' | 'table_service'): {
79
- service_type: 'dine_in' | '';
75
+ service_type: 'dine_in';
80
76
  pickup_reference_mode: 'counter_pickup' | 'table_service';
81
77
  };
82
78
  setPickupRef(buzzer: string): string;
83
- private ensureScanOrderTempOrder;
79
+ private ensureTempOrder;
84
80
  addNewOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
85
81
  restoreOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
86
82
  getOrderProducts(): import("../../modules/Order/types").OrderProduct[];
@@ -96,10 +92,7 @@ export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
96
92
  }): Promise<void>;
97
93
  private findReservationRuleResource;
98
94
  private buildScanOrderResourceMetadata;
99
- private prepareRetailAvailability;
100
95
  private buildSubmitPayloadEnhancer;
101
- private isScanOrderMoreMode;
102
- private submitScanOrderMore;
103
96
  submitScanOrder<T = any>(): Promise<T>;
104
97
  addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<import("../../modules/Order/types").OrderProduct[]>;
105
98
  updateOrderProduct(params: UpdateOrderProductParams): Promise<import("../../modules/Order/types").OrderProduct[]>;
@@ -124,10 +117,8 @@ export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
124
117
  setItemRuleRuntimeConfig(config?: ScanOrderItemRuleRuntimeConfig): Promise<void>;
125
118
  private normalizeResourceState;
126
119
  private resolveResourceSelectType;
127
- private fetchResourceOccupyDetailsByResourceId;
128
- private resolveAdditionalOrderFromOccupyDetail;
129
- checkResourceAvailable(resourceId?: string | null, hasOrderId?: boolean): Promise<ScanOrderAvailabilityInfo>;
130
- restorePreviousOrderData(): Promise<void>;
120
+ private fetchResourceOccupyDetailByResourceId;
121
+ checkResourceAvailable(resourceId: string, hasOrderId: boolean): Promise<ScanOrderAvailabilityInfo>;
131
122
  getAdditionalOrderInfo(): Promise<{
132
123
  orderId: string;
133
124
  orderStatus: 'pending' | 'processing' | 'completed' | 'cancelled';
@@ -150,9 +141,6 @@ export declare class ScanOrderImpl extends BaseSalesImpl implements Module {
150
141
  clearUIState(): void;
151
142
  setEntryPaxNumber(number: number): Promise<void>;
152
143
  getEntryPaxNumber(): number | null;
153
- syncAdditionalOrderFromResource(resourceId?: string | null): Promise<ScanOrderSyncAdditionalOrderResult>;
154
- getReservationResourceSelectType(): ScanOrderReservationResourceSelectInfo;
155
- checkAllowAddItems(): ScanOrderAllowAddItemsInfo;
156
144
  getFulfillmentModes(): {
157
145
  enablePickup: boolean;
158
146
  enableTableService: boolean;