@pisell/pisellos 0.10.16 → 0.10.18

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 (63) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/OpenData/index.d.ts +5 -2
  3. package/dist/modules/OpenData/index.js +27 -12
  4. package/dist/modules/OpenData/types.d.ts +42 -0
  5. package/dist/modules/OpenData/types.js +7 -1
  6. package/dist/modules/OpenData/utils.d.ts +15 -1
  7. package/dist/modules/OpenData/utils.js +85 -0
  8. package/dist/modules/Order/index.d.ts +3 -1
  9. package/dist/modules/Order/index.js +68 -44
  10. package/dist/modules/Order/types.d.ts +3 -0
  11. package/dist/modules/Order/types.js +1 -0
  12. package/dist/modules/ProductList/index.js +96 -74
  13. package/dist/modules/Rules/index.js +11 -8
  14. package/dist/modules/SalesSummary/index.js +6 -4
  15. package/dist/server/index.d.ts +11 -0
  16. package/dist/server/index.js +845 -481
  17. package/dist/server/modules/order/index.d.ts +8 -0
  18. package/dist/server/modules/order/index.js +251 -215
  19. package/dist/server/utils/small-ticket.d.ts +9 -1
  20. package/dist/server/utils/small-ticket.js +117 -43
  21. package/dist/solution/BaseSales/index.d.ts +7 -0
  22. package/dist/solution/BaseSales/index.js +251 -144
  23. package/dist/solution/BookingByStep/index.d.ts +2 -2
  24. package/dist/solution/BookingTicket/index.d.ts +14 -19
  25. package/dist/solution/BookingTicket/index.js +545 -429
  26. package/dist/solution/Sales/index.d.ts +20 -4
  27. package/dist/solution/Sales/index.js +348 -75
  28. package/dist/solution/Sales/types.d.ts +10 -0
  29. package/dist/solution/UnifiedBookingSales/index.d.ts +5 -4
  30. package/dist/solution/UnifiedBookingSales/index.js +495 -422
  31. package/dist/solution/UnifiedBookingSales/types.d.ts +7 -1
  32. package/lib/model/strategy/adapter/promotion/index.js +1 -46
  33. package/lib/modules/OpenData/index.d.ts +5 -2
  34. package/lib/modules/OpenData/index.js +50 -3
  35. package/lib/modules/OpenData/types.d.ts +42 -0
  36. package/lib/modules/OpenData/types.js +9 -1
  37. package/lib/modules/OpenData/utils.d.ts +15 -1
  38. package/lib/modules/OpenData/utils.js +85 -0
  39. package/lib/modules/Order/index.d.ts +3 -1
  40. package/lib/modules/Order/index.js +41 -21
  41. package/lib/modules/Order/types.d.ts +3 -0
  42. package/lib/modules/Order/types.js +1 -0
  43. package/lib/modules/ProductList/index.js +9 -6
  44. package/lib/modules/Rules/index.js +8 -6
  45. package/lib/modules/SalesSummary/index.js +3 -1
  46. package/lib/server/index.d.ts +11 -0
  47. package/lib/server/index.js +395 -96
  48. package/lib/server/modules/order/index.d.ts +8 -0
  49. package/lib/server/modules/order/index.js +23 -0
  50. package/lib/server/utils/small-ticket.d.ts +9 -1
  51. package/lib/server/utils/small-ticket.js +107 -35
  52. package/lib/solution/BaseSales/index.d.ts +7 -0
  53. package/lib/solution/BaseSales/index.js +125 -28
  54. package/lib/solution/BookingByStep/index.d.ts +2 -2
  55. package/lib/solution/BookingTicket/index.d.ts +14 -19
  56. package/lib/solution/BookingTicket/index.js +70 -17
  57. package/lib/solution/Sales/index.d.ts +20 -4
  58. package/lib/solution/Sales/index.js +183 -15
  59. package/lib/solution/Sales/types.d.ts +10 -0
  60. package/lib/solution/UnifiedBookingSales/index.d.ts +5 -4
  61. package/lib/solution/UnifiedBookingSales/index.js +41 -15
  62. package/lib/solution/UnifiedBookingSales/types.d.ts +7 -1
  63. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import type { OpenDataConfig } from '../../modules/OpenData';
1
+ import type { InvoiceLayoutConfig, InvoiceTemplateSettings, OpenDataConfig } from '../../modules/OpenData';
2
2
  import type { ProductListLoadProductsParams } from '../../modules/ProductList';
3
3
  import type { LoadScheduleAvailableDateParams } from '../../modules/Schedule/types';
4
4
  import type { AvailabilityDateRange, AvailabilityErrorCode, AvailabilityId, AvailabilityOccupancy, AvailabilityProduct, AvailabilityProjection, AvailabilityQuery, AvailabilityRequirementSelection, AvailabilityResource, AvailabilitySelectionValidationResult, DateAvailabilityQueryResult, GetProductTimeRangesRequest, ProductAvailabilityQueryResult, ProductTimeRange, ProductTimeRangeGroup, ResourceAvailabilityGroup, ResourceAvailabilityRangeGroup, TimeAvailabilityGroup, TimeAvailabilityItem } from '../../modules/ResourcePlanner';
