@pisell/pisellos 2.2.167 → 2.2.168

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.
@@ -150,12 +150,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
150
150
  customerId: number;
151
151
  }): Promise<void>;
152
152
  private recalculateOrderPricesFromQuotation;
153
- scanCode(code: string, customerId?: number): Promise<{
154
- isAvailable: boolean;
155
- discountList: import("../../modules/Discount").Discount[];
156
- type: "server" | "clientCalc";
157
- unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
158
- }>;
153
+ scanCode(code: string, customerId?: number): Promise<import("../../modules/Order/types").OrderScanCodeResult>;
159
154
  /** 获取当前折扣列表(包装 order.getDiscountList) */
160
155
  getDiscountList(): import("../../modules/Discount").Discount[];
161
156
  /** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
@@ -1,49 +0,0 @@
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
- });
@@ -135,6 +135,7 @@ export interface Discount {
135
135
  appliedProductDetails: ApplicableProductDetails[];
136
136
  isDisabledForProductUsed?: boolean;
137
137
  amount?: number;
138
+ customer_id?: number | string | null;
138
139
  extension_data?: ExtensionData[];
139
140
  total_order_behavior_count?: number;
140
141
  today_order_behavior_count?: number;
@@ -3,10 +3,9 @@ import { BaseModule } from '../BaseModule';
3
3
  import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CheckoutOrderParams, CancelOrderParams, ChangeBookingStatusParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
5
  import { type SubmitPayloadEnhancer } from './utils';
6
- import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions } from './types';
6
+ import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, OrderScanCodeResult, ReplaceTempOrderOptions } from './types';
7
7
  import type { ICustomer } from '../AccountList/types';
8
8
  import type { Discount } from '../Discount/types';
9
- import { UnavailableReason } from '../Rules/types';
10
9
  export declare class OrderModule extends BaseModule implements Module, OrderModuleAPI {
11
10
  protected defaultName: string;
12
11
  protected defaultVersion: string;
@@ -48,12 +47,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
48
47
  apply?: boolean;
49
48
  }): Promise<Discount[]>;
50
49
  getDiscountList(): Discount[];
51
- scanCode(code: string, customerId?: number): Promise<{
52
- isAvailable: boolean;
53
- discountList: Discount[];
54
- type: 'server' | 'clientCalc';
55
- unavailableReason?: UnavailableReason;
56
- }>;
50
+ scanCode(code: string, customerId?: number): Promise<OrderScanCodeResult>;
57
51
  applyDiscount(): void;
58
52
  initTempOrder(params: {
59
53
  cacheId?: string;
@@ -190,7 +184,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
190
184
  private logSubmitBackendRejected;
191
185
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
192
186
  createOrder(params: CommitOrderParams['query']): {
193
- type: "virtual" | "appointment_booking";
187
+ type: "appointment_booking" | "virtual";
194
188
  platform: string;
195
189
  sales_channel: string;
196
190
  order_sales_channel: string;
@@ -207,6 +207,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
207
207
  type: "clientCalc",
208
208
  isAvailable: false,
209
209
  discountList: this.getDiscountList(),
210
+ scannedDiscountList: resultDiscountList,
210
211
  unavailableReason: import_types2.UnavailableReason.Unknown
211
212
  };
212
213
  }
@@ -214,7 +215,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
214
215
  return {
215
216
  type: "server",
216
217
  isAvailable: false,
217
- discountList: this.getDiscountList()
218
+ discountList: this.getDiscountList(),
219
+ scannedDiscountList: resultDiscountList
218
220
  };
219
221
  }
220
222
  const withScanList = resultDiscountList.map((item) => ({
@@ -226,7 +228,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
226
228
  return {
227
229
  type: "clientCalc",
228
230
  isAvailable: true,
229
- discountList: this.getDiscountList()
231
+ discountList: this.getDiscountList(),
232
+ scannedDiscountList: resultDiscountList
230
233
  };
231
234
  }
232
235
  const tempOrder = this.store.tempOrder;
@@ -247,6 +250,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
247
250
  type: "clientCalc",
248
251
  isAvailable: isAvailable || false,
249
252
  discountList: newDiscountList || this.getDiscountList(),
253
+ scannedDiscountList: resultDiscountList,
250
254
  unavailableReason
251
255
  };
252
256
  }
@@ -2,6 +2,7 @@ import { CartItem } from '../Cart/types';
2
2
  import type { DiscountModule } from '../Discount';
3
3
  import type { RulesModule } from '../Rules';
4
4
  import type { Discount } from '../Discount/types';
5
+ import type { UnavailableReason } from '../Rules/types';
5
6
  import type { SubmitPayloadEnhancer } from './utils';
6
7
  import type { PaymentItem } from '../Payment/types';
7
8
  import type { ICustomer } from '../AccountList/types';
@@ -48,6 +49,13 @@ export interface OrderCustomerChangePayload {
48
49
  patch: OrderCustomerView;
49
50
  snapshot: ICustomer | null;
50
51
  }
52
+ export interface OrderScanCodeResult {
53
+ isAvailable: boolean;
54
+ discountList: Discount[];
55
+ scannedDiscountList: Discount[];
56
+ type: 'server' | 'clientCalc';
57
+ unavailableReason?: UnavailableReason;
58
+ }
51
59
  export interface OrderProductIdentity {
52
60
  product_id: number | null;
53
61
  product_variant_id: number;
@@ -572,7 +572,7 @@ function buildSubmitPayload(params) {
572
572
  note: tempOrder.note || "",
573
573
  delivery_type: tempOrder.delivery_type || "nil",
574
574
  schedule_date: scheduleDate,
575
- created_at: tempOrder.created_at || formatDateTime(now),
575
+ // created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
576
576
  bookings: (tempOrder.bookings || []).filter(
577
577
  (booking) => Number(booking.parent_id) !== 0
578
578
  ).map((booking) => normalizeSubmitBooking(booking)),
@@ -33,6 +33,13 @@ __export(filterOrders_exports, {
33
33
  });
34
34
  module.exports = __toCommonJS(filterOrders_exports);
35
35
  var import_dayjs = __toESM(require("dayjs"));
36
+ function getOrderPaymentCodes(order) {
37
+ const payments = order.payments;
38
+ if (!Array.isArray(payments) || payments.length === 0) {
39
+ return [];
40
+ }
41
+ return payments.map((item) => item == null ? void 0 : item.code).filter((code) => typeof code === "string" && code.length > 0);
42
+ }
36
43
  function filterOrders(orders, filters) {
37
44
  const safeFilters = filters || {};
38
45
  if (!orders || !Array.isArray(orders)) {
@@ -133,26 +140,27 @@ function filterOrders(orders, filters) {
133
140
  }
134
141
  }
135
142
  if (safeFilters.payment_methods && safeFilters.payment_methods.length > 0) {
136
- if (!order.payment_methods || !Array.isArray(order.payment_methods) || order.payment_methods.length === 0) {
143
+ const orderPaymentCodes = getOrderPaymentCodes(order);
144
+ if (orderPaymentCodes.length === 0) {
137
145
  rejected.push({
138
146
  order_id: order.order_id,
139
147
  order_number: order.order_number,
140
148
  reason: {
141
149
  field: "payment_methods",
142
- actual: order.payment_methods,
150
+ actual: order.payments,
143
151
  expected: safeFilters.payment_methods
144
152
  }
145
153
  });
146
154
  return false;
147
155
  }
148
- const hasMatch = order.payment_methods.some((pm) => safeFilters.payment_methods.includes(pm));
156
+ const hasMatch = orderPaymentCodes.some((code) => safeFilters.payment_methods.includes(code));
149
157
  if (!hasMatch) {
150
158
  rejected.push({
151
159
  order_id: order.order_id,
152
160
  order_number: order.order_number,
153
161
  reason: {
154
162
  field: "payment_methods",
155
- actual: order.payment_methods,
163
+ actual: orderPaymentCodes,
156
164
  expected: safeFilters.payment_methods
157
165
  }
158
166
  });
@@ -780,6 +780,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
780
780
  tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
781
781
  await this.store.order.recalculateSummary({ createIfMissing: true });
782
782
  this.store.order.persistTempOrder();
783
+ this.effectsEmit("onDiscountApplied", {
784
+ productList: tempOrder.products,
785
+ discountList: nextDiscountList,
786
+ selectedDiscountList: tempOrder.discount_list,
787
+ tempOrder
788
+ });
783
789
  } catch (error) {
784
790
  throw error;
785
791
  }
@@ -4,6 +4,7 @@ import type { ProductData } from '../../modules';
4
4
  import { type BookingContextConfig, type BookingContextDateInput, type BookingContextResource, type BookingContextResourceMap, type BookingContextState, type InitBookingContextParams, type LoadBookingConfigParams, type LoadBookingResourcesParams, type ResourceError, type BookingCalcContext } from '../../modules/BookingContext';
5
5
  import type { OrderCustomerView } from '../../modules/Order/types';
6
6
  import { BaseSalesImpl } from '../BaseSales';
7
+ import type { BaseSalesScanCodeResult } from '../BaseSales/types';
7
8
  import type { ISalesDetail } from '../BaseSales/utils/parseSalesResponse';
8
9
  import type { LoadSalesDetailParams } from '../../modules/Order/types';
9
10
  import { AddProductDecideContext, AddProductRequiresDetailPayload } from './utils/addProductDecision';
@@ -43,6 +44,14 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
43
44
  * 让现有 setActiveCustomer / getActiveCustomer 调用方零成本拿到详情态客户。
44
45
  */
