@pisell/pisellos 0.0.275 → 0.0.277

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.
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  };
327
327
  setOtherData(key: string, value: any): void;
328
328
  getOtherData(key: string): any;
329
- getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
329
+ getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
330
330
  /**
331
331
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
332
332
  *
@@ -44,7 +44,7 @@ import { handleAvailableDateByResource } from "../../modules/Date/utils";
44
44
  import { areAllNormalProducts, isNormalProduct } from "../../modules/Product/utils";
45
45
  import { calculateResourceAvailableTime, filterConditionTimeSlots, findFastestAvailableResource } from "./utils/timeslots";
46
46
  import { updateAllCartItemPrice } from "../../modules/Cart/utils/changePrice";
47
- import { getCapacityInfoByCartItem, checkSubResourcesCapacity, checkResourceCanUseByCapacity, calculateCartItemsCapacityUsageByResourceType, getResourcesIdsByProduct, checkTimeSlotCapacity } from "./utils/capacity";
47
+ import { getCapacityInfoByCartItem, checkSubResourcesCapacity, checkResourceCanUseByCapacity, getResourcesIdsByProduct, checkTimeSlotCapacity } from "./utils/capacity";
48
48
  import { checkProductStock } from "./utils/stock";
49
49
  export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
50
50
  _inherits(BookingByStepImpl, _BaseModule);
@@ -2367,7 +2367,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2367
2367
  }, {
2368
2368
  key: "getTimeslotBySchedule",
2369
2369
  value: function getTimeslotBySchedule(_ref10) {
2370
- var _this$store$currentPr2, _targetProductData$pr;
2370
+ var _this$store$currentPr2,
2371
+ _targetProductData$pr,
2372
+ _this14 = this;
2371
2373
  var date = _ref10.date,
2372
2374
  scheduleIds = _ref10.scheduleIds,
2373
2375
  resources = _ref10.resources,
@@ -2415,139 +2417,197 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2415
2417
  var formatScheduleTimeSlots = scheduleTimeSlots.map(function (item) {
2416
2418
  // 用来计算资源的可使用情况,针对单个schedule 时间片
2417
2419
  var resourcesUseableMap = {};
2418
-
2419
- // 按资源类型分组
2420
- var resourceTypeMap = {};
2421
- allProductResources === null || allProductResources === void 0 || allProductResources.forEach(function (resource) {
2422
- var _resource$form_id;
2423
- var formId = ((_resource$form_id = resource.form_id) === null || _resource$form_id === void 0 ? void 0 : _resource$form_id.toString()) || 'default';
2424
- if (!resourceTypeMap[formId]) {
2425
- resourceTypeMap[formId] = [];
2420
+ var count = 0;
2421
+ var bookingLeft = 0;
2422
+ // 遍历所有资源
2423
+ allProductResources === null || allProductResources === void 0 || allProductResources.forEach(function (m) {
2424
+ // 遍历所有资源的上工时间片
2425
+ var currentResourcesCount = 0;
2426
+ var currentResourcesTimeSlotCanUsedArr = [];
2427
+ // m.times 需要做个过滤,假设 timeSlice.start_at 是 09:30 timeSlice.end_at 是 11:30
2428
+ // time 是 time.start_at = 2025-05-26 10:30, time.end_at = 2025-05-26 12:30
2429
+ // 需要判断 time 的开始结束时间 是否包含timeSlice的开始结束时间
2430
+
2431
+ // n.start_at 是 2025-06-30 15:00 end_at 2025-06-30 17:00
2432
+ // item.start 是 2025-06-30 16:00 item.end 是 2025-06-30 19:00
2433
+ // 需要判断 n.start_at 和 n.end_at 是否在 item.start 和 item.end 之间
2434
+ // 如果 n.start_at 和 n.end_at 在 item.start 和 item.end 有交集,则此时间需要计算
2435
+ var mTimes = m.times.filter(function (n) {
2436
+ return !dayjs(n.start_at).isAfter(dayjs(item.start), 'minute') && !dayjs(n.end_at).isBefore(dayjs(item.end), 'minute') || dayjs(n.start_at).isBefore(dayjs(item.end), 'minute') && dayjs(n.end_at).isAfter(dayjs(item.start), 'minute');
2437
+ });
2438
+ // 如果在这个区间的时间一个都没有,可以直接认为这个资源不可用
2439
+ if (mTimes.length === 0) {
2440
+ return;
2441
+ }
2442
+ mTimes.forEach(function (childTiem) {
2443
+ // 挨个去匹配某个工作时间段结合当前日程时间,资源能不能用,有多少容量能用
2444
+ var res = getIsUsableByTimeItem({
2445
+ timeSlice: {
2446
+ start_time: item.start,
2447
+ end_time: item.end,
2448
+ start_at: dayjs(item.start),
2449
+ end_at: dayjs(item.end)
2450
+ },
2451
+ time: childTiem,
2452
+ resource: m,
2453
+ currentCount: 1,
2454
+ resourcesUseableMap: resourcesUseableMap,
2455
+ cut_off_time: targetProductData === null || targetProductData === void 0 ? void 0 : targetProductData.cut_off_time
2456
+ });
2457
+ if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[m.id]) !== false && res.reason !== 'capacityOnly') {
2458
+ resourcesUseableMap[m.id] = res.usable;
2459
+ }
2460
+ if (res.usable && res.remainingCapacity >= count && !m.onlyComputed) {
2461
+ currentResourcesCount = res.remainingCapacity;
2462
+ }
2463
+ currentResourcesTimeSlotCanUsedArr.push(res.usable);
2464
+ });
2465
+ // 在已经选定时间的情况下,只要canUseTime如果有一个 false 那就不可用
2466
+ if (!currentResourcesTimeSlotCanUsedArr.some(function (n) {
2467
+ return n === false;
2468
+ }) &&
2469
+ // 只统计第一种资源的容量和 left
2470
+ m.form_id === firstEnabledResourceId) {
2471
+ if (currentResourcesCount >= count) {
2472
+ count = currentResourcesCount;
2473
+ }
2474
+ if (!m.onlyComputed) {
2475
+ bookingLeft += 1;
2476
+ }
2426
2477
  }
2427
- resourceTypeMap[formId].push(resource);
2428
- });
2429
-
2430
- // 计算购物车中商品的容量占用情况
2431
- var cartCapacityUsage = calculateCartItemsCapacityUsageByResourceType({
2432
- cartItems: cartItems,
2433
- timeSlotStart: item.start,
2434
- timeSlotEnd: item.end,
2435
- allProductResources: allProductResources || []
2436
2478
  });
2437
-
2438
- // 计算每种资源类型的可用容量
2439
- var minAvailableCount = Number.MAX_SAFE_INTEGER;
2440
- var totalBookingLeft = 0;
2441
- var hasAnyAvailableResource = false;
2442
- Object.keys(resourceTypeMap).forEach(function (formId) {
2443
- var resourcesInType = resourceTypeMap[formId];
2444
- if (resourcesInType.length === 0) return;
2445
-
2446
- // 确定这种资源类型的预约类型(取第一个资源的类型)
2447
- var firstResource = resourcesInType[0];
2448
- var isMultipleBooking = firstResource.resourceType === 'multiple';
2449
- var cartUsageForThisType = cartCapacityUsage[formId] || 0;
2450
- if (isMultipleBooking) {
2451
- // 多个预约:计算所有资源的总可用容量
2452
- var totalAvailableCapacity = 0;
2453
- var availableResourceCount = 0;
2454
- resourcesInType.forEach(function (resource) {
2455
- var mTimes = resource.times.filter(function (n) {
2456
- return !dayjs(n.start_at).isAfter(dayjs(item.start), 'minute') && !dayjs(n.end_at).isBefore(dayjs(item.end), 'minute') || dayjs(n.start_at).isBefore(dayjs(item.end), 'minute') && dayjs(n.end_at).isAfter(dayjs(item.start), 'minute');
2479
+ // 容量检测
2480
+ var cartItems = _this14.store.cart.getItems();
2481
+ productResources.forEach(function (n) {
2482
+ // 单个预约检测规则:
2483
+ // 1、跟我一样的商品同一时间在购物车里不可以超过我最少的那种资源的关联的资源个数
2484
+ // 2、跟我不一样的商品,只需要跟我当前商品有同一种类型的资源的同一时间的,她配置了几个资源的个数+我配置了几个资源的个数,然后购物车里有几个这样的商品,对应的资源做一个去重,不超过这个去重以后的总数
2485
+ if (n.type === 'single') {
2486
+ var currentResourcesSet = new Set([].concat(_toConsumableArray(n.optional_resource), _toConsumableArray(n.default_resource)));
2487
+ // 规则 1
2488
+ var sameCartItems = cartItems.filter(function (m) {
2489
+ var _m$_productOrigin, _targetProductData$id;
2490
+ 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;
2491
+ });
2492
+ if (sameCartItems.length > 0 && sameCartItems.length >= currentResourcesSet.size || sameCartItems.length > bookingLeft) {
2493
+ bookingLeft = 0;
2494
+ count = 0;
2495
+ }
2496
+ // 规则 2
2497
+ var otherCartItems = cartItems.filter(function (m) {
2498
+ var _m$_productOrigin2, _targetProductData$id2;
2499
+ return ((_m$_productOrigin2 = m._productOrigin) === null || _m$_productOrigin2 === void 0 || (_m$_productOrigin2 = _m$_productOrigin2.id) === null || _m$_productOrigin2 === void 0 ? void 0 : _m$_productOrigin2.toString()) !== (targetProductData === null || targetProductData === void 0 || (_targetProductData$id2 = targetProductData.id) === null || _targetProductData$id2 === void 0 ? void 0 : _targetProductData$id2.toString()) && "".concat(m.start_date, " ").concat(m.start_time) === item.start && "".concat(m.start_date, " ").concat(m.end_time) === item.end;
2500
+ });
2501
+ otherCartItems.forEach(function (m) {
2502
+ var _m$_productOrigin3;
2503
+ var sameTypeResources = (_m$_productOrigin3 = m._productOrigin) === null || _m$_productOrigin3 === void 0 || (_m$_productOrigin3 = _m$_productOrigin3.product_resource) === null || _m$_productOrigin3 === void 0 || (_m$_productOrigin3 = _m$_productOrigin3.resources) === null || _m$_productOrigin3 === void 0 ? void 0 : _m$_productOrigin3.find(function (m) {
2504
+ return m.type === n.type;
2457
2505
  });
2458
- if (mTimes.length === 0) return;
2459
- var resourceAvailableCapacity = 0;
2460
- mTimes.forEach(function (childTime) {
2461
- var res = getIsUsableByTimeItem({
2462
- timeSlice: {
2463
- start_time: item.start,
2464
- end_time: item.end,
2465
- start_at: dayjs(item.start),
2466
- end_at: dayjs(item.end)
2467
- },
2468
- time: childTime,
2469
- resource: resource,
2470
- currentCount: 1,
2471
- resourcesUseableMap: resourcesUseableMap,
2472
- cut_off_time: targetProductData === null || targetProductData === void 0 ? void 0 : targetProductData.cut_off_time
2506
+ var sameTypeResourcesSet = new Set([].concat(_toConsumableArray((sameTypeResources === null || sameTypeResources === void 0 ? void 0 : sameTypeResources.optional_resource) || []), _toConsumableArray((sameTypeResources === null || sameTypeResources === void 0 ? void 0 : sameTypeResources.default_resource) || [])));
2507
+ // 把sameTypeResourcesSet 加到currentResourcesSet
2508
+ sameTypeResourcesSet.forEach(function (resource) {
2509
+ return currentResourcesSet.add(resource);
2510
+ });
2511
+ });
2512
+ // 先确定是否每一个currentResourcesSet在这个时间点的 event_list 都是空的,如果不是空的还需要把他踢出currentResourcesSet
2513
+ var currentDataResources = _this14.store.date.getResourcesListByDate(dayjs(item.start).format('YYYY-MM-DD'));
2514
+ currentDataResources === null || currentDataResources === void 0 || currentDataResources.forEach(function (m) {
2515
+ if (currentResourcesSet.has(m.id)) {
2516
+ var mTimes = m.times.filter(function (n) {
2517
+ return !dayjs(n.start_at).isAfter(dayjs(item.start), 'minute') && !dayjs(n.end_at).isBefore(dayjs(item.end), 'minute') || dayjs(n.start_at).isBefore(dayjs(item.end), 'minute') && dayjs(n.end_at).isAfter(dayjs(item.start), 'minute');
2473
2518
  });
2474
- if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[resource.id]) !== false && res.reason !== 'capacityOnly') {
2475
- resourcesUseableMap[resource.id] = res.usable;
2476
- }
2477
- if (res.usable && !resource.onlyComputed) {
2478
- resourceAvailableCapacity = Math.max(resourceAvailableCapacity, res.remainingCapacity);
2479
- availableResourceCount++;
2519
+ if (!mTimes.length || mTimes.some(function (n) {
2520
+ return n.event_list.length;
2521
+ })) {
2522
+ currentResourcesSet.delete(m.id);
2480
2523
  }
2481
- });
2482
- totalAvailableCapacity += resourceAvailableCapacity;
2524
+ }
2483
2525
  });
2484
-
2485
- // 减去购物车中已占用的容量
2486
- var netAvailableCapacity = Math.max(0, totalAvailableCapacity - cartUsageForThisType);
2487
- if (netAvailableCapacity < minAvailableCount) {
2488
- minAvailableCount = netAvailableCapacity;
2489
- }
2490
- if (netAvailableCapacity > 0) {
2491
- hasAnyAvailableResource = true;
2526
+ if (currentResourcesSet.size > 0 && otherCartItems.length + sameCartItems.length >= currentResourcesSet.size) {
2527
+ bookingLeft = 0;
2528
+ count = 0;
2492
2529
  }
2493
2530
  } else {
2494
- // 单个预约:计算可用资源个数
2495
- var _availableResourceCount = 0;
2496
- resourcesInType.forEach(function (resource) {
2497
- var mTimes = resource.times.filter(function (n) {
2531
+ // 多个预约的检测规则:
2532
+ // 规则1、跟我一样的商品同一时间在购物车需要的容量总数不可以超过我配置的资源的 capacity 之和
2533
+ var _sameCartItems = cartItems.filter(function (m) {
2534
+ var _m$_productOrigin4, _targetProductData$id3;
2535
+ return ((_m$_productOrigin4 = m._productOrigin) === null || _m$_productOrigin4 === void 0 || (_m$_productOrigin4 = _m$_productOrigin4.id) === null || _m$_productOrigin4 === void 0 ? void 0 : _m$_productOrigin4.toString()) === (targetProductData === null || targetProductData === void 0 || (_targetProductData$id3 = targetProductData.id) === null || _targetProductData$id3 === void 0 ? void 0 : _targetProductData$id3.toString()) && "".concat(m.start_date, " ").concat(m.start_time) === item.start && "".concat(m.start_date, " ").concat(m.end_time) === item.end;
2536
+ });
2537
+ var sameCartNeedCapacity = _sameCartItems.reduce(function (acc, curr) {
2538
+ return acc + getCapacityInfoByCartItem(curr).currentCapacity;
2539
+ }, 0);
2540
+ var currentProductResourcesCapacity = n.renderList.reduce(function (acc, curr) {
2541
+ return !curr.onlyComputed ? acc + curr.capacity || 0 : acc;
2542
+ }, 0);
2543
+ if (sameCartNeedCapacity >= currentProductResourcesCapacity) {
2544
+ bookingLeft = 0;
2545
+ count = 0;
2546
+ }
2547
+ // 规则2、不管是不是跟我一样的商品,只需要跟我当前商品有同一种类型的资源的同一时间的,把所有购物车的 capacity 之和 和 所有当前类型资源的 capacity 之和比较,如果超过了resourcesCapacity,则不可用
2548
+ // const otherCartItems = cartItems.filter((m) => m._productOrigin?.id?.toString() !== targetProductData?.id?.toString() && m.start_time === item.start && m.end_time === item.end);
2549
+ var otherSameTimesCartItems = cartItems.filter(function (m) {
2550
+ return "".concat(m.start_date, " ").concat(m.start_time) === item.start && "".concat(m.start_date, " ").concat(m.end_time) === item.end;
2551
+ });
2552
+ var otherCartNeedCapacity = otherSameTimesCartItems.reduce(function (acc, curr) {
2553
+ return acc + getCapacityInfoByCartItem(curr).currentCapacity;
2554
+ }, 0);
2555
+ var allRenderList = _toConsumableArray(n.renderList.filter(function (m) {
2556
+ return !m.onlyComputed;
2557
+ }));
2558
+ otherSameTimesCartItems.forEach(function (m) {
2559
+ var _m$_productOrigin5;
2560
+ var productResources = getResourcesByProduct(getResourcesMap((targetResourceDate === null || targetResourceDate === void 0 ? void 0 : targetResourceDate.resource) || []), ((_m$_productOrigin5 = m._productOrigin) === null || _m$_productOrigin5 === void 0 || (_m$_productOrigin5 = _m$_productOrigin5.product_resource) === null || _m$_productOrigin5 === void 0 ? void 0 : _m$_productOrigin5.resources) || [], selectedResources, 1);
2561
+ productResources.forEach(function (m) {
2562
+ if (m.id === n.id) {
2563
+ m.renderList.forEach(function (n) {
2564
+ if (!n.onlyComputed && !allRenderList.find(function (m) {
2565
+ return m.id === n.id;
2566
+ })) {
2567
+ allRenderList.push(n);
2568
+ }
2569
+ });
2570
+ }
2571
+ });
2572
+ });
2573
+ var currentTypeResourcesCapacity = allRenderList.reduce(function (acc, curr) {
2574
+ return acc + curr.capacity || 0;
2575
+ }, 0);
2576
+ // 计算当前时间段内所有资源的已使用容量
2577
+ var usedCapacity = allRenderList.reduce(function (acc, curr) {
2578
+ var mTimes = curr.times.filter(function (n) {
2498
2579
  return !dayjs(n.start_at).isAfter(dayjs(item.start), 'minute') && !dayjs(n.end_at).isBefore(dayjs(item.end), 'minute') || dayjs(n.start_at).isBefore(dayjs(item.end), 'minute') && dayjs(n.end_at).isAfter(dayjs(item.start), 'minute');
2499
2580
  });
2500
- if (mTimes.length === 0) return;
2501
- var isResourceAvailable = false;
2502
- mTimes.forEach(function (childTime) {
2503
- var res = getIsUsableByTimeItem({
2504
- timeSlice: {
2505
- start_time: item.start,
2506
- end_time: item.end,
2507
- start_at: dayjs(item.start),
2508
- end_at: dayjs(item.end)
2509
- },
2510
- time: childTime,
2511
- resource: resource,
2512
- currentCount: 1,
2513
- resourcesUseableMap: resourcesUseableMap,
2514
- cut_off_time: targetProductData === null || targetProductData === void 0 ? void 0 : targetProductData.cut_off_time
2581
+ // 这里为什么要设置个 map,因为有可能日程有重叠,所以要把重叠的 event_list 去除
2582
+ var mSet = new Map();
2583
+ mTimes.forEach(function (n) {
2584
+ // acc += n.event_list?.reduce((acc: any, curr: any) => acc + curr.pax, 0);
2585
+ // mSet.set(n)
2586
+ n.event_list.forEach(function (m) {
2587
+ mSet.set(m.id, m.pax || 1);
2515
2588
  });
2516
- if ((resourcesUseableMap === null || resourcesUseableMap === void 0 ? void 0 : resourcesUseableMap[resource.id]) !== false && res.reason !== 'capacityOnly') {
2517
- resourcesUseableMap[resource.id] = res.usable;
2518
- }
2519
- if (res.usable && !resource.onlyComputed) {
2520
- isResourceAvailable = true;
2521
- }
2522
2589
  });
2523
- if (isResourceAvailable) {
2524
- _availableResourceCount++;
2525
- }
2526
- });
2527
-
2528
- // 减去购物车中需要占用的资源个数
2529
- var netAvailableResources = Math.max(0, _availableResourceCount - cartUsageForThisType);
2530
- if (netAvailableResources < minAvailableCount) {
2531
- minAvailableCount = netAvailableResources;
2532
- }
2533
- if (netAvailableResources > 0) {
2534
- hasAnyAvailableResource = true;
2590
+ acc += Array.from(mSet.values()).reduce(function (acc, curr) {
2591
+ return acc + curr;
2592
+ }, 0);
2593
+ return acc;
2594
+ }, 0);
2595
+ // 如果已使用容量超过了当前类型资源的容量,则不可用
2596
+ if (sameCartNeedCapacity + otherCartNeedCapacity + usedCapacity >= currentTypeResourcesCapacity) {
2597
+ bookingLeft = 0;
2598
+ count = 0;
2535
2599
  }
2536
- totalBookingLeft += netAvailableResources;
2537
2600
  }
2538
2601
  });
2539
2602
  var startDayJs = dayjs(item.start);
2540
2603
  var endDayJs = dayjs(item.end);
2541
-
2542
- // 最终的可用容量是所有资源类型中最小的那个
2543
- var finalCount = hasAnyAvailableResource ? minAvailableCount === Number.MAX_SAFE_INTEGER ? 0 : minAvailableCount : 0;
2544
2604
  return {
2545
2605
  start_time: startDayJs.format('HH:mm'),
2546
2606
  end_time: endDayJs.format('HH:mm'),
2547
2607
  start_at: startDayJs,
2548
2608
  end_at: endDayJs,
2549
- count: finalCount,
2550
- left: Math.max(0, totalBookingLeft)
2609
+ count: count,
2610
+ left: bookingLeft
2551
2611
  };
2552
2612
  });
2553
2613
  return formatScheduleTimeSlots;
@@ -2639,7 +2699,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2639
2699
  }, {
2640
2700
  key: "checkMaxDurationCapacity",
2641
2701
  value: function checkMaxDurationCapacity() {
2642
- var _this14 = this;
2702
+ var _this15 = this;
2643
2703
  var cartItems = cloneDeep(this.store.cart.getItems());
2644
2704
  if (cartItems.length === 0) return {
2645
2705
  success: true,
@@ -2746,9 +2806,9 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2746
2806
  items.forEach(function (cartItem) {
2747
2807
  var productResourceIds = getResourcesIdsByProduct(cartItem._productOrigin);
2748
2808
  productResourceIds.forEach(function (resourceId) {
2749
- var _resource$form_id2;
2809
+ var _resource$form_id;
2750
2810
  var resource = resourcesMap[resourceId];
2751
- if (resource && ((_resource$form_id2 = resource.form_id) === null || _resource$form_id2 === void 0 ? void 0 : _resource$form_id2.toString()) === targetFormId) {
2811
+ if (resource && ((_resource$form_id = resource.form_id) === null || _resource$form_id === void 0 ? void 0 : _resource$form_id.toString()) === targetFormId) {
2752
2812
  // 避免重复添加同一个资源
2753
2813
  if (!resourcesOfThisType.find(function (r) {
2754
2814
  return r.id === resource.id;
@@ -2840,7 +2900,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2840
2900
  }));
2841
2901
 
2842
2902
  // 找到所有资源都可用的时间段
2843
- var commonTimeSlots = _this14.findCommonAvailableTimeSlots(resourcesOfThisType);
2903
+ var commonTimeSlots = _this15.findCommonAvailableTimeSlots(resourcesOfThisType);
2844
2904
  console.log("\u8D44\u6E90\u7C7B\u578B ".concat(resourceCode, " \u7684\u516C\u5171\u65F6\u95F4\u6BB5:"), commonTimeSlots);
2845
2905
  if (commonTimeSlots.length === 0) {
2846
2906
  console.log("\u8D44\u6E90\u7C7B\u578B ".concat(resourceCode, " \u6CA1\u6709\u516C\u5171\u53EF\u7528\u65F6\u95F4\u6BB5"));
@@ -2930,8 +2990,8 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2930
2990
  var resourcesIdSet = new Set();
2931
2991
 
2932
2992
  // 获取资源数据
2933
- var dateRange = _this14.store.date.getDateRange();
2934
- var resourcesDates = _this14.store.date.getDateList();
2993
+ var dateRange = _this15.store.date.getDateRange();
2994
+ var resourcesDates = _this15.store.date.getDateList();
2935
2995
  var targetResourceDate = resourcesDates.find(function (n) {
2936
2996
  return n.date === startDate;
2937
2997
  });
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  };
327
327
  setOtherData(key: string, value: any): void;
328
328
  getOtherData(key: string): any;
329
- getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
329
+ getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
330
330
  /**
331
331
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
332
332
  *
@@ -1691,126 +1691,149 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1691
1691
  )) == null ? void 0 : _e.id;
1692
1692
  const formatScheduleTimeSlots = scheduleTimeSlots.map((item) => {
1693
1693
  const resourcesUseableMap = {};
1694
- const resourceTypeMap = {};
1695
- allProductResources == null ? void 0 : allProductResources.forEach((resource) => {
1696
- var _a2;
1697
- const formId = ((_a2 = resource.form_id) == null ? void 0 : _a2.toString()) || "default";
1698
- if (!resourceTypeMap[formId]) {
1699
- resourceTypeMap[formId] = [];
1694
+ let count = 0;
1695
+ let bookingLeft = 0;
1696
+ allProductResources == null ? void 0 : allProductResources.forEach((m) => {
1697
+ let currentResourcesCount = 0;
1698
+ const currentResourcesTimeSlotCanUsedArr = [];
1699
+ const mTimes = m.times.filter((n) => {
1700
+ return !(0, import_dayjs.default)(n.start_at).isAfter((0, import_dayjs.default)(item.start), "minute") && !(0, import_dayjs.default)(n.end_at).isBefore((0, import_dayjs.default)(item.end), "minute") || (0, import_dayjs.default)(n.start_at).isBefore((0, import_dayjs.default)(item.end), "minute") && (0, import_dayjs.default)(n.end_at).isAfter((0, import_dayjs.default)(item.start), "minute");
1701
+ });
1702
+ if (mTimes.length === 0) {
1703
+ return;
1704
+ }
1705
+ mTimes.forEach((childTiem) => {
1706
+ const res = (0, import_resources.getIsUsableByTimeItem)({
1707
+ timeSlice: {
1708
+ start_time: item.start,
1709
+ end_time: item.end,
1710
+ start_at: (0, import_dayjs.default)(item.start),
1711
+ end_at: (0, import_dayjs.default)(item.end)
1712
+ },
1713
+ time: childTiem,
1714
+ resource: m,
1715
+ currentCount: 1,
1716
+ resourcesUseableMap,
1717
+ cut_off_time: targetProductData == null ? void 0 : targetProductData.cut_off_time
1718
+ });
1719
+ if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[m.id]) !== false && res.reason !== "capacityOnly") {
1720
+ resourcesUseableMap[m.id] = res.usable;
1721
+ }
1722
+ if (res.usable && res.remainingCapacity >= count && !m.onlyComputed) {
1723
+ currentResourcesCount = res.remainingCapacity;
1724
+ }
1725
+ currentResourcesTimeSlotCanUsedArr.push(res.usable);
1726
+ });
1727
+ if (!currentResourcesTimeSlotCanUsedArr.some(
1728
+ (n) => n === false
1729
+ ) && // 只统计第一种资源的容量和 left
1730
+ m.form_id === firstEnabledResourceId) {
1731
+ if (currentResourcesCount >= count) {
1732
+ count = currentResourcesCount;
1733
+ }
1734
+ if (!m.onlyComputed) {
1735
+ bookingLeft += 1;
1736
+ }
1700
1737
  }
1701
- resourceTypeMap[formId].push(resource);
1702
- });
1703
- const cartCapacityUsage = (0, import_capacity.calculateCartItemsCapacityUsageByResourceType)({
1704
- cartItems,
1705
- timeSlotStart: item.start,
1706
- timeSlotEnd: item.end,
1707
- allProductResources: allProductResources || []
1708
1738
  });
1709
- let minAvailableCount = Number.MAX_SAFE_INTEGER;
1710
- let totalBookingLeft = 0;
1711
- let hasAnyAvailableResource = false;
1712
- Object.keys(resourceTypeMap).forEach((formId) => {
1713
- const resourcesInType = resourceTypeMap[formId];
1714
- if (resourcesInType.length === 0)
1715
- return;
1716
- const firstResource = resourcesInType[0];
1717
- const isMultipleBooking = firstResource.resourceType === "multiple";
1718
- const cartUsageForThisType = cartCapacityUsage[formId] || 0;
1719
- if (isMultipleBooking) {
1720
- let totalAvailableCapacity = 0;
1721
- let availableResourceCount = 0;
1722
- resourcesInType.forEach((resource) => {
1723
- const mTimes = resource.times.filter((n) => {
1724
- return !(0, import_dayjs.default)(n.start_at).isAfter((0, import_dayjs.default)(item.start), "minute") && !(0, import_dayjs.default)(n.end_at).isBefore((0, import_dayjs.default)(item.end), "minute") || (0, import_dayjs.default)(n.start_at).isBefore((0, import_dayjs.default)(item.end), "minute") && (0, import_dayjs.default)(n.end_at).isAfter((0, import_dayjs.default)(item.start), "minute");
1725
- });
1726
- if (mTimes.length === 0)
1727
- return;
1728
- let resourceAvailableCapacity = 0;
1729
- mTimes.forEach((childTime) => {
1730
- const res = (0, import_resources.getIsUsableByTimeItem)({
1731
- timeSlice: {
1732
- start_time: item.start,
1733
- end_time: item.end,
1734
- start_at: (0, import_dayjs.default)(item.start),
1735
- end_at: (0, import_dayjs.default)(item.end)
1736
- },
1737
- time: childTime,
1738
- resource,
1739
- currentCount: 1,
1740
- resourcesUseableMap,
1741
- cut_off_time: targetProductData == null ? void 0 : targetProductData.cut_off_time
1739
+ const cartItems2 = this.store.cart.getItems();
1740
+ productResources.forEach((n) => {
1741
+ if (n.type === "single") {
1742
+ const currentResourcesSet = /* @__PURE__ */ new Set([...n.optional_resource, ...n.default_resource]);
1743
+ const sameCartItems = cartItems2.filter((m) => {
1744
+ var _a2, _b2, _c2;
1745
+ return ((_b2 = (_a2 = m._productOrigin) == null ? void 0 : _a2.id) == null ? void 0 : _b2.toString()) === ((_c2 = targetProductData == null ? void 0 : targetProductData.id) == null ? void 0 : _c2.toString()) && `${m.start_date} ${m.start_time}` === item.start && `${m.start_date} ${m.end_time}` === item.end;
1746
+ });
1747
+ if (sameCartItems.length > 0 && sameCartItems.length >= currentResourcesSet.size || sameCartItems.length > bookingLeft) {
1748
+ bookingLeft = 0;
1749
+ count = 0;
1750
+ }
1751
+ const otherCartItems = cartItems2.filter((m) => {
1752
+ var _a2, _b2, _c2;
1753
+ return ((_b2 = (_a2 = m._productOrigin) == null ? void 0 : _a2.id) == null ? void 0 : _b2.toString()) !== ((_c2 = targetProductData == null ? void 0 : targetProductData.id) == null ? void 0 : _c2.toString()) && `${m.start_date} ${m.start_time}` === item.start && `${m.start_date} ${m.end_time}` === item.end;
1754
+ });
1755
+ otherCartItems.forEach((m) => {
1756
+ var _a2, _b2, _c2;
1757
+ const sameTypeResources = (_c2 = (_b2 = (_a2 = m._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) == null ? void 0 : _c2.find((m2) => m2.type === n.type);
1758
+ const sameTypeResourcesSet = /* @__PURE__ */ new Set([...(sameTypeResources == null ? void 0 : sameTypeResources.optional_resource) || [], ...(sameTypeResources == null ? void 0 : sameTypeResources.default_resource) || []]);
1759
+ sameTypeResourcesSet.forEach((resource) => currentResourcesSet.add(resource));
1760
+ });
1761
+ const currentDataResources = this.store.date.getResourcesListByDate((0, import_dayjs.default)(item.start).format("YYYY-MM-DD"));
1762
+ currentDataResources == null ? void 0 : currentDataResources.forEach((m) => {
1763
+ if (currentResourcesSet.has(m.id)) {
1764
+ const mTimes = m.times.filter((n2) => {
1765
+ return !(0, import_dayjs.default)(n2.start_at).isAfter((0, import_dayjs.default)(item.start), "minute") && !(0, import_dayjs.default)(n2.end_at).isBefore((0, import_dayjs.default)(item.end), "minute") || (0, import_dayjs.default)(n2.start_at).isBefore((0, import_dayjs.default)(item.end), "minute") && (0, import_dayjs.default)(n2.end_at).isAfter((0, import_dayjs.default)(item.start), "minute");
1742
1766
  });
1743
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[resource.id]) !== false && res.reason !== "capacityOnly") {
1744
- resourcesUseableMap[resource.id] = res.usable;
1767
+ if (!mTimes.length || mTimes.some((n2) => n2.event_list.length)) {
1768
+ currentResourcesSet.delete(m.id);
1745
1769
  }
1746
- if (res.usable && !resource.onlyComputed) {
1747
- resourceAvailableCapacity = Math.max(resourceAvailableCapacity, res.remainingCapacity);
1748
- availableResourceCount++;
1749
- }
1750
- });
1751
- totalAvailableCapacity += resourceAvailableCapacity;
1770
+ }
1752
1771
  });
