@pisell/pisellos 2.1.68 → 2.1.72

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.
@@ -320,7 +320,7 @@ export function checkTimeSlotCapacity(timeSlotStart, timeSlotEnd, cartItems, all
320
320
  resourcesInType.forEach(function (resource) {
321
321
  // 过滤出在时间段内的资源时间片
322
322
  var availableTimes = resource.times.filter(function (time) {
323
- return !dayjs(time.start_at).isAfter(dayjs(timeSlotStart), 'minute') && !dayjs(time.end_at).isBefore(dayjs(timeSlotEnd), 'minute') || dayjs(time.start_at).isBefore(dayjs(timeSlotEnd), 'minute') && dayjs(time.end_at).isAfter(dayjs(timeSlotStart), 'minute');
323
+ return !dayjs(time.start_at).isAfter(dayjs(timeSlotStart), 'minute') && !dayjs(time.end_at).isBefore(dayjs(timeSlotEnd), 'minute') || resource.onlyComputed && dayjs(time.start_at).isBefore(dayjs(timeSlotEnd), 'minute') && dayjs(time.end_at).isAfter(dayjs(timeSlotStart), 'minute');
324
324
  });
325
325
  if (availableTimes.length > 0) {
326
326
  // 简化逻辑:如果资源在时间段内有可用时间,就计算其容量
@@ -444,6 +444,10 @@ export var getTimeSlicesByResource = function getTimeSlicesByResource(_ref5) {
444
444
  // 解析开始和结束时间
445
445
  var startTime = dayjs("".concat(time.start_at));
446
446
  var endTime = dayjs("".concat(time.end_at));
447
+ // 结束时间要做修复,如果time.end_at 是超过了 currentDate 的那一天,则把 end_at 设置为 currentDate 那一天的 23:59:59
448
+ if (endTime.isAfter(dayjs(currentDate).endOf('day'))) {
449
+ endTime = dayjs(currentDate).endOf('day');
450
+ }
447
451
 
448
452
  // 当前切片的开始时间
449
453
  var currentStart = startTime;
@@ -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, "skip" | "num">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
@@ -20,7 +20,9 @@ export interface ITime {
20
20
  date: string;
21
21
  week: string;
22
22
  weekNum: number;
23
- status: 'unavailable' | 'available';
23
+ status: 'unavailable' | 'available' | 'lots_of_space' | 'filling_up_fast' | 'sold_out';
24
+ summaryCount?: number;
25
+ availableCount?: number;
24
26
  resource?: any[];
25
27
  color?: string[];
26
28
  }
@@ -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
  }
@@ -96,11 +96,13 @@ var RulesModule = class extends import_BaseModule.BaseModule {
96
96
  productList
97
97
  };
98
98
  }
99
- const filteredOldDiscountList = oldDiscountList.filter((discount) => !discount.isEditMode && discount.tag !== "good_pass");
100
- const mergedDiscountList = (0, import_utils.uniqueById)((0, import_utils.uniqueById)([
99
+ const filteredOldDiscountList = oldDiscountList.filter(
100
+ (discount) => !discount.isEditMode && (discount.tag !== "good_pass" || discount.isScan)
101
+ );
102
+ const mergedDiscountList = (0, import_utils.uniqueById)([
101
103
  ...filteredOldDiscountList,
102
104
  ...newDiscountList
103
- ]), "product_id");
105
+ ]);
104
106
  const result = this.calcDiscount({
105
107
  discountList: mergedDiscountList,
106
108
  productList: [...productList],
@@ -299,6 +299,16 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
299
299
  errorList: any[];
300
300
  };
301
301
  getTimeSlotByAllResources(resources_code: string): any[];
302
+ getTimeSlotByAllResourcesForDate({ resources_code, startDate, endDate }: {
303
+ resources_code: string;
304
+ startDate: string;
305
+ endDate: string;
306
+ }): Promise<{
307
+ date: string;
308
+ status: string;
309
+ week: string;
310
+ weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
311
+ }[]>;
302
312
  submitTimeSlot(timeSlots: TimeSliceItem): void;
303
313
  private getScheduleDataByIds;
304
314
  openProductDetail(productId: number): Promise<void>;
@@ -316,6 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
316
326
  count: number;
317
327
  left: number;
318
328
  summaryCount: number;
329
+ status: keyof TimeStatusMap;
319
330
  }[];
320
331
  /**
321
332
  * 找到多个资源的公共可用时间段
@@ -343,7 +354,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
343
354
  };
344
355
  setOtherData(key: string, value: any): void;
345
356
  getOtherData(key: string): any;
346
- getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
357
+ getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
347
358
  /**
348
359
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
349
360
  *
@@ -380,3 +391,9 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
380
391
  */
381
392
  getContactInfo(params: any): Promise<any>;
382
393
  }
394
+ interface TimeStatusMap {
395
+ lots_of_space: true;
396
+ filling_up_fast: true;
397
+ sold_out: true;
398
+ }
399
+ export {};
@@ -1405,7 +1405,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1405
1405
  }
1406
1406
  // 从购物车中获取已经分配好第一步资源的所有时间片
1407
1407
  getTimeSlotByAllResources(resources_code) {
1408
- var _a, _b, _c, _d, _e, _f, _g, _h;
1408
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1409
1409
  let dateRange = this.store.date.getDateRange();
1410
1410
  const resources = [];
1411
1411
  const cartItems = this.store.cart.getItems().filter((n) => !(0, import_utils5.isNormalProduct)(n._productOrigin));
@@ -1415,7 +1415,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1415
1415
  let maxCutOffTime = void 0;
1416
1416
  let maxCutOffTimeValue = (0, import_dayjs.default)();
1417
1417
  cartItems.forEach((item) => {
1418
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i;
1418
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
1419
1419
  (_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) == null ? void 0 : _c2.forEach((n) => {
1420
1420
  if (n.code === resources_code) {
1421
1421
  resources.push(...n.renderList || []);
@@ -1428,7 +1428,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1428
1428
  resourcesTypeId = (_g2 = (_f2 = (_e2 = (_d2 = item == null ? void 0 : item._productOrigin) == null ? void 0 : _d2.product_resource) == null ? void 0 : _e2.resources) == null ? void 0 : _f2.find(
1429
1429
  (n) => n.code === resources_code
1430
1430
  )) == null ? void 0 : _g2.id;
1431
- if (((_h2 = item._productOrigin) == null ? void 0 : _h2.cut_off_time) && ((_i = item._productOrigin) == null ? void 0 : _i.cut_off_time.type) === "advance") {
1431
+ if (((_h2 = item._productOrigin) == null ? void 0 : _h2.cut_off_time) && ((_i2 = item._productOrigin) == null ? void 0 : _i2.cut_off_time.type) === "advance") {
1432
1432
  const currentCutOffTime = (0, import_dayjs.default)().add(
1433
1433
  item._productOrigin.cut_off_time.unit,
1434
1434
  item._productOrigin.cut_off_time.unit_type
@@ -1446,6 +1446,19 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1446
1446
  }
1447
1447
  });
1448
1448
  }
1449
+ if (((_c = dateRange == null ? void 0 : dateRange[0]) == null ? void 0 : _c.date) && resources.length) {
1450
+ const currentDate = (_d = dateRange == null ? void 0 : dateRange[0]) == null ? void 0 : _d.date;
1451
+ const theDateResources = this.store.date.getResourcesListByDate(currentDate);
1452
+ resources.forEach((item) => {
1453
+ var _a2;
1454
+ const noCurrentDateTimes = item.times.some((n) => {
1455
+ return (0, import_dayjs.default)(n.start_at).isSame((0, import_dayjs.default)(currentDate), "day");
1456
+ });
1457
+ if (!noCurrentDateTimes) {
1458
+ item.times = ((_a2 = theDateResources == null ? void 0 : theDateResources.find((n) => n.id === item.id)) == null ? void 0 : _a2.times) || [];
1459
+ }
1460
+ });
1461
+ }
1449
1462
  const resourcesMap = (0, import_utils2.getResourcesMap)(resources);
1450
1463
  let duration = 0;
1451
1464
  const accountList = this.store.accountList.getAccounts();
@@ -1473,7 +1486,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1473
1486
  } else {
1474
1487
  checkDuration(cartItems);
1475
1488
  }
1476
- if (!((_c = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _c.start_date) && !((_d = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _d.resource_id) || !(cartItems == null ? void 0 : cartItems[0].duration)) {
1489
+ if (!((_e = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _e.start_date) && !((_f = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _f.resource_id) || !(cartItems == null ? void 0 : cartItems[0].duration)) {
1477
1490
  return [];
1478
1491
  }
1479
1492
  if ((cartItems == null ? void 0 : cartItems[0].start_date) && !dateRange) {
@@ -1485,7 +1498,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1485
1498
  weekNum: 0
1486
1499
  },
1487
1500
  {
1488
- date: ((_e = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _e.end_date) || ((_f = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _f.start_date) || "",
1501
+ date: ((_g = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _g.end_date) || ((_h = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _h.start_date) || "",
1489
1502
  status: "available",
1490
1503
  week: "",
1491
1504
  weekNum: 0
@@ -1499,18 +1512,30 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1499
1512
  return ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.type) === "flexible";
1500
1513
  }
1501
1514
  );
1502
- let operating_day_boundary = (_h = (_g = this.shopStore.get("core")) == null ? void 0 : _g.core) == null ? void 0 : _h.operating_day_boundary;
1515
+ let operating_day_boundary = (_j = (_i = this.shopStore.get("core")) == null ? void 0 : _i.core) == null ? void 0 : _j.operating_day_boundary;
1503
1516
  let maxBlockThreshold = 0;
1504
1517
  if (hasFlexibleDuration) {
1505
1518
  maxBlockThreshold = cartItems.reduce((max, item) => {
1506
1519
  var _a2, _b2, _c2, _d2, _e2, _f2;
1507
1520
  if ((_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.flexible_config) == null ? void 0 : _c2.is_enable_minimum_duration) {
1508
- return Math.max(max, ((_f2 = (_e2 = (_d2 = item._productOrigin) == null ? void 0 : _d2.duration) == null ? void 0 : _e2.flexible_config) == null ? void 0 : _f2.block_threshold) || 0);
1521
+ return Math.max(
1522
+ max,
1523
+ ((_f2 = (_e2 = (_d2 = item._productOrigin) == null ? void 0 : _d2.duration) == null ? void 0 : _e2.flexible_config) == null ? void 0 : _f2.block_threshold) || 0
1524
+ );
1509
1525
  }
1510
1526
  return 0;
1511
1527
  }, 0);
1512
1528
  }
1513
1529
  const calculateCapacityFromCartItems = (items) => {
1530
+ var _a2;
1531
+ const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1532
+ const sameResourceLength = items.filter((item) => {
1533
+ var _a3;
1534
+ return ((_a3 = item._resourceOrigin) == null ? void 0 : _a3[0].id) === firstResource;
1535
+ }).length;
1536
+ if (sameResourceLength !== items.length) {
1537
+ return 1;
1538
+ }
1514
1539
  return items.reduce((total, item) => {
1515
1540
  return total + ((0, import_capacity.getCapacityInfoByCartItem)(item).currentCapacity || 0);
1516
1541
  }, 0);
@@ -1518,7 +1543,9 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1518
1543
  let maxCapacity = 1;
1519
1544
  if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1520
1545
  accountList.forEach((account) => {
1521
- const accountCartItems = this.store.cart.getCartByAccount(account.getId());
1546
+ const accountCartItems = this.store.cart.getCartByAccount(
1547
+ account.getId()
1548
+ );
1522
1549
  const currentCapacity = calculateCapacityFromCartItems(accountCartItems);
1523
1550
  if (currentCapacity > maxCapacity) {
1524
1551
  maxCapacity = currentCapacity;
@@ -1542,6 +1569,174 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1542
1569
  });
1543
1570
  return timeSlots;
1544
1571
  }
1572
+ // 从购物车中获取已经分配好第一步资源的所有时间片,批量版本,用于给日期提供能否高亮的判断
1573
+ async getTimeSlotByAllResourcesForDate({ resources_code, startDate, endDate }) {
1574
+ var _a, _b, _c, _d;
1575
+ if ((0, import_dayjs.default)(endDate).diff((0, import_dayjs.default)(startDate), "day") < 30) {
1576
+ endDate = (0, import_dayjs.default)(startDate).add(30, "day").format("YYYY-MM-DD");
1577
+ }
1578
+ await this.getAvailableDate({
1579
+ startDate,
1580
+ endDate,
1581
+ useCache: true
1582
+ });
1583
+ const resources = [];
1584
+ const cartItems = this.store.cart.getItems().filter((n) => !(0, import_utils5.isNormalProduct)(n._productOrigin));
1585
+ const resourceIds = [];
1586
+ let resourcesTypeId = void 0;
1587
+ let isSingleResource = false;
1588
+ let maxCutOffTime = void 0;
1589
+ let maxCutOffTimeValue = (0, import_dayjs.default)();
1590
+ cartItems.forEach((item) => {
1591
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i;
1592
+ (_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) == null ? void 0 : _c2.forEach((n) => {
1593
+ if (n.code === resources_code) {
1594
+ resources.push(...n.renderList || []);
1595
+ isSingleResource = n.type === "single";
1596
+ }
1597
+ });
1598
+ if (item.resource_id && !resourceIds.includes(item.resource_id)) {
1599
+ resourceIds.push(item.resource_id);
1600
+ }
1601
+ resourcesTypeId = (_g = (_f = (_e = (_d2 = item == null ? void 0 : item._productOrigin) == null ? void 0 : _d2.product_resource) == null ? void 0 : _e.resources) == null ? void 0 : _f.find(
1602
+ (n) => n.code === resources_code
1603
+ )) == null ? void 0 : _g.id;
1604
+ if (((_h = item._productOrigin) == null ? void 0 : _h.cut_off_time) && ((_i = item._productOrigin) == null ? void 0 : _i.cut_off_time.type) === "advance") {
1605
+ const currentCutOffTime = (0, import_dayjs.default)().add(
1606
+ item._productOrigin.cut_off_time.unit,
1607
+ item._productOrigin.cut_off_time.unit_type
1608
+ );
1609
+ if (currentCutOffTime.isAfter(maxCutOffTimeValue, "minute")) {
1610
+ maxCutOffTimeValue = currentCutOffTime;
1611
+ maxCutOffTime = item._productOrigin.cut_off_time;
1612
+ }
1613
+ }
1614
+ });
1615
+ if (!resources.length)
1616
+ return [];
1617
+ let duration = 0;
1618
+ const accountList = this.store.accountList.getAccounts();
1619
+ const checkDuration = (cartItems2) => {
1620
+ let accountDuration = 0;
1621
+ cartItems2.forEach((item) => {
1622
+ var _a2, _b2, _c2, _d2, _e, _f;
1623
+ if (isSingleResource) {
1624
+ accountDuration += ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.value) || 10;
1625
+ } else {
1626
+ if (accountDuration < (((_d2 = (_c2 = item._productOrigin) == null ? void 0 : _c2.duration) == null ? void 0 : _d2.value) || 10)) {
1627
+ accountDuration = ((_f = (_e = item._productOrigin) == null ? void 0 : _e.duration) == null ? void 0 : _f.value) || 10;
1628
+ }
1629
+ }
1630
+ });
1631
+ if (accountDuration > duration) {
1632
+ duration = accountDuration;
1633
+ }
1634
+ };
1635
+ if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1636
+ accountList.forEach((account) => {
1637
+ const cartItems2 = this.store.cart.getCartByAccount(account.getId());
1638
+ checkDuration(cartItems2);
1639
+ });
1640
+ } else {
1641
+ checkDuration(cartItems);
1642
+ }
1643
+ if (!((_a = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _a.start_date) && !((_b = cartItems == null ? void 0 : cartItems[0]) == null ? void 0 : _b.resource_id) || !(cartItems == null ? void 0 : cartItems[0].duration)) {
1644
+ return [];
1645
+ }
1646
+ const resourcesUseableMap = {};
1647
+ const hasFlexibleDuration = cartItems.some(
1648
+ (item) => {
1649
+ var _a2, _b2;
1650
+ return ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.type) === "flexible";
1651
+ }
1652
+ );
1653
+ let operating_day_boundary = (_d = (_c = this.shopStore.get("core")) == null ? void 0 : _c.core) == null ? void 0 : _d.operating_day_boundary;
1654
+ let maxBlockThreshold = 0;
1655
+ if (hasFlexibleDuration) {
1656
+ maxBlockThreshold = cartItems.reduce((max, item) => {
1657
+ var _a2, _b2, _c2, _d2, _e, _f;
1658
+ if ((_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.flexible_config) == null ? void 0 : _c2.is_enable_minimum_duration) {
1659
+ return Math.max(max, ((_f = (_e = (_d2 = item._productOrigin) == null ? void 0 : _d2.duration) == null ? void 0 : _e.flexible_config) == null ? void 0 : _f.block_threshold) || 0);
1660
+ }
1661
+ return 0;
1662
+ }, 0);
1663
+ }
1664
+ const calculateCapacityFromCartItems = (items) => {
1665
+ var _a2;
1666
+ const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1667
+ const sameResourceLength = items.filter((item) => {
1668
+ var _a3;
1669
+ return ((_a3 = item._resourceOrigin) == null ? void 0 : _a3[0].id) === firstResource;
1670
+ }).length;
1671
+ if (sameResourceLength !== items.length) {
1672
+ return 1;
1673
+ }
1674
+ return items.reduce((total, item) => {
1675
+ return total + ((0, import_capacity.getCapacityInfoByCartItem)(item).currentCapacity || 0);
1676
+ }, 0);
1677
+ };
1678
+ let maxCapacity = 1;
1679
+ if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1680
+ accountList.forEach((account) => {
1681
+ const accountCartItems = this.store.cart.getCartByAccount(account.getId());
1682
+ const currentCapacity = calculateCapacityFromCartItems(accountCartItems);
1683
+ if (currentCapacity > maxCapacity) {
1684
+ maxCapacity = currentCapacity;
1685
+ }
1686
+ });
1687
+ } else {
1688
+ maxCapacity = calculateCapacityFromCartItems(cartItems);
1689
+ }
1690
+ const arr = [];
1691
+ const today = (0, import_dayjs.default)().startOf("day");
1692
+ for (let i = (0, import_dayjs.default)(startDate); i.isBefore((0, import_dayjs.default)(endDate)); i = i.add(1, "day")) {
1693
+ const currentDate = i.format("YYYY-MM-DD");
1694
+ const theDateResources = this.store.date.getResourcesListByDate(currentDate);
1695
+ resources.forEach((item) => {
1696
+ var _a2;
1697
+ item.times = ((_a2 = theDateResources == null ? void 0 : theDateResources.find((n) => n.id === item.id)) == null ? void 0 : _a2.times) || [];
1698
+ });
1699
+ const resourcesMap = (0, import_utils2.getResourcesMap)(resources);
1700
+ if (i.isBefore(today)) {
1701
+ arr.push({
1702
+ date: currentDate,
1703
+ status: "unavailable",
1704
+ week: i.format("ddd"),
1705
+ weekNum: i.day()
1706
+ });
1707
+ continue;
1708
+ }
1709
+ const timeSlots = (0, import_resources.getTimeSlicesByResources)({
1710
+ resourceIds,
1711
+ resourcesMap,
1712
+ duration,
1713
+ currentDate,
1714
+ split: 10,
1715
+ resourcesUseableMap,
1716
+ capacity: maxCapacity,
1717
+ cut_off_time: maxCutOffTime,
1718
+ hasFlexibleDuration,
1719
+ operating_day_boundary,
1720
+ maxBlockThreshold
1721
+ });
1722
+ if (timeSlots.length > 0) {
1723
+ arr.push({
1724
+ date: currentDate,
1725
+ status: "available",
1726
+ week: i.format("ddd"),
1727
+ weekNum: i.day()
1728
+ });
1729
+ } else {
1730
+ arr.push({
1731
+ date: currentDate,
1732
+ status: "unavailable",
1733
+ week: i.format("ddd"),
1734
+ weekNum: i.day()
1735
+ });
1736
+ }
1737
+ }
1738
+ return arr;
1739
+ }
1545
1740
  // 提交时间切片,绑定到对应购物车的商品上,更新购物车---只有 duration 商品
1546
1741
  submitTimeSlot(timeSlots) {
1547
1742
  var _a, _b;
@@ -1685,7 +1880,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1685
1880
  resources,
1686
1881
  product
1687
1882
  }) {
1688
- var _a, _b, _c, _d, _e;
1883
+ var _a, _b, _c, _d, _e, _f, _g;
1689
1884
  const targetProduct = this.store.currentProduct;
1690
1885
  const targetProductData = product || targetProduct;
1691
1886
  let targetSchedules = [];
@@ -1731,17 +1926,22 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1731
1926
  const firstEnabledResourceId = (_e = (_d = (_c = targetProductData == null ? void 0 : targetProductData.product_resource) == null ? void 0 : _c.resources) == null ? void 0 : _d.find(
1732
1927
  (n) => n.status === 1
1733
1928
  )) == null ? void 0 : _e.id;
1929
+ const firstEnabledResourceConfig = (_g = (_f = targetProductData == null ? void 0 : targetProductData.product_resource) == null ? void 0 : _f.resources) == null ? void 0 : _g.find(
1930
+ (n) => n.status === 1 && n.id === firstEnabledResourceId
1931
+ );
1932
+ const isMultipleBooking = (firstEnabledResourceConfig == null ? void 0 : firstEnabledResourceConfig.type) === "multiple";
1734
1933
  const formatScheduleTimeSlots = scheduleTimeSlots.map((item) => {
1735
1934
  const resourcesUseableMap = {};
1736
1935
  let count = 0;
1737
1936
  let bookingLeft = 0;
1738
1937
  let summaryCount = 0;
1938
+ let summaryConfigCount = 0;
1739
1939
  allProductResources == null ? void 0 : allProductResources.forEach((m) => {
1740
1940
  let currentResourcesCount = 0;
1741
1941
  let currentResourcesSummaryCount = 0;
1742
1942
  const currentResourcesTimeSlotCanUsedArr = [];
1743
1943
  const mTimes = m.times.filter((n) => {
1744
- 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");
1944
+ 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") || m.onlyComputed && (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");
1745
1945
  });
1746
1946
  if (mTimes.length === 0) {
1747
1947
  return;
@@ -1771,6 +1971,13 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1771
1971
  }
1772
1972
  currentResourcesTimeSlotCanUsedArr.push(res.usable);
1773
1973
  });
1974
+ if (m.form_id === firstEnabledResourceId) {
1975
+ if (isMultipleBooking) {
1976
+ summaryConfigCount += m.capacity;
1977
+ } else {
1978
+ summaryConfigCount += 1;
1979
+ }
1980
+ }
1774
1981
  if (!currentResourcesTimeSlotCanUsedArr.some(
1775
1982
  (n) => n === false
1776
1983
  ) && // 只统计第一种资源的容量和 left
@@ -1797,13 +2004,17 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1797
2004
  count = 0;
1798
2005
  summaryCount = 0;
1799
2006
  }
1800
- const otherCartItems = cartItems2.filter((m) => {
1801
- var _a2, _b2, _c2;
1802
- 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;
1803
- });
2007
+ let otherCartItems = cartItems2.filter(
2008
+ (m) => {
2009
+ var _a2, _b2, _c2, _d2, _e2, _f2;
2010
+ const isTimeMatch = ((_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;
2011
+ const isResourceMatch = (_f2 = (_e2 = (_d2 = m._productOrigin) == null ? void 0 : _d2.product_resource) == null ? void 0 : _e2.resources) == null ? void 0 : _f2.find((m2) => m2.type === n.type && m2.status === 1);
2012
+ return isTimeMatch && isResourceMatch;
2013
+ }
2014
+ );
1804
2015
  otherCartItems.forEach((m) => {
1805
2016
  var _a2, _b2, _c2;
1806
- 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);
2017
+ 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 && m2.status === 1);
1807
2018
  const sameTypeResourcesSet = /* @__PURE__ */ new Set([...(sameTypeResources == null ? void 0 : sameTypeResources.optional_resource) || [], ...(sameTypeResources == null ? void 0 : sameTypeResources.default_resource) || []]);
1808
2019
  sameTypeResourcesSet.forEach((resource) => currentResourcesSet.add(resource));
1809
2020
  });
@@ -1884,6 +2095,34 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1884
2095
  });
1885
2096
  const startDayJs = (0, import_dayjs.default)(item.start);
1886
2097
  const endDayJs = (0, import_dayjs.default)(item.end);
2098
+ let timeStatus = "sold_out";
2099
+ if (bookingLeft === 0)
2100
+ timeStatus = "sold_out";
2101
+ else if (isMultipleBooking) {
2102
+ if (summaryConfigCount === 0)
2103
+ timeStatus = "sold_out";
2104
+ else {
2105
+ const usageRatio = summaryCount / summaryConfigCount;
2106
+ if (usageRatio > 0.5)
2107
+ timeStatus = "lots_of_space";
2108
+ else if (summaryCount > 0)
2109
+ timeStatus = "filling_up_fast";
2110
+ else
2111
+ timeStatus = "sold_out";
2112
+ }
2113
+ } else {
2114
+ if (summaryConfigCount === 0)
2115
+ timeStatus = "sold_out";
2116
+ else {
2117
+ const usageRatio = bookingLeft / summaryConfigCount;
2118
+ if (usageRatio > 0.5)
2119
+ timeStatus = "lots_of_space";
2120
+ else if (count > 0)
2121
+ timeStatus = "filling_up_fast";
2122
+ else
2123
+ timeStatus = "sold_out";
2124
+ }
2125
+ }
1887
2126
  return {
1888
2127
  start_time: startDayJs.format("HH:mm"),
1889
2128
  end_time: endDayJs.format("HH:mm"),
@@ -1891,7 +2130,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1891
2130
  end_at: endDayJs,
1892
2131
  count,
1893
2132
  left: bookingLeft,
1894
- summaryCount
2133
+ summaryCount,
2134
+ status: timeStatus
1895
2135
  };
1896
2136
  });
1897
2137
  return formatScheduleTimeSlots;
@@ -2662,6 +2902,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2662
2902
  while ((0, import_dayjs.default)(currentDate).isBefore((0, import_dayjs.default)(endDate), "day") || (0, import_dayjs.default)(currentDate).isSame((0, import_dayjs.default)(endDate), "day")) {
2663
2903
  const currentDateStr = currentDate.format("YYYY-MM-DD");
2664
2904
  let status = "available";
2905
+ let summaryCount = 0;
2906
+ let availableCount = 0;
2665
2907
  const { latestStartDate, earliestEndDate } = (0, import_resources.checkSessionProductLeadTime)(tempProducts);
2666
2908
  if (latestStartDate || earliestEndDate) {
2667
2909
  if (latestStartDate && (0, import_dayjs.default)(currentDate).isBefore(latestStartDate, "day")) {
@@ -2686,43 +2928,64 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2686
2928
  currentDateStr
2687
2929
  );
2688
2930
  const scheduleTimeSlots = (0, import_utils3.getAllSortedDateRanges)(minTimeMaxTime);
2689
- const timesSlotCanUse = scheduleTimeSlots.some((item) => {
2931
+ let timesSlotCanUse = false;
2932
+ scheduleTimeSlots.forEach((item) => {
2690
2933
  const resourcesUseableMap = {};
2691
- return openResources.every((resource) => {
2934
+ let isAllResourceTypesUseable = true;
2935
+ openResources.forEach((resource) => {
2692
2936
  const currentResourcesList = allProductResources.filter(
2693
2937
  (n) => n.form_id === resource.resource_type_id
2694
2938
  );
2695
- return currentResourcesList == null ? void 0 : currentResourcesList.some((m) => {
2939
+ let isAnyResourceUseableInType = false;
2940
+ currentResourcesList == null ? void 0 : currentResourcesList.forEach((m) => {
2696
2941
  const mTimes = m.times.filter((n) => {
2697
2942
  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");
2698
2943
  });
2699
- if (mTimes.length === 0) {
2944
+ if (mTimes.length === 0)
2700
2945
  return;
2946
+ if (resource.type === "multiple") {
2947
+ summaryCount += m.capacity;
2948
+ } else {
2949
+ summaryCount += 1;
2701
2950
  }
2702
- const targetCanUseTimes = mTimes.some(
2703
- (childTiem) => {
2704
- const res2 = (0, import_resources.getIsUsableByTimeItem)({
2705
- timeSlice: {
2706
- start_time: item.start,
2707
- end_time: item.end,
2708
- start_at: (0, import_dayjs.default)(item.start),
2709
- end_at: (0, import_dayjs.default)(item.end)
2710
- },
2711
- time: childTiem,
2712
- resource: m,
2713
- currentCount: 1,
2714
- resourcesUseableMap,
2715
- cut_off_time: tempProducts == null ? void 0 : tempProducts.cut_off_time
2716
- });
2717
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[m.id]) !== false && res2.reason !== "capacityOnly") {
2718
- resourcesUseableMap[m.id] = res2.usable;
2951
+ let isAnyTimeSliceUseable = false;
2952
+ mTimes.forEach((childTiem) => {
2953
+ if (isAnyTimeSliceUseable)
2954
+ return;
2955
+ const res2 = (0, import_resources.getIsUsableByTimeItem)({
2956
+ timeSlice: {
2957
+ start_time: item.start,
2958
+ end_time: item.end,
2959
+ start_at: (0, import_dayjs.default)(item.start),
2960
+ end_at: (0, import_dayjs.default)(item.end)
2961
+ },
2962
+ time: childTiem,
2963
+ resource: m,
2964
+ currentCount: 1,
2965
+ resourcesUseableMap,
2966
+ cut_off_time: tempProducts == null ? void 0 : tempProducts.cut_off_time
2967
+ });
2968
+ if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[m.id]) !== false && res2.reason !== "capacityOnly") {
2969
+ resourcesUseableMap[m.id] = res2.usable;
2970
+ }
2971
+ if (res2.usable && !m.onlyComputed) {
2972
+ isAnyTimeSliceUseable = true;
2973
+ if (resource.type === "multiple") {
2974
+ availableCount += res2.remainingCapacity;
2975
+ } else {
2976
+ availableCount += 1;
2719
2977
  }
2720
- return res2.usable && !m.onlyComputed;
2721
2978
  }
2722
- );
2723
- return targetCanUseTimes;
2979
+ ;
2980
+ });
2981
+ if (isAnyTimeSliceUseable)
2982
+ isAnyResourceUseableInType = true;
2724
2983
  });
2984
+ if (!isAnyResourceUseableInType)
2985
+ isAllResourceTypesUseable = false;
2725
2986
  });
2987
+ if (isAllResourceTypesUseable)
2988
+ timesSlotCanUse = true;
2726
2989
  });
2727
2990
  if (!timesSlotCanUse) {
2728
2991
  status = "unavailable";
@@ -2731,11 +2994,26 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2731
2994
  firstAvailableDate = currentDateStr;
2732
2995
  }
2733
2996
  }
2997
+ let dateStatus;
2998
+ if (status === "unavailable") {
2999
+ if (availableCount === 0 && summaryCount > 0)
3000
+ dateStatus = "sold_out";
3001
+ else
3002
+ dateStatus = "unavailable";
3003
+ } else {
3004
+ const usageRatio = availableCount / summaryCount;
3005
+ if (usageRatio > 0.5)
3006
+ dateStatus = "lots_of_space";
3007
+ else
3008
+ dateStatus = "filling_up_fast";
3009
+ }
2734
3010
  dates.push({
2735
3011
  date: (0, import_dayjs.default)(currentDate).format("YYYY-MM-DD"),
2736
3012
  week: (0, import_dayjs.default)(currentDate).format("ddd"),
2737
3013
  weekNum: (0, import_dayjs.default)(currentDate).day(),
2738
- status
3014
+ summaryCount,
3015
+ availableCount,
3016
+ status: dateStatus
2739
3017
  });
2740
3018
  if (firstAvailableDate && (0, import_dayjs.default)(currentDate).diff((0, import_dayjs.default)(startDate), "day") > 31) {
2741
3019
  break;
@@ -230,7 +230,7 @@ function checkTimeSlotCapacity(timeSlotStart, timeSlotEnd, cartItems, allResourc
230
230
  let totalAvailableCapacity = 0;
231
231
  resourcesInType.forEach((resource) => {
232
232
  const availableTimes = resource.times.filter((time) => {
233
- return !(0, import_dayjs.default)(time.start_at).isAfter((0, import_dayjs.default)(timeSlotStart), "minute") && !(0, import_dayjs.default)(time.end_at).isBefore((0, import_dayjs.default)(timeSlotEnd), "minute") || (0, import_dayjs.default)(time.start_at).isBefore((0, import_dayjs.default)(timeSlotEnd), "minute") && (0, import_dayjs.default)(time.end_at).isAfter((0, import_dayjs.default)(timeSlotStart), "minute");
233
+ return !(0, import_dayjs.default)(time.start_at).isAfter((0, import_dayjs.default)(timeSlotStart), "minute") && !(0, import_dayjs.default)(time.end_at).isBefore((0, import_dayjs.default)(timeSlotEnd), "minute") || resource.onlyComputed && (0, import_dayjs.default)(time.start_at).isBefore((0, import_dayjs.default)(timeSlotEnd), "minute") && (0, import_dayjs.default)(time.end_at).isAfter((0, import_dayjs.default)(timeSlotStart), "minute");
234
234
  });
235
235
  if (availableTimes.length > 0) {
236
236
  totalAvailableCapacity += resource.capacity || 0;
@@ -353,7 +353,10 @@ var getTimeSlicesByResource = ({
353
353
  });
354
354
  times.forEach((time) => {
355
355
  const startTime = (0, import_dayjs.default)(`${time.start_at}`);
356
- const endTime = (0, import_dayjs.default)(`${time.end_at}`);
356
+ let endTime = (0, import_dayjs.default)(`${time.end_at}`);
357
+ if (endTime.isAfter((0, import_dayjs.default)(currentDate).endOf("day"))) {
358
+ endTime = (0, import_dayjs.default)(currentDate).endOf("day");
359
+ }
357
360
  let currentStart = startTime;
358
361
  while (true) {
359
362
  const currentEnd = currentStart.add(duration, "minute");