@pisell/pisellos 3.0.78 → 3.0.79

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 (37) hide show
  1. package/dist/modules/Cart/types.d.ts +2 -0
  2. package/dist/modules/Cart/utils/cartProduct.js +21 -1
  3. package/dist/modules/Cart/utils/changePrice.js +6 -0
  4. package/dist/modules/Date/index.d.ts +1 -1
  5. package/dist/modules/Date/index.js +16 -8
  6. package/dist/modules/Discount/index.d.ts +1 -0
  7. package/dist/modules/Discount/index.js +2 -1
  8. package/dist/modules/Rules/index.js +14 -14
  9. package/dist/modules/Schedule/index.d.ts +9 -0
  10. package/dist/modules/Schedule/index.js +76 -0
  11. package/dist/modules/Summary/index.d.ts +3 -0
  12. package/dist/modules/Summary/index.js +134 -15
  13. package/dist/modules/Summary/types.d.ts +7 -0
  14. package/dist/modules/Summary/utils.d.ts +104 -1
  15. package/dist/modules/Summary/utils.js +1131 -13
  16. package/dist/solution/BookingByStep/index.d.ts +4 -7
  17. package/dist/solution/BookingByStep/index.js +232 -119
  18. package/dist/solution/ShopDiscount/index.js +2 -1
  19. package/lib/modules/Cart/types.d.ts +2 -0
  20. package/lib/modules/Cart/utils/cartProduct.js +16 -1
  21. package/lib/modules/Cart/utils/changePrice.js +5 -0
  22. package/lib/modules/Date/index.d.ts +1 -1
  23. package/lib/modules/Date/index.js +7 -1
  24. package/lib/modules/Discount/index.d.ts +1 -0
  25. package/lib/modules/Discount/index.js +2 -1
  26. package/lib/modules/Rules/index.js +3 -3
  27. package/lib/modules/Schedule/index.d.ts +9 -0
  28. package/lib/modules/Schedule/index.js +60 -0
  29. package/lib/modules/Summary/index.d.ts +3 -0
  30. package/lib/modules/Summary/index.js +61 -2
  31. package/lib/modules/Summary/types.d.ts +7 -0
  32. package/lib/modules/Summary/utils.d.ts +104 -1
  33. package/lib/modules/Summary/utils.js +673 -8
  34. package/lib/solution/BookingByStep/index.d.ts +4 -7
  35. package/lib/solution/BookingByStep/index.js +189 -90
  36. package/lib/solution/ShopDiscount/index.js +2 -1
  37. package/package.json +1 -1
@@ -147,6 +147,9 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
147
147
  taxTitle?: string | undefined;
148
148
  totalTaxFee?: string | number | undefined;
149
149
  isPriceIncludeTax?: 0 | 1 | undefined;
150
+ surchargeAmount?: string | number | undefined;
151
+ surcharge?: any[] | undefined;
152
+ taxRate?: string | number | undefined;
150
153
  deposit?: {
151
154
  total?: string | number | undefined;
152
155
  policies?: import("../../modules/Summary/types").IProtocol[] | undefined;
@@ -326,7 +329,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
329
  count: number;
327
330
  left: number;
328
331
  summaryCount: number;
329
- status: keyof TimeStatusMap;
332
+ status: "lots_of_space" | "filling_up_fast" | "sold_out";
330
333
  }[];
331
334
  /**
332
335
  * 找到多个资源的公共可用时间段
@@ -391,9 +394,3 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
391
394
  */
392
395
  getContactInfo(params: any): Promise<any>;
393
396
  }
394
- interface TimeStatusMap {
395
- lots_of_space: true;
396
- filling_up_fast: true;
397
- sold_out: true;
398
- }
399
- export {};
@@ -1469,7 +1469,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
1469
1469
  resources.push.apply(resources, _toConsumableArray(dateResources || []));
1470
1470
  } else {
1471
1471
  var dateList = this.store.date.getDateList();
1472
- dateList.forEach(function (n) {
1472
+ dateList === null || dateList === void 0 || dateList.forEach(function (n) {
1473
1473
  if (n.resource) resources.push.apply(resources, _toConsumableArray(n.resource));
1474
1474
  });
1475
1475
  }
@@ -2104,6 +2104,11 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2104
2104
  }
2105
2105
  });
2106
2106
  }
2107
+
2108
+ // 如果依然 resources 空的,则证明他是切换日期了,此时直接从 date 模块里取
2109
+ if (resources.length === 0) {
2110
+ resources.push.apply(resources, _toConsumableArray(this.store.date.getResourcesListByDate(dateRange[0].date) || []));
2111
+ }
2107
2112
  var resourcesMap = getResourcesMap(resources);
2108
2113
  var duration = 0;
2109
2114
  // duration = 不同账号的最长时间
@@ -2516,14 +2521,63 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2516
2521
  var targetResourceTimes = allResources === null || allResources === void 0 || (_allResources$find = allResources.find(function (n) {
2517
2522
  return n.id === resource.id;
2518
2523
  })) === null || _allResources$find === void 0 ? void 0 : _allResources$find.times;
