diff --git a/src/views/review/meeting/MeetingEdit.vue b/src/views/review/meeting/MeetingEdit.vue index 9329c9f0a..239c28865 100644 --- a/src/views/review/meeting/MeetingEdit.vue +++ b/src/views/review/meeting/MeetingEdit.vue @@ -187,10 +187,10 @@ v-if="!isView" type="button" class="btn-primary" - :disabled="formLoading" + :disabled="formLoading || isSubmitting" @click="submitForm" > - {{ formLoading ? '提交中...' : '提交' }} + {{ formLoading || isSubmitting ? '提交中...' : '提交' }} @@ -239,8 +239,8 @@ @@ -291,6 +291,7 @@ const formLoading = ref(false) const expertOptions = ref([]) const isProjectsModified = ref(false) const meetingLocationOptions = ['东5楼326', '南6楼203', '南6楼207'] +const isSubmitting = ref(false) // 防止重复提交 // 上传会议附件弹窗 const agendaDialogVisible = ref(false) @@ -619,7 +620,7 @@ const buildAgendaGenerateData = (): ReviewMeetingAgendaGenerateReqVO | undefined } const submitForm = async () => { - if (formLoading.value) return + if (formLoading.value || isSubmitting.value) return const valid = await formRef.value?.validate().catch(() => false) if (!valid) return if (formData.meetingTimeRange?.length === 2) { @@ -628,6 +629,7 @@ const submitForm = async () => { } // 编辑模式且有议程附件:直接保存 if (isEdit.value && formData.agendaAttachmentUrl) { + isSubmitting.value = true formLoading.value = true try { const projects = buildScheduledProjects() @@ -658,6 +660,7 @@ const submitForm = async () => { router.push({ name: 'ReviewMeeting' }) } finally { formLoading.value = false + isSubmitting.value = false } } else { // 新建模式或编辑模式下议程附件为空:弹出上传议程附件弹窗 @@ -711,10 +714,12 @@ const handleDialogGenerateAgenda = async () => { // 弹窗确定按钮 - 真正保存草稿 const handleDialogConfirm = async () => { + if (agendaDialogLoading.value || isSubmitting.value) return if (!formData.agendaAttachmentUrl) { ElMessage.warning('请上传或生成议程附件') return } + isSubmitting.value = true agendaDialogLoading.value = true try { const projects = buildScheduledProjects() @@ -736,6 +741,7 @@ const handleDialogConfirm = async () => { router.push({ name: 'ReviewMeeting' }) } finally { agendaDialogLoading.value = false + isSubmitting.value = false } } @@ -1031,38 +1037,87 @@ const handleBack = () => { .attachment-cards { display: flex; gap: 12px; + flex-wrap: wrap; } .attachment-card { - flex: 1; - background-color: #fff; - border: 1px solid #e1e7f0; - border-radius: 4px; - overflow: hidden; + background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); + border: 1px solid #e8eaef; + border-radius: 8px; + padding: 12px 14px; + min-width: 320px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); + transition: all 0.2s ease; +} +.attachment-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + border-color: #d0d4dc; } .attachment-card-header { - padding: 1px 6px; - background-color: #f5f7fa; - border-bottom: 1px solid #e1e7f0; + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 8px; } .attachment-card-title { font-size: 12px; font-weight: 600; - color: #333; + color: #6b7280; + text-transform: uppercase; + letter-spacing: 0.3px; } .attachment-card-body { - padding: 2px 6px; + display: flex; + flex-direction: column; + gap: 6px; } .attachment-file-info { display: flex; align-items: center; - gap: 4px; + gap: 8px; flex-wrap: wrap; + min-width: 0; +} +.attachment-file-info .el-link { + font-size: 13px; + color: #3b82f6; + font-weight: 500; + word-break: break-all; + flex: 1; + min-width: 100px; +} +.attachment-file-info .el-link:hover { + text-decoration: underline; +} +.attachment-file-info .el-tag { + background-color: #eef2ff; + color: #6366f1; + border-color: #e0e7ff; + font-weight: 500; +} +.attachment-file-info .el-text { + color: #9ca3af; + font-size: 12px; +} +.attachment-file-info .el-button { + color: #ef4444; + font-size: 12px; +} +.attachment-file-info .el-button:hover { + color: #dc2626; } .minutes-ai-line { - margin-top: 2px; display: flex; align-items: center; - gap: 4px; + gap: 6px; flex-wrap: wrap; + padding-top: 4px; + border-top: 1px solid #f0f0f0; +} +.minutes-ai-line .el-tag { + font-weight: 500; +} +.minutes-ai-line .el-text { + color: #9ca3af; + font-size: 11px; }