@pisell/pisellos 2.2.93 → 2.2.94

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 (69) hide show
  1. package/dist/core/index.d.ts +0 -1
  2. package/dist/core/index.js +0 -7
  3. package/dist/modules/Customer/index.d.ts +0 -1
  4. package/dist/modules/Customer/index.js +12 -28
  5. package/dist/plugins/app-types/app/app.d.ts +1 -0
  6. package/dist/server/index.d.ts +55 -5
  7. package/dist/server/index.js +832 -236
  8. package/dist/server/modules/index.d.ts +6 -0
  9. package/dist/server/modules/index.js +7 -0
  10. package/dist/server/modules/order/index.d.ts +87 -0
  11. package/dist/server/modules/order/index.js +916 -0
  12. package/dist/server/modules/order/types.d.ts +530 -0
  13. package/dist/server/modules/order/types.js +141 -0
  14. package/dist/server/modules/order/utils/filterBookings.d.ts +6 -0
  15. package/dist/server/modules/order/utils/filterBookings.js +350 -0
  16. package/dist/server/modules/order/utils/filterOrders.d.ts +15 -0
  17. package/dist/server/modules/order/utils/filterOrders.js +226 -0
  18. package/dist/server/modules/products/index.d.ts +24 -19
  19. package/dist/server/modules/products/index.js +600 -429
  20. package/dist/server/modules/products/types.d.ts +0 -1
  21. package/dist/server/modules/resource/index.d.ts +88 -0
  22. package/dist/server/modules/resource/index.js +1202 -0
  23. package/dist/server/modules/resource/types.d.ts +121 -0
  24. package/dist/server/modules/resource/types.js +47 -0
  25. package/dist/server/utils/product.d.ts +0 -4
  26. package/dist/server/utils/product.js +0 -34
  27. package/dist/solution/BookingTicket/index.d.ts +1 -1
  28. package/dist/solution/Sales/index.d.ts +96 -0
  29. package/dist/solution/Sales/index.js +510 -0
  30. package/dist/solution/Sales/types.d.ts +65 -0
  31. package/dist/solution/Sales/types.js +26 -0
  32. package/dist/solution/index.d.ts +1 -0
  33. package/dist/solution/index.js +2 -1
  34. package/dist/types/index.d.ts +0 -2
  35. package/lib/core/index.d.ts +0 -1
  36. package/lib/core/index.js +0 -4
  37. package/lib/modules/Customer/index.d.ts +0 -1
  38. package/lib/modules/Customer/index.js +6 -21
  39. package/lib/plugins/app-types/app/app.d.ts +1 -0
  40. package/lib/server/index.d.ts +55 -5
  41. package/lib/server/index.js +350 -28
  42. package/lib/server/modules/index.d.ts +6 -0
  43. package/lib/server/modules/index.js +16 -2
  44. package/lib/server/modules/order/index.d.ts +87 -0
  45. package/lib/server/modules/order/index.js +543 -0
  46. package/lib/server/modules/order/types.d.ts +530 -0
  47. package/lib/server/modules/order/types.js +34 -0
  48. package/lib/server/modules/order/utils/filterBookings.d.ts +6 -0
  49. package/lib/server/modules/order/utils/filterBookings.js +320 -0
  50. package/lib/server/modules/order/utils/filterOrders.d.ts +15 -0
  51. package/lib/server/modules/order/utils/filterOrders.js +197 -0
  52. package/lib/server/modules/products/index.d.ts +24 -19
  53. package/lib/server/modules/products/index.js +150 -151
  54. package/lib/server/modules/products/types.d.ts +0 -1
  55. package/lib/server/modules/resource/index.d.ts +88 -0
  56. package/lib/server/modules/resource/index.js +571 -0
  57. package/lib/server/modules/resource/types.d.ts +121 -0
  58. package/lib/server/modules/resource/types.js +35 -0
  59. package/lib/server/utils/product.d.ts +0 -4
  60. package/lib/server/utils/product.js +0 -27
  61. package/lib/solution/BookingTicket/index.d.ts +1 -1
  62. package/lib/solution/Sales/index.d.ts +96 -0
  63. package/lib/solution/Sales/index.js +358 -0
  64. package/lib/solution/Sales/types.d.ts +65 -0
  65. package/lib/solution/Sales/types.js +35 -0
  66. package/lib/solution/index.d.ts +1 -0
  67. package/lib/solution/index.js +3 -1
  68. package/lib/types/index.d.ts +0 -2
  69. package/package.json +1 -1
