| | |
| | | <script lang="ts" setup> |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from "#/packages/effects/common-ui/src"; |
| | | |
| | | import { message } from "ant-design-vue"; |
| | | import { message, Popconfirm } from "ant-design-vue"; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { createItem, getItem, updateItem } from '#/api/mdm/item'; |
| | | import { |
| | | createItem, |
| | | createTechnicalFile, |
| | | deleteTechnicalFile, |
| | | getItem, |
| | | getTechnicalFileList, |
| | | updateItem, |
| | | } from '#/api/mdm/item'; |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import { FileUpload } from '#/components/upload'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useFormSchema } from '../data'; |
| | | import { useFormSchema, clearUnitListCache, buildCategoryTree } from '../data'; |
| | | import { getItemTypeSimpleList } from '#/api/mes/md/item/type'; |
| | | |
| | | defineOptions({ name: "ItemForm" }); |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<MdmItemApi.Item>(); |
| | | const technicalFiles = ref<MdmItemApi.TechnicalFile[]>([]); |
| | | const technicalUploadValue = ref<number | number[] | string>([]); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | formData.value = undefined; |
| | | technicalFiles.value = []; |
| | | technicalUploadValue.value = []; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<MdmItemApi.Item>(); |
| | | // 清除单位缓存,确保获取最新数据 |
| | | clearUnitListCache(); |
| | | // 加载最新分类数据 |
| | | const categoryRes = await getItemTypeSimpleList(); |
| | | const categoryTreeData = buildCategoryTree(categoryRes || []); |
| | | // 设置 schema(formApi 已初始化) |
| | | formApi.setState({ schema: useFormSchema(formApi) }); |
| | | formApi.setState({ schema: useFormSchema(formApi, categoryTreeData) }); |
| | | if (data?.id) { |
| | | // 编辑模式 |
| | | modalApi.lock(); |
| | | try { |
| | | formData.value = await getItem(data.id); |
| | | // 同步状态映射:详情接口返回 syncedMes,表单字段为 syncMes |
| | | formData.value.syncMes = formData.value.syncedMes ?? true; |
| | | await formApi.setValues(formData.value); |
| | | technicalFiles.value = await getTechnicalFileList(data.id); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | } else { |
| | | // 新增模式 |
| | | formData.value = undefined; |
| | | technicalFiles.value = []; |
| | | technicalUploadValue.value = []; |
| | | await formApi.resetForm(); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | async function handleTechnicalFileChange(value: unknown) { |
| | | if (!formData.value?.id) { |
| | | return; |
| | | } |
| | | // 单文件上传组件返回单个 ID;兼容数组和数字字符串。 |
| | | const rawId = Array.isArray(value) ? value[0] : value; |
| | | const blobId = typeof rawId === 'number' ? rawId : |
| | | typeof rawId === 'string' && /^\d+$/.test(rawId) ? Number(rawId) : 0; |
| | | if (!Number.isSafeInteger(blobId) || blobId <= 0) { |
| | | return; |
| | | } |
| | | try { |
| | | await createTechnicalFile(formData.value.id, blobId); |
| | | technicalFiles.value = await getTechnicalFileList(formData.value.id); |
| | | message.success('技术文件已添加'); |
| | | } finally { |
| | | technicalUploadValue.value = []; |
| | | } |
| | | } |
| | | |
| | | async function handleDeleteTechnicalFile(id: number) { |
| | | const itemId = formData.value?.id; |
| | | if (!itemId) return; |
| | | await deleteTechnicalFile(itemId, id); |
| | | technicalFiles.value = await getTechnicalFileList(itemId); |
| | | message.success('技术文件已移除'); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[1000px]" :title="formData?.id ? $t('ui.actionTitle.edit', ['物料']) : $t('ui.actionTitle.create', ['物料'])"> |
| | | <Form class="mx-4" /> |
| | | <div v-if="formData?.id" class="mx-4 mb-4 rounded border p-4"> |
| | | <div class="mb-3 text-base font-medium">技术文件</div> |
| | | <FileUpload |
| | | v-model:value="technicalUploadValue" |
| | | value-key="id" |
| | | :max-number="1" |
| | | :multiple="false" |
| | | :accept="['pdf', 'doc', 'docx', 'xls', 'xlsx', 'dwg', 'png', 'jpg', 'jpeg']" |
| | | help-text="每次上传会追加一份技术文件,原文件继续保留" |
| | | @change="handleTechnicalFileChange" |
| | | /> |
| | | <a-table |
| | | class="mt-3" |
| | | size="small" |
| | | :data-source="technicalFiles" |
| | | :pagination="false" |
| | | row-key="id" |
| | | > |
| | | <a-table-column key="versionNo" title="上传序号" data-index="versionNo" /> |
| | | <a-table-column key="fileName" title="文件名" data-index="fileName" /> |
| | | <a-table-column key="createTime" title="上传时间" data-index="createTime" /> |
| | | <a-table-column key="action" title="操作"> |
| | | <template #default="{ record }"> |
| | | <a :href="record.downloadURL || record.previewURL" target="_blank">查看文件</a> |
| | | <Popconfirm title="移除该技术文件?已有工单仍保留原文件,新工单将不再带入。" ok-text="移除" cancel-text="取消" @confirm="handleDeleteTechnicalFile(record.id)"> |
| | | <a class="ml-3 text-red-500">删除</a> |
| | | </Popconfirm> |
| | | </template> |
| | | </a-table-column> |
| | | </a-table> |
| | | </div> |
| | | </Modal> |
| | | </template> |