2524
+ // 找到最晚的 end_at 还没用,因为可能存在资源工作时间是 10:00-19:00,但是资源的 times 里有 16:30-19:00 被 block 的情况
2525
+ // 所以还需要排除掉 block 时间
2526
+ function getEarliestBlockedStartTime(_ref11) {
2527
+ var _earliestBlockStart;
2528
+ var currentStartTime = _ref11.currentStartTime,
2529
+ times = _ref11.times;
2530
+ var currentStart = dayjs(currentStartTime);
2531
+ var earliestBlockStart;
2532
+ var _iterator3 = _createForOfIteratorHelper(times || []),
2533
+ _step3;
2534
+ try {
2535
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
2536
+ var time = _step3.value;
2537
+ var _iterator4 = _createForOfIteratorHelper(time.event_list || []),
2538
+ _step4;
2539
+ try {
2540
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
2541
+ var event = _step4.value;
2542
+ var eventStart = dayjs(event.start_at);
2543
+ var eventEnd = dayjs(event.end_at);
2544
+ if (eventStart.isBefore(currentStart) && eventEnd.isAfter(currentStart)) {
2545
+ return currentStart.format('YYYY-MM-DD HH:mm');
2546
+ }
2547
+ if (eventStart.isAfter(currentStart)) {
2548
+ if (!earliestBlockStart || eventStart.isBefore(earliestBlockStart)) {
2549
+ earliestBlockStart = eventStart;
2550
+ }
2551
+ }
2552
+ }
2553
+ } catch (err) {
2554
+ _iterator4.e(err);
2555
+ } finally {
2556
+ _iterator4.f();
2557
+ }
2558
+ }
2559
+ } catch (err) {
2560
+ _iterator3.e(err);
2561
+ } finally {
2562
+ _iterator3.f();
2563
+ }
2564
+ return (_earliestBlockStart = earliestBlockStart) === null || _earliestBlockStart === void 0 ? void 0 : _earliestBlockStart.format('YYYY-MM-DD HH:mm');
2565
+ }
2519
2566
  var resourcesEndTime = targetResourceTimes.reduce(function (acc, curr) {
2520
2567
  return dayjs(curr.end_at).isAfter(dayjs(acc.end_at)) ? curr : acc;
2521
2568
  }, targetResourceTimes[0]);
2569
+ var earliestBlockedStartTime = getEarliestBlockedStartTime({
2570
+ currentStartTime: currentStartTime,
2571
+ times: targetResourceTimes
2572
+ });
2522
2573
 
2523
2574
  // 将 operating_day_boundary 转换为与 resourcesEndTime.end_at 相同日期的完整日期时间
2524
2575
  var resourceDate = dayjs(resourcesEndTime.end_at).format('YYYY-MM-DD');
2525
2576
  var operatingBoundaryDateTime = "".concat(resourceDate, " ").concat(operating_day_boundary.type === 'start_time' ? '23:59' : operating_day_boundary.time);
2526
- var endTime = dayjs(resourcesEndTime.end_at).isBefore(dayjs(operatingBoundaryDateTime)) ? resourcesEndTime.end_at : operatingBoundaryDateTime;
2577
+ var endTimeCandidates = [resourcesEndTime.end_at, operatingBoundaryDateTime].concat(_toConsumableArray(earliestBlockedStartTime ? [earliestBlockedStartTime] : []));
2578
+ var endTime = endTimeCandidates.reduce(function (earliest, value) {
2579
+ return dayjs(value).isBefore(dayjs(earliest)) ? value : earliest;
2580
+ }, endTimeCandidates[0]);
2527
2581
  // 修复:如果 endTime 只是时间格式(如 "17:00"),需要加上日期
2528
2582
  var formattedEndTime;
