@pisell/pisellos 1.0.143 → 1.0.146

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.
@@ -0,0 +1,9 @@
1
+ // 导出评估器
2
+ export { PromotionEvaluator } from "./evaluator";
3
+
4
+ // 导出适配器
5
+ export { PromotionAdapter } from "./adapter";
6
+ export { default } from "./adapter";
7
+
8
+ // 导出策略配置示例常量
9
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { Discount, DiscountModuleAPI } from './types';
3
+ import { Discount, DiscountModuleAPI, DiscountWithReason } from './types';
4
4
  export declare class DiscountModule extends BaseModule implements Module, DiscountModuleAPI {
5
5
  protected defaultName: string;
6
6
  protected defaultVersion: string;
@@ -17,17 +17,20 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
17
17
  setOriginalDiscountList(originalDiscountList: Discount[]): Promise<void>;
18
18
  getOriginalDiscountList(): Discount[];
19
19
  loadPrepareConfig(params: {
20
- action?: 'create';
20
+ action?: 'create' | 'edit';
21
21
  with_good_pass: 0 | 1;
22
22
  with_discount_card: 0 | 1;
23
23
  customer_id: number;
24
24
  with_wallet_pass_holder: 0 | 1;
25
25
  request_timezone: string;
26
+ order_id?: number;
26
27
  }): Promise<Discount[]>;
27
- batchSearch(code: string, customerId?: number): Promise<Discount[]>;
28
+ batchSearch(code: string, customerId?: number): Promise<DiscountWithReason>;
28
29
  batchSearchByProductIds(productIds: number[]): Promise<any>;
29
30
  filterEnabledDiscountList(discountList: Discount[]): Discount[];
30
31
  private checkUsageCreditsLimit;
32
+ filterEnabledDiscountListWithReason(discountList: Discount[]): DiscountWithReason;
33
+ private checkUsageCreditsLimitWithFailKey;
31
34
  uniqueByProductId(discountList: Discount[]): Discount[];
32
35
  filterDiscountListByProductIds(discountList: Discount[], productIds: number[]): Discount[];
33
36
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
@@ -1,4 +1,6 @@
1
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 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; }
3
+ 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; }
2
4
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
5
  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
