@pisell/pisellos 3.0.77 → 3.0.78

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.
@@ -1393,7 +1393,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1393
1393
  }
1394
1394
  // 从购物车中获取已经分配好第一步资源的所有时间片
1395
1395
  getTimeSlotByAllResources(resources_code) {
1396
- var _a, _b, _c, _d, _e, _f, _g, _h;
1396
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1397
1397
  let dateRange = this.store.date.getDateRange();
1398
1398
  const resources = [];
1399
1399
  const cartItems = this.store.cart.getItems().filter((n) => !(0, import_utils5.isNormalProduct)(n._productOrigin));
@@ -1403,7 +1403,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1403
1403
  let maxCutOffTime = void 0;
1404
1404
  let maxCutOffTimeValue = (0, import_dayjs.default)();
1405
1405
  cartItems.forEach((item) => {
1406
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i;
1406
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
1407
1407
  (_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) == null ? void 0 : _c2.forEach((n) => {
1408
1408
  if (n.code === resources_code) {
1409
1409
  resources.push(...n.renderList || []);
@@ -1416,7 +1416,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1416
1416
  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(
1417
1417
  (n) => n.code === resources_code
1418
1418
  )) == null ? void 0 : _g2.id;
1419
- if (((_h2 = item._productOrigin) == null ? void 0 : _h2.cut_off_time) && ((_i = item._productOrigin) == null ? void 0 : _i.cut_off_time.type) === "advance") {
1419
+ if (((_h2 = item._productOrigin) == null ? void 0 : _h2.cut_off_time) && ((_i2 = item._productOrigin) == null ? void 0 : _i2.cut_off_time.type) === "advance") {
1420
1420
  const currentCutOffTime = (0, import_dayjs.default)().add(
1421
1421
  item._productOrigin.cut_off_time.unit,
1422
1422
  item._productOrigin.cut_off_time.unit_type
@@ -1434,6 +1434,19 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1434
1434
  }
1435
1435
  });
1436
1436
  }
1437
+ if (((_c = dateRange == null ? void 0 : dateRange[0]) == null ? void 0 : _c.date) && resources.length) {
1438
+ const currentDate = (_d = dateRange == null ? void 0 : dateRange[0]) == null ? void 0 : _d.date;
1439
+ const theDateResources = this.store.date.getResourcesListByDate(currentDate);
1440
+ resources.forEach((item) => {
1441
+ var _a2;
1442
+ const noCurrentDateTimes = item.times.some((n) => {
1443
+ return (0, import_dayjs.default)(n.start_at).isSame((0, import_dayjs.default)(currentDate), "day");
1444
+ });
1445
+ if (!noCurrentDateTimes) {
1446
+ item.times = ((_a2 = theDateResources == null ? void 0 : theDateResources.find((n) => n.id === item.id)) == null ? void 0 : _a2.times) || [];
1447
+ }
1448
+ });
1449
+ }
1437
1450
  const resourcesMap = (0, import_utils2.getResourcesMap)(resources);
1438
1451
  let duration = 0;
1439
1452
  const accountList = this.store.accountList.getAccounts();
@@ -1461,7 +1474,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1461
1474
  } else {
1462
1475
  checkDuration(cartItems);
1463
1476
  }
1464
- 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)) {
1477
+ 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)) {
1465
1478
  return [];
1466
1479
  }
1467
1480
  if ((cartItems == null ? void 0 : cartItems[0].start_date) && !dateRange) {
@@ -1473,7 +1486,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1473
1486
  weekNum: 0
1474
1487
  },
1475
1488
  {
1476
- 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) || "",
1489
+ 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) || "",
1477
1490
  status: "available",
1478
1491
  week: "",
1479
1492
  weekNum: 0
@@ -1487,26 +1500,38 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1487
1500
  return ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.type) === "flexible";
1488
1501
  }
1489
1502
  );
1490
- let operating_day_boundary = (_h = (_g = this.shopStore.get("core")) == null ? void 0 : _g.core) == null ? void 0 : _h.operating_day_boundary;
1503
+ let operating_day_boundary = (_j = (_i = this.shopStore.get("core")) == null ? void 0 : _i.core) == null ? void 0 : _j.operating_day_boundary;
1491
1504
  let maxBlockThreshold = 0;
