@pisell/pisellos 2.3.95 → 2.3.96

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.
@@ -1,4 +1,3 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
1
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
3
2
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
3
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -6,6 +5,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
6
5
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
6
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8
7
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
9
9
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
10
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
11
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -195,9 +195,120 @@ var I18N_FIELD_MAP = {
195
195
  description_i18n: 'description',
196
196
  cover_i18n: 'cover'
197
197
  };
198
+ /**
199
+ * 按当前语言读取 i18n 文案;当前语言为空时回退到商家原始文案。
200
+ */
201
+ function resolveI18nValue(i18nDict, locale) {
202
+ if (!i18nDict) return undefined;
203
+ return i18nDict[locale] || i18nDict.original || undefined;
204
+ }
205
+
206
+ /**
207
+ * 递归格式化商品分类名称,同时保留未变化节点的引用。
208
+ */
209
+ function applyI18nToCategory(category, locale) {
210
+ if (!category || _typeof(category) !== 'object') return category;
211
+ var localizedName = resolveI18nValue(category.name_i18n, locale);
212
+ var localizedParent = applyI18nToCategory(category.parent_category, locale);
213
+ var nameChanged = localizedName !== undefined && localizedName !== category.name;
214
+ var parentChanged = localizedParent !== category.parent_category;
215
+ if (!nameChanged && !parentChanged) return category;
216
+ return _objectSpread(_objectSpread(_objectSpread({}, category), nameChanged ? {
217
+ name: localizedName
218
+ } : {}), parentChanged ? {
219
+ parent_category: localizedParent
220
+ } : {});
221
+ }
222
+ function applyI18nToCategories(categories, locale) {
223
+ if (!Array.isArray(categories)) return categories;
224
+ var changed = false;
225
+ var localizedCategories = categories.map(function (category) {
226
+ var localizedCategory = applyI18nToCategory(category, locale);
227
+ if (localizedCategory !== category) changed = true;
228
+ return localizedCategory;
229
+ });
230
+ return changed ? localizedCategories : categories;
231
+ }
232
+ function applyI18nToNamedItems(items, locale) {
233
+ if (!Array.isArray(items)) return items;
234
+ var changed = false;
235
+ var localizedItems = items.map(function (item) {
236
+ if (!item || _typeof(item) !== 'object') return item;
237
+ var localizedName = resolveI18nValue(item.name_i18n, locale);
238
+ if (localizedName === undefined || localizedName === item.name) return item;
239
+ changed = true;
240
+ return _objectSpread(_objectSpread({}, item), {}, {
241
+ name: localizedName
242
+ });
243
+ });
244
+ return changed ? localizedItems : items;
245
+ }
246
+
247
+ /**
248
+ * 格式化选项组、规格组及其子项名称,同时保留未变化节点的引用。
249
+ */
250
+ function applyI18nToNamedGroups(groups, itemKey, locale) {
251
+ if (!Array.isArray(groups)) return groups;
252
+ var changed = false;
253
+ var localizedGroups = groups.map(function (group) {
254
+ if (!group || _typeof(group) !== 'object') return group;
255
+ var localizedName = resolveI18nValue(group.name_i18n, locale);
256
+ var localizedItems = applyI18nToNamedItems(group[itemKey], locale);
257
+ var nameChanged = localizedName !== undefined && localizedName !== group.name;
258
+ var itemsChanged = localizedItems !== group[itemKey];
259
+ if (!nameChanged && !itemsChanged) return group;
260
+ changed = true;
261
+ return _objectSpread(_objectSpread(_objectSpread({}, group), nameChanged ? {
262
+ name: localizedName
263
+ } : {}), itemsChanged ? _defineProperty({}, itemKey, localizedItems) : {});
264
+ });
265
+ return changed ? localizedGroups : groups;
266
+ }
267
+ function applyI18nToBundleItems(items, locale) {
268
+ if (!Array.isArray(items)) return items;
269
+ var changed = false;
270
+ var localizedItems = items.map(function (item) {
271
+ if (!item || _typeof(item) !== 'object') return item;
272
+ var localizedTitle = resolveI18nValue(item.trans_title, locale);
273
+ var localizedOptionGroups = applyI18nToNamedGroups(item.option_group, 'option_item', locale);
274
+ var titleChanged = localizedTitle !== undefined && localizedTitle !== item.title;
275
+ var optionGroupsChanged = localizedOptionGroups !== item.option_group;
276
+ if (!titleChanged && !optionGroupsChanged) return item;
277
+ changed = true;
278
+ return _objectSpread(_objectSpread(_objectSpread({}, item), titleChanged ? {
279
+ title: localizedTitle
280
+ } : {}), optionGroupsChanged ? {
281
+ option_group: localizedOptionGroups
282
+ } : {});
283
+ });
284
+ return changed ? localizedItems : items;
285
+ }
198
286
 
