@pisell/pisellos 2.2.249 → 2.2.251

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 (33) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/Order/index.d.ts +1 -1
  3. package/dist/modules/Order/index.js +97 -91
  4. package/dist/modules/Order/types.d.ts +5 -0
  5. package/dist/server/index.d.ts +21 -0
  6. package/dist/server/index.js +32 -3
  7. package/dist/server/modules/order/index.d.ts +1 -1
  8. package/dist/server/modules/order/index.js +76 -51
  9. package/dist/server/modules/order/types.d.ts +3 -0
  10. package/dist/server/modules/order/utils/filterBookings.js +8 -1
  11. package/dist/server/utils/small-ticket.d.ts +0 -1
  12. package/dist/server/utils/small-ticket.js +12 -15
  13. package/dist/solution/BaseSales/index.js +47 -29
  14. package/dist/solution/BookingByStep/index.d.ts +1 -1
  15. package/dist/solution/BookingTicket/index.d.ts +13 -1
  16. package/dist/solution/BookingTicket/index.js +3 -4
  17. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  18. package/lib/modules/Order/index.d.ts +1 -1
  19. package/lib/modules/Order/index.js +10 -8
  20. package/lib/modules/Order/types.d.ts +5 -0
  21. package/lib/server/index.d.ts +21 -0
  22. package/lib/server/index.js +24 -1
  23. package/lib/server/modules/order/index.d.ts +1 -1
  24. package/lib/server/modules/order/index.js +24 -13
  25. package/lib/server/modules/order/types.d.ts +3 -0
  26. package/lib/server/modules/order/utils/filterBookings.js +6 -1
  27. package/lib/server/utils/small-ticket.d.ts +0 -1
  28. package/lib/server/utils/small-ticket.js +3 -6
  29. package/lib/solution/BaseSales/index.js +14 -7
  30. package/lib/solution/BookingByStep/index.d.ts +1 -1
  31. package/lib/solution/BookingTicket/index.d.ts +13 -1
  32. package/lib/solution/BookingTicket/index.js +0 -1
  33. package/package.json +1 -1
@@ -502,10 +502,9 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
502
502
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
503
503
  while (1) switch (_context6.prev = _context6.next) {
504
504
  case 0:
505
- debugger;
506
- _context6.next = 3;
505
+ _context6.next = 2;
507
506
  return _get(_getPrototypeOf(BookingTicketImpl.prototype), "loadSalesDetail", this).call(this, orderIdOrParams);
508
- case 3:
507
+ case 2:
509
508
  sales = _context6.sent;
510
509
  customerModule = this.store.customer;
511
510
  detailCustomer = sales === null || sales === void 0 ? void 0 : sales.customer;
@@ -534,7 +533,7 @@ export var BookingTicketImpl = /*#__PURE__*/function (_BaseSalesImpl) {
534
533
  // await this.store.order.saveDraft();
535
534
  }
536
535
  return _context6.abrupt("return", sales);
537
- case 12:
536
+ case 11:
538
537
  case "end":
539
538
  return _context6.stop();
540
539
  }
@@ -0,0 +1,49 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/model/strategy/adapter/promotion/index.ts
30
+ var promotion_exports = {};
31
+ __export(promotion_exports, {
32
+ BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
33
+ PromotionAdapter: () => import_adapter.PromotionAdapter,
34
+ PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
35
+ X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
36
+ default: () => import_adapter2.default
37
+ });
38
+ module.exports = __toCommonJS(promotion_exports);
39
+ var import_evaluator = require("./evaluator");
40
+ var import_adapter = require("./adapter");
41
+ var import_adapter2 = __toESM(require("./adapter"));
42
+ var import_examples = require("./examples");
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ BUY_X_GET_Y_FREE_STRATEGY,
46
+ PromotionAdapter,
47
+ PromotionEvaluator,
48
+ X_ITEMS_FOR_Y_PRICE_STRATEGY
49
+ });
@@ -429,7 +429,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
429
429
  generateIdempotencyToken(): string;
430
430
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
431
431
  createOrder(params: CommitOrderParams['query']): {
432
- type: "virtual" | "appointment_booking";
432
+ type: "appointment_booking" | "virtual";
433
433
  platform: string;
434
434
  sales_channel: string;
435
435
  order_sales_channel: string;
@@ -805,9 +805,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
805
805
  return ((_a = result == null ? void 0 : result.data) == null ? void 0 : _a.order_id) ?? (result == null ? void 0 : result.order_id) ?? ((_b = result == null ? void 0 : result.data) == null ? void 0 : _b.id) ?? (result == null ? void 0 : result.id) ?? null;
806
806
  }
807
807
  calculatePaymentEffectiveAmount(payment) {
808
- const amount = new import_decimal.default(payment.amount || 0).minus(new import_decimal.default(payment.service_fee || 0));
808
+ const amount = new import_decimal.default(payment.amount || 0);
809
+ const originAmount = new import_decimal.default(payment.origin_amount ?? payment.amount ?? 0);
810
+ const serviceFee = new import_decimal.default(payment.service_fee || 0);
811
+ const effectiveAmount = serviceFee.gt(0) && amount.eq(originAmount) ? amount.plus(serviceFee) : amount;
809
812
  const rounding = new import_decimal.default(payment.rounding_amount || 0);
810
- return amount.minus(rounding);
813
+ return effectiveAmount.minus(rounding);
811
814
  }
812
815
  calculatePaymentTotal(payments) {
813
816
  return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
@@ -931,8 +934,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
931
934
  if (normalizedStatus !== "refunded" && normalizedStatus !== "partially_refunded") {
932
935
  return false;
933
936
  }
934
- if (params.refundAmount.lte(0))
935
- return false;
936
937
  if (params.previousSummary) {
937
938
  const previousTargetAmount = this.calculatePaymentTargetAmount(
938
939
  params.tempOrder,
@@ -942,10 +943,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
942
943
  if (!previousTargetAmount.eq(params.targetAmount))
943
944
  return false;
944
945
  }
945
- if (normalizedStatus === "refunded") {
946
- return params.refundAmount.gte(params.paymentTotal);
947
- }
948
- return params.netPaymentTotal.gte(params.targetAmount);
946
+ return true;
949
947
  }
950
948
  resolveWalletPassUseValue(payment, amount) {
951
949
  const usageUnit = payment.wallet_pass_usage_unit && typeof payment.wallet_pass_usage_unit === "object" ? payment.wallet_pass_usage_unit : null;
@@ -2560,6 +2558,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2560
2558
  */
2561
2559
  async addProductToOrder(product, booking) {
2562
2560
  const tempOrder = this.ensureTempOrder();
2561
+ debugger;
2563
2562
  if (booking) {
2564
2563
  const productRecord = product;
2565
2564
  const splitCount = (0, import_utils3.getSafeProductNum)(
@@ -3638,6 +3637,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3638
3637
  ...this.createDefaultTempOrderInstance(),
3639
3638
  ...raw || {}
3640
3639
  };
3640
+ if ((nextTempOrder.order_id === void 0 || nextTempOrder.order_id === null) && (raw == null ? void 0 : raw.id) !== void 0 && (raw == null ? void 0 : raw.id) !== null) {
3641
+ nextTempOrder.order_id = raw.id;
3642
+ }
3641
3643
  delete nextTempOrder.summary;
3642
3644
  delete nextTempOrder.lastOrderInfo;
3643
3645
  delete nextTempOrder.discount_list;
@@ -518,6 +518,11 @@ export interface LoadSalesDetailParams {
518
518
  orderNumber?: string;
519
519
  externalSaleNumber?: string;
520
520
  external_sale_number?: string;
521
+ /**
522
+ * 已由调用方查询到的销售详情记录。
523
+ * 存在时 loadSalesDetail 会跳过远端 lookup,直接复用 hydrate 后半段逻辑。
524
+ */
525
+ preloadedSalesDetail?: Record<string, any>;
521
526
  forceRemote?: boolean;
522
527
  merge?: boolean;
523
528
  }
@@ -9,6 +9,20 @@ import { PisellCore, ServerModuleConfig, InitializeServerOptions } from '../type
9
9
  import type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, RequestSetting } from './types';
10
10
  import { OrderModule } from './modules/order';
11
11
  export type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, };
12
+ /** Server 运行时诊断快照,用于排查订阅者是否持续增长。 */
13
+ export interface ServerDiagnosticsSnapshot {
14
+ subscribers: {
15
+ productQuerySubscribers: number;
16
+ orderQuerySubscribers: number;
17
+ bookingQuerySubscribers: number;
18
+ bookingRemoteQuerySubscribers: number;
19
+ salesSearchSubscribers: number;
20
+ floorPlanQuerySubscribers: number;
21
+ };
22
+ caches: {
23
+ bookingRemoteCache: number;
24
+ };
25
+ }
12
26
  /**
13
27
  * Server 类
14
28
  * 用于注册和管理服务端模块
@@ -44,6 +58,13 @@ declare class Server {
44
58
  private floorPlanQuerySubscribers;
45
59
  private moduleRegistry;
46
60
  constructor(core: PisellCore);
61
+ /**
62
+ * 获取 Server 内部订阅者和缓存数量快照。
63
+ *
64
+ * @example
65
+ * const snapshot = pisellos.server?.getDiagnosticsSnapshot?.();
66
+ */
67
+ getDiagnosticsSnapshot(): ServerDiagnosticsSnapshot;
47
68
  /**
48
69
  * 注册路由
49
70
  * @param routes 路由定义数组
@@ -756,7 +756,7 @@ var Server = class {
756
756
  this.handleFloorPlanGet = async ({ url, data, config, path: routePath }) => {
757
757
  const base = "/shop/schedule/floor-plan";
758
758
  const path = this.parseRequestPath(url, routePath);
759
- if (path === `${base}/unsubscribe`) {
759
+ if (path === `${base}/unsubscribe` || path === `${base}/code/unsubscribe`) {
760
760
  const subscriberId2 = data == null ? void 0 : data.subscriberId;
761
761
  if (subscriberId2) {
762
762
  this.floorPlanQuerySubscribers.delete(subscriberId2);
@@ -905,6 +905,27 @@ var Server = class {
905
905
  hasLogger: !!this.logger
906
906
  });
907
907
  }
908
+ /**
909
+ * 获取 Server 内部订阅者和缓存数量快照。
910
+ *
911
+ * @example
912
+ * const snapshot = pisellos.server?.getDiagnosticsSnapshot?.();
913
+ */
914
+ getDiagnosticsSnapshot() {
915
+ return {
916
+ subscribers: {
917
+ productQuerySubscribers: this.productQuerySubscribers.size,
918
+ orderQuerySubscribers: this.orderQuerySubscribers.size,
919
+ bookingQuerySubscribers: this.bookingQuerySubscribers.size,
920
+ bookingRemoteQuerySubscribers: this.bookingRemoteQuerySubscribers.size,
921
+ salesSearchSubscribers: this.salesSearchSubscribers.size,
922
+ floorPlanQuerySubscribers: this.floorPlanQuerySubscribers.size
923
+ },
924
+ caches: {
925
+ bookingRemoteCache: this.bookingRemoteCache.size
926
+ }
927
+ };
928
+ }
908
929
  /**
909
930
  * 注册路由
910
931
  * @param routes 路由定义数组
@@ -4048,6 +4069,8 @@ var Server = class {
4048
4069
  if (changedOrders.length === 0) {
4049
4070
  return;
4050
4071
  }
4072
+ if (window.isPaymentModalPluginOpen)
4073
+ return;
4051
4074
  for (const [subscriberId, subscriber] of this.salesSearchSubscribers.entries()) {
4052
4075
  try {
4053
4076
  const changedVisibleOrders = changedOrders.filter((order) => {
@@ -193,7 +193,7 @@ export declare class OrderModule extends BaseModule implements Module {
193
193
  private findOrderIndexByIdentity;
194
194
  private getOrderCompletenessScore;
195
195
  private pickPreferredOrder;
196
- private getProductMergeKey;
196
+ private getProductIdentityKeys;
197
197
  private mergeOrderProductLists;
198
198
  private getPaymentMergeKey;
199
199
  private mergeOrderPaymentLists;
@@ -1141,24 +1141,25 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1141
1141
  return right;
1142
1142
  return left;
1143
1143
  }
1144
- getProductMergeKey(product) {
1144
+ getProductIdentityKeys(product) {
1145
1145
  var _a;
1146
1146
  const record = product;
1147
1147
  if (!record)
1148
- return "";
1148
+ return [];
1149
+ const keys = [];
1149
1150
  const metadataUid = (_a = record.metadata) == null ? void 0 : _a.unique_identification_number;
1150
1151
  if (!this.isBlankIdentityValue(metadataUid))
1151
- return `uid:${String(metadataUid)}`;
1152
+ keys.push(`uid:${String(metadataUid)}`);
1152
1153
  const topLevelUid = record.unique_identification_number;
1153
1154
  if (!this.isBlankIdentityValue(topLevelUid))
1154
- return `uid:${String(topLevelUid)}`;
1155
+ keys.push(`uid:${String(topLevelUid)}`);
1155
1156
  const orderDetailId = record.order_detail_id;
1156
1157
  if (!this.isBlankIdentityValue(orderDetailId))
1157
- return `detail:${String(orderDetailId)}`;
1158
+ keys.push(`detail:${String(orderDetailId)}`);
1158
1159
  const bookingUid = record.booking_uid;
1159
1160
  if (!this.isBlankIdentityValue(bookingUid))
1160
- return `booking:${String(bookingUid)}`;
1161
- return "";
1161
+ keys.push(`booking:${String(bookingUid)}`);
1162
+ return keys;
1162
1163
  }
1163
1164
  mergeOrderProductLists(preferred, secondary) {
1164
1165
  const preferredList = Array.isArray(preferred) ? preferred : [];
@@ -1169,16 +1170,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1169
1170
  return secondaryList;
1170
1171
  const seenKeys = /* @__PURE__ */ new Set();
1171
1172
  for (const item of preferredList) {
1172
- const key = this.getProductMergeKey(item);
1173
- if (key)
1173
+ const keys = this.getProductIdentityKeys(item);
1174
+ for (const key of keys)
1174
1175
  seenKeys.add(key);
1175
1176
  }
1176
1177
  const result = [...preferredList];
1177
1178
  for (const item of secondaryList) {
1178
- const key = this.getProductMergeKey(item);
1179
- if (!key || seenKeys.has(key))
1179
+ const keys = this.getProductIdentityKeys(item);
1180
+ if (keys.length === 0 || keys.some((key) => seenKeys.has(key)))
1180
1181
  continue;
1181
- seenKeys.add(key);
1182
+ for (const key of keys)
1183
+ seenKeys.add(key);
1182
1184
  result.push((0, import_lodash_es.cloneDeep)(item));
1183
1185
  }
1184
1186
  return result;
@@ -1254,7 +1256,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1254
1256
  "shop_discount",
1255
1257
  "summary",
1256
1258
  "products",
1257
- "bookings"
1259
+ "bookings",
1260
+ "note",
1261
+ "customer_id",
1262
+ "customer_name",
1263
+ "customer",
1264
+ "holder",
1265
+ "contacts_info",
1266
+ "phone",
1267
+ "email",
1268
+ "relation_forms"
1258
1269
  ];
1259
1270
  const mergedRecord = merged;
1260
1271
  const preferredRecord = preferred;
@@ -458,7 +458,10 @@ export interface OrderFilters {
458
458
  * 预约展开列表筛选条件(订单级条件匹配 booking.order.*,预约级匹配 booking 自身)
459
459
  */
460
460
  export interface BookingFilters {
461
+ /** RecordBoard 通用搜索字段(单数),用于本地预约过滤 */
461
462
  keyword?: string;
463
+ /** `/shop/schedule/booking` 后端协议搜索字段(复数),OS Server 需兼容 */
464
+ keywords?: string;
462
465
  order_by?: string;
463
466
  order_payment_status?: string[];
464
467
  order_status?: string[];
@@ -104,9 +104,14 @@ function parseNumberRange(range) {
104
104
  return null;
105
105
  return [min, max];
106
106
  }
107
+ function resolveBookingKeyword(f) {
108
+ const keyword = f.keyword ?? f.keywords;
109
+ return typeof keyword === "string" ? keyword.trim() : "";
110
+ }
107
111
  function prepareFilters(f) {
108
112
  var _a, _b, _c, _d, _e, _f;
109
113
  const hasCustomerId = f.customer_id !== void 0 && f.customer_id !== null;
114
+ const keyword = resolveBookingKeyword(f);
110
115
  return {
111
116
  orderPaymentStatusSet: ((_a = f.order_payment_status) == null ? void 0 : _a.length) ? new Set(f.order_payment_status) : null,
112
117
  orderStatusSet: ((_b = f.order_status) == null ? void 0 : _b.length) ? new Set(f.order_status) : null,
@@ -123,7 +128,7 @@ function prepareFilters(f) {
123
128
  updatedAtRange: parseDateRange(f.updated_at_between),
124
129
  numberRange: parseNumberRange(f.number_between),
125
130
  totalAmountRange: Array.isArray(f.total_amount_between) && f.total_amount_between.length === 2 ? f.total_amount_between : null,
126
- keywordLower: f.keyword ? f.keyword.toLowerCase() : "",
131
+ keywordLower: keyword ? keyword.toLowerCase() : "",
127
132
  afterExecutionTimeMs: (() => {
128
133
  const raw = f.after_execution_time;
129
134
  if (raw === void 0 || raw === null || raw === "")
@@ -35,7 +35,6 @@ export interface SmallTicketProduct {
35
35
  original_price: string;
36
36
  total_original_price: string;
37
37
  extension_list: any[];
38
- discount_list?: any[];
39
38
  options?: Array<{
40
39
  name: string;
41
40
  num?: number;
@@ -200,7 +200,6 @@ function buildProducts(order, locale, productMap) {
200
200
  quantity,
201
201
  originalPrice
202
202
  });
203
- const discountList = normalizeProductDiscounts({ product, locale, currencySymbol, quantity });
204
203
  return {
205
204
  product_title: productTitle,
206
205
  product_quantity: quantity,
@@ -208,7 +207,6 @@ function buildProducts(order, locale, productMap) {
208
207
  original_price: formatMoney(originalPrice, currencySymbol),
209
208
  total_original_price: formatMoney(new import_decimal.default(toMoneyNumber(originalPrice)).mul(quantity), currencySymbol),
210
209
  extension_list: extensionList,
211
- ...discountList.length ? { discount_list: discountList } : {},
212
210
  ...options.length ? { options } : {},
213
211
  ...resolvedVariant ? { variant: resolvedVariant } : {},
214
212
  ...Array.isArray(product.combinations) ? { combinations: product.combinations } : combinations.length ? { combinations } : {}
@@ -222,16 +220,14 @@ function normalizeProductDiscounts(params) {
222
220
  const amount = discount.amount ?? discount.value ?? discount.discount_amount;
223
221
  const formattedAmount = formatNegativeMoney(new import_decimal.default(toMoneyNumber(amount)).mul(quantity), currencySymbol);
224
222
  return {
225
- ...discount,
226
223
  item: title,
227
- name: title,
228
- title,
229
224
  value: formattedAmount
230
225
  };
231
226
  });
232
227
  }
233
228
  function buildProductExtensionList(params) {
234
229
  const { product, locale, currencySymbol, quantity, originalPrice } = params;
230
+ const discountList = normalizeProductDiscounts({ product, locale, currencySymbol, quantity });
235
231
  const extensionList = [
236
232
  ...buildProductOpenWeightRows({ product, locale, currencySymbol }),
237
233
  ...quantity > 1 ? [{
@@ -239,7 +235,8 @@ function buildProductExtensionList(params) {
239
235
  value: ""
240
236
  }] : []
241
237
  ];
242
- return extensionList.length ? extensionList : normalizeArray(product.extension_list);
238
+ const productExtensionList = extensionList.length ? extensionList : normalizeArray(product.extension_list);
239
+ return [...productExtensionList, ...discountList];
243
240
  }
244
241
  function buildProductOpenWeightRows(params) {
245
242
  const { product, locale, currencySymbol } = params;
@@ -596,21 +596,25 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
596
596
  throw new Error("order 模块未初始化");
597
597
  const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
598
598
  const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
599
- const lookup = params.orderId ?? externalSaleNumber ?? params.orderNumber;
600
- if (lookup === void 0 || lookup === null || lookup === "") {
599
+ const preloadedSalesDetail = params.preloadedSalesDetail;
600
+ const lookup = params.orderId ?? externalSaleNumber ?? params.orderNumber ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_id) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.external_sale_number) ?? (preloadedSalesDetail == null ? void 0 : preloadedSalesDetail.order_number);
601
+ if (!preloadedSalesDetail && (lookup === void 0 || lookup === null || lookup === "")) {
601
602
  throw new Error("加载销售详情需要 orderId、externalSaleNumber 或 orderNumber");
602
603
  }
603
- const res = await this.store.order.getSalesOrderByLookup({
604
+ const loadedRecord = preloadedSalesDetail ?? await this.store.order.getSalesOrderByLookup({
604
605
  lookup,
605
606
  forceRemote: params.forceRemote
606
607
  });
607
- if (!res || res.code !== 200) {
608
- const message = res && (res.message || res.msg) || `加载销售详情失败: ${lookup}`;
608
+ if (!preloadedSalesDetail && (!loadedRecord || loadedRecord.code !== 200)) {
609
+ const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
609
610
  throw new Error(message);
610
611
  }
612
+ const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
611
613
  const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
612
- const record = params.merge ? mergeSalesDetailRecordWithTempOrder(currentTempOrder, res.data) : res.data;
613
- const sales = await this.store.order.hydrateTempOrderFromRecord(record, { recalcOnHydrate: false });
614
+ const record = params.merge ? mergeSalesDetailRecordWithTempOrder(currentTempOrder, remoteRecord) : remoteRecord;
615
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
616
+ recalcOnHydrate: false
617
+ });
614
618
  this.currentSalesDetail = sales;
615
619
  await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
616
620
  return sales;
@@ -1465,8 +1469,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1465
1469
  const paymentTimestamp = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1466
1470
  const paymentTime = paymentRecord.payment_time ?? paymentTimestamp;
1467
1471
  const createdAt = paymentRecord.created_at ?? paymentTimestamp;
1472
+ const serviceCharge = paymentRecord.service_charge && typeof paymentRecord.service_charge === "object" ? paymentRecord.service_charge : null;
1473
+ const calculatedServiceFee = serviceCharge ? new import_decimal.default(paymentRecord.origin_amount ?? paymentRecord.amount ?? 0).times(serviceCharge.percentage || 0).plus(serviceCharge.amount || 0).toDecimalPlaces(2).toFixed(2) : void 0;
1468
1474
  const payments = this.store.order.addOrderPayment({
1469
1475
  ...paymentRecord,
1476
+ ...calculatedServiceFee !== void 0 ? { service_fee: calculatedServiceFee } : {},
1470
1477
  metadata,
1471
1478
  payment_time: paymentTime,
1472
1479
  created_at: createdAt
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 2 | 1 | 6 | 3 | 4 | 5;
314
+ weekNum: 0 | 2 | 1 | 5 | 3 | 4 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -441,7 +441,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
441
441
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
442
442
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
443
443
  */
444
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
444
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
445
+ action: "reloadCatalog";
446
+ } | {
447
+ action: "add";
448
+ cacheItem: any;
449
+ } | {
450
+ action: "requiresDetail";
451
+ payload: AddProductRequiresDetailPayload;
452
+ } | {
453
+ action: "requiresBookingEdit";
454
+ cacheItem: any;
455
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
456
+ };
445
457
  /** 规格弹窗 callback 后的第二段决策。 */
446
458
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
447
459
  /**
@@ -307,7 +307,6 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
307
307
  * 让现有 setActiveCustomer / getActiveCustomer 调用方零成本拿到详情态客户。
308
308
  */
309
309
  async loadSalesDetail(orderIdOrParams) {
310
- debugger;
311
310
  const sales = await super.loadSalesDetail(orderIdOrParams);
312
311
  const customerModule = this.store.customer;
313
312
  const detailCustomer = sales == null ? void 0 : sales.customer;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.249",
4
+ "version": "2.2.251",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",