6
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -177,7 +179,7 @@ export var DiscountModule = /*#__PURE__*/function (_BaseModule) {
177
179
  key: "batchSearch",
178
180
  value: function () {
179
181
  var _batchSearch = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(code, customerId) {
180
- var result, resultDiscountList;
182
+ var result, resultDiscountWithReason;
181
183
  return _regeneratorRuntime().wrap(function _callee5$(_context5) {
182
184
  while (1) switch (_context5.prev = _context5.next) {
183
185
  case 0:
@@ -186,17 +188,18 @@ export var DiscountModule = /*#__PURE__*/function (_BaseModule) {
186
188
  code: code,
187
189
  translate_flag: 1,
188
190
  tags: ['good_pass', 'product_discount_card'],
189
- available: 1,
191
+ // available: 1,
190
192
  relation_product: 1,
191
193
  with: ['extensionData', 'customScheduleSnapshot', 'holder.detail'],
192
194
  order_behavior_count: 1,
193
195
  order_behavior_count_customer_id: customerId || 1,
196
+ unified_status_info_flag: 1,
194
197
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
195
198
  });
196
199
  case 2:
197
200
  result = _context5.sent;
198
- resultDiscountList = this.filterEnabledDiscountList((result === null || result === void 0 ? void 0 : result.data) || []) || [];
199
- return _context5.abrupt("return", resultDiscountList);
201
+ resultDiscountWithReason = this.filterEnabledDiscountListWithReason((result === null || result === void 0 ? void 0 : result.data) || []) || [];
202
+ return _context5.abrupt("return", resultDiscountWithReason);
200
203
  case 5:
201
204
  case "end":
202
205
  return _context5.stop();
@@ -305,6 +308,91 @@ export var DiscountModule = /*#__PURE__*/function (_BaseModule) {
305
308
  return true;
306
309
  }
307
310
 
311
+ // 过滤启用且可用的优惠券,并返回校验失败原因
312
+ }, {
313
+ key: "filterEnabledDiscountListWithReason",
314
+ value: function filterEnabledDiscountListWithReason(discountList) {
315
+ var _this3 = this;
316
+ var lists = discountList.filter(function (discount) {
317
+ return discount.limit_status === 'enable';
318
+ }).filter(function (discount) {
319
+ var remaining = new Decimal((discount === null || discount === void 0 ? void 0 : discount.par_value) || 0).minus(new Decimal((discount === null || discount === void 0 ? void 0 : discount.used_par_value) || 0)).greaterThan(0);
320
+ return remaining;
321
+ }).map(function (discount) {
322
+ var limitFailKey = _this3.checkUsageCreditsLimitWithFailKey(discount);
323
+ return _objectSpread(_objectSpread({}, discount), {}, {
324
+ usageLimitFailKey: limitFailKey
325
+ });
326
+ });
327
+
328
+ // 可用的列表
329
+ var availableLists = lists.filter(function (item) {
330
+ return !item.usageLimitFailKey && item.unified_available_status !== 0;
331
+ });
332
+ // 不可用数据
333
+ var currentFailDiscount = lists.find(function (item) {
334
+ return item.usageLimitFailKey;
335
+ });
336
+ return {
337
+ discountList: availableLists,
338
+ unavailableReasonKey: currentFailDiscount === null || currentFailDiscount === void 0 ? void 0 : currentFailDiscount.usageLimitFailKey
339
+ };
340
+ }
341
+
342
+ // 检查使用次数限制,并返回校验失败原因
343
+ }, {
344
+ key: "checkUsageCreditsLimitWithFailKey",
345
+ value: function checkUsageCreditsLimitWithFailKey(discount) {
346
+ if (!discount.extension_data || discount.extension_data.length === 0) {
347
+ return null;
348
+ }
349
+ var usageCreditsData = discount.extension_data.find(function (data) {
350
+ return data.field_key === 'usage_credits';
351
+ });
352
+ if (!usageCreditsData) {
353
+ return null;
354
+ }
355
+ var value = usageCreditsData.value;
356
+
357
+ // 总次数限制
358
+ if (value.total_credits && value.total_credits > 0) {
359
+ if ((discount.total_order_behavior_count || 0) >= value.total_credits) {
360
+ return 'total_credits';
361
+ }
362
+ }
363
+
364
+ // 单用户限制
365
+ if (value.per_user_limit && value.per_user_limit > 0) {
366
+ if ((discount.customer_order_behavior_count || 0) >= value.per_user_limit) {
367
+ return 'per_user_limit';
368
+ }
369
+ }
370
+
371
+ // 单日限制
372
+ if (value.max_per_day && value.max_per_day > 0) {
373
+ if ((discount.today_order_behavior_count || 0) >= value.max_per_day) {
374
+ return 'max_per_day';
375
+ }
376
+ }
377
+
378
+ // 单周限制
379
+ if (value.max_per_week && value.max_per_week > 0) {
380
+ if ((discount.week_order_behavior_count || 0) >= value.max_per_week) {
381
+ return 'max_per_week';
382
+ }
383
+ }
384
+
385
+ // 单月限制
386
+ if (value.max_per_month && value.max_per_month > 0) {
387
+ if ((discount.month_order_behavior_count || 0) >= value.max_per_month) {
388
+ return 'max_per_month';
389
+ }
390
+ }
391
+
392
+ // 全部通过
393
+ return null;
394
+ }
395
+
308
396
  // 根据productIds去重
309
397
  }, {
310
398
  key: "uniqueByProductId",
@@ -63,6 +63,11 @@ interface UsageCreditsValue {
63
63
  max_per_week: number;
64
64
  max_per_month: number;
65
65
  }
66
+ export type DiscountFilterRejectKey = 'total_credits' | 'per_user_limit' | 'max_per_day' | 'max_per_week' | 'max_per_month';
67
+ export interface DiscountWithReason {
68
+ discountList: Discount[];
69
+ unavailableReasonKey: DiscountFilterRejectKey | null;
70
+ }
66
71
  interface ExtensionData {
67
72
  id: number;
68
73
  shop_id: number;
@@ -147,6 +152,8 @@ export interface Discount {
147
152
  start_date?: string;
148
153
  start_time?: string;
149
154
  discount_rule_uncheck_flag?: boolean;
155
+ usageLimitFailKey?: string | null;
156
+ unified_available_status?: number | undefined | null;
150
157
  }
151
158
  export interface DiscountState {
152
159
  discountList: Discount[];
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
49
49
  getCategories(): ProductCategory[];
50
50
  setOtherParams(key: string, value: any): void;
51
51
  getOtherParams(): any;
52
- getProductType(): "normal" | "duration" | "session";
52
+ getProductType(): "duration" | "session" | "normal";
53
53
  }
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 5 | 3 | 4 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -115,7 +115,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
115
115
  * 获取当前的客户搜索条件
116
116
  * @returns 当前搜索条件
117
117
  */
118
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
@@ -26,6 +26,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
26
26
  setHolders(holders: {
27
27
  form_record_id: number;
28
28
  }[]): void;
29
+ setOrderId(id?: number): void;
29
30
  setBookingSubject(bookingSubject: {
30
31
  type?: 'form' | 'customer';
31
32
  [key: string]: any;
@@ -46,6 +47,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
46
47
  discountList: Discount[];
47
48
  type: "server" | "clientCalc";
48
49
  unavailableReason?: UnavailableReason;
50
+ unavailableReasonKey?: string | null;
49
51
  }>;
50
52
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
51
53
  private getCustomer;
@@ -57,7 +59,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
57
59
  private bestDiscount;
58
60
  loadPrepareConfig(params: {
59
61
  customerId: number;
60
- action?: 'create' | 'update';
62
+ action?: 'create' | 'edit';
61
63
  with_good_pass?: 0 | 1;
62
64
  with_discount_card?: 0 | 1;
63
65
  }): Promise<void>;
@@ -57,7 +57,8 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
57
57
  currentBookingTime: "",
58
58
  filteredDiscountList: [],
59
59
  orderTotalAmount: 0,
60
- bookingSubject: undefined
60
+ bookingSubject: undefined,
61
+ orderId: undefined
61
62
  };
62
63
  return _this;
63
64
  }
@@ -302,6 +303,11 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
302
303
  value: function setHolders(holders) {
303
304
  this.store.holders = holders;
304
305
  }
306
+ }, {
307
+ key: "setOrderId",
308
+ value: function setOrderId(id) {
309
+ this.store.orderId = id;
310
+ }
305
311
  }, {
306
312
  key: "setBookingSubject",
307
313
  value: function setBookingSubject(bookingSubject) {
@@ -437,7 +443,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
437
443
  key: "scanCode",
438
444
  value: function () {
439
445
  var _scanCode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(code, customerId) {
440
- var _this$store$discount4, _this$store$bookingSu2, resultDiscountList, rulesModule, withScanList, currentSelectedDiscountList, _ref2, newProductList, newDiscountList, isAvailable, unavailableReason, _this$options$otherPa6;
446
+ var _this$store$discount4, _this$store$bookingSu2, resultDiscountWithReason, resultDiscountList, unavailableReasonKey, rulesModule, withScanList, currentSelectedDiscountList, _ref2, newProductList, newDiscountList, isAvailable, unavailableReason, _this$options$otherPa6;
441
447
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
442
448
  while (1) switch (_context6.prev = _context6.next) {
443
449
  case 0:
@@ -450,12 +456,16 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
450
456
  _context6.next = 6;
451
457
  break;
452
458
  }
453
- _context6.t0 = [];
459
+ _context6.t0 = {
460
+ discountList: [],
461
+ unavailableReasonKey: null
462
+ };
454
463
  case 6:
455
- resultDiscountList = _context6.t0;
464
+ resultDiscountWithReason = _context6.t0;
465
+ resultDiscountList = resultDiscountWithReason.discountList, unavailableReasonKey = resultDiscountWithReason.unavailableReasonKey;
456
466
  rulesModule = this.store.rules;
457
467
  if (rulesModule) {
458
- _context6.next = 10;
468
+ _context6.next = 11;
459
469
  break;
460
470
  }
461
471
  return _context6.abrupt("return", {
@@ -465,18 +475,19 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
465
475
  discountList: this.getDiscountList(),
466
476
  unavailableReason: UnavailableReason.Unknown
467
477
  });
468
- case 10:
478
+ case 11:
469
479
  if (resultDiscountList.length) {
470
- _context6.next = 12;
480
+ _context6.next = 13;
471
481
  break;
472
482
  }
473
483
  return _context6.abrupt("return", {
474
484
  type: "server",
475
485
  isAvailable: false,
476
486
  productList: this.store.productList || [],
477
- discountList: this.getDiscountList()
487
+ discountList: this.getDiscountList(),
488
+ unavailableReasonKey: unavailableReasonKey
478
489
  });
479
- case 12:
490
+ case 13:
480
491
  withScanList = resultDiscountList.map(function (item) {
481
492
  return _objectSpread(_objectSpread({}, item), {}, {
482
493
  isScan: true
@@ -490,7 +501,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
490
501
  return m.id === n.id;
491
502
  });
492
503
  }))) {
493
- _context6.next = 16;
504
+ _context6.next = 17;
494
505
  break;
495
506
  }
496
507
  return _context6.abrupt("return", {
@@ -499,7 +510,7 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
499
510
  productList: this.store.productList || [],
500
511
  discountList: this.getDiscountList()
501
512
  });
502
- case 16:
513
+ case 17:
503
514
  _ref2 = rulesModule.isDiscountListAvailable({
504
515
  productList: this.store.productList || [],
505
516
  oldDiscountList: this.getDiscountList(),
@@ -513,19 +524,19 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
513
524
  discountList: this.getDiscountList()
514
525
  }, newProductList = _ref2.productList, newDiscountList = _ref2.discountList, isAvailable = _ref2.isAvailable, unavailableReason = _ref2.unavailableReason;
515
526
  if (!isAvailable) {
516
- _context6.next = 24;
527
+ _context6.next = 25;
517
528
  break;
518
529
  }
519
530
  this.setDiscountList(newDiscountList || []);
520
531
  this.store.originalDiscountList = newDiscountList || [];
521
532
  this.setProductList(newProductList || []);
522
533
  if (!(this.isWalkIn() && resultDiscountList.length && ((_this$options$otherPa6 = this.options.otherParams) === null || _this$options$otherPa6 === void 0 ? void 0 : _this$options$otherPa6.platform) === 'shop')) {
523
- _context6.next = 24;
534
+ _context6.next = 25;
524
535
  break;
525
536
  }
526
- _context6.next = 24;
537
+ _context6.next = 25;
527
538
  return this.getCustomerWallet(resultDiscountList[0].customer_id);
528
- case 24:
539
+ case 25:
529
540
  return _context6.abrupt("return", {
530
541
  type: "clientCalc",
531
542
  isAvailable: isAvailable || false,
@@ -533,8 +544,8 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
533
544
  discountList: newDiscountList || this.getDiscountList(),
534
545
  unavailableReason: unavailableReason
535
546
  });
536
- case 27:
537
- _context6.prev = 27;
547
+ case 28:
548
+ _context6.prev = 28;
538
549
  _context6.t1 = _context6["catch"](0);
539
550
  console.error('[ShopDiscount] 扫码出错:', _context6.t1);
540
551
  return _context6.abrupt("return", {
@@ -544,11 +555,11 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
544
555
  discountList: this.getDiscountList(),
545
556
  unavailableReason: UnavailableReason.Unknown
546
557
  });
547
- case 31:
558
+ case 32:
548
559
  case "end":
549
560
  return _context6.stop();
550
561
  }
551
- }, _callee6, this, [[0, 27]]);
562
+ }, _callee6, this, [[0, 28]]);
552
563
  }));
