From f3f855be1fd86d28485fceb02c30b6c6b2853aef Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 04 十一月 2026 18:15:40 +0800
Subject: [PATCH] feat(mes): 质检附件与来源关联界面,新增工单技术文件、废料登记与领料单打印

---
 src/views/basicData/mdm/modules/form.vue |   95 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/src/views/basicData/mdm/modules/form.vue b/src/views/basicData/mdm/modules/form.vue
index 7cf30a7..e96e7f8 100644
--- a/src/views/basicData/mdm/modules/form.vue
+++ b/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: {
@@ -26,7 +36,7 @@
     labelWidth: 110,
   },
   layout: 'horizontal',
-  schema: useFormSchema(),
+  schema: [],
   showDefaultActions: false,
   wrapperClass: 'grid-cols-2',
 });
@@ -51,29 +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锛坒ormApi 宸插垵濮嬪寲锛�
+    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>

--
Gitblit v1.9.3