gaoluyang
9 天以前 4f894ae17a8c2d9c8f5d1a7161415a728c5170b5
src/views/basicData/mdm/modules/form.vue
@@ -1,22 +1,32 @@
<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: {
@@ -51,31 +61,102 @@
  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>