@pisell/private-materials 6.11.680 → 6.11.681
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/build/lowcode/assets-daily.json +11 -11
- package/build/lowcode/assets-dev.json +2 -2
- package/build/lowcode/assets-prod.json +11 -11
- package/build/lowcode/meta.js +1 -1
- package/build/lowcode/render/default/view.js +1 -1
- package/build/lowcode/view.js +1 -1
- package/es/plus/salesSdk/adjustTime/components/ChangeTimeControls.js +26 -6
- package/es/plus/salesSdk/adjustTime/hooks/useAdjustTimeModalController.js +13 -14
- package/es/plus/salesSdk/adjustTime/locales.js +5 -0
- package/es/plus/salesSdk/adjustTime/utils/changeTime.js +29 -14
- package/lib/plus/salesSdk/adjustTime/components/ChangeTimeControls.js +23 -3
- package/lib/plus/salesSdk/adjustTime/hooks/useAdjustTimeModalController.js +13 -14
- package/lib/plus/salesSdk/adjustTime/locales.js +5 -0
- package/lib/plus/salesSdk/adjustTime/utils/changeTime.js +29 -13
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
|
|
2
2
|
import BookingAvailabilityCalendar from "../../../../components/eventBooking/components/bookingAvailabilityCalendar/index.js";
|
|
3
3
|
import { t } from "../i18n.js";
|
|
4
|
-
import { buildChangeTimeCalendarProps, buildChangeTimeDateRangeProps } from "../utils/changeTime.js";
|
|
5
|
-
import React, { useMemo } from "react";
|
|
6
|
-
import { DatePicker, Iconfont, SelectTime } from "@pisell/materials";
|
|
4
|
+
import { buildChangeTimeCalendarProps, buildChangeTimeDateRangeProps, resolveChangeTimePickerDraft } from "../utils/changeTime.js";
|
|
5
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
6
|
+
import { DatePicker, Iconfont, SelectTime, useToast } from "@pisell/materials";
|
|
7
7
|
import classNames from "classnames";
|
|
8
8
|
import { LocalizationProvider, ThemeProvider, createTheme } from "@pisell/date-picker";
|
|
9
9
|
import { AdapterDayjs } from "@pisell/date-picker/es/AdapterDayjs";
|
|
@@ -28,20 +28,37 @@ const datePickerDarkTheme = createTheme({
|
|
|
28
28
|
} } } }
|
|
29
29
|
});
|
|
30
30
|
const ChangeTimeControls = ({ visible, value, onChange, rangeMode = "multiDay", showTime = true }) => {
|
|
31
|
+
const Toast = useToast();
|
|
32
|
+
const [pickerDraft, setPickerDraft] = useState(value);
|
|
33
|
+
const pickerOpenRef = useRef(false);
|
|
34
|
+
useEffect(() => setPickerDraft(value), [value]);
|
|
35
|
+
const handlePickerOpen = useCallback(() => {
|
|
36
|
+
pickerOpenRef.current = true;
|
|
37
|
+
}, []);
|
|
38
|
+
const handlePickerClose = useCallback(() => {
|
|
39
|
+
pickerOpenRef.current = false;
|
|
40
|
+
setPickerDraft(value);
|
|
41
|
+
}, [value]);
|
|
42
|
+
const handlePickerDateChange = useCallback((next) => {
|
|
43
|
+
if (!pickerOpenRef.current || !showTime) return;
|
|
44
|
+
setPickerDraft((previous) => resolveChangeTimePickerDraft(previous, next));
|
|
45
|
+
}, [showTime]);
|
|
31
46
|
const calendarProps = useMemo(() => buildChangeTimeCalendarProps({
|
|
32
47
|
value,
|
|
33
48
|
onChange
|
|
34
49
|
}), [onChange, value]);
|
|
35
50
|
const dateRangeProps = useMemo(() => buildChangeTimeDateRangeProps({
|
|
36
|
-
value,
|
|
51
|
+
value: pickerDraft,
|
|
37
52
|
mode: rangeMode,
|
|
38
53
|
showTime,
|
|
39
|
-
onChange
|
|
54
|
+
onChange,
|
|
55
|
+
onValidationError: Toast.error
|
|
40
56
|
}), [
|
|
41
57
|
onChange,
|
|
42
58
|
rangeMode,
|
|
43
59
|
showTime,
|
|
44
|
-
|
|
60
|
+
pickerDraft,
|
|
61
|
+
Toast.error
|
|
45
62
|
]);
|
|
46
63
|
return /* @__PURE__ */ React.createElement("section", { className: classNames("pisell-adjust-time__change-time-panel", { "pisell-adjust-time__change-time-panel--visible": visible }) }, /* @__PURE__ */ React.createElement("div", { className: "pisell-adjust-time__change-time-card" }, /* @__PURE__ */ React.createElement("span", { className: "pisell-adjust-time__end-time-label" }, t("pisell2.adjust-time.change-time-new-schedule")), /* @__PURE__ */ React.createElement(BookingAvailabilityCalendar, _objectSpread2(_objectSpread2({}, calendarProps), {}, {
|
|
47
64
|
showHeader: false,
|
|
@@ -50,6 +67,9 @@ const ChangeTimeControls = ({ visible, value, onChange, rangeMode = "multiDay",
|
|
|
50
67
|
dateAdapter: AdapterDayjs,
|
|
51
68
|
adapterLocale: "en"
|
|
52
69
|
}, /* @__PURE__ */ React.createElement(ThemeProvider, { theme: datePickerDarkTheme }, /* @__PURE__ */ React.createElement(RangePicker, _objectSpread2(_objectSpread2({}, dateRangeProps), {}, {
|
|
70
|
+
onOpen: handlePickerOpen,
|
|
71
|
+
onClose: handlePickerClose,
|
|
72
|
+
onDateChange: handlePickerDateChange,
|
|
53
73
|
timeInputComponent: SelectTime,
|
|
54
74
|
timeInputProps: {
|
|
55
75
|
slice: 15,
|
|
@@ -64,7 +64,7 @@ const resolveOptionalDate = (value) => {
|
|
|
64
64
|
const date = value instanceof Date ? value : new Date(value);
|
|
65
65
|
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
66
66
|
};
|
|
67
|
-
/**
|
|
67
|
+
/** 商品加时和补付超时按营业结束时间截断。 */
|
|
68
68
|
const clampToBusinessEnd = (date, businessEnd) => {
|
|
69
69
|
return date.getTime() > businessEnd.getTime() ? businessEnd : date;
|
|
70
70
|
};
|
|
@@ -88,11 +88,11 @@ const resolveAdjustTimeContext = ({ current, start, end, resourceEndTime, shopCl
|
|
|
88
88
|
const resolveAdjustTimePolicy = (context, bookingDuration) => {
|
|
89
89
|
const { current, start, end, businessEnd, resourceEndDate, isFutureBooking, hasBusinessEndConflict } = context;
|
|
90
90
|
const isCurrentBookingDay = isSameLocalDate(end, current);
|
|
91
|
+
const isOngoingBooking = start.getTime() <= current.getTime() && current.getTime() < end.getTime();
|
|
91
92
|
const configuredDuration = Number(bookingDuration);
|
|
92
93
|
const restartDuration = Number.isFinite(configuredDuration) && configuredDuration > 0 ? configuredDuration : minutesBetween(start, end);
|
|
93
|
-
const canRestart = isCurrentBookingDay
|
|
94
|
-
const
|
|
95
|
-
const restartEnd = canRestart ? clampToBusinessEnd(restartUncappedEnd, businessEnd) : end;
|
|
94
|
+
const canRestart = isCurrentBookingDay || isFutureBooking || isOngoingBooking;
|
|
95
|
+
const restartEnd = canRestart ? addMinutes(current, restartDuration) : end;
|
|
96
96
|
return {
|
|
97
97
|
start,
|
|
98
98
|
end,
|
|
@@ -110,21 +110,20 @@ const resolveAdjustTimePolicy = (context, bookingDuration) => {
|
|
|
110
110
|
canRestart,
|
|
111
111
|
payOvertimeEnd: isCurrentBookingDay && current.getTime() > end.getTime() ? current : end,
|
|
112
112
|
restartStart: canRestart ? current : start,
|
|
113
|
-
restartEnd
|
|
114
|
-
restartUncappedEnd
|
|
113
|
+
restartEnd
|
|
115
114
|
};
|
|
116
115
|
};
|
|
117
116
|
/**
|
|
118
|
-
*
|
|
117
|
+
* 原预约结束时间已经超过营业结束时间时,商品加时和补付超时不可继续加时。
|
|
119
118
|
* 这里仍返回一个可展示的方案,但 valid=false,用于 UI 展示原因和禁用提交。
|
|
120
119
|
*/
|
|
121
120
|
const resolveBusinessConflictScenario = (activeAction, start, end, products) => {
|
|
122
121
|
const productId = isProductAction(activeAction) ? activeAction.slice(8) : void 0;
|
|
123
122
|
const product = productId ? products.find((item) => String(item.id) === productId) : void 0;
|
|
124
123
|
return {
|
|
125
|
-
title:
|
|
126
|
-
subtitle:
|
|
127
|
-
icon:
|
|
124
|
+
title: (product === null || product === void 0 ? void 0 : product.title) || t("pisell2.adjust-time.pay-overtime"),
|
|
125
|
+
subtitle: isProductAction(activeAction) ? t("pisell2.adjust-time.product-subtitle") : t("pisell2.adjust-time.pay-overtime-subtitle"),
|
|
126
|
+
icon: (product === null || product === void 0 ? void 0 : product.unlimited) ? "Day" : product ? `${Number(product.minMinutes || 0)}m` : "◷",
|
|
128
127
|
newStart: start,
|
|
129
128
|
newEnd: end,
|
|
130
129
|
uncappedNewEnd: end,
|
|
@@ -140,7 +139,7 @@ const resolveBusinessConflictScenario = (activeAction, start, end, products) =>
|
|
|
140
139
|
*/
|
|
141
140
|
const buildAdjustTimeScenario = ({ activeAction, manualEndDate, changeTimeValue, policy, products }) => {
|
|
142
141
|
const { start, end, addTimeStart, addTimeBaseEnd, addTimeEndLimit, hasBusinessEndConflict } = policy;
|
|
143
|
-
if (activeAction !== "manualDuration" && activeAction !== "changeTime" && hasBusinessEndConflict) return resolveBusinessConflictScenario(activeAction, start, end, products);
|
|
142
|
+
if (activeAction !== "manualDuration" && activeAction !== "changeTime" && activeAction !== "restart" && hasBusinessEndConflict) return resolveBusinessConflictScenario(activeAction, start, end, products);
|
|
144
143
|
if (activeAction === "changeTime") {
|
|
145
144
|
const targetMinutes = minutesBetween(changeTimeValue.start, changeTimeValue.end);
|
|
146
145
|
return {
|
|
@@ -160,8 +159,7 @@ const buildAdjustTimeScenario = ({ activeAction, manualEndDate, changeTimeValue,
|
|
|
160
159
|
icon: "⟳",
|
|
161
160
|
newStart: policy.restartStart,
|
|
162
161
|
newEnd: policy.restartEnd,
|
|
163
|
-
uncappedNewEnd: policy.
|
|
164
|
-
effectiveEndLimit: addTimeEndLimit,
|
|
162
|
+
uncappedNewEnd: policy.restartEnd,
|
|
165
163
|
targetMinutes: policy.canRestart ? minutesBetween(policy.restartStart, policy.restartEnd) : 0,
|
|
166
164
|
valid: policy.canRestart && policy.restartEnd.getTime() > policy.restartStart.getTime()
|
|
167
165
|
};
|
|
@@ -295,7 +293,8 @@ const resolveAdjustTimeHints = ({ activeAction, addedMinutes, policy, scenario,
|
|
|
295
293
|
const { businessEnd, hasBusinessEndConflict, resourceEndDate } = policy;
|
|
296
294
|
const businessEndTime = formatTime(businessEnd);
|
|
297
295
|
const cappedEffectiveUntilTime = scenario.valid && pricedNewEnd.getTime() < uncappedPricedNewEnd.getTime() ? formatTime(pricedNewEnd) : void 0;
|
|
298
|
-
const
|
|
296
|
+
const isManualBeyondBusinessEnd = activeAction === "manualDuration" && pricedNewEnd.getTime() > businessEnd.getTime();
|
|
297
|
+
const shouldShowEffectiveUntilHint = activeAction !== "restart" && (isManualBeyondBusinessEnd || Boolean(cappedEffectiveUntilTime) || Boolean(hasBusinessEndConflict) || Boolean(scenario.unlimited));
|
|
299
298
|
const shouldShowResourceAvailabilityWarning = resourceEndDate ? !shouldShowEffectiveUntilHint && activeAction !== "restart" && activeAction !== "changeTime" && addedMinutes > 0 && resourceEndDate.getTime() < businessEnd.getTime() && pricedNewEnd.getTime() > resourceEndDate.getTime() : false;
|
|
300
299
|
return {
|
|
301
300
|
shouldShowEffectiveUntilHint,
|
|
@@ -25,6 +25,7 @@ var locales_default = {
|
|
|
25
25
|
"pisell2.adjust-time.change-time-date-range": "Select schedule date",
|
|
26
26
|
"pisell2.adjust-time.start-time": "Start time",
|
|
27
27
|
"pisell2.adjust-time.end-time": "End time",
|
|
28
|
+
"pisell2.adjust-time.end-must-be-after-start": "End time must be later than the start time.",
|
|
28
29
|
"pisell2.adjust-time.edit": "edit",
|
|
29
30
|
"pisell2.adjust-time.amount-due": "Amount Due",
|
|
30
31
|
"pisell2.adjust-time.amount-due-with-ticket-count": "Amount Due ({tickets})",
|
|
@@ -103,6 +104,7 @@ var locales_default = {
|
|
|
103
104
|
"pisell2.adjust-time.change-time-date-range": "选择日程日期",
|
|
104
105
|
"pisell2.adjust-time.start-time": "开始时间",
|
|
105
106
|
"pisell2.adjust-time.end-time": "结束时间",
|
|
107
|
+
"pisell2.adjust-time.end-must-be-after-start": "结束时间必须晚于开始时间",
|
|
106
108
|
"pisell2.adjust-time.edit": "编辑",
|
|
107
109
|
"pisell2.adjust-time.amount-due": "应付金额",
|
|
108
110
|
"pisell2.adjust-time.amount-due-with-ticket-count": "应付金额({tickets})",
|
|
@@ -181,6 +183,7 @@ var locales_default = {
|
|
|
181
183
|
"pisell2.adjust-time.change-time-date-range": "選擇日程日期",
|
|
182
184
|
"pisell2.adjust-time.start-time": "開始時間",
|
|
183
185
|
"pisell2.adjust-time.end-time": "結束時間",
|
|
186
|
+
"pisell2.adjust-time.end-must-be-after-start": "結束時間必須晚於開始時間",
|
|
184
187
|
"pisell2.adjust-time.edit": "編輯",
|
|
185
188
|
"pisell2.adjust-time.amount-due": "應付金額",
|
|
186
189
|
"pisell2.adjust-time.amount-due-with-ticket-count": "應付金額({tickets})",
|
|
@@ -259,6 +262,7 @@ var locales_default = {
|
|
|
259
262
|
"pisell2.adjust-time.change-time-date-range": "スケジュール日を選択",
|
|
260
263
|
"pisell2.adjust-time.start-time": "開始時間",
|
|
261
264
|
"pisell2.adjust-time.end-time": "終了時間",
|
|
265
|
+
"pisell2.adjust-time.end-must-be-after-start": "終了時間は開始時間より後にしてください。",
|
|
262
266
|
"pisell2.adjust-time.edit": "編集",
|
|
263
267
|
"pisell2.adjust-time.amount-due": "支払い金額",
|
|
264
268
|
"pisell2.adjust-time.amount-due-with-ticket-count": "支払い金額({tickets})",
|
|
@@ -337,6 +341,7 @@ var locales_default = {
|
|
|
337
341
|
"pisell2.adjust-time.change-time-date-range": "Selecionar data do agendamento",
|
|
338
342
|
"pisell2.adjust-time.start-time": "Horário de início",
|
|
339
343
|
"pisell2.adjust-time.end-time": "Horário de término",
|
|
344
|
+
"pisell2.adjust-time.end-must-be-after-start": "O horário de término deve ser posterior ao horário de início.",
|
|
340
345
|
"pisell2.adjust-time.edit": "editar",
|
|
341
346
|
"pisell2.adjust-time.amount-due": "Valor devido",
|
|
342
347
|
"pisell2.adjust-time.amount-due-with-ticket-count": "Valor devido ({tickets})",
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
|
|
2
1
|
import { addMinutes, applyTimeToDate, formatTime, minutesBetween } from "./time.js";
|
|
3
2
|
import dayjs from "dayjs";
|
|
3
|
+
import { locales } from "@pisell/utils";
|
|
4
4
|
//#region src/plus/salesSdk/adjustTime/utils/changeTime.ts
|
|
5
5
|
const DEFAULT_DATE_FORMAT = "YYYY/MM/DD";
|
|
6
6
|
const DEFAULT_DATE_TIME_FORMAT = "YYYY/MM/DD HH:mm";
|
|
7
7
|
const FALLBACK_DURATION_MINUTES = 60;
|
|
8
8
|
const toPickerValue = (value) => [dayjs(value.start), dayjs(value.end)];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
/** 在业务组件内联动开始时间,结束时间单独编辑时保留输入,交给 Apply 校验。 */
|
|
10
|
+
const resolveChangeTimePickerDraft = (previous, next) => {
|
|
11
|
+
var _next$, _next$2;
|
|
12
|
+
if (!((_next$ = next[0]) === null || _next$ === void 0 ? void 0 : _next$.isValid()) || !((_next$2 = next[1]) === null || _next$2 === void 0 ? void 0 : _next$2.isValid())) return previous;
|
|
13
|
+
const start = next[0].toDate();
|
|
14
|
+
const duration = previous.end.getTime() - previous.start.getTime();
|
|
15
|
+
return {
|
|
16
|
+
start,
|
|
17
|
+
end: start.getTime() !== previous.start.getTime() && duration > 0 ? new Date(start.getTime() + duration) : next[1].toDate()
|
|
18
|
+
};
|
|
12
19
|
};
|
|
13
20
|
const applyDateWithClock = (date, clockSource) => {
|
|
14
21
|
return applyTimeToDate(date.toDate(), formatTime(clockSource));
|
|
@@ -24,8 +31,22 @@ const resolveDefaultChangeTimeValue = (value, minDate = dayjs().startOf("day"))
|
|
|
24
31
|
if (!dayjs(value.start).isBefore(minDate, "day")) return value;
|
|
25
32
|
return moveChangeTimeRangeToDate(value, minDate.format("YYYY-MM-DD"));
|
|
26
33
|
};
|
|
27
|
-
const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = true, placeholder, minDate, maxDate, onChange, disabledDate }) => {
|
|
34
|
+
const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = true, placeholder, minDate, maxDate, onChange, onValidationError, disabledDate }) => {
|
|
28
35
|
const resolvedMinDate = minDate || dayjs().startOf("day");
|
|
36
|
+
const resolveValidNextValue = (nextValue) => {
|
|
37
|
+
if (!Array.isArray(nextValue) || !nextValue[0] || !nextValue[1]) return;
|
|
38
|
+
const [nextStartDay, nextEndDay] = nextValue;
|
|
39
|
+
const endDay = mode === "singleDay" && !showTime ? nextStartDay : nextEndDay;
|
|
40
|
+
const next = {
|
|
41
|
+
start: showTime ? nextStartDay.toDate() : applyDateWithClock(nextStartDay, value.start),
|
|
42
|
+
end: showTime ? endDay.toDate() : applyDateWithClock(endDay, value.end)
|
|
43
|
+
};
|
|
44
|
+
if (!(next.end.getTime() > next.start.getTime())) {
|
|
45
|
+
onValidationError === null || onValidationError === void 0 || onValidationError(locales.getText("pisell2.adjust-time.end-must-be-after-start"));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
return next;
|
|
49
|
+
};
|
|
29
50
|
return {
|
|
30
51
|
value: toPickerValue(value),
|
|
31
52
|
placeholder,
|
|
@@ -50,14 +71,8 @@ const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = tr
|
|
|
50
71
|
isHideCustomSelect: true,
|
|
51
72
|
disabledDate,
|
|
52
73
|
onChange: (nextValue) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const endDay = mode === "singleDay" ? nextStartDay : nextEndDay || nextStartDay;
|
|
56
|
-
if (!endDay) return;
|
|
57
|
-
onChange(ensureEndAfterStart({
|
|
58
|
-
start: showTime ? nextStartDay.toDate() : applyDateWithClock(nextStartDay, value.start),
|
|
59
|
-
end: showTime ? endDay.toDate() : applyDateWithClock(endDay, value.end)
|
|
60
|
-
}));
|
|
74
|
+
const next = resolveValidNextValue(nextValue);
|
|
75
|
+
if (next) onChange(next);
|
|
61
76
|
}
|
|
62
77
|
};
|
|
63
78
|
};
|
|
@@ -87,4 +102,4 @@ const buildChangeTimeCalendarProps = ({ value, onChange }) => {
|
|
|
87
102
|
};
|
|
88
103
|
};
|
|
89
104
|
//#endregion
|
|
90
|
-
export { buildChangeTimeCalendarProps, buildChangeTimeDateRangeProps, resolveDefaultChangeTimeValue };
|
|
105
|
+
export { buildChangeTimeCalendarProps, buildChangeTimeDateRangeProps, resolveChangeTimePickerDraft, resolveDefaultChangeTimeValue };
|
|
@@ -31,20 +31,37 @@ const datePickerDarkTheme = (0, _pisell_date_picker.createTheme)({
|
|
|
31
31
|
} } } }
|
|
32
32
|
});
|
|
33
33
|
const ChangeTimeControls = ({ visible, value, onChange, rangeMode = "multiDay", showTime = true }) => {
|
|
34
|
+
const Toast = (0, _pisell_materials.useToast)();
|
|
35
|
+
const [pickerDraft, setPickerDraft] = (0, react.useState)(value);
|
|
36
|
+
const pickerOpenRef = (0, react.useRef)(false);
|
|
37
|
+
(0, react.useEffect)(() => setPickerDraft(value), [value]);
|
|
38
|
+
const handlePickerOpen = (0, react.useCallback)(() => {
|
|
39
|
+
pickerOpenRef.current = true;
|
|
40
|
+
}, []);
|
|
41
|
+
const handlePickerClose = (0, react.useCallback)(() => {
|
|
42
|
+
pickerOpenRef.current = false;
|
|
43
|
+
setPickerDraft(value);
|
|
44
|
+
}, [value]);
|
|
45
|
+
const handlePickerDateChange = (0, react.useCallback)((next) => {
|
|
46
|
+
if (!pickerOpenRef.current || !showTime) return;
|
|
47
|
+
setPickerDraft((previous) => require_changeTime.resolveChangeTimePickerDraft(previous, next));
|
|
48
|
+
}, [showTime]);
|
|
34
49
|
const calendarProps = (0, react.useMemo)(() => require_changeTime.buildChangeTimeCalendarProps({
|
|
35
50
|
value,
|
|
36
51
|
onChange
|
|
37
52
|
}), [onChange, value]);
|
|
38
53
|
const dateRangeProps = (0, react.useMemo)(() => require_changeTime.buildChangeTimeDateRangeProps({
|
|
39
|
-
value,
|
|
54
|
+
value: pickerDraft,
|
|
40
55
|
mode: rangeMode,
|
|
41
56
|
showTime,
|
|
42
|
-
onChange
|
|
57
|
+
onChange,
|
|
58
|
+
onValidationError: Toast.error
|
|
43
59
|
}), [
|
|
44
60
|
onChange,
|
|
45
61
|
rangeMode,
|
|
46
62
|
showTime,
|
|
47
|
-
|
|
63
|
+
pickerDraft,
|
|
64
|
+
Toast.error
|
|
48
65
|
]);
|
|
49
66
|
return /* @__PURE__ */ react.default.createElement("section", { className: (0, classnames.default)("pisell-adjust-time__change-time-panel", { "pisell-adjust-time__change-time-panel--visible": visible }) }, /* @__PURE__ */ react.default.createElement("div", { className: "pisell-adjust-time__change-time-card" }, /* @__PURE__ */ react.default.createElement("span", { className: "pisell-adjust-time__end-time-label" }, require_i18n.t("pisell2.adjust-time.change-time-new-schedule")), /* @__PURE__ */ react.default.createElement(require_index.default, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, calendarProps), {}, {
|
|
50
67
|
showHeader: false,
|
|
@@ -53,6 +70,9 @@ const ChangeTimeControls = ({ visible, value, onChange, rangeMode = "multiDay",
|
|
|
53
70
|
dateAdapter: _pisell_date_picker_es_AdapterDayjs.AdapterDayjs,
|
|
54
71
|
adapterLocale: "en"
|
|
55
72
|
}, /* @__PURE__ */ react.default.createElement(_pisell_date_picker.ThemeProvider, { theme: datePickerDarkTheme }, /* @__PURE__ */ react.default.createElement(RangePicker, require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, dateRangeProps), {}, {
|
|
73
|
+
onOpen: handlePickerOpen,
|
|
74
|
+
onClose: handlePickerClose,
|
|
75
|
+
onDateChange: handlePickerDateChange,
|
|
56
76
|
timeInputComponent: _pisell_materials.SelectTime,
|
|
57
77
|
timeInputProps: {
|
|
58
78
|
slice: 15,
|
|
@@ -65,7 +65,7 @@ const resolveOptionalDate = (value) => {
|
|
|
65
65
|
const date = value instanceof Date ? value : new Date(value);
|
|
66
66
|
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
67
67
|
};
|
|
68
|
-
/**
|
|
68
|
+
/** 商品加时和补付超时按营业结束时间截断。 */
|
|
69
69
|
const clampToBusinessEnd = (date, businessEnd) => {
|
|
70
70
|
return date.getTime() > businessEnd.getTime() ? businessEnd : date;
|
|
71
71
|
};
|
|
@@ -89,11 +89,11 @@ const resolveAdjustTimeContext = ({ current, start, end, resourceEndTime, shopCl
|
|
|
89
89
|
const resolveAdjustTimePolicy = (context, bookingDuration) => {
|
|
90
90
|
const { current, start, end, businessEnd, resourceEndDate, isFutureBooking, hasBusinessEndConflict } = context;
|
|
91
91
|
const isCurrentBookingDay = isSameLocalDate(end, current);
|
|
92
|
+
const isOngoingBooking = start.getTime() <= current.getTime() && current.getTime() < end.getTime();
|
|
92
93
|
const configuredDuration = Number(bookingDuration);
|
|
93
94
|
const restartDuration = Number.isFinite(configuredDuration) && configuredDuration > 0 ? configuredDuration : require_time.minutesBetween(start, end);
|
|
94
|
-
const canRestart = isCurrentBookingDay
|
|
95
|
-
const
|
|
96
|
-
const restartEnd = canRestart ? clampToBusinessEnd(restartUncappedEnd, businessEnd) : end;
|
|
95
|
+
const canRestart = isCurrentBookingDay || isFutureBooking || isOngoingBooking;
|
|
96
|
+
const restartEnd = canRestart ? require_time.addMinutes(current, restartDuration) : end;
|
|
97
97
|
return {
|
|
98
98
|
start,
|
|
99
99
|
end,
|
|
@@ -111,21 +111,20 @@ const resolveAdjustTimePolicy = (context, bookingDuration) => {
|
|
|
111
111
|
canRestart,
|
|
112
112
|
payOvertimeEnd: isCurrentBookingDay && current.getTime() > end.getTime() ? current : end,
|
|
113
113
|
restartStart: canRestart ? current : start,
|
|
114
|
-
restartEnd
|
|
115
|
-
restartUncappedEnd
|
|
114
|
+
restartEnd
|
|
116
115
|
};
|
|
117
116
|
};
|
|
118
117
|
/**
|
|
119
|
-
*
|
|
118
|
+
* 原预约结束时间已经超过营业结束时间时,商品加时和补付超时不可继续加时。
|
|
120
119
|
* 这里仍返回一个可展示的方案,但 valid=false,用于 UI 展示原因和禁用提交。
|
|
121
120
|
*/
|
|
122
121
|
const resolveBusinessConflictScenario = (activeAction, start, end, products) => {
|
|
123
122
|
const productId = isProductAction(activeAction) ? activeAction.slice(8) : void 0;
|
|
124
123
|
const product = productId ? products.find((item) => String(item.id) === productId) : void 0;
|
|
125
124
|
return {
|
|
126
|
-
title:
|
|
127
|
-
subtitle:
|
|
128
|
-
icon:
|
|
125
|
+
title: (product === null || product === void 0 ? void 0 : product.title) || t("pisell2.adjust-time.pay-overtime"),
|
|
126
|
+
subtitle: isProductAction(activeAction) ? t("pisell2.adjust-time.product-subtitle") : t("pisell2.adjust-time.pay-overtime-subtitle"),
|
|
127
|
+
icon: (product === null || product === void 0 ? void 0 : product.unlimited) ? "Day" : product ? `${Number(product.minMinutes || 0)}m` : "◷",
|
|
129
128
|
newStart: start,
|
|
130
129
|
newEnd: end,
|
|
131
130
|
uncappedNewEnd: end,
|
|
@@ -141,7 +140,7 @@ const resolveBusinessConflictScenario = (activeAction, start, end, products) =>
|
|
|
141
140
|
*/
|
|
142
141
|
const buildAdjustTimeScenario = ({ activeAction, manualEndDate, changeTimeValue, policy, products }) => {
|
|
143
142
|
const { start, end, addTimeStart, addTimeBaseEnd, addTimeEndLimit, hasBusinessEndConflict } = policy;
|
|
144
|
-
if (activeAction !== "manualDuration" && activeAction !== "changeTime" && hasBusinessEndConflict) return resolveBusinessConflictScenario(activeAction, start, end, products);
|
|
143
|
+
if (activeAction !== "manualDuration" && activeAction !== "changeTime" && activeAction !== "restart" && hasBusinessEndConflict) return resolveBusinessConflictScenario(activeAction, start, end, products);
|
|
145
144
|
if (activeAction === "changeTime") {
|
|
146
145
|
const targetMinutes = require_time.minutesBetween(changeTimeValue.start, changeTimeValue.end);
|
|
147
146
|
return {
|
|
@@ -161,8 +160,7 @@ const buildAdjustTimeScenario = ({ activeAction, manualEndDate, changeTimeValue,
|
|
|
161
160
|
icon: "⟳",
|
|
162
161
|
newStart: policy.restartStart,
|
|
163
162
|
newEnd: policy.restartEnd,
|
|
164
|
-
uncappedNewEnd: policy.
|
|
165
|
-
effectiveEndLimit: addTimeEndLimit,
|
|
163
|
+
uncappedNewEnd: policy.restartEnd,
|
|
166
164
|
targetMinutes: policy.canRestart ? require_time.minutesBetween(policy.restartStart, policy.restartEnd) : 0,
|
|
167
165
|
valid: policy.canRestart && policy.restartEnd.getTime() > policy.restartStart.getTime()
|
|
168
166
|
};
|
|
@@ -296,7 +294,8 @@ const resolveAdjustTimeHints = ({ activeAction, addedMinutes, policy, scenario,
|
|
|
296
294
|
const { businessEnd, hasBusinessEndConflict, resourceEndDate } = policy;
|
|
297
295
|
const businessEndTime = require_time.formatTime(businessEnd);
|
|
298
296
|
const cappedEffectiveUntilTime = scenario.valid && pricedNewEnd.getTime() < uncappedPricedNewEnd.getTime() ? require_time.formatTime(pricedNewEnd) : void 0;
|
|
299
|
-
const
|
|
297
|
+
const isManualBeyondBusinessEnd = activeAction === "manualDuration" && pricedNewEnd.getTime() > businessEnd.getTime();
|
|
298
|
+
const shouldShowEffectiveUntilHint = activeAction !== "restart" && (isManualBeyondBusinessEnd || Boolean(cappedEffectiveUntilTime) || Boolean(hasBusinessEndConflict) || Boolean(scenario.unlimited));
|
|
300
299
|
const shouldShowResourceAvailabilityWarning = resourceEndDate ? !shouldShowEffectiveUntilHint && activeAction !== "restart" && activeAction !== "changeTime" && addedMinutes > 0 && resourceEndDate.getTime() < businessEnd.getTime() && pricedNewEnd.getTime() > resourceEndDate.getTime() : false;
|
|
301
300
|
return {
|
|
302
301
|
shouldShowEffectiveUntilHint,
|
|
@@ -25,6 +25,7 @@ var locales_default = {
|
|
|
25
25
|
"pisell2.adjust-time.change-time-date-range": "Select schedule date",
|
|
26
26
|
"pisell2.adjust-time.start-time": "Start time",
|
|
27
27
|
"pisell2.adjust-time.end-time": "End time",
|
|
28
|
+
"pisell2.adjust-time.end-must-be-after-start": "End time must be later than the start time.",
|
|
28
29
|
"pisell2.adjust-time.edit": "edit",
|
|
29
30
|
"pisell2.adjust-time.amount-due": "Amount Due",
|
|
30
31
|
"pisell2.adjust-time.amount-due-with-ticket-count": "Amount Due ({tickets})",
|
|
@@ -103,6 +104,7 @@ var locales_default = {
|
|
|
103
104
|
"pisell2.adjust-time.change-time-date-range": "选择日程日期",
|
|
104
105
|
"pisell2.adjust-time.start-time": "开始时间",
|
|
105
106
|
"pisell2.adjust-time.end-time": "结束时间",
|
|
107
|
+
"pisell2.adjust-time.end-must-be-after-start": "结束时间必须晚于开始时间",
|
|
106
108
|
"pisell2.adjust-time.edit": "编辑",
|
|
107
109
|
"pisell2.adjust-time.amount-due": "应付金额",
|
|
108
110
|
"pisell2.adjust-time.amount-due-with-ticket-count": "应付金额({tickets})",
|
|
@@ -181,6 +183,7 @@ var locales_default = {
|
|
|
181
183
|
"pisell2.adjust-time.change-time-date-range": "選擇日程日期",
|
|
182
184
|
"pisell2.adjust-time.start-time": "開始時間",
|
|
183
185
|
"pisell2.adjust-time.end-time": "結束時間",
|
|
186
|
+
"pisell2.adjust-time.end-must-be-after-start": "結束時間必須晚於開始時間",
|
|
184
187
|
"pisell2.adjust-time.edit": "編輯",
|
|
185
188
|
"pisell2.adjust-time.amount-due": "應付金額",
|
|
186
189
|
"pisell2.adjust-time.amount-due-with-ticket-count": "應付金額({tickets})",
|
|
@@ -259,6 +262,7 @@ var locales_default = {
|
|
|
259
262
|
"pisell2.adjust-time.change-time-date-range": "スケジュール日を選択",
|
|
260
263
|
"pisell2.adjust-time.start-time": "開始時間",
|
|
261
264
|
"pisell2.adjust-time.end-time": "終了時間",
|
|
265
|
+
"pisell2.adjust-time.end-must-be-after-start": "終了時間は開始時間より後にしてください。",
|
|
262
266
|
"pisell2.adjust-time.edit": "編集",
|
|
263
267
|
"pisell2.adjust-time.amount-due": "支払い金額",
|
|
264
268
|
"pisell2.adjust-time.amount-due-with-ticket-count": "支払い金額({tickets})",
|
|
@@ -337,6 +341,7 @@ var locales_default = {
|
|
|
337
341
|
"pisell2.adjust-time.change-time-date-range": "Selecionar data do agendamento",
|
|
338
342
|
"pisell2.adjust-time.start-time": "Horário de início",
|
|
339
343
|
"pisell2.adjust-time.end-time": "Horário de término",
|
|
344
|
+
"pisell2.adjust-time.end-must-be-after-start": "O horário de término deve ser posterior ao horário de início.",
|
|
340
345
|
"pisell2.adjust-time.edit": "editar",
|
|
341
346
|
"pisell2.adjust-time.amount-due": "Valor devido",
|
|
342
347
|
"pisell2.adjust-time.amount-due-with-ticket-count": "Valor devido ({tickets})",
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
const require_runtime = require("../../../../_virtual/_rolldown/runtime.js");
|
|
2
|
-
const require_objectSpread2 = require("../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
|
|
3
2
|
const require_time = require("./time.js");
|
|
4
3
|
let dayjs = require("dayjs");
|
|
5
4
|
dayjs = require_runtime.__toESM(dayjs);
|
|
5
|
+
let _pisell_utils = require("@pisell/utils");
|
|
6
6
|
//#region src/plus/salesSdk/adjustTime/utils/changeTime.ts
|
|
7
7
|
const DEFAULT_DATE_FORMAT = "YYYY/MM/DD";
|
|
8
8
|
const DEFAULT_DATE_TIME_FORMAT = "YYYY/MM/DD HH:mm";
|
|
9
9
|
const FALLBACK_DURATION_MINUTES = 60;
|
|
10
10
|
const toPickerValue = (value) => [(0, dayjs.default)(value.start), (0, dayjs.default)(value.end)];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/** 在业务组件内联动开始时间,结束时间单独编辑时保留输入,交给 Apply 校验。 */
|
|
12
|
+
const resolveChangeTimePickerDraft = (previous, next) => {
|
|
13
|
+
var _next$, _next$2;
|
|
14
|
+
if (!((_next$ = next[0]) === null || _next$ === void 0 ? void 0 : _next$.isValid()) || !((_next$2 = next[1]) === null || _next$2 === void 0 ? void 0 : _next$2.isValid())) return previous;
|
|
15
|
+
const start = next[0].toDate();
|
|
16
|
+
const duration = previous.end.getTime() - previous.start.getTime();
|
|
17
|
+
return {
|
|
18
|
+
start,
|
|
19
|
+
end: start.getTime() !== previous.start.getTime() && duration > 0 ? new Date(start.getTime() + duration) : next[1].toDate()
|
|
20
|
+
};
|
|
14
21
|
};
|
|
15
22
|
const applyDateWithClock = (date, clockSource) => {
|
|
16
23
|
return require_time.applyTimeToDate(date.toDate(), require_time.formatTime(clockSource));
|
|
@@ -26,8 +33,22 @@ const resolveDefaultChangeTimeValue = (value, minDate = (0, dayjs.default)().sta
|
|
|
26
33
|
if (!(0, dayjs.default)(value.start).isBefore(minDate, "day")) return value;
|
|
27
34
|
return moveChangeTimeRangeToDate(value, minDate.format("YYYY-MM-DD"));
|
|
28
35
|
};
|
|
29
|
-
const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = true, placeholder, minDate, maxDate, onChange, disabledDate }) => {
|
|
36
|
+
const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = true, placeholder, minDate, maxDate, onChange, onValidationError, disabledDate }) => {
|
|
30
37
|
const resolvedMinDate = minDate || (0, dayjs.default)().startOf("day");
|
|
38
|
+
const resolveValidNextValue = (nextValue) => {
|
|
39
|
+
if (!Array.isArray(nextValue) || !nextValue[0] || !nextValue[1]) return;
|
|
40
|
+
const [nextStartDay, nextEndDay] = nextValue;
|
|
41
|
+
const endDay = mode === "singleDay" && !showTime ? nextStartDay : nextEndDay;
|
|
42
|
+
const next = {
|
|
43
|
+
start: showTime ? nextStartDay.toDate() : applyDateWithClock(nextStartDay, value.start),
|
|
44
|
+
end: showTime ? endDay.toDate() : applyDateWithClock(endDay, value.end)
|
|
45
|
+
};
|
|
46
|
+
if (!(next.end.getTime() > next.start.getTime())) {
|
|
47
|
+
onValidationError === null || onValidationError === void 0 || onValidationError(_pisell_utils.locales.getText("pisell2.adjust-time.end-must-be-after-start"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
return next;
|
|
51
|
+
};
|
|
31
52
|
return {
|
|
32
53
|
value: toPickerValue(value),
|
|
33
54
|
placeholder,
|
|
@@ -52,14 +73,8 @@ const buildChangeTimeDateRangeProps = ({ value, mode = "multiDay", showTime = tr
|
|
|
52
73
|
isHideCustomSelect: true,
|
|
53
74
|
disabledDate,
|
|
54
75
|
onChange: (nextValue) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const endDay = mode === "singleDay" ? nextStartDay : nextEndDay || nextStartDay;
|
|
58
|
-
if (!endDay) return;
|
|
59
|
-
onChange(ensureEndAfterStart({
|
|
60
|
-
start: showTime ? nextStartDay.toDate() : applyDateWithClock(nextStartDay, value.start),
|
|
61
|
-
end: showTime ? endDay.toDate() : applyDateWithClock(endDay, value.end)
|
|
62
|
-
}));
|
|
76
|
+
const next = resolveValidNextValue(nextValue);
|
|
77
|
+
if (next) onChange(next);
|
|
63
78
|
}
|
|
64
79
|
};
|
|
65
80
|
};
|
|
@@ -91,4 +106,5 @@ const buildChangeTimeCalendarProps = ({ value, onChange }) => {
|
|
|
91
106
|
//#endregion
|
|
92
107
|
exports.buildChangeTimeCalendarProps = buildChangeTimeCalendarProps;
|
|
93
108
|
exports.buildChangeTimeDateRangeProps = buildChangeTimeDateRangeProps;
|
|
109
|
+
exports.resolveChangeTimePickerDraft = resolveChangeTimePickerDraft;
|
|
94
110
|
exports.resolveDefaultChangeTimeValue = resolveDefaultChangeTimeValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pisell/private-materials",
|
|
3
|
-
"version": "6.11.
|
|
3
|
+
"version": "6.11.681",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"module": "./es/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
"use-sync-external-store": "^1.6.0",
|
|
72
72
|
"@pisell/pi-payment-sdk": "0.0.3",
|
|
73
73
|
"@pisell/utils": "3.0.4",
|
|
74
|
-
"@pisell/icon": "0.0.11",
|
|
75
74
|
"@pisell/materials": "6.11.263",
|
|
75
|
+
"@pisell/icon": "0.0.11",
|
|
76
76
|
"@pisell/date-picker": "3.0.10"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|