@pisell/pisellos 3.0.78 → 3.0.79

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 (37) hide show
  1. package/dist/modules/Cart/types.d.ts +2 -0
  2. package/dist/modules/Cart/utils/cartProduct.js +21 -1
  3. package/dist/modules/Cart/utils/changePrice.js +6 -0
  4. package/dist/modules/Date/index.d.ts +1 -1
  5. package/dist/modules/Date/index.js +16 -8
  6. package/dist/modules/Discount/index.d.ts +1 -0
  7. package/dist/modules/Discount/index.js +2 -1
  8. package/dist/modules/Rules/index.js +14 -14
  9. package/dist/modules/Schedule/index.d.ts +9 -0
  10. package/dist/modules/Schedule/index.js +76 -0
  11. package/dist/modules/Summary/index.d.ts +3 -0
  12. package/dist/modules/Summary/index.js +134 -15
  13. package/dist/modules/Summary/types.d.ts +7 -0
  14. package/dist/modules/Summary/utils.d.ts +104 -1
  15. package/dist/modules/Summary/utils.js +1131 -13
  16. package/dist/solution/BookingByStep/index.d.ts +4 -7
  17. package/dist/solution/BookingByStep/index.js +232 -119
  18. package/dist/solution/ShopDiscount/index.js +2 -1
  19. package/lib/modules/Cart/types.d.ts +2 -0
  20. package/lib/modules/Cart/utils/cartProduct.js +16 -1
  21. package/lib/modules/Cart/utils/changePrice.js +5 -0
  22. package/lib/modules/Date/index.d.ts +1 -1
  23. package/lib/modules/Date/index.js +7 -1
  24. package/lib/modules/Discount/index.d.ts +1 -0
  25. package/lib/modules/Discount/index.js +2 -1
  26. package/lib/modules/Rules/index.js +3 -3
  27. package/lib/modules/Schedule/index.d.ts +9 -0
  28. package/lib/modules/Schedule/index.js +60 -0
  29. package/lib/modules/Summary/index.d.ts +3 -0
  30. package/lib/modules/Summary/index.js +61 -2
  31. package/lib/modules/Summary/types.d.ts +7 -0
  32. package/lib/modules/Summary/utils.d.ts +104 -1
  33. package/lib/modules/Summary/utils.js +673 -8
  34. package/lib/solution/BookingByStep/index.d.ts +4 -7
  35. package/lib/solution/BookingByStep/index.js +189 -90
  36. package/lib/solution/ShopDiscount/index.js +2 -1
  37. package/package.json +1 -1
@@ -60,6 +60,11 @@ async function updateAllCartItemPrice(cartItems, priceData, getProduct, updateCa
60
60
  if (targetBundleItem.price_type === "markdown") {
61
61
  targetBundleItem.price = new import_decimal.default(targetBundleItem.price || 0).mul(-1).toNumber();
62
62
  }
63
+ if (n.option) {
64
+ targetBundleItem.price = new import_decimal.default(targetBundleItem.price || 0).add(n.option.reduce((pre, cur) => {
65
+ return pre + new import_decimal.default(cur.price || 0).mul(cur.num || 1).toNumber();
66
+ }, 0)).toNumber();
67
+ }
63
68
  if (targetBundleItem) {
64
69
  return {
65
70
  ...n,
@@ -37,5 +37,5 @@ export declare class DateModule extends BaseModule implements Module, DateModule
37
37
  getResourceAvailableTimeList(params: IGetAvailableTimeListParams): Promise<ITime[]>;
38
38
  clearDateRange(): void;
39
39
  storeChange(): void;
40
- getResourcesListByDate(date: string): any[] | undefined;
40
+ getResourcesListByDate(date: string): any[];
41
41
  }
@@ -64,6 +64,12 @@ var DateModule = class extends import_BaseModule.BaseModule {
64
64
  }
65
65
  }
66
66
  setDateRange(dateRange) {
67
+ dateRange.forEach((item) => {
68
+ var _a;
69
+ if (!((_a = item.resource) == null ? void 0 : _a.length)) {
70
+ item.resource = this.getResourcesListByDate(item.date);
71
+ }
72
+ });
67
73
  this.store.dateRange = dateRange;
68
74
  }
69
75
  getDateRange() {
@@ -252,7 +258,7 @@ var DateModule = class extends import_BaseModule.BaseModule {
252
258
  getResourcesListByDate(date) {
253
259
  var _a;
254
260
  const dateList = this.store.dateList;
255
- const resourcesList = (_a = dateList.find((item) => item.date === date)) == null ? void 0 : _a.resource;
261
+ const resourcesList = ((_a = dateList == null ? void 0 : dateList.find((item) => item.date === date)) == null ? void 0 : _a.resource) || [];
256
262
  return resourcesList;
257
263
  }
258
264
  };
@@ -22,6 +22,7 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
22
22
  with_discount_card: 0 | 1;
23
23
  customer_id: number;
24
24
  with_wallet_pass_holder: 0 | 1;
25
+ request_timezone: string;
25
26
  }): Promise<Discount[]>;