1492
1505
  if (hasFlexibleDuration) {
1493
1506
  maxBlockThreshold = cartItems.reduce((max, item) => {
1494
1507
  var _a2, _b2, _c2, _d2, _e2, _f2;
1495
1508
  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) {
1496
- 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);
1509
+ return Math.max(
1510
+ max,
1511
+ ((_f2 = (_e2 = (_d2 = item._productOrigin) == null ? void 0 : _d2.duration) == null ? void 0 : _e2.flexible_config) == null ? void 0 : _f2.block_threshold) || 0
1512
+ );
1497
1513
  }
1498
1514
  return 0;
1499
1515
  }, 0);
1500
1516
  }
1501
1517
  const calculateCapacityFromCartItems = (items) => {
1502
- return items.reduce((total, item) => {
1503
- return total + ((0, import_capacity.getCapacityInfoByCartItem)(item).currentCapacity || 0);
1504
- }, 0);
1518
+ var _a2;
1519
+ const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1520
+ const sameResourceLength = items.filter((item) => {
1521
+ var _a3;
1522
+ return ((_a3 = item._resourceOrigin) == null ? void 0 : _a3[0].id) === firstResource;
1523
+ }).length;
1524
+ if (sameResourceLength === items.length) {
1525
+ return 1;
1526
+ }
1527
+ return Math.max(...items.map((item) => (0, import_capacity.getCapacityInfoByCartItem)(item).currentCapacity || 1));
1505
1528
  };
1506
1529
  let maxCapacity = 1;
1507
1530
  if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1508
1531
  accountList.forEach((account) => {
1509
- const accountCartItems = this.store.cart.getCartByAccount(account.getId());
1532
+ const accountCartItems = this.store.cart.getCartByAccount(
1533
+ account.getId()
1534
+ );
1510
1535
  const currentCapacity = calculateCapacityFromCartItems(accountCartItems);
1511
1536
  if (currentCapacity > maxCapacity) {
1512
1537
  maxCapacity = currentCapacity;
@@ -1530,6 +1555,172 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1530
1555
  });
1531
1556
  return timeSlots;
1532
1557
  }