199
287
  /**
200
- * 根据 locale 将商品的 i18n 字段覆盖到对应原始字段
288
+ * 格式化套餐组名称、套餐子商品标题及子商品选项,同时保留未变化节点的引用。
289
+ */
290
+ function applyI18nToBundleGroups(groups, locale) {
291
+ if (!Array.isArray(groups)) return groups;
292
+ var changed = false;
293
+ var localizedGroups = groups.map(function (group) {
294
+ if (!group || _typeof(group) !== 'object') return group;
295
+ var localizedName = resolveI18nValue(group.name_i18n, locale);
296
+ var localizedItems = applyI18nToBundleItems(group.bundle_item, locale);
297
+ var nameChanged = localizedName !== undefined && localizedName !== group.name;
298
+ var itemsChanged = localizedItems !== group.bundle_item;
299
+ if (!nameChanged && !itemsChanged) return group;
300
+ changed = true;
301
+ return _objectSpread(_objectSpread(_objectSpread({}, group), nameChanged ? {
302
+ name: localizedName
303
+ } : {}), itemsChanged ? {
304
+ bundle_item: localizedItems
305
+ } : {});
306
+ });
307
+ return changed ? localizedGroups : groups;
308
+ }
309
+
310
+ /**
311
+ * 根据 locale 格式化商品、分类、规格及套餐文案,缺少对应语言时回退 original。
201
312
  */
202
313
  export function applyI18nToProducts(products, locale) {
203
314
  if (!locale) return products;
@@ -210,12 +321,65 @@ export function applyI18nToProducts(products, locale) {
210
321
  originalKey = _Object$entries$_i[1];
211
322
  var i18nDict = product[i18nKey];
212
323
  if (!i18nDict) continue;
213
- var localizedValue = i18nDict[locale];
214
- if (localizedValue) {
324
+ var localizedValue = resolveI18nValue(i18nDict, locale);
325
+ if (localizedValue !== undefined && localizedValue !== product[originalKey]) {
215
326
  if (!patched) patched = _objectSpread({}, product);
216
327
  patched[originalKey] = localizedValue;
217
328
  }
218
329
  }
330
+ var _iterator = _createForOfIteratorHelper(['category', 'categories']),
331
+ _step;
332
+ try {
333
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
334
+ var categoryKey = _step.value;
335
+ var categories = product[categoryKey];
336
+ var localizedCategories = applyI18nToCategories(categories, locale);
337
+ if (localizedCategories !== categories) {
338
+ if (!patched) patched = _objectSpread({}, product);
339
+ patched[categoryKey] = localizedCategories;
340
+ }
341
+ }
342
+ } catch (err) {
343
+ _iterator.e(err);
344
+ } finally {
345
+ _iterator.f();
346
+ }
347
+ var _iterator2 = _createForOfIteratorHelper([['option_group', 'option_item'], ['variant_group', 'variant_item']]),
348
+ _step2;
349
+ try {
350
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
351
+ var _step2$value = _slicedToArray(_step2.value, 2),
352
+ groupKey = _step2$value[0],
353
+ itemKey = _step2$value[1];
354
+ var groups = product[groupKey];
355
+ var localizedGroups = applyI18nToNamedGroups(groups, itemKey, locale);
356
+ if (localizedGroups !== groups) {
357
+ if (!patched) patched = _objectSpread({}, product);
358
+ patched[groupKey] = localizedGroups;
359
+ }
360
+ }
361
+ } catch (err) {
362
+ _iterator2.e(err);
363
+ } finally {
364
+ _iterator2.f();
365
+ }
366
+ var _iterator3 = _createForOfIteratorHelper(['bundle_group', 'bundle_groups']),
367
+ _step3;
368
+ try {
369
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
370
+ var bundleGroupKey = _step3.value;
371
+ var _groups = product[bundleGroupKey];
372
+ var _localizedGroups = applyI18nToBundleGroups(_groups, locale);
373
+ if (_localizedGroups !== _groups) {
374
+ if (!patched) patched = _objectSpread({}, product);
375
+ patched[bundleGroupKey] = _localizedGroups;
376
+ }
377
+ }
378
+ } catch (err) {
379
+ _iterator3.e(err);
380
+ } finally {
381
+ _iterator3.f();
382
+ }
219
383
  return (_patched = patched) !== null && _patched !== void 0 ? _patched : product;