45
46
  loadSalesDetail(orderIdOrParams: number | string | LoadSalesDetailParams): Promise<ISalesDetail>;
47
+ scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
48
+ private hydrateOrderCustomerFromScanDiscounts;
49
+ private getDiscountCustomerId;
50
+ private resolveCustomerByDiscountCustomerId;
51
+ private findCustomerById;
52
+ private normalizeCustomer;
53
+ private getRawCustomerId;
54
+ private hasUsableCustomerDetails;
46
55
  /**
47
56
  * 更新当前预约的 appointment_status。
48
57
  *
@@ -251,7 +260,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
251
260
  * 获取当前的客户搜索条件
252
261
  * @returns 当前搜索条件
253
262
  */
254
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
263
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
255
264
  /**
256
265
  * 获取客户列表状态(包含滚动加载相关状态)
257
266
  * @returns 客户状态
@@ -133,6 +133,83 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
133
133
  }
134
134
  return sales;
135
135
  }
136
+ async scanPromotionCode(code, customerId) {
137
+ if (!this.store.order)
138
+ throw new Error("order 模块未初始化");
139
+ const raw = await this.store.order.scanCode(code, customerId);
140
+ if (raw.isAvailable) {
141
+ await this.hydrateOrderCustomerFromScanDiscounts(raw.scannedDiscountList);
142
+ await this.store.order.recalculateSummary({ createIfMissing: true });
143
+ this.store.order.persistTempOrder();
144
+ }
145
+ return {
146
+ isAvailable: raw.isAvailable,
147
+ type: raw.type,
148
+ unavailableReason: raw.unavailableReason
149
+ };
150
+ }
151
+ async hydrateOrderCustomerFromScanDiscounts(discounts) {
152
+ const currentOrderCustomer = this.store.order.getOrderCustomer();
153
+ if (currentOrderCustomer)
154
+ return;
155
+ const customerId = this.getDiscountCustomerId(discounts);
156
+ if (!customerId)
157
+ return;
158
+ const customer = await this.resolveCustomerByDiscountCustomerId(customerId);
159
+ if (!customer)
160
+ return;
161
+ this.store.customer.setSelectedCustomer(customer);
162
+ this.setOrderCustomer(customer);
163
+ }
164
+ getDiscountCustomerId(discounts) {
165
+ const discount = discounts.find((item) => item.customer_id != null);
166
+ const customerId = Number(discount == null ? void 0 : discount.customer_id);
167
+ if (!Number.isFinite(customerId) || customerId <= 0)
168
+ return null;
169
+ return customerId;
170
+ }
171
+ async resolveCustomerByDiscountCustomerId(customerId) {
172
+ var _a;
173
+ const localCustomers = this.store.customer.getCustomers();
174
+ const localCustomer = this.findCustomerById(localCustomers, customerId);
175
+ const normalizedLocalCustomer = localCustomer ? this.normalizeCustomer(localCustomer) : null;
176
+ if (normalizedLocalCustomer && this.hasUsableCustomerDetails(normalizedLocalCustomer)) {
177
+ return normalizedLocalCustomer;
178
+ }
179
+ const result = await this.store.customer.getCustomerList({
180
+ ids: [customerId],
181
+ skip: 1,
182
+ num: 1
183
+ });
184
+ const remoteCustomer = this.findCustomerById((result == null ? void 0 : result.list) || [], customerId) || ((_a = result == null ? void 0 : result.list) == null ? void 0 : _a[0]) || null;
185
+ return remoteCustomer ? this.normalizeCustomer(remoteCustomer) : null;
186
+ }
187
+ findCustomerById(customers = [], customerId) {
188
+ return customers.find((customer) => {
189
+ const rawId = this.getRawCustomerId(customer);
190
+ return rawId !== null && String(rawId) === String(customerId);
191
+ }) || null;
192
+ }
193
+ normalizeCustomer(customer) {
194
+ const raw = customer;
195
+ const rawId = this.getRawCustomerId(customer);
196
+ const name = customer.name || raw.display_name || raw.nickname || raw.customer_name || [raw.first_name, raw.last_name].filter(Boolean).join(" ") || "";
197
+ return {
198
+ ...customer,
199
+ id: rawId ?? customer.id,
200
+ name,
201
+ phone: customer.phone ?? raw.phone ?? raw.mobile ?? "",
202
+ email: customer.email ?? raw.email ?? "",
203
+ country_calling_code: customer.country_calling_code ?? raw.country_calling_code ?? ""
204
+ };
205
+ }
206
+ getRawCustomerId(customer) {
207
+ const raw = customer;
208
+ return customer.id ?? raw.customer_id ?? raw.customerId ?? null;
209
+ }
210
+ hasUsableCustomerDetails(customer) {
211
+ return !!(customer.name || customer.phone || customer.email || customer.display_name || customer.customer_name);
212
+ }
136
213
  /**
137
214
  * 更新当前预约的 appointment_status。
138
215
  *
@@ -150,12 +150,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
150
150
  customerId: number;
151
151
  }): Promise<void>;
152
152
  private recalculateOrderPricesFromQuotation;
153
- scanCode(code: string, customerId?: number): Promise<{
154
- isAvailable: boolean;
155
- discountList: import("../../modules/Discount").Discount[];
156
- type: "server" | "clientCalc";
157
- unavailableReason?: import("../../modules/Rules/types").UnavailableReason | undefined;
158
- }>;
153
+ scanCode(code: string, customerId?: number): Promise<import("../../modules/Order/types").OrderScanCodeResult>;
159
154
  /** 获取当前折扣列表(包装 order.getDiscountList) */
160
155
  getDiscountList(): import("../../modules/Discount").Discount[];
161
156
  /** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.167",
4
+ "version": "2.2.168",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",