@pisell/pisellos 2.2.203 → 2.2.205

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 (44) hide show
  1. package/dist/modules/Order/index.d.ts +38 -1
  2. package/dist/modules/Order/index.js +388 -224
  3. package/dist/modules/Order/types.d.ts +2 -0
  4. package/dist/modules/Payment/index.d.ts +0 -13
  5. package/dist/modules/Payment/index.js +449 -833
  6. package/dist/plugins/request.d.ts +1 -0
  7. package/dist/server/index.d.ts +6 -0
  8. package/dist/server/index.js +730 -619
  9. package/dist/server/modules/index.d.ts +2 -0
  10. package/dist/server/modules/index.js +2 -0
  11. package/dist/server/modules/payment/index.d.ts +28 -0
  12. package/dist/server/modules/payment/index.js +305 -0
  13. package/dist/server/modules/payment/types.d.ts +9 -0
  14. package/dist/server/modules/payment/types.js +1 -0
  15. package/dist/solution/BaseSales/index.d.ts +13 -1
  16. package/dist/solution/BaseSales/index.js +132 -60
  17. package/dist/solution/BookingByStep/index.d.ts +1 -1
  18. package/dist/solution/BookingTicket/index.js +1 -1
  19. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +51 -52
  20. package/dist/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  21. package/dist/solution/BookingTicket/utils/scan/index.js +20 -8
  22. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  23. package/lib/modules/Order/index.d.ts +38 -1
  24. package/lib/modules/Order/index.js +94 -19
  25. package/lib/modules/Order/types.d.ts +2 -0
  26. package/lib/modules/Payment/index.d.ts +0 -13
  27. package/lib/modules/Payment/index.js +6 -149
  28. package/lib/plugins/request.d.ts +1 -0
  29. package/lib/server/index.d.ts +6 -0
  30. package/lib/server/index.js +46 -0
  31. package/lib/server/modules/index.d.ts +2 -0
  32. package/lib/server/modules/index.js +3 -0
  33. package/lib/server/modules/payment/index.d.ts +28 -0
  34. package/lib/server/modules/payment/index.js +192 -0
  35. package/lib/server/modules/payment/types.d.ts +9 -0
  36. package/lib/server/modules/payment/types.js +17 -0
  37. package/lib/solution/BaseSales/index.d.ts +13 -1
  38. package/lib/solution/BaseSales/index.js +62 -9
  39. package/lib/solution/BookingByStep/index.d.ts +1 -1
  40. package/lib/solution/BookingTicket/index.js +1 -1
  41. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +1 -2
  42. package/lib/solution/BookingTicket/utils/scan/index.d.ts +5 -0
  43. package/lib/solution/BookingTicket/utils/scan/index.js +17 -3
  44. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ var _class;
1
2
  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
