@pisell/pisellos 2.2.171 → 2.2.172
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.
- package/dist/modules/BookingContext/index.d.ts +37 -0
- package/dist/modules/BookingContext/index.js +436 -0
- package/dist/modules/BookingContext/types.d.ts +102 -0
- package/dist/modules/BookingContext/types.js +51 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +193 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +137 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +75 -0
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +215 -0
- package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/dist/modules/BookingContext/utils/flexible.js +56 -0
- package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
- package/dist/modules/BookingContext/utils/index.d.ts +11 -0
- package/dist/modules/BookingContext/utils/index.js +11 -0
- package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/dist/modules/BookingContext/utils/noResource.js +77 -0
- package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/dist/modules/BookingContext/utils/productExtend.js +339 -0
- package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
- package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
- package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
- package/dist/modules/BookingContext/utils/resources.js +486 -0
- package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
- package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
- package/dist/modules/Customer/index.d.ts +6 -0
- package/dist/modules/Customer/index.js +129 -83
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Discount/index.d.ts +2 -4
- package/dist/modules/Discount/index.js +8 -93
- package/dist/modules/Discount/types.d.ts +1 -7
- package/dist/modules/Order/index.d.ts +47 -16
- package/dist/modules/Order/index.js +743 -334
- package/dist/modules/Order/types.d.ts +57 -17
- package/dist/modules/Order/types.js +2 -0
- package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
- package/dist/modules/Order/utils/manualProductDiscount.js +212 -0
- package/dist/modules/Order/utils.d.ts +23 -1
- package/dist/modules/Order/utils.js +139 -30
- package/dist/modules/Quotation/index.js +16 -5
- package/dist/modules/Rules/index.d.ts +4 -0
- package/dist/modules/Rules/index.js +26 -10
- package/dist/modules/SalesSummary/index.js +4 -2
- package/dist/modules/Schedule/index.js +6 -2
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +2 -1
- package/dist/server/index.js +10 -6
- package/dist/server/modules/order/utils/filterOrders.js +20 -6
- package/dist/server/modules/products/index.js +9 -8
- package/dist/server/modules/schedule/index.js +13 -6
- package/dist/solution/BaseSales/index.d.ts +65 -7
- package/dist/solution/BaseSales/index.js +1066 -315
- package/dist/solution/BaseSales/types.d.ts +53 -1
- package/dist/solution/BaseSales/types.js +3 -1
- package/dist/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
- package/dist/solution/BaseSales/utils/quotationPrice.js +159 -0
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +65 -15
- package/dist/solution/BaseSales/utils.js +46 -8
- package/dist/solution/BookingTicket/index.d.ts +134 -2
- package/dist/solution/BookingTicket/index.js +768 -175
- package/dist/solution/BookingTicket/types.d.ts +2 -0
- package/dist/solution/BookingTicket/types.js +3 -0
- package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +113 -0
- package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
- package/dist/solution/ScanOrder/index.d.ts +9 -3
- package/dist/solution/ScanOrder/index.js +231 -128
- package/dist/solution/ScanOrder/utils.js +46 -8
- package/dist/solution/ShopDiscount/index.d.ts +0 -1
- package/dist/solution/ShopDiscount/index.js +18 -23
- package/dist/solution/VenueBooking/index.d.ts +5 -9
- package/dist/solution/VenueBooking/index.js +103 -55
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
- package/dist/solution/VenueBooking/utils/slotMerge.js +10 -0
- package/lib/modules/BookingContext/index.d.ts +37 -0
- package/lib/modules/BookingContext/index.js +297 -0
- package/lib/modules/BookingContext/types.d.ts +102 -0
- package/lib/modules/BookingContext/types.js +34 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +207 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +141 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +75 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +198 -0
- package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
- package/lib/modules/BookingContext/utils/flexible.js +80 -0
- package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
- package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
- package/lib/modules/BookingContext/utils/index.d.ts +11 -0
- package/lib/modules/BookingContext/utils/index.js +43 -0
- package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
- package/lib/modules/BookingContext/utils/noResource.js +90 -0
- package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
- package/lib/modules/BookingContext/utils/productExtend.js +283 -0
- package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
- package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
- package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
- package/lib/modules/BookingContext/utils/resourceSelection.js +46 -0
- package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
- package/lib/modules/BookingContext/utils/resources.js +377 -0
- package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
- package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
- package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
- package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
- package/lib/modules/Customer/index.d.ts +6 -0
- package/lib/modules/Customer/index.js +26 -11
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Discount/index.d.ts +2 -4
- package/lib/modules/Discount/index.js +8 -63
- package/lib/modules/Discount/types.d.ts +1 -7
- package/lib/modules/Order/index.d.ts +47 -16
- package/lib/modules/Order/index.js +389 -90
- package/lib/modules/Order/types.d.ts +57 -17
- package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
- package/lib/modules/Order/utils/manualProductDiscount.js +207 -0
- package/lib/modules/Order/utils.d.ts +23 -1
- package/lib/modules/Order/utils.js +145 -21
- package/lib/modules/Quotation/index.js +17 -6
- package/lib/modules/Rules/index.d.ts +4 -0
- package/lib/modules/Rules/index.js +22 -14
- package/lib/modules/SalesSummary/index.js +4 -2
- package/lib/modules/Schedule/index.js +3 -1
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +3 -1
- package/lib/server/index.js +2 -0
- package/lib/server/modules/order/utils/filterOrders.js +12 -4
- package/lib/server/modules/products/index.js +8 -9
- package/lib/server/modules/schedule/index.js +2 -1
- package/lib/solution/BaseSales/index.d.ts +65 -7
- package/lib/solution/BaseSales/index.js +492 -20
- package/lib/solution/BaseSales/types.d.ts +53 -1
- package/lib/solution/BaseSales/types.js +3 -1
- package/lib/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
- package/lib/solution/BaseSales/utils/quotationPrice.js +201 -0
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +70 -11
- package/lib/solution/BaseSales/utils.js +46 -6
- package/lib/solution/BookingTicket/index.d.ts +134 -2
- package/lib/solution/BookingTicket/index.js +341 -8
- package/lib/solution/BookingTicket/types.d.ts +2 -0
- package/lib/solution/BookingTicket/types.js +6 -0
- package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +113 -0
- package/lib/solution/BookingTicket/utils/addProductDecision.js +318 -0
- package/lib/solution/ScanOrder/index.d.ts +9 -3
- package/lib/solution/ScanOrder/index.js +147 -66
- package/lib/solution/ScanOrder/utils.js +46 -6
- package/lib/solution/ShopDiscount/index.d.ts +0 -1
- package/lib/solution/ShopDiscount/index.js +2 -4
- package/lib/solution/VenueBooking/index.d.ts +5 -9
- package/lib/solution/VenueBooking/index.js +50 -14
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
- package/lib/solution/VenueBooking/utils/slotMerge.js +10 -0
- package/package.json +2 -2
|
@@ -2,9 +2,12 @@ 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';
|
|
9
|
+
import type { OrderProductDiscountItem } from '../../server/modules/order/types';
|
|
10
|
+
export type { OrderProductDiscountItem } from '../../server/modules/order/types';
|
|
8
11
|
export declare enum OrderHooks {
|
|
9
12
|
OnOrderCreate = "order:onOrderCreate",
|
|
10
13
|
OnOrderUpdate = "order:onOrderUpdate",
|
|
@@ -48,6 +51,13 @@ export interface OrderCustomerChangePayload {
|
|
|
48
51
|
patch: OrderCustomerView;
|
|
49
52
|
snapshot: ICustomer | null;
|
|
50
53
|
}
|
|
54
|
+
export interface OrderScanCodeResult {
|
|
55
|
+
isAvailable: boolean;
|
|
56
|
+
discountList: Discount[];
|
|
57
|
+
scannedDiscountList: Discount[];
|
|
58
|
+
type: 'server' | 'clientCalc';
|
|
59
|
+
unavailableReason?: UnavailableReason;
|
|
60
|
+
}
|
|
51
61
|
export interface OrderProductIdentity {
|
|
52
62
|
product_id: number | null;
|
|
53
63
|
product_variant_id: number;
|
|
@@ -66,7 +76,7 @@ export interface OrderProduct extends OrderProductIdentity {
|
|
|
66
76
|
original_price: string;
|
|
67
77
|
tax_fee: string;
|
|
68
78
|
is_charge_tax: number;
|
|
69
|
-
discount_list:
|
|
79
|
+
discount_list: OrderProductDiscountItem[];
|
|
70
80
|
product_bundle: any[];
|
|
71
81
|
booking_uid?: string;
|
|
72
82
|
metadata: Record<string, any>;
|
|
@@ -103,11 +113,11 @@ export interface OrderSummary {
|
|
|
103
113
|
export interface OrderTempOrder {
|
|
104
114
|
order_id: number | null;
|
|
105
115
|
external_sale_number: string;
|
|
106
|
-
order_number: string;
|
|
107
|
-
shop_order_number: string;
|
|
108
|
-
shop_full_order_number: string;
|
|
116
|
+
order_number: string | null;
|
|
117
|
+
shop_order_number: string | null;
|
|
118
|
+
shop_full_order_number: string | null;
|
|
109
119
|
type: string;
|
|
110
|
-
business_code
|
|
120
|
+
business_code?: string;
|
|
111
121
|
platform: string;
|
|
112
122
|
sales_channel: string;
|
|
113
123
|
order_sales_channel: string;
|
|
@@ -141,7 +151,7 @@ export interface OrderTempOrder {
|
|
|
141
151
|
bookings: any[];
|
|
142
152
|
payments: any[];
|
|
143
153
|
surcharges: any[];
|
|
144
|
-
discount_list
|
|
154
|
+
discount_list?: any[];
|
|
145
155
|
relation_forms: any[];
|
|
146
156
|
contacts: any[];
|
|
147
157
|
contacts_info: Record<string, any> | null;
|
|
@@ -157,7 +167,7 @@ export interface OrderSubmitProduct extends Omit<OrderProduct, 'unique_identific
|
|
|
157
167
|
payment_price: string;
|
|
158
168
|
product_sku: Record<string, any>;
|
|
159
169
|
}
|
|
160
|
-
export interface OrderSubmitPayload extends Omit<OrderTempOrder, 'platform' | 'products' | '_extend' | 'customer' | '
|
|
170
|
+
export interface OrderSubmitPayload extends Omit<OrderTempOrder, 'platform' | 'products' | '_extend' | 'customer' | 'discount_list'> {
|
|
161
171
|
platform: string;
|
|
162
172
|
request_unique_idempotency_token?: string;
|
|
163
173
|
form_record_ids?: Array<{
|
|
@@ -176,16 +186,32 @@ export interface OrderState {
|
|
|
176
186
|
discount: DiscountModule | null;
|
|
177
187
|
rules: RulesModule | null;
|
|
178
188
|
}
|
|
189
|
+
export interface ReplaceTempOrderOptions {
|
|
190
|
+
recalculateSummary?: boolean;
|
|
191
|
+
persist?: boolean;
|
|
192
|
+
saveDraft?: boolean;
|
|
193
|
+
}
|
|
194
|
+
export type AddProductBookingInput = Record<string, any>;
|
|
179
195
|
/** 更新购物车行:仅传 SKU 时命中同 SKU 第一行;多行同 SKU 须传 unique_identification_number / 选项指纹等 */
|
|
180
|
-
export interface
|
|
196
|
+
export interface UpdateOrderProductParams {
|
|
181
197
|
product_id: number | null;
|
|
182
198
|
product_variant_id: number;
|
|
183
199
|
updates: Partial<OrderProduct>;
|
|
184
200
|
unique_identification_number?: string;
|
|
201
|
+
identity_key?: string;
|
|
185
202
|
product_option_item?: any[];
|
|
186
203
|
product_bundle?: any[];
|
|
204
|
+
booking?: AddProductBookingInput;
|
|
205
|
+
}
|
|
206
|
+
/** 仅更新购物车行数量;行定位语义与 updateOrderProduct / removeProductFromOrder 保持一致 */
|
|
207
|
+
export interface UpdateOrderProductQuantityParams extends OrderProductIdentity {
|
|
208
|
+
num: number;
|
|
209
|
+
identity_key?: string;
|
|
210
|
+
}
|
|
211
|
+
export interface UpdateOrderBookingParams {
|
|
212
|
+
unique_identification_number: string;
|
|
213
|
+
updates: AddProductBookingInput;
|
|
187
214
|
}
|
|
188
|
-
export type AddProductBookingInput = Record<string, any>;
|
|
189
215
|
export interface OrderProductMergeDecisionContext {
|
|
190
216
|
incomingProduct: Partial<OrderProduct> & OrderProductIdentity;
|
|
191
217
|
normalizedIncoming: OrderProduct;
|
|
@@ -236,10 +262,11 @@ export interface SubmitSalesOrderParams {
|
|
|
236
262
|
query: {
|
|
237
263
|
order_id: number | null;
|
|
238
264
|
external_sale_number: string;
|
|
239
|
-
order_number: string;
|
|
240
|
-
shop_order_number: string;
|
|
265
|
+
order_number: string | null;
|
|
266
|
+
shop_order_number: string | null;
|
|
267
|
+
shop_full_order_number: string | null;
|
|
241
268
|
type: string;
|
|
242
|
-
business_code
|
|
269
|
+
business_code?: string;
|
|
243
270
|
platform: string;
|
|
244
271
|
request_unique_idempotency_token?: string;
|
|
245
272
|
sales_channel: string;
|
|
@@ -271,7 +298,6 @@ export interface SubmitSalesOrderParams {
|
|
|
271
298
|
bookings: OrderSubmitBooking[];
|
|
272
299
|
payments: any[];
|
|
273
300
|
surcharges?: any[];
|
|
274
|
-
discount_list: any[];
|
|
275
301
|
relation_forms: any[];
|
|
276
302
|
form_record_ids?: OrderSubmitFormRecord[];
|
|
277
303
|
contacts: any[];
|
|
@@ -350,6 +376,7 @@ export interface SyncPaymentsToOrderParams {
|
|
|
350
376
|
paymentStatus?: SubmitSalesOrderParams['query']['payment_status'];
|
|
351
377
|
submitWhenPaid?: boolean;
|
|
352
378
|
smallTicketDataFlag?: number;
|
|
379
|
+
channel?: string;
|
|
353
380
|
}
|
|
354
381
|
export interface SyncPaymentsToOrderResult<T = any> {
|
|
355
382
|
isFullyPaid: boolean;
|
|
@@ -446,6 +473,7 @@ export interface OrderModuleAPI {
|
|
|
446
473
|
}) => void;
|
|
447
474
|
getTempOrder: () => OrderTempOrder | null;
|
|
448
475
|
ensureTempOrder: () => OrderTempOrder;
|
|
476
|
+
replaceTempOrder: (tempOrder: OrderTempOrder, options?: ReplaceTempOrderOptions) => Promise<OrderTempOrder>;
|
|
449
477
|
addNewOrder: () => Promise<OrderTempOrder>;
|
|
450
478
|
restoreOrder: () => OrderTempOrder;
|
|
451
479
|
getOrderProducts: () => OrderProduct[];
|
|
@@ -458,15 +486,25 @@ export interface OrderModuleAPI {
|
|
|
458
486
|
getOrderSyncState: () => OrderSyncState;
|
|
459
487
|
getOrderAmountSnapshot: () => OrderAmountSnapshot | null;
|
|
460
488
|
getTempOrderNote: () => string;
|
|
461
|
-
updateTempOrderNote:
|
|
489
|
+
updateTempOrderNote: {
|
|
490
|
+
(note: string): string;
|
|
491
|
+
(note: string, sync: true): Promise<string>;
|
|
492
|
+
(note: string, sync: boolean): string | Promise<string>;
|
|
493
|
+
};
|
|
462
494
|
updateTempOrderShopDiscount: (amount: string | number) => string;
|
|
463
495
|
updateTempOrderCustomer: (customer: UpdateTempOrderCustomerInput) => OrderSnapshot['customer'];
|
|
464
496
|
updateTempOrderBuzzer: (buzzer: string) => string;
|
|
465
497
|
updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
|
|
466
498
|
addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput) => Promise<OrderProduct[]>;
|
|
467
|
-
|
|
499
|
+
updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
|
|
500
|
+
updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
|
|
501
|
+
updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
|
|
468
502
|
removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
|
|
469
503
|
persistTempOrder: () => void;
|
|
504
|
+
/** 运行时切换 tempOrder localStorage 持久化开关。 */
|
|
505
|
+
setEnableTempOrderPersist: (enabled: boolean) => void;
|
|
506
|
+
/** 当前是否启用 tempOrder localStorage 持久化。 */
|
|
507
|
+
isTempOrderPersistEnabled: () => boolean;
|
|
470
508
|
submitTempOrder: <T = any>(params?: {
|
|
471
509
|
cacheId?: string;
|
|
472
510
|
platform?: string;
|
|
@@ -516,8 +554,10 @@ export interface OrderModuleAPI {
|
|
|
516
554
|
clearOrderCustomer: () => void;
|
|
517
555
|
loadDiscountConfig: (params: {
|
|
518
556
|
customerId: number;
|
|
519
|
-
action?: 'create';
|
|
520
|
-
|
|
557
|
+
action?: 'create' | 'edit';
|
|
558
|
+
orderId?: number;
|
|
559
|
+
apply?: boolean;
|
|
560
|
+
}) => Promise<Discount[]>;
|
|
521
561
|
getDiscountList: () => Discount[];
|
|
522
562
|
applyDiscount: () => void;
|
|
523
563
|
/**
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** 解析商品行数量(checkout 协议 product_num 语义 = 当前行 num) */
|
|
2
|
+
export declare function resolveSafeProductNum(num?: number | null): number;
|
|
3
|
+
/**
|
|
4
|
+
* 将 discount_list 中 type=product 项的 product_num 同步为当前商品数量。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* syncManualProductDiscountProductNum(line.discount_list, line.num);
|
|
8
|
+
*/
|
|
9
|
+
export declare function syncManualProductDiscountProductNum(discountList: any[] | undefined | null, productNum?: number | null): any[];
|
|
10
|
+
/** 从多源解析改价前行总价(与 cacheItem._extend.origin_total 语义一致) */
|
|
11
|
+
export declare function resolveManualDiscountOriginTotal(sources: {
|
|
12
|
+
originTotal?: unknown;
|
|
13
|
+
extendOriginTotal?: unknown;
|
|
14
|
+
originExtendOriginTotal?: unknown;
|
|
15
|
+
sourceExtendOriginTotal?: unknown;
|
|
16
|
+
catalogUnitPrice?: unknown;
|
|
17
|
+
quantity?: number;
|
|
18
|
+
}): number;
|
|
19
|
+
/** 从 payload / extend / origin 解析手动折扣原因 */
|
|
20
|
+
export declare function resolveManualDiscountReasonFromSources(sources: {
|
|
21
|
+
discountReason?: unknown;
|
|
22
|
+
extendDiscountReason?: unknown;
|
|
23
|
+
originExtendDiscountReason?: unknown;
|
|
24
|
+
}): string;
|
|
25
|
+
/** 是否带手动改价标记(price_override / is_manual_discount) */
|
|
26
|
+
export declare function hasManualProductDiscountFlag(metadata?: Record<string, any> | null): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* normalize 兜底:手动改价但 discount_list 缺 type=product 时,按行级原价/折后价补写。
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ensureManualProductDiscountList({
|
|
32
|
+
* discountList: [],
|
|
33
|
+
* metadata: { price_override: '5', is_manual_discount: 1 },
|
|
34
|
+
* originalPrice: '11.00',
|
|
35
|
+
* sellingPrice: '5.00',
|
|
36
|
+
* quantity: 1,
|
|
37
|
+
* });
|
|
38
|
+
*/
|
|
39
|
+
export declare function ensureManualProductDiscountList(params: {
|
|
40
|
+
discountList?: any[] | null;
|
|
41
|
+
metadata?: Record<string, any> | null;
|
|
42
|
+
originalPrice: string | number;
|
|
43
|
+
sellingPrice: string | number;
|
|
44
|
+
quantity?: number;
|
|
45
|
+
}): any[];
|
|
46
|
+
/** 商品手动折扣 discount_list 项(checkout 协议,type = product) */
|
|
47
|
+
export interface ManualProductDiscountItem {
|
|
48
|
+
amount: number;
|
|
49
|
+
type: 'product';
|
|
50
|
+
discount: {
|
|
51
|
+
message: string;
|
|
52
|
+
discountway: string;
|
|
53
|
+
product_num: number;
|
|
54
|
+
discount_per: string;
|
|
55
|
+
discount_type: 'discount' | 'change_price';
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 从 discount_list 中取手动改价项(type = product)。
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const manual = findManualProductDiscountItem(product.discount_list);
|
|
63
|
+
* manual?.discount.message; // 折扣原因
|
|
64
|
+
*/
|
|
65
|
+
export declare function findManualProductDiscountItem(discountList?: any[] | null): ManualProductDiscountItem | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* 解析折扣原因:优先 discount_list[type=product].discount.message。
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* resolveManualDiscountMessage(line.discount_list, line.metadata?.legacy_reason);
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveManualDiscountMessage(discountList?: any[] | null, fallback?: string): string;
|
|
73
|
+
/** 去掉 discount_list 中已有的手动改价项,避免重复叠加 */
|
|
74
|
+
export declare function stripManualProductDiscountItems(discountList?: any[] | null): any[];
|
|
75
|
+
/**
|
|
76
|
+
* 由改价前后行总价构建手动折扣项;amount = |originTotal - sellingTotal|(行级差额)。
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* buildManualProductDiscountItem({
|
|
80
|
+
* originTotal: 11,
|
|
81
|
+
* sellingTotal: 4,
|
|
82
|
+
* quantity: 1,
|
|
83
|
+
* message: 'VIP',
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildManualProductDiscountItem(params: {
|
|
87
|
+
originTotal: number;
|
|
88
|
+
sellingTotal: number;
|
|
89
|
+
quantity?: number;
|
|
90
|
+
message?: string;
|
|
91
|
+
discountway?: string;
|
|
92
|
+
discount_per?: string;
|
|
93
|
+
}): ManualProductDiscountItem;
|
|
94
|
+
/**
|
|
95
|
+
* 将手动改价项合并进 discount_list(替换已有 type=product 项)。
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* mergeManualProductDiscountIntoList(coupons, manualItem);
|
|
99
|
+
*/
|
|
100
|
+
export declare function mergeManualProductDiscountIntoList(discountList: any[] | undefined | null, manualItem: ManualProductDiscountItem | null | undefined): any[];
|
|
101
|
+
/** 是否应写入手动改价 discount_list 项 */
|
|
102
|
+
export declare function shouldBuildManualProductDiscount(params: {
|
|
103
|
+
hasPriceOverride?: boolean;
|
|
104
|
+
originTotal?: number;
|
|
105
|
+
sellingTotal?: number;
|
|
106
|
+
}): boolean;
|
|
@@ -0,0 +1,212 @@
|
|
|
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
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
7
|
+
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; }
|
|
8
|
+
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; }
|
|
9
|
+
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; }
|
|
10
|
+
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; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
12
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
|
+
import Decimal from 'decimal.js';
|
|
14
|
+
|
|
15
|
+
/** 解析商品行数量(checkout 协议 product_num 语义 = 当前行 num) */
|
|
16
|
+
export function resolveSafeProductNum(num) {
|
|
17
|
+
var parsed = Number(num);
|
|
18
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return 1;
|
|
19
|
+
return Math.floor(parsed);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 将 discount_list 中 type=product 项的 product_num 同步为当前商品数量。
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* syncManualProductDiscountProductNum(line.discount_list, line.num);
|
|
27
|
+
*/
|
|
28
|
+
export function syncManualProductDiscountProductNum(discountList, productNum) {
|
|
29
|
+
var quantity = resolveSafeProductNum(productNum);
|
|
30
|
+
return (discountList || []).map(function (item) {
|
|
31
|
+
if ((item === null || item === void 0 ? void 0 : item.type) !== 'product') return item;
|
|
32
|
+
return _objectSpread(_objectSpread({}, item), {}, {
|
|
33
|
+
discount: _objectSpread(_objectSpread({}, item.discount || {}), {}, {
|
|
34
|
+
product_num: quantity
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 从多源解析改价前行总价(与 cacheItem._extend.origin_total 语义一致) */
|
|
41
|
+
export function resolveManualDiscountOriginTotal(sources) {
|
|
42
|
+
var _sources$quantity;
|
|
43
|
+
var candidates = [sources.originTotal, sources.extendOriginTotal, sources.originExtendOriginTotal, sources.sourceExtendOriginTotal];
|
|
44
|
+
for (var _i = 0, _candidates = candidates; _i < _candidates.length; _i++) {
|
|
45
|
+
var candidate = _candidates[_i];
|
|
46
|
+
if (candidate === undefined || candidate === null || candidate === '') continue;
|
|
47
|
+
var parsed = Number(candidate);
|
|
48
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
49
|
+
}
|
|
50
|
+
var unit = Number(sources.catalogUnitPrice);
|
|
51
|
+
var quantity = (_sources$quantity = sources.quantity) !== null && _sources$quantity !== void 0 ? _sources$quantity : 1;
|
|
52
|
+
if (Number.isFinite(unit) && unit > 0) {
|
|
53
|
+
return new Decimal(unit).mul(quantity).toNumber();
|
|
54
|
+
}
|
|
55
|
+
return NaN;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** 从 payload / extend / origin 解析手动折扣原因 */
|
|
59
|
+
export function resolveManualDiscountReasonFromSources(sources) {
|
|
60
|
+
for (var _i2 = 0, _arr = [sources.discountReason, sources.extendDiscountReason, sources.originExtendDiscountReason]; _i2 < _arr.length; _i2++) {
|
|
61
|
+
var candidate = _arr[_i2];
|
|
62
|
+
if (candidate != null && String(candidate).trim() !== '') {
|
|
63
|
+
return String(candidate);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** 是否带手动改价标记(price_override / is_manual_discount) */
|
|
70
|
+
export function hasManualProductDiscountFlag(metadata) {
|
|
71
|
+
if (!metadata) return false;
|
|
72
|
+
var override = metadata.price_override;
|
|
73
|
+
if (override !== undefined && override !== null && override !== '') {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return metadata.is_manual_discount === 1 || metadata.is_manual_discount === true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* normalize 兜底:手动改价但 discount_list 缺 type=product 时,按行级原价/折后价补写。
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ensureManualProductDiscountList({
|
|
84
|
+
* discountList: [],
|
|
85
|
+
* metadata: { price_override: '5', is_manual_discount: 1 },
|
|
86
|
+
* originalPrice: '11.00',
|
|
87
|
+
* sellingPrice: '5.00',
|
|
88
|
+
* quantity: 1,
|
|
89
|
+
* });
|
|
90
|
+
*/
|
|
91
|
+
export function ensureManualProductDiscountList(params) {
|
|
92
|
+
var _metadata$origin, _metadata$origin2, _metadata$origin3, _metadata$origin4;
|
|
93
|
+
var list = params.discountList || [];
|
|
94
|
+
var quantity = resolveSafeProductNum(params.quantity);
|
|
95
|
+
if (findManualProductDiscountItem(list)) {
|
|
96
|
+
return syncManualProductDiscountProductNum(list, quantity);
|
|
97
|
+
}
|
|
98
|
+
var metadata = params.metadata || {};
|
|
99
|
+
var originalNum = Number(params.originalPrice);
|
|
100
|
+
var sellingNum = Number(params.sellingPrice);
|
|
101
|
+
var shouldBuild = hasManualProductDiscountFlag(metadata) || shouldBuildManualProductDiscount({
|
|
102
|
+
originTotal: originalNum,
|
|
103
|
+
sellingTotal: sellingNum
|
|
104
|
+
});
|
|
105
|
+
if (!shouldBuild) {
|
|
106
|
+
return list;
|
|
107
|
+
}
|
|
108
|
+
if (!Number.isFinite(originalNum) || !Number.isFinite(sellingNum) || originalNum === sellingNum) {
|
|
109
|
+
return list;
|
|
110
|
+
}
|
|
111
|
+
var message = resolveManualDiscountMessage(list, resolveManualDiscountReasonFromSources({
|
|
112
|
+
extendDiscountReason: (_metadata$origin = metadata.origin) === null || _metadata$origin === void 0 || (_metadata$origin = _metadata$origin._extend) === null || _metadata$origin === void 0 ? void 0 : _metadata$origin.discount_reason,
|
|
113
|
+
originExtendDiscountReason: (_metadata$origin2 = metadata.origin) === null || _metadata$origin2 === void 0 || (_metadata$origin2 = _metadata$origin2._extend) === null || _metadata$origin2 === void 0 ? void 0 : _metadata$origin2.discount_reason
|
|
114
|
+
}));
|
|
115
|
+
return mergeManualProductDiscountIntoList(list, buildManualProductDiscountItem({
|
|
116
|
+
originTotal: originalNum,
|
|
117
|
+
sellingTotal: sellingNum,
|
|
118
|
+
quantity: quantity,
|
|
119
|
+
message: message,
|
|
120
|
+
discountway: (_metadata$origin3 = metadata.origin) === null || _metadata$origin3 === void 0 || (_metadata$origin3 = _metadata$origin3._extend) === null || _metadata$origin3 === void 0 ? void 0 : _metadata$origin3.discountway,
|
|
121
|
+
discount_per: (_metadata$origin4 = metadata.origin) === null || _metadata$origin4 === void 0 || (_metadata$origin4 = _metadata$origin4._extend) === null || _metadata$origin4 === void 0 ? void 0 : _metadata$origin4.discount_per
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** 商品手动折扣 discount_list 项(checkout 协议,type = product) */
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 从 discount_list 中取手动改价项(type = product)。
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* const manual = findManualProductDiscountItem(product.discount_list);
|
|
132
|
+
* manual?.discount.message; // 折扣原因
|
|
133
|
+
*/
|
|
134
|
+
export function findManualProductDiscountItem(discountList) {
|
|
135
|
+
return (discountList || []).find(function (item) {
|
|
136
|
+
return (item === null || item === void 0 ? void 0 : item.type) === 'product';
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 解析折扣原因:优先 discount_list[type=product].discount.message。
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* resolveManualDiscountMessage(line.discount_list, line.metadata?.legacy_reason);
|
|
145
|
+
*/
|
|
146
|
+
export function resolveManualDiscountMessage(discountList, fallback) {
|
|
147
|
+
var _findManualProductDis;
|
|
148
|
+
var message = (_findManualProductDis = findManualProductDiscountItem(discountList)) === null || _findManualProductDis === void 0 || (_findManualProductDis = _findManualProductDis.discount) === null || _findManualProductDis === void 0 ? void 0 : _findManualProductDis.message;
|
|
149
|
+
if (message != null && String(message).trim() !== '') {
|
|
150
|
+
return String(message);
|
|
151
|
+
}
|
|
152
|
+
return fallback !== null && fallback !== void 0 ? fallback : '';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 去掉 discount_list 中已有的手动改价项,避免重复叠加 */
|
|
156
|
+
export function stripManualProductDiscountItems(discountList) {
|
|
157
|
+
return (discountList || []).filter(function (item) {
|
|
158
|
+
return (item === null || item === void 0 ? void 0 : item.type) !== 'product';
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 由改价前后行总价构建手动折扣项;amount = |originTotal - sellingTotal|(行级差额)。
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* buildManualProductDiscountItem({
|
|
167
|
+
* originTotal: 11,
|
|
168
|
+
* sellingTotal: 4,
|
|
169
|
+
* quantity: 1,
|
|
170
|
+
* message: 'VIP',
|
|
171
|
+
* });
|
|
172
|
+
*/
|
|
173
|
+
export function buildManualProductDiscountItem(params) {
|
|
174
|
+
var _params$message, _params$discountway, _params$discount_per;
|
|
175
|
+
var origin = new Decimal(Number(params.originTotal) || 0);
|
|
176
|
+
var selling = new Decimal(Number(params.sellingTotal) || 0);
|
|
177
|
+
var diff = origin.minus(selling);
|
|
178
|
+
var quantity = resolveSafeProductNum(params.quantity);
|
|
179
|
+
return {
|
|
180
|
+
amount: diff.abs().toDecimalPlaces(2).toNumber(),
|
|
181
|
+
type: 'product',
|
|
182
|
+
discount: {
|
|
183
|
+
message: (_params$message = params.message) !== null && _params$message !== void 0 ? _params$message : '',
|
|
184
|
+
discountway: (_params$discountway = params.discountway) !== null && _params$discountway !== void 0 ? _params$discountway : 'num',
|
|
185
|
+
product_num: quantity,
|
|
186
|
+
discount_per: (_params$discount_per = params.discount_per) !== null && _params$discount_per !== void 0 ? _params$discount_per : '',
|
|
187
|
+
discount_type: diff.isNegative() ? 'change_price' : 'discount'
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* 将手动改价项合并进 discount_list(替换已有 type=product 项)。
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* mergeManualProductDiscountIntoList(coupons, manualItem);
|
|
197
|
+
*/
|
|
198
|
+
export function mergeManualProductDiscountIntoList(discountList, manualItem) {
|
|
199
|
+
var base = stripManualProductDiscountItems(discountList);
|
|
200
|
+
if (!manualItem) return base;
|
|
201
|
+
if (manualItem.amount === 0 && !manualItem.discount.message) return base;
|
|
202
|
+
return [].concat(_toConsumableArray(base), [manualItem]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** 是否应写入手动改价 discount_list 项 */
|
|
206
|
+
export function shouldBuildManualProductDiscount(params) {
|
|
207
|
+
if (params.hasPriceOverride) return true;
|
|
208
|
+
var origin = Number(params.originTotal);
|
|
209
|
+
var selling = Number(params.sellingTotal);
|
|
210
|
+
if (!Number.isFinite(origin) || !Number.isFinite(selling)) return false;
|
|
211
|
+
return origin !== selling;
|
|
212
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Decimal from 'decimal.js';
|
|
2
2
|
import { CartItem } from "../Cart";
|
|
3
|
-
import type { OrderSubmitPayload, OrderSubmitProduct, OrderSummary, OrderTempOrder } from './types';
|
|
3
|
+
import type { OrderProductDiscountItem, OrderSubmitPayload, OrderSubmitProduct, OrderSummary, OrderTempOrder } from './types';
|
|
4
4
|
import type { RulesParamsHooks } from '../Rules/types';
|
|
5
5
|
import type { MapOrderPaymentsOptions, OrderPaymentData, OrderPaymentSource } from './types';
|
|
6
6
|
/**
|
|
@@ -65,6 +65,26 @@ export declare function sumOptionUnitPrice(options?: Array<{
|
|
|
65
65
|
*
|
|
66
66
|
* 导出为纯函数方便单测直接驱动钩子,不依赖 OrderModule 实例。
|
|
67
67
|
*/
|
|
68
|
+
/** Rules calcDiscount 用手动价标记;undefined 表示交给 Rules 用 total/origin_total 推断 */
|
|
69
|
+
export declare function resolveRulesManualDiscountFlag(metadata: Record<string, any> | null | undefined): boolean | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* 商品行折扣只保留后端 OrderProductDiscountItem 协议字段。
|
|
72
|
+
* Rules/券计算过程中的 `_num`、`config` 等运行态字段不应进入 tempOrder 或提交 payload。
|
|
73
|
+
*/
|
|
74
|
+
export declare function normalizeOrderProductDiscountList(discountList?: unknown[] | null): OrderProductDiscountItem[];
|
|
75
|
+
/**
|
|
76
|
+
* 手动改价(price_override)时行级 original_price(composite 单价):
|
|
77
|
+
* 购物车划线价应对齐 metadata.origin._extend.origin_total(改价前单价 composite,如 40),
|
|
78
|
+
* 而非 bundle 子项 catalog 原价合成的 composedOriginalPrice(如 30)。
|
|
79
|
+
*
|
|
80
|
+
* origin_total 与 SkuDetailModal / cacheItem._extend 一致,为单价语义,不再除以 num。
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveManualOverrideLineOriginalPrice(params: {
|
|
83
|
+
num?: number;
|
|
84
|
+
metadata?: Record<string, any> | null;
|
|
85
|
+
/** 已有行级 original_price(origin 被裁剪时兜底划线价) */
|
|
86
|
+
lineOriginalPrice?: string | number | null;
|
|
87
|
+
}, fallbackCompositeOriginal: string): string;
|
|
68
88
|
export declare function createDefaultOrderRulesHooks(): RulesParamsHooks;
|
|
69
89
|
/**
|
|
70
90
|
* 通过 session 类商品的开始时间结束时间生成商品的时长
|
|
@@ -141,3 +161,5 @@ export declare function formatV1Product(products: OrderSubmitProduct[]): {
|
|
|
141
161
|
unique: string;
|
|
142
162
|
}[];
|
|
143
163
|
export { createEmptySummary } from '../../solution/ScanOrder/utils';
|
|
164
|
+
export { buildManualProductDiscountItem, ensureManualProductDiscountList, findManualProductDiscountItem, mergeManualProductDiscountIntoList, resolveManualDiscountMessage, resolveManualDiscountOriginTotal, resolveManualDiscountReasonFromSources, resolveSafeProductNum, shouldBuildManualProductDiscount, syncManualProductDiscountProductNum, stripManualProductDiscountItems, } from './utils/manualProductDiscount';
|
|
165
|
+
export type { ManualProductDiscountItem } from './utils/manualProductDiscount';
|