1558
+ // 从购物车中获取已经分配好第一步资源的所有时间片,批量版本,用于给日期提供能否高亮的判断
1559
+ async getTimeSlotByAllResourcesForDate({ resources_code, startDate, endDate }) {
1560
+ var _a, _b, _c, _d;
1561
+ if ((0, import_dayjs.default)(endDate).diff((0, import_dayjs.default)(startDate), "day") < 30) {
1562
+ endDate = (0, import_dayjs.default)(startDate).add(30, "day").format("YYYY-MM-DD");
1563
+ }
1564
+ await this.getAvailableDate({
1565
+ startDate,
1566
+ endDate,
1567
+ useCache: true
1568
+ });
1569
+ const resources = [];
1570
+ const cartItems = this.store.cart.getItems().filter((n) => !(0, import_utils5.isNormalProduct)(n._productOrigin));
1571
+ const resourceIds = [];
1572
+ let resourcesTypeId = void 0;
1573
+ let isSingleResource = false;
1574
+ let maxCutOffTime = void 0;
1575
+ let maxCutOffTimeValue = (0, import_dayjs.default)();
1576
+ cartItems.forEach((item) => {
1577
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i;
1578
+ (_c2 = (_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) == null ? void 0 : _c2.forEach((n) => {
1579
+ if (n.code === resources_code) {
1580
+ resources.push(...n.renderList || []);
1581
+ isSingleResource = n.type === "single";
1582
+ }
1583
+ });
1584
+ if (item.resource_id && !resourceIds.includes(item.resource_id)) {
1585
+ resourceIds.push(item.resource_id);
1586
+ }
1587
+ 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(
1588
+ (n) => n.code === resources_code
1589
+ )) == null ? void 0 : _g.id;
1590
+ if (((_h = item._productOrigin) == null ? void 0 : _h.cut_off_time) && ((_i = item._productOrigin) == null ? void 0 : _i.cut_off_time.type) === "advance") {
1591
+ const currentCutOffTime = (0, import_dayjs.default)().add(
1592
+ item._productOrigin.cut_off_time.unit,
1593
+ item._productOrigin.cut_off_time.unit_type
1594
+ );
1595
+ if (currentCutOffTime.isAfter(maxCutOffTimeValue, "minute")) {
1596
+ maxCutOffTimeValue = currentCutOffTime;
1597
+ maxCutOffTime = item._productOrigin.cut_off_time;
1598
+ }
1599
+ }
1600
+ });
1601
+ if (!resources.length)
1602
+ return [];
1603
+ let duration = 0;
1604
+ const accountList = this.store.accountList.getAccounts();
1605
+ const checkDuration = (cartItems2) => {
1606
+ let accountDuration = 0;
1607
+ cartItems2.forEach((item) => {
1608
+ var _a2, _b2, _c2, _d2, _e, _f;
1609
+ if (isSingleResource) {
1610
+ accountDuration += ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.value) || 10;
1611
+ } else {
1612
+ if (accountDuration < (((_d2 = (_c2 = item._productOrigin) == null ? void 0 : _c2.duration) == null ? void 0 : _d2.value) || 10)) {
1613
+ accountDuration = ((_f = (_e = item._productOrigin) == null ? void 0 : _e.duration) == null ? void 0 : _f.value) || 10;
1614
+ }
1615
+ }
1616
+ });
1617
+ if (accountDuration > duration) {
1618
+ duration = accountDuration;
1619
+ }
1620
+ };
1621
+ if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1622
+ accountList.forEach((account) => {
1623
+ const cartItems2 = this.store.cart.getCartByAccount(account.getId());
1624
+ checkDuration(cartItems2);
1625
+ });
1626
+ } else {
1627
+ checkDuration(cartItems);
1628
+ }
1629
+ 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)) {
1630
+ return [];
1631
+ }
1632
+ const resourcesUseableMap = {};
1633
+ const hasFlexibleDuration = cartItems.some(
1634
+ (item) => {
1635
+ var _a2, _b2;
1636
+ return ((_b2 = (_a2 = item._productOrigin) == null ? void 0 : _a2.duration) == null ? void 0 : _b2.type) === "flexible";
1637
+ }
1638
+ );
1639
+ let operating_day_boundary = (_d = (_c = this.shopStore.get("core")) == null ? void 0 : _c.core) == null ? void 0 : _d.operating_day_boundary;
1640
+ let maxBlockThreshold = 0;
1641
+ if (hasFlexibleDuration) {
1642
+ maxBlockThreshold = cartItems.reduce((max, item) => {
1643
+ var _a2, _b2, _c2, _d2, _e, _f;
1644
+ 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) {
1645
+ 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);
1646
+ }
1647
+ return 0;
1648
+ }, 0);
1649
+ }
1650
+ const calculateCapacityFromCartItems = (items) => {
1651
+ var _a2;
1652
+ const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1653
+ const sameResourceLength = items.filter((item) => {
1654
+ var _a3;
1655
+ return ((_a3 = item._resourceOrigin) == null ? void 0 : _a3[0].id) === firstResource;
1656
+ }).length;
1657
+ if (sameResourceLength !== items.length) {
1658
+ return 1;
1659
+ }
1660
+ return Math.max(...items.map((item) => (0, import_capacity.getCapacityInfoByCartItem)(item).currentCapacity || 1));
1661
+ };
1662
+ let maxCapacity = 1;
1663
+ if (cartItems == null ? void 0 : cartItems[0].holder_id) {
1664
+ accountList.forEach((account) => {
1665
+ const accountCartItems = this.store.cart.getCartByAccount(account.getId());
1666
+ const currentCapacity = calculateCapacityFromCartItems(accountCartItems);
1667
+ if (currentCapacity > maxCapacity) {
1668
+ maxCapacity = currentCapacity;
1669
+ }
1670
+ });
1671
+ } else {
1672
+ maxCapacity = calculateCapacityFromCartItems(cartItems);
1673
+ }
1674
+ const arr = [];
1675
+ const today = (0, import_dayjs.default)().startOf("day");
1676
+ for (let i = (0, import_dayjs.default)(startDate); i.isBefore((0, import_dayjs.default)(endDate)); i = i.add(1, "day")) {
1677
+ const currentDate = i.format("YYYY-MM-DD");
1678
+ const theDateResources = this.store.date.getResourcesListByDate(currentDate);
1679
+ resources.forEach((item) => {
1680
+ var _a2;
1681
+ item.times = ((_a2 = theDateResources == null ? void 0 : theDateResources.find((n) => n.id === item.id)) == null ? void 0 : _a2.times) || [];
1682
+ });
1683
+ const resourcesMap = (0, import_utils2.getResourcesMap)(resources);
1684
+ if (i.isBefore(today)) {
1685
+ arr.push({
1686
+ date: currentDate,
1687
+ status: "unavailable",
1688
+ week: i.format("ddd"),
1689
+ weekNum: i.day()
1690
+ });
1691
+ continue;
1692
+ }
1693
+ const timeSlots = (0, import_resources.getTimeSlicesByResources)({
1694
+ resourceIds,
1695
+ resourcesMap,
1696
+ duration,
1697
+ currentDate,
1698
+ split: 10,
1699
+ resourcesUseableMap,
1700
+ capacity: maxCapacity,
1701
+ cut_off_time: maxCutOffTime,
1702
+ hasFlexibleDuration,
1703
+ operating_day_boundary,
1704
+ maxBlockThreshold
1705
+ });
1706
+ if (timeSlots.length > 0) {
1707
+ arr.push({
1708
+ date: currentDate,
1709
+ status: "available",
1710
+ week: i.format("ddd"),
1711
+ weekNum: i.day()
1712
+ });
1713
+ } else {
1714
+ arr.push({
1715
+ date: currentDate,
1716
+ status: "unavailable",
1717
+ week: i.format("ddd"),
1718
+ weekNum: i.day()
1719
+ });
1720
+ }
1721
+ }
1722
+ return arr;
1723
+ }
1533
1724
  // 提交时间切片,绑定到对应购物车的商品上,更新购物车---只有 duration 商品