1753
- const netAvailableCapacity = Math.max(0, totalAvailableCapacity - cartUsageForThisType);
1754
- if (netAvailableCapacity < minAvailableCount) {
1755
- minAvailableCount = netAvailableCapacity;
1756
- }
1757
- if (netAvailableCapacity > 0) {
1758
- hasAnyAvailableResource = true;
1772
+ if (currentResourcesSet.size > 0 && otherCartItems.length + sameCartItems.length >= currentResourcesSet.size) {
1773
+ bookingLeft = 0;
1774
+ count = 0;
1759
1775
  }
1760
1776
  } else {
1761
- let availableResourceCount = 0;
1762
- resourcesInType.forEach((resource) => {
1763
- const mTimes = resource.times.filter((n) => {
1764
- return !(0, import_dayjs.default)(n.start_at).isAfter((0, import_dayjs.default)(item.start), "minute") && !(0, import_dayjs.default)(n.end_at).isBefore((0, import_dayjs.default)(item.end), "minute") || (0, import_dayjs.default)(n.start_at).isBefore((0, import_dayjs.default)(item.end), "minute") && (0, import_dayjs.default)(n.end_at).isAfter((0, import_dayjs.default)(item.start), "minute");
1765
- });
1766
- if (mTimes.length === 0)
1767
- return;
1768
- let isResourceAvailable = false;
1769
- mTimes.forEach((childTime) => {
1770
- const res = (0, import_resources.getIsUsableByTimeItem)({
1771
- timeSlice: {
1772
- start_time: item.start,
1773
- end_time: item.end,
1774
- start_at: (0, import_dayjs.default)(item.start),
1775
- end_at: (0, import_dayjs.default)(item.end)
1776
- },
1777
- time: childTime,
1778
- resource,
1779
- currentCount: 1,
1780
- resourcesUseableMap,
1781
- cut_off_time: targetProductData == null ? void 0 : targetProductData.cut_off_time
1782
- });
1783
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[resource.id]) !== false && res.reason !== "capacityOnly") {
1784
- resourcesUseableMap[resource.id] = res.usable;
1785
- }
1786
- if (res.usable && !resource.onlyComputed) {
1787
- isResourceAvailable = true;
1777
+ const sameCartItems = cartItems2.filter((m) => {
1778
+ var _a2, _b2, _c2;
1779
+ return ((_b2 = (_a2 = m._productOrigin) == null ? void 0 : _a2.id) == null ? void 0 : _b2.toString()) === ((_c2 = targetProductData == null ? void 0 : targetProductData.id) == null ? void 0 : _c2.toString()) && `${m.start_date} ${m.start_time}` === item.start && `${m.start_date} ${m.end_time}` === item.end;
1780
+ });
1781
+ const sameCartNeedCapacity = sameCartItems.reduce((acc, curr) => acc + (0, import_capacity.getCapacityInfoByCartItem)(curr).currentCapacity, 0);
1782
+ const currentProductResourcesCapacity = n.renderList.reduce((acc, curr) => !curr.onlyComputed ? acc + curr.capacity || 0 : acc, 0);
1783
+ if (sameCartNeedCapacity >= currentProductResourcesCapacity) {
1784
+ bookingLeft = 0;
1785
+ count = 0;
1786
+ }
1787
+ const otherSameTimesCartItems = cartItems2.filter((m) => `${m.start_date} ${m.start_time}` === item.start && `${m.start_date} ${m.end_time}` === item.end);
1788
+ const otherCartNeedCapacity = otherSameTimesCartItems.reduce((acc, curr) => acc + (0, import_capacity.getCapacityInfoByCartItem)(curr).currentCapacity, 0);
1789
+ const allRenderList = [...n.renderList.filter((m) => !m.onlyComputed)];
1790
+ otherSameTimesCartItems.forEach((m) => {
1791
+ var _a2, _b2;
1792
+ const productResources2 = (0, import_resources.getResourcesByProduct)(
1793
+ (0, import_utils.getResourcesMap)((targetResourceDate == null ? void 0 : targetResourceDate.resource) || []),
1794
+ ((_b2 = (_a2 = m._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) || [],
1795
+ selectedResources,
1796
+ 1
1797
+ );
1798
+ productResources2.forEach((m2) => {
1799
+ if (m2.id === n.id) {
1800
+ m2.renderList.forEach((n2) => {
1801
+ if (!n2.onlyComputed && !allRenderList.find((m3) => m3.id === n2.id)) {
1802
+ allRenderList.push(n2);
1803
+ }
1804
+ });
1788
1805
  }
1789
1806
  });
1790
- if (isResourceAvailable) {
1791
- availableResourceCount++;
1792
- }
1793
1807
  });
1794
- const netAvailableResources = Math.max(0, availableResourceCount - cartUsageForThisType);
1795
- if (netAvailableResources < minAvailableCount) {
1796
- minAvailableCount = netAvailableResources;
1797
- }
1798
- if (netAvailableResources > 0) {
1799
- hasAnyAvailableResource = true;
1808
+ const currentTypeResourcesCapacity = allRenderList.reduce((acc, curr) => acc + curr.capacity || 0, 0);
1809
+ const usedCapacity = allRenderList.reduce((acc, curr) => {
1810
+ const mTimes = curr.times.filter((n2) => {
1811
+ return !(0, import_dayjs.default)(n2.start_at).isAfter((0, import_dayjs.default)(item.start), "minute") && !(0, import_dayjs.default)(n2.end_at).isBefore((0, import_dayjs.default)(item.end), "minute") || (0, import_dayjs.default)(n2.start_at).isBefore((0, import_dayjs.default)(item.end), "minute") && (0, import_dayjs.default)(n2.end_at).isAfter((0, import_dayjs.default)(item.start), "minute");
1812
+ });
1813
+ const mSet = /* @__PURE__ */ new Map();
1814
+ mTimes.forEach((n2) => {
1815
+ n2.event_list.forEach((m) => {
1816
+ mSet.set(m.id, m.pax || 1);
1817
+ });
1818
+ });
1819
+ acc += Array.from(mSet.values()).reduce((acc2, curr2) => acc2 + curr2, 0);
1820
+ return acc;
1821
+ }, 0);
1822
+ if (sameCartNeedCapacity + otherCartNeedCapacity + usedCapacity >= currentTypeResourcesCapacity) {
1823
+ bookingLeft = 0;
1824
+ count = 0;
1800
1825
  }
1801
- totalBookingLeft += netAvailableResources;
1802
1826
  }
1803
1827
  });
1804
1828
  const startDayJs = (0, import_dayjs.default)(item.start);
1805
1829
  const endDayJs = (0, import_dayjs.default)(item.end);
1806
- const finalCount = hasAnyAvailableResource ? minAvailableCount === Number.MAX_SAFE_INTEGER ? 0 : minAvailableCount : 0;
1807
1830
  return {
1808
1831
  start_time: startDayJs.format("HH:mm"),
1809
1832
  end_time: endDayJs.format("HH:mm"),
1810
1833
  start_at: startDayJs,
1811
1834
  end_at: endDayJs,
1812
- count: finalCount,
1813
- left: Math.max(0, totalBookingLeft)
1835
+ count,
1836
+ left: bookingLeft
1814
1837
  };
1815
1838
  });
1816
1839
  return formatScheduleTimeSlots;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.275",
4
+ "version": "0.0.277",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",