@pisell/pisellos 2.2.94 → 2.2.95
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/core/index.d.ts +1 -0
- package/dist/core/index.js +7 -0
- package/dist/modules/Customer/index.d.ts +1 -0
- package/dist/modules/Customer/index.js +28 -12
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js +40 -17
- package/dist/server/modules/order/types.d.ts +1 -1
- package/dist/server/modules/order/utils/filterBookings.js +1 -1
- package/dist/server/modules/products/index.d.ts +19 -24
- package/dist/server/modules/products/index.js +429 -600
- package/dist/server/modules/products/types.d.ts +1 -0
- package/dist/server/utils/product.d.ts +4 -0
- package/dist/server/utils/product.js +34 -0
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/Sales/index.d.ts +1 -1
- package/dist/solution/Sales/index.js +72 -20
- package/dist/solution/Sales/types.d.ts +5 -4
- package/dist/types/index.d.ts +2 -0
- package/lib/core/index.d.ts +1 -0
- package/lib/core/index.js +4 -0
- package/lib/modules/Customer/index.d.ts +1 -0
- package/lib/modules/Customer/index.js +21 -6
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/server/index.d.ts +6 -1
- package/lib/server/index.js +33 -13
- package/lib/server/modules/order/types.d.ts +1 -1
- package/lib/server/modules/order/utils/filterBookings.js +1 -1
- package/lib/server/modules/products/index.d.ts +19 -24
- package/lib/server/modules/products/index.js +151 -150
- package/lib/server/modules/products/types.d.ts +1 -0
- package/lib/server/utils/product.d.ts +4 -0
- package/lib/server/utils/product.js +27 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/Sales/index.d.ts +1 -1
- package/lib/solution/Sales/index.js +67 -12
- package/lib/solution/Sales/types.d.ts +5 -4
- package/lib/types/index.d.ts +2 -0
- package/package.json +1 -1
|
@@ -147,17 +147,20 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
147
147
|
* - n = booking 数量
|
|
148
148
|
* - s = 时间片数量
|
|
149
149
|
*/
|
|
150
|
-
getTimelineHighlights(bookingList = []) {
|
|
150
|
+
getTimelineHighlights(bookingList = [], startDateTime, endDateTime) {
|
|
151
151
|
const bucketMinutes = this.getTimelineBucketMinutes();
|
|
152
152
|
const bucketMs = bucketMinutes * 60 * 1e3;
|
|
153
|
-
const
|
|
153
|
+
const customStartAt = startDateTime ? (0, import_dayjs.default)(startDateTime) : (0, import_dayjs.default)("");
|
|
154
|
+
const customEndExclusiveAt = endDateTime ? (0, import_dayjs.default)(endDateTime) : (0, import_dayjs.default)("");
|
|
155
|
+
const hasValidCustomRange = customStartAt.isValid() && customEndExclusiveAt.isValid();
|
|
156
|
+
const { startAt, endExclusiveAt } = hasValidCustomRange ? { startAt: customStartAt, endExclusiveAt: customEndExclusiveAt } : this.getTimelineRangeByOperatingBoundary();
|
|
154
157
|
const startAtMs = startAt.valueOf();
|
|
155
158
|
const endExclusiveAtMs = endExclusiveAt.valueOf();
|
|
156
159
|
if (!startAt.isValid() || !endExclusiveAt.isValid() || endExclusiveAtMs <= startAtMs)
|
|
157
|
-
return
|
|
160
|
+
return [];
|
|
158
161
|
const slotCount = Math.ceil((endExclusiveAtMs - startAtMs) / bucketMs);
|
|
159
162
|
if (slotCount <= 0)
|
|
160
|
-
return
|
|
163
|
+
return [];
|
|
161
164
|
const diff = new Int32Array(slotCount + 1);
|
|
162
165
|
for (let i = 0; i < bookingList.length; i++) {
|
|
163
166
|
const booking = bookingList[i];
|
|
@@ -179,12 +182,11 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
179
182
|
diff[startIdx] += 1;
|
|
180
183
|
diff[endIdx + 1] -= 1;
|
|
181
184
|
}
|
|
182
|
-
const timeline =
|
|
185
|
+
const timeline = [];
|
|
183
186
|
let runningCount = 0;
|
|
184
187
|
for (let i = 0; i < slotCount; i++) {
|
|
185
188
|
runningCount += diff[i];
|
|
186
|
-
|
|
187
|
-
timeline[label] = runningCount;
|
|
189
|
+
timeline.push(runningCount);
|
|
188
190
|
}
|
|
189
191
|
return timeline;
|
|
190
192
|
}
|
|
@@ -247,6 +249,37 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
247
249
|
});
|
|
248
250
|
if (dayScopedBookings.length === 0)
|
|
249
251
|
return [];
|
|
252
|
+
const appendNextStartGroupIfNeeded = (selectedBookings) => {
|
|
253
|
+
if (selectedBookings.length === 0)
|
|
254
|
+
return selectedBookings;
|
|
255
|
+
const shouldAppendNextGroup = selectedBookings.some(
|
|
256
|
+
(booking) => booking.status === "reserved" || booking.status === "occupied"
|
|
257
|
+
);
|
|
258
|
+
if (!shouldAppendNextGroup)
|
|
259
|
+
return selectedBookings;
|
|
260
|
+
const selectedStartValues = new Set(
|
|
261
|
+
selectedBookings.map((booking) => this.toBookingDateTime(booking.start_date, booking.start_time)).filter((startAt) => startAt.isValid()).map((startAt) => startAt.valueOf())
|
|
262
|
+
);
|
|
263
|
+
const futureCandidates = dayScopedBookings.filter((booking) => {
|
|
264
|
+
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
265
|
+
if (!startAt.isValid())
|
|
266
|
+
return false;
|
|
267
|
+
return startAt.isAfter(current) && !selectedStartValues.has(startAt.valueOf());
|
|
268
|
+
});
|
|
269
|
+
if (futureCandidates.length === 0)
|
|
270
|
+
return selectedBookings;
|
|
271
|
+
const nextStartAt = this.toBookingDateTime(
|
|
272
|
+
futureCandidates[0].start_date,
|
|
273
|
+
futureCandidates[0].start_time
|
|
274
|
+
).valueOf();
|
|
275
|
+
const nextStartGroup = futureCandidates.filter((booking) => {
|
|
276
|
+
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
277
|
+
return startAt.isValid() && startAt.valueOf() === nextStartAt;
|
|
278
|
+
});
|
|
279
|
+
if (nextStartGroup.length === 0)
|
|
280
|
+
return selectedBookings;
|
|
281
|
+
return [...selectedBookings, ...nextStartGroup];
|
|
282
|
+
};
|
|
250
283
|
const activeBookings = dayScopedBookings.filter((booking) => {
|
|
251
284
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
252
285
|
const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
|
|
@@ -255,22 +288,23 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
255
288
|
return this.isSameOrAfter(current, startAt) && this.isSameOrBefore(current, endAt);
|
|
256
289
|
});
|
|
257
290
|
if (activeBookings.length > 0)
|
|
258
|
-
return activeBookings;
|
|
291
|
+
return appendNextStartGroupIfNeeded(activeBookings);
|
|
259
292
|
const timeoutOccupied = dayScopedBookings.filter(
|
|
260
293
|
(booking) => booking.status === "occupied" && booking.isTimeout
|
|
261
294
|
);
|
|
262
295
|
if (timeoutOccupied.length > 0)
|
|
263
|
-
return timeoutOccupied;
|
|
296
|
+
return appendNextStartGroupIfNeeded(timeoutOccupied);
|
|
264
297
|
const upcoming = dayScopedBookings.filter((booking) => {
|
|
265
298
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
266
299
|
return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, "day");
|
|
267
300
|
});
|
|
268
301
|
if (upcoming.length > 0) {
|
|
269
302
|
const firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
|
|
270
|
-
|
|
303
|
+
const upcomingStartGroup = upcoming.filter((booking) => {
|
|
271
304
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
272
305
|
return startAt.valueOf() === firstStartAt;
|
|
273
306
|
});
|
|
307
|
+
return appendNextStartGroupIfNeeded(upcomingStartGroup);
|
|
274
308
|
}
|
|
275
309
|
const fallback = dayScopedBookings[dayScopedBookings.length - 1];
|
|
276
310
|
return fallback ? [fallback] : [];
|
|
@@ -289,17 +323,39 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
289
323
|
const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
|
|
290
324
|
const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
|
|
291
325
|
const isTimeout = bookingStatus === "occupied" && endAt.isValid() && current.isAfter(endAt);
|
|
326
|
+
const timeoutTime = isTimeout ? current.diff(endAt, "minute") : void 0;
|
|
327
|
+
const progressPercent = (() => {
|
|
328
|
+
if (bookingStatus !== "occupied")
|
|
329
|
+
return 0;
|
|
330
|
+
if (!startAt.isValid() || !endAt.isValid())
|
|
331
|
+
return 0;
|
|
332
|
+
const totalMinutes = endAt.diff(startAt, "minute");
|
|
333
|
+
if (totalMinutes <= 0)
|
|
334
|
+
return 0;
|
|
335
|
+
const elapsedMinutes = current.diff(startAt, "minute");
|
|
336
|
+
if (elapsedMinutes <= 0)
|
|
337
|
+
return 0;
|
|
338
|
+
if (elapsedMinutes >= totalMinutes)
|
|
339
|
+
return 100;
|
|
340
|
+
return Math.floor(elapsedMinutes / totalMinutes * 100);
|
|
341
|
+
})();
|
|
292
342
|
let reservedStatus;
|
|
343
|
+
let lateTime;
|
|
293
344
|
if (bookingStatus === "reserved" && startAt.isValid() && endAt.isValid()) {
|
|
294
345
|
if (current.isBefore(startAt))
|
|
295
346
|
reservedStatus = "not_arrived";
|
|
296
|
-
if (current.isAfter(endAt))
|
|
347
|
+
if (current.isAfter(endAt)) {
|
|
297
348
|
reservedStatus = "late";
|
|
349
|
+
lateTime = current.diff(startAt, "minute");
|
|
350
|
+
}
|
|
298
351
|
}
|
|
299
352
|
return {
|
|
300
353
|
...booking,
|
|
301
354
|
status: bookingStatus,
|
|
302
355
|
isTimeout,
|
|
356
|
+
timeoutTime,
|
|
357
|
+
progressPercent,
|
|
358
|
+
lateTime,
|
|
303
359
|
reserved_status: reservedStatus
|
|
304
360
|
};
|
|
305
361
|
}
|
|
@@ -315,7 +371,6 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
315
371
|
{ osServer: true, isShopApi: true }
|
|
316
372
|
);
|
|
317
373
|
const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
|
|
318
|
-
console.log(1111, currentTime, resourceList, bookingList);
|
|
319
374
|
if (!Array.isArray(resourceList) || resourceList.length === 0)
|
|
320
375
|
return [];
|
|
321
376
|
const normalizedBookings = bookingList.map((booking) => this.normalizeMatchedBooking(current, booking)).filter((booking) => Boolean(booking)).sort((left, right) => {
|
|
@@ -21,15 +21,16 @@ export type SalesReservedStatus = 'not_arrived' | 'late' | undefined;
|
|
|
21
21
|
export interface SalesResourceMatchedBooking extends Omit<BookingData, 'status'> {
|
|
22
22
|
status: SalesBookingStatus;
|
|
23
23
|
isTimeout: boolean;
|
|
24
|
+
timeoutTime?: number;
|
|
25
|
+
progressPercent?: number;
|
|
26
|
+
lateTime?: number;
|
|
24
27
|
reserved_status: SalesReservedStatus;
|
|
25
28
|
}
|
|
26
29
|
export interface SalesResourceBookingItem extends Omit<ResourceData, 'bookings'> {
|
|
27
30
|
resource_id: ResourceId;
|
|
28
31
|
bookings: SalesResourceMatchedBooking[];
|
|
29
32
|
}
|
|
30
|
-
export
|
|
31
|
-
[time: string]: number;
|
|
32
|
-
}
|
|
33
|
+
export type SalesTimelineHighlights = number[];
|
|
33
34
|
/**
|
|
34
35
|
* Sales 解决方案状态
|
|
35
36
|
*
|
|
@@ -61,5 +62,5 @@ export interface SalesModuleAPI {
|
|
|
61
62
|
/** 获取资源维度的预约占用列表 */
|
|
62
63
|
getResourceBookingList: (currentTime: string, bookingList: BookingData[]) => Promise<SalesResourceBookingItem[]>;
|
|
63
64
|
/** 获取时间轴每个时间片的预约数量 */
|
|
64
|
-
getTimelineHighlights: (bookingList: BookingData[]) => SalesTimelineHighlights;
|
|
65
|
+
getTimelineHighlights: (bookingList: BookingData[], startDateTime?: string, endDateTime?: string) => SalesTimelineHighlights;
|
|
65
66
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ export interface PisellCore {
|
|
|
52
52
|
validateContext: (config: ModuleContextConfig) => boolean;
|
|
53
53
|
serverOptions?: ServerOptions;
|
|
54
54
|
server?: any;
|
|
55
|
+
setContext: (ctx: Partial<BusinessContext>) => void;
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* 业务上下文接口
|
|
@@ -59,6 +60,7 @@ export interface PisellCore {
|
|
|
59
60
|
export interface BusinessContext {
|
|
60
61
|
userId?: string;
|
|
61
62
|
companyId?: string;
|
|
63
|
+
locale?: string;
|
|
62
64
|
[key: string]: any;
|
|
63
65
|
}
|
|
64
66
|
/**
|