1534
1725
  submitTimeSlot(timeSlots) {
1535
1726
  var _a, _b;
@@ -1673,7 +1864,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1673
1864
  resources,
1674
1865
  product
1675
1866
  }) {
1676
- var _a, _b, _c, _d, _e;
1867
+ var _a, _b, _c, _d, _e, _f, _g;
1677
1868
  const targetProduct = this.store.currentProduct;
1678
1869
  const targetProductData = product || targetProduct;
1679
1870
  let targetSchedules = [];
@@ -1719,17 +1910,22 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1719
1910
  const firstEnabledResourceId = (_e = (_d = (_c = targetProductData == null ? void 0 : targetProductData.product_resource) == null ? void 0 : _c.resources) == null ? void 0 : _d.find(
1720
1911
  (n) => n.status === 1
1721
1912
  )) == null ? void 0 : _e.id;
1913
+ const firstEnabledResourceConfig = (_g = (_f = targetProductData == null ? void 0 : targetProductData.product_resource) == null ? void 0 : _f.resources) == null ? void 0 : _g.find(
1914
+ (n) => n.status === 1 && n.id === firstEnabledResourceId
1915
+ );
1916
+ const isMultipleBooking = (firstEnabledResourceConfig == null ? void 0 : firstEnabledResourceConfig.type) === "multiple";
1722
1917
  const formatScheduleTimeSlots = scheduleTimeSlots.map((item) => {
1723
1918
  const resourcesUseableMap = {};
1724
1919
  let count = 0;
1725
1920
  let bookingLeft = 0;
1726
1921
  let summaryCount = 0;
1922
+ let summaryConfigCount = 0;
1727
1923
  allProductResources == null ? void 0 : allProductResources.forEach((m) => {
1728
1924
  let currentResourcesCount = 0;
1729
1925
  let currentResourcesSummaryCount = 0;
1730
1926
  const currentResourcesTimeSlotCanUsedArr = [];
1731
1927
  const mTimes = m.times.filter((n) => {
1732
- 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");
1928
+ 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");
1733
1929
  });
1734
1930
  if (mTimes.length === 0) {
1735
1931
  return;
@@ -1759,6 +1955,13 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1759
1955
  }
1760
1956
  currentResourcesTimeSlotCanUsedArr.push(res.usable);
1761
1957
  });
1958
+ if (m.form_id === firstEnabledResourceId) {
1959
+ if (isMultipleBooking) {
1960
+ summaryConfigCount += m.capacity;
1961
+ } else {
1962
+ summaryConfigCount += 1;
1963
+ }
1964
+ }
1762
1965
  if (!currentResourcesTimeSlotCanUsedArr.some(
1763
1966
  (n) => n === false
1764
1967
  ) && // 只统计第一种资源的容量和 left
@@ -1785,13 +1988,17 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1785
1988
  count = 0;
1786
1989
  summaryCount = 0;
1787
1990
  }
1788
- const otherCartItems = cartItems2.filter((m) => {
1789
- var _a2, _b2, _c2;
1790
- 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;
1791
- });
1991
+ let otherCartItems = cartItems2.filter(
1992
+ (m) => {
1993
+ var _a2, _b2, _c2, _d2, _e2, _f2;
1994
+ 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;
1995
+ 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);
1996
+ return isTimeMatch && isResourceMatch;
1997
+ }
1998
+ );
1792
1999
  otherCartItems.forEach((m) => {
1793
2000
  var _a2, _b2, _c2;
1794
- 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);
2001
+ 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);
1795
2002
  const sameTypeResourcesSet = /* @__PURE__ */ new Set([...(sameTypeResources == null ? void 0 : sameTypeResources.optional_resource) || [], ...(sameTypeResources == null ? void 0 : sameTypeResources.default_resource) || []]);
1796
2003
  sameTypeResourcesSet.forEach((resource) => currentResourcesSet.add(resource));
1797
2004
  });
