Files
shanxia2.0/web-admin/src/views/crm/contract/components/UploadDialog.vue
T
2026-06-06 19:44:18 +08:00

132 lines
3.4 KiB
Vue

<template>
<el-dialog
v-model="dialogVisible"
title="上传合同扫描件"
width="900px"
align-center
append-to-body
destroy-on-close
class="dialog-form-layout upload-scan-dialog"
modal-class="order-module-dialog-mask"
:close-on-click-modal="false"
>
<ContractAttachmentPanel
v-model="attachmentList"
:biz-type="CRM_UPLOAD_BIZ_TYPE.CONTRACT_ATTACHMENT"
hint="支持上传图片、PDF、Word文档等,最多10个文件"
/>
<template #footer>
<div class="upload-dialog-actions">
<el-button @click="handleClose">
<el-icon><Close /></el-icon>关闭
</el-button>
<el-button type="primary" :loading="saveLoading" @click="handleSaveAndClose">
<el-icon><Check /></el-icon>保存并关闭
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="UploadDialog">
import { ref } from 'vue'
import { Close, Check } from '@element-plus/icons-vue'
import ContractAttachmentPanel from './ContractAttachmentPanel.vue'
import { uploadAttachments, getContract } from '@/api/crm/contract'
import { $modal } from '@/utils/modal'
import {
buildUploadFileListFromField,
mapContractAttachmentsPayload,
type ContractAttachmentItem
} from '@/utils/crm-attachment'
import { CRM_UPLOAD_BIZ_TYPE } from '@/utils/crm-upload'
const emit = defineEmits(['success'])
const dialogVisible = ref(false)
const contractId = ref<number>()
const attachmentList = ref<ContractAttachmentItem[]>([])
const saveLoading = ref(false)
const open = async (id: number) => {
contractId.value = id
dialogVisible.value = true
attachmentList.value = []
await loadExistingAttachments()
}
const loadExistingAttachments = async () => {
if (!contractId.value) return
try {
const res = await getContract(contractId.value)
const contract = res.data
if (!contract?.attachmentFiles) return
attachmentList.value = buildUploadFileListFromField(
contract.attachmentFiles
) as ContractAttachmentItem[]
} catch (error) {
console.error('[附件回显] 加载附件数据失败:', error)
}
}
const validateAttachments = () => {
if (attachmentList.value.some((file) => file.status === 'uploading')) {
$modal.msgWarning('仍有附件正在上传,请稍候')
return false
}
const unclassified = attachmentList.value.filter(
(file) => file.status === 'success' && file.ossId && !file.category
)
if (unclassified.length > 0) {
$modal.msgWarning('请为所有附件选择分类')
return false
}
return true
}
const handleSaveAndClose = async () => {
if (!contractId.value) return
if (!validateAttachments()) return
saveLoading.value = true
try {
await uploadAttachments({
id: contractId.value,
attachments: mapContractAttachmentsPayload(attachmentList.value)
})
$modal.msgSuccess('保存成功')
emit('success')
handleClose()
} catch (error) {
console.error('保存附件失败:', error)
$modal.msgError('保存附件失败')
} finally {
saveLoading.value = false
}
}
const handleClose = () => {
dialogVisible.value = false
attachmentList.value = []
}
defineExpose({ open })
</script>
<style scoped lang="scss">
.upload-scan-dialog {
:deep(.el-dialog__body) {
padding-top: 12px;
}
}
.upload-dialog-actions {
display: flex;
flex-wrap: wrap;
gap: 4px 16px;
justify-content: flex-end;
width: 100%;
}
</style>