26
27
  batchSearch(code: string, customerId?: number): Promise<Discount[]>;
27
28
  filterEnabledDiscountList(discountList: Discount[]): Discount[];
@@ -111,7 +111,8 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
111
111
  relation_product: 1,
112
112
  with: ["extensionData", "customScheduleSnapshot", "holder.detail"],
113
113
  order_behavior_count: 1,
114
- order_behavior_count_customer_id: customerId || 1
114
+ order_behavior_count_customer_id: customerId || 1,
115
+ request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
115
116
  });
116
117
  const resultDiscountList = this.filterEnabledDiscountList((result == null ? void 0 : result.data) || []) || [];
117
118
  return resultDiscountList;
@@ -451,7 +451,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
451
451
  }
452
452
  const applicableProducts = [];
453
453
  sortedFlattenedList.forEach((flatItem) => {
454
- var _a, _b;
454
+ var _a, _b, _c;
455
455
  const occupyingDiscountId = occupiedItems.get(flatItem._id);
456
456
  if (occupyingDiscountId !== void 0 && occupyingDiscountId !== discount.id) {
457
457
  return;
@@ -471,7 +471,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
471
471
  num: flatItem.num
472
472
  };
473
473
  }
474
- const quantity = flatItem.type === "main" ? product.quantity || 1 : (product.num || 1) * (((_a = flatItem.parentProduct) == null ? void 0 : _a.quantity) || 1);
474
+ const quantity = flatItem.type === "main" ? product.num || product.quantity || 1 : (product.num || product.quantity || 1) * (((_a = flatItem.parentProduct) == null ? void 0 : _a.num) || ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1);
475
475
  const originalAmount = flatItem.type === "main" ? Number(product.price ?? 0) : Number(flatItem.original_price ?? flatItem.price ?? 0);
476
476
  const productData = {
477
477
  productId: flatItem._id,
@@ -479,7 +479,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
479
479
  quantity
480
480
  };
481
481
  if (flatItem.type === "bundle") {
482
- productData.parentQuantity = ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1;
482
+ productData.parentQuantity = ((_c = flatItem.parentProduct) == null ? void 0 : _c.quantity) || 1;
483
483
  }
484
484
  applicableProducts.push(productData);
485
485
  });
@@ -25,4 +25,13 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
25
25
  setOtherProductsIds(ids: number[]): void;
26
26
  getOtherProductsIds(): number[];
27
27
  storeChange(): void;
28
+ /**
29
+ * 传入一个时间, 判断改时间是否在schedule 内
30
+ * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
31
+ * @returns
32
+ */
33
+ static isInScheduleByDate({ date, schedule, }: {
34
+ date: string;
35
+ schedule: any;
36
+ }): boolean | undefined;
28
37
  }
@@ -38,6 +38,7 @@ var import_dayjs = __toESM(require("dayjs"));
38
38
  var import_isSameOrBefore = __toESM(require("dayjs/plugin/isSameOrBefore"));
39
39
  var import_isSameOrAfter = __toESM(require("dayjs/plugin/isSameOrAfter"));
40
40
  var import_utils = require("../Date/utils");
41
+ var import_utils2 = require("./utils");
41
42
  import_dayjs.default.extend(import_isSameOrBefore.default);
42
43
  import_dayjs.default.extend(import_isSameOrAfter.default);
43
44
  var ScheduleModule = class extends import_BaseModule.BaseModule {
@@ -158,6 +159,65 @@ var ScheduleModule = class extends import_BaseModule.BaseModule {
158
159
  });
159
160
  }
160
161
  }