2529
2583
  if (typeof endTime === 'string' && endTime.includes(':') && !endTime.includes(' ') && !endTime.includes('T')) {
@@ -2664,15 +2718,14 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2664
2718
  // 通过商品和 schedule 来获取视频可用的时间片、时间片内资源可用的数据
2665
2719
  }, {
2666
2720
  key: "getTimeslotBySchedule",
2667
- value: function getTimeslotBySchedule(_ref11) {
2721
+ value: function getTimeslotBySchedule(_ref12) {
2668
2722
  var _this$store$currentPr2,
2669
2723
  _targetProductData$pr,
2670
- _targetProductData$pr2,
2671
2724
  _this15 = this;
2672
- var date = _ref11.date,
2673
- scheduleIds = _ref11.scheduleIds,
2674
- resources = _ref11.resources,
2675
- product = _ref11.product;
2725
+ var date = _ref12.date,
2726
+ scheduleIds = _ref12.scheduleIds,
2727
+ resources = _ref12.resources,
2728
+ product = _ref12.product;
2676
2729
  var targetProduct = this.store.currentProduct;
2677
2730
  // 如果外面传递了product 优先用外面的
2678
2731
  var targetProductData = product || targetProduct;
@@ -2706,29 +2759,35 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2706
2759
  if (!aIsCombined && bIsCombined) return -1;
2707
2760
  return 0;
2708
2761
  });
2709
-
2710
- // 找到当前商品下第一个启用的资源id
2711
- var firstEnabledResourceId = targetProductData === null || targetProductData === void 0 || (_targetProductData$pr = targetProductData.product_resource) === null || _targetProductData$pr === void 0 || (_targetProductData$pr = _targetProductData$pr.resources) === null || _targetProductData$pr === void 0 || (_targetProductData$pr = _targetProductData$pr.find(function (n) {
2762
+ var enabledResourceTypeConfigs = (targetProductData === null || targetProductData === void 0 || (_targetProductData$pr = targetProductData.product_resource) === null || _targetProductData$pr === void 0 || (_targetProductData$pr = _targetProductData$pr.resources) === null || _targetProductData$pr === void 0 ? void 0 : _targetProductData$pr.filter(function (n) {
2712
2763
  return n.status === 1;
2713
- })) === null || _targetProductData$pr === void 0 ? void 0 : _targetProductData$pr.id;
2714
- var firstEnabledResourceConfig = targetProductData === null || targetProductData === void 0 || (_targetProductData$pr2 = targetProductData.product_resource) === null || _targetProductData$pr2 === void 0 || (_targetProductData$pr2 = _targetProductData$pr2.resources) === null || _targetProductData$pr2 === void 0 ? void 0 : _targetProductData$pr2.find(function (n) {
2715
- return n.status === 1 && n.id === firstEnabledResourceId;
2716
- });
2717
- var isMultipleBooking = (firstEnabledResourceConfig === null || firstEnabledResourceConfig === void 0 ? void 0 : firstEnabledResourceConfig.type) === 'multiple';
2764
+ })) || [];
2765
+ var resourceTypeConfigById = new Map(enabledResourceTypeConfigs.map(function (n) {
2766
+ return [n.id, n];
2767
+ }));
2768
+
2718
2769
  // 计算每个日程切片下日程可用的资源的容量总和
2719
2770
  var formatScheduleTimeSlots = scheduleTimeSlots.map(function (item) {
2720
2771
  // 用来计算资源的可使用情况,针对单个schedule 时间片
2721
2772
  var resourcesUseableMap = {};
2722
- var count = 0;
2723
- var bookingLeft = 0;
2724
- var summaryCount = 0;
2725
- var summaryConfigCount = 0;
2773
+ var statsByResourceType = {};
2774
+ enabledResourceTypeConfigs.forEach(function (cfg) {
2775
+ statsByResourceType[cfg.id] = {
2776
+ count: 0,
2777
+ left: 0,
2778
+ summaryCount: 0,
2779
+ summaryConfigCount: 0
2780
+ };
2781
+ });
2782
+
2726
2783
  // 遍历所有资源
2727
2784
  allProductResources === null || allProductResources === void 0 || allProductResources.forEach(function (m) {
2785
+ var currentResourceTypeConfig = resourceTypeConfigById.get(m.form_id);
2786
+ if (!currentResourceTypeConfig) return;
2787
+
2728
2788
  // 遍历所有资源的上工时间片
2729
- var currentResourcesCount = 0;
2730
- var currentResourcesSummaryCount = 0;
2731
- var currentResourcesTimeSlotCanUsedArr = [];
2789
+ var currentResourceMaxRemainingCapacity = 0;
2790
+ var isAllTimeSlicesUsable = true;
2732
2791
  // m.times 需要做个过滤,假设 timeSlice.start_at 是 09:30 timeSlice.end_at 是 11:30
2733
2792
  // time 是 time.start_at = 2025-05-26 10:30, time.end_at = 2025-05-26 12:30
2734
2793
  // 需要判断 time 的开始结束时间 是否包含timeSlice的开始结束时间
@@ -2745,6 +2804,18 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2745
2804
  if (mTimes.length === 0) {
2746
2805
  return;
2747
2806
  }
2807
+
2808
+ // 统计该资源类型在这个时间片的“配置容量”(无占用),只统计上工的资源
2809
+ if (!m.onlyComputed) {
2810
+ var _currentStats = statsByResourceType[m.form_id] || {
2811
+ count: 0,
2812
+ left: 0,
2813
+ summaryCount: 0,
2814
+ summaryConfigCount: 0
2815
+ };
2816
+ if (currentResourceTypeConfig.type === 'multiple') _currentStats.summaryConfigCount += m.capacity;else _currentStats.summaryConfigCount += 1;
2817
+ statsByResourceType[m.form_id] = _currentStats;
2818
+ }
2748
2819
  mTimes.forEach(function (childTiem) {
2749
2820
  // 挨个去匹配某个工作时间段结合当前日程时间,资源能不能用,有多少容量能用
2750
2821
  var res = getIsUsableByTimeItem({
@@ -2763,40 +2834,41 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2763
2834
  if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[m.id]) !== false && res.reason !== 'capacityOnly') {
2764
2835
  resourcesUseableMap[m.id] = res.usable;
2765
2836
  }
2766
- if (res.usable && res.remainingCapacity >= count && !m.onlyComputed) {
2767
- currentResourcesCount = res.remainingCapacity;
2768
- }
2769
- if (res.usable && !m.onlyComputed && res.remainingCapacity >= currentResourcesSummaryCount) {
2770
- currentResourcesSummaryCount = res.remainingCapacity;
2837
+ if (!res.usable) isAllTimeSlicesUsable = false;
2838
+ if (res.usable && !m.onlyComputed) {
2839
+ if (res.remainingCapacity > currentResourceMaxRemainingCapacity) currentResourceMaxRemainingCapacity = res.remainingCapacity;
2771
2840
  }
2772
- currentResourcesTimeSlotCanUsedArr.push(res.usable);
2773
2841
  });
2774
- if (m.form_id === firstEnabledResourceId) {
2775
- // 确认当前资源是单个预约还是多个预约,单个预约则只需要计数,多个预约才添加容量
2776
- if (isMultipleBooking) {
2777
- summaryConfigCount += m.capacity;
2778
- } else {
2779
- summaryConfigCount += 1;
2780
- }
2781
- }
2782
- // 在已经选定时间的情况下,只要canUseTime如果有一个 false 那就不可用
2783
- if (!currentResourcesTimeSlotCanUsedArr.some(function (n) {
2784
- return n === false;
2785
- }) &&
2786
- // 只统计第一种资源的容量和 left
2787
- m.form_id === firstEnabledResourceId) {
2788
- if (currentResourcesCount >= count) {
2789
- count = currentResourcesCount;
2790
- }
2791
- if (!m.onlyComputed) {
2792
- bookingLeft += 1;
2793
- summaryCount += currentResourcesSummaryCount;
2794
- }
2842
+ if (!isAllTimeSlicesUsable) return;
2843
+ if (m.onlyComputed) return;
2844
+ var currentStats = statsByResourceType[m.form_id] || {
2845
+ count: 0,
2846
+ left: 0,
2847
+ summaryCount: 0,
2848
+ summaryConfigCount: 0
2849
+ };
2850
+ currentStats.left += 1;
2851
+ if (currentResourceTypeConfig.type === 'multiple') {
2852
+ currentStats.summaryCount += currentResourceMaxRemainingCapacity;
2853
+ if (currentResourceMaxRemainingCapacity > currentStats.count) currentStats.count = currentResourceMaxRemainingCapacity;
2854
+ } else {
2855
+ // 单个预约:一个资源只计 1,不关心剩余容量
2856
+ currentStats.summaryCount += 1;
2857
+ if (currentStats.count < 1) currentStats.count = 1;
2795
2858
  }
2859
+ statsByResourceType[m.form_id] = currentStats;
2796
2860
  });
2797
2861
  // 容量检测
2798
2862
  var cartItems = _this15.store.cart.getItems();
2799
2863
  productResources.forEach(function (n) {
2864
+ var currentResourceTypeConfig = resourceTypeConfigById.get(n.id);
2865
+ if (!currentResourceTypeConfig) return;
2866
+ var currentStats = statsByResourceType[n.id] || {
2867
+ count: 0,
2868
+ left: 0,
2869
+ summaryCount: 0
2870
+ };
2871
+
2800
2872
  // 单个预约检测规则:
2801
2873
  // 1、跟我一样的商品同一时间在购物车里不可以超过我最少的那种资源的关联的资源个数
2802
2874
  // 2、跟我不一样的商品,只需要跟我当前商品有同一种类型的资源的同一时间的,她配置了几个资源的个数+我配置了几个资源的个数,然后购物车里有几个这样的商品,对应的资源做一个去重,不超过这个去重以后的总数
@@ -2807,10 +2879,10 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2807
2879
  var _m$_productOrigin, _targetProductData$id;
2808
2880
  return ((_m$_productOrigin = m._productOrigin) === null || _m$_productOrigin === void 0 || (_m$_productOrigin = _m$_productOrigin.id) === null || _m$_productOrigin === void 0 ? void 0 : _m$_productOrigin.toString()) === (targetProductData === null || targetProductData === void 0 || (_targetProductData$id = targetProductData.id) === null || _targetProductData$id === void 0 ? void 0 : _targetProductData$id.toString()) && "".concat(m.start_date, " ").concat(m.start_time) === item.start && "".concat(m.start_date, " ").concat(m.end_time) === item.end;
2809
2881
  });
2810
- if (sameCartItems.length > 0 && sameCartItems.length >= currentResourcesSet.size || sameCartItems.length > bookingLeft) {
2811
- bookingLeft = 0;
2812
- count = 0;
2813
- summaryCount = 0;
2882
+ if (sameCartItems.length > 0 && sameCartItems.length >= currentResourcesSet.size || sameCartItems.length > currentStats.left) {
2883
+ currentStats.left = 0;
2884
+ currentStats.count = 0;
2885
+ currentStats.summaryCount = 0;
2814
2886
  }
2815
2887
  // 规则 2
2816
2888
  var otherCartItems = cartItems.filter(function (m) {
@@ -2847,9 +2919,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2847
2919
  }
2848
2920
  });
2849
2921
  if (currentResourcesSet.size > 0 && otherCartItems.length + sameCartItems.length >= currentResourcesSet.size) {
2850
- bookingLeft = 0;
2851
- count = 0;
2852
- summaryCount = 0;
2922
+ currentStats.left = 0;
2923
+ currentStats.count = 0;
2924
+ currentStats.summaryCount = 0;
2853
2925
  }
2854
2926
  } else {
2855
2927
  // 多个预约的检测规则:
@@ -2865,9 +2937,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2865
2937
  return !curr.onlyComputed ? acc + curr.capacity || 0 : acc;
2866
2938
  }, 0);
2867
2939
  if (sameCartNeedCapacity >= currentProductResourcesCapacity) {
2868
- bookingLeft = 0;
2869
- count = 0;
2870
- summaryCount = 0;
2940
+ currentStats.left = 0;
2941
+ currentStats.count = 0;
2942
+ currentStats.summaryCount = 0;
2871
2943
  }
2872
2944
  // 规则2、不管是不是跟我一样的商品,只需要跟我当前商品有同一种类型的资源的同一时间的,把所有购物车的 capacity 之和 和 所有当前类型资源的 capacity 之和比较,如果超过了resourcesCapacity,则不可用
2873
2945
  // const otherCartItems = cartItems.filter((m) => m._productOrigin?.id?.toString() !== targetProductData?.id?.toString() && m.start_time === item.start && m.end_time === item.end);
@@ -2929,45 +3001,61 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2929
3001
  }, 0);
2930
3002
  // 如果已使用容量超过了当前类型资源的容量,则不可用
2931
3003
  if (otherCartNeedCapacity + usedCapacity >= currentTypeResourcesCapacity) {
2932
- bookingLeft = 0;
2933
- count = 0;
2934
- summaryCount = 0;
3004
+ currentStats.left = 0;
3005
+ currentStats.count = 0;
3006
+ currentStats.summaryCount = 0;
2935
3007
  }
2936
3008
  }
