From dfda6c599ca7dab4e9fa118e17f16dc759405736 Mon Sep 17 00:00:00 2001 From: weizong song Date: Sun, 7 Jun 2026 18:52:19 +0800 Subject: [PATCH] up --- src/styles/apply-form-prototype.css | 44 +++++- src/views/ApplyFormView.vue | 225 +++++++++++++++++++++++++++- 2 files changed, 261 insertions(+), 8 deletions(-) diff --git a/src/styles/apply-form-prototype.css b/src/styles/apply-form-prototype.css index 8eae95c..99f3319 100644 --- a/src/styles/apply-form-prototype.css +++ b/src/styles/apply-form-prototype.css @@ -261,9 +261,21 @@ body.prototype-page #applyForm select.form-select option { } body.prototype-page #applyForm input[type='file'].form-control { - min-height: auto !important; - padding-top: 0.38rem !important; - padding-bottom: 0.38rem !important; + min-height: 2.75rem !important; + padding: 0.42rem !important; + color: #4d5f73 !important; + cursor: pointer; +} + +body.prototype-page #applyForm input[type='file'].form-control::file-selector-button { + min-height: 1.85rem; + margin-right: 0.7rem; + border: 0; + border-radius: 6px; + background: #052d62; + color: #fff; + font-weight: 600; + padding: 0.32rem 0.85rem; } body.prototype-page #applyForm .track-custom-toggle.form-select { @@ -298,6 +310,32 @@ body.prototype-page #applyForm .track-custom-toggle.form-select::after { vertical-align: middle; } +body.prototype-page #applyForm .track-custom-menu { + max-height: min(56vh, 30rem); + overflow-y: auto; +} + +@media (max-width: 575.98px) { + body.prototype-page #applyForm .form-select, + body.prototype-page #applyForm .track-custom-toggle.form-select, + body.prototype-page #applyForm input.form-control:not([type='file']) { + min-height: 2.75rem !important; + font-size: 1rem !important; + } + + body.prototype-page #applyForm input[type='file'].form-control { + min-height: 3rem !important; + font-size: 0.95rem !important; + } + + body.prototype-page #applyForm input[type='file'].form-control::file-selector-button { + display: block; + width: 100%; + margin: 0 0 0.4rem; + min-height: 2.35rem; + } +} + body.prototype-page #applyForm.was-validated .form-control:valid, body.prototype-page #applyForm .form-control.is-valid, body.prototype-page #applyForm.was-validated textarea.form-control:valid, diff --git a/src/views/ApplyFormView.vue b/src/views/ApplyFormView.vue index 95ed55c..52b01cf 100644 --- a/src/views/ApplyFormView.vue +++ b/src/views/ApplyFormView.vue @@ -211,8 +211,31 @@ function ensureFormKeys(fields: SignupFormSchemaField[]) { const STORAGE_KEY = computed(() => `jscc_signup_form_draft_v2_${slug.value || 'x'}`) const applicationStatus = ref<'draft' | 'submitted'>('draft') +const submittedAt = ref('') /** 与后端 participant_may_edit 对齐:有评审记录后为 false,表单整表禁用 */ const participantMayEdit = ref(true) +const isSubmitted = computed(() => applicationStatus.value === 'submitted') +const submittedAtText = computed(() => formatSubmittedAt(submittedAt.value)) +const applicationStatusTitle = computed(() => { + if (isSubmitted.value && participantMayEdit.value) return '报名已提交,可继续修改' + if (isSubmitted.value) return '报名已提交,已锁定' + if (!participantMayEdit.value) return '报名未提交,当前不可编辑' + return '报名信息未提交' +}) +const applicationStatusBody = computed(() => { + if (isSubmitted.value && participantMayEdit.value) { + const time = submittedAtText.value ? `上次提交时间:${submittedAtText.value}。` : '' + return `${time}在报名截止且没有任一评委提交评分前,你仍可修改资料、增删附件,并点击“更新报名”覆盖提交。评审开始后报名会自动锁定,请保持联系方式畅通。` + } + if (isSubmitted.value) { + const time = submittedAtText.value ? `提交时间:${submittedAtText.value}。` : '' + return `${time}报名已因截止或评审记录产生而锁定,不能再修改资料、增删附件或重复提交。后续请等待赛事组委会通知;如需更正请联系组委会。` + } + if (!participantMayEdit.value) { + return '当前报名窗口已关闭或报名已被锁定,无法新建、保存或提交报名。如认为状态异常,请联系赛事组委会。' + } + return '请完整填写报名信息、上传商业计划书并签署承诺书;点击“保存”只暂存草稿,点击“提交报名”后才进入已提交状态。' +}) const trackInvalid = ref(false) const trackHiddenSelect = ref(null) @@ -406,6 +429,25 @@ function fileItemSuggestedDownloadName(item: FileItem): string | undefined { return n || undefined } +function formatSubmittedAt(value: string): string { + if (!value) return '' + const d = new Date(value) + if (Number.isNaN(d.getTime())) return '' + const pad = (n: number) => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}` +} + +function uploadedFileCountText(items: FileItem[]): string { + if (items.length === 0) return '尚未选择文件' + const uploaded = items.filter((item) => item.fromServer).length + if (uploaded === items.length) return `已上传 ${items.length} 个文件` + return `已选择 ${items.length} 个文件,正在上传 ${items.length - uploaded} 个` +} + +function selectPlaceholder(field: SignupFormSchemaField): string { + return `请选择${field.label}` +} + function formatApiErrSafe(data: Record) { const msg = (data.message as string) || '' const errObj = data.errors as Record | undefined @@ -1051,9 +1093,11 @@ function applyServerPayload(d: { intro?: string promise_signed_at?: string | null promise_signature?: string | null + submitted_at?: string | null files?: { id: number; kind: string; original_name: string; size: number; url: string }[] }) { applicationStatus.value = (d.status as 'draft' | 'submitted') || 'draft' + submittedAt.value = typeof d.submitted_at === 'string' ? d.submitted_at : '' participantMayEdit.value = d.participant_may_edit !== false formModel.player_name = d.player_name || '' formModel.school = d.school || '' @@ -1294,6 +1338,28 @@ onMounted(() => {
+
+ +
+ {{ applicationStatusTitle }} + {{ applicationStatusBody }} +
+
{ > {{ trackMainText }} - {{ trackNoteText }} + {{ trackNoteText }}