162
+ /**
163
+ * 传入一个时间, 判断改时间是否在schedule 内
164
+ * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
165
+ * @returns
166
+ */
167
+ static isInScheduleByDate({
168
+ date,
169
+ schedule
170
+ }) {
171
+ var _a, _b, _c, _d;
172
+ if (schedule.start_time && schedule.end_time) {
173
+ const isBeforeStartTime = (0, import_dayjs.default)(date).isBefore(
174
+ (0, import_dayjs.default)(schedule.start_time)
175
+ );
176
+ const isAfterEndTime = (0, import_dayjs.default)(date).isAfter((0, import_dayjs.default)(schedule.end_time));
177
+ if (isBeforeStartTime || isAfterEndTime) {
178
+ return false;
179
+ }
180
+ }
181
+ let _schedule = {
182
+ ...schedule,
183
+ // 开始时间向前推一天
184
+ start_time: (0, import_dayjs.default)(date).subtract(1, "day").format("YYYY-MM-DD HH:mm:ss"),
185
+ end_time: (0, import_dayjs.default)(date).add(1, "day").format("YYYY-MM-DD HH:mm:ss")
186
+ };
187
+ if (((_b = (_a = _schedule.repeat_rule) == null ? void 0 : _a.end) == null ? void 0 : _b.type) === "never") {
188
+ _schedule = {
189
+ ..._schedule,
190
+ repeat_rule: {
191
+ ..._schedule.repeat_rule,
192
+ end: {
193
+ type: "date",
194
+ end_date: _schedule.end_time,
195
+ occurrence: null
196
+ }
197
+ }
198
+ };
199
+ }
200
+ if (((_d = (_c = _schedule.repeat_rule) == null ? void 0 : _c.end) == null ? void 0 : _d.type) === "date") {
201
+ _schedule = {
202
+ ..._schedule,
203
+ repeat_rule: {
204
+ ..._schedule.repeat_rule,
205
+ end: {
206
+ ..._schedule.repeat_rule.end,
207
+ end_date: _schedule.end_time
208
+ }
209
+ }
210
+ };
211
+ }
212
+ const dateRanges = (0, import_utils2.calcScheduleDateRange)({ ..._schedule });
213
+ for (const range of dateRanges) {
214
+ const startTime = (0, import_dayjs.default)(range.start);
215
+ const endTime = (0, import_dayjs.default)(range.end);
216
+ if ((0, import_dayjs.default)(date).isSameOrAfter(startTime) && (0, import_dayjs.default)(date).isSameOrBefore(endTime)) {
217
+ return true;
218
+ }
219
+ }
220
+ }
161
221
  };
162
222
  // Annotate the CommonJS export names for ESM import in node:
163
223
  0 && (module.exports = {
@@ -13,6 +13,7 @@ export declare class SummaryModule extends BaseModule implements Module, ISummar
13
13
  private fatherModule;
14
14
  constructor(name?: string, version?: string);
15
15
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
16
+ getSurchargeList(): Promise<void>;
16
17
  getSummary(cartItems: CartItem[]): Promise<ISummaryState['summary']>;
17
18
  /**
18
19
  * 获取协议
@@ -21,4 +22,6 @@ export declare class SummaryModule extends BaseModule implements Module, ISummar
21
22
  */
22
23
  getProtocol(protocolId: string): Promise<any>;
23
24
  storeChange(): void;
25
+ private getTaxforUtils;
26
+ private getSurchargeforUtils;
24
27
  }
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
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
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
 
19
29
  // src/modules/Summary/index.ts
@@ -22,7 +32,9 @@ __export(Summary_exports, {
22
32
  SummaryModule: () => SummaryModule
23
33
  });
24
34
  module.exports = __toCommonJS(Summary_exports);
35
+ var import_decimal = __toESM(require("decimal.js"));
25
36
  var import_BaseModule = require("../BaseModule");
37
+ var import_Schedule = require("../Schedule");
26
38
  var import_utils = require("./utils");
27
39
  var SummaryModule = class extends import_BaseModule.BaseModule {
28
40
  constructor(name, version) {
@@ -50,11 +62,30 @@ var SummaryModule = class extends import_BaseModule.BaseModule {
50
62
  if (!this.shopStore) {
51
63
  throw new Error("SummaryModule 需要 shopStore 插件支持");
52
64
  }
65
+ this.getSurchargeList();
66
+ }
67
+ async getSurchargeList() {
68
+ const surchargeList = await this.request.get("/order/custom-surcharge/available/v2", {
69
+ channel: "online-store",
70
+ is_assemble_product_data: 1,
71
+ is_assemble_schedule_data: 1,
72
+ with: ["relationSchedule"]
73
+ });
74
+ this.store.surchargeList = (surchargeList == null ? void 0 : surchargeList.data) || [];
53
75
  }
54
76
  async getSummary(cartItems) {
55
- var _a, _b;
77
+ var _a, _b, _c;
56
78
  const shopInfo = ((_b = (_a = this.shopStore.get("core")) == null ? void 0 : _a.core) == null ? void 0 : _b.shop) || {};
57
- const summary = (0, import_utils.calculatePriceDetails)(shopInfo, cartItems);
79
+ const scheduleModule = this.core.getModule("appointmentBooking_schedule");
80
+ const needScheduleIds = this.store.surchargeList.map((item) => item.available_schedule_ids).flat();
81
+ const scheduleList = scheduleModule == null ? void 0 : scheduleModule.getScheduleListByIds(needScheduleIds);
82
+ const scheduleById = {};
83
+ if (Array.isArray(scheduleList)) {
84
+ for (let item of scheduleList) {
85
+ scheduleById[item.id] = item;
86
+ }
87
+ }
88
+ const summary = (0, import_utils.calculatePriceDetails)(shopInfo, cartItems, (_c = import_Schedule.ScheduleModule) == null ? void 0 : _c.isInScheduleByDate, this.store.surchargeList, scheduleById);
58
89
  this.store.summary = summary;
59
90
  return this.store.summary;
60
91
  }
@@ -76,6 +107,34 @@ var SummaryModule = class extends import_BaseModule.BaseModule {
76
107
  });
77
108
  }
78
109
  }
110
+ getTaxforUtils(items, shopInfo, subtotal) {
111
+ return (0, import_utils.getTax)({ service: items, bookingDetail: null, bookingId: void 0 }, {
112
+ computed: {
113
+ productExpectAmount: subtotal,
114
+ shopDiscount: 0
115
+ },
116
+ isEdit: false,
117
+ tax_rate: shopInfo == null ? void 0 : shopInfo.tax_rate,
118
+ is_price_include_tax: shopInfo == null ? void 0 : shopInfo.is_price_include_tax
119
+ });
120
+ }
121
+ getSurchargeforUtils(items) {
122
+ const scheduleModule = this.core.getModule("appointmentBooking_schedule");
123
+ const needScheduleIds = this.store.surchargeList.map((item) => item.available_schedule_ids).flat();
124
+ const scheduleList = scheduleModule == null ? void 0 : scheduleModule.getScheduleListByIds(needScheduleIds);
125
+ const scheduleById = {};
126
+ if (Array.isArray(scheduleList)) {
127
+ for (let item of scheduleList) {
128
+ scheduleById[item.id] = item;
129
+ }
130
+ }
131
+ const surchargeList = (0, import_utils.getSurcharge)({ service: items, addons: [], bookingDetail: null, bookingId: void 0 }, { isEdit: false, isInScheduleByDate: import_Schedule.ScheduleModule.isInScheduleByDate, surcharge_list: this.store.surchargeList, scheduleById });
132
+ const surchargeAmount = new import_decimal.default((0, import_utils.getSurchargeAmount)({ bookingDetail: null, bookingId: void 0 }, surchargeList, { isEdit: false }));
133
+ return {
134
+ surchargeList,
135
+ surchargeAmount: surchargeAmount.toFixed(2)
136
+ };
137
+ }
79
138
  };
80
139
  // Annotate the CommonJS export names for ESM import in node:
81
140
  0 && (module.exports = {
@@ -1,5 +1,6 @@
1
1
  import { CartItem } from '../Cart/types';
2
2
  export interface ISummaryState {
3
+ surchargeList: any[];
3
4
  summary: {
4
5
  /** 商品总价 */
5
6
  subtotal: string | number;
@@ -11,6 +12,12 @@ export interface ISummaryState {
11
12
  totalTaxFee?: string | number;
12
13
  /** 商品价格是否包含费率 */
13
14
  isPriceIncludeTax?: 0 | 1;
15
+ /** 附加费金额 */
16
+ surchargeAmount?: string | number;
17
+ /** 附加费列表 */
18
+ surcharge?: any[];
19
+ /** 税率 */
20
+ taxRate?: string | number;
14
21
  /** 定金 */
15
22
  deposit?: {
16
23
  /** 定金总价 */
@@ -1,12 +1,57 @@
1
1
  import Decimal from 'decimal.js';
2
2
  import { CartItem } from '../Cart/types';
3
3
  import { ISummaryState } from './types';
4
- export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[]) => ISummaryState['summary'];
4
+ export declare const calculatePriceDetails: (shopInfo: any, items: CartItem[], isInScheduleByDate: any, surchargeList: any[], scheduleById: Record<string, any>) => ISummaryState['summary'];
5
5
  /**
6
6
  * 获取子商品折扣信息
7
7
  * @param item
8
8
  */
9
9
  export declare const getBundleDiscountList: (bundle: any[]) => any[];
10
+ export declare const calcDiscountListDifference: (discountList: any[]) => any;
11
+ export declare const getProductDiscountProductDiscountDifference: (item: CartItem) => any;
12
+ /**
13
+ * 计算订单税费(折扣前/折扣后),并把单品税费信息回写到商品数据上(用于明细展示/后续计算)。
14
+ *
15
+ * - **折扣前税费**:`originTax`
16
+ * - **折扣后税费**:`tax`(会考虑 `computed.shopDiscount` 对每个商品的分摊影响)
17
+ * - **税率/是否含税**:优先取 `bookingDetail.tax_rate` / `bookingDetail.is_price_include_tax`,取不到再回退到 `options.tax_rate` / `options.is_price_include_tax`
18
+ *
19
+ * **副作用(会修改入参商品对象)**:
20
+ * - 主商品:写入 `item.original_tax_fee` / `item.tax_fee`(四舍五入保留两位)
21
+ * - bundle 原价子商品:写入 `bundleItem.original_tax_fee` / `bundleItem.tax_fee`
22
+ * - 加时商品(`relation_details`):写入 `atItem.tax_fee`
23
+ * - 税费舍入差值:追加到最后一个“含税商品”的 `tax_fee_rounding_remainder` / `original_tax_fee_rounding_remainder`
24
+ *
25
+ * @param params 入参集合(RORO)
26
+ * @param params.service 服务商品数组(主商品)。通常是购物车商品结构(可能包含 `bundle` / `relation_details`)
27
+ * @param params.addons 附加商品数组(可选)。结构同商品数组
28
+ * @param params.bookingDetail 订单详情(编辑/详情场景用于读取后端税率配置),可选
29
+ * @param params.bookingId 订单/预约 ID(编辑/详情场景识别用),可选
30
+ * @param options 计算选项
31
+ * @param options.isEdit 是否处于“编辑中”。当前实现不强依赖该值(历史逻辑保留),但建议按真实状态传入
32
+ * @param options.computed 预计算结果(用于折扣分摊)
33
+ * @param options.computed.productExpectAmount 商品期望总金额(用于按比例分摊折扣)
34
+ * @param options.computed.shopDiscount 店铺折扣总额(用于按比例分摊到商品)
35
+ * @param options.tax_rate 管理端税率(百分比,如 5 表示 5%)。仅当 `bookingDetail.tax_rate` 不存在时生效
36
+ * @param options.is_price_include_tax 是否含税:`0` 不含税、`1` 含税。仅当 `bookingDetail.is_price_include_tax` 不存在时生效
37
+ * @returns 税费汇总(number,金额单位与商品价格一致,四舍五入保留两位)
38
+ * @returns.originTax 折扣前税费合计
39
+ * @returns.tax 折扣后税费合计
40
+ */
41
+ export declare const getTax: ({ service, addons, bookingDetail, bookingId }: {
42
+ service?: any;
43
+ addons?: any;
44
+ bookingDetail?: any;
45
+ bookingId?: number | undefined;
46
+ }, options: {
47
+ isEdit: boolean;
48
+ computed: Record<string, number | string>;
49
+ tax_rate?: number;
50
+ is_price_include_tax?: number;
51
+ } & Record<string, any>) => {
52
+ originTax: number;
53
+ tax: number;
54
+ };
10
55
  /**
11
56
  * 计算商品小计(不含其他费用)
12
57
  * @param items - 购物车商品数组
@@ -32,3 +77,61 @@ export declare const calculateDeposit: (items: CartItem[]) => {
32
77
  protocols: any[];
33
78
  hasDeposit: never;
34
79
  } | undefined;
80
+ /**
81
+ * 计算订单附加费金额(订单级别合计)。
82
+ *
83
+ * - **详情未编辑**(`!options.isEdit && bookingId`)且存在后端详情时:直接返回 `bookingDetail.surcharge_fee`
84
+ * - **新增/编辑**时:对 `surcharge`(通常为 `getSurcharge` 的返回值)按 `item.value` 求和
85
+ *
86
+ * @param params 入参集合(RORO)
87
+ * @param params.bookingDetail 订单详情(详情未编辑时用于读取后端的 `surcharge_fee`),可选
88
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
89
+ * @param surcharge 附加费列表(通常来自 `getSurcharge`),元素结构至少包含 `value: number`
90
+ * @param options 计算选项
91
+ * @param options.isEdit 是否处于“编辑中”。`false` 时会优先走后端金额直取逻辑(若存在)
92
+ * @returns 订单附加费金额(number,金额单位与商品价格一致)
93
+ */
94
+ export declare const getSurchargeAmount: ({ bookingDetail, bookingId }: {
95
+ bookingDetail?: any;
96
+ bookingId?: number | undefined;
97
+ }, surcharge: any[], options: any) => any;
98
+ /**
99
+ * 订单附加费各项信息
100
+ *
101
+ * - **详情未编辑**(`!options.isEdit && bookingId`)时:直接返回 `bookingDetail.surcharge`(后端计算结果)
102
+ * - **新增/编辑**时:按 `options.surcharge_list` 逐条配置计算本次订单的附加费
103
+ *
104
+ * 规则要点:
105
+ * - 匹配范围包含:主商品(`service`)、原价 bundle 子商品(`item.bundle`)、加时商品(`item.relation_details`)、以及 addons(`addons.value`)
106
+ * - 固定附加费 `fixed`:只加一次,再按商品数量分摊(向下取整保留两位),剩余小数会以 `surcharge_rounding_remainder` 形式抹平到最后一个商品
107
+ * - 百分比附加费 `percentage`:按每个商品(价格 * 数量)分别计算再累加
108
+ * - 当 `open_product === 0`:不回写到商品,只在订单级别累加;否则会把单品附加费回写到商品
109
+ *
110
+ * **副作用(可能修改入参商品对象)**:
111
+ * - 当 `open_product !== 0` 时:写入 `item.surcharge_fee`(单品单数量附加费,保留两位、向下取整)
112
+ * - 写入 `item.relation_surcharge_ids`(关联到的 surcharge 配置 id 列表)
113
+ * - 写入 `item.surcharge_rounding_remainder`(用于抹平固定附加费/总额舍入差)
114
+ *
115
+ * @param params 入参集合(RORO)
116
+ * @param params.service 服务商品数组(主商品)。元素可能包含 `bundle` / `relation_details`
117
+ * @param params.addons 附加商品容器。当前实现读取 `addons.value` 作为商品数组(所以通常传 `{ value: CartItem[] }`)
118
+ * @param params.bookingDetail 订单详情(详情未编辑时用于直接取后端的 surcharge 列表),可选
119
+ * @param params.bookingId 订单/预约 ID(详情未编辑时生效),可选
120
+ * @param options 计算选项
121
+ * @param options.isEdit 是否处于“编辑中”。`false` 且存在 `bookingId` 时会走详情直取逻辑
122
+ * @param options.surcharge_list 附加费配置列表(后端下发)。缺失/为空则返回空数组
123
+ * @param options.isInScheduleByDate 判断日期是否落在某个 schedule 内的方法(通常来自 ScheduleModule)
124
+ * @param options.scheduleById schedule 映射表:`{ [scheduleId]: schedule }`(用于根据配置的 `available_schedule_ids` 做日程匹配)
125
+ * @returns 附加费列表(仅返回金额 > 0 的项)
126
+ */
127
+ export declare const getSurcharge: ({ service, addons, bookingDetail, bookingId }: {
128
+ service: any;
129
+ addons: any;
130
+ bookingDetail?: any;
131
+ bookingId?: number | undefined;
132
+ }, options: {
133
+ isEdit: boolean;
134
+ isInScheduleByDate: any;
135
+ surcharge_list?: any[];
136
+ scheduleById?: Record<string, any>;
137
+ } & Record<string, any>) => any;