+
{{ sourceMode ? '返回可视化' : '查看源代码' }}
一键清除样式
@@ -75,7 +106,7 @@ watch(
v-model:content="model"
content-type="html"
theme="snow"
- :options="editorOptions"
+ :options="mergedEditorOptions"
/>
@@ -92,9 +123,18 @@ watch(
.rich-editor-field :deep(.ql-container) {
min-height: v-bind(minHeightPx);
+ overflow: visible;
}
.rich-editor-field :deep(.ql-editor) {
min-height: 140px;
}
+
+/* Quill Snow 外链气泡:中文标签(覆盖主题默认 Enter link / Save) */
+.rich-editor-field :deep(.ql-snow .ql-tooltip[data-mode='link']::before) {
+ content: '输入外链';
+}
+.rich-editor-field :deep(.ql-snow .ql-tooltip.ql-editing a.ql-action::after) {
+ content: '保存';
+}
diff --git a/src/views/activities/ActivityList.vue b/src/views/activities/ActivityList.vue
index 2485a02..0c48b6d 100644
--- a/src/views/activities/ActivityList.vue
+++ b/src/views/activities/ActivityList.vue
@@ -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
{
rt === 'online'
? String(d.booking_deadline_at || '').trim()
: String(d.booking_deadline_at || '').trim() || start
+ const dq = d.day_quota
const row: Record = {
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"
/>
-
+
{{ ((record as BookingDayRow).quota_note || '').trim() || '—' }}
@@ -2591,7 +2630,7 @@ async function removeActivity(row: Activity) {
{{ activityBookingStepIntro }}
- 活动已结束:本次保存将不更新场次与可预约人数(仅活动基本信息)。
+ 活动已结束:本次保存将不更新场次与场次人数信息(仅活动基本信息)。
@@ -2620,7 +2659,7 @@ async function removeActivity(row: Activity) {
-
+
{{ sessionRulesHint }}
-
+
diff --git a/src/views/activities/Registrations.vue b/src/views/activities/Registrations.vue
index a6b1a1e..cbcf022 100644
--- a/src/views/activities/Registrations.vue
+++ b/src/views/activities/Registrations.vue
@@ -8,7 +8,7 @@ import { reservationStatusLabel } from '../../utils/reservationStatus'
import { listTableRowIndex } from '../../utils/listTableRowIndex'
import * as XLSX from 'xlsx'
-const REGISTRATIONS_LIST_SCROLL_X = 1960
+const REGISTRATIONS_LIST_SCROLL_X = 2100
type ActivityDayRef = {
id: number
@@ -301,7 +301,6 @@ function onPageChange(p: number) {
查询
- 刷新
@@ -411,8 +410,8 @@ function onPageChange(p: number) {
-
- 输入预约二维码 token 进行核销。场馆管理员仅可核销自己绑定场馆的预约。
-
-
立即核销
@@ -147,8 +135,6 @@ onMounted(loadRows)
查询
- 重置
- 刷新列表
@@ -215,8 +201,8 @@ onMounted(loadRows)