@@ -1872,6 +2079,34 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1872
2079
  });
1873
2080
  const startDayJs = (0, import_dayjs.default)(item.start);
1874
2081
  const endDayJs = (0, import_dayjs.default)(item.end);
2082
+ let timeStatus = "sold_out";
2083
+ if (bookingLeft === 0)
2084
+ timeStatus = "sold_out";
2085
+ else if (isMultipleBooking) {
2086
+ if (summaryConfigCount === 0)
2087
+ timeStatus = "sold_out";
2088
+ else {
2089
+ const usageRatio = summaryCount / summaryConfigCount;
2090
+ if (usageRatio > 0.5)
2091
+ timeStatus = "lots_of_space";
2092
+ else if (summaryCount > 0)
2093
+ timeStatus = "filling_up_fast";
2094
+ else
2095
+ timeStatus = "sold_out";
2096
+ }
2097
+ } else {
2098
+ if (summaryConfigCount === 0)
2099
+ timeStatus = "sold_out";
2100
+ else {
2101
+ const usageRatio = bookingLeft / summaryConfigCount;
2102
+ if (usageRatio > 0.5)
2103
+ timeStatus = "lots_of_space";
2104
+ else if (count > 0)
2105
+ timeStatus = "filling_up_fast";
2106
+ else
2107
+ timeStatus = "sold_out";
2108
+ }
2109
+ }
1875
2110
  return {
1876
2111
  start_time: startDayJs.format("HH:mm"),
1877
2112
  end_time: endDayJs.format("HH:mm"),
@@ -1879,7 +2114,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1879
2114
  end_at: endDayJs,
1880
2115
  count,
1881
2116
  left: bookingLeft,
1882
- summaryCount
2117
+ summaryCount,
2118
+ status: timeStatus
1883
2119
  };
1884
2120
  });
1885
2121
  return formatScheduleTimeSlots;
@@ -1965,6 +2201,9 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1965
2201
  if (!itemsByResourceType[resourceCode]) {
1966
2202
  itemsByResourceType[resourceCode] = [];
1967
2203
  }
2204
+ if (itemsByResourceType[resourceCode].find((item) => item.holder_id === cartItem.holder_id)) {
2205
+ return;
2206
+ }
1968
2207
  if (!itemsByResourceType[resourceCode].find((item) => item._id === cartItem._id)) {
1969
2208
  itemsByResourceType[resourceCode].push(cartItem);
1970
2209
  }
@@ -2650,6 +2889,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2650
2889
  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")) {
2651
2890
  const currentDateStr = currentDate.format("YYYY-MM-DD");
2652
2891
  let status = "available";
2892
+ let summaryCount = 0;
2893
+ let availableCount = 0;
2653
2894
  const { latestStartDate, earliestEndDate } = (0, import_resources.checkSessionProductLeadTime)(tempProducts);