@@ -201,7 +201,13 @@ export interface UnifiedBookingSalesDiscountResult {
201
201
  }
202
202
  export interface UnifiedBookingSalesApi {
203
203
  loadOpenData: (params: UnifiedBookingSalesLoadOpenDataParams) => Promise<OpenDataConfig>;
204
+ /** Returns the latest OpenData payload cached by this solution instance. */
204
205
  getOpenData: () => Promise<OpenDataConfig | null>;
206
+ /** Returns the normalized Documents Invoice layout for the active target. */
207
+ getInvoiceLayoutConfig: () => Promise<InvoiceLayoutConfig>;
208
+ /** Returns the Native Invoice template settings for the active target. */
209
+ getInvoiceTemplateSettings: () => Promise<InvoiceTemplateSettings>;
210
+ /** Date-first calendar availability backed by ScheduleModule. */
205
211
  loadScheduleAvailableDate: (params: LoadScheduleAvailableDateParams) => Promise<unknown>;
206
212
  loadProductsByScheduleDate: (params: UnifiedBookingSalesLoadProductsByScheduleDateParams) => Promise<unknown[]>;
207
213
  stageRetailProducts: (params: UnifiedBookingSalesStageRetailProductsParams) => Promise<Record<string, any> | null>;
@@ -1,46 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
7
- enumerable: true,
8
- get: function () {
9
- return _examples.BUY_X_GET_Y_FREE_STRATEGY;
10
- }
11
- });
12
- Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
13
- enumerable: true,
14
- get: function () {
15
- return _examples.ITEM_REWARD_STRATEGY;
16
- }
17
- });
18
- Object.defineProperty(exports, "PromotionAdapter", {
19
- enumerable: true,
20
- get: function () {
21
- return _adapter.PromotionAdapter;
22
- }
23
- });
24
- Object.defineProperty(exports, "PromotionEvaluator", {
25
- enumerable: true,
26
- get: function () {
27
- return _evaluator.PromotionEvaluator;
28
- }
29
- });
30
- Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
31
- enumerable: true,
32
- get: function () {
33
- return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
34
- }
35
- });
36
- Object.defineProperty(exports, "default", {
37
- enumerable: true,
38
- get: function () {
39
- return _adapter.default;
40
- }
41
- });
42
- var _evaluator = require("./evaluator");
43
- var _adapter = _interopRequireWildcard(require("./adapter"));
44
- var _examples = require("./examples");
45
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
46
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
1
+ "use strict";
@@ -1,9 +1,9 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
3
  import type { ScheduleModule } from '../Schedule';
4
- import type { OpenDataConfig, OpenDataFetchParams, OpenDataAvailabilityResult } from './types';
4
+ import type { OpenDataConfig, OpenDataFetchParams, OpenDataAvailabilityResult, InvoiceLayoutConfig, InvoiceTemplateSettings } from './types';
5
5
  export * from './types';