220
384
  });
221
385
  }
@@ -234,54 +398,54 @@ var formatDataKey = function formatDataKey(data) {
234
398
 
235
399
  // 单规格
236
400
  if (_data !== null && _data !== void 0 && (_data$option = _data.option) !== null && _data$option !== void 0 && _data$option.length) {
237
- var _iterator = _createForOfIteratorHelper(_data.option),
238
- _step;
401
+ var _iterator4 = _createForOfIteratorHelper(_data.option),
402
+ _step4;
239
403
  try {
240
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
241
- var item = _step.value;
404
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
405
+ var item = _step4.value;
242
406
  var _str = "_".concat(item.option_group_id, "_").concat(item.option_group_item_id);
243
407
  key += _str;
244
408
  rowKey += "".concat(_str, "_").concat(item.quantity || item.num);
245
409
  }
246
410
  } catch (err) {
247
- _iterator.e(err);
411
+ _iterator4.e(err);
248
412
  } finally {
249
- _iterator.f();
413
+ _iterator4.f();
250
414
  }
251
415
  }
252
416
 
253
417
  // 套餐
254
418
  if (_data !== null && _data !== void 0 && (_data$bundle = _data.bundle) !== null && _data$bundle !== void 0 && _data$bundle.length) {
255
- var _iterator2 = _createForOfIteratorHelper(_data.bundle),
256
- _step2;
419
+ var _iterator5 = _createForOfIteratorHelper(_data.bundle),
420
+ _step5;
257
421
  try {
258
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
259
- var _item = _step2.value;
422
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
423
+ var _item = _step5.value;
260
424
  var _str2 = "_".concat(_item.group_id, "_").concat(_item.bundle_product_id);
261
425
  key += _str2;
262
426
  rowKey += "".concat(_str2, "_").concat(_item.quantity || _item.num);
263
427
  // 如果有单规格
264
428
  if (_item !== null && _item !== void 0 && _item.option) {
265
- var _iterator3 = _createForOfIteratorHelper(_item.option),
266
- _step3;
429
+ var _iterator6 = _createForOfIteratorHelper(_item.option),
430
+ _step6;
267
431
  try {
268
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
269
- var opt = _step3.value;
432
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
433
+ var opt = _step6.value;
270
434
  var _str3 = "_".concat(opt.option_group_id, "_").concat(opt.option_group_item_id);
271
435
  key += _str3;
272
436
  rowKey += "".concat(_str3, "_").concat(opt.quantity || opt.num);
273
437
  }
274
438
  } catch (err) {
275
- _iterator3.e(err);
439
+ _iterator6.e(err);
276
440
  } finally {
277
- _iterator3.f();
441
+ _iterator6.f();
278
442
  }
279
443
  }
280
444
  }
281
445
  } catch (err) {
282
- _iterator2.e(err);
446
+ _iterator5.e(err);
283
447
  } finally {
284
- _iterator2.f();
448
+ _iterator5.f();
285
449
  }