3
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
4
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
@@ -24,6 +25,7 @@ var Scan = /*#__PURE__*/function () {
24
25
  _defineProperty(this, "listenerConfig", new Map());
25
26
  this.solution = solution;
26
27
  this.watchKey = watchKey;
28
+ Scan.scanInstances.add(this);
27
29
 
28
30
  // 初始化扫码监听
29
31
  // this.initPeripheralsListener();
@@ -31,18 +33,23 @@ var Scan = /*#__PURE__*/function () {
31
33
 
32
34
  /**
33
35
  * 初始化外设扫码结果监听
36
+ *
37
+ * @example
38
+ * scan.initPeripheralsListener();
34
39
  */
35
40
  _createClass(Scan, [{
36
41
  key: "initPeripheralsListener",
37
42
  value: function initPeripheralsListener() {
38
- var _this$solution,
39
- _this$solution$mountF,
40
- _this = this;
43
+ var _this$solution, _this$solution$mountF;
44
+ if (Scan.peripheralsListenerMounted) return;
45
+ Scan.peripheralsListenerMounted = true;
41
46
  (_this$solution = this.solution) === null || _this$solution === void 0 || (_this$solution = _this$solution.window) === null || _this$solution === void 0 || (_this$solution = _this$solution.interaction) === null || _this$solution === void 0 || (_this$solution = _this$solution.utils) === null || _this$solution === void 0 || (_this$solution$mountF = _this$solution.mountFunction) === null || _this$solution$mountF === void 0 || _this$solution$mountF.call(_this$solution, 'global', 'peripheralsResult', function (strVal) {
42
47
  try {
43
48
  var _result = JSON.parse(strVal);
44
49
  console.log('nativeScannerResult>>>>>>>', _result);
45
- _this.handleScan(_result);
50
+ Scan.scanInstances.forEach(function (instance) {
51
+ instance.handleScan(_result);
52
+ });
46
53
  } catch (err) {
47
54
  console.error(err);
48
55
  }
@@ -61,8 +68,9 @@ var Scan = /*#__PURE__*/function () {
61
68
  if (lastEnableEventKey) {
62
69
  var listenerConfig = this.listenerConfig.get(lastEnableEventKey);
63
70
  if (listenerConfig) {
71
+ var taskUuid = this.generateUuid();
64
72
  listenerConfig.task.addTask({
65
- uuid: this.generateUuid(),
73
+ uuid: taskUuid,
66
74
  type: lastEnableEventKey,
67
75
  actionParams: {
68
76
  scanResult: result
@@ -91,7 +99,7 @@ var Scan = /*#__PURE__*/function () {
91
99
  }, {
92
100
  key: "addListener",
93
101
  value: function addListener(event, scanCallback) {
94
- var _this2 = this;
102
+ var _this = this;
95
103
  // 订阅事件
96
104
  watch.subscribe(this.watchKey, event);
97
105
  // 创建任务
@@ -100,7 +108,7 @@ var Scan = /*#__PURE__*/function () {
100
108
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
101
109
  args[_key] = arguments[_key];
102
110
  }
103
- return _this2.scanTaskAction.apply(_this2, [event.key].concat(args));
111
+ return _this.scanTaskAction.apply(_this, [event.key].concat(args));
104
112
  });
105
113
 
106
114
  // 创建监听配置
@@ -110,7 +118,7 @@ var Scan = /*#__PURE__*/function () {
110
118
  });
111
119
  return {
112
120
  remove: function remove() {
113
- _this2.removeListener(event);
121
+ _this.removeListener(event);
114
122
  }
115
123
  };
116
124
  }
@@ -136,6 +144,7 @@ var Scan = /*#__PURE__*/function () {
136
144
  key: "removeAllListeners",
137
145
  value: function removeAllListeners() {
138
146
  var _this$listenerConfig, _this$listenerConfig$2, _this$listenerConfig2, _this$listenerConfig3;
147
+ Scan.scanInstances.delete(this);
139
148
  watch.clearEvent(this.watchKey);
140
149
  (_this$listenerConfig = this.listenerConfig) === null || _this$listenerConfig === void 0 || (_this$listenerConfig$2 = _this$listenerConfig.forEach) === null || _this$listenerConfig$2 === void 0 || _this$listenerConfig$2.call(_this$listenerConfig, function (item) {
141
150
  var _item$task;
@@ -291,4 +300,7 @@ var Scan = /*#__PURE__*/function () {
291
300
  }]);
292
301
  return Scan;
293
302
  }();
303
+ _class = Scan;
304
+ _defineProperty(Scan, "scanInstances", new Set());
305
+ _defineProperty(Scan, "peripheralsListenerMounted", false);
294
306
  export { Scan as default };
@@ -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
+ });
@@ -250,6 +250,28 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
250
250
  */
251
251
  updateVoucherOrderPayments(payments: OrderPaymentSource[]): OrderPaymentData[];
252
252
  private shouldMergeProductToOrder;
253
+ /**
254
+ * 预约商品加车后的统一收尾:促销、折扣、summary 重算与持久化(批量拆行时只调用一次)。
255
+ *
256
+ * @example
257
+ * await this.finalizeProductOrderMutation(tempOrder);
258
+ */
259
+ private finalizeProductOrderMutation;
260
+ /**
261
+ * 向 tempOrder 追加一条商品行(及可选 booking),不触发 summary 重算。
262
+ * 带 booking 且 num>1 时由 `addProductToOrder` 拆成多次本方法调用(每次 num=1)。
263
+ *
264
+ * @example
265
+ * await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
266
+ */
267
+ private appendProductLineToTempOrder;
268
+ /**
269
+ * 添加商品行。带 booking 时强制独立行;num>1 时拆成多条 num=1 的 product+booking(对齐 BookingByStep / ticketBooking addService)。
270
+ *
271
+ * @example
272
+ * await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
273
+ * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
274
+ */
253
275
  addProductToOrder(product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput): Promise<OrderProduct[]>;
254
276
  private hasGoodPassDiscount;
255
277
  private getBundleRuntimeIdentity;
@@ -257,6 +279,21 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
257
279
  updateOrderProduct(params: UpdateOrderProductParams): Promise<OrderProduct[]>;
258
280
  updateOrderProductQuantity(params: UpdateOrderProductQuantityParams): Promise<OrderProduct[]>;
259
281
  updateOrderBooking(params: UpdateOrderBookingParams): any[];
282
+ /**
283
+ * 商品行写路径收尾:促销 → 折扣 → 清洗 → summary → 持久化。
284
+ * 批量删除等多行变更场景只应调用一次,避免 N 次 applyPromotion。
285
+ *
286
+ * @example
287
+ * await this.finalizeAfterProductsMutation(tempOrder);
288
+ */
289
+ private finalizeAfterProductsMutation;
290
+ /**
291
+ * 批量按 identity 删除购物车行,末尾仅一次促销重算。
292
+ *
293
+ * @example
294
+ * await order.removeProductsFromOrder([identityA, identityB]);
295
+ */
296
+ removeProductsFromOrder(identities: OrderProductIdentity[]): Promise<OrderProduct[]>;
260
297
  removeProductFromOrder(identity: OrderProductIdentity): Promise<OrderProduct[]>;
261
298
  /**
262
299
  * 仅清空购物车行(products / bookings),不重置整单。
@@ -287,7 +324,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
287
324
  private logSubmitBackendRejected;
288
325
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
289
326
  createOrder(params: CommitOrderParams['query']): {
290
- type: "virtual" | "appointment_booking";
327
+ type: "appointment_booking" | "virtual";
291
328
  platform: string;
292
329
  sales_channel: string;
293
330
  order_sales_channel: string;
@@ -518,13 +518,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
518
518
  * - 不主动调用 applyDiscount / recalculateSummary,调用方负责跟进。
519
519
  */
520
520
  async applyPromotion() {
521
- if (this.isApplyingPromotion)
521
+ if (this.isApplyingPromotion) {
522
522
  return;
523
- if (!this.promotionEvaluator)
523
+ }
524
+ if (!this.promotionEvaluator) {
524
525
  return;
526
+ }
525
527
  const tempOrder = this.store.tempOrder;
526
- if (!tempOrder)
528
+ if (!tempOrder) {
527
529
  return;
530
+ }
528
531
  this.isApplyingPromotion = true;
529
532
  try {
530
533
  const result = (0, import_cartPromotion.processCartPromotion)(
@@ -1968,9 +1971,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1968
1971
  return true;
1969
1972
  }
1970
1973
  // ─── TempOrder: 商品 CRUD ───
1971
- async addProductToOrder(product, booking) {
1974
+ /**
1975
+ * 预约商品加车后的统一收尾:促销、折扣、summary 重算与持久化(批量拆行时只调用一次)。
1976
+ *
1977
+ * @example
1978
+ * await this.finalizeProductOrderMutation(tempOrder);
1979
+ */
1980
+ async finalizeProductOrderMutation(tempOrder) {
1981
+ await this.ensureEditDiscountConfigForProductChange(tempOrder);
1982
+ await this.applyPromotion();
1983
+ this.applyDiscount();
1984
+ this.sanitizeTempOrderProducts(tempOrder);
1985
+ await this.recalculateSummary({ createIfMissing: true });
1986
+ this.persistTempOrder();
1987
+ }
1988
+ /**
1989
+ * 向 tempOrder 追加一条商品行(及可选 booking),不触发 summary 重算。
1990
+ * 带 booking 且 num>1 时由 `addProductToOrder` 拆成多次本方法调用(每次 num=1)。
1991
+ *
1992
+ * @example
1993
+ * await this.appendProductLineToTempOrder(tempOrder, { product_id: 1, num: 1 }, booking);
1994
+ */
1995
+ async appendProductLineToTempOrder(tempOrder, product, booking) {
1972
1996
  var _a;
1973
- const tempOrder = this.ensureTempOrder();
1974
1997
  const linked = booking ? this.createLinkedProductAndBooking({ product, booking }) : null;
1975
1998
  const productToAdd = (linked == null ? void 0 : linked.product) || product;
1976
1999
  const incomingFingerprint = (0, import_utils3.buildProductLineFingerprint)(
@@ -1991,6 +2014,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1991
2014
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
1992
2015
  if (this.hasGoodPassDiscount(item))
1993
2016
  return false;
2017
+ if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
2018
+ return false;
1994
2019
  if (item.product_id !== productToAdd.product_id)
1995
2020
  return false;
1996
2021
  if (item.product_variant_id !== productToAdd.product_variant_id)
@@ -2092,12 +2117,38 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2092
2117
  if (linked) {
2093
2118
  tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
2094
2119
  }
2095
- await this.ensureEditDiscountConfigForProductChange(tempOrder);
2096
- await this.applyPromotion();
2097
- this.applyDiscount();
2098
- this.sanitizeTempOrderProducts(tempOrder);
2099
- await this.recalculateSummary({ createIfMissing: true });
2100
- this.persistTempOrder();
2120
+ }
2121
+ /**
2122
+ * 添加商品行。带 booking 时强制独立行;num>1 时拆成多条 num=1 的 product+booking(对齐 BookingByStep / ticketBooking addService)。
2123
+ *
2124
+ * @example
2125
+ * await order.addProductToOrder({ product_id: 1, num: 3 }, { start_time: '10:00' });
2126
+ * // → tempOrder.products 新增 3 行,每行 num=1,bookings 3 条
2127
+ */
2128
+ async addProductToOrder(product, booking) {
2129
+ const tempOrder = this.ensureTempOrder();
2130
+ if (booking) {
2131
+ const productRecord = product;
2132
+ const splitCount = (0, import_utils3.getSafeProductNum)(
2133
+ productRecord.num ?? productRecord.product_quantity ?? 1
2134
+ );
2135
+ if (splitCount > 1) {
2136
+ for (let i = 0; i < splitCount; i += 1) {
2137
+ const singleLine = (0, import_lodash_es.cloneDeep)(productRecord);
2138
+ singleLine.num = 1;
2139
+ delete singleLine.product_quantity;
2140
+ await this.appendProductLineToTempOrder(
2141
+ tempOrder,
2142
+ singleLine,
2143
+ (0, import_lodash_es.cloneDeep)(booking)
2144
+ );
2145
+ }
2146
+ await this.finalizeProductOrderMutation(tempOrder);
2147
+ return tempOrder.products;
2148
+ }
2149
+ }
2150
+ await this.appendProductLineToTempOrder(tempOrder, product, booking);
2151
+ await this.finalizeProductOrderMutation(tempOrder);
2101
2152
  return tempOrder.products;
2102
2153
  }
2103
2154
  hasGoodPassDiscount(product) {
@@ -2395,11 +2446,34 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2395
2446
  this.persistTempOrder();
2396
2447
  return tempOrder.bookings;
2397
2448
  }
2398
- async removeProductFromOrder(identity) {
2449
+ /**
2450
+ * 商品行写路径收尾:促销 → 折扣 → 清洗 → summary → 持久化。
2451
+ * 批量删除等多行变更场景只应调用一次,避免 N 次 applyPromotion。
2452
+ *
2453
+ * @example
2454
+ * await this.finalizeAfterProductsMutation(tempOrder);
2455
+ */
2456
+ async finalizeAfterProductsMutation(tempOrder) {
2457
+ await this.applyPromotion();
2458
+ this.applyDiscount();
2459
+ this.sanitizeTempOrderProducts(tempOrder);
2460
+ await this.recalculateSummary({ createIfMissing: true });
2461
+ this.persistTempOrder();
2462
+ }
2463
+ /**
2464
+ * 批量按 identity 删除购物车行,末尾仅一次促销重算。
2465
+ *
2466
+ * @example
2467
+ * await order.removeProductsFromOrder([identityA, identityB]);
2468
+ */
2469
+ async removeProductsFromOrder(identities) {
2399
2470
  const tempOrder = this.ensureTempOrder();
2471
+ if (!identities.length) {
2472
+ return tempOrder.products;
2473
+ }
2400
2474
  const removedProducts = [];
2401
2475
  tempOrder.products = tempOrder.products.filter((item) => {
2402
- const shouldRemove = (0, import_utils3.isIdentityMatch)(item, identity);
2476
+ const shouldRemove = identities.some((identity) => (0, import_utils3.isIdentityMatch)(item, identity));
2403
2477
  if (shouldRemove)
2404
2478
  removedProducts.push(item);
2405
2479
  return !shouldRemove;
@@ -2407,13 +2481,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2407
2481
  for (const product of removedProducts) {
2408
2482
  this.removeLinkedBookingsForProduct(tempOrder, product);
2409
2483
  }
2410
- await this.applyPromotion();
2411
- this.applyDiscount();
2412
- this.sanitizeTempOrderProducts(tempOrder);
2413
- await this.recalculateSummary({ createIfMissing: true });
2414
- this.persistTempOrder();
2484
+ await this.finalizeAfterProductsMutation(tempOrder);
2415
2485
  return tempOrder.products;
2416
2486
  }
2487
+ async removeProductFromOrder(identity) {
2488
+ return this.removeProductsFromOrder([identity]);
2489
+ }
2417
2490
  /**
2418
2491
  * 仅清空购物车行(products / bookings),不重置整单。
2419
2492
  * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
@@ -2518,6 +2591,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2518
2591
  submittedOrderId,
2519
2592
  (resultRecord == null ? void 0 : resultRecord.data) || resultRecord || {}
2520
2593
  );
2594
+ } else {
2595
+ this.store.syncState = "submitted";
2521
2596
  }
2522
2597
  return result;
2523
2598
  }
@@ -2836,7 +2911,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2836
2911
  hasOrderId: !!orderData.order_id,
2837
2912
  smallTicketDataFlag: orderData.small_ticket_data_flag
2838
2913
  });
2839
- const response = await this.request.post("/shop/order/checkout", orderData, {
2914
+ const response = await this.request.post("/order/checkout", orderData, {
2840
2915
  osServer: true,
2841
2916
  customToast: () => {
2842
2917
  }
@@ -612,6 +612,8 @@ export interface OrderModuleAPI {
612
612
  updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
613
613
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
614
614
  removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
615
+ /** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
616
+ removeProductsFromOrder: (identities: OrderProductIdentity[]) => Promise<OrderProduct[]>;
615
617
  /** @deprecated no-op;OrderModule 不再负责 tempOrder localStorage 持久化。 */
616
618
  persistTempOrder: () => void;
617
619
  /**
@@ -25,9 +25,6 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
25
25
  private dbManager;
26
26
  private logger;
27
27
  private voucherUpdateLockByOrderUuid;
28
- private payMethodMemoryCache;
29
- private payMethodListInFlight;
30
- private isRefreshingPaymentMethods;
31
28
  protected otherParams: any;
32
29
  cash: CashPayment;
33
30
  eftpos: EftposPayment;
@@ -57,20 +54,10 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
57
54
  *
58
55
  */
59
56
  private registerNetworkHandlers;
60
- private filterPayMethods;
61
57
  /**
62
58
  * 获取支付方式列表
63
59
  */
64
60
  getPayMethodListAsync(): Promise<PaymentMethod[]>;
65
- private loadPayMethodListAsync;
66
- /**
67
- * 后台刷新支付方式列表
68
- */
69
- private refreshPaymentMethodsInBackground;
70
- /**
71
- * 检查支付方式列表是否有变化
72
- */
73
- private hasPaymentMethodsChanged;
74
61
  /**
75
62
  * 获取订单列表
76
63
  */
@@ -76,9 +76,6 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
76
76
  this.defaultVersion = "1.0.0";
77
77
  // LoggerManager 实例
78
78
  this.voucherUpdateLockByOrderUuid = /* @__PURE__ */ new Map();
79
- this.payMethodMemoryCache = null;
80
- this.payMethodListInFlight = null;
81
- this.isRefreshingPaymentMethods = false;
82
79
  this.otherParams = {};
83
80
  this.cash = new import_cash.CashPaymentImpl(this);
84
81
  this.eftpos = new import_eftpos.EftposPaymentImpl(this);
@@ -213,66 +210,18 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
213
210
  }
214
211
  });
215
212
  }
216
- async filterPayMethods(payMethods) {
217
- payMethods = payMethods.filter((method) => method.status === 1 && method.disable === 0);
218
- const walletPassMethod = payMethods.find((method) => method.code === "WALLET_PASS");
219
- if (walletPassMethod) {
220
- payMethods.forEach((method) => {
221
- if (method.code === "PRODUCTVOUCHER" || method.code === "GIFTCARD" || method.code === "POINTCARD") {
222
- method.channel_application = walletPassMethod.channel_application;
223
- }
224
- });
225
- } else {
226
- payMethods = payMethods.filter((method) => method.code !== "PRODUCTVOUCHER" && method.code !== "GIFTCARD" && method.code !== "POINTCARD");
227
- }
228
- return payMethods;
229
- }
230
213
  /**
231
214
  * 获取支付方式列表
232
215
  */
233
216
  async getPayMethodListAsync() {
234
- var _a;
235
217
  this.logInfo("Starting getPayMethodListAsync");
236
- if ((_a = this.payMethodMemoryCache) == null ? void 0 : _a.length) {
237
- return this.payMethodMemoryCache;
238
- }
239
- if (this.payMethodListInFlight) {
240
- return this.payMethodListInFlight;
241
- }
242
- this.payMethodListInFlight = this.loadPayMethodListAsync().finally(() => {
243
- this.payMethodListInFlight = null;
244
- });
245
- return this.payMethodListInFlight;
246
- }
247
- async loadPayMethodListAsync() {
248
218
  try {
249
- let cachedMethods = [];
250
- try {
251
- cachedMethods = await this.dbManager.getAll("pay_method");
252
- } catch (dbError) {
253
- console.warn("[PaymentModule] pay_method 表不存在,将从服务器获取数据");
254
- }
255
- const hasCache = cachedMethods.length > 0;
256
- if (hasCache) {
257
- this.payMethodMemoryCache = cachedMethods;
258
- this.refreshPaymentMethodsInBackground(cachedMethods);
259
- return cachedMethods;
260
- }
261
- const response = await this.request.get("/pay/custom-payment/all");
262
- response.data = await this.filterPayMethods(response.data);
263
- const payMethods = response.data || [];
264
- this.payMethodMemoryCache = payMethods;
265
- try {
266
- for (const method of payMethods) {
267
- await this.dbManager.update("pay_method", method);
268
- }
269
- } catch (dbError) {
270
- console.warn("[PaymentModule] 无法缓存支付方式,pay_method 表不存在");
271
- }
272
- await this.core.effects.emit(
273
- `${this.name}:onPaymentMethodsLoaded`,
274
- payMethods
275
- );
219
+ const response = await this.request.get("/pay/custom-payment/all", {
220
+ filterPaymentMethods: true
221
+ }, {
222
+ osServer: true
223
+ });
224
+ const payMethods = (response == null ? void 0 : response.data) || response || [];
276
225
  this.logInfo("getPayMethodListAsync completed successfully", {
277
226
  payMethods
278
227
  });
@@ -283,98 +232,6 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
283
232
  return [];
284
233
  }
285
234
  }
286
- /**
287
- * 后台刷新支付方式列表
288
- */
289
- async refreshPaymentMethodsInBackground(cachedMethods) {
290
- if (this.isRefreshingPaymentMethods)
291
- return;
292
- this.isRefreshingPaymentMethods = true;
293
- this.logInfo("Starting refreshPaymentMethodsInBackground", {
294
- cachedMethodsCount: cachedMethods.length
295
- });
296
- try {
297
- console.log("[PaymentModule] 后台刷新支付方式列表...");
298
- const response = await this.request.get("/pay/custom-payment/all");
299
- response.data = await this.filterPayMethods(response.data);
300
- const newPayMethods = response.data || [];
301
- this.payMethodMemoryCache = newPayMethods;
302
- const hasChanges = this.hasPaymentMethodsChanged(
303
- cachedMethods,
304
- newPayMethods
305
- );
306
- if (hasChanges) {
307
- console.log("[PaymentModule] 支付方式列表已更新");
308
- this.logInfo("Payment methods updated in background", {
309
- oldCount: cachedMethods.length,
310
- newCount: newPayMethods.length
311
- });
312
- try {
313
- for (const method of cachedMethods) {
314
- await this.dbManager.delete("pay_method", method.id);
315
- }
316
- for (const method of newPayMethods) {
317
- await this.dbManager.update("pay_method", method);
318
- }
319
- } catch (dbError) {
320
- console.warn("[PaymentModule] 无法更新支付方式缓存", dbError);
321
- }
322
- const eventData = {
323
- oldMethods: cachedMethods,
324
- newMethods: newPayMethods
325
- };
326
- await this.core.effects.emit(
327
- `${this.name}:onPaymentMethodsChanged`,
328
- eventData
329
- );
330
- } else {
331
- console.log("[PaymentModule] 支付方式列表无变化");
332
- }
333
- } catch (error) {
334
- console.error("[PaymentModule] 后台刷新支付方式失败", error);
335
- } finally {
336
- this.isRefreshingPaymentMethods = false;
337
- }
338
- }
339
- /**
340
- * 检查支付方式列表是否有变化
341
- */
342
- hasPaymentMethodsChanged(oldMethods, newMethods) {
343
- if (oldMethods.length !== newMethods.length) {
344
- return true;
345
- }
346
- const oldMethodsMap = new Map(
347
- oldMethods.map((method) => [method.id, method])
348
- );
349
- for (const newMethod of newMethods) {
350
- const oldMethod = oldMethodsMap.get(newMethod.id);
351
- if (!oldMethod) {
352
- return true;
353
- }
354
- if (oldMethod.code !== newMethod.code || oldMethod.name !== newMethod.name || oldMethod.type !== newMethod.type || oldMethod.description !== newMethod.description || oldMethod.status !== newMethod.status || oldMethod.disable !== newMethod.disable || oldMethod.is_surcharge !== newMethod.is_surcharge || oldMethod.fixed !== newMethod.fixed || oldMethod.percentage !== newMethod.percentage || oldMethod.enabled !== newMethod.enabled || JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) || JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) || JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {})) {
355
- console.log(`[PaymentModule] 支付方式 ${newMethod.id} (${newMethod.code}) 发生变化:`, {
356
- id: newMethod.id,
357
- changes: {
358
- code: oldMethod.code !== newMethod.code ? { old: oldMethod.code, new: newMethod.code } : void 0,
359
- name: oldMethod.name !== newMethod.name ? { old: oldMethod.name, new: newMethod.name } : void 0,
360
- type: oldMethod.type !== newMethod.type ? { old: oldMethod.type, new: newMethod.type } : void 0,
361
- description: oldMethod.description !== newMethod.description ? { old: oldMethod.description, new: newMethod.description } : void 0,
362
- status: oldMethod.status !== newMethod.status ? { old: oldMethod.status, new: newMethod.status } : void 0,
363
- disable: oldMethod.disable !== newMethod.disable ? { old: oldMethod.disable, new: newMethod.disable } : void 0,
364
- is_surcharge: oldMethod.is_surcharge !== newMethod.is_surcharge ? { old: oldMethod.is_surcharge, new: newMethod.is_surcharge } : void 0,
365
- fixed: oldMethod.fixed !== newMethod.fixed ? { old: oldMethod.fixed, new: newMethod.fixed } : void 0,
366
- percentage: oldMethod.percentage !== newMethod.percentage ? { old: oldMethod.percentage, new: newMethod.percentage } : void 0,
367
- enabled: oldMethod.enabled !== newMethod.enabled ? { old: oldMethod.enabled, new: newMethod.enabled } : void 0,
368
- channel_application: JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) ? { old: oldMethod.channel_application, new: newMethod.channel_application } : void 0,
369
- companies: JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) ? { old: oldMethod.companies, new: newMethod.companies } : void 0,
370
- metadata: JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {}) ? { old: oldMethod.metadata, new: newMethod.metadata } : void 0
371
- }
372
- });
373
- return true;
374
- }
375
- }
376
- return false;
377
- }
378
235
  /**
379
236
  * 获取订单列表
380
237
  */
@@ -69,6 +69,7 @@ export interface RequestOptions {
69
69
  customToast?: () => void;
70
70
  cache?: CacheProps;
71
71
  osServer?: boolean;
72
+ prefix?: boolean;
72
73
  callback?: (res: any) => void;
73
74
  subscriberId?: string;
74
75
  }
@@ -4,6 +4,7 @@ import { QuotationModule } from './modules/quotation';
4
4
  import { ScheduleModuleEx } from './modules/schedule';
5
5
  import { ResourceModule } from './modules/resource';
6
6
  import { FloorPlanModule } from './modules/floor-plan';
7
+ import { PaymentServerModule } from './modules/payment';
7
8
  import { PisellCore, ServerModuleConfig, InitializeServerOptions } from '../types';
8
9
  import type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, RequestSetting } from './types';
9
10
  import { OrderModule } from './modules/order';
@@ -23,6 +24,9 @@ declare class Server {
23
24
  resource?: ResourceModule;
24
25
  order?: OrderModule;
25
26
  floor_plan?: FloorPlanModule;
27
+ payment?: PaymentServerModule;
28
+ private paymentRouteModule?;
29
+ private paymentRouteModuleInFlight?;
26
30
  /** GET 前缀路由(最长前缀优先匹配) */
27
31
  private prefixRouterGet;
28
32
  router: Router;
@@ -167,6 +171,8 @@ declare class Server {
167
171
  * @private
168
172
  */
169
173
  private registerServerRoutes;
174
+ private getPaymentRouteModule;
175
+ private handlePaymentMethods;
170
176
  /**
171
177
  * 根据 subscriberId 移除商品查询订阅者
172
178
  */