6
- export { computeAvailability } from './utils';
6
+ export { computeAvailability, getDefaultInvoiceLayoutConfig, getDefaultInvoiceTemplateSettings, normalizeInvoiceLayoutConfig, normalizeInvoiceTemplateSettings, normalizeRawInvoiceTemplateSettings, } from './utils';
7
7
  export declare class OpenDataModule extends BaseModule implements Module {
8
8
  protected defaultName: string;
9
9
  protected defaultVersion: string;
@@ -15,6 +15,7 @@ export declare class OpenDataModule extends BaseModule implements Module {
15
15
  private openCache;
16
16
  private fatherModule;
17
17
  private otherParams;
18
+ private fetchRevision;
18
19
  constructor(name?: string, version?: string);
19
20
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
20
21
  /**
@@ -26,6 +27,8 @@ export declare class OpenDataModule extends BaseModule implements Module {
26
27
  updateOtherParams(params: Record<string, any>): void;
27
28
  fetchOpenData(params: OpenDataFetchParams): Promise<OpenDataConfig>;
28
29
  getOpenData(): OpenDataConfig | null;
30
+ getInvoiceLayoutConfig(): InvoiceLayoutConfig;
31
+ getInvoiceTemplateSettings(): InvoiceTemplateSettings;
29
32
  getLastFetchedAt(): number | null;
30
33
  /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
31
34
  clearCache(): void;
@@ -5,7 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  var _exportNames = {
7
7
  OpenDataModule: true,
8
- computeAvailability: true
8
+ computeAvailability: true,
9
+ getDefaultInvoiceLayoutConfig: true,
10
+ getDefaultInvoiceTemplateSettings: true,
11
+ normalizeInvoiceLayoutConfig: true,
12
+ normalizeInvoiceTemplateSettings: true,
13
+ normalizeRawInvoiceTemplateSettings: true
9
14
  };
10
15
  exports.OpenDataModule = void 0;
11
16
  Object.defineProperty(exports, "computeAvailability", {
@@ -14,6 +19,36 @@ Object.defineProperty(exports, "computeAvailability", {
14
19
  return _utils.computeAvailability;
15
20
  }
16
21
  });
22
+ Object.defineProperty(exports, "getDefaultInvoiceLayoutConfig", {
23
+ enumerable: true,
24
+ get: function () {
25
+ return _utils.getDefaultInvoiceLayoutConfig;
26
+ }
27
+ });
28
+ Object.defineProperty(exports, "getDefaultInvoiceTemplateSettings", {
29
+ enumerable: true,
30
+ get: function () {
31
+ return _utils.getDefaultInvoiceTemplateSettings;
32
+ }
33
+ });
34
+ Object.defineProperty(exports, "normalizeInvoiceLayoutConfig", {
35
+ enumerable: true,
36
+ get: function () {
37
+ return _utils.normalizeInvoiceLayoutConfig;
38
+ }
39
+ });
40
+ Object.defineProperty(exports, "normalizeInvoiceTemplateSettings", {
41
+ enumerable: true,
42
+ get: function () {
43
+ return _utils.normalizeInvoiceTemplateSettings;
44
+ }
45
+ });
46
+ Object.defineProperty(exports, "normalizeRawInvoiceTemplateSettings", {
47
+ enumerable: true,
48
+ get: function () {
49
+ return _utils.normalizeRawInvoiceTemplateSettings;
50
+ }
51
+ });
17
52
  var _BaseModule = require("../BaseModule");
18
53
  var _utils = require("./utils");
19
54
  var _types = require("./types");
@@ -39,6 +74,7 @@ class OpenDataModule extends _BaseModule.BaseModule {
39
74
  openCache = false;
40
75
  fatherModule;
41
76
  otherParams = {};
77
+ fetchRevision = 0;
42
78
  constructor(name, version) {
43
79
  super(name, version);
44
80
  }
@@ -75,6 +111,7 @@ class OpenDataModule extends _BaseModule.BaseModule {
75
111
  this.fatherModule = this.otherParams.fatherModule;
76
112
  }
77
113
  async fetchOpenData(params) {
114
+ const fetchRevision = ++this.fetchRevision;
78
115
  const getData = this.appPlugin?.getData?.();
79
116
  const shopId = getData?.('shop_id');
80
117
  if (!shopId) throw new Error('[OpenDataModule] 无法获取 shop_id');
@@ -95,19 +132,29 @@ class OpenDataModule extends _BaseModule.BaseModule {
95
132
  throw new Error(response?.message || '获取 OpenData 配置失败');
96
133
  }
97
134
  const data = response?.data || {};
98
- this.store.data = data;
99
- this.store.lastFetchedAt = Date.now();
135
+ // clearCache() 或后续请求发生后,旧响应不得复活已失效的 target 配置。
136
+ if (fetchRevision === this.fetchRevision) {
137
+ this.store.data = data;
138
+ this.store.lastFetchedAt = Date.now();
139
+ }
100
140
  return data;
101
141
  }
102
142
  getOpenData() {
103
143
  return this.store.data;
104
144
  }
145
+ getInvoiceLayoutConfig() {
146
+ return (0, _utils.normalizeInvoiceLayoutConfig)(this.store.data);
147
+ }
148
+ getInvoiceTemplateSettings() {
149
+ return (0, _utils.normalizeInvoiceTemplateSettings)(this.store.data);
150
+ }
105
151
  getLastFetchedAt() {
106
152
  return this.store.lastFetchedAt ?? null;
107
153
  }
108
154
 
109
155
  /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
110
156
  clearCache() {
157
+ this.fetchRevision += 1;
111
158
  this.store.data = null;
112
159
  this.store.lastFetchedAt = null;
113
160
  }
@@ -8,6 +8,40 @@ export interface MultiLangObject {
8
8
  original?: string;
9
9
  [key: string]: string | undefined;
10
10
  }
11
+ export declare const INVOICE_MODULE_KEYS: readonly ["reference", "brand", "custom_1", "order", "handover", "customer", "line_groups", "settlement", "custom_2", "payment", "card", "total_savings", "custom_3", "barcode"];
12
+ export type InvoiceModuleKey = (typeof INVOICE_MODULE_KEYS)[number];
13
+ /**
14
+ * Documents Registry 中的 Invoice 模块配置。
15
+ *
16
+ * 模块 key、显隐值及模块私有字段均由 Registry/Native 约定,OS 不做枚举收窄或改写。
17
+ */
18
+ export interface InvoiceTemplateModuleConfig {
19
+ key: string;
20
+ is_show?: unknown;
21
+ [key: string]: unknown;
22
+ }
23
+ export interface InvoiceModuleConfig extends InvoiceTemplateModuleConfig {
24
+ }
25
+ export interface InvoiceLayoutConfig {
26
+ locale?: string;
27
+ module: InvoiceModuleConfig[];
28
+ }
29
+ export interface InvoiceTemplateSettings {
30
+ template: string;
31
+ language: Record<string, number>;
32
+ modules: InvoiceTemplateModuleConfig[];
33
+ [key: string]: unknown;
34
+ }
35
+ export type RawInvoiceEditConfig = string | {
36
+ language?: unknown;
37
+ modules?: unknown;
38
+ [key: string]: unknown;
39
+ };
40
+ export type RawInvoiceLayoutConfig = string | {
41
+ locale?: unknown;
42
+ module?: unknown[];
43
+ [key: string]: unknown;
44
+ };
11
45
  export interface OpenDataConfig {
12
46
  'basic.enable'?: boolean;
13
47
  'basic.code'?: string | null;
@@ -45,6 +79,14 @@ export interface OpenDataConfig {
45
79
  label: string;
46
80
  value: number;
47
81
  }>;
82
+ 'documents.invoice_template'?: string;
83
+ 'documents.invoice_edit'?: RawInvoiceEditConfig;
84
+ /** @deprecated 仅保留旧调用方的类型兼容,Invoice 读取逻辑不再消费该字段。 */
85
+ 'documents.invoice'?: RawInvoiceLayoutConfig;
86
+ /** @deprecated Invoice 读取逻辑只消费扁平的 documents.invoice_* 字段。 */
87
+ documents?: {
88
+ invoice?: RawInvoiceLayoutConfig;
89
+ };
48
90
  [key: string]: any;
49
91
  }
50
92
  export interface OpenDataState {
@@ -2,4 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
- });
5
+ });
6
+ exports.INVOICE_MODULE_KEYS = void 0;
7
+ const INVOICE_MODULE_KEYS = exports.INVOICE_MODULE_KEYS = ['reference', 'brand', 'custom_1', 'order', 'handover', 'customer', 'line_groups', 'settlement', 'custom_2', 'payment', 'card', 'total_savings', 'custom_3', 'barcode'];
8
+
9
+ /**
10
+ * Documents Registry 中的 Invoice 模块配置。
11
+ *
12
+ * 模块 key、显隐值及模块私有字段均由 Registry/Native 约定,OS 不做枚举收窄或改写。
13
+ */
@@ -1,2 +1,16 @@
1
- import type { OpenDataAvailabilityResult, ComputeAvailabilityParams } from './types';
1
+ import type { OpenDataConfig, OpenDataAvailabilityResult, ComputeAvailabilityParams, InvoiceLayoutConfig, InvoiceTemplateSettings } from './types';
2
+ export declare function getDefaultInvoiceLayoutConfig(): InvoiceLayoutConfig;
3
+ export declare function getDefaultInvoiceTemplateSettings(): InvoiceTemplateSettings;
4
+ /**
5
+ * 规范化已经提取出的公开 template_settings 值,供打印入口复用。
6
+ */
7
+ export declare function normalizeRawInvoiceTemplateSettings(value: unknown): InvoiceTemplateSettings;
8
+ /**
9
+ * 从 OpenData Documents section 的两个扁平字段中构造 Native Invoice 配置。
10
+ */
11
+ export declare function normalizeInvoiceTemplateSettings(config: OpenDataConfig | null | undefined): InvoiceTemplateSettings;
12
+ /**
13
+ * 将 invoice_edit.modules 原样投影为 Web Invoice 使用的 module 字段。
14
+ */
15
+ export declare function normalizeInvoiceLayoutConfig(config: OpenDataConfig | null | undefined): InvoiceLayoutConfig;
2
16
  export declare function computeAvailability(params: ComputeAvailabilityParams): OpenDataAvailabilityResult;
