@pisell/pisellos 2.1.129 → 2.1.131

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 (54) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/Order/index.d.ts +7 -6
  3. package/dist/modules/Order/index.js +137 -42
  4. package/dist/modules/Order/types.d.ts +32 -6
  5. package/dist/modules/Order/types.js +2 -0
  6. package/dist/modules/Order/utils.d.ts +73 -11
  7. package/dist/modules/Order/utils.js +304 -52
  8. package/dist/modules/SalesSummary/utils.js +33 -68
  9. package/dist/modules/ScanOrderLogger/providers/feishu.js +168 -60
  10. package/dist/modules/ScanOrderLogger/types.d.ts +6 -0
  11. package/dist/modules/Summary/utils.js +6 -21
  12. package/dist/solution/ScanOrder/index.d.ts +57 -8
  13. package/dist/solution/ScanOrder/index.js +1531 -583
  14. package/dist/solution/ScanOrder/types.d.ts +86 -26
  15. package/dist/solution/ScanOrder/types.js +20 -1
  16. package/dist/solution/ScanOrder/utils.d.ts +53 -5
  17. package/dist/solution/ScanOrder/utils.js +257 -37
  18. package/dist/solution/VenueBooking/index.d.ts +30 -10
  19. package/dist/solution/VenueBooking/index.js +460 -217
  20. package/dist/solution/VenueBooking/types.d.ts +23 -0
  21. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -1
  22. package/dist/solution/VenueBooking/utils/dateSummary.js +1 -1
  23. package/dist/solution/VenueBooking/utils/resource.d.ts +11 -1
  24. package/dist/solution/VenueBooking/utils/resource.js +57 -21
  25. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +5 -0
  26. package/dist/solution/VenueBooking/utils/slotMerge.js +33 -12
  27. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -1
  28. package/dist/solution/VenueBooking/utils/timeSlot.js +259 -62
  29. package/lib/modules/Order/index.d.ts +7 -6
  30. package/lib/modules/Order/index.js +123 -31
  31. package/lib/modules/Order/types.d.ts +32 -6
  32. package/lib/modules/Order/utils.d.ts +73 -11
  33. package/lib/modules/Order/utils.js +203 -28
  34. package/lib/modules/SalesSummary/utils.js +13 -47
  35. package/lib/modules/ScanOrderLogger/providers/feishu.js +100 -34
  36. package/lib/modules/ScanOrderLogger/types.d.ts +6 -0
  37. package/lib/modules/Summary/utils.js +4 -18
  38. package/lib/solution/ScanOrder/index.d.ts +57 -8
  39. package/lib/solution/ScanOrder/index.js +713 -117
  40. package/lib/solution/ScanOrder/types.d.ts +86 -26
  41. package/lib/solution/ScanOrder/utils.d.ts +53 -5
  42. package/lib/solution/ScanOrder/utils.js +186 -19
  43. package/lib/solution/VenueBooking/index.d.ts +30 -10
  44. package/lib/solution/VenueBooking/index.js +206 -51
  45. package/lib/solution/VenueBooking/types.d.ts +23 -0
  46. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -1
  47. package/lib/solution/VenueBooking/utils/dateSummary.js +1 -1
  48. package/lib/solution/VenueBooking/utils/resource.d.ts +11 -1
  49. package/lib/solution/VenueBooking/utils/resource.js +15 -4
  50. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +5 -0
  51. package/lib/solution/VenueBooking/utils/slotMerge.js +29 -12
  52. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -1
  53. package/lib/solution/VenueBooking/utils/timeSlot.js +182 -43
  54. package/package.json +1 -1
@@ -1,3 +1,13 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
10
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
1
11
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
12
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
13
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -6,6 +16,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6
16
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
7
17
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
18
  import dayjs from 'dayjs';
19
+ import Decimal from 'decimal.js';
9
20
  export function isBusinessHoursCrossDay(config) {
10
21
  var _config$businessStart = config.businessStartTime.split(':').map(Number),
11
22
  _config$businessStart2 = _slicedToArray(_config$businessStart, 2),
@@ -152,6 +163,160 @@ export function computeSlotStatus(params) {
152
163
  remainingCapacity: remaining
153
164
  };
154
165
  }