553
564
  function scanCode(_x5, _x6) {
554
565
  return _scanCode.apply(this, arguments);
@@ -785,24 +796,27 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
785
796
  key: "loadPrepareConfig",
786
797
  value: function () {
787
798
  var _loadPrepareConfig = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(params) {
788
- var _this$getCustomer2, _this$store$discount8, _this$getDiscountList, _this$store$discount9, _this$store$productLi2, customerId, goodPassList, scanDiscount, scanDiscountIds, newGoodPassList, newDiscountList, filteredDiscountList, _result3;
799
+ var _this$getCustomer2, _this$store$discount8, _this$getDiscountList, _this$store$discount9, _this$store$productLi2, orderId, customerId, goodPassList, scanDiscount, scanDiscountIds, newGoodPassList, newDiscountList, filteredDiscountList, _result3;
789
800
  return _regeneratorRuntime().wrap(function _callee10$(_context10) {
790
801
  while (1) switch (_context10.prev = _context10.next) {
791
802
  case 0:
792
803
  _context10.prev = 0;
804
+ orderId = this.store.orderId;
793
805
  customerId = params.customerId || ((_this$getCustomer2 = this.getCustomer()) === null || _this$getCustomer2 === void 0 ? void 0 : _this$getCustomer2.id); // if (customerId === 1 || !customerId) {
794
806
  // return
795
807
  // }
796
- _context10.next = 4;
797
- return (_this$store$discount8 = this.store.discount) === null || _this$store$discount8 === void 0 ? void 0 : _this$store$discount8.loadPrepareConfig({
808
+ _context10.next = 5;
809
+ return (_this$store$discount8 = this.store.discount) === null || _this$store$discount8 === void 0 ? void 0 : _this$store$discount8.loadPrepareConfig(_objectSpread({
798
810
  customer_id: customerId,
799
- action: 'create',
811
+ action: orderId ? 'edit' : 'create',
800
812
  with_good_pass: 1,
801
813
  with_discount_card: 1,
802
814
  with_wallet_pass_holder: 1,
803
815
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
804
- });
805
- case 4:
816
+ }, orderId ? {
817
+ order_id: orderId
818
+ } : {}));
819
+ case 5:
806
820
  goodPassList = _context10.sent;
807
821
  scanDiscount = (_this$getDiscountList = this.getDiscountList()) === null || _this$getDiscountList === void 0 ? void 0 : _this$getDiscountList.filter(function (item) {
808
822
  return item.isScan;
@@ -815,35 +829,35 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
815
829
  });
816
830
  newDiscountList = [].concat(_toConsumableArray(scanDiscount), _toConsumableArray(newGoodPassList || [])); // 存储原始优惠券列表
817
831
  this.store.originalDiscountList = newDiscountList;
818
- _context10.next = 12;
832
+ _context10.next = 13;
819
833
  return (_this$store$discount9 = this.store.discount) === null || _this$store$discount9 === void 0 ? void 0 : _this$store$discount9.setOriginalDiscountList(newDiscountList);
820
- case 12:
834
+ case 13:
821
835
  // 根据当前预约时间过滤优惠券列表
822
836
  filteredDiscountList = this.filterDiscountListByBookingTime(newDiscountList, this.store.currentBookingTime);
823
837
  this.store.filteredDiscountList = filteredDiscountList;
824
838
  this.setDiscountList(filteredDiscountList || []);
825
839
  if (!((_this$store$productLi2 = this.store.productList) !== null && _this$store$productLi2 !== void 0 && _this$store$productLi2.length)) {
826
- _context10.next = 19;
840
+ _context10.next = 20;
827
841
  break;
828
842
  }
829
843
  _result3 = this.calcDiscount(this.store.productList);
830
- _context10.next = 19;
844
+ _context10.next = 20;
831
845
  return this.core.effects.emit("".concat(this.name, ":onLoadPrepareCalcResult"), _result3);
832
- case 19:
833
- _context10.next = 21;
846
+ case 20:
847
+ _context10.next = 22;
834
848
  return this.core.effects.emit("".concat(this.name, ":onLoadDiscountList"), filteredDiscountList);
835
- case 21:
836
- _context10.next = 26;
849
+ case 22:
850
+ _context10.next = 27;
837
851
  break;
838
- case 23:
839
- _context10.prev = 23;
852
+ case 24:
853
+ _context10.prev = 24;
840
854
  _context10.t0 = _context10["catch"](0);
841
855
  console.error('[ShopDiscount] 加载准备配置出错:', _context10.t0);
842
- case 26:
856
+ case 27:
843
857
  case "end":
844
858
  return _context10.stop();
845
859
  }
846
- }, _callee10, this, [[0, 23]]);
860
+ }, _callee10, this, [[0, 24]]);
847
861
  }));
