|
|
@@ -229,6 +229,15 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
</div>
|
|
|
+ <el-divider v-if="attachmentGroups.length" content-position="center">附件资料</el-divider>
|
|
|
+ <el-form-item v-for="group in attachmentGroups" :key="group.type" :label="group.label">
|
|
|
+ <UploadFile
|
|
|
+ v-model="attachmentFiles[group.type]"
|
|
|
+ :file-type="['pdf', 'png', 'jpg', 'jpeg']"
|
|
|
+ :return-object="true"
|
|
|
+ :limit="10"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
<el-button type="primary" :loading="formLoading" @click="submitForm">确定</el-button>
|
|
|
@@ -268,6 +277,7 @@ const total = ref(0)
|
|
|
const deptList = ref<Tree[]>([])
|
|
|
const formRef = ref()
|
|
|
const queryFormRef = ref()
|
|
|
+const attachmentFiles = reactive<Record<string, any[]>>({})
|
|
|
|
|
|
const queryParams = reactive({
|
|
|
pageNo: 1,
|
|
|
@@ -307,6 +317,11 @@ interface ExtendAttribute {
|
|
|
dropdownList?: Array<{ name: string; value: string | number }>
|
|
|
}
|
|
|
|
|
|
+interface AttachmentGroup {
|
|
|
+ type: string
|
|
|
+ label: string
|
|
|
+}
|
|
|
+
|
|
|
const getSubTypeDict = (achievementType: string | number) => {
|
|
|
const dictMap: Record<string, string> = {
|
|
|
'1': DICT_TYPE.PAPER_SUB_TYPE,
|
|
|
@@ -323,6 +338,22 @@ const subTypeOptions = computed(() =>
|
|
|
: []
|
|
|
)
|
|
|
|
|
|
+const attachmentGroups = computed<AttachmentGroup[]>(() => {
|
|
|
+ const type = String(formData.value.achievementType)
|
|
|
+ if (type === '1') return [{ type: 'PAPER', label: '论文附件' }]
|
|
|
+ if (type === '2') {
|
|
|
+ return [
|
|
|
+ { type: 'AUTH_NOTICE', label: '授权通知书' },
|
|
|
+ { type: 'CERTIFICATE', label: '证书' },
|
|
|
+ { type: 'REGISTER_COPY', label: '登记副本' },
|
|
|
+ { type: 'OTHER_MATERIAL', label: '其他' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ if (type === '3') return [{ type: 'COPYRIGHT', label: '软著附件' }]
|
|
|
+ if (type === '4') return [{ type: 'HONOR_CERTIFICATE', label: '荣誉证书附件' }]
|
|
|
+ return []
|
|
|
+})
|
|
|
+
|
|
|
const getDeptName = (id?: number) => {
|
|
|
if (!id) return '-'
|
|
|
const find = (items: Tree[]): string | undefined => {
|
|
|
@@ -369,11 +400,56 @@ const resetQuery = () => {
|
|
|
const handleAchievementTypeChange = () => {
|
|
|
formData.value.subType = ''
|
|
|
formData.value.extAttributes = []
|
|
|
+ clearAttachmentFiles()
|
|
|
if (formData.value.achievementType) {
|
|
|
loadExtendAttributes(formData.value.achievementType)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const clearAttachmentFiles = () => {
|
|
|
+ Object.keys(attachmentFiles).forEach((type) => delete attachmentFiles[type])
|
|
|
+}
|
|
|
+
|
|
|
+const normalizeAttachments = (attachments: unknown): any[] => {
|
|
|
+ if (!Array.isArray(attachments)) return []
|
|
|
+ return attachments.filter((attachment) => attachment && typeof attachment === 'object')
|
|
|
+}
|
|
|
+
|
|
|
+const prepareAttachmentFiles = (attachments: unknown) => {
|
|
|
+ clearAttachmentFiles()
|
|
|
+ normalizeAttachments(attachments).forEach((attachment) => {
|
|
|
+ const type = attachment.type
|
|
|
+ if (!type) return
|
|
|
+ if (!attachmentFiles[type]) attachmentFiles[type] = []
|
|
|
+ attachmentFiles[type].push({
|
|
|
+ ...attachment,
|
|
|
+ name: attachment.filename || attachment.fileName || attachment.filePath,
|
|
|
+ fileName: attachment.filename || attachment.fileName || attachment.filePath,
|
|
|
+ url: attachment.filePath,
|
|
|
+ attachment: {
|
|
|
+ ...attachment,
|
|
|
+ fileName: attachment.filename || attachment.fileName,
|
|
|
+ filePath: attachment.filePath
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const getAttachments = () =>
|
|
|
+ attachmentGroups.value.flatMap((group) =>
|
|
|
+ (attachmentFiles[group.type] || []).map((file) => {
|
|
|
+ const metadata = file.attachment || file
|
|
|
+ return {
|
|
|
+ category: 'ACHIEVEMENT',
|
|
|
+ type: group.type,
|
|
|
+ filename: metadata.filename || metadata.fileName || file.name || '',
|
|
|
+ fileType: metadata.fileType || file.raw?.type || '',
|
|
|
+ filePath: metadata.filePath || file.url || '',
|
|
|
+ fileSize: metadata.fileSize || file.raw?.size || 0
|
|
|
+ }
|
|
|
+ })
|
|
|
+ )
|
|
|
+
|
|
|
const normalizeExtendAttributes = (data: unknown): ExtendAttribute[] => {
|
|
|
if (Array.isArray(data)) return data
|
|
|
if (data && typeof data === 'object' && Array.isArray((data as any).data)) {
|
|
|
@@ -423,6 +499,7 @@ const openForm = async (type: 'create' | 'update', id?: number) => {
|
|
|
formType.value = type
|
|
|
dialogTitle.value = type === 'create' ? '新增研究成果' : '编辑研究成果'
|
|
|
formData.value = createDefaultForm()
|
|
|
+ clearAttachmentFiles()
|
|
|
if (type === 'update') {
|
|
|
formLoading.value = true
|
|
|
try {
|
|
|
@@ -432,6 +509,7 @@ const openForm = async (type: 'create' | 'update', id?: number) => {
|
|
|
...data,
|
|
|
extAttributes: prepareExtendAttributes(normalizeExtendAttributes(data.extAttributes))
|
|
|
}
|
|
|
+ prepareAttachmentFiles(data.attachments)
|
|
|
} finally {
|
|
|
formLoading.value = false
|
|
|
}
|
|
|
@@ -446,6 +524,7 @@ const submitForm = async () => {
|
|
|
try {
|
|
|
const payload = {
|
|
|
...formData.value,
|
|
|
+ attachments: getAttachments(),
|
|
|
extAttributes: formData.value.extAttributes.map(({ dateValue, ...attribute }) => ({
|
|
|
...attribute,
|
|
|
actualValue:
|