@@ -0,0 +1,320 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/server/modules/order/utils/filterBookings.ts
20
+ var filterBookings_exports = {};
21
+ __export(filterBookings_exports, {
22
+ filterBookings: () => filterBookings,
23
+ filterBookingsFromOrders: () => filterBookingsFromOrders,
24
+ flattenOrdersToBookings: () => flattenOrdersToBookings,
25
+ sortBookings: () => sortBookings
26
+ });
27
+ module.exports = __toCommonJS(filterBookings_exports);
28
+ function getBookingAppointmentStatus(booking) {
29
+ return String(booking.appointment_status ?? booking.status ?? "");
30
+ }
31
+ function toTimestamp(value) {
32
+ if (value === void 0 || value === null || value === "")
33
+ return 0;
34
+ if (typeof value === "number")
35
+ return value;
36
+ return new Date(value).getTime();
37
+ }
38
+ function bookingDateTimeString(datePart, timePart) {
39
+ const d = (datePart ?? "").trim();
40
+ let t = (timePart ?? "").trim();
41
+ if (t && /^\d{1,2}:\d{2}$/.test(t)) {
42
+ t = `${t}:00`;
43
+ }
44
+ return `${d} ${t}`.trim();
45
+ }
46
+ function parseDateRange(range) {
47
+ if (!Array.isArray(range) || range.length < 2)
48
+ return null;
49
+ const start = toTimestamp(range[0]);
50
+ const end = toTimestamp(range[1]);
51
+ if (!start && !end)
52
+ return null;
53
+ return [start, end];
54
+ }
55
+ function parseNumberRange(range) {
56
+ if (!Array.isArray(range) || range.length < 2)
57
+ return null;
58
+ const min = Number(range[0]);
59
+ const max = Number(range[1]);
60
+ if (isNaN(min) || isNaN(max))
61
+ return null;
62
+ return [min, max];
63
+ }
64
+ function prepareFilters(f) {
65
+ var _a, _b, _c, _d, _e, _f;
66
+ const hasCustomerId = f.customer_id !== void 0 && f.customer_id !== null;
67
+ return {
68
+ orderPaymentStatusSet: ((_a = f.order_payment_status) == null ? void 0 : _a.length) ? new Set(f.order_payment_status) : null,
69
+ orderStatusSet: ((_b = f.order_status) == null ? void 0 : _b.length) ? new Set(f.order_status) : null,
70
+ orderSalesChannelSet: ((_c = f.order_sales_channel) == null ? void 0 : _c.length) ? new Set(f.order_sales_channel) : null,
71
+ paymentMethodSet: ((_d = f.payment_method) == null ? void 0 : _d.length) ? new Set(f.payment_method) : null,
72
+ appointmentStatusSet: ((_e = f.appointment_status) == null ? void 0 : _e.length) ? new Set(f.appointment_status) : null,
73
+ formRecordIdSet: ((_f = f.form_record_ids) == null ? void 0 : _f.length) ? new Set(f.form_record_ids) : null,
74
+ hasCustomerId,
75
+ customerIdStr: hasCustomerId ? String(f.customer_id) : "",
76
+ hasBusinessCode: !!f.business_code,
77
+ businessCode: f.business_code,
78
+ bookingTimeRange: parseDateRange(f.es_start_datetime_between),
79
+ createdAtRange: parseDateRange(f.created_at_between),
80
+ updatedAtRange: parseDateRange(f.updated_at_between),
81
+ numberRange: parseNumberRange(f.number_between),
82
+ totalAmountRange: Array.isArray(f.total_amount_between) && f.total_amount_between.length === 2 ? f.total_amount_between : null,
83
+ keywordLower: f.keyword ? f.keyword.toLowerCase() : "",
84
+ afterExecutionTimeMs: (() => {
85
+ const raw = f.after_execution_time;
86
+ if (raw === void 0 || raw === null || raw === "")
87
+ return null;
88
+ const ms = toTimestamp(raw);
89
+ return Number.isFinite(ms) ? ms : null;
90
+ })(),
91
+ enableChildBookingFilter: f.child_booking === 1
92
+ };
93
+ }
94
+ function matchOrder(order, ctx) {
95
+ var _a;
96
+ if (ctx.hasBusinessCode && order.business_code !== ctx.businessCode)
97
+ return false;
98
+ if (ctx.hasCustomerId && String(order.customer_id) !== ctx.customerIdStr)
99
+ return false;
100
+ if (ctx.orderPaymentStatusSet && !ctx.orderPaymentStatusSet.has(order.payment_status))
101
+ return false;
102
+ if (ctx.orderStatusSet && !ctx.orderStatusSet.has(order.status))
103
+ return false;
104
+ if (ctx.orderSalesChannelSet && !ctx.orderSalesChannelSet.has(order.order_sales_channel))
105
+ return false;
106
+ if (ctx.paymentMethodSet) {
107
+ const pm = order.payments;
108
+ if (!Array.isArray(pm) || pm.length === 0)
109
+ return false;
110
+ let matched = false;
111
+ for (let k = 0; k < pm.length; k++) {
112
+ if (ctx.paymentMethodSet.has(pm[k].code)) {
113
+ matched = true;
114
+ break;
115
+ }
116
+ }
117
+ if (!matched)
118
+ return false;
119
+ }
120
+ if (ctx.createdAtRange) {
121
+ const ts = toTimestamp(order.created_at);
122
+ if (ts < ctx.createdAtRange[0] || ts > ctx.createdAtRange[1])
123
+ return false;
124
+ }
125
+ if (ctx.updatedAtRange) {
126
+ const ts = toTimestamp(order.updated_at);
127
+ if (ts < ctx.updatedAtRange[0] || ts > ctx.updatedAtRange[1])
128
+ return false;
129
+ }
130
+ if (ctx.totalAmountRange) {
131
+ const raw = ((_a = order.summary) == null ? void 0 : _a.total_amount) ?? order.total_amount;
132
+ const amt = Number(raw);
133
+ if (isNaN(amt))
134
+ return false;
135
+ if (ctx.totalAmountRange[0] != null && amt < ctx.totalAmountRange[0])
136
+ return false;
137
+ if (ctx.totalAmountRange[1] != null && amt > ctx.totalAmountRange[1])
138
+ return false;
139
+ }
140
+ return true;
141
+ }
142
+ function matchBooking(booking, orderInfo, ctx) {
143
+ if (ctx.enableChildBookingFilter) {
144
+ const parentId = Number(booking.parent_id ?? 0);
145
+ const itemType = String(booking.item_type ?? "");
146
+ const isMatched = parentId !== 0 && itemType !== "recurring_booking" || parentId === 0 && itemType === "recurring_booking";
147
+ if (!isMatched)
148
+ return false;
149
+ }
150
+ if (ctx.appointmentStatusSet && !ctx.appointmentStatusSet.has(getBookingAppointmentStatus(booking)))
151
+ return false;
152
+ if (ctx.bookingTimeRange) {
153
+ const ts = toTimestamp(booking.start_date);
154
+ if (ts < ctx.bookingTimeRange[0] || ts > ctx.bookingTimeRange[1])
155
+ return false;
156
+ }
157
+ if (ctx.afterExecutionTimeMs != null) {
158
+ const bookingStartMs = toTimestamp(bookingDateTimeString(booking.start_date, booking.start_time));
159
+ if (!Number.isFinite(bookingStartMs) || bookingStartMs < ctx.afterExecutionTimeMs)
160
+ return false;
161
+ }
162
+ if (ctx.numberRange) {
163
+ const num = Number(booking.number);
164
+ if (isNaN(num) || num < ctx.numberRange[0] || num > ctx.numberRange[1])
165
+ return false;
166
+ }
167
+ if (ctx.formRecordIdSet) {
168
+ let formMatched = false;
169
+ const resources = booking.resources;
170
+ if (Array.isArray(resources)) {
171
+ for (let r = 0; r < resources.length; r++) {
172
+ if (resources[r].relation_type === "form" && ctx.formRecordIdSet.has(resources[r].relation_id)) {
173
+ formMatched = true;
174
+ break;
175
+ }
176
+ }
177
+ }
178
+ if (!formMatched && booking.relation_type === "form" && booking.relation_id && booking.relation_id > 0) {
179
+ formMatched = ctx.formRecordIdSet.has(booking.relation_id);
180
+ }
181
+ if (!formMatched)
182
+ return false;
183
+ }
184
+ if (ctx.keywordLower) {
185
+ const target = orderInfo ? { ...booking, order: orderInfo } : booking;
186
+ const str = JSON.stringify(target).toLowerCase();
187
+ if (!str.includes(ctx.keywordLower))
188
+ return false;
189
+ }
190
+ return true;
191
+ }
192
+ function flattenOrdersToBookings(orders) {
193
+ if (!orders || !Array.isArray(orders))
194
+ return [];
195
+ const result = [];
196
+ for (let i = 0, len = orders.length; i < len; i++) {
197
+ const order = orders[i];
198
+ const bookings = order.bookings;
199
+ if (!Array.isArray(bookings) || bookings.length === 0)
200
+ continue;
201
+ const { bookings: _omit, ...orderInfo } = order;
202
+ for (let j = 0, bLen = bookings.length; j < bLen; j++) {
203
+ result.push({ ...bookings[j], order: orderInfo });
204
+ }
205
+ }
206
+ return result;
207
+ }
208
+ function filterBookingsFromOrders(orders, filters) {
209
+ const f = filters || {};
210
+ if (!orders || !Array.isArray(orders)) {
211
+ return { list: [], count: 0, size: 0, skip: 0 };
212
+ }
213
+ const size = f.num || 20;
214
+ const page = f.skip || 1;
215
+ const startIndex = (page - 1) * size;
216
+ const ctx = prepareFilters(f);
217
+ let totalCount = 0;
218
+ const paginatedList = [];
219
+ for (let i = 0, oLen = orders.length; i < oLen; i++) {
220
+ const order = orders[i];
221
+ const bookings = order.bookings;
222
+ if (!Array.isArray(bookings) || bookings.length === 0)
223
+ continue;
224
+ if (!matchOrder(order, ctx))
225
+ continue;
226
+ let orderInfo = null;
227
+ for (let j = 0, bLen = bookings.length; j < bLen; j++) {
228
+ const booking = bookings[j];
229
+ if (ctx.keywordLower && !orderInfo) {
230
+ const { bookings: _omit, ...rest } = order;
231
+ orderInfo = rest;
232
+ }
233
+ if (!matchBooking(booking, orderInfo, ctx))
234
+ continue;
235
+ if (totalCount >= startIndex && paginatedList.length < size) {
236
+ if (!orderInfo) {
237
+ const { bookings: _omit, ...rest } = order;
238
+ orderInfo = rest;
239
+ }
240
+ paginatedList.push({ ...booking, order: orderInfo });
241
+ }
242
+ totalCount++;
243
+ }
244
+ }
245
+ return {
246
+ list: paginatedList,
247
+ count: totalCount,
248
+ size,
249
+ skip: page
250
+ };
251
+ }
252
+ function sortBookings(result, filters) {
253
+ const f = filters || {};
254
+ const orderBy = f.order_by;
255
+ if (!orderBy)
256
+ return result;
257
+ const separatorIdx = orderBy.lastIndexOf(":");
258
+ if (separatorIdx === -1)
259
+ return result;
260
+ const field = orderBy.slice(0, separatorIdx);
261
+ const direction = orderBy.slice(separatorIdx + 1);
262
+ if (direction !== "asc" && direction !== "desc")
263
+ return result;
264
+ const multiplier = direction === "asc" ? 1 : -1;
265
+ const getTimestamp = (booking) => {
266
+ switch (field) {
267
+ case "start_at":
268
+ return toTimestamp(bookingDateTimeString(booking.start_date, booking.start_time));
269
+ case "end_at":
270
+ return toTimestamp(bookingDateTimeString(booking.end_date, booking.end_time));
271
+ case "created_at":
272
+ return toTimestamp(booking.order.created_at);
273
+ case "updated_at":
274
+ return toTimestamp(booking.order.updated_at);
275
+ default:
276
+ return 0;
277
+ }
278
+ };
279
+ const sorted = result.list.slice().sort((a, b) => {
280
+ return (getTimestamp(a) - getTimestamp(b)) * multiplier;
281
+ });
282
+ return { ...result, list: sorted };
283
+ }
284
+ function filterBookings(bookings, filters) {
285
+ const f = filters || {};
286
+ if (!bookings || !Array.isArray(bookings)) {
287
+ return { list: [], count: 0, size: 0, skip: 0 };
288
+ }
289
+ const size = f.num || 20;
290
+ const page = f.skip || 1;
291
+ const startIndex = (page - 1) * size;
292
+ const ctx = prepareFilters(f);
293
+ let totalCount = 0;
294
+ const paginatedList = [];
295
+ for (let i = 0, len = bookings.length; i < len; i++) {
296
+ const booking = bookings[i];
297
+ const order = booking.order;
298
+ if (!matchOrder(order, ctx))
299
+ continue;
300
+ if (!matchBooking(booking, order, ctx))
301
+ continue;
302
+ if (totalCount >= startIndex && paginatedList.length < size) {
303
+ paginatedList.push(booking);
304
+ }
305
+ totalCount++;
306
+ }
307
+ return {
308
+ list: paginatedList,
309
+ count: totalCount,
310
+ size,
311
+ skip: page
312
+ };
313
+ }
314
+ // Annotate the CommonJS export names for ESM import in node:
315
+ 0 && (module.exports = {
316
+ filterBookings,
317
+ filterBookingsFromOrders,
318
+ flattenOrdersToBookings,
319
+ sortBookings
320
+ });
@@ -0,0 +1,15 @@
1
+ import type { OrderData, OrderFilters, OrderFilterResult } from '../types';
2
+ export type { OrderFilters, OrderFilterResult } from '../types';
3
+ /**
4
+ * 订单过滤函数
5
+ * @param orders 原始订单列表
6
+ * @param filters 过滤条件
7
+ * @returns 过滤 + 排序 + 分页后的结果
8
+ *
9
+ * @优化口子 性能优化预留:
10
+ * - 可在此函数入口加缓存(按 filters 签名缓存结果)
11
+ * - 可对枚举字段建倒排索引(status/payment_status/shipping_status/customer_id)
12
+ * - 可对文本字段加前缀树或分词索引
13
+ * - 可做增量过滤而非全量遍历
14
+ */
15
+ export declare function filterOrders(orders: OrderData[], filters: OrderFilters): OrderFilterResult;
@@ -0,0 +1,197 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/server/modules/order/utils/filterOrders.ts
20
+ var filterOrders_exports = {};
21
+ __export(filterOrders_exports, {
22
+ filterOrders: () => filterOrders
23
+ });
24
+ module.exports = __toCommonJS(filterOrders_exports);
25
+ function filterOrders(orders, filters) {
26
+ const safeFilters = filters || {};
27
+ if (!orders || !Array.isArray(orders)) {
28
+ return {
29
+ list: [],
30
+ count: 0,
31
+ size: 0,
32
+ skip: 0
33
+ };
34
+ }
35
+ const size = safeFilters.num || 20;
36
+ const page = safeFilters.skip || 1;
37
+ let filteredList = orders.filter((order) => {
38
+ if (safeFilters.status && safeFilters.status.length > 0) {
39
+ if (!order.status || !safeFilters.status.includes(order.status)) {
40
+ return false;
41
+ }
42
+ }
43
+ if (safeFilters.payment_status && safeFilters.payment_status.length > 0) {
44
+ if (!order.payment_status || !safeFilters.payment_status.includes(order.payment_status)) {
45
+ return false;
46
+ }
47
+ }
48
+ if (safeFilters.shipping_status && safeFilters.shipping_status.length > 0) {
49
+ if (!order.shipping_status || !safeFilters.shipping_status.includes(order.shipping_status)) {
50
+ return false;
51
+ }
52
+ }
53
+ if (safeFilters.customer_id !== void 0 && safeFilters.customer_id !== null) {
54
+ if (String(order.customer_id) !== String(safeFilters.customer_id)) {
55
+ return false;
56
+ }
57
+ }
58
+ if (safeFilters.order_sales_channel && safeFilters.order_sales_channel.length > 0) {
59
+ if (!order.order_sales_channel || !safeFilters.order_sales_channel.includes(order.order_sales_channel)) {
60
+ return false;
61
+ }
62
+ }
63
+ if (safeFilters.payment_methods && safeFilters.payment_methods.length > 0) {
64
+ if (!order.payment_methods || !Array.isArray(order.payment_methods) || order.payment_methods.length === 0) {
65
+ return false;
66
+ }
67
+ const hasMatch = order.payment_methods.some((pm) => safeFilters.payment_methods.includes(pm));
68
+ if (!hasMatch) {
69
+ return false;
70
+ }
71
+ }
72
+ if (safeFilters.min_total_amount !== void 0 || safeFilters.max_total_amount !== void 0) {
73
+ const orderAmount = parseFloat(String(order.total_amount || 0));
74
+ if (safeFilters.min_total_amount !== void 0 && orderAmount < safeFilters.min_total_amount) {
75
+ return false;
76
+ }
77
+ if (safeFilters.max_total_amount !== void 0 && orderAmount > safeFilters.max_total_amount) {
78
+ return false;
79
+ }
80
+ }
81
+ if (safeFilters.tag_ids && safeFilters.tag_ids.length > 0) {
82
+ if (!order.tag_ids || !Array.isArray(order.tag_ids) || order.tag_ids.length === 0) {
83
+ return false;
84
+ }
85
+ const filterTagSet = new Set(safeFilters.tag_ids.map(String));
86
+ const hasMatch = order.tag_ids.some((tag) => filterTagSet.has(String(tag)));
87
+ if (!hasMatch) {
88
+ return false;
89
+ }
90
+ }
91
+ if (safeFilters.shipping_type && safeFilters.shipping_type.length > 0) {
92
+ if (!order.shipping_type || !safeFilters.shipping_type.includes(order.shipping_type)) {
93
+ return false;
94
+ }
95
+ }
96
+ if (safeFilters.delivery_zone_name !== void 0 && safeFilters.delivery_zone_name !== null && safeFilters.delivery_zone_name !== "") {
97
+ if (!order.delivery_zone_name || !order.delivery_zone_name.toLowerCase().includes(safeFilters.delivery_zone_name.toLowerCase())) {
98
+ return false;
99
+ }
100
+ }
101
+ if (safeFilters.location_id !== void 0 && safeFilters.location_id !== null) {
102
+ if (String(order.location_id) !== String(safeFilters.location_id)) {
103
+ return false;
104
+ }
105
+ }
106
+ if (safeFilters.shipping_order_number !== void 0 && safeFilters.shipping_order_number !== null && safeFilters.shipping_order_number !== "") {
107
+ if (!order.shipping_order_number || !order.shipping_order_number.toLowerCase().includes(safeFilters.shipping_order_number.toLowerCase())) {
108
+ return false;
109
+ }
110
+ }
111
+ if (safeFilters.logistics_company_id && safeFilters.logistics_company_id.length > 0) {
112
+ if (!order.logistics_company_id) {
113
+ return false;
114
+ }
115
+ const orderLogisticsId = String(order.logistics_company_id);
116
+ const hasMatch = safeFilters.logistics_company_id.some((id) => String(id) === orderLogisticsId);
117
+ if (!hasMatch) {
118
+ return false;
119
+ }
120
+ }
121
+ if (safeFilters.zip !== void 0 && safeFilters.zip !== null && safeFilters.zip !== "") {
122
+ if (!order.zip || !order.zip.toLowerCase().includes(safeFilters.zip.toLowerCase())) {
123
+ return false;
124
+ }
125
+ }
126
+ if (safeFilters.business_code) {
127
+ if (!order.business_code || order.business_code !== safeFilters.business_code) {
128
+ return false;
129
+ }
130
+ }
131
+ if (safeFilters.start_time || safeFilters.end_time) {
132
+ const orderTime = order.created_at ? typeof order.created_at === "number" ? order.created_at : new Date(String(order.created_at)).getTime() : 0;
133
+ if (safeFilters.start_time) {
134
+ const startTs = new Date(safeFilters.start_time).getTime();
135
+ if (orderTime < startTs)
136
+ return false;
137
+ }
138
+ if (safeFilters.end_time) {
139
+ const endTs = new Date(safeFilters.end_time).getTime() + 864e5 - 1;
140
+ if (orderTime > endTs)
141
+ return false;
142
+ }
143
+ }
144
+ return true;
145
+ });
146
+ if (safeFilters.order_by) {
147
+ const sortField = safeFilters.order_by;
148
+ const sortOrder = safeFilters.sort || "desc";
149
+ filteredList.sort((a, b) => {
150
+ let aVal;
151
+ let bVal;
152
+ switch (sortField) {
153
+ case "created_at":
154
+ aVal = a.created_at ? typeof a.created_at === "number" ? a.created_at : new Date(String(a.created_at)).getTime() : 0;
155
+ bVal = b.created_at ? typeof b.created_at === "number" ? b.created_at : new Date(String(b.created_at)).getTime() : 0;
156
+ break;
157
+ case "updated_at":
158
+ aVal = a.updated_at ? typeof a.updated_at === "number" ? a.updated_at : new Date(String(a.updated_at)).getTime() : 0;
159
+ bVal = b.updated_at ? typeof b.updated_at === "number" ? b.updated_at : new Date(String(b.updated_at)).getTime() : 0;
160
+ break;
161
+ case "total_amount":
162
+ aVal = parseFloat(String(a.total_amount || 0));
163
+ bVal = parseFloat(String(b.total_amount || 0));
164
+ break;
165
+ case "customer_name":
166
+ aVal = (a.customer_name || "").toLowerCase();
167
+ bVal = (b.customer_name || "").toLowerCase();
168
+ break;
169
+ case "amount_gap":
170
+ return 0;
171
+ default:
172
+ return 0;
173
+ }
174
+ if (aVal < bVal) {
175
+ return sortOrder === "asc" ? -1 : 1;
176
+ }
177
+ if (aVal > bVal) {
178
+ return sortOrder === "asc" ? 1 : -1;
179
+ }
180
+ return 0;
181
+ });
182
+ }
183
+ const totalCount = filteredList.length;
184
+ const startIndex = (page - 1) * size;
185
+ const endIndex = startIndex + size;
186
+ const paginatedList = filteredList.slice(startIndex, endIndex);
187
+ return {
188
+ list: paginatedList,
189
+ count: totalCount,
190
+ size,
191
+ skip: page
192
+ };
193
+ }
194
+ // Annotate the CommonJS export names for ESM import in node:
195
+ 0 && (module.exports = {
196
+ filterOrders
197
+ });
@@ -53,20 +53,14 @@ export declare class ProductsModule extends BaseModule implements Module {
53
53
  * 缓存的是已经应用了价格的完整商品列表,避免重复转换
54
54
  * @param schedule_date 日期
55
55
  * @param extraContext 额外的上下文数据(可选,由 Server 层传入)
56
- * @param options 可选参数
57
- * @param options.changedIds 变更的商品 IDs,非空时仅对这些商品增量执行 prepare 并更新缓存
58
56
  * @returns 应用了价格的商品列表
59
57
  */
60
- getProductsWithPrice(schedule_date: string, extraContext?: Partial<ProductFormatterContext>, options?: {
61
- changedIds?: number[];
62
- }): Promise<ProductData[]>;
58
+ getProductsWithPrice(schedule_date: string, extraContext?: Partial<ProductFormatterContext>): Promise<ProductData[]>;
63
59
  /**
64
60
  * 准备带价格的商品数据(通过格式化器流程处理)
65
61
  * @param schedule_date 日期
66
62
  * @param extraContext 额外的上下文数据(可选)
67
- * @param options 可选参数
68
- * @param options.productIds 指定商品 IDs,仅处理这些商品;不传则处理全量
69
- * @returns 处理后的商品列表
63
+ * @returns 完整处理后的商品列表
70
64
  * @private
71
65
  */
72
66
  private prepareProductsWithPrice;
@@ -162,6 +156,11 @@ export declare class ProductsModule extends BaseModule implements Module {
162
156
  * 用于 pubsub 同步 create / update / batch_update 场景
163
157
  */
164
158
  refreshProducts(): Promise<ProductData[]>;
159
+ /**
160
+ * 局部更新指定商品的报价单价格
161
+ * 遍历所有已缓存的日期,为目标商品重新获取价格并覆盖到缓存中
162
+ */
163
+ updateProductPriceByIds(ids: number[]): Promise<void>;
165
164
  /**
166
165
  * 清空缓存
167
166
  */
@@ -203,18 +202,15 @@ export declare class ProductsModule extends BaseModule implements Module {
203
202
  *
204
203
  * product 模块:
205
204
  * - operation === 'delete' → 本地删除
206
- * - change_types 包含 price → 仅收集变更 IDs(不拉商品数据)
207
- * - bodybody 完整数据直接覆盖本地
208
- * - 其他SSE 增量拉取
205
+ * - body(无 price change_types) body 完整数据直接覆盖本地
206
+ * - change_types 包含 price SSE 增量拉取 + 刷新报价单价格缓存
207
+ * - change_types 仅 stock 跳过(暂不响应)
209
208
  *
210
- * product_collection / product_category:
209
+ * product_collection / product_category / product_quotation
211
210
  * - 按 relation_product_ids SSE 拉取受影响商品
211
+ * - product_quotation 额外刷新报价单价格缓存
212
212
  *
213
- * product_quotation:
214
- * - 报价单变更影响范围大,直接清除价格缓存走全量重建
215
- *
216
- * 处理完成后 emit onProductsSyncCompleted(携带 changedIds),
217
- * Server 层监听该事件后对变更商品增量执行 prepareProductsWithPrice 并更新缓存
213
+ * 处理完成后 emit onProductsSyncCompleted 通知 Server 层
218
214
  */
219
215
  private processProductSyncMessages;
220
216
  /**
@@ -225,8 +221,7 @@ export declare class ProductsModule extends BaseModule implements Module {
225
221
  /**
226
222
  * 将 body 完整数据直接覆盖到本地 store(不调用报价单接口)
227
223
  * 已存在的 → 直接替换;不存在的 → 追加
228
- * 同时更新 Map 缓存、IndexDB,触发 onProductsChanged
229
- * 价格缓存由 processProductSyncMessages 末尾统一清除
224
+ * 同时更新 Map 缓存、IndexDB,清空价格缓存,触发 onProductsChanged
230
225
  */
231
226
  private applyBodyUpdatesToStore;
232
227
  /**
@@ -235,6 +230,16 @@ export declare class ProductsModule extends BaseModule implements Module {
235
230
  * 同时更新 store.map、IndexDB,触发 onProductsChanged
236
231
  */
237
232
  private mergeProductsToStore;
233
+ /**
234
+ * 增量更新价格缓存中变更的商品
235
+ * 对每个已缓存的日期 key:替换/追加最新商品数据,重新拉取这些 ID 的价格并应用
236
+ */
237
+ private updatePriceCacheForProducts;
238
+ /**
239
+ * 全量重新拉取报价单价格并重建价格缓存
240
+ * 遍历当前已缓存的所有日期 key,对每个日期重新调用 loadProductsPrice
241
+ */
242
+ private refreshAllPriceCache;
238
243
  /**
239
244
  * 静默全量刷新:后台重新拉取全量 SSE 数据并更新本地
240
245
  * 拿到完整数据后一次性替换 store,清除价格缓存,触发 onProductsSyncCompleted