286
450
  }
287
451
 
@@ -40,6 +40,7 @@ var LABELS = {
40
40
  orderDiscount: 'Order discount',
41
41
  manualDiscount: 'Manual discount',
42
42
  payProcessingFee: 'Pay processing fee',
43
+ surchargeIncluded: 'Surcharge(Included)',
43
44
  rounding: 'Rounding',
44
45
  gross: 'Gross',
45
46
  tare: 'Tare'
@@ -66,6 +67,7 @@ var LABELS = {
66
67
  orderDiscount: '整单折扣',
67
68
  manualDiscount: '手动折扣',
68
69
  payProcessingFee: '支付手续费',
70
+ surchargeIncluded: '手续费(已含)',
69
71
  rounding: '抹零',
70
72
  gross: '重量',
71
73
  tare: '去皮'
@@ -92,6 +94,7 @@ var LABELS = {
92
94
  orderDiscount: '整單折扣',
93
95
  manualDiscount: '手動折扣',
94
96
  payProcessingFee: '支付手續費',
97
+ surchargeIncluded: '手續費(已含)',
95
98
  rounding: '抹零',
96
99
  gross: '重量',
97
100
  tare: '去皮'
@@ -760,11 +763,17 @@ function buildPaymentData(params) {
760
763
  return payments.filter(function (payment) {
761
764
  return isPrintablePayment(payment);
762
765
  }).map(function (payment) {
763
- var _payment$amount;
766
+ var serviceFee = getPaymentServiceFee(payment);
764
767
  var items = [{
765
768
  item: paymentMethodName(payment, params.locale),
766
- value: formatMoney((_payment$amount = payment.amount) !== null && _payment$amount !== void 0 ? _payment$amount : payment.origin_amount, params.currencySymbol)
769
+ value: formatMoney(resolveReceiptPaymentAmount(payment, serviceFee), params.currencySymbol)
767
770
  }];
771
+ if (serviceFee.gt(0)) {
772
+ items.push({
773
+ item: label(params.locale, 'surchargeIncluded'),
774
+ value: formatMoney(serviceFee, params.currencySymbol)
775
+ });
776
+ }
768
777
  var fundRecord = getFundRecord(payment);
769
778
  if (fundRecord) {
770
779
  items.push.apply(items, _toConsumableArray(buildFundRecordPaymentItems({
@@ -790,6 +799,18 @@ function buildPaymentData(params) {
790
799
  return items;
791
800
  });
792
801
  }
802
+ function getPaymentServiceFee(payment) {
803
+ return new Decimal(toMoneyNumber(payment.service_fee));
804
+ }
805
+ function resolveReceiptPaymentAmount(payment, serviceFee) {
806
+ var _payment$amount;
807
+ var amount = new Decimal(toMoneyNumber((_payment$amount = payment.amount) !== null && _payment$amount !== void 0 ? _payment$amount : payment.origin_amount));
808
+ var hasAmount = payment.amount !== undefined && payment.amount !== null && payment.amount !== '';
809
+ var hasOriginAmount = payment.origin_amount !== undefined && payment.origin_amount !== null && payment.origin_amount !== '';
810
+ if (!hasAmount || !hasOriginAmount || serviceFee.lte(0)) return amount;
811
+ var originAmount = new Decimal(toMoneyNumber(payment.origin_amount));
812
+ return amount.eq(originAmount) ? amount.plus(serviceFee) : amount;
813
+ }
793
814
  function buildFundRecordPaymentItems(params) {
794
815
  var payment = params.payment,
795
816
  fundRecord = params.fundRecord,
@@ -197,8 +197,9 @@ export function transformBaseProductToOrderProduct(params) {
197
197
  metadata.unique_identification_number = String(uniqueIdentificationNumber);
198
198
  }
199
199
  // 从源头补充商品多语言标题
200
- var productTitle = _objectSpread(_objectSpread({}, (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title_i18n) || {}), {}, {
201
- original: (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.original_title) || (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
200
+ var productTitleI18n = (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title_i18n) || {};
201
+ var productTitle = _objectSpread(_objectSpread({}, productTitleI18n), {}, {
202
+ original: productTitleI18n.original || (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.original_title) || (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
202
203
  });
203
204
  return _objectSpread(_objectSpread({
204
205
  product_id: productId,
@@ -234,15 +234,25 @@ class DataVariantEvaluator {
234
234
  if (!appliedInfo?.appliedFields?.length) {
235
235
  return originalItem;
236
236
  }
237
+
238
+ // 套餐加价/减价使用配置价;仅商品原价模式跟随子商品的 Data Variant 价格。
239
+ const isOriginalPriceBundleItem = originalItem.price_type === 'markup' && originalItem.price_type_ext === 'product_price';
240
+ const appliedFields = appliedInfo.appliedFields.filter(field => field !== 'price' || isOriginalPriceBundleItem);
241
+ if (!appliedFields.length) {
242
+ return originalItem;
243
+ }
237
244
  const result = {
238
245
  ...originalItem
239
246
  };
240
- for (const field of appliedInfo.appliedFields) {
247
+ for (const field of appliedFields) {
241
248
  if (resolvedItem[field] !== undefined) {
242
249
  result[field] = resolvedItem[field];
243
250
  }
244
251
  }
245
- result._dataVariant = appliedInfo;
252
+ result._dataVariant = {
253
+ ...appliedInfo,
254
+ appliedFields
255
+ };
246
256
  return result;
247
257
  }
248
258
  evaluateProductRules(rule, product, businessData, menuScopeMap) {
@@ -179,6 +179,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
179
179
  private calculateOrderPaidPaymentTotal;
180
180
  private getDepositAmount;
181
181
  private normalizeDepositAmount;
182
+ private normalizeDepositFlag;
183
+ private getHistoricalDepositSnapshot;
182
184
  private getLastOrderDepositSnapshot;
183
185
  private getLastOrderSubmitSnapshot;
184
186
  private applyDepositAmountToSummary;
@@ -1008,19 +1008,26 @@ class OrderModule extends _BaseModule.BaseModule {
1008
1008
  normalizeDepositAmount(amount) {
1009
1009
  return _decimal.default.max(new _decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
1010
1010
  }
1011
- getLastOrderDepositSnapshot() {
1012
- const lastOrderInfo = this.store.lastOrderInfo;
1013
- if (!lastOrderInfo || typeof lastOrderInfo !== 'object') return null;
1014
- const rawDepositAmount = lastOrderInfo.deposit_amount ?? lastOrderInfo.summary?.deposit_amount;
1011
+ normalizeDepositFlag(value) {
1012
+ if (value === 0 || value === '0') return 0;
1013
+ if (value === 1 || value === '1') return 1;
1014
+ return null;
1015
+ }
1016
+ getHistoricalDepositSnapshot(source) {
1017
+ if (!source || typeof source !== 'object') return null;
1018
+ const record = source;
1019
+ const rawDepositAmount = record.deposit_amount ?? record.summary?.deposit_amount;
1015
1020
  const depositAmount = this.normalizeDepositAmount(rawDepositAmount ?? 0);
1016
- const hasDepositAmount = new _decimal.default(depositAmount).gt(0);
1017
- const isDeposit = Number(lastOrderInfo.is_deposit) === 1 || hasDepositAmount;
1018
- if (!isDeposit || !hasDepositAmount) return null;
1021
+ if (!new _decimal.default(depositAmount).gt(0)) return null;
1019
1022
  return {
1020
- isDeposit: 1,
1023
+ // 兼容历史数据:旧快照缺少 is_deposit 时,沿用正定金金额的推导规则。
1024
+ isDeposit: this.normalizeDepositFlag(record.is_deposit) ?? 1,
1021
1025
  depositAmount
1022
1026
  };
1023
1027
  }
1028
+ getLastOrderDepositSnapshot() {
1029
+ return this.getHistoricalDepositSnapshot(this.store.lastOrderInfo);
1030
+ }
1024
1031
  getLastOrderSubmitSnapshot() {
1025
1032
  const lastOrderInfo = this.store.lastOrderInfo;
1026
1033
  if (!lastOrderInfo || typeof lastOrderInfo !== 'object') return {};
@@ -1068,7 +1075,7 @@ class OrderModule extends _BaseModule.BaseModule {
1068
1075
  }
1069
1076
  };
1070
1077
  tempOrder.deposit_amount = snapshot.depositAmount;
1071
- tempOrder.is_deposit = tempOrder.is_deposit === 0 && new _decimal.default(tempOrder.deposit_amount || 0).gt(0) ? 0 : snapshot.isDeposit;
1078
+ tempOrder.is_deposit = snapshot.isDeposit;
1072
1079
  return nextSummary;
1073
1080
  }
1074
1081
  isDepositOrder(tempOrder, depositAmount) {
@@ -1605,10 +1612,17 @@ class OrderModule extends _BaseModule.BaseModule {
1605
1612
  ...(0, _lodashEs.cloneDeep)(snapshot.summary || {})
1606
1613
  };
1607
1614
  const shouldUseManualDepositOverride = Boolean(manualDepositOverride && manualDepositOverride.productStructuralFingerprint === this.buildOrderProductsStructuralFingerprint(tempOrder.products));
1615
+ const historicalDepositSnapshot = this.getHistoricalDepositSnapshot(snapshot);
1608
1616
  if (shouldUseManualDepositOverride) {
1609
1617
  summary = this.applyDepositAmountToSummary(tempOrder, summary, manualDepositOverride.amount);
1610
- } else if (manualDepositOverride) {
1611
- this.clearManualDepositOverride(tempOrder);
1618
+ } else {
1619
+ if (manualDepositOverride) {
1620
+ this.clearManualDepositOverride(tempOrder);
1621
+ }
1622
+ if (historicalDepositSnapshot) {
1623
+ summary = this.applyDepositAmountToSummary(tempOrder, summary, historicalDepositSnapshot.depositAmount);
1624
+ tempOrder.is_deposit = historicalDepositSnapshot.isDeposit;
1625
+ }
1612
1626
  }
1613
1627
  const isPayableAmountUnchanged = this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary);
1614
1628
  if (!isPayableAmountUnchanged) return null;
@@ -1625,8 +1639,8 @@ class OrderModule extends _BaseModule.BaseModule {
1625
1639
  tempOrder.surcharges = (0, _lodashEs.cloneDeep)(snapshot.surcharges);
1626
1640
  }
1627
1641
  tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
1628
- tempOrder.deposit_amount = summary.deposit_amount || '0.00';
1629
- tempOrder.is_deposit = summary.deposit_amount !== '0.00' ? 1 : 0;
1642
+ tempOrder.deposit_amount = this.normalizeDepositAmount(summary.deposit_amount || 0);
1643
+ 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);
1630
1644
  const previousSummary = this.store.summary;
1631
1645
  this.store.summary = summary;
1632
1646
  this.updateTempOrderPaymentStatus(tempOrder, {
@@ -2083,7 +2097,7 @@ class OrderModule extends _BaseModule.BaseModule {
2083
2097
  const isExistingDepositDisabled = tempOrder.is_deposit === 0 && new _decimal.default(tempOrder.deposit_amount || 0).gt(0);
2084
2098
  tempOrder.deposit_amount = depositAmount;
2085
2099
  tempOrder.is_deposit = hasDepositAmount && !isExistingDepositDisabled ? 1 : 0;
2086
- return this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
2100
+ return shouldUseManualDepositOverride ? nextSummary : this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
2087
2101
  }
2088
2102
  async recalculateSummary(options) {
2089
2103
  const tempOrder = options?.createIfMissing ? this.ensureTempOrder() : this.store.tempOrder;
@@ -4469,6 +4483,7 @@ class OrderModule extends _BaseModule.BaseModule {
4469
4483
  externalSaleNumber: nextTempOrder.external_sale_number
4470
4484
  };
4471
4485
  const rawSummary = raw.summary && typeof raw.summary === 'object' ? raw.summary : {};
4486
+ const historicalDepositSnapshot = this.getHistoricalDepositSnapshot(sourceLastOrderInfo);
4472
4487
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map(s => ({
4473
4488
  ...(s || {})
4474
4489
  })) : (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []);
@@ -4487,6 +4502,10 @@ class OrderModule extends _BaseModule.BaseModule {
4487
4502
  surcharges: (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []),
4488
4503
  shop_discount: nextTempOrder.shop_discount || '0.00',
4489
4504
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || []),
4505
+ ...(historicalDepositSnapshot ? {
4506
+ is_deposit: historicalDepositSnapshot.isDeposit,
4507
+ deposit_amount: historicalDepositSnapshot.depositAmount
4508
+ } : {}),
4490
4509
  // merged record 的 summary 仍是远端旧值,保留快照仅用于完整重算的价格清理基线。
4491
4510
  ...(isMergedSalesDetailHydrate ? {
4492
4511
  requiresFullSummaryRecalculation: true
@@ -133,7 +133,9 @@ class SalesSummaryModule extends _BaseModule.BaseModule {
133
133
  await this.getSurchargeList(summaryChannel);
134
134
  }
135
135
  const taxConfig = this.getTaxConfig();
136
- const summarySchedule = this.core.getModule(`${this.name.split('_')[0]}_schedule`);
136
+ const fatherModuleName = this.otherParams?.fatherModule || this.name.replace(/_salesSummary$/, '');
137
+ const scheduleModuleName = `${fatherModuleName}_schedule`;
138
+ const summarySchedule = this.core.getModule(scheduleModuleName);
137
139
  const needScheduleIds = (this.store.surchargeList?.map(item => item.available_schedule_ids)?.flat() || []).filter(id => id !== undefined && id !== null && id !== '');
138
140
  const scheduleList = needScheduleIds.length > 0 ? summarySchedule?.getScheduleListByIds(needScheduleIds) : [];
139
141
  const scheduleById = {};
@@ -3464,26 +3464,28 @@ class Server {
3464
3464
  if (!Array.isArray(bookings)) return '';
3465
3465
  const values = [];
3466
3466
  const seen = new Set();
3467
- const visitResource = resource => {
3468
- const identifier = this.getCheckoutResourceIdentifier(resource);
3467
+ const visitResource = (resource, fallbackName) => {
3468
+ const identifier = this.getCheckoutResourceIdentifier(resource, fallbackName);
3469
3469
  if (identifier && !seen.has(identifier)) {
3470
3470
  seen.add(identifier);
3471
3471
  values.push(identifier);
3472
3472
  }
3473
3473
  if (Array.isArray(resource?.children)) {
3474
- resource.children.forEach(visitResource);
3474
+ resource.children.forEach(child => visitResource(child));
3475
3475
  }
3476
3476
  };
3477
3477
  bookings.forEach(booking => {
3478
3478
  if (Array.isArray(booking?.resources)) {
3479
- booking.resources.forEach(visitResource);
3479
+ booking.resources.forEach((resource, index) => {
3480
+ visitResource(resource, index === 0 ? booking?.relation_form_name : undefined);
3481
+ });
3480
3482
  }
3481
3483
  });
3482
3484
  return values.join(',');
3483
3485
  }
3484
- getCheckoutResourceIdentifier(resource) {
3486
+ getCheckoutResourceIdentifier(resource, fallbackName) {
3485
3487
  if (!resource || typeof resource !== 'object') return '';
3486
- const candidates = [resource.main_field, resource.name, resource.title, resource.metadata?.resource_name, resource.metadata?.name, resource.relation_id, resource.id];
3488
+ const candidates = [resource.main_field, resource.name, resource.title, resource.metadata?.resource_name, resource.metadata?.name, fallbackName, resource.relation_id, resource.id];
3487
3489
  for (const candidate of candidates) {
3488
3490
  const value = this.stringifyCheckoutResourceIdentifier(candidate);
3489
3491
  if (value) return value;
@@ -5740,6 +5742,8 @@ class Server {
5740
5742
  schedule_datetime: context.schedule_datetime,
5741
5743
  customer_id: context.customer_id,
5742
5744
  strategy_context: context.strategy_context,
5745
+ // 固定本次商品查询使用的语言,确保格式化与缓存使用同一份 locale 快照。
5746
+ locale: this.core.context?.locale,
5743
5747
  menuList: this.menu?.getMenuList?.() || [],
5744
5748
  scheduleList: scheduleModule?.getScheduleList?.() || [],
5745
5749
  dataVariantEvaluator: this.core.context?.dataVariantEvaluator
@@ -89,8 +89,8 @@ export declare class ProductsModule extends BaseModule implements Module {
89
89
  private buildBundleGroupPriceData;
90
90
  /**
91
91
  * 获取应用了价格的商品列表(带缓存)
92
- * 使用日期作为缓存 key,同一天的商品价格会被缓存
93
- * 缓存的是已经应用了价格的完整商品列表,避免重复转换
92
+ * 使用时间、客户、策略、商品范围和语言作为缓存 key
93
+ * 缓存的是已经应用了价格与多语言的完整商品列表,避免重复转换
94
94
  * @param schedule_date 日期
95
95
  * @param extraContext 额外的上下文数据(可选,由 Server 层传入)
96
96
  * @param options 可选参数
@@ -30,7 +30,7 @@ class ProductsModule extends _BaseModule.BaseModule {
30
30
  logger; // LoggerManager 实例
31
31
  otherParams = {};
32
32
 
33
- // 商品价格缓存:Map<日期, 应用了价格的商品列表>
33
+ // 商品格式化缓存:Map<查询上下文 key, 已应用价格与多语言的商品列表>
34
34
  productsPriceCache = new Map();
35
35
 
36
36
  // 缓存配置
@@ -394,8 +394,8 @@ class ProductsModule extends _BaseModule.BaseModule {
394
394
 
395
395
  /**
396
396
  * 获取应用了价格的商品列表(带缓存)
397
- * 使用日期作为缓存 key,同一天的商品价格会被缓存
398
- * 缓存的是已经应用了价格的完整商品列表,避免重复转换
397
+ * 使用时间、客户、策略、商品范围和语言作为缓存 key
398
+ * 缓存的是已经应用了价格与多语言的完整商品列表,避免重复转换
399
399
  * @param schedule_date 日期
400
400
  * @param extraContext 额外的上下文数据(可选,由 Server 层传入)
401
401
  * @param options 可选参数
@@ -600,9 +600,10 @@ class ProductsModule extends _BaseModule.BaseModule {
600
600
  }
601
601
  getProductsPriceCacheKey(schedule_date, extraContext, productIds) {
602
602
  const datetime = extraContext?.schedule_datetime || schedule_date;
603
+ const locale = extraContext?.locale ?? this.core?.context?.locale ?? '';
603
604
  const productScope = productIds ? `:products:${productIds.join(',')}` : '';
604
605
  const strategyScope = this.stringifyStable(extraContext?.strategy_context || {});
605
- return `${datetime}:customer:${extraContext?.customer_id ?? ''}:strategy:${strategyScope}${productScope}`;
606
+ return `${datetime}:locale:${locale}:customer:${extraContext?.customer_id ?? ''}` + `:strategy:${strategyScope}${productScope}`;
606
607
  }
607
608
 
608
609
  /**
@@ -11,7 +11,7 @@ export declare function perfMark(label: string, durationMs: number, meta?: Recor
11
11
  export declare function applyPriceDataToProducts(products: ProductData[], priceData: LoadProductsPriceData[]): ProductData[];
12
12
  export declare const getIsSessionProduct: (product: ProductData) => boolean;
13
13
  /**
14
- * 根据 locale 将商品的 i18n 字段覆盖到对应原始字段
14
+ * 根据 locale 格式化商品、分类、规格及套餐文案,缺少对应语言时回退 original。
15
15
  */
16
16
  export declare function applyI18nToProducts(products: ProductData[], locale?: string): ProductData[];
17
17
  /**