848
862
  function loadPrepareConfig(_x10) {
849
863
  return _loadPrepareConfig.apply(this, arguments);
@@ -35,6 +35,7 @@ export interface ShopDiscountState {
35
35
  type?: 'form' | 'customer';
36
36
  [key: string]: any;
37
37
  };
38
+ orderId?: number;
38
39
  }
39
40
  export interface SetDiscountSelectedParams {
40
41
  discountId: number;
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { Discount, DiscountModuleAPI } from './types';
3
+ import { Discount, DiscountModuleAPI, DiscountWithReason } from './types';
4
4
  export declare class DiscountModule extends BaseModule implements Module, DiscountModuleAPI {
5
5
  protected defaultName: string;
6
6
  protected defaultVersion: string;
@@ -17,17 +17,20 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
17
17
  setOriginalDiscountList(originalDiscountList: Discount[]): Promise<void>;
18
18
  getOriginalDiscountList(): Discount[];
19
19
  loadPrepareConfig(params: {
20
- action?: 'create';
20
+ action?: 'create' | 'edit';
21
21
  with_good_pass: 0 | 1;
22
22
  with_discount_card: 0 | 1;
23
23
  customer_id: number;
24
24
  with_wallet_pass_holder: 0 | 1;
25
25
  request_timezone: string;
26
+ order_id?: number;
26
27
  }): Promise<Discount[]>;
27
- batchSearch(code: string, customerId?: number): Promise<Discount[]>;
28
+ batchSearch(code: string, customerId?: number): Promise<DiscountWithReason>;
28
29
  batchSearchByProductIds(productIds: number[]): Promise<any>;
29
30
  filterEnabledDiscountList(discountList: Discount[]): Discount[];
30
31
  private checkUsageCreditsLimit;
32
+ filterEnabledDiscountListWithReason(discountList: Discount[]): DiscountWithReason;
33
+ private checkUsageCreditsLimitWithFailKey;
31
34
  uniqueByProductId(discountList: Discount[]): Discount[];
32
35
  filterDiscountListByProductIds(discountList: Discount[], productIds: number[]): Discount[];
33
36
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
@@ -107,15 +107,16 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
107
107
  code,
108
108
  translate_flag: 1,
109
109
  tags: ["good_pass", "product_discount_card"],
110
- available: 1,
110
+ // available: 1,
111
111
  relation_product: 1,
112
112
  with: ["extensionData", "customScheduleSnapshot", "holder.detail"],
113
113
  order_behavior_count: 1,
114
114
  order_behavior_count_customer_id: customerId || 1,
115
+ unified_status_info_flag: 1,
115
116
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
116
117
  });
