@pisell/pisellos 0.0.506 → 0.0.508

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.
@@ -235,3 +235,9 @@ export interface ScanOrderLoggerRuntimeConfig {
235
235
  }
236
236
  export interface ScanOrderAddLogParams extends ScanOrderLogInput {
237
237
  }
238
+ /** ScanOrder.scanCode 对外的轻量结果(不含 discountList,UI 在 resolve 后调 getDiscountList) */
239
+ export interface ScanOrderScanCodeResult {
240
+ isAvailable: boolean;
241
+ type?: 'server' | string;
242
+ unavailableReason?: 'time_limit' | string;
243
+ }
@@ -17,4 +17,6 @@ export var ScanOrderHooks = /*#__PURE__*/function (ScanOrderHooks) {
17
17
 
18
18
  /** `resource_capacity[i].capacity_list[j]` */
19
19
 
20
- /** `/order/resource/occupy-detail` 单条 `occupy_details[i]` */
20
+ /** `/order/resource/occupy-detail` 单条 `occupy_details[i]` */
21
+
22
+ /** ScanOrder.scanCode 对外的轻量结果(不含 discountList,UI 在 resolve 后调 getDiscountList) */
@@ -22,58 +22,124 @@ __export(feishu_exports, {
22
22
  feishuLoggerProvider: () => feishuLoggerProvider
23
23
  });
24
24
  module.exports = __toCommonJS(feishu_exports);
25
- function safeStringify(payload) {
26
- if (payload === void 0 || payload === null)
25
+ var DEFAULT_THROTTLE_MS = 3e3;
26
+ var pendingQueue = [];
27
+ var flushTimer = null;
28
+ var cachedProviderConfig;
29
+ function safeStringify(value) {
30
+ if (value === void 0 || value === null)
27
31
  return "";
32
+ if (typeof value === "string")
33
+ return value;
34
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
35
+ return String(value);
36
+ }
28
37
  try {
29
- return JSON.stringify(payload);
38
+ return JSON.stringify(value);
30
39
  } catch (error) {
31
40
  return `[unserializable: ${String(error)}]`;
32
41
  }
33
42
  }
34
- function createFeishuMessageContent(contentArr) {
35
- return JSON.stringify(
36
- contentArr.map((item) => [
37
- { tag: "text", text: `${item.key}: ` },
38
- { tag: "text", text: item.value }
39
- ])
40
- );
43
+ function isWebhookUsable(webhook) {
44
+ if (!webhook)
45
+ return false;
46
+ if (webhook.includes("REPLACE_ME"))
47
+ return false;
48
+ return true;
49
+ }
50
+ function buildRecordSegments(record) {
51
+ const context = record.context || {};
52
+ return [
53
+ [{ tag: "text", text: `[${record.level}] ${record.timestamp} ${record.title}
54
+ ` }],
55
+ [{ tag: "text", text: `缓存标识: ${safeStringify(context.cacheId)}
56
+ ` }],
57
+ [{ tag: "text", text: `日志来源: ${safeStringify(context)}
58
+ ` }],
59
+ [{ tag: "text", text: `日志内容: ${safeStringify(record.payload)}
60
+ ` }],
61
+ [{ tag: "text", text: `扩展信息: ${safeStringify(record.extra)}
62
+ ` }],
63
+ [{ tag: "text", text: "------\n" }]
64
+ ];
65
+ }
66
+ function buildFeishuBody(records) {
67
+ const title = records.length === 1 ? records[0].title : `ScanOrder 日志批量 (${records.length} 条)`;
68
+ const content = [];
69
+ records.forEach((record) => {
70
+ buildRecordSegments(record).forEach((segment) => content.push(segment));
71
+ });
72
+ return JSON.stringify({
73
+ msg_type: "post",
74
+ content: JSON.stringify({
75
+ post: {
76
+ zh_cn: {
77
+ title,
78
+ content
79
+ }
80
+ }
81
+ })
82
+ });
83
+ }
84
+ async function postToFeishu(webhook, body) {
85
+ await fetch(webhook, {
86
+ method: "POST",
87
+ headers: {
88
+ "Content-Type": "application/json"
89
+ },
90
+ body
91
+ });
92
+ }
93
+ async function flushQueue() {
94
+ var _a;
95
+ flushTimer = null;
96
+ if (!pendingQueue.length)
97
+ return;
98
+ const records = pendingQueue.splice(0, pendingQueue.length);
99
+ const webhook = (_a = cachedProviderConfig == null ? void 0 : cachedProviderConfig.feishu) == null ? void 0 : _a.webhook;
100
+ if (!isWebhookUsable(webhook)) {
101
+ return;
102
+ }
103
+ if (typeof fetch !== "function") {
104
+ console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志批量上报");
105
+ return;
106
+ }
107
+ try {
108
+ await postToFeishu(webhook, buildFeishuBody(records));
109
+ } catch (error) {
110
+ console.warn("[ScanOrderLogger] Feishu 批量上报失败", error);
111
+ }
41
112
  }
42
113
  var feishuLoggerProvider = {
43
114
  async send(payload) {
44
- var _a, _b;
115
+ var _a, _b, _c, _d;
116
+ cachedProviderConfig = payload.providerConfig;
45
117
  const webhook = (_b = (_a = payload.providerConfig) == null ? void 0 : _a.feishu) == null ? void 0 : _b.webhook;
46
- if (webhook && webhook.includes("REPLACE_ME"))
47
- return;
48
118
  if (!webhook) {
49
119
  console.warn("[ScanOrderLogger] Feishu webhook 未配置,跳过日志上报");
50
120
  return;
51
121
  }
122
+ if (!isWebhookUsable(webhook))
123
+ return;
52
124
  if (typeof fetch !== "function") {
53
125
  console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报");
54
126
  return;
55
127
  }
56
- const { record } = payload;
57
- const contentArr = [
58
- { key: "日志级别", value: record.level },
59
- { key: "日志时间", value: record.timestamp },
60
- { key: "日志标题", value: record.title },
61
- { key: "缓存标识", value: record.context.cacheId || "" },
62
- { key: "日志来源", value: safeStringify(record.context) },
63
- { key: "日志内容", value: safeStringify(record.payload) },
64
- { key: "扩展信息", value: safeStringify(record.extra) }
65
- ];
66
- const contentStr = createFeishuMessageContent(contentArr);
67
- await fetch(webhook, {
68
- headers: {
69
- "Content-Type": "application/json"
70
- },
71
- method: "POST",
72
- body: JSON.stringify({
73
- msg_type: "post",
74
- content: `{"post":{"zh_cn":{"title":"${record.title}","content":${contentStr}}}}`
75
- })
76
- });
128
+ const throttleMs = ((_d = (_c = payload.providerConfig) == null ? void 0 : _c.feishu) == null ? void 0 : _d.throttleMs) ?? DEFAULT_THROTTLE_MS;
129
+ if (throttleMs <= 0) {
130
+ try {
131
+ await postToFeishu(webhook, buildFeishuBody([payload.record]));
132
+ } catch (error) {
133
+ console.warn("[ScanOrderLogger] Feishu 日志上报失败", error);
134
+ }
135
+ return;
136
+ }
137
+ pendingQueue.push(payload.record);
138
+ if (!flushTimer) {
139
+ flushTimer = setTimeout(() => {
140
+ void flushQueue();
141
+ }, throttleMs);
142
+ }
77
143
  }
78
144
  };
79
145
  // Annotate the CommonJS export names for ESM import in node:
@@ -2,6 +2,12 @@ export type ScanOrderLogLevel = 'info' | 'warning' | 'error' | 'debug';
2
2
  export type ScanOrderLoggerProviderType = 'feishu' | 'grafana';
3
3
  export interface ScanOrderLoggerProviderFeishuConfig {
4
4
  webhook?: string;
5
+ /**
6
+ * 节流窗口毫秒数,默认 3000ms
7
+ * - >0:首条日志进入队列并启动定时器,窗口结束后合并成一条 Feishu post 统一发送
8
+ * - <=0:关闭节流,保持每条日志立即单独发送
9
+ */
10
+ throttleMs?: number;
5
11
  }
6
12
  export interface ScanOrderLoggerProviderGrafanaConfig {
7
13
  endpoint?: string;
@@ -1,6 +1,7 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
- import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity } from './types';
3
+ import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderScanCodeResult } from './types';
4
+ import type { Discount } from '../../modules/Discount/types';
4
5
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
5
6
  import type { StrategyConfig } from '../../model/strategy/type';
6
7
  export * from './types';
@@ -29,6 +30,10 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
29
30
  private itemRuleRuntimeConfig;
30
31
  /** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
31
32
  private enabledReservationRuleProducts;
33
+ private loginEffectDisposers;
34
+ private customerLoginRefreshInFlight;
35
+ private customerLoginRefreshIdInFlight;
36
+ private static readonly PISELL1_LOGIN_SUCCESS;
32
37
  private getScanOrderLoggerContext;
33
38
  private serializeError;
34
39
  private addScanOrderLog;
@@ -36,6 +41,12 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
36
41
  private logMethodSuccess;
37
42
  private logMethodError;
38
43
  addLog(params: ScanOrderAddLogParams): Promise<void>;
44
+ private normalizeCustomerId;
45
+ private resolveCustomerIdFromLoginPayload;
46
+ private clearLoginEffectListeners;
47
+ private registerLoginEffect;
48
+ private registerCustomerLoginListeners;
49
+ private refreshOrderMarketingAfterLogin;
39
50
  constructor(name?: string, version?: string);
40
51
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
41
52
  destroy(): Promise<void>;
@@ -62,6 +73,15 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
62
73
  restoreOrder(): Promise<import("./types").ScanOrderTempOrder>;
63
74
  getOrderProducts(): ScanOrderOrderProduct[];
64
75
  getSummary(): Promise<import("./types").ScanOrderSummary>;
76
+ getDiscountList(): Discount[];
77
+ scanCode(code: string, customerId?: number): Promise<ScanOrderScanCodeResult>;
78
+ setDiscountSelected(params: {
79
+ discountId: number;
80
+ isSelected: boolean;
81
+ }): Promise<void>;
82
+ onCustomerLogin(params: {
83
+ customerId: number;
84
+ }): Promise<void>;
65
85
  private buildSubmitPayloadEnhancer;
66
86
  submitScanOrder<T = any>(): Promise<T>;
67
87
  addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
@@ -35,8 +35,12 @@ __export(ScanOrder_exports, {
35
35
  module.exports = __toCommonJS(ScanOrder_exports);
36
36
  var import_BaseModule = require("../../modules/BaseModule");
37
37
  var import_types = require("./types");
38
+ var import_Order = require("../../modules/Order");
39
+ var import_types2 = require("../../modules/Account/types");
40
+ var import_types3 = require("../RegisterAndLogin/types");
41
+ var import_decimal = __toESM(require("decimal.js"));
38
42
  var import_utils = require("./utils");
39
- var import_types2 = require("../BookingByStep/types");
43
+ var import_types4 = require("../BookingByStep/types");
40
44
  var import_ProductList = require("../../modules/ProductList");
41
45
  var import_Schedule = require("../../modules/Schedule");
42
46
  var import_getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
@@ -74,6 +78,9 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
74
78
  this.itemRuleRuntimeConfig = {};
75
79
  /** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
76
80
  this.enabledReservationRuleProducts = [];
81
+ this.loginEffectDisposers = [];
82
+ this.customerLoginRefreshInFlight = null;
83
+ this.customerLoginRefreshIdInFlight = null;
77
84
  }
78
85
  getScanOrderLoggerContext() {
79
86
  return {
@@ -157,6 +164,102 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
157
164
  }
158
165
  });
159
166
  }
167
+ normalizeCustomerId(value) {
168
+ const customerId = Number(value);
169
+ if (!Number.isFinite(customerId) || customerId <= 0)
170
+ return null;
171
+ return customerId;
172
+ }
173
+ resolveCustomerIdFromLoginPayload(payload) {
174
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
175
+ const candidates = [
176
+ payload == null ? void 0 : payload.customerId,
177
+ payload == null ? void 0 : payload.customer_id,
178
+ payload == null ? void 0 : payload.id,
179
+ (_a = payload == null ? void 0 : payload.user) == null ? void 0 : _a.customerId,
180
+ (_b = payload == null ? void 0 : payload.user) == null ? void 0 : _b.customer_id,
181
+ (_c = payload == null ? void 0 : payload.user) == null ? void 0 : _c.id,
182
+ (_e = (_d = payload == null ? void 0 : payload.user) == null ? void 0 : _d._origin) == null ? void 0 : _e.customer_id,
183
+ (_f = payload == null ? void 0 : payload.account) == null ? void 0 : _f.customerId,
184
+ (_g = payload == null ? void 0 : payload.account) == null ? void 0 : _g.customer_id,
185
+ (_h = payload == null ? void 0 : payload.account) == null ? void 0 : _h.id,
186
+ (_i = payload == null ? void 0 : payload._origin) == null ? void 0 : _i.customer_id
187
+ ];
188
+ for (const candidate of candidates) {
189
+ const customerId = this.normalizeCustomerId(candidate);
190
+ if (customerId)
191
+ return customerId;
192
+ }
193
+ return null;
194
+ }
195
+ clearLoginEffectListeners() {
196
+ for (const dispose of this.loginEffectDisposers) {
197
+ dispose();
198
+ }
199
+ this.loginEffectDisposers = [];
200
+ }
201
+ registerLoginEffect(event, callback) {
202
+ var _a;
203
+ const effects = (_a = this.core) == null ? void 0 : _a.effects;
204
+ if (!(effects == null ? void 0 : effects.on))
205
+ return;
206
+ effects.on(event, callback);
207
+ this.loginEffectDisposers.push(() => {
208
+ if (typeof effects.off === "function") {
209
+ effects.off(event, callback);
210
+ }
211
+ });
212
+ }
213
+ registerCustomerLoginListeners() {
214
+ this.clearLoginEffectListeners();
215
+ const createHandleLogin = () => async (payload) => {
216
+ const customerId = this.resolveCustomerIdFromLoginPayload(payload);
217
+ if (!customerId)
218
+ return;
219
+ await this.refreshOrderMarketingAfterLogin({ customerId });
220
+ };
221
+ this.registerLoginEffect(
222
+ _ScanOrderImpl.PISELL1_LOGIN_SUCCESS,
223
+ createHandleLogin()
224
+ );
225
+ this.registerLoginEffect(import_types2.AccountHooks.OnLogin, createHandleLogin());
226
+ this.registerLoginEffect(
227
+ import_types3.RegisterAndLoginHooks.onLoginSuccess,
228
+ createHandleLogin()
229
+ );
230
+ }
231
+ async refreshOrderMarketingAfterLogin(params) {
232
+ if (!this.store.order)
233
+ throw new Error("order 模块未初始化");
234
+ if (this.customerLoginRefreshInFlight) {
235
+ if (this.customerLoginRefreshIdInFlight === params.customerId) {
236
+ await this.customerLoginRefreshInFlight;
237
+ return;
238
+ }
239
+ await this.customerLoginRefreshInFlight;
240
+ }
241
+ this.customerLoginRefreshIdInFlight = params.customerId;
242
+ const refreshTask = (async () => {
243
+ await this.store.order.loadDiscountConfig({
244
+ customerId: params.customerId
245
+ });
246
+ await this.store.order.recalculateSummary({ createIfMissing: true });
247
+ this.store.order.persistTempOrder();
248
+ await this.refreshItemRuleQuantityLimits();
249
+ await this.refreshCartValidationPassed();
250
+ })();
251
+ this.customerLoginRefreshInFlight = refreshTask;
252
+ try {
253
+ await refreshTask;
254
+ } catch (error) {
255
+ throw error;
256
+ } finally {
257
+ if (this.customerLoginRefreshInFlight === refreshTask) {
258
+ this.customerLoginRefreshInFlight = null;
259
+ this.customerLoginRefreshIdInFlight = null;
260
+ }
261
+ }
262
+ }
160
263
  async initialize(core, options = {}) {
161
264
  var _a, _b, _c, _d, _e, _f;
162
265
  this.logMethodStart("initialize");
@@ -195,7 +298,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
195
298
  ];
196
299
  moduleArr.forEach((step) => {
197
300
  var _a2, _b2, _c2, _d2, _e2, _f2;
198
- const targetModule = (0, import_types2.createModule)(step, this.name);
301
+ const targetModule = (0, import_types4.createModule)(step, this.name);
199
302
  if (targetModule) {
200
303
  this.store[step] = targetModule;
201
304
  const initialState = step === "salesSummary" ? {
@@ -236,6 +339,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
236
339
  fatherModule: this.name
237
340
  }
238
341
  });
342
+ this.registerCustomerLoginListeners();
239
343
  console.log("[ScanOrder] 初始化开始");
240
344
  try {
241
345
  await ((_e = this.store.order) == null ? void 0 : _e.recalculateSummary({ createIfMissing: false }));
@@ -269,6 +373,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
269
373
  }
270
374
  async destroy() {
271
375
  this.logMethodStart("destroy");
376
+ this.clearLoginEffectListeners();
272
377
  await this.core.effects.emit(import_types.ScanOrderHooks.onDestroy, {});
273
378
  console.log("[ScanOrder] 已销毁");
274
379
  this.logMethodSuccess("destroy");
@@ -494,6 +599,127 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
494
599
  throw error;
495
600
  }
496
601
  }
602
+ getDiscountList() {
603
+ if (!this.store.order)
604
+ return [];
605
+ return this.store.order.getDiscountList();
606
+ }
607
+ async scanCode(code, customerId) {
608
+ this.logMethodStart("scanCode", { code });
609
+ try {
610
+ if (!this.store.order)
611
+ throw new Error("order 模块未初始化");
612
+ const raw = await this.store.order.scanCode(code, customerId);
613
+ if (raw.isAvailable) {
614
+ await this.store.order.recalculateSummary({ createIfMissing: true });
615
+ this.store.order.persistTempOrder();
616
+ }
617
+ this.logMethodSuccess("scanCode", { isAvailable: raw.isAvailable });
618
+ return {
619
+ isAvailable: raw.isAvailable,
620
+ type: raw.type,
621
+ unavailableReason: raw.unavailableReason
622
+ };
623
+ } catch (error) {
624
+ this.logMethodError("scanCode", error);
625
+ throw error;
626
+ }
627
+ }
628
+ async setDiscountSelected(params) {
629
+ var _a, _b, _c;
630
+ this.logMethodStart("setDiscountSelected", params);
631
+ try {
632
+ if (!this.store.order)
633
+ throw new Error("order 模块未初始化");
634
+ const list = this.store.order.getDiscountList();
635
+ const updated = list.map(
636
+ (d) => d.id === params.discountId ? {
637
+ ...d,
638
+ isSelected: params.isSelected,
639
+ isManualSelect: !params.isSelected
640
+ } : d
641
+ );
642
+ const tempOrder = this.store.order.ensureTempOrder();
643
+ const orderStore = this.store.order.store || {};
644
+ const discountModule = orderStore.discount;
645
+ const rulesModule = orderStore.rules;
646
+ const holders = ((_a = tempOrder.holder) == null ? void 0 : _a.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
647
+ let nextDiscountList = updated;
648
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
649
+ if (rulesModule) {
650
+ const result = rulesModule.calcDiscount(
651
+ {
652
+ productList: tempOrder.products,
653
+ discountList: updated,
654
+ holders,
655
+ isFormSubject: !!((_b = tempOrder.holder) == null ? void 0 : _b.type) && tempOrder.holder.type === "form"
656
+ },
657
+ {
658
+ discountId: params.discountId,
659
+ isSelected: params.isSelected
660
+ }
661
+ ) || { productList: tempOrder.products, discountList: updated };
662
+ if (result == null ? void 0 : result.productList) {
663
+ tempOrder.products = result.productList;
664
+ }
665
+ if (result == null ? void 0 : result.discountList) {
666
+ nextDiscountList = result.discountList;
667
+ if (!params.isSelected) {
668
+ const beforeSelectedIds = new Set(
669
+ updated.filter((d) => d.isSelected).map((d) => d.id)
670
+ );
671
+ for (const d of nextDiscountList) {
672
+ if (d.isSelected && !beforeSelectedIds.has(d.id)) {
673
+ d.isSelected = false;
674
+ }
675
+ }
676
+ }
677
+ }
678
+ }
679
+ const selectedResourceIds = new Set(
680
+ nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
681
+ );
682
+ for (const product of tempOrder.products) {
683
+ if ((_c = product._origin) == null ? void 0 : _c.isManualDiscount)
684
+ continue;
685
+ product.discount_list = (product.discount_list || []).filter((pd) => {
686
+ var _a2;
687
+ const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
688
+ return rid != null && selectedResourceIds.has(rid);
689
+ });
690
+ const totalPerUnitDiscount = (product.discount_list || []).reduce(
691
+ (sum, pd) => sum + (pd.amount || 0),
692
+ 0
693
+ );
694
+ const newSellingPrice = new import_decimal.default(product.original_price || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
695
+ product.selling_price = newSellingPrice;
696
+ if (product.metadata) {
697
+ product.metadata.main_product_selling_price = newSellingPrice;
698
+ }
699
+ }
700
+ import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
701
+ await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
702
+ tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
703
+ await this.store.order.recalculateSummary({ createIfMissing: true });
704
+ this.store.order.persistTempOrder();
705
+ this.logMethodSuccess("setDiscountSelected", params);
706
+ } catch (error) {
707
+ this.logMethodError("setDiscountSelected", error);
708
+ throw error;
709
+ }
710
+ }
711
+ async onCustomerLogin(params) {
712
+ this.logMethodStart("onCustomerLogin", { customerId: params.customerId });
713
+ try {
714
+ await this.refreshOrderMarketingAfterLogin({
715
+ customerId: params.customerId
716
+ });
717
+ this.logMethodSuccess("onCustomerLogin", { customerId: params.customerId });
718
+ } catch (error) {
719
+ this.logMethodError("onCustomerLogin", error);
720
+ throw error;
721
+ }
722
+ }
497
723
  // ScanOrder 提交 payload enhancer:
498
724
  // - 给所有 booking 注入 appointment_status: 'started'(扫码点餐语义)
499
725
  // - 给所有 booking 的 metadata 注入 resource_select_type(来自预约规则商品的 resource.type)
@@ -1499,6 +1725,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1499
1725
  }
1500
1726
  };
1501
1727
  var ScanOrderImpl = _ScanOrderImpl;
1728
+ ScanOrderImpl.PISELL1_LOGIN_SUCCESS = "pisell1.login.success";
1502
1729
  // ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
1503
1730
  //
1504
1731
  // 用于物料层持久化 UI 层面的轻量状态(如当前步骤、gate 标记、登录回跳意图等)。
@@ -235,3 +235,9 @@ export interface ScanOrderLoggerRuntimeConfig {
235
235
  }
236
236
  export interface ScanOrderAddLogParams extends ScanOrderLogInput {
237
237
  }
238
+ /** ScanOrder.scanCode 对外的轻量结果(不含 discountList,UI 在 resolve 后调 getDiscountList) */
239
+ export interface ScanOrderScanCodeResult {
240
+ isAvailable: boolean;
241
+ type?: 'server' | string;
242
+ unavailableReason?: 'time_limit' | string;
243
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.506",
4
+ "version": "0.0.508",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",