精彩回顾

main
lion 2 weeks ago
parent 4d76aca429
commit 779ed4a979

@ -118,6 +118,13 @@ function applyOptionsText(element: FormSchemaEditorItem, raw: string) {
placeholder="如 project_name"
/>
</el-col>
<el-col :span="24">
<div class="field-label">标题补充</div>
<el-input
v-model="element.titleSupplement"
placeholder="可选,展示在标题后;必填项时显示在 * 后面"
/>
</el-col>
<el-col :xs="24" :sm="12">
<div class="field-label">占位提示</div>
<el-input v-model="element.placeholder" placeholder="可选" />

@ -6,6 +6,8 @@ export interface SignupFormSchemaField {
key: string
type: string
label: string
/** 标题后、`*`若有后面的补充文案与管理端「标题补充」一致JSON`title_supplement` */
title_supplement?: string
required: boolean
placeholder?: string
help?: string
@ -156,6 +158,9 @@ export function normalizeSignupSchema(raw: unknown): SignupFormSchemaField[] {
const helpRaw = o.help
const help =
helpRaw != null && String(helpRaw).trim() !== '' ? String(helpRaw).trim() : undefined
const tsRaw = o.title_supplement
const title_supplement =
tsRaw != null && String(tsRaw).trim() !== '' ? String(tsRaw).trim() : undefined
let required_when: { field: string; values: string[] } | undefined
const rw = o.required_when
if (rw != null && typeof rw === 'object' && !Array.isArray(rw)) {
@ -188,7 +193,7 @@ export function normalizeSignupSchema(raw: unknown): SignupFormSchemaField[] {
}
}
}
out.push({ key, type, label, required, placeholder, help, options, required_when })
out.push({ key, type, label, title_supplement, required, placeholder, help, options, required_when })
}
return out.length ? out : DEFAULT_SIGNUP_FORM_SCHEMA.map((f) => ({ ...f }))
}

@ -9,6 +9,8 @@ export interface FormSchemaEditorItem {
type: string
label: string
required: boolean
/** 选手端展示在标题后;必填时落在 * 之后(入库 title_supplement */
titleSupplement?: string
placeholder?: string
help?: string
/** select 等:{ label, value } */
@ -56,6 +58,7 @@ export function createEmptySchemaItem(
type,
label: purpose === 'review' ? `评分维度 ${index + 1}` : `字段 ${index + 1}`,
required: purpose !== 'review',
titleSupplement: '',
placeholder: '',
help: '',
options: [],
@ -110,6 +113,7 @@ export function schemaJsonToEditorItems(json: unknown, purpose: FormSchemaPurpos
type,
label: String(o.label ?? `字段 ${index + 1}`),
required: Boolean(o.required),
titleSupplement: o.title_supplement != null ? String(o.title_supplement) : '',
placeholder: o.placeholder != null ? String(o.placeholder) : '',
help: o.help != null ? String(o.help) : '',
options: type === 'select' ? normalizeOptions(o.options) : [],
@ -131,6 +135,7 @@ export function editorItemsToSchemaJson(items: FormSchemaEditorItem[], purpose:
}
if (item.placeholder?.trim()) row.placeholder = item.placeholder.trim()
if (item.help?.trim()) row.help = item.help.trim()
if (item.titleSupplement?.trim()) row.title_supplement = item.titleSupplement.trim()
if (item.type === 'select' && item.options?.length) {
row.options = item.options.filter((o) => o.value !== '' || o.label !== '')
}

@ -68,6 +68,11 @@ function participantFieldHelp(help?: string): string {
return t
}
/** 管理端「标题补充」:展示在标题后,必填时位于 * 之后 */
function participantFieldTitleSupplement(field: SignupFormSchemaField): string {
return String(field.title_supplement ?? '').trim()
}
function apiBase() {
return getApiBase()
}
@ -1091,9 +1096,15 @@ onMounted(() => {
>
<template v-for="field in orderedSignupFields" :key="field.type === 'file' ? 'f-' + field.key : field.key">
<div v-if="field.key === 'track'" class="col-md-4">
<label class="form-label" id="trackFieldLabel"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label" id="trackFieldLabel">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<div class="track-custom-select w-100">
<select
id="track"
@ -1154,9 +1165,15 @@ onMounted(() => {
</div>
<div v-else-if="field.type === 'file' && field.key === 'plan'" class="col-12">
<label class="form-label"
>{{ field.label }} <span v-if="field.required" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<input
ref="planFileInput"
type="file"
@ -1211,7 +1228,15 @@ onMounted(() => {
</div>
<div v-else-if="field.type === 'file' && field.key === 'supporting'" class="col-12">
<label class="form-label">{{ field.label }}</label>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<input
ref="supportingFileInput"
type="file"
@ -1268,9 +1293,15 @@ onMounted(() => {
</div>
<div v-else-if="field.type === 'select' && !isCitySelectField(field)" :class="fieldColClass(field)">
<label class="form-label"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<select
v-model="formModel[field.key]"
class="form-select editable"
@ -1290,9 +1321,15 @@ onMounted(() => {
</div>
<div v-else-if="isCitySelectField(field)" :class="fieldColClass(field)">
<label class="form-label"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<select
v-model="formModel.location_city"
class="form-select editable"
@ -1315,9 +1352,15 @@ onMounted(() => {
v-else-if="field.type === 'checkbox' && field.key === 'commitment_accepted'"
:class="fieldColClass(field)"
>
<label class="form-label"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<p class="small text-secondary mb-2">
请点击按钮打开承诺书全文阅读后在文末手写签名并点击确认签署
</p>
@ -1354,7 +1397,13 @@ onMounted(() => {
:disabled="formDisabled"
/>
<label class="form-check-label" :for="'signup-field-' + field.key">
{{ field.label }}<span v-if="effectiveRequired(field)" class="text-danger"> *</span>
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger ms-1">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<div class="invalid-feedback">请勾选此项以继续</div>
</div>
@ -1366,9 +1415,15 @@ onMounted(() => {
</div>
<div v-else-if="field.type === 'textarea'" :class="fieldColClass(field)">
<label class="form-label"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<textarea
v-model="formModel[field.key]"
class="form-control editable"
@ -1399,9 +1454,15 @@ onMounted(() => {
</div>
<div v-else :class="fieldColClass(field)">
<label class="form-label"
>{{ field.label }} <span v-if="effectiveRequired(field)" class="text-danger">*</span></label
>
<label class="form-label">
{{ field.label }}
<span v-if="effectiveRequired(field)" class="text-danger">*</span>
<span
v-if="participantFieldTitleSupplement(field)"
class="signup-field-title-supplement ms-1 fw-normal text-secondary"
>{{ participantFieldTitleSupplement(field) }}</span
>
</label>
<input
v-model="formModel[field.key]"
:type="

Loading…
Cancel
Save