@@ -4,9 +4,94 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.computeAvailability = computeAvailability;
7
+ exports.getDefaultInvoiceLayoutConfig = getDefaultInvoiceLayoutConfig;
8
+ exports.getDefaultInvoiceTemplateSettings = getDefaultInvoiceTemplateSettings;
9
+ exports.normalizeInvoiceLayoutConfig = normalizeInvoiceLayoutConfig;
10
+ exports.normalizeInvoiceTemplateSettings = normalizeInvoiceTemplateSettings;
11
+ exports.normalizeRawInvoiceTemplateSettings = normalizeRawInvoiceTemplateSettings;
7
12
  var _dayjs = _interopRequireDefault(require("dayjs"));
8
13
  var _getDateIsInSchedule = require("../Schedule/getDateIsInSchedule");
9
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ function isRecord(value) {
16
+ return !!value && typeof value === 'object' && !Array.isArray(value);
17
+ }
18
+ function parseInvoiceRecord(value) {
19
+ let parsed = value;
20
+ if (typeof parsed === 'string') {
21
+ try {
22
+ parsed = JSON.parse(parsed);
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+ return isRecord(parsed) ? parsed : null;
28
+ }
29
+ function getDefaultInvoiceLayoutConfig() {
30
+ return {
31
+ module: []
32
+ };
33
+ }
34
+ function getDefaultInvoiceTemplateSettings() {
35
+ return {
36
+ template: 'DEFAULT',
37
+ language: {},
38
+ modules: []
39
+ };
40
+ }
41
+ function normalizeInvoiceTemplate(value) {
42
+ if (typeof value !== 'string' || value.trim().length === 0) return 'DEFAULT';
43
+ return value.trim().toUpperCase() === 'DEFAULT' ? 'DEFAULT' : value;
44
+ }
45
+ function normalizeInvoiceLanguage(value) {
46
+ if (!isRecord(value)) return {};
47
+ if (Object.values(value).some(item => typeof item !== 'number')) return {};
48
+ return {
49
+ ...value
50
+ };
51
+ }
52
+ function normalizeInvoiceModules(value) {
53
+ if (!Array.isArray(value)) return [];
54
+ if (value.some(item => !isRecord(item) || typeof item.key !== 'string')) {
55
+ return [];
56
+ }
57
+ return value.map(item => ({
58
+ ...item
59
+ }));
60
+ }
61
+
62
+ /**
63
+ * 规范化已经提取出的公开 template_settings 值,供打印入口复用。
64
+ */
65
+ function normalizeRawInvoiceTemplateSettings(value) {
66
+ const parsed = parseInvoiceRecord(value);
67
+ if (!parsed) return getDefaultInvoiceTemplateSettings();
68
+ return {
69
+ ...parsed,
70
+ template: normalizeInvoiceTemplate(parsed.template),
71
+ language: normalizeInvoiceLanguage(parsed.language),
72
+ modules: normalizeInvoiceModules(parsed.modules)
73
+ };
74
+ }
75
+
76
+ /**
77
+ * 从 OpenData Documents section 的两个扁平字段中构造 Native Invoice 配置。
78
+ */
79
+ function normalizeInvoiceTemplateSettings(config) {
80
+ const parsedEdit = parseInvoiceRecord(config?.['documents.invoice_edit']);
81
+ return normalizeRawInvoiceTemplateSettings({
82
+ ...(parsedEdit ?? {}),
83
+ template: normalizeInvoiceTemplate(config?.['documents.invoice_template'])
84
+ });
85
+ }
86
+
87
+ /**
88
+ * 将 invoice_edit.modules 原样投影为 Web Invoice 使用的 module 字段。
89
+ */
90
+ function normalizeInvoiceLayoutConfig(config) {
91
+ return {
92
+ module: normalizeInvoiceTemplateSettings(config).modules
93
+ };
94
+ }
10
95
  function toBoolean(value) {
11
96
  if (typeof value === 'boolean') return value;
12
97
  if (typeof value === 'string') return value === 'true' || value === '1';
@@ -182,6 +182,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
182
182
  private calculateOrderPaidPaymentTotal;
183
183
  private getDepositAmount;
184
184
  private normalizeDepositAmount;
185
+ private normalizeDepositFlag;
186
+ private getHistoricalDepositSnapshot;
185
187
  private getLastOrderDepositSnapshot;
186
188
  private getLastOrderSubmitSnapshot;
187
189
  private applyDepositAmountToSummary;
@@ -526,7 +528,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
526
528
  generateIdempotencyToken(): string;
527
529
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
528
530
  createOrder(params: CommitOrderParams['query']): {
529
- type: "appointment_booking" | "virtual";
531
+ type: "virtual" | "appointment_booking";
530
532
  platform: string;
531
533
  sales_channel: string;
532
534
  order_sales_channel: string;
@@ -1044,19 +1044,26 @@ class OrderModule extends _BaseModule.BaseModule {
1044
1044
  normalizeDepositAmount(amount) {
1045
1045
  return _decimal.default.max(new _decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
1046
1046
  }
1047
- getLastOrderDepositSnapshot() {
1048
- const lastOrderInfo = this.store.lastOrderInfo;
1049
- if (!lastOrderInfo || typeof lastOrderInfo !== 'object') return null;
1050
- const rawDepositAmount = lastOrderInfo.deposit_amount ?? lastOrderInfo.summary?.deposit_amount;
1047
+ normalizeDepositFlag(value) {
1048
+ if (value === 0 || value === '0') return 0;
1049
+ if (value === 1 || value === '1') return 1;
1050
+ return null;
1051
+ }
1052
+ getHistoricalDepositSnapshot(source) {
1053
+ if (!source || typeof source !== 'object') return null;
1054
+ const record = source;
1055
+ const rawDepositAmount = record.deposit_amount ?? record.summary?.deposit_amount;
1051
1056
  const depositAmount = this.normalizeDepositAmount(rawDepositAmount ?? 0);
1052
- const hasDepositAmount = new _decimal.default(depositAmount).gt(0);
1053
- const isDeposit = Number(lastOrderInfo.is_deposit) === 1 || hasDepositAmount;
1054
- if (!isDeposit || !hasDepositAmount) return null;
1057
+ if (!new _decimal.default(depositAmount).gt(0)) return null;
1055
1058
  return {
1056
- isDeposit: 1,
1059
+ // 兼容历史数据:旧快照缺少 is_deposit 时,沿用正定金金额的推导规则。
1060
+ isDeposit: this.normalizeDepositFlag(record.is_deposit) ?? 1,
1057
1061
  depositAmount
1058
1062
  };
1059
1063
  }
1064
+ getLastOrderDepositSnapshot() {
1065
+ return this.getHistoricalDepositSnapshot(this.store.lastOrderInfo);
1066
+ }
1060
1067
  getLastOrderSubmitSnapshot() {
1061
1068
  const lastOrderInfo = this.store.lastOrderInfo;
1062
1069
  if (!lastOrderInfo || typeof lastOrderInfo !== 'object') return {};
@@ -1104,7 +1111,7 @@ class OrderModule extends _BaseModule.BaseModule {
1104
1111
  }
1105
1112
  };
1106
1113
  tempOrder.deposit_amount = snapshot.depositAmount;
1107
- tempOrder.is_deposit = tempOrder.is_deposit === 0 && new _decimal.default(tempOrder.deposit_amount || 0).gt(0) ? 0 : snapshot.isDeposit;
1114
+ tempOrder.is_deposit = snapshot.isDeposit;
1108
1115
  return nextSummary;
1109
1116
  }
1110
1117
  isDepositOrder(tempOrder, depositAmount) {
@@ -1641,10 +1648,17 @@ class OrderModule extends _BaseModule.BaseModule {
1641
1648
  ...(0, _lodashEs.cloneDeep)(snapshot.summary || {})
1642
1649
  };
1643
1650
  const shouldUseManualDepositOverride = Boolean(manualDepositOverride && manualDepositOverride.productStructuralFingerprint === this.buildOrderProductsStructuralFingerprint(tempOrder.products));
1651
+ const historicalDepositSnapshot = this.getHistoricalDepositSnapshot(snapshot);
1644
1652
  if (shouldUseManualDepositOverride) {
1645
1653
  summary = this.applyDepositAmountToSummary(tempOrder, summary, manualDepositOverride.amount);
1646
- } else if (manualDepositOverride) {
1647
- this.clearManualDepositOverride(tempOrder);
1654
+ } else {
1655
+ if (manualDepositOverride) {
1656
+ this.clearManualDepositOverride(tempOrder);
1657
+ }
1658
+ if (historicalDepositSnapshot) {
1659
+ summary = this.applyDepositAmountToSummary(tempOrder, summary, historicalDepositSnapshot.depositAmount);
1660
+ tempOrder.is_deposit = historicalDepositSnapshot.isDeposit;
1661
+ }
1648
1662
  }
1649
1663
  const isPayableAmountUnchanged = this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary);
1650
1664
  if (!isPayableAmountUnchanged) return null;
@@ -1661,8 +1675,8 @@ class OrderModule extends _BaseModule.BaseModule {
1661
1675
  tempOrder.surcharges = (0, _lodashEs.cloneDeep)(snapshot.surcharges);
1662
1676
  }
1663
1677
  tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
1664
- tempOrder.deposit_amount = summary.deposit_amount || '0.00';
1665
- tempOrder.is_deposit = summary.deposit_amount !== '0.00' ? 1 : 0;
1678
+ tempOrder.deposit_amount = this.normalizeDepositAmount(summary.deposit_amount || 0);
1679
+ tempOrder.is_deposit = shouldUseManualDepositOverride ? new _decimal.default(tempOrder.deposit_amount).gt(0) ? 1 : 0 : historicalDepositSnapshot?.isDeposit ?? (new _decimal.default(tempOrder.deposit_amount).gt(0) ? 1 : 0);
1666
1680
  const previousSummary = this.store.summary;
1667
1681
  this.store.summary = summary;
1668
1682
  this.updateTempOrderPaymentStatus(tempOrder, {
@@ -2120,7 +2134,7 @@ class OrderModule extends _BaseModule.BaseModule {
2120
2134
  const isExistingDepositDisabled = tempOrder.is_deposit === 0 && new _decimal.default(tempOrder.deposit_amount || 0).gt(0);
2121
2135
  tempOrder.deposit_amount = depositAmount;
2122
2136
  tempOrder.is_deposit = hasDepositAmount && !isExistingDepositDisabled ? 1 : 0;
2123
- return this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
2137
+ return shouldUseManualDepositOverride ? nextSummary : this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
2124
2138
  }
2125
2139
  async recalculateSummary(options) {
2126
2140
  const tempOrder = options?.createIfMissing ? this.ensureTempOrder() : this.store.tempOrder;
@@ -3971,6 +3985,13 @@ class OrderModule extends _BaseModule.BaseModule {
3971
3985
  }
3972
3986
  this.store.syncState = 'submitting';
3973
3987
  const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(tempOrder, effectivePayments);
3988
+ const enhancePayload = (payload, ctx) => {
3989
+ const enhancedPayload = params.enhancePayload ? params.enhancePayload(payload, ctx) : payload;
3990
+ return {
3991
+ ...enhancedPayload,
3992
+ request_unique_idempotency_token: paymentSyncIdempotencyToken
3993
+ };
3994
+ };
3974
3995
  const submitParams = {
3975
3996
  payments: effectivePayments,
3976
3997
  paymentStatus,
@@ -3978,13 +3999,7 @@ class OrderModule extends _BaseModule.BaseModule {
3978
3999
  businessCode: params.businessCode,
3979
4000
  channel: params.channel,
3980
4001
  confirmPendingVoucherPayments: true,
3981
- enhancePayload: payload => {
3982
- const nextPayload = {
3983
- ...payload,
3984
- request_unique_idempotency_token: paymentSyncIdempotencyToken
3985
- };
3986
- return nextPayload;
3987
- }
4002
+ enhancePayload
3988
4003
  };
3989
4004
  const submitResult = params.checkoutSyncTaskEnabled === false ? await this.submitTempOrderAsync(submitParams) : await this.submitTempOrder(submitParams);
3990
4005
  return {
@@ -4363,6 +4378,7 @@ class OrderModule extends _BaseModule.BaseModule {
4363
4378
  externalSaleNumber: nextTempOrder.external_sale_number
4364
4379
  };
4365
4380
  const rawSummary = raw.summary && typeof raw.summary === 'object' ? raw.summary : {};
4381
+ const historicalDepositSnapshot = this.getHistoricalDepositSnapshot(sourceLastOrderInfo);
4366
4382
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map(s => ({
4367
4383
  ...(s || {})
4368
4384
  })) : (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []);
@@ -4381,6 +4397,10 @@ class OrderModule extends _BaseModule.BaseModule {
4381
4397
  surcharges: (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []),
4382
4398
  shop_discount: nextTempOrder.shop_discount || '0.00',
4383
4399
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || []),
4400
+ ...(historicalDepositSnapshot ? {
4401
+ is_deposit: historicalDepositSnapshot.isDeposit,
4402
+ deposit_amount: historicalDepositSnapshot.depositAmount
4403
+ } : {}),
4384
4404
  // merged record 的 summary 仍是远端旧值,保留快照仅用于完整重算的价格清理基线。
4385
4405
  ...(isMergedSalesDetailHydrate ? {
4386
4406
  requiresFullSummaryRecalculation: true
@@ -157,11 +157,13 @@ export interface OrderCustomerPatch {
157
157
  * 下单客户变更事件 payload。
158
158
  * - `patch`:tempOrder 上的协议字段视图(会随订单提交)
159
159
  * - `snapshot`:UI 富字段快照(仅本地,不随订单提交)
160
+ * - `source`:缺省表示真实业务变更;`detailHydrate` 仅表示打开详情时快照已就绪
160
161
  * 清空时整个 payload 为 null。
161
162
  */
162
163
  export interface OrderCustomerChangePayload {
163
164
  patch: OrderCustomerView;
164
165
  snapshot: ICustomer | null;
166
+ source?: 'detailHydrate';
165
167
  }
166
168
  export interface OrderScanCodeResult {
167
169
  isAvailable: boolean;
@@ -612,6 +614,7 @@ export interface SyncPaymentsToOrderParams {
612
614
  businessCode?: string;
613
615
  channel?: string;
614
616
  confirmPendingVoucherPayments?: boolean;
617
+ enhancePayload?: SubmitPayloadEnhancer;
615
618
  }
616
619
  export interface SyncPaymentsToOrderResult<T = any> {
617
620
  isFullyPaid: boolean;
@@ -56,6 +56,7 @@ let OrderHooks = exports.OrderHooks = /*#__PURE__*/function (OrderHooks) {
56
56
  * 下单客户变更事件 payload。
57
57
  * - `patch`:tempOrder 上的协议字段视图(会随订单提交)
58
58
  * - `snapshot`:UI 富字段快照(仅本地,不随订单提交)
59
+ * - `source`:缺省表示真实业务变更;`detailHydrate` 仅表示打开详情时快照已就绪
59
60
  * 清空时整个 payload 为 null。
60
61
  */
61
62
  /**
@@ -202,23 +202,26 @@ class ProductList extends _BaseModule.BaseModule {
202
202
  strategy_context
203
203
  };
204
204
  const handledByOsServer = this.isProductQueryHandledByOsServer();
205
- const callback = !handledByOsServer && typeof options?.callback === 'function' ? result => {
205
+ const originalCallback = options?.callback;
206
+ const subscriptionCallback = originalCallback ? async result => {
206
207
  const callbackList = result?.data?.list;
207
208
  if (!Array.isArray(callbackList)) {
208
- options.callback?.(result);
209
+ originalCallback(result);
209
210
  return;
210
211
  }
211
- options.callback?.({
212
+ const resolvedCallbackList = this.resolveClientDataVariants(callbackList, queryPayload, handledByOsServer);
213
+ await this.addProduct(resolvedCallbackList);
214
+ originalCallback(resolvedCallbackList === callbackList ? result : {
212
215
  ...result,
213
216
  data: {
214
217
  ...result.data,
215
- list: this.resolveClientDataVariants(callbackList, queryPayload, false)
218
+ list: resolvedCallbackList
216
219
  }
217
220
  });
218
- } : options?.callback;
221
+ } : undefined;
219
222
  const productsData = await this.request.post(`/product/query`, queryPayload, {
220
223
  osServer: true,
221
- callback,
224
+ callback: subscriptionCallback,
222
225
  subscriberId: options?.subscriberId,
223
226
  customToast: () => {}
224
227
  });
@@ -1961,7 +1961,7 @@ class RulesModule extends _BaseModule.BaseModule {
1961
1961
  // 套餐适用范围配置
1962
1962
  const packageScope = usageRules?.package_scope;
1963
1963
  const {
1964
- type: scopeType,
1964
+ type: scopeType = 'product_all',
1965
1965
  exclude_bundle_product_ids = [],
1966
1966
  include_bundle_product_ids = [],
1967
1967
  filter = 0
@@ -1969,6 +1969,8 @@ class RulesModule extends _BaseModule.BaseModule {
1969
1969
  const isMainProduct = flatItem.type === 'main'; // 单独购买
1970
1970
  const isBundleItem = flatItem.type === 'bundle'; // 套餐中购买
1971
1971
  const bundleMainProductId = flatItem.product?.product_id;
1972
+ // 主商品id
1973
+ const mainProductId = flatItem?.originProduct?._productOrigin?.id || flatItem?.parentProduct?.id || 0;
1972
1974
 
1973
1975
  // 主商品直接可用
1974
1976
  if (isMainProduct) {
@@ -1985,7 +1987,7 @@ class RulesModule extends _BaseModule.BaseModule {
1985
1987
  const priceType = flatItem.bundleItem?.price_type;
1986
1988
  const priceTypeExt = flatItem.bundleItem?.price_type_ext;
1987
1989
  // 主商品id
1988
- const mainProductId = flatItem?.originProduct?._productOrigin?.id || flatItem?.parentProduct?.id || 0;
1990
+ // const mainProductId = flatItem?.originProduct?._productOrigin?.id || flatItem?.parentProduct?.id || 0;
1989
1991
  // original_price 对应:
1990
1992
  // 1. price_type: "markup" && price_type_ext: "product_price"
1991
1993
  // markup_price 对应:
@@ -2010,13 +2012,13 @@ class RulesModule extends _BaseModule.BaseModule {
2010
2012
  if (!filter) {
2011
2013
  isScopeValid = true;
2012
2014
  } else {
2013
- isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
2015
+ isScopeValid = !exclude_bundle_product_ids.includes(Number(mainProductId));
2014
2016
  }
2015
2017
  }
2016
2018
 
2017
2019
  // 包含套餐判断, products值兼容旧数据
2018
2020
  if (scopeType === 'specific_packages' || scopeType === 'products') {
2019
- isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
2021
+ isScopeValid = include_bundle_product_ids.includes(Number(mainProductId));
2020
2022
  }
2021
2023
 
2022
2024
  // 价格和套餐适用范围都符合,则可用
@@ -2078,13 +2080,13 @@ class RulesModule extends _BaseModule.BaseModule {
2078
2080
  if (!filter) {
2079
2081
  isScopeValid = true;
2080
2082
  } else {
2081
- isScopeValid = !exclude_bundle_product_ids.includes(Number(bundleMainProductId));
2083
+ isScopeValid = !exclude_bundle_product_ids.includes(Number(mainProductId));
2082
2084
  }
2083
2085
  }
2084
2086
 
2085
2087
  // 包含套餐判断, products值兼容旧数据
2086
2088
  if (scopeType === 'specific_packages' || scopeType === 'products') {
2087
- isScopeValid = include_bundle_product_ids.includes(Number(bundleMainProductId));
2089
+ isScopeValid = include_bundle_product_ids.includes(Number(mainProductId));
2088
2090
  }
2089
2091
 
2090
2092
  // 价格和套餐适用范围都符合,则可用
@@ -134,7 +134,9 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
134
134
  await this.getSurchargeList(summaryChannel);
135
135
  }
136
136
  const taxConfig = this.getTaxConfig();
137
- const summarySchedule = this.core.getModule(`${this.name.split('_')[0]}_schedule`);
137
+ const fatherModuleName = this.otherParams?.fatherModule || this.name.replace(/_salesSummary$/, '');
138
+ const scheduleModuleName = `${fatherModuleName}_schedule`;
139
+ const summarySchedule = this.core.getModule(scheduleModuleName);
138
140
  const needScheduleIds = (this.store.surchargeList?.map(item => item.available_schedule_ids)?.flat() || []).filter(id => id !== undefined && id !== null && id !== '');
139
141
  const scheduleList = needScheduleIds.length > 0 ? summarySchedule?.getScheduleListByIds(needScheduleIds) : [];
140
142
  const scheduleById = {};