166
+
167
+ /**
168
+ * 合并多个子商品的同一个时段为一个"外层 slot"。
169
+ * - status 取优先级最高的(available > partially_occupied > occupied > unavailable / past)
170
+ * - price 取非空子 slot 中最小的那个
171
+ * - 其它字段使用第一个参考子 slot(外层 slot 不带 productId)
172
+ */
173
+ function mergeSubSlots(subSlots) {
174
+ var priority = {
175
+ available: 5,
176
+ partially_occupied: 4,
177
+ occupied: 3,
178
+ unavailable: 2,
179
+ past: 1
180
+ };
181
+ var best = subSlots[0];
182
+ var _iterator5 = _createForOfIteratorHelper(subSlots),
183
+ _step5;
184
+ try {
185
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
186
+ var _priority$slot$status, _priority$best$status;
187
+ var slot = _step5.value;
188
+ if (((_priority$slot$status = priority[slot.status]) !== null && _priority$slot$status !== void 0 ? _priority$slot$status : 0) > ((_priority$best$status = priority[best.status]) !== null && _priority$best$status !== void 0 ? _priority$best$status : 0)) best = slot;
189
+ }
190
+ } catch (err) {
191
+ _iterator5.e(err);
192
+ } finally {
193
+ _iterator5.f();
194
+ }
195
+ var minPrice = null;
196
+ var _iterator6 = _createForOfIteratorHelper(subSlots),
197
+ _step6;
198
+ try {
199
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
200
+ var _slot = _step6.value;
201
+ if (_slot.price == null) continue;
202
+ var decimal = new Decimal(_slot.price || '0');
203
+ if (!minPrice || decimal.lt(minPrice)) minPrice = decimal;
204
+ }
205
+ } catch (err) {
206
+ _iterator6.e(err);
207
+ } finally {
208
+ _iterator6.f();
209
+ }
210
+ return {
211
+ startTime: best.startTime,
212
+ endTime: best.endTime,
213
+ status: best.status,
214
+ price: minPrice ? minPrice.toFixed(2) : null,
215
+ resourceId: best.resourceId,
216
+ resourceFormId: best.resourceFormId,
217
+ capacity: best.capacity,
218
+ remainingCapacity: best.remainingCapacity
219
+ };
220
+ }
221
+ function buildProductSlots(params) {
222
+ var date = params.date,
223
+ config = params.config,
224
+ resource = params.resource,
225
+ mapping = params.mapping,
226
+ timeLabels = params.timeLabels,
227
+ timesForDate = params.timesForDate,
228
+ events = params.events,
229
+ resCapacity = params.resCapacity,
230
+ now = params.now,
231
+ crossDay = params.crossDay,
232
+ quotationPriceMap = params.quotationPriceMap,
233
+ childRawResources = params.childRawResources,
234
+ childTimesCache = params.childTimesCache,
235
+ childEventsCache = params.childEventsCache,
236
+ config_businessStartHour = params.config_businessStartHour;
237
+ var slots = [];
238
+ var _iterator7 = _createForOfIteratorHelper(timeLabels),
239
+ _step7;
240
+ try {
241
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
242
+ var _quotationPriceMap$ge;
243
+ var label = _step7.value;
244
+ var _label$split$map = label.split(':').map(Number),
245
+ _label$split$map2 = _slicedToArray(_label$split$map, 1),
246
+ h = _label$split$map2[0];
247
+ var isNextDay = crossDay && h < config_businessStartHour;
248
+ var slotDate = isNextDay ? dayjs(date).add(1, 'day').format('YYYY-MM-DD') : date;
249
+ var slotStart = dayjs("".concat(slotDate, " ").concat(label));
250
+ var slotEnd = slotStart.add(config.slotDurationMinutes, 'minute');
251
+ var status = void 0;
252
+ var remainingCapacity = null;
253
+ if (slotStart.isBefore(now)) {
254
+ status = 'past';
255
+ } else if (!isSlotWithinResourceTimes(slotStart, slotEnd, timesForDate)) {
256
+ status = 'unavailable';
257
+ } else {
258
+ var result = computeSlotStatus({
259
+ slotStart: slotStart,
260
+ slotEnd: slotEnd,
261
+ events: events,
262
+ resourceType: mapping.resourceType,
263
+ capacity: resCapacity
264
+ });
265
+ status = result.status;
266
+ remainingCapacity = result.remainingCapacity;
267
+ if (status !== 'occupied' && childRawResources && childRawResources.length) {
268
+ for (var i = 0; i < childRawResources.length; i++) {
269
+ var _childTimesCache$i, _childEventsCache$i, _child$capacity;
270
+ var child = childRawResources[i];
271
+ var childTimes = (_childTimesCache$i = childTimesCache === null || childTimesCache === void 0 ? void 0 : childTimesCache[i]) !== null && _childTimesCache$i !== void 0 ? _childTimesCache$i : getResourceTimesForDate(child, date, config);
272
+ var childEvents = (_childEventsCache$i = childEventsCache === null || childEventsCache === void 0 ? void 0 : childEventsCache[i]) !== null && _childEventsCache$i !== void 0 ? _childEventsCache$i : collectEventsForDate(child, date, config);
273
+ if (!isSlotWithinResourceTimes(slotStart, slotEnd, childTimes)) {
274
+ status = 'unavailable';
275
+ remainingCapacity = null;
276
+ break;
277
+ }
278
+ var childType = child.type || 'single';
279
+ var childResult = computeSlotStatus({
280
+ slotStart: slotStart,
281
+ slotEnd: slotEnd,
282
+ events: childEvents,
283
+ resourceType: childType,
284
+ capacity: (_child$capacity = child.capacity) !== null && _child$capacity !== void 0 ? _child$capacity : 1
285
+ });
286
+ if (childResult.status === 'occupied') {
287
+ status = 'occupied';
288
+ remainingCapacity = 0;
289
+ break;
290
+ }
291
+ if (childResult.status === 'partially_occupied' && status === 'available') {
292
+ var _remainingCapacity;
293
+ status = 'partially_occupied';
294
+ remainingCapacity = Math.min((_remainingCapacity = remainingCapacity) !== null && _remainingCapacity !== void 0 ? _remainingCapacity : childResult.remainingCapacity, childResult.remainingCapacity);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ var isBookable = status === 'available' || status === 'partially_occupied';
300
+ var slotStartStr = slotStart.format('YYYY-MM-DD HH:mm');
301
+ slots.push({
302
+ startTime: slotStartStr,
303
+ endTime: slotEnd.format('YYYY-MM-DD HH:mm'),
304
+ status: status,
305
+ price: isBookable ? (_quotationPriceMap$ge = quotationPriceMap === null || quotationPriceMap === void 0 ? void 0 : quotationPriceMap.get("".concat(mapping.productId, ":").concat(slotStartStr))) !== null && _quotationPriceMap$ge !== void 0 ? _quotationPriceMap$ge : mapping.price : null,
306
+ resourceId: resource.resourceId,
307
+ resourceFormId: resource.formId,
308
+ capacity: status === 'past' || status === 'unavailable' ? null : resCapacity,
309
+ remainingCapacity: remainingCapacity,
310
+ productId: mapping.productId
311
+ });
312
+ }
313
+ } catch (err) {
314
+ _iterator7.e(err);
315
+ } finally {
316
+ _iterator7.f();
317
+ }
318
+ return slots;
319
+ }
155
320
  export function buildTimeSlotGrid(params) {
156
321
  var date = params.date,
157
322
  config = params.config,
@@ -161,83 +326,115 @@ export function buildTimeSlotGrid(params) {
161
326
  var timeLabels = generateTimeLabels(config);
162
327
  var now = dayjs();
163
328
  var crossDay = isBusinessHoursCrossDay(config);
329
+ var config_businessStartHour = Number(config.businessStartTime.split(':')[0]);
330
+ var rawResourceById = new Map();
331
+ var _iterator8 = _createForOfIteratorHelper(rawResources),
332
+ _step8;
333
+ try {
334
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
335
+ var item = _step8.value;
336
+ rawResourceById.set(item.resourceId, item);
337
+ }
338
+ } catch (err) {
339
+ _iterator8.e(err);
340
+ } finally {
341
+ _iterator8.f();
342
+ }
164
343
  var resources = [];
165
- var _iterator5 = _createForOfIteratorHelper(rawResources),
166
- _step5;
344
+ var _iterator9 = _createForOfIteratorHelper(rawResources),
345
+ _step9;
167
346
  try {
168
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
347
+ var _loop = function _loop() {
169
348
  var _resource$capacity;
170
- var resource = _step5.value;
171
- var mapping = resourceProductMap.get(resource.resourceId);
172
- if (!mapping) continue;
349
+ var resource = _step9.value;
350
+ var mappings = resourceProductMap.get(resource.resourceId);
351
+ if (!mappings || !mappings.length) return 1; // continue
173
352
  var timesForDate = getResourceTimesForDate(resource, date, config);
174
353
  var events = collectEventsForDate(resource, date, config);
175
354
  var resCapacity = (_resource$capacity = resource.capacity) !== null && _resource$capacity !== void 0 ? _resource$capacity : 1;
176
- var slots = [];
177
- var _iterator6 = _createForOfIteratorHelper(timeLabels),
178
- _step6;
179
- try {
180
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
181
- var _quotationPriceMap$ge;
182
- var label = _step6.value;
183
- var _label$split$map = label.split(':').map(Number),
184
- _label$split$map2 = _slicedToArray(_label$split$map, 2),
185
- h = _label$split$map2[0],
186
- m = _label$split$map2[1];
187
- var isNextDay = crossDay && h < Number(config.businessStartTime.split(':')[0]);
188
- var slotDate = isNextDay ? dayjs(date).add(1, 'day').format('YYYY-MM-DD') : date;
189
- var slotStart = dayjs("".concat(slotDate, " ").concat(label));
190
- var slotEnd = slotStart.add(config.slotDurationMinutes, 'minute');
191
- var status = void 0;
192
- var remainingCapacity = null;
193
- if (slotStart.isBefore(now)) {
194
- status = 'past';
195
- } else if (!isSlotWithinResourceTimes(slotStart, slotEnd, timesForDate)) {
196
- status = 'unavailable';
197
- } else {
198
- var result = computeSlotStatus({
199
- slotStart: slotStart,
200
- slotEnd: slotEnd,
201
- events: events,
202
- resourceType: mapping.resourceType,
203
- capacity: resCapacity
204
- });
205
- status = result.status;
206
- remainingCapacity = result.remainingCapacity;
207
- }
208
- var isBookable = status === 'available' || status === 'partially_occupied';
209
- var slotStartStr = slotStart.format('YYYY-MM-DD HH:mm');
210
- slots.push({
211
- startTime: slotStartStr,
212
- endTime: slotEnd.format('YYYY-MM-DD HH:mm'),
213
- status: status,
214
- price: isBookable ? (_quotationPriceMap$ge = quotationPriceMap === null || quotationPriceMap === void 0 ? void 0 : quotationPriceMap.get("".concat(mapping.productId, ":").concat(slotStartStr))) !== null && _quotationPriceMap$ge !== void 0 ? _quotationPriceMap$ge : mapping.price : null,
215
- resourceId: resource.resourceId,
216
- resourceFormId: resource.formId,
217
- capacity: status === 'past' || status === 'unavailable' ? null : resCapacity,
218
- remainingCapacity: remainingCapacity
355
+ var combined = resource.combined_resource;
356
+ var isCombined = !!(combined && combined.status === 1 && Array.isArray(combined.resource_ids) && combined.resource_ids.length);
357
+ var childRawResources = isCombined ? combined.resource_ids.map(function (id) {
358
+ return rawResourceById.get(id);
359
+ }).filter(function (r) {
360
+ return !!r;
361
+ }) : undefined;
362
+ var childTimesCache = childRawResources === null || childRawResources === void 0 ? void 0 : childRawResources.map(function (child) {
363
+ return getResourceTimesForDate(child, date, config);
364
+ });
365
+ var childEventsCache = childRawResources === null || childRawResources === void 0 ? void 0 : childRawResources.map(function (child) {
366
+ return collectEventsForDate(child, date, config);
367
+ });
368
+ var subRows = mappings.map(function (mapping) {
369
+ var productSlots = buildProductSlots({
370
+ date: date,
371
+ config: config,
372
+ resource: resource,
373
+ mapping: mapping,
374
+ timeLabels: timeLabels,
375
+ timesForDate: timesForDate,
376
+ events: events,
377
+ resCapacity: resCapacity,
378
+ now: now,
379
+ crossDay: crossDay,
380
+ quotationPriceMap: quotationPriceMap,
381
+ childRawResources: childRawResources,
382
+ childTimesCache: childTimesCache,
383
+ childEventsCache: childEventsCache,
384
+ config_businessStartHour: config_businessStartHour
385
+ });
386
+ return {
387
+ productId: mapping.productId,
388
+ productTitle: mapping.productTitle,
389
+ price: mapping.price,
390
+ slots: productSlots
391
+ };
392
+ });
393
+ var hasMultipleProducts = subRows.length > 1;
394
+ var primary = mappings[0];
395
+ var outerSlots;
396
+ if (hasMultipleProducts) {
397
+ outerSlots = timeLabels.map(function (_label, slotIndex) {
398
+ var group = subRows.map(function (row) {
399
+ return row.slots[slotIndex];
219
400
  });
220
- }
221
- } catch (err) {
222
- _iterator6.e(err);
223
- } finally {
224
- _iterator6.f();
401
+ return mergeSubSlots(group);
402
+ });
403
+ } else {
404
+ outerSlots = subRows[0].slots.map(function (slot) {
405
+ return _objectSpread(_objectSpread({}, slot), {}, {
406
+ productId: undefined
407
+ });
408
+ });
225
409
  }
226
- resources.push({
410
+ var row = {
227
411
  resourceId: resource.resourceId,
228
412
  resourceFormId: resource.formId,
229
- resourceName: resource.main_field || mapping.resourceName,
230
- productId: mapping.productId,
231
- productTitle: mapping.productTitle,
232
- slots: slots
233
- });
413
+ resourceName: resource.main_field || primary.resourceName,
414
+ productId: primary.productId,
415
+ productTitle: primary.productTitle,
416
+ slots: outerSlots
417
+ };
418
+ if (hasMultipleProducts) {
419
+ row.products = subRows;
420
+ row.hasMultipleProducts = true;
421
+ }
422
+ if (isCombined && combined) {
423
+ row.combinedResource = {
424
+ resourceIds: _toConsumableArray(combined.resource_ids)
425
+ };
426
+ }
427
+ resources.push(row);
428
+ };
429
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
430
+ if (_loop()) continue;
234
431
  }
235
432
 
236
433
  // 按 productId 分组排序,确保同一商品的场地连续排列
237
434
  } catch (err) {
238
- _iterator5.e(err);
435
+ _iterator9.e(err);
239
436
  } finally {
240
- _iterator5.f();
437
+ _iterator9.f();
241
438
  }
242
439
  var productOrder = new Map();
243
440
  for (var _i = 0, _resources = resources; _i < _resources.length; _i++) {
@@ -1,7 +1,8 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { OrderModuleAPI, CommitOrderParams, SubmitScanOrderParams, ScanOrderMoreParams, CheckoutOrderParams } from './types';
3
+ import { OrderModuleAPI, CommitOrderParams, SubmitScanOrderParams, ScanOrderMoreParams, CheckoutOrderParams, UpdateProductInOrderParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
+ import { type SubmitPayloadEnhancer } from './utils';
5
6
  import type { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderSummary, ScanOrderTempOrder } from '../../solution/ScanOrder/types';
6
7
  import type { Discount } from '../Discount/types';
7
8
  import { UnavailableReason } from '../Rules/types';
@@ -57,6 +58,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
57
58
  persistTempOrder(): void;
58
59
  private createDefaultTempOrderInstance;
59
60
  ensureTempOrder(): ScanOrderTempOrder;
61
+ restoreOrder(): ScanOrderTempOrder;
60
62
  getTempOrder(): ScanOrderTempOrder | null;
61
63
  addNewOrder(): Promise<ScanOrderTempOrder>;
62
64
  getOrderProducts(): ScanOrderOrderProduct[];
@@ -66,13 +68,10 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
66
68
  }): Promise<ScanOrderSummary | null>;
67
69
  getScanOrderSummary(): Promise<ScanOrderSummary>;
68
70
  updateTempOrderNote(note: string): string;
71
+ updateTempOrderBuzzer(buzzer: string): string;
69
72
  updateTempOrderContactsInfo(contactsInfo: any[]): any[];
70
73
  addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
71
- updateProductInOrder(params: {
72
- product_id: number | null;
73
- product_variant_id: number;
74
- updates: Partial<ScanOrderOrderProduct>;
75
- }): Promise<ScanOrderOrderProduct[]>;
74
+ updateProductInOrder(params: UpdateProductInOrderParams): Promise<ScanOrderOrderProduct[]>;
76
75
  removeProductFromOrder(identity: ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
77
76
  submitTempOrder<T = any>(params?: {
78
77
  cacheId?: string;
@@ -80,6 +79,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
80
79
  businessCode?: string;
81
80
  channel?: string;
82
81
  type?: string;
82
+ enhancePayload?: SubmitPayloadEnhancer;
83
83
  }): Promise<T>;
84
84
  createOrder(params: CommitOrderParams['query']): {
85
85
  type: "virtual" | "appointment_booking";
@@ -115,3 +115,4 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
115
115
  getOrderInfoByRemote(order_id: number): Promise<any>;
116
116
  getLastOrderInfo(): Record<string, any> | undefined;
117
117
  }
118
+ export type { UpdateProductInOrderParams } from './types';
@@ -285,6 +285,31 @@ var OrderModule = class extends import_BaseModule.BaseModule {
285
285
  this.window.localStorage.removeItem(key);
286
286
  return;
287
287
  }
288
+ if (Array.isArray(parsedData.products)) {
289
+ for (let i = 0; i < parsedData.products.length; i++) {
290
+ const p = parsedData.products[i];
291
+ if (!p || typeof p !== "object")
292
+ continue;
293
+ if (!Array.isArray(p.product_option_item)) {
294
+ p.product_option_item = [];
295
+ }
296
+ if (!Array.isArray(p.product_bundle)) {
297
+ p.product_bundle = [];
298
+ }
299
+ const row = p;
300
+ if (typeof row.identity_key !== "string" || row.identity_key.length === 0) {
301
+ const newKey = (0, import_utils.createUuidV4)();
302
+ row.identity_key = newKey;
303
+ if (!row.metadata || typeof row.metadata !== "object") {
304
+ row.metadata = {};
305
+ }
306
+ if (!row.metadata.unique_identification_number) {
307
+ row.metadata.unique_identification_number = newKey;
308
+ }
309
+ }
310
+ parsedData.products[i] = (0, import_utils3.normalizeOrderProduct)(row);
311
+ }
312
+ }
288
313
  this.store.tempOrder = parsedData;
289
314
  } catch {
290
315
  (_b = (_a = this.window) == null ? void 0 : _a.localStorage) == null ? void 0 : _b.removeItem(key);
@@ -313,6 +338,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
313
338
  this.persistTempOrder();
314
339
  return newOrder;
315
340
  }
341
+ restoreOrder() {
342
+ const freshTempOrder = this.createDefaultTempOrderInstance();
343
+ this.store.tempOrder = freshTempOrder;
344
+ this.persistTempOrder();
345
+ return freshTempOrder;
346
+ }
316
347
  getTempOrder() {
317
348
  return this.store.tempOrder;
318
349
  }
@@ -373,6 +404,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
373
404
  this.persistTempOrder();
374
405
  return tempOrder.note;
375
406
  }
407
+ updateTempOrderBuzzer(buzzer) {
408
+ const tempOrder = this.ensureTempOrder();
409
+ tempOrder.buzzer = String(buzzer || "");
410
+ this.persistTempOrder();
411
+ return tempOrder.buzzer;
412
+ }
376
413
  updateTempOrderContactsInfo(contactsInfo) {
377
414
  const tempOrder = this.ensureTempOrder();
378
415
  tempOrder.contacts_info = Array.isArray(contactsInfo) ? contactsInfo : [];
@@ -382,21 +419,57 @@ var OrderModule = class extends import_BaseModule.BaseModule {
382
419
  // ─── TempOrder: 商品 CRUD ───
383
420
  async addProductToOrder(product) {
384
421
  const tempOrder = this.ensureTempOrder();
385
- const normalizedProduct = (0, import_utils3.normalizeOrderProduct)(product);
386
- const productIndex = (0, import_utils3.getProductIdentityIndex)(
387
- tempOrder.products,
388
- normalizedProduct
389
- );
390
- if (productIndex === -1) {
391
- tempOrder.products.push(normalizedProduct);
422
+ const hasExplicitIdentityKey = typeof product.identity_key === "string" && product.identity_key.length > 0;
423
+ if (hasExplicitIdentityKey) {
424
+ const normalizedProduct = (0, import_utils3.normalizeOrderProduct)(product);
425
+ const productIndex = (0, import_utils3.getProductIdentityIndex)(
426
+ tempOrder.products,
427
+ normalizedProduct
428
+ );
429
+ if (productIndex === -1) {
430
+ tempOrder.products.push(normalizedProduct);
431
+ } else {
432
+ const targetProduct = tempOrder.products[productIndex];
433
+ tempOrder.products[productIndex] = {
434
+ ...targetProduct,
435
+ ...normalizedProduct,
436
+ num: (0, import_utils3.getSafeProductNum)(targetProduct.num + normalizedProduct.num),
437
+ _origin: normalizedProduct._origin || targetProduct._origin
438
+ };
439
+ }
392
440
  } else {
393
- const targetProduct = tempOrder.products[productIndex];
394
- tempOrder.products[productIndex] = {
395
- ...targetProduct,
396
- ...normalizedProduct,
397
- num: (0, import_utils3.getSafeProductNum)(targetProduct.num + normalizedProduct.num),
398
- _origin: normalizedProduct._origin || targetProduct._origin
399
- };
441
+ const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
442
+ product.product_option_item,
443
+ product.product_bundle
444
+ );
445
+ const matchedIndex = tempOrder.products.findIndex((item) => {
446
+ if (item.product_id !== product.product_id)
447
+ return false;
448
+ if (item.product_variant_id !== product.product_variant_id)
449
+ return false;
450
+ const existedFingerprint = (0, import_utils3.buildProductLineFingerprint)(
451
+ item.product_option_item,
452
+ item.product_bundle
453
+ );
454
+ return existedFingerprint === incomingFingerprint;
455
+ });
456
+ if (matchedIndex === -1) {
457
+ const normalizedProduct = (0, import_utils3.normalizeOrderProduct)(product);
458
+ tempOrder.products.push(normalizedProduct);
459
+ } else {
460
+ const targetProduct = tempOrder.products[matchedIndex];
461
+ const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
462
+ ...product,
463
+ identity_key: targetProduct.identity_key
464
+ });
465
+ tempOrder.products[matchedIndex] = {
466
+ ...targetProduct,
467
+ ...normalizedProduct,
468
+ identity_key: targetProduct.identity_key,
469
+ num: (0, import_utils3.getSafeProductNum)(targetProduct.num + normalizedProduct.num),
470
+ _origin: normalizedProduct._origin || targetProduct._origin
471
+ };
472
+ }
400
473
  }
401
474
  this.applyDiscount();
402
475
  await this.recalculateSummary({ createIfMissing: true });
@@ -404,12 +477,27 @@ var OrderModule = class extends import_BaseModule.BaseModule {
404
477
  return tempOrder.products;
405
478
  }
406
479
  async updateProductInOrder(params) {
407
- const { product_id, product_variant_id, updates } = params;
480
+ var _a, _b, _c;
481
+ const {
482
+ product_id,
483
+ product_variant_id,
484
+ updates,
485
+ identity_key,
486
+ product_option_item,
487
+ product_bundle
488
+ } = params;
408
489
  const tempOrder = this.ensureTempOrder();
409
- const productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, {
490
+ const identityLookup = {
410
491
  product_id,
411
492
  product_variant_id
412
- });
493
+ };
494
+ if (identity_key !== void 0)
495
+ identityLookup.identity_key = identity_key;
496
+ if (product_option_item !== void 0)
497
+ identityLookup.product_option_item = product_option_item;
498
+ if (product_bundle !== void 0)
499
+ identityLookup.product_bundle = product_bundle;
500
+ const productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
413
501
  if (productIndex === -1) {
414
502
  throw new Error("[Order] 目标商品不存在,无法更新");
415
503
  }
@@ -421,7 +509,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
421
509
  product_variant_id
422
510
  };
423
511
  nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
424
- tempOrder.products[productIndex] = nextProduct;
512
+ const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
513
+ const callerUpdatesMainMeta = ((_a = updates == null ? void 0 : updates.metadata) == null ? void 0 : _a.main_product_selling_price) !== void 0 || ((_b = updates == null ? void 0 : updates.metadata) == null ? void 0 : _b.main_product_original_price) !== void 0 || ((_c = updates == null ? void 0 : updates.metadata) == null ? void 0 : _c.source_product_price) !== void 0;
514
+ if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
515
+ const existedMeta = nextProduct.metadata || {};
516
+ nextProduct.metadata = { ...existedMeta };
517
+ delete nextProduct.metadata.source_product_price;
518
+ delete nextProduct.metadata.main_product_selling_price;
519
+ delete nextProduct.metadata.main_product_original_price;
520
+ delete nextProduct.metadata.price_schema_version;
521
+ }
522
+ tempOrder.products[productIndex] = (0, import_utils3.normalizeOrderProduct)(nextProduct);
425
523
  this.applyDiscount();
426
524
  await this.recalculateSummary({ createIfMissing: true });
427
525
  this.persistTempOrder();
@@ -429,18 +527,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
429
527
  }
430
528
  async removeProductFromOrder(identity) {
431
529
  const tempOrder = this.ensureTempOrder();
432
- const beforeProducts = tempOrder.products;
433
530
  tempOrder.products = tempOrder.products.filter(
434
531
  (item) => !(0, import_utils3.isIdentityMatch)(item, identity)
435
532
  );
436
- const removedByStrictIdentity = beforeProducts.length - tempOrder.products.length;
437
- if (removedByStrictIdentity === 0 && identity.identity_key) {
438
- tempOrder.products = tempOrder.products.filter((item) => {
439
- const isSameProduct = String(item.product_id) === String(identity.product_id) && String(item.product_variant_id) === String(identity.product_variant_id);
440
- const hasNoIdentityKey = !item.identity_key;
441
- return !(isSameProduct && hasNoIdentityKey);
442
- });
443
- }
444
533
  this.applyDiscount();
445
534
  await this.recalculateSummary({ createIfMissing: true });
446
535
  this.persistTempOrder();
@@ -457,11 +546,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
457
546
  platform: params == null ? void 0 : params.platform,
458
547
  businessCode: params == null ? void 0 : params.businessCode,
459
548
  channel: params == null ? void 0 : params.channel,
460
- type: params == null ? void 0 : params.type
549
+ type: params == null ? void 0 : params.type,
550
+ enhance: params == null ? void 0 : params.enhancePayload
461
551
  });
462
552
  let result;
463
553
  if (tempOrder.order_id) {
464
- const products = (0, import_utils.formatV1Product)(payload.products);
554
+ const products = (0, import_utils.filterProductsForScanOrderMore)(payload.products);
465
555
  const moreResult = await this.scanOrderMore({
466
556
  query: {
467
557
  order_id: tempOrder.order_id,
@@ -687,7 +777,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
687
777
  async submitScanOrder(params) {
688
778
  const { url, query } = params;
689
779
  const fetchUrl = url || "/order/sales/checkout";
690
- return this.request.post(fetchUrl, query);
780
+ return this.request.post(fetchUrl, query, { customToast: () => {
781
+ } });
691
782
  }
692
783
  async scanOrderMore(params) {
693
784
  const { url, query } = params;
@@ -696,7 +787,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
696
787
  products: query.products,
697
788
  request_unique_idempotency_token: query.request_unique_idempotency_token
698
789
  };
699
- return this.request.put(fetchUrl, requestBody);
790
+ return this.request.put(fetchUrl, requestBody, { customToast: () => {
791
+ } });
700
792
  }
701
793
  // TODO 获取详情的接口
702
794
  async getOrderInfoByRemote(order_id) {