3009
+ statsByResourceType[n.id] = currentStats;
2937
3010
  });
2938
3011
  var startDayJs = dayjs(item.start);
2939
3012
  var endDayJs = dayjs(item.end);
2940
3013
 
2941
- // 状态
2942
- // 如果是isMultipleBooking
2943
- // lots_of_space: summaryCount / summaryConfigCount > 0.5
2944
- // filling_up_fast: summaryCount / summaryConfigCount <= 0.5 && summaryCount > 0
2945
- // sold_out: bookingLeft = 0
2946
- // 如果不是isMultipleBooking
2947
- // lots_of_space: bookingLeft / summaryConfigCount > 0.5
2948
- // filling_up_fast: bookingLeft / summaryConfigCount <= 0.5 && count > 0
2949
- // sold_out: bookingLeft = 0
2950
- var timeStatus = 'sold_out';
2951
- if (bookingLeft === 0) timeStatus = 'sold_out';else if (isMultipleBooking) {
2952
- if (summaryConfigCount === 0) timeStatus = 'sold_out';else {
2953
- var usageRatio = summaryCount / summaryConfigCount;
2954
- if (usageRatio > 0.5) timeStatus = 'lots_of_space';else if (summaryCount > 0) timeStatus = 'filling_up_fast';else timeStatus = 'sold_out';
3014
+ // 选择“瓶颈资源类型”:multiple 取 summaryCount 最小,single 取 left 最小
3015
+ var bottleneckResourceTypeId;
3016
+ var bottleneckValue = Infinity;
3017
+ enabledResourceTypeConfigs.forEach(function (cfg) {
3018
+ var stats = statsByResourceType[cfg.id] || {
3019
+ count: 0,
3020
+ left: 0,
3021
+ summaryCount: 0,
3022
+ summaryConfigCount: 0
3023
+ };
3024
+ var value = cfg.type === 'multiple' ? stats.summaryCount : stats.left;
3025
+ if (value < bottleneckValue) {
3026
+ bottleneckValue = value;
3027
+ bottleneckResourceTypeId = cfg.id;
2955
3028
  }
3029
+ });
3030
+ var bottleneckStats = bottleneckResourceTypeId !== undefined ? statsByResourceType[bottleneckResourceTypeId] || {
3031
+ count: 0,
3032
+ left: 0,
3033
+ summaryCount: 0,
3034
+ summaryConfigCount: 0
3035
+ } : {
3036
+ count: 0,
3037
+ left: 0,
3038
+ summaryCount: 0,
3039
+ summaryConfigCount: 0
3040
+ };
3041
+ var bottleneckConfig = bottleneckResourceTypeId !== undefined ? resourceTypeConfigById.get(bottleneckResourceTypeId) : undefined;
3042
+ var status = 'sold_out';
3043
+ if (bottleneckStats.left === 0) status = 'sold_out';else if (!bottleneckConfig || bottleneckStats.summaryConfigCount === 0) status = 'sold_out';else if (bottleneckConfig.type === 'multiple') {
3044
+ var usageRatio = bottleneckStats.summaryCount / bottleneckStats.summaryConfigCount;
3045
+ if (usageRatio > 0.5) status = 'lots_of_space';else if (bottleneckStats.summaryCount > 0) status = 'filling_up_fast';else status = 'sold_out';
2956
3046
  } else {
2957
- if (summaryConfigCount === 0) timeStatus = 'sold_out';else {
2958
- var _usageRatio = bookingLeft / summaryConfigCount;
2959
- if (_usageRatio > 0.5) timeStatus = 'lots_of_space';else if (count > 0) timeStatus = 'filling_up_fast';else timeStatus = 'sold_out';
2960
- }
3047
+ var _usageRatio = bottleneckStats.left / bottleneckStats.summaryConfigCount;
3048
+ if (_usageRatio > 0.5) status = 'lots_of_space';else if (bottleneckStats.count > 0) status = 'filling_up_fast';else status = 'sold_out';
2961
3049
  }
2962
3050
  return {
2963
3051
  start_time: startDayJs.format('HH:mm'),
2964
3052
  end_time: endDayJs.format('HH:mm'),
2965
3053
  start_at: startDayJs,
2966
3054
  end_at: endDayJs,
2967
- count: count,
2968
- left: bookingLeft,
2969
- summaryCount: summaryCount,
2970
- status: timeStatus
3055
+ count: bottleneckStats.count,
3056
+ left: bottleneckStats.left,
3057
+ summaryCount: bottleneckStats.summaryCount,
3058
+ status: status
2971
3059
  };
2972
3060
  });