117
- const resultDiscountList = this.filterEnabledDiscountList((result == null ? void 0 : result.data) || []) || [];
118
- return resultDiscountList;
118
+ const resultDiscountWithReason = this.filterEnabledDiscountListWithReason((result == null ? void 0 : result.data) || []) || [];
119
+ return resultDiscountWithReason;
119
120
  }
120
121
  async batchSearchByProductIds(productIds) {
121
122
  const result = await this.request.get(`/machinecode/batch-search`, {
@@ -170,6 +171,64 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
170
171
  }
171
172
  return true;
172
173
  }
174
+ // 过滤启用且可用的优惠券,并返回校验失败原因
175
+ filterEnabledDiscountListWithReason(discountList) {
176
+ let lists = discountList.filter((discount) => discount.limit_status === "enable").filter((discount) => {
177
+ const remaining = new import_decimal.default((discount == null ? void 0 : discount.par_value) || 0).minus(new import_decimal.default((discount == null ? void 0 : discount.used_par_value) || 0)).greaterThan(0);
178
+ return remaining;
179
+ }).map((discount) => {
180
+ const limitFailKey = this.checkUsageCreditsLimitWithFailKey(discount);
181
+ return {
182
+ ...discount,
183
+ usageLimitFailKey: limitFailKey
184
+ };
185
+ });
186
+ const availableLists = lists.filter((item) => !item.usageLimitFailKey && item.unified_available_status !== 0);
187
+ const currentFailDiscount = lists.find((item) => item.usageLimitFailKey);
188
+ return {
189
+ discountList: availableLists,
190
+ unavailableReasonKey: currentFailDiscount == null ? void 0 : currentFailDiscount.usageLimitFailKey
191
+ };
192
+ }
193
+ // 检查使用次数限制,并返回校验失败原因
194
+ checkUsageCreditsLimitWithFailKey(discount) {
195
+ if (!discount.extension_data || discount.extension_data.length === 0) {
196
+ return null;
197
+ }
198
+ const usageCreditsData = discount.extension_data.find(
199
+ (data) => data.field_key === "usage_credits"
200
+ );
201
+ if (!usageCreditsData) {
202
+ return null;
203
+ }
204
+ const value = usageCreditsData.value;
205
+ if (value.total_credits && value.total_credits > 0) {
206
+ if ((discount.total_order_behavior_count || 0) >= value.total_credits) {
207
+ return "total_credits";
208
+ }
209
+ }
210
+ if (value.per_user_limit && value.per_user_limit > 0) {
211
+ if ((discount.customer_order_behavior_count || 0) >= value.per_user_limit) {
212
+ return "per_user_limit";
213
+ }
214
+ }
215
+ if (value.max_per_day && value.max_per_day > 0) {
216
+ if ((discount.today_order_behavior_count || 0) >= value.max_per_day) {
217
+ return "max_per_day";
218
+ }
219
+ }
220
+ if (value.max_per_week && value.max_per_week > 0) {
221
+ if ((discount.week_order_behavior_count || 0) >= value.max_per_week) {
222
+ return "max_per_week";
223
+ }
224
+ }
225
+ if (value.max_per_month && value.max_per_month > 0) {
226
+ if ((discount.month_order_behavior_count || 0) >= value.max_per_month) {
227
+ return "max_per_month";
228
+ }
229
+ }
230
+ return null;
231
+ }
173
232
  // 根据productIds去重
174
233
  uniqueByProductId(discountList) {
175
234
  return (0, import_utils.uniqueById)(discountList, "product_id");
@@ -63,6 +63,11 @@ interface UsageCreditsValue {
63
63
  max_per_week: number;
64
64
  max_per_month: number;
65
65
  }
66
+ export type DiscountFilterRejectKey = 'total_credits' | 'per_user_limit' | 'max_per_day' | 'max_per_week' | 'max_per_month';
67
+ export interface DiscountWithReason {
68
+ discountList: Discount[];
69
+ unavailableReasonKey: DiscountFilterRejectKey | null;
70
+ }
66
71
  interface ExtensionData {
67
72
  id: number;
68
73
  shop_id: number;
@@ -147,6 +152,8 @@ export interface Discount {
147
152
  start_date?: string;
148
153
  start_time?: string;
149
154
  discount_rule_uncheck_flag?: boolean;
155
+ usageLimitFailKey?: string | null;
156
+ unified_available_status?: number | undefined | null;
150
157
  }
151
158
  export interface DiscountState {
152
159
  discountList: Discount[];
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
49
49
  getCategories(): ProductCategory[];
50
50
  setOtherParams(key: string, value: any): void;
51
51
  getOtherParams(): any;
52
- getProductType(): "normal" | "duration" | "session";
52
+ getProductType(): "duration" | "session" | "normal";
53
53
  }
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 5 | 3 | 4 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -115,7 +115,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
115
115
  * 获取当前的客户搜索条件
116
116
  * @returns 当前搜索条件
117
117
  */
118
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
@@ -26,6 +26,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
26
26
  setHolders(holders: {
27
27
  form_record_id: number;
28
28
  }[]): void;
29
+ setOrderId(id?: number): void;
29
30
  setBookingSubject(bookingSubject: {
30
31
  type?: 'form' | 'customer';
31
32
  [key: string]: any;
@@ -46,6 +47,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
46
47
  discountList: Discount[];
47
48
  type: "server" | "clientCalc";
48
49
  unavailableReason?: UnavailableReason;
50
+ unavailableReasonKey?: string | null;
49
51
  }>;
50
52
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
51
53
  private getCustomer;
@@ -57,7 +59,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
57
59
  private bestDiscount;
58
60
  loadPrepareConfig(params: {
59
61
  customerId: number;
60
- action?: 'create' | 'update';
62
+ action?: 'create' | 'edit';
61
63
  with_good_pass?: 0 | 1;
62
64
  with_discount_card?: 0 | 1;
63
65
  }): Promise<void>;
@@ -57,7 +57,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
57
57
  currentBookingTime: "",
58
58
  filteredDiscountList: [],
59
59
  orderTotalAmount: 0,
60
- bookingSubject: void 0
60
+ bookingSubject: void 0,
61
+ orderId: void 0
61
62
  };
62
63
  }
63
64
  // =========== 生命周期方法 ===========
@@ -202,6 +203,9 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
202
203
  setHolders(holders) {
203
204
  this.store.holders = holders;
204
205
  }
206
+ setOrderId(id) {
207
+ this.store.orderId = id;
208
+ }
205
209
  setBookingSubject(bookingSubject) {
206
210
  this.store.bookingSubject = bookingSubject;
207
211
  }
@@ -282,7 +286,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
282
286
  async scanCode(code, customerId) {
283
287
  var _a, _b, _c;
284
288
  try {
285
- const resultDiscountList = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, customerId)) || [];
289
+ const resultDiscountWithReason = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, customerId)) || { discountList: [], unavailableReasonKey: null };
290
+ const { discountList: resultDiscountList, unavailableReasonKey } = resultDiscountWithReason;
286
291
  const rulesModule = this.store.rules;