2654
2895
  if (latestStartDate || earliestEndDate) {
2655
2896
  if (latestStartDate && (0, import_dayjs.default)(currentDate).isBefore(latestStartDate, "day")) {
@@ -2674,43 +2915,64 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2674
2915
  currentDateStr
2675
2916
  );
2676
2917
  const scheduleTimeSlots = (0, import_utils3.getAllSortedDateRanges)(minTimeMaxTime);
2677
- const timesSlotCanUse = scheduleTimeSlots.some((item) => {
2918
+ let timesSlotCanUse = false;
2919
+ scheduleTimeSlots.forEach((item) => {
2678
2920
  const resourcesUseableMap = {};
2679
- return openResources.every((resource) => {
2921
+ let isAllResourceTypesUseable = true;
2922
+ openResources.forEach((resource) => {
2680
2923
  const currentResourcesList = allProductResources.filter(
2681
2924
  (n) => n.form_id === resource.resource_type_id
2682
2925
  );
2683
- return currentResourcesList == null ? void 0 : currentResourcesList.some((m) => {
2926
+ let isAnyResourceUseableInType = false;
2927
+ currentResourcesList == null ? void 0 : currentResourcesList.forEach((m) => {
2684
2928
  const mTimes = m.times.filter((n) => {
2685
2929
  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");
2686
2930
  });
2687
- if (mTimes.length === 0) {
2931
+ if (mTimes.length === 0)
2688
2932
  return;
2933
+ if (resource.type === "multiple") {
2934
+ summaryCount += m.capacity;
2935
+ } else {
2936
+ summaryCount += 1;
2689
2937
  }
2690
- const targetCanUseTimes = mTimes.some(
2691
- (childTiem) => {
2692
- const res2 = (0, import_resources.getIsUsableByTimeItem)({
2693
- timeSlice: {
2694
- start_time: item.start,
2695
- end_time: item.end,
2696
- start_at: (0, import_dayjs.default)(item.start),
2697
- end_at: (0, import_dayjs.default)(item.end)
2698
- },
2699
- time: childTiem,
2700
- resource: m,
2701
- currentCount: 1,
2702
- resourcesUseableMap,
2703
- cut_off_time: tempProducts == null ? void 0 : tempProducts.cut_off_time
2704
- });
2705
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[m.id]) !== false && res2.reason !== "capacityOnly") {
2706
- resourcesUseableMap[m.id] = res2.usable;
2938
+ let isAnyTimeSliceUseable = false;
2939
+ mTimes.forEach((childTiem) => {
2940
+ if (isAnyTimeSliceUseable)
2941
+ return;
2942
+ const res2 = (0, import_resources.getIsUsableByTimeItem)({
2943
+ timeSlice: {
2944
+ start_time: item.start,
2945
+ end_time: item.end,
2946
+ start_at: (0, import_dayjs.default)(item.start),
2947
+ end_at: (0, import_dayjs.default)(item.end)
2948
+ },
2949
+ time: childTiem,
2950
+ resource: m,
2951
+ currentCount: 1,
2952
+ resourcesUseableMap,
2953
+ cut_off_time: tempProducts == null ? void 0 : tempProducts.cut_off_time
2954
+ });
2955
+ if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[m.id]) !== false && res2.reason !== "capacityOnly") {
2956
+ resourcesUseableMap[m.id] = res2.usable;
2957
+ }
2958
+ if (res2.usable && !m.onlyComputed) {
2959
+ isAnyTimeSliceUseable = true;
2960
+ if (resource.type === "multiple") {
2961
+ availableCount += res2.remainingCapacity;
2962
+ } else {
2963
+ availableCount += 1;
2707
2964
  }
2708
- return res2.usable && !m.onlyComputed;
2709
2965
  }
2710
- );
2711
- return targetCanUseTimes;
2966
+ ;
2967
+ });
2968
+ if (isAnyTimeSliceUseable)
2969
+ isAnyResourceUseableInType = true;
2712
2970
  });
2971
+ if (!isAnyResourceUseableInType)
2972
+ isAllResourceTypesUseable = false;
2713
2973
  });
2974
+ if (isAllResourceTypesUseable)
2975
+ timesSlotCanUse = true;
2714
2976
  });
2715
2977
  if (!timesSlotCanUse) {
2716
2978
  status = "unavailable";
@@ -2719,11 +2981,26 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
2719
2981
  firstAvailableDate = currentDateStr;
2720
2982
  }
2721
2983
  }
2984
+ let dateStatus;
2985
+ if (status === "unavailable") {
2986
+ if (availableCount === 0 && summaryCount > 0)
2987
+ dateStatus = "sold_out";
2988
+ else
2989
+ dateStatus = "unavailable";
2990
+ } else {
2991
+ const usageRatio = availableCount / summaryCount;
2992
+ if (usageRatio > 0.5)
2993
+ dateStatus = "lots_of_space";
2994
+ else
2995
+ dateStatus = "filling_up_fast";
2996
+ }
2722
2997
  dates.push({
2723
2998
  date: (0, import_dayjs.default)(currentDate).format("YYYY-MM-DD"),
2724
2999
  week: (0, import_dayjs.default)(currentDate).format("ddd"),
2725
3000
  weekNum: (0, import_dayjs.default)(currentDate).day(),
2726
- status
3001
+ summaryCount,
3002
+ availableCount,
3003
+ status: dateStatus
2727
3004
  });
2728
3005
  if (firstAvailableDate && (0, import_dayjs.default)(currentDate).diff((0, import_dayjs.default)(startDate), "day") > 31) {
2729
3006
  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");
@@ -2,6 +2,7 @@ import { Module, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
3
  import { Customer } from './types';
4
4
  import { Discount } from '../../modules/Discount/types';
5
+ import { UnavailableReason } from '../../modules/Rules/types';
5
6
  export declare class ShopDiscountImpl extends BaseModule implements Module {
6
7
  protected defaultName: string;
7
8
  protected defaultVersion: string;
@@ -48,6 +49,7 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
48
49
  productList: Record<string, any>[];
49
50
  discountList: Discount[];
50
51
  type: "server" | "clientCalc";
52
+ unavailableReason?: UnavailableReason;
51
53
  }>;
52
54
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
53
55
  private getCustomer;
@@ -38,6 +38,7 @@ var import_types = require("./types");
38
38
  var import_Discount = require("../../modules/Discount");
39
39
  var import_Rules = require("../../modules/Rules");
40
40
  var import_utils = require("./utils");
41
+ var import_types2 = require("../../modules/Rules/types");
41
42
  var import_decimal = __toESM(require("decimal.js"));
42
43
  var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
43
44
  constructor(name, version) {
@@ -262,7 +263,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
262
263
  type: "clientCalc",
263
264
  isAvailable: false,
264
265
  productList: this.store.productList || [],
265
- discountList: this.getDiscountList()
266
+ discountList: this.getDiscountList(),
267
+ unavailableReason: import_types2.UnavailableReason.Unknown
266
268
  };
267
269
  }
268
270
  if (!resultDiscountList.length) {
@@ -291,7 +293,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
291
293
  const {
292
294
  productList: newProductList,
293
295
  discountList: newDiscountList,
294
- isAvailable
296
+ isAvailable,
297
+ unavailableReason
295
298
  } = rulesModule.isDiscountListAvailable({
296
299
  productList: this.store.productList || [],
297
300
  oldDiscountList: this.getDiscountList(),
@@ -316,7 +319,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
316
319
  type: "clientCalc",
317
320
  isAvailable: isAvailable || false,
318
321
  productList: newProductList || this.store.productList || [],
319
- discountList: newDiscountList || this.getDiscountList()
322
+ discountList: newDiscountList || this.getDiscountList(),
323
+ unavailableReason
320
324
  };
321
325
  } catch (error) {
322
326
  console.error("[ShopDiscount] 扫码出错:", error);
@@ -324,7 +328,8 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
324
328
  type: "clientCalc",
325
329
  isAvailable: false,
326
330
  productList: this.store.productList || [],
327
- discountList: this.getDiscountList()
331
+ discountList: this.getDiscountList(),
332
+ unavailableReason: import_types2.UnavailableReason.Unknown
328
333
  };
329
334
  }
330
335
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "3.0.77",
4
+ "version": "3.0.78",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",