2973
3061
  return formatScheduleTimeSlots;
@@ -3196,12 +3284,12 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3196
3284
  // 检查资源类型(单个预约 vs 多个预约)
3197
3285
  // 从商品配置中获取资源类型信息
3198
3286
  var resourceTypeConfig = null;
3199
- var _iterator3 = _createForOfIteratorHelper(items),
3200
- _step3;
3287
+ var _iterator5 = _createForOfIteratorHelper(items),
3288
+ _step5;
3201
3289
  try {
3202
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
3290
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
3203
3291
  var _cartItem$_productOri12;
3204
- var cartItem = _step3.value;
3292
+ var cartItem = _step5.value;
3205
3293
  if ((_cartItem$_productOri12 = cartItem._productOrigin) !== null && _cartItem$_productOri12 !== void 0 && (_cartItem$_productOri12 = _cartItem$_productOri12.product_resource) !== null && _cartItem$_productOri12 !== void 0 && _cartItem$_productOri12.resources) {
3206
3294
  resourceTypeConfig = cartItem._productOrigin.product_resource.resources.find(function (r) {
3207
3295
  return r.code === resourceCode && r.status === 1;
@@ -3210,9 +3298,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3210
3298
  }
3211
3299
  }
3212
3300
  } catch (err) {
3213
- _iterator3.e(err);
3301
+ _iterator5.e(err);
3214
3302
  } finally {
3215
- _iterator3.f();
3303
+ _iterator5.f();
3216
3304
  }
3217
3305
  var isMultipleBooking = ((_resourceTypeConfig = resourceTypeConfig) === null || _resourceTypeConfig === void 0 ? void 0 : _resourceTypeConfig.type) === 'multiple';
3218
3306
  var totalAvailable;
@@ -3415,17 +3503,17 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3415
3503
  */
3416
3504
  }, {
3417
3505
  key: "convertProductToCartItem",
3418
- value: function convertProductToCartItem(_ref12) {
3419
- var product = _ref12.product,
3420
- date = _ref12.date,
3421
- account = _ref12.account;
3422
- var _ref13 = product || {},
3423
- bundle = _ref13.bundle,
3424
- options = _ref13.options,
3425
- origin = _ref13.origin,
3426
- product_variant_id = _ref13.product_variant_id,
3427
- _ref13$quantity = _ref13.quantity,
3428
- quantity = _ref13$quantity === void 0 ? 1 : _ref13$quantity;
3506
+ value: function convertProductToCartItem(_ref13) {
3507
+ var product = _ref13.product,
3508
+ date = _ref13.date,
3509
+ account = _ref13.account;
3510
+ var _ref14 = product || {},
3511
+ bundle = _ref14.bundle,
3512
+ options = _ref14.options,
3513
+ origin = _ref14.origin,
3514
+ product_variant_id = _ref14.product_variant_id,
3515
+ _ref14$quantity = _ref14.quantity,
3516
+ quantity = _ref14$quantity === void 0 ? 1 : _ref14$quantity;
3429
3517
 
3430
3518
  // 处理商品数据,类似 addProductToCart 中的逻辑
3431
3519
  var productData = _objectSpread(_objectSpread({}, origin), {}, {
@@ -3480,11 +3568,11 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3480
3568
  }
3481
3569
  }, {
3482
3570
  key: "checkMaxDurationCapacityForDetailNums",
3483
- value: function checkMaxDurationCapacityForDetailNums(_ref14) {
3571
+ value: function checkMaxDurationCapacityForDetailNums(_ref15) {
3484
3572
  var _this17 = this;
3485
- var product = _ref14.product,
3486
- date = _ref14.date,
3487
- account = _ref14.account;
3573
+ var product = _ref15.product,
3574
+ date = _ref15.date,
3575
+ account = _ref15.account;
3488
3576
  var cartItems = this.store.cart.getItems().filter(function (item) {
3489
3577
  return !isNormalProduct(item._productOrigin);
3490
3578
  });
@@ -3629,12 +3717,12 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3629
3717
  // 检查资源类型(单个预约 vs 多个预约)
3630
3718
  // 从商品配置中获取资源类型信息
3631
3719
  var resourceTypeConfig = null;
3632
- var _iterator4 = _createForOfIteratorHelper(items),
3633
- _step4;
3720
+ var _iterator6 = _createForOfIteratorHelper(items),
3721
+ _step6;
3634
3722
  try {
3635
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
3723
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
3636
3724
  var _cartItem$_productOri15;
3637
- var cartItem = _step4.value;
3725
+ var cartItem = _step6.value;
3638
3726
  if ((_cartItem$_productOri15 = cartItem._productOrigin) !== null && _cartItem$_productOri15 !== void 0 && (_cartItem$_productOri15 = _cartItem$_productOri15.product_resource) !== null && _cartItem$_productOri15 !== void 0 && _cartItem$_productOri15.resources) {
3639
3727
  resourceTypeConfig = cartItem._productOrigin.product_resource.resources.find(function (r) {
3640
3728
  return r.code === resourceCode && r.status === 1;
@@ -3643,9 +3731,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
3643
3731
  }
3644
3732
  }
3645
3733
  } catch (err) {
3646
- _iterator4.e(err);
3734
+ _iterator6.e(err);
3647
3735
  } finally {
3648
- _iterator4.f();
3736
+ _iterator6.f();
3649
3737
  }
3650
3738
  var isMultipleBooking = ((_resourceTypeConfig2 = resourceTypeConfig) === null || _resourceTypeConfig2 === void 0 ? void 0 : _resourceTypeConfig2.type) === 'multiple';
3651
3739
  var totalAvailable;
@@ -4016,12 +4104,12 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
4016
4104
  }, {
4017
4105
  key: "getTimeslotsScheduleByDateRange",
4018
4106
  value: (function () {
4019
- var _getTimeslotsScheduleByDateRange = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27(_ref15) {
4107
+ var _getTimeslotsScheduleByDateRange = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27(_ref16) {
4020
4108
  var startDate, endDate, scheduleIds, resources, dates, currentDate, end, results, _i5, _dates, date;
4021
4109
  return _regeneratorRuntime().wrap(function _callee27$(_context28) {
4022
4110
  while (1) switch (_context28.prev = _context28.next) {
4023
4111
  case 0:
4024
- startDate = _ref15.startDate, endDate = _ref15.endDate, scheduleIds = _ref15.scheduleIds, resources = _ref15.resources;
4112
+ startDate = _ref16.startDate, endDate = _ref16.endDate, scheduleIds = _ref16.scheduleIds, resources = _ref16.resources;
4025
4113
  console.log('appoimentBooking-session-date-getTimeslotsScheduleByDateRange', {
4026
4114
  startDate: startDate,
4027
4115
  endDate: endDate,
@@ -4146,7 +4234,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
4146
4234
  openResources = ((_tempProducts = tempProducts) === null || _tempProducts === void 0 || (_tempProducts = _tempProducts.product_resource) === null || _tempProducts === void 0 || (_tempProducts = _tempProducts.resources) === null || _tempProducts === void 0 ? void 0 : _tempProducts.filter(function (m) {
4147
4235
  return m.status === 1;
4148
4236
  })) || []; // res.data 返回的一定是启用商品的资源列表,不需要再过滤了
4149
- allProductResources = sortCombinedResources(res.data); // allProductResources 需要根据商品里的资源的单个预约多个预约补充resourceType
4237
+ allProductResources = cloneDeep(sortCombinedResources(res.data) || []); // allProductResources 需要根据商品里的资源的单个预约多个预约补充resourceType
4150
4238
  allProductResources.forEach(function (m) {
4151
4239
  var _tempProducts2;
4152
4240
  var resource = (_tempProducts2 = tempProducts) === null || _tempProducts2 === void 0 || (_tempProducts2 = _tempProducts2.product_resource) === null || _tempProducts2 === void 0 || (_tempProducts2 = _tempProducts2.resources) === null || _tempProducts2 === void 0 ? void 0 : _tempProducts2.find(function (n) {
@@ -4202,12 +4290,35 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
4202
4290
  // 总量=每个资源在每个时间片内资源总量之和
4203
4291
  var isAllResourceTypesUseable = true;
4204
4292
  openResources.forEach(function (resource) {
4293
+ var _resource$renderList;
4205
4294
  // if (!isAllResourceTypesUseable) return;
4206
4295
 
4207
4296
  // 获取当前资源类型的资源列表
4208
4297
  var currentResourcesList = allProductResources.filter(function (n) {
4209
4298
  return n.form_id === resource.resource_type_id;
4210
4299
  });
4300
+ // 如果resource.renderList里含有 onlyComputed 的数据,需要把 currentResourcesList 的数据也修正回来
4301
+ (_resource$renderList = resource.renderList) === null || _resource$renderList === void 0 || _resource$renderList.forEach(function (item) {
4302
+ if (item.onlyComputed) {
4303
+ var targetIndex = currentResourcesList.findIndex(function (n) {
4304
+ return n.id === item.id;
4305
+ });
4306
+ if (targetIndex && targetIndex !== -1) {
4307
+ currentResourcesList[targetIndex].onlyComputed = true;
4308
+ }
4309
+ }
4310
+ });
4311
+ // 可能存在 renderList 没有的情况,则需要判断 resource.optional_resource 和 resource.default_resource 是否存在那个资源,如果不存在也打上 onlyComputed 的标记
4312
+ currentResourcesList.forEach(function (item) {
4313
+ var _resource$optional_re, _resource$default_res;
4314
+ if (!((_resource$optional_re = resource.optional_resource) !== null && _resource$optional_re !== void 0 && _resource$optional_re.includes(item.id)) && !((_resource$default_res = resource.default_resource) !== null && _resource$default_res !== void 0 && _resource$default_res.includes(item.id))) {
4315
+ item.onlyComputed = true;
4316
+ }
4317
+ });
4318
+ // currentResourcesList 排序,onlyComputed 的资源排在前面先计算
4319
+ currentResourcesList.sort(function (a, b) {
4320
+ return a.onlyComputed ? -1 : 1;
4321
+ });
4211
4322
  var isAnyResourceUseableInType = false;
4212
4323
  currentResourcesList === null || currentResourcesList === void 0 || currentResourcesList.forEach(function (m) {
4213
4324
  // 遍历所有资源的上工时间片
@@ -4221,10 +4332,12 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
4221
4332
  // 如果在这个区间的时间一个都没有,可以直接认为这个资源不可用
4222
4333
  if (mTimes.length === 0) return;
4223
4334
  // 如果资源可用则把他的容量纳入总计
4224
- if (resource.type === 'multiple') {
4225
- summaryCount += m.capacity;
4226
- } else {
4227
- summaryCount += 1;
4335
+ if (!m.onlyComputed) {
4336
+ if (resource.type === 'multiple') {
4337
+ summaryCount += m.capacity;
4338
+ } else {
4339
+ summaryCount += 1;
4340
+ }
4228
4341
  }
4229
4342
  var isAnyTimeSliceUseable = false;
4230
4343
  mTimes.forEach(function (childTiem) {
@@ -695,7 +695,8 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
695
695
  action: 'create',
696
696
  with_good_pass: 1,
697
697
  with_discount_card: 1,
698
- with_wallet_pass_holder: 1
698
+ with_wallet_pass_holder: 1,
699
+ request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
699
700
  });
700
701
  case 4:
701
702
  goodPassList = _context8.sent;
@@ -146,6 +146,8 @@ export interface CartItem {
146
146
  _optionsOrigin?: any[];
147
147
  /** 操作系统提示 */
148
148
  osWarnTips?: string[];
149
+ /** 金额差值 */
150
+ totalDifference?: number;
149
151
  }
150
152
  /**
151
153
  * 购物车状态接口
@@ -45,6 +45,7 @@ module.exports = __toCommonJS(cartProduct_exports);
45
45
  var import_decimal = __toESM(require("decimal.js"));
46
46
  var import_utils = require("../../Product/utils");
47
47
  var import_utils2 = require("../../../solution/ShopDiscount/utils");
48
+ var import_utils3 = require("../../Summary/utils");
48
49
  var handleVariantProduct = (product) => {
49
50
  var _a;
50
51
  if (product == null ? void 0 : product.product_variant_id) {
@@ -80,6 +81,7 @@ var formatProductToCartItem = (params) => {
80
81
  cartItem.price = product == null ? void 0 : product.price;
81
82
  cartItem.num = num;
82
83
  cartItem.total = getProductTotalPrice({ product, bundle, options, num, discounts });
84
+ cartItem.totalDifference = getTotalDifference({ product, bundle, discounts });
83
85
  cartItem.summaryTotal = cartItem.total * (num || 1);
84
86
  cartItem.origin_total = getProductOriginTotalPrice({
85
87
  product,
@@ -207,6 +209,18 @@ var getProductTotalPrice = (params) => {
207
209
  }
208
210
  return Math.max(0, price);
209
211
  };
212
+ var getTotalDifference = (params) => {
213
+ const { bundle, discounts } = params;
214
+ const bundleDiscountList = [];
215
+ if (bundle == null ? void 0 : bundle.length) {
216
+ bundle.forEach((currentValue) => {
217
+ bundleDiscountList.push(...(currentValue == null ? void 0 : currentValue.discount_list) || []);
218
+ });
219
+ }
220
+ const allDiscounts = [...discounts || [], ...bundleDiscountList];
221
+ const productDiscountProductDiscountDifference = (0, import_utils3.calcDiscountListDifference)(allDiscounts);
222
+ return productDiscountProductDiscountDifference || 0;
223
+ };
210
224
  var getProductOriginTotalPrice = (params) => {
211
225
  const { product, bundle, options, discounts } = params;
212
226
  const num = (params == null ? void 0 : params.num) || 1;
@@ -271,7 +285,8 @@ var formatBundle = (bundle) => {
271
285
  options: formatOptions(item == null ? void 0 : item.option),
272
286
  _bundle_product_id: item._bundle_product_id,
273
287
  discount_list: item.discount_list,
274
- originBundleItem: item.originBundleItem || item
288
+ originBundleItem: item.originBundleItem || item,
289
+ is_charge_tax: item == null ? void 0 : item.is_charge_tax
275
290
  };
276
291
  });
277
292
  };