287
292
  if (!rulesModule) {
288
293
  return {
@@ -298,7 +303,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
298
303
  type: "server",
299
304
  isAvailable: false,
300
305
  productList: this.store.productList || [],
301
- discountList: this.getDiscountList()
306
+ discountList: this.getDiscountList(),
307
+ unavailableReasonKey
302
308
  };
303
309
  }
304
310
  const withScanList = resultDiscountList.map((item) => {
@@ -517,14 +523,16 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
517
523
  async loadPrepareConfig(params) {
518
524
  var _a, _b, _c, _d, _e;
519
525
  try {
526
+ const orderId = this.store.orderId;
520
527
  const customerId = params.customerId || ((_a = this.getCustomer()) == null ? void 0 : _a.id);
521
528
  const goodPassList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
522
529
  customer_id: customerId,
523
- action: "create",
530
+ action: orderId ? "edit" : "create",
524
531
  with_good_pass: 1,
525
532
  with_discount_card: 1,
526
533
  with_wallet_pass_holder: 1,
527
- request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
534
+ request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
535
+ ...orderId ? { order_id: orderId } : {}
528
536
  }));
529
537
  const scanDiscount = (_c = this.getDiscountList()) == null ? void 0 : _c.filter(
530
538
  (item) => item.isScan
@@ -35,6 +35,7 @@ export interface ShopDiscountState {
35
35
  type?: 'form' | 'customer';
36
36
  [key: string]: any;
37
37
  };
38
+ orderId?: number;
38
39
  }
39
40
  export interface SetDiscountSelectedParams {
40
41
  discountId: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "1.0.143",
4
+ "version": "1.0.146",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
19
19
  "changeset": "changeset",
20
20
  "version": "changeset version",
21
- "release": "changeset publish --registry=https://registry.npmjs.com/ && npm run sync && git push",
21
+ "release": "changeset publish && npm run sync && git push",
22
22
  "example": "npx parcel-bundler examples/index.html",
23
23
  "docs": "typedoc --out docs src/index.ts",
24
24
  "sync": "node sync.js",