fix(review-meeting): 优化会议附件卡片样式并防止重复提交
- 优化卡片布局为现代风格,支持长文件名完整显示 - 添加 isSubmitting 状态防止快速连续点击导致重复创建会议 - 按钮在提交中禁用并显示"提交中..."文字 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>pull/874/head
parent
b3eaefc511
commit
9b94f733ba
|
|
@ -187,10 +187,10 @@
|
|||
v-if="!isView"
|
||||
type="button"
|
||||
class="btn-primary"
|
||||
:disabled="formLoading"
|
||||
:disabled="formLoading || isSubmitting"
|
||||
@click="submitForm"
|
||||
>
|
||||
{{ formLoading ? '提交中...' : '提交' }}
|
||||
{{ formLoading || isSubmitting ? '提交中...' : '提交' }}
|
||||
</button>
|
||||
<button type="button" class="btn-default" @click="handleBack">返回</button>
|
||||
</div>
|
||||
|
|
@ -239,8 +239,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button type="primary" :disabled="agendaDialogLoading" @click="handleDialogConfirm">
|
||||
确定
|
||||
<el-button type="primary" :disabled="agendaDialogLoading || isSubmitting" @click="handleDialogConfirm">
|
||||
{{ agendaDialogLoading || isSubmitting ? '提交中...' : '确定' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
|
@ -291,6 +291,7 @@ const formLoading = ref(false)
|
|||
const expertOptions = ref<any[]>([])
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue