src/views/basicData/mdm/modules/form.vue
@@ -3,12 +3,13 @@
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,
  createTechnicalFile,
  deleteTechnicalFile,
  getItem,
  getTechnicalFileList,
  updateItem,
@@ -25,7 +26,7 @@
const emit = defineEmits(['success']);
const formData = ref<MdmItemApi.Item>();
const technicalFiles = ref<MdmItemApi.TechnicalFile[]>([]);
const technicalUploadValue = ref<number[]>([]);
const technicalUploadValue = ref<number | number[] | string>([]);
const [Form, formApi] = useVbenForm({
  commonConfig: {
@@ -95,20 +96,31 @@
});
async function handleTechnicalFileChange(value: unknown) {
  if (!formData.value?.id || !Array.isArray(value)) {
  if (!formData.value?.id) {
    return;
  }
  const blobId = value.find((item): item is number => typeof item === 'number');
  if (!blobId) {
  // 单文件上传组件返回单个 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('技术文件已保存,历史版本已保留');
    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>
@@ -116,14 +128,14 @@
  <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>
      <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="上传新文件会生成新的版本,历史文件仍可查看"
        :accept="['pdf', 'doc', 'docx', 'xls', 'xlsx', 'dwg', 'png', 'jpg', 'jpeg']"
        help-text="每次上传会追加一份技术文件,原文件继续保留"
        @change="handleTechnicalFileChange"
      />
      <a-table
@@ -133,12 +145,15 @@
        :pagination="false"
        row-key="id"
      >
        <a-table-column key="versionNo" title="版本" data-index="versionNo" />
        <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>