|
|
|
|
@ -140,9 +140,9 @@ type BookingDayRow = {
|
|
|
|
|
/** 可选;空=不限制开始,仅需在截止前 */
|
|
|
|
|
booking_opens_at: string
|
|
|
|
|
booking_deadline_at: string
|
|
|
|
|
/** 未填写时表格为空,提交前须填 */
|
|
|
|
|
/** 未填写时表格为空;需预约活动时提交前必填,其余性质选填 */
|
|
|
|
|
day_quota: number | undefined
|
|
|
|
|
/** 有值时 H5 场次「人数限制」展示此处文案,否则展示可预约人数数字 */
|
|
|
|
|
/** 有值时 H5 场次「参与人数」优先展示此处说明,否则展示数字 */
|
|
|
|
|
quota_note?: string
|
|
|
|
|
booked_count?: number
|
|
|
|
|
}
|
|
|
|
|
@ -267,7 +267,14 @@ const activityBookingStepIntro = computed(() => {
|
|
|
|
|
is_active: !!form.is_active,
|
|
|
|
|
}
|
|
|
|
|
const datePart = formatActivityTableDateRange(r)
|
|
|
|
|
return `本次活动日期 ${datePart},请逐项手动填写各场次的场次开始、场次结束${normalizeReservationKind(form.reservation_type) === 'online' ? '、预约开始与预约截止' : ''}及可预约人数;保存时将一并提交活动信息与场次。`
|
|
|
|
|
const rt = normalizeReservationKind(form.reservation_type)
|
|
|
|
|
if (rt === 'none' || rt === 'paid_study') {
|
|
|
|
|
return `本次活动日期 ${datePart},请逐项手动填写各场次信息`
|
|
|
|
|
}
|
|
|
|
|
if (rt === 'online') {
|
|
|
|
|
return `本次活动日期 ${datePart},请逐项手动填写各场次的场次开始、场次结束、预约开始与预约截止及可预约人数(必填)。保存时将一并提交活动信息与场次。`
|
|
|
|
|
}
|
|
|
|
|
return `本次活动日期 ${datePart},请逐项手动填写各场次信息`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
/** 审核弹窗内「提交人」展示文案 */
|
|
|
|
|
@ -421,19 +428,29 @@ const showBookingAudienceFields = computed(
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const sessionRulesHint = computed(() => {
|
|
|
|
|
const rt = normalizeReservationKind(form.reservation_type)
|
|
|
|
|
if (rt !== 'online') {
|
|
|
|
|
return ''
|
|
|
|
|
}
|
|
|
|
|
const groupNote =
|
|
|
|
|
'团体每单最少人数以及团体每单最多人数不是场次的可预约人数,仅限制每场次团体用户可预约的人数;'
|
|
|
|
|
const sameDay = '每场次的开始时间与结束时间须为同一天内;'
|
|
|
|
|
if (normalizeReservationKind(form.reservation_type) === 'online') {
|
|
|
|
|
return `${groupNote}${sameDay}场次开始、场次结束、预约开始、预约截止时间须填写;预约截止时间须早于场次开始时间;预约开始不得晚于预约截止;更改可预约人数不可低于已约人数;`
|
|
|
|
|
}
|
|
|
|
|
return `${groupNote}${sameDay}场次开始、场次结束须填写;更改可预约人数不可低于已约人数;`
|
|
|
|
|
return `${groupNote}${sameDay}场次开始、场次结束、预约开始、预约截止时间须填写;预约截止时间须早于场次开始时间;预约开始不得晚于预约截止;更改可预约人数不可低于已约人数;`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const sessionTableScrollX = computed(() =>
|
|
|
|
|
showSessionBookingWindowColumns.value ? 1470 : 920,
|
|
|
|
|
showSessionBookingWindowColumns.value ? 1470 : 940,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/** 场次表格/审核预览中「人数」列标题:需预约为可预约人数,其余为参加人数 */
|
|
|
|
|
const sessionQuotaColumnTitle = computed(() =>
|
|
|
|
|
normalizeReservationKind(form.reservation_type) === 'online' ? '可预约人数' : '参加人数',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
function auditSessionQuotaColumnTitle(rt?: string | null): string {
|
|
|
|
|
return normalizeReservationKind(rt) === 'online' ? '可预约人数' : '参加人数'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const activityModalTitle = computed(() => (isCreate.value ? '新增活动' : '编辑活动'))
|
|
|
|
|
|
|
|
|
|
function addBookingDayRow() {
|
|
|
|
|
@ -609,18 +626,33 @@ function validateBookingFormInternal(): boolean {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const booked = Math.max(0, Number(d.booked_count) || 0)
|
|
|
|
|
const minQ = Math.max(1, booked)
|
|
|
|
|
const quotaRaw = d.day_quota
|
|
|
|
|
if (quotaRaw === undefined || quotaRaw === null || !Number.isFinite(Number(quotaRaw))) {
|
|
|
|
|
Message.warning(`第 ${i + 1} 行请填写可预约人数`)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
const quotaNum = Math.floor(Number(quotaRaw))
|
|
|
|
|
if (quotaNum < minQ) {
|
|
|
|
|
Message.warning(
|
|
|
|
|
`第 ${i + 1} 行可预约人数须≥${minQ}${booked > 0 ? `(已约 ${booked} 人)` : ''}`,
|
|
|
|
|
)
|
|
|
|
|
return false
|
|
|
|
|
if (rt === 'online') {
|
|
|
|
|
const minQ = Math.max(1, booked)
|
|
|
|
|
if (quotaRaw === undefined || quotaRaw === null || !Number.isFinite(Number(quotaRaw))) {
|
|
|
|
|
Message.warning(`第 ${i + 1} 行请填写可预约人数`)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
const quotaNum = Math.floor(Number(quotaRaw))
|
|
|
|
|
if (quotaNum < minQ) {
|
|
|
|
|
Message.warning(
|
|
|
|
|
`第 ${i + 1} 行可预约人数须≥${minQ}${booked > 0 ? `(已约 ${booked} 人)` : ''}`,
|
|
|
|
|
)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} else if (quotaRaw !== undefined && quotaRaw !== null) {
|
|
|
|
|
if (!Number.isFinite(Number(quotaRaw))) {
|
|
|
|
|
Message.warning(`第 ${i + 1} 行参加人数须为有效数字`)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
const quotaNum = Math.floor(Number(quotaRaw))
|
|
|
|
|
const minAtt = Math.max(0, booked)
|
|
|
|
|
if (quotaNum < minAtt) {
|
|
|
|
|
Message.warning(
|
|
|
|
|
`第 ${i + 1} 行参加人数须≥${minAtt}${booked > 0 ? `(已约 ${booked} 人)` : ''}`,
|
|
|
|
|
)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
@ -649,14 +681,21 @@ function buildBookingPayload(): Record<string, unknown> {
|
|
|
|
|
rt === 'online'
|
|
|
|
|
? String(d.booking_deadline_at || '').trim()
|
|
|
|
|
: String(d.booking_deadline_at || '').trim() || start
|
|
|
|
|
const dq = d.day_quota
|
|
|
|
|
const row: Record<string, unknown> = {
|
|
|
|
|
session_name: d.session_name.trim(),
|
|
|
|
|
session_start_at: d.session_start_at,
|
|
|
|
|
session_end_at: d.session_end_at,
|
|
|
|
|
booking_deadline_at: deadlineIn || null,
|
|
|
|
|
day_quota: Math.floor(Number(d.day_quota)),
|
|
|
|
|
quota_note: (d.quota_note || '').trim() || null,
|
|
|
|
|
}
|
|
|
|
|
if (rt === 'online') {
|
|
|
|
|
row.day_quota = Math.floor(Number(dq))
|
|
|
|
|
} else if (dq === undefined || dq === null || (typeof dq === 'number' && !Number.isFinite(dq))) {
|
|
|
|
|
row.day_quota = null
|
|
|
|
|
} else {
|
|
|
|
|
row.day_quota = Math.floor(Number(dq))
|
|
|
|
|
}
|
|
|
|
|
if (rt === 'online') {
|
|
|
|
|
const opens = (d.booking_opens_at || '').trim()
|
|
|
|
|
row.booking_opens_at = opens || null
|
|
|
|
|
@ -2218,7 +2257,7 @@ async function removeActivity(row: Activity) {
|
|
|
|
|
data-index="booking_deadline_at"
|
|
|
|
|
:width="184"
|
|
|
|
|
/>
|
|
|
|
|
<a-table-column title="可预约人数" data-index="day_quota" :width="100" />
|
|
|
|
|
<a-table-column :title="auditSessionQuotaColumnTitle(auditActivityRecord?.reservation_type)" data-index="day_quota" :width="108" />
|
|
|
|
|
<a-table-column title="说明" :width="220" :ellipsis="true" :tooltip="true">
|
|
|
|
|
<template #cell="{ record }">
|
|
|
|
|
<span>{{ ((record as BookingDayRow).quota_note || '').trim() || '—' }}</span>
|
|
|
|
|
@ -2591,7 +2630,7 @@ async function removeActivity(row: Activity) {
|
|
|
|
|
{{ activityBookingStepIntro }}
|
|
|
|
|
</a-typography-text>
|
|
|
|
|
<a-typography-text v-else type="warning" style="display: block; margin-bottom: 12px">
|
|
|
|
|
活动已结束:本次保存将不更新场次与可预约人数(仅活动基本信息)。
|
|
|
|
|
活动已结束:本次保存将不更新场次与场次人数信息(仅活动基本信息)。
|
|
|
|
|
</a-typography-text>
|
|
|
|
|
<a-form v-if="showBookingAudienceFields" layout="vertical">
|
|
|
|
|
<a-row :gutter="16">
|
|
|
|
|
@ -2620,7 +2659,7 @@ async function removeActivity(row: Activity) {
|
|
|
|
|
</a-col>
|
|
|
|
|
</a-row>
|
|
|
|
|
</a-form>
|
|
|
|
|
<div style="margin-bottom: 8px; color: var(--color-text-3); font-size: 12px">
|
|
|
|
|
<div v-if="sessionRulesHint" style="margin-bottom: 8px; color: var(--color-text-3); font-size: 12px">
|
|
|
|
|
{{ sessionRulesHint }}
|
|
|
|
|
</div>
|
|
|
|
|
<a-button
|
|
|
|
|
@ -2703,12 +2742,16 @@ async function removeActivity(row: Activity) {
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
</a-table-column>
|
|
|
|
|
<a-table-column title="可预约人数" :width="100">
|
|
|
|
|
<a-table-column :title="sessionQuotaColumnTitle" :width="108">
|
|
|
|
|
<template #cell="{ rowIndex }">
|
|
|
|
|
<a-input-number
|
|
|
|
|
v-model="bookingForm.days[rowIndex].day_quota"
|
|
|
|
|
:min="Math.max(1, Number(bookingForm.days[rowIndex].booked_count) || 0)"
|
|
|
|
|
placeholder="必填"
|
|
|
|
|
:min="
|
|
|
|
|
showSessionBookingWindowColumns
|
|
|
|
|
? Math.max(1, Number(bookingForm.days[rowIndex].booked_count) || 0)
|
|
|
|
|
: Math.max(0, Number(bookingForm.days[rowIndex].booked_count) || 0)
|
|
|
|
|
"
|
|
|
|
|
:placeholder="showSessionBookingWindowColumns ? '必填' : '选填'"
|
|
|
|
|
allow-clear
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
:disabled="!canSaveSessionsWithActivity"
|
|
|
|
|
@ -2723,7 +2766,11 @@ async function removeActivity(row: Activity) {
|
|
|
|
|
<template #cell="{ rowIndex }">
|
|
|
|
|
<a-input
|
|
|
|
|
v-model="bookingForm.days[rowIndex].quota_note"
|
|
|
|
|
placeholder="可与可预约人数配合说明"
|
|
|
|
|
:placeholder="
|
|
|
|
|
showSessionBookingWindowColumns
|
|
|
|
|
? '可与可预约人数配合说明'
|
|
|
|
|
: '可与参加人数配合说明'
|
|
|
|
|
"
|
|
|
|
|
allow-clear
|
|
|
|
|
:disabled="!canSaveSessionsWithActivity"
|
|
|
|
|
/>
|
|
|
|
|
|