@pisell/pisellos 2.1.158 → 2.1.159

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.
@@ -553,6 +553,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
553
553
  // 存储 UI 层选择的取餐方式到 tempOrder.metadata.shop_service_data
554
554
  // service_type 在扫码点餐场景固定为 dine_in
555
555
  setPickupReferenceMode(mode) {
556
+ var _a;
556
557
  this.logMethodStart("setPickupReferenceMode", { mode });
557
558
  try {
558
559
  if (!this.store.order)
@@ -562,7 +563,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
562
563
  ...tempOrder.metadata || {},
563
564
  shop_service_data: {
564
565
  ...(tempOrder.metadata || {}).shop_service_data || {},
565
- service_type: "dine_in",
566
+ service_type: ((_a = this.otherParams) == null ? void 0 : _a.businessCode) === "dine_in" ? "dine_in" : "take_away",
566
567
  pickup_reference_mode: mode
567
568
  }
568
569
  };
@@ -867,13 +868,13 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
867
868
  const ruleProduct = this.enabledReservationRuleProducts[0];
868
869
  const resourceState = this.store.resource;
869
870
  const resourceSelectType = resourceState == null ? void 0 : resourceState.resourceSelectType;
870
- const resolveResourceCapacity = () => {
871
+ const resolveBookingCapacityValue = () => {
871
872
  var _a;
872
873
  if (resourceSelectType === "single") {
873
874
  const raw = (_a = resourceState == null ? void 0 : resourceState.table_form_record) == null ? void 0 : _a.capacity;
874
875
  const num = Number(raw);
875
876
  if (Number.isFinite(num) && num > 0)
876
- return num;
877
+ return Math.max(1, Math.floor(num));
877
878
  return 1;
878
879
  }
879
880
  return 1;
@@ -892,8 +893,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
892
893
  };
893
894
  }
894
895
  const rawCollectPax = (_a = tempOrder.metadata) == null ? void 0 : _a.collect_pax;
895
- const hasCollectPaxForCapacity = rawCollectPax !== null && rawCollectPax !== void 0 && rawCollectPax !== "";
896
- const resourceCapacityValue = hasCollectPaxForCapacity ? (0, import_utils2.normalizeSubmitCollectPaxValue)(rawCollectPax) : resolveResourceCapacity();
896
+ const hasExplicitCollectPax = rawCollectPax !== null && rawCollectPax !== void 0 && rawCollectPax !== "";
897
+ const bookingCapacityValue = resolveBookingCapacityValue();
897
898
  const pickOriginal = (value) => {
898
899
  if (value && typeof value === "object" && !Array.isArray(value)) {
899
900
  const original = value.original;
@@ -909,35 +910,42 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
909
910
  main_field: mainField,
910
911
  form_id: resourceState.tableFormId,
911
912
  relation_id: resourceState.relationId ?? resourceId,
912
- capacity: resourceCapacityValue,
913
+ capacity: bookingCapacityValue,
913
914
  metadata: this.buildScanOrderResourceMetadata({
914
915
  resourceState,
915
916
  resourceName: mainField
916
917
  })
917
918
  } : void 0;
918
919
  const ruleProductUid = ruleProduct ? (0, import_utils2.createUuidV4)() : void 0;
919
- const bookingCapacityValue = resourceCapacityValue;
920
920
  const bookingCapacityDimensionId = (0, import_utils.pickFirstCustomCapacityDimensionId)(this.enabledReservationRuleProducts) ?? 0;
921
- const nextBookings = (payload.bookings || []).map((booking, idx) => ({
922
- ...booking,
923
- number: bookingCapacityValue,
924
- appointment_status: "started",
925
- metadata: {
926
- ...booking.metadata || {},
927
- ...resourceSelectType ? { resource_select_type: resourceSelectType } : {},
928
- ...resourceSelectType ? {
929
- capacity: [
930
- {
931
- id: bookingCapacityDimensionId,
932
- value: bookingCapacityValue,
933
- name: ""
934
- }
935
- ]
936
- } : {}
937
- },
938
- ...idx === 0 && resourceEntry ? { resources: [resourceEntry] } : {},
939
- ...idx === 0 && ruleProductUid ? { product_uid: ruleProductUid } : {}
940
- }));
921
+ const nextBookings = (payload.bookings || []).map((booking, idx) => {
922
+ const metadata = { ...booking.metadata || {} };
923
+ if (hasExplicitCollectPax) {
924
+ metadata.collect_pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(rawCollectPax);
925
+ } else {
926
+ delete metadata.collect_pax;
927
+ }
928
+ return {
929
+ ...booking,
930
+ number: bookingCapacityValue,
931
+ appointment_status: "started",
932
+ metadata: {
933
+ ...metadata,
934
+ ...resourceSelectType ? { resource_select_type: resourceSelectType } : {},
935
+ ...resourceSelectType ? {
936
+ capacity: [
937
+ {
938
+ id: bookingCapacityDimensionId,
939
+ value: bookingCapacityValue,
940
+ name: ""
941
+ }
942
+ ]
943
+ } : {}
944
+ },
945
+ ...idx === 0 && resourceEntry ? { resources: [resourceEntry] } : {},
946
+ ...idx === 0 && ruleProductUid ? { product_uid: ruleProductUid } : {}
947
+ };
948
+ });
941
949
  const nextProducts = [...payload.products || []];
942
950
  if (ruleProduct && ruleProductUid && !tempOrder.order_id) {
943
951
  const sellingPrice = String(ruleProduct.price ?? "0.00");
@@ -974,10 +982,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
974
982
  if (!this.store.order) {
975
983
  throw new Error("scanOrder解决方案需要 order 模块支持");
976
984
  }
977
- const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(this.store.entryPaxNumber);
978
- this.store.entryPaxNumber = pax;
979
985
  const tempOrderForSubmit = this.store.order.ensureTempOrder();
980
- tempOrderForSubmit.metadata = { ...tempOrderForSubmit.metadata, collect_pax: pax };
981
986
  tempOrderForSubmit.delivery_type = "shop_service";
982
987
  const resourceTableName = (_b = (_a = this.store.resource) == null ? void 0 : _a.table_form_record) == null ? void 0 : _b.name;
983
988
  if (resourceTableName && typeof resourceTableName === "object") {
@@ -1524,8 +1529,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1524
1529
  const matched = resources.find((r) => Number(r == null ? void 0 : r.id) === numericFormId);
1525
1530
  return matched == null ? void 0 : matched.type;
1526
1531
  }
1527
- async fetchResourceOccupyDetailByResourceId(resourceId) {
1528
- var _a, _b, _c, _d;
1532
+ async fetchResourceOccupyDetailsByResourceId(resourceId) {
1533
+ var _a, _b, _c;
1529
1534
  const formRecordId = Number(resourceId);
1530
1535
  if (!Number.isFinite(formRecordId) || formRecordId <= 0) {
1531
1536
  throw new Error(`[ScanOrder] 非法桌台 resourceId: ${resourceId}`);
@@ -1547,13 +1552,57 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1547
1552
  if (!(response == null ? void 0 : response.status)) {
1548
1553
  throw new Error((response == null ? void 0 : response.message) || "获取资源占用详情失败");
1549
1554
  }
1550
- return ((_d = (_c = response == null ? void 0 : response.data) == null ? void 0 : _c.occupy_details) == null ? void 0 : _d[0]) ?? null;
1555
+ return ((_c = response == null ? void 0 : response.data) == null ? void 0 : _c.occupy_details) ?? [];
1556
+ }
1557
+ resolveAdditionalOrderFromOccupyDetail(detail, resourceSelectType, allowAddItems) {
1558
+ const currentOrderId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.order_id);
1559
+ if (currentOrderId) {
1560
+ return {
1561
+ matched: true,
1562
+ order_id: currentOrderId
1563
+ };
1564
+ }
1565
+ const orderListIds = (Array.isArray(detail == null ? void 0 : detail.order_list) ? (detail == null ? void 0 : detail.order_list) || [] : []).map((order) => (0, import_utils.toPositiveString)(order == null ? void 0 : order.id)).filter(Boolean);
1566
+ if (resourceSelectType !== "single") {
1567
+ return {
1568
+ matched: false,
1569
+ reason: "no_order"
1570
+ };
1571
+ }
1572
+ if (!orderListIds.length) {
1573
+ return {
1574
+ matched: false,
1575
+ reason: "no_order"
1576
+ };
1577
+ }
1578
+ if (!allowAddItems) {
1579
+ return {
1580
+ matched: false,
1581
+ reason: "add_items_disabled"
1582
+ };
1583
+ }
1584
+ if (orderListIds.length === 1) {
1585
+ return {
1586
+ matched: true,
1587
+ order_id: orderListIds[0]
1588
+ };
1589
+ }
1590
+ if (orderListIds.length > 1) {
1591
+ return {
1592
+ matched: false,
1593
+ reason: "multiple_orders"
1594
+ };
1595
+ }
1596
+ return {
1597
+ matched: false,
1598
+ reason: "no_order"
1599
+ };
1551
1600
  }
1552
1601
  // 检测当前链接是否可用
1553
1602
  // 通过 resource_id + 店铺配置
1554
1603
  // hasOrderId 表示 url 上是否有 orderid,如果是的话,后续的流程会走加单
1555
1604
  async checkResourceAvailable(resourceId, hasOrderId = false) {
1556
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
1605
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1557
1606
  const normalizedResourceId = String(resourceId ?? "").trim();
1558
1607
  this.logMethodStart("checkResourceAvailable", {
1559
1608
  resourceId: normalizedResourceId
@@ -1645,14 +1694,19 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1645
1694
  cacheId: this.cacheId
1646
1695
  });
1647
1696
  if (Array.isArray(loaded)) {
1648
- this.enabledReservationRuleProducts = loaded;
1649
- const occupancyMinutes = (0, import_utils.pickFirstDurationMinutesFromProducts)(loaded);
1697
+ const matchedRuleProduct = (0, import_utils.findReservationRuleProductByResourceId)(
1698
+ loaded,
1699
+ normalizedResourceId
1700
+ );
1701
+ const ruleProductsForResource = matchedRuleProduct ? [matchedRuleProduct] : [];
1702
+ this.enabledReservationRuleProducts = ruleProductsForResource;
1703
+ const occupancyMinutes = (0, import_utils.pickFirstDurationMinutesFromProducts)(ruleProductsForResource);
1650
1704
  if (occupancyMinutes !== void 0) {
1651
1705
  tempOrder.metadata.table_occupancy_duration = occupancyMinutes;
1652
1706
  }
1653
- if ((0, import_utils.hasCustomCapacityProduct)(loaded)) {
1707
+ if ((0, import_utils.hasCustomCapacityProduct)(ruleProductsForResource)) {
1654
1708
  pendingRequestEntryPax = 1;
1655
- const paxBounds = (0, import_utils.pickFirstCustomCapacityPaxBounds)(loaded);
1709
+ const paxBounds = (0, import_utils.pickFirstCustomCapacityPaxBounds)(ruleProductsForResource);
1656
1710
  if ((paxBounds == null ? void 0 : paxBounds.min) !== void 0)
1657
1711
  pendingRequestPaxMin = paxBounds.min;
1658
1712
  if ((paxBounds == null ? void 0 : paxBounds.max) !== void 0)
@@ -1669,15 +1723,54 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1669
1723
  cacheId: this.cacheId
1670
1724
  });
1671
1725
  }
1672
- const occupyDetail = await this.fetchResourceOccupyDetailByResourceId(normalizedResourceId);
1726
+ const occupyDetails = await this.fetchResourceOccupyDetailsByResourceId(normalizedResourceId);
1727
+ const occupyDetail = occupyDetails[0] ?? null;
1673
1728
  const resourceSelectType = this.resolveResourceSelectType(
1674
1729
  (0, import_utils.toPositiveString)(occupyDetail == null ? void 0 : occupyDetail.form_id)
1675
1730
  );
1731
+ const allowAddItems = (0, import_utils.toBoolean)(dineInConfig == null ? void 0 : dineInConfig["sale.allow_add_items"]);
1732
+ const additionalOrderResult = this.resolveAdditionalOrderFromOccupyDetail(
1733
+ occupyDetail,
1734
+ resourceSelectType,
1735
+ allowAddItems
1736
+ );
1737
+ if (additionalOrderResult.reason === "multiple_orders") {
1738
+ const multipleOrdersState = {
1739
+ ...this.normalizeResourceState(occupyDetail, resourceSelectType, hasOrderId),
1740
+ mode: "multiple_orders"
1741
+ };
1742
+ this.store.resource = multipleOrdersState;
1743
+ const availabilityInfo2 = {
1744
+ mode: "multiple_orders",
1745
+ deskmate_valid: multipleOrdersState.deskmate_valid,
1746
+ relation_id: multipleOrdersState.relationId,
1747
+ table_form_id: multipleOrdersState.tableFormId,
1748
+ table_form_record: multipleOrdersState.table_form_record
1749
+ };
1750
+ this.logMethodSuccess("checkResourceAvailable", {
1751
+ resourceId: normalizedResourceId,
1752
+ mode: availabilityInfo2.mode,
1753
+ orderListCount: ((_e = occupyDetail == null ? void 0 : occupyDetail.order_list) == null ? void 0 : _e.length) || 0,
1754
+ resourceSelectType
1755
+ });
1756
+ return availabilityInfo2;
1757
+ }
1676
1758
  const resourceState = this.normalizeResourceState(
1677
1759
  occupyDetail,
1678
1760
  resourceSelectType,
1679
1761
  hasOrderId
1680
1762
  );
1763
+ const additionalOrderId = additionalOrderResult.order_id;
1764
+ if (additionalOrderId) {
1765
+ resourceState.mode = "additional_order";
1766
+ resourceState.order_id = additionalOrderId;
1767
+ } else if (additionalOrderResult.reason === "add_items_disabled") {
1768
+ resourceState.mode = "resource_busy";
1769
+ resourceState.order_id = "0";
1770
+ } else if (resourceSelectType === "multiple" && resourceState.isFull) {
1771
+ resourceState.mode = "resource_busy";
1772
+ resourceState.order_id = "0";
1773
+ }
1681
1774
  this.store.resource = resourceState;
1682
1775
  if (pendingRequestEntryPax !== void 0) {
1683
1776
  this.store.resource.requestEntryPax = pendingRequestEntryPax;
@@ -1695,34 +1788,25 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1695
1788
  table_form_id: resourceState.tableFormId,
1696
1789
  deskmate_valid: resourceState.deskmate_valid,
1697
1790
  table_form_record: resourceState.table_form_record,
1698
- policy: (_e = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _e.policy,
1699
- partyroom_booking: (_f = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _f.partyroom_booking,
1791
+ policy: (_f = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _f.policy,
1792
+ partyroom_booking: (_g = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _g.partyroom_booking,
1700
1793
  ...this.store.resource.requestEntryPax !== void 0 ? { requestEntryPax: this.store.resource.requestEntryPax } : {},
1701
1794
  ...this.store.resource.requestPaxMin !== void 0 ? { requestPaxMin: this.store.resource.requestPaxMin } : {},
1702
1795
  ...this.store.resource.requestPaxMax !== void 0 ? { requestPaxMax: this.store.resource.requestPaxMax } : {}
1703
1796
  };
1704
- tempOrder.relation_id = normalizedResourceId || ((_g = this.otherParams) == null ? void 0 : _g.relation_id);
1797
+ tempOrder.relation_id = normalizedResourceId || ((_h = this.otherParams) == null ? void 0 : _h.relation_id);
1705
1798
  tempOrder.table_form_id = resourceState.tableFormId;
1706
1799
  tempOrder.resource_id = normalizedResourceId;
1707
- (_h = this.store.order) == null ? void 0 : _h.persistTempOrder();
1800
+ (_i = this.store.order) == null ? void 0 : _i.persistTempOrder();
1708
1801
  if (availabilityInfo.mode === "idle") {
1709
1802
  await this.addNewOrder();
1710
1803
  }
1711
- if (availabilityInfo.mode === "additional_order" || availabilityInfo.mode === "additional_order_with_code") {
1712
- tempOrder.order_id = resourceState.lastOrderId;
1804
+ const isAdditionalOrderMode = availabilityInfo.mode === "additional_order" || availabilityInfo.mode === "additional_order_with_code";
1805
+ if (isAdditionalOrderMode) {
1806
+ tempOrder.order_id = additionalOrderId;
1713
1807
  }
1714
- if (tempOrder.order_id) {
1715
- const res = await ((_i = this.store.order) == null ? void 0 : _i.getOrderInfoByRemote(tempOrder.order_id));
1716
- const entryPaxNumber = (_m = (_l = (_k = (_j = res == null ? void 0 : res.data) == null ? void 0 : _j.bookings) == null ? void 0 : _k.find((p) => {
1717
- var _a2;
1718
- return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
1719
- })) == null ? void 0 : _l.metadata) == null ? void 0 : _m.collect_pax;
1720
- if (entryPaxNumber) {
1721
- await this.setEntryPaxNumber(entryPaxNumber);
1722
- }
1723
- }
1724
- const lastOrderInfo = (_o = (_n = this.store.order) == null ? void 0 : _n.getLastOrderInfo) == null ? void 0 : _o.call(_n);
1725
- const historicalItems = hasOrderId && Array.isArray(lastOrderInfo == null ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce((acc, p) => {
1808
+ const lastOrderInfo = (_k = (_j = this.store.order) == null ? void 0 : _j.getLastOrderInfo) == null ? void 0 : _k.call(_j);
1809
+ const historicalItems = isAdditionalOrderMode && Array.isArray(lastOrderInfo == null ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce((acc, p) => {
1726
1810
  if (typeof (p == null ? void 0 : p.product_id) !== "number")
1727
1811
  return acc;
1728
1812
  acc.push({
@@ -1733,8 +1817,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1733
1817
  return acc;
1734
1818
  }, []) : [];
1735
1819
  await this.setItemRuleRuntimeConfig({
1736
- serviceType: (_p = this.otherParams) == null ? void 0 : _p.businessCode,
1737
- submissionIndex: hasOrderId ? 1 : 0,
1820
+ serviceType: (_l = this.otherParams) == null ? void 0 : _l.businessCode,
1821
+ submissionIndex: isAdditionalOrderMode ? 1 : 0,
1738
1822
  historicalItems
1739
1823
  });
1740
1824
  if (outsideOperatingHours && closedBehaviorValue === "show_menu_disabled") {
@@ -1763,6 +1847,21 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1763
1847
  throw error;
1764
1848
  }
1765
1849
  }
1850
+ // 恢复之前订单的数据,读取 entrypax
1851
+ async restorePreviousOrderData() {
1852
+ var _a, _b, _c, _d, _e;
1853
+ const tempOrder = this.ensureTempOrder();
1854
+ if (tempOrder.order_id) {
1855
+ const res = await ((_a = this.store.order) == null ? void 0 : _a.getOrderInfoByRemote(tempOrder.order_id));
1856
+ const entryPaxNumber = (_e = (_d = (_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b.bookings) == null ? void 0 : _c.find((p) => {
1857
+ var _a2;
1858
+ return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
1859
+ })) == null ? void 0 : _d.metadata) == null ? void 0 : _e.collect_pax;
1860
+ if (entryPaxNumber) {
1861
+ await this.setEntryPaxNumber(entryPaxNumber);
1862
+ }
1863
+ }
1864
+ }
1766
1865
  // 如果是加单的情况,提供返回当前订单相关信息的能力
1767
1866
  async getAdditionalOrderInfo() {
1768
1867
  this.logMethodStart("getAdditionalOrderInfo");
@@ -1907,6 +2006,83 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1907
2006
  getEntryPaxNumber() {
1908
2007
  return this.store.entryPaxNumber;
1909
2008
  }
2009
+ async syncAdditionalOrderFromResource(resourceId) {
2010
+ var _a, _b, _c, _d, _e, _f;
2011
+ const tempOrder = this.ensureTempOrder();
2012
+ const normalizedResourceId = String(
2013
+ resourceId ?? tempOrder.resource_id ?? ((_a = this.store.resource) == null ? void 0 : _a.relationId) ?? ((_b = this.store.resource) == null ? void 0 : _b.relation_id) ?? ""
2014
+ ).trim();
2015
+ this.logMethodStart("syncAdditionalOrderFromResource", {
2016
+ resourceId: normalizedResourceId
2017
+ });
2018
+ if (!normalizedResourceId) {
2019
+ const result2 = {
2020
+ matched: false,
2021
+ reason: "missing_resource_id"
2022
+ };
2023
+ this.logMethodSuccess("syncAdditionalOrderFromResource", result2);
2024
+ return result2;
2025
+ }
2026
+ const occupyDetails = await this.fetchResourceOccupyDetailsByResourceId(normalizedResourceId);
2027
+ const occupyDetail = occupyDetails[0] ?? null;
2028
+ const resourceSelectType = ((_c = this.store.resource) == null ? void 0 : _c.resourceSelectType) || this.resolveResourceSelectType((0, import_utils.toPositiveString)(occupyDetail == null ? void 0 : occupyDetail.form_id));
2029
+ const allowAddItems = (0, import_utils.toBoolean)(
2030
+ (_e = (_d = this.otherParams) == null ? void 0 : _d.dineInConfig) == null ? void 0 : _e["sale.allow_add_items"]
2031
+ );
2032
+ const result = this.resolveAdditionalOrderFromOccupyDetail(
2033
+ occupyDetail,
2034
+ resourceSelectType,
2035
+ allowAddItems
2036
+ );
2037
+ if (!result.matched || !result.order_id) {
2038
+ this.logMethodSuccess("syncAdditionalOrderFromResource", {
2039
+ ...result,
2040
+ resourceId: normalizedResourceId,
2041
+ resourceSelectType,
2042
+ allowAddItems
2043
+ });
2044
+ return result;
2045
+ }
2046
+ tempOrder.order_id = result.order_id;
2047
+ tempOrder.resource_id = normalizedResourceId;
2048
+ tempOrder.relation_id = (0, import_utils.toPositiveString)(occupyDetail == null ? void 0 : occupyDetail.form_record_id) || normalizedResourceId || tempOrder.relation_id;
2049
+ tempOrder.table_form_id = (0, import_utils.toPositiveString)(occupyDetail == null ? void 0 : occupyDetail.form_id) || tempOrder.table_form_id;
2050
+ (_f = this.store.order) == null ? void 0 : _f.persistTempOrder();
2051
+ this.logMethodSuccess("syncAdditionalOrderFromResource", {
2052
+ ...result,
2053
+ resourceId: normalizedResourceId,
2054
+ resourceSelectType,
2055
+ allowAddItems
2056
+ });
2057
+ return result;
2058
+ }
2059
+ // 读取预约规则商品的资源选择类型:single=单个预约,multiple=多个预约,capacity=容量型预约
2060
+ // 依赖 checkResourceAvailable 已根据预约规则商品与 occupy-detail 的 form_id 计算并缓存 store.resource
2061
+ getReservationResourceSelectType() {
2062
+ var _a;
2063
+ this.logMethodStart("getReservationResourceSelectType");
2064
+ const resourceSelectType = (_a = this.store.resource) == null ? void 0 : _a.resourceSelectType;
2065
+ const result = {
2066
+ ...resourceSelectType ? { resourceSelectType } : {},
2067
+ isSingleReservation: resourceSelectType === "single",
2068
+ isMultipleReservation: resourceSelectType === "multiple",
2069
+ isCapacityReservation: resourceSelectType === "capacity"
2070
+ };
2071
+ this.logMethodSuccess("getReservationResourceSelectType", result);
2072
+ return result;
2073
+ }
2074
+ // 判定后台是否开启允许加餐
2075
+ // 依赖 checkResourceAvailable 已缓存的 dineInConfig
2076
+ checkAllowAddItems() {
2077
+ var _a;
2078
+ this.logMethodStart("checkAllowAddItems");
2079
+ const dineInConfig = ((_a = this.otherParams) == null ? void 0 : _a.dineInConfig) || {};
2080
+ const result = {
2081
+ enabled: (0, import_utils.toBoolean)(dineInConfig["sale.allow_add_items"])
2082
+ };
2083
+ this.logMethodSuccess("checkAllowAddItems", result);
2084
+ return result;
2085
+ }
1910
2086
  // 读取取餐/送餐开关
1911
2087
  // 依赖 checkResourceAvailable 已缓存的 dineInConfig
1912
2088
  getFulfillmentModes() {
@@ -186,7 +186,7 @@ export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platfo
186
186
  }>;
187
187
  products: ScanOrderSubmitProduct[];
188
188
  }
189
- export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
189
+ export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'multiple_orders' | 'additional_order_with_code' | 'additional_order';
190
190
  export interface ScanOrderTableFormRecord {
191
191
  policy?: string | null;
192
192
  partyroom_booking?: string | null;
@@ -229,6 +229,10 @@ export interface ScanOrderResourceOccupyDetail {
229
229
  form_id?: number | string | null;
230
230
  order_id?: number | string | null;
231
231
  last_order_id?: number | string | null;
232
+ order_list?: Array<{
233
+ id?: number | string | null;
234
+ [key: string]: any;
235
+ }> | null;
232
236
  resource_capacity?: ScanOrderResourceCapacity[] | null;
233
237
  form_record?: ScanOrderTableFormRecord | null;
234
238
  [key: string]: any;
@@ -242,6 +246,21 @@ export interface ScanOrderResourceOccupyDetailApiResponse {
242
246
  } | null;
243
247
  }
244
248
  export type ScanOrderResourceSelectType = 'single' | 'multiple' | 'capacity';
249
+ export interface ScanOrderReservationResourceSelectInfo {
250
+ resourceSelectType?: ScanOrderResourceSelectType;
251
+ isSingleReservation: boolean;
252
+ isMultipleReservation: boolean;
253
+ isCapacityReservation: boolean;
254
+ }
255
+ export interface ScanOrderAllowAddItemsInfo {
256
+ enabled: boolean;
257
+ }
258
+ export type ScanOrderSyncAdditionalOrderReason = 'missing_resource_id' | 'no_order' | 'multiple_orders' | 'add_items_disabled' | 'invalid_order_id';
259
+ export interface ScanOrderSyncAdditionalOrderResult {
260
+ matched: boolean;
261
+ order_id?: string;
262
+ reason?: ScanOrderSyncAdditionalOrderReason;
263
+ }
245
264
  export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
246
265
  relationId?: string;
247
266
  tableFormId?: string;
@@ -134,6 +134,11 @@ export declare function normalizeOrderProduct(product: Partial<ScanOrderOrderPro
134
134
  * 从 reservation.enabled_reservation_rules 中收集 type=link 的商品 id。
135
135
  */
136
136
  export declare function collectLinkProductIdsFromReservationRules(rules: unknown): number[];
137
+ /**
138
+ * 找到第一个归属指定桌台的预约规则商品。
139
+ * 归属判断基于商品资源中的 default_resource / optional_resource。
140
+ */
141
+ export declare function findReservationRuleProductByResourceId(products: ProductData[], resourceId: string | number | null | undefined): ProductData | undefined;
137
142
  /**
138
143
  * 返回列表中第一个带有效 duration.value(分钟)的商品时长。
139
144
  */
@@ -39,6 +39,7 @@ __export(utils_exports, {
39
39
  computeResourceIsFull: () => computeResourceIsFull,
40
40
  createEmptySummary: () => createEmptySummary,
41
41
  extractStrategyModelIdsFromTableConfig: () => extractStrategyModelIdsFromTableConfig,
42
+ findReservationRuleProductByResourceId: () => findReservationRuleProductByResourceId,
42
43
  getProductIdentityIndex: () => getProductIdentityIndex,
43
44
  getSafeProductNum: () => getSafeProductNum,
44
45
  getTopLevelProductId: () => getTopLevelProductId,
@@ -510,6 +511,27 @@ function collectLinkProductIdsFromReservationRules(rules) {
510
511
  }
511
512
  return [...new Set(ids)];
512
513
  }
514
+ function findReservationRuleProductByResourceId(products, resourceId) {
515
+ var _a;
516
+ const numericResourceId = Number(resourceId);
517
+ if (!Number.isFinite(numericResourceId) || numericResourceId <= 0)
518
+ return void 0;
519
+ for (const product of products) {
520
+ const resources = (_a = product == null ? void 0 : product.product_resource) == null ? void 0 : _a.resources;
521
+ if (!Array.isArray(resources))
522
+ continue;
523
+ const hasMatchedResource = resources.some((resource) => {
524
+ const defaultResources = Array.isArray(resource == null ? void 0 : resource.default_resource) ? resource.default_resource : [];
525
+ const optionalResources = Array.isArray(resource == null ? void 0 : resource.optional_resource) ? resource.optional_resource : [];
526
+ return [...defaultResources, ...optionalResources].some(
527
+ (id) => Number(id) === numericResourceId
528
+ );
529
+ });
530
+ if (hasMatchedResource)
531
+ return product;
532
+ }
533
+ return void 0;
534
+ }
513
535
  function pickFirstDurationMinutesFromProducts(products) {
514
536
  var _a;
515
537
  for (const product of products) {
@@ -613,6 +635,7 @@ function pickFirstCustomCapacityDimensionId(products) {
613
635
  computeResourceIsFull,
614
636
  createEmptySummary,
615
637
  extractStrategyModelIdsFromTableConfig,
638
+ findReservationRuleProductByResourceId,
616
639
  getProductIdentityIndex,
617
640
  getSafeProductNum,
618
641
  getTopLevelProductId,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.1.158",
4
+ "version": "2.1.159",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",