@pisell/pisellos 1.0.65 → 1.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/modules/Date/index.js +4 -0
  2. package/dist/modules/Order/index.js +10 -4
  3. package/dist/modules/Payment/index.d.ts +1 -0
  4. package/dist/modules/Payment/index.js +75 -41
  5. package/dist/modules/Payment/walletpass.js +3 -4
  6. package/dist/modules/Rules/index.js +2 -0
  7. package/dist/modules/Schedule/index.d.ts +1 -1
  8. package/dist/modules/Schedule/index.js +9 -0
  9. package/dist/solution/BookingByStep/index.d.ts +16 -4
  10. package/dist/solution/BookingByStep/index.js +671 -109
  11. package/dist/solution/BookingByStep/utils/capacity.d.ts +23 -0
  12. package/dist/solution/BookingByStep/utils/capacity.js +219 -1
  13. package/dist/solution/BookingByStep/utils/stock.d.ts +29 -0
  14. package/dist/solution/BookingByStep/utils/stock.js +126 -0
  15. package/dist/solution/BookingTicket/index.d.ts +1 -1
  16. package/dist/solution/Checkout/index.d.ts +6 -148
  17. package/dist/solution/Checkout/index.js +1188 -2434
  18. package/dist/solution/Checkout/types.d.ts +7 -220
  19. package/dist/solution/Checkout/types.js +1 -49
  20. package/dist/solution/Checkout/utils/index.d.ts +9 -5
  21. package/dist/solution/Checkout/utils/index.js +18 -56
  22. package/lib/modules/Date/index.js +3 -0
  23. package/lib/modules/Order/index.js +6 -0
  24. package/lib/modules/Payment/index.d.ts +1 -0
  25. package/lib/modules/Payment/index.js +35 -8
  26. package/lib/modules/Payment/walletpass.js +2 -2
  27. package/lib/modules/Rules/index.js +2 -0
  28. package/lib/modules/Schedule/index.d.ts +1 -1
  29. package/lib/modules/Schedule/index.js +9 -0
  30. package/lib/solution/BookingByStep/index.d.ts +16 -4
  31. package/lib/solution/BookingByStep/index.js +363 -8
  32. package/lib/solution/BookingByStep/utils/capacity.d.ts +23 -0
  33. package/lib/solution/BookingByStep/utils/capacity.js +157 -0
  34. package/lib/solution/BookingByStep/utils/stock.d.ts +29 -0
  35. package/lib/solution/BookingByStep/utils/stock.js +89 -0
  36. package/lib/solution/BookingTicket/index.d.ts +1 -1
  37. package/lib/solution/Checkout/index.d.ts +6 -148
  38. package/lib/solution/Checkout/index.js +337 -1115
  39. package/lib/solution/Checkout/types.d.ts +7 -220
  40. package/lib/solution/Checkout/types.js +3 -27
  41. package/lib/solution/Checkout/utils/index.d.ts +9 -5
  42. package/lib/solution/Checkout/utils/index.js +12 -53
  43. package/package.json +1 -1
@@ -33,5 +33,5 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
33
33
  static isInScheduleByDate({ date, schedule, }: {
34
34
  date: string;
35
35
  schedule: any;
36
- }): true | undefined;
36
+ }): boolean | undefined;
37
37
  }
@@ -169,6 +169,15 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
169
169
  schedule
170
170
  }) {
171
171
  var _a, _b, _c, _d;
172
+ if (schedule.start_time && schedule.end_time) {
173
+ const isBeforeStartTime = (0, import_dayjs.default)(date).isBefore(
174
+ (0, import_dayjs.default)(schedule.start_time)
175
+ );
176
+ const isAfterEndTime = (0, import_dayjs.default)(date).isAfter((0, import_dayjs.default)(schedule.end_time));
177
+ if (isBeforeStartTime || isAfterEndTime) {
178
+ return false;
179
+ }
180
+ }
172
181
  let _schedule = {
173
182
  ...schedule,
174
183
  // 开始时间向前推一天
@@ -180,7 +180,10 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
180
180
  * @param {ProductData} productData
181
181
  * @memberof BookingByStepImpl
182
182
  */
183
- storeProduct(productData: ProductData): Promise<void>;
183
+ storeProduct(productData: ProductData): {
184
+ success: boolean;
185
+ errorCode?: string;
186
+ };
184
187
  /**
185
188
  * 往购物车加商品数据
186
189
  *
@@ -203,7 +206,10 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
203
206
  endTime: string;
204
207
  } | null;
205
208
  account?: Account | null;
206
- }): void;
209
+ }): {
210
+ success: boolean;
211
+ errorCode?: string;
212
+ };
207
213
  /**
208
214
  * 添加完购物车以后做的一些检测,比如日期是否在同一天
209
215
  *
@@ -294,8 +300,6 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
294
300
  };
295
301
  getTimeSlotByAllResources(resources_code: string): any[];
296
302
  submitTimeSlot(timeSlots: TimeSliceItem): void;
297
- clearCache(): void;
298
- clearCacheByModule(module: string): void;
299
303
  private getScheduleDataByIds;
300
304
  openProductDetail(productId: number): Promise<void>;
301
305
  closeProductDetail(): void;
@@ -312,6 +316,14 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
312
316
  count: number;
313
317
  left: number;
314
318
  }[];
319
+ /**
320
+ * 找到多个资源的公共可用时间段
321
+ */
322
+ private findCommonAvailableTimeSlots;
323
+ checkMaxDurationCapacity(): {
324
+ success: boolean;
325
+ minAvailableCount: number;
326
+ };
315
327
  setOtherData(key: string, value: any): void;
316
328
  getOtherData(key: string): any;
317
329
  getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
@@ -47,6 +47,7 @@ var import_utils4 = require("../../modules/Product/utils");
47
47
  var import_timeslots = require("./utils/timeslots");
48
48
  var import_changePrice = require("../../modules/Cart/utils/changePrice");
49
49
  var import_capacity = require("./utils/capacity");
50
+ var import_stock = require("./utils/stock");
50
51
  import_dayjs.default.extend(import_isSameOrBefore.default);
51
52
  import_dayjs.default.extend(import_isSameOrAfter.default);
52
53
  var BookingByStepImpl = class extends import_BaseModule.BaseModule {
@@ -560,9 +561,9 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
560
561
  * @param {ProductData} productData
561
562
  * @memberof BookingByStepImpl
562
563
  */
563
- async storeProduct(productData) {
564
+ storeProduct(productData) {
564
565
  const activeAccount = this.getActiveAccount();
565
- this.addProductToCart({
566
+ return this.addProductToCart({
566
567
  product: productData,
567
568
  account: activeAccount
568
569
  });
@@ -596,6 +597,17 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
596
597
  quantity = 1
597
598
  } = product || {};
598
599
  const productData = { ...origin, product_variant_id };
600
+ const currentCartItems = this.store.cart.getItems();
601
+ const stockCheckResult = (0, import_stock.checkProductStock)({
602
+ productData,
603
+ product_variant_id,
604
+ quantity,
605
+ bundle,
606
+ currentCartItems
607
+ });
608
+ if (!stockCheckResult.success) {
609
+ return stockCheckResult;
610
+ }
599
611
  if (!account) {
600
612
  const activeAccount = this.getActiveAccount();
601
613
  if (activeAccount) {
@@ -608,7 +620,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
608
620
  account: account || void 0
609
621
  });
610
622
  if (flag) {
611
- return;
623
+ return { success: true };
612
624
  }
613
625
  const addItemParams = {
614
626
  product: productData,
@@ -624,6 +636,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
624
636
  }
625
637
  this.addProductCheck({ date });
626
638
  this.store.cart.addItem(addItemParams);
639
+ return { success: true };
627
640
  }
628
641
  /**
629
642
  * 添加完购物车以后做的一些检测,比如日期是否在同一天
@@ -1569,10 +1582,6 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1569
1582
  });
1570
1583
  });
1571
1584
  }
1572
- clearCache() {
1573
- }
1574
- clearCacheByModule(module2) {
1575
- }
1576
1585
  getScheduleDataByIds(scheduleIds) {
1577
1586
  const targetSchedules = this.store.schedule.getScheduleListByIds(scheduleIds);
1578
1587
  const targetSchedulesData = targetSchedules.map((item) => {
@@ -1627,6 +1636,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1627
1636
  }
1628
1637
  this.store.currentProduct = void 0;
1629
1638
  }
1639
+ // 通过商品和 schedule 来获取视频可用的时间片、时间片内资源可用的数据
1630
1640
  getTimeslotBySchedule({
1631
1641
  date,
1632
1642
  scheduleIds,
@@ -1726,6 +1736,95 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1726
1736
  }
1727
1737
  }
1728
1738
  });
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");
1766
+ });
1767
+ if (!mTimes.length || mTimes.some((n2) => n2.event_list.length)) {
1768
+ currentResourcesSet.delete(m.id);
1769
+ }
1770
+ }
1771
+ });
1772
+ if (currentResourcesSet.size > 0 && otherCartItems.length + sameCartItems.length >= currentResourcesSet.size) {
1773
+ bookingLeft = 0;
1774
+ count = 0;
1775
+ }
1776
+ } else {
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
+ });
1805
+ }
1806
+ });
1807
+ });
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 (otherCartNeedCapacity + usedCapacity >= currentTypeResourcesCapacity) {
1823
+ bookingLeft = 0;
1824
+ count = 0;
1825
+ }
1826
+ }
1827
+ });
1729
1828
  const startDayJs = (0, import_dayjs.default)(item.start);
1730
1829
  const endDayJs = (0, import_dayjs.default)(item.end);
1731
1830
  return {
@@ -1739,6 +1838,262 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1739
1838
  });
1740
1839
  return formatScheduleTimeSlots;
1741
1840
  }
1841
+ // 提供给 UI的方法,当前步骤是选择商品,下一步不管是什么都需要在这里做一次检测
1842
+ // 时长类商品关联的资源为多个预约时,在点击进入"选择资源"步骤之前,需要检测当前所有资源的总容量
1843
+ // 选择商品数量大于所有资源配置的总容量时,不能进入下一步,需要在"选择商品"这一步时提示。
1844
+ // 注意 资源分为多个种类,需要每个种类单独检测,不能一股脑把所有资源的容量加起来检测
1845
+ /**
1846
+ * 找到多个资源的公共可用时间段
1847
+ */
1848
+ findCommonAvailableTimeSlots(resources) {
1849
+ if (resources.length === 0)
1850
+ return [];
1851
+ console.log(`计算 ${resources.length} 个资源的公共时间段`);
1852
+ const allTimeSlots = resources.map(
1853
+ (resource) => resource.times.map((time) => ({
1854
+ start: (0, import_dayjs.default)(time.start_at),
1855
+ end: (0, import_dayjs.default)(time.end_at)
1856
+ }))
1857
+ );
1858
+ console.log("所有资源的时间段:", allTimeSlots.map(
1859
+ (slots) => slots.map((slot) => `${slot.start.format("HH:mm")}-${slot.end.format("HH:mm")}`)
1860
+ ));
1861
+ let commonSlots = allTimeSlots[0];
1862
+ console.log("初始公共时间段:", commonSlots.map((slot) => `${slot.start.format("HH:mm")}-${slot.end.format("HH:mm")}`));
1863
+ for (let i = 1; i < allTimeSlots.length; i++) {
1864
+ const currentResourceSlots = allTimeSlots[i];
1865
+ const intersections = [];
1866
+ commonSlots.forEach((commonSlot) => {
1867
+ currentResourceSlots.forEach((currentSlot) => {
1868
+ const overlapStart = commonSlot.start.isAfter(currentSlot.start) ? commonSlot.start : currentSlot.start;
1869
+ const overlapEnd = commonSlot.end.isBefore(currentSlot.end) ? commonSlot.end : currentSlot.end;
1870
+ if (overlapStart.isBefore(overlapEnd)) {
1871
+ intersections.push({
1872
+ start: overlapStart,
1873
+ end: overlapEnd
1874
+ });
1875
+ }
1876
+ });
1877
+ });
1878
+ commonSlots = intersections;
1879
+ console.log(`与资源${i}求交集后的公共时间段:`, commonSlots.map((slot) => `${slot.start.format("HH:mm")}-${slot.end.format("HH:mm")}`));
1880
+ if (commonSlots.length === 0) {
1881
+ console.log("没有找到公共时间段");
1882
+ return [];
1883
+ }
1884
+ }
1885
+ const result = commonSlots.map((slot) => ({
1886
+ startTime: slot.start.format("HH:mm"),
1887
+ endTime: slot.end.format("HH:mm")
1888
+ }));
1889
+ console.log("最终公共时间段:", result);
1890
+ return result;
1891
+ }
1892
+ checkMaxDurationCapacity() {
1893
+ var _a, _b;
1894
+ const cartItems = (0, import_lodash_es.cloneDeep)(this.store.cart.getItems());
1895
+ if (cartItems.length === 0)
1896
+ return { success: true, minAvailableCount: 0 };
1897
+ const itemsWithTime = [];
1898
+ const itemsWithoutTime = [];
1899
+ const availableCountsByResourceType = [];
1900
+ cartItems.forEach((cartItem) => {
1901
+ if (cartItem.start_time && cartItem.end_time && cartItem.start_date) {
1902
+ itemsWithTime.push(cartItem);
1903
+ } else {
1904
+ itemsWithoutTime.push(cartItem);
1905
+ }
1906
+ });
1907
+ const processedItemsWithoutTime = [];
1908
+ if (itemsWithoutTime.length > 0) {
1909
+ const itemsByResourceType = {};
1910
+ itemsWithoutTime.forEach((cartItem) => {
1911
+ var _a2;
1912
+ if (!cartItem._productOrigin)
1913
+ return;
1914
+ const resourceTypes = ((_a2 = cartItem._productOrigin.product_resource) == null ? void 0 : _a2.resources) || [];
1915
+ resourceTypes.forEach((resourceType) => {
1916
+ var _a3;
1917
+ if (resourceType.status === 1) {
1918
+ const resourceCode = resourceType.code || ((_a3 = resourceType.id) == null ? void 0 : _a3.toString());
1919
+ if (!itemsByResourceType[resourceCode]) {
1920
+ itemsByResourceType[resourceCode] = [];
1921
+ }
1922
+ if (!itemsByResourceType[resourceCode].find((item) => item._id === cartItem._id)) {
1923
+ itemsByResourceType[resourceCode].push(cartItem);
1924
+ }
1925
+ }
1926
+ });
1927
+ });
1928
+ const dateRange = this.store.date.getDateRange();
1929
+ if (!dateRange || dateRange.length === 0)
1930
+ return { success: false, minAvailableCount: 0 };
1931
+ const resourcesDates = this.store.date.getDateList();
1932
+ const targetResourceDate = resourcesDates.find((n) => n.date === dateRange[0].date);
1933
+ if (!targetResourceDate)
1934
+ return { success: false, minAvailableCount: 0 };
1935
+ const resourcesMap = (0, import_utils.getResourcesMap)(targetResourceDate.resource || []);
1936
+ const resourceCodeToFormIdMap = {};
1937
+ Object.values(itemsByResourceType).flat().forEach((cartItem) => {
1938
+ var _a2, _b2;
1939
+ if ((_b2 = (_a2 = cartItem._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b2.resources) {
1940
+ cartItem._productOrigin.product_resource.resources.forEach((resourceConfig) => {
1941
+ var _a3, _b3;
1942
+ if (resourceConfig.status === 1 && resourceConfig.code) {
1943
+ const formId = ((_a3 = resourceConfig.id) == null ? void 0 : _a3.toString()) || ((_b3 = resourceConfig.resource_type_id) == null ? void 0 : _b3.toString());
1944
+ if (formId) {
1945
+ resourceCodeToFormIdMap[resourceConfig.code] = formId;
1946
+ }
1947
+ }
1948
+ });
1949
+ }
1950
+ });
1951
+ let hasCapacityIssue = false;
1952
+ const resourceCapacityInfo = [];
1953
+ const processedCartItemIds = /* @__PURE__ */ new Set();
1954
+ for (const [resourceCode, items] of Object.entries(itemsByResourceType)) {
1955
+ const targetFormId = resourceCodeToFormIdMap[resourceCode];
1956
+ if (!targetFormId) {
1957
+ console.log(`资源类型 ${resourceCode} 找不到对应的 form_id`);
1958
+ return { success: false, minAvailableCount: 0 };
1959
+ }
1960
+ const resourcesOfThisType = [];
1961
+ items.forEach((cartItem) => {
1962
+ const productResourceIds = (0, import_capacity.getResourcesIdsByProduct)(cartItem._productOrigin);
1963
+ productResourceIds.forEach((resourceId) => {
1964
+ var _a2;
1965
+ const resource = resourcesMap[resourceId];
1966
+ if (resource && ((_a2 = resource.form_id) == null ? void 0 : _a2.toString()) === targetFormId) {
1967
+ if (!resourcesOfThisType.find((r) => r.id === resource.id)) {
1968
+ resourcesOfThisType.push(resource);
1969
+ }
1970
+ }
1971
+ });
1972
+ });
1973
+ if (resourcesOfThisType.length === 0) {
1974
+ console.log(`资源类型 ${resourceCode} 没有找到可用资源`);
1975
+ return { success: false, minAvailableCount: 0 };
1976
+ }
1977
+ let resourceTypeConfig = null;
1978
+ for (const cartItem of items) {
1979
+ if ((_b = (_a = cartItem._productOrigin) == null ? void 0 : _a.product_resource) == null ? void 0 : _b.resources) {
1980
+ resourceTypeConfig = cartItem._productOrigin.product_resource.resources.find(
1981
+ (r) => r.code === resourceCode && r.status === 1
1982
+ );
1983
+ if (resourceTypeConfig)
1984
+ break;
1985
+ }
1986
+ }
1987
+ const isMultipleBooking = (resourceTypeConfig == null ? void 0 : resourceTypeConfig.type) === "multiple";
1988
+ let totalAvailable;
1989
+ let requiredAmount;
1990
+ let availableAmount;
1991
+ if (isMultipleBooking) {
1992
+ totalAvailable = resourcesOfThisType.reduce((sum, resource) => {
1993
+ return sum + (resource.capacity || 0);
1994
+ }, 0);
1995
+ requiredAmount = items.reduce((sum, cartItem) => {
1996
+ const { currentCapacity } = (0, import_capacity.getCapacityInfoByCartItem)(cartItem);
1997
+ return sum + currentCapacity;
1998
+ }, 0);
1999
+ availableAmount = Math.max(0, totalAvailable - requiredAmount);
2000
+ } else {
2001
+ totalAvailable = resourcesOfThisType.length;
2002
+ requiredAmount = items.reduce((sum, cartItem) => {
2003
+ return sum + (cartItem.num || 1);
2004
+ }, 0);
2005
+ availableAmount = Math.max(0, totalAvailable - requiredAmount);
2006
+ }
2007
+ resourceCapacityInfo.push({
2008
+ code: resourceCode,
2009
+ available: availableAmount,
2010
+ total: totalAvailable,
2011
+ required: requiredAmount,
2012
+ isMultiple: isMultipleBooking
2013
+ });
2014
+ availableCountsByResourceType.push(availableAmount);
2015
+ if (requiredAmount > totalAvailable) {
2016
+ hasCapacityIssue = true;
2017
+ console.log(`资源类型 ${resourceCode} ${isMultipleBooking ? "容量" : "资源数量"}不足: 需要 ${requiredAmount}, 总共 ${totalAvailable}`);
2018
+ }
2019
+ console.log(`资源类型 ${resourceCode} 的资源时间信息:`, resourcesOfThisType.map((r) => ({
2020
+ id: r.id,
2021
+ times: r.times.map((t) => `${t.start_at} - ${t.end_at}`)
2022
+ })));
2023
+ const commonTimeSlots = this.findCommonAvailableTimeSlots(resourcesOfThisType);
2024
+ console.log(`资源类型 ${resourceCode} 的公共时间段:`, commonTimeSlots);
2025
+ if (commonTimeSlots.length === 0) {
2026
+ console.log(`资源类型 ${resourceCode} 没有公共可用时间段`);
2027
+ return { success: false, minAvailableCount: 0 };
2028
+ }
2029
+ const firstCommonSlot = commonTimeSlots[0];
2030
+ console.log(`使用公共时间段: ${firstCommonSlot.startTime} - ${firstCommonSlot.endTime}`);
2031
+ items.forEach((cartItem) => {
2032
+ if (!processedCartItemIds.has(cartItem._id)) {
2033
+ processedCartItemIds.add(cartItem._id);
2034
+ const processedItem = {
2035
+ ...cartItem,
2036
+ start_date: dateRange[0].date,
2037
+ start_time: firstCommonSlot.startTime,
2038
+ end_time: firstCommonSlot.endTime,
2039
+ end_date: dateRange[0].date
2040
+ };
2041
+ processedItemsWithoutTime.push(processedItem);
2042
+ }
2043
+ });
2044
+ }
2045
+ if (hasCapacityIssue) {
2046
+ const overCapacityResources = resourceCapacityInfo.filter((info) => info.required > info.total);
2047
+ if (overCapacityResources.length > 0) {
2048
+ const minTotalCapacity2 = Math.min(...overCapacityResources.map((info) => info.total));
2049
+ return { success: false, minAvailableCount: minTotalCapacity2 };
2050
+ }
2051
+ const minTotalCapacity = Math.min(...resourceCapacityInfo.map((info) => info.total));
2052
+ return { success: false, minAvailableCount: minTotalCapacity };
2053
+ }
2054
+ }
2055
+ const allProcessedItems = [...itemsWithTime, ...processedItemsWithoutTime];
2056
+ const cartItemsByTimeSlot = {};
2057
+ allProcessedItems.forEach((cartItem) => {
2058
+ if (!cartItem.start_time || !cartItem.end_time || !cartItem.start_date)
2059
+ return;
2060
+ const timeSlotKey = `${cartItem.start_date}_${cartItem.start_time}_${cartItem.end_date || cartItem.start_date}_${cartItem.end_time}`;
2061
+ if (!cartItemsByTimeSlot[timeSlotKey]) {
2062
+ cartItemsByTimeSlot[timeSlotKey] = [];
2063
+ }
2064
+ cartItemsByTimeSlot[timeSlotKey].push(cartItem);
2065
+ });
2066
+ for (const [timeSlotKey, itemsInTimeSlot] of Object.entries(cartItemsByTimeSlot)) {
2067
+ const [startDate, startTime, endDate, endTime] = timeSlotKey.split("_");
2068
+ const timeSlotStart = `${startDate} ${startTime}`;
2069
+ const timeSlotEnd = `${endDate} ${endTime}`;
2070
+ const allResourcesForTimeSlot = [];
2071
+ const resourcesIdSet = /* @__PURE__ */ new Set();
2072
+ const dateRange = this.store.date.getDateRange();
2073
+ const resourcesDates = this.store.date.getDateList();
2074
+ const targetResourceDate = resourcesDates.find((n) => n.date === startDate);
2075
+ if (!targetResourceDate)
2076
+ continue;
2077
+ const resourcesMap = (0, import_utils.getResourcesMap)(targetResourceDate.resource || []);
2078
+ itemsInTimeSlot.forEach((cartItem) => {
2079
+ if (!cartItem._productOrigin)
2080
+ return;
2081
+ const productResourceIds = (0, import_capacity.getResourcesIdsByProduct)(cartItem._productOrigin);
2082
+ productResourceIds.forEach((resourceId) => {
2083
+ if (resourcesMap[resourceId] && !resourcesIdSet.has(resourceId)) {
2084
+ resourcesIdSet.add(resourceId);
2085
+ allResourcesForTimeSlot.push(resourcesMap[resourceId]);
2086
+ }
2087
+ });
2088
+ });
2089
+ if (!(0, import_capacity.checkTimeSlotCapacity)(timeSlotStart, timeSlotEnd, itemsInTimeSlot, allResourcesForTimeSlot)) {
2090
+ const minAvailableCount2 = availableCountsByResourceType.length > 0 ? Math.min(...availableCountsByResourceType) : 0;
2091
+ return { success: false, minAvailableCount: minAvailableCount2 };
2092
+ }
2093
+ }
2094
+ const minAvailableCount = availableCountsByResourceType.length > 0 ? Math.min(...availableCountsByResourceType) : 0;
2095
+ return { success: true, minAvailableCount };
2096
+ }
1742
2097
  setOtherData(key, value) {
1743
2098
  this.otherData[key] = value;
1744
2099
  this.checkSaveCache({
@@ -1956,7 +2311,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1956
2311
  startDate || "",
1957
2312
  endDate || ""
1958
2313
  );
1959
- const tempResourceIds = (0, import_resources.getResourcesIdsByProduct)(tempProducts);
2314
+ const tempResourceIds = (0, import_capacity.getResourcesIdsByProduct)(tempProducts);
1960
2315
  const res = await this.store.date.fetchResourceDates({
1961
2316
  query: {
1962
2317
  start_date: startDate || "",
@@ -45,3 +45,26 @@ export declare const checkSubResourcesCapacity: (resource: ResourceItem) => void
45
45
  * @returns 如果资源可以容纳额外的容量则返回 true
46
46
  */
47
47
  export declare const checkResourceCanUseByCapacity: (currentCapacity: number, requiredCapacity: number, maxCapacity: number) => boolean;
48
+ /**
49
+ * 计算按资源类型分组的容量占用情况
50
+ *
51
+ * @param {CartItem[]} cartItems 购物车商品列表
52
+ * @param {string} timeSlotStart 时间段开始时间
53
+ * @param {string} timeSlotEnd 时间段结束时间
54
+ * @param {ResourceItem[]} allProductResources 当前商品的所有资源列表
55
+ * @return {Record<string, number>} 返回每种资源类型(form_id)的容量占用
56
+ */
57
+ export declare function calculateCartItemsCapacityUsageByResourceType({ cartItems, timeSlotStart, timeSlotEnd, allProductResources }: {
58
+ cartItems: CartItem[];
59
+ timeSlotStart: string;
60
+ timeSlotEnd: string;
61
+ allProductResources: ResourceItem[];
62
+ }): Record<string, number>;
63
+ /**
64
+ * 获取商品的资源ID列表
65
+ */
66
+ export declare function getResourcesIdsByProduct(product: any): number[];
67
+ /**
68
+ * 检查特定时间段的容量是否足够
69
+ */
70
+ export declare function checkTimeSlotCapacity(timeSlotStart: string, timeSlotEnd: string, cartItems: CartItem[], allResources: ResourceItem[]): boolean;