132 lines
3.4 KiB
Vue
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>
|