From 915aa93d7a0cc8e5cc3eacfe05a81025780fccf5 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 23 一月 2026 16:37:13 +0800
Subject: [PATCH] fix: 完成工单上传附件功能

---
 src/views/productionManagement/productStructure/Detail/index.vue |   10 +-
 src/views/productionManagement/workOrder/components/filesDia.vue |  202 ++++++++++++++++++++++++++++++++++++++++
 src/views/productionManagement/workOrder/index.vue               |   13 ++
 src/api/productionManagement/productWorkOrderFile.js             |   29 +++++
 4 files changed, 249 insertions(+), 5 deletions(-)

diff --git a/src/api/productionManagement/productWorkOrderFile.js b/src/api/productionManagement/productWorkOrderFile.js
new file mode 100644
index 0000000..9fc04a9
--- /dev/null
+++ b/src/api/productionManagement/productWorkOrderFile.js
@@ -0,0 +1,29 @@
+import request from "@/utils/request";
+
+// 鏌ヨ宸ュ崟闄勪欢鍒楄〃
+export function productWorkOrderFileListPage(query) {
+  return request({
+    url: "/productWorkOrderFile/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板宸ュ崟闄勪欢
+export function productWorkOrderFileAdd(data) {
+  return request({
+    url: "/productWorkOrderFile/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎宸ュ崟闄勪欢
+export function productWorkOrderFileDel(data) {
+  return request({
+    url: "/productWorkOrderFile/del",
+    method: "delete",
+    data,
+  });
+}
+
diff --git a/src/views/productionManagement/productStructure/Detail/index.vue b/src/views/productionManagement/productStructure/Detail/index.vue
index c56b247..3a76e48 100644
--- a/src/views/productionManagement/productStructure/Detail/index.vue
+++ b/src/views/productionManagement/productStructure/Detail/index.vue
@@ -342,11 +342,11 @@
         isValid = false;
         return;
       }
-      if (!item.unit) {
-        ElMessage.error("璇疯緭鍏ュ崟浣�");
-        isValid = false;
-        return;
-      }
+      // if (!item.unit) {
+      //   ElMessage.error("璇疯緭鍏ュ崟浣�");
+      //   isValid = false;
+      //   return;
+      // }
 
       // 閫掑綊鏍¢獙瀛愰」
       if (item.children && item.children.length > 0) {
diff --git a/src/views/productionManagement/workOrder/components/filesDia.vue b/src/views/productionManagement/workOrder/components/filesDia.vue
new file mode 100644
index 0000000..ca6d7a9
--- /dev/null
+++ b/src/views/productionManagement/workOrder/components/filesDia.vue
@@ -0,0 +1,202 @@
+<template>
+  <div>
+    <el-dialog v-model="dialogVisible" title="宸ュ崟闄勪欢" width="50%" @close="closeDia">
+      <div style="margin-bottom: 10px; text-align: right">
+        <el-upload
+          v-model:file-list="fileList"
+          class="upload-demo"
+          :action="uploadUrl"
+          :on-success="handleUploadSuccess"
+          :on-error="handleUploadError"
+          :before-upload="beforeUpload"
+          name="file"
+          :show-file-list="false"
+          :headers="headers"
+          accept="image/*"
+          style="display: inline; margin-right: 10px"
+        >
+          <el-button type="primary">涓婁紶鍥剧墖</el-button>
+        </el-upload>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+
+      <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :total="page.total"
+        :tableLoading="tableLoading"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        @pagination="paginationSearch"
+        height="500"
+      />
+
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <filePreview ref="filePreviewRef" />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, getCurrentInstance } from "vue";
+import { ElMessageBox } from "element-plus";
+import { getToken } from "@/utils/auth.js";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import filePreview from "@/components/filePreview/index.vue";
+import {
+  productWorkOrderFileAdd,
+  productWorkOrderFileDel,
+  productWorkOrderFileListPage,
+} from "@/api/productionManagement/productWorkOrderFile.js";
+
+const { proxy } = getCurrentInstance();
+const emit = defineEmits(["close"]);
+
+const dialogVisible = ref(false);
+const currentWorkOrderId = ref("");
+const selectedRows = ref([]);
+const filePreviewRef = ref();
+
+const tableColumn = ref([
+  {
+    label: "鏂囦欢鍚嶇О",
+    prop: "name",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    width: 120,
+    operation: [
+      {
+        name: "涓嬭浇",
+        type: "text",
+        clickFun: row => {
+          proxy.$download.name(row.url);
+        },
+      },
+      {
+        name: "棰勮",
+        type: "text",
+        clickFun: row => {
+          filePreviewRef.value?.open(row.url);
+        },
+      },
+    ],
+  },
+]);
+
+const page = reactive({
+  current: 1,
+  size: 100,
+  total: 0,
+});
+const tableData = ref([]);
+const fileList = ref([]);
+const tableLoading = ref(false);
+const headers = ref({
+  Authorization: "Bearer " + getToken(),
+});
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload");
+
+const beforeUpload = file => {
+  const isImage = file?.type?.startsWith("image/");
+  if (!isImage) {
+    proxy.$modal.msgError("鍙兘涓婁紶鍥剧墖鏂囦欢");
+  }
+  return isImage;
+};
+
+const openDialog = row => {
+  dialogVisible.value = true;
+  currentWorkOrderId.value = row.id;
+  page.current = 1;
+  getList();
+};
+
+const closeDia = () => {
+  dialogVisible.value = false;
+  emit("close");
+};
+
+const paginationSearch = obj => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  productWorkOrderFileListPage({
+    workOrderId: currentWorkOrderId.value,
+    current: page.current,
+    size: page.size,
+  })
+    .then(res => {
+      tableData.value = res.data.records || [];
+      page.total = res.data.total || 0;
+    })
+    .finally(() => {
+      tableLoading.value = false;
+    });
+};
+
+const handleSelectionChange = selection => {
+  selectedRows.value = selection;
+};
+
+function handleUploadSuccess(res) {
+  if (res.code == 200) {
+    const fileRow = {
+      name: res.data.originalName,
+      url: res.data.tempPath,
+      workOrderId: currentWorkOrderId.value,
+    };
+    productWorkOrderFileAdd(fileRow).then(() => {
+      proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+      getList();
+    });
+  } else {
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  }
+}
+
+function handleUploadError() {
+  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+}
+
+const handleDelete = () => {
+  if (selectedRows.value.length === 0) {
+    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+    return;
+  }
+  const ids = selectedRows.value.map(item => item.id);
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      productWorkOrderFileDel(ids).then(() => {
+        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        getList();
+      });
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped></style>
+
diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
index de91893..3ca6206 100644
--- a/src/views/productionManagement/workOrder/index.vue
+++ b/src/views/productionManagement/workOrder/index.vue
@@ -209,6 +209,7 @@
         </span>
       </template>
     </el-dialog>
+    <FilesDia ref="workOrderFilesRef" />
   </div>
 </template>
 
@@ -224,6 +225,7 @@
   import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js";
   import QRCode from "qrcode";
   import { getCurrentInstance, reactive, toRefs } from "vue";
+  import FilesDia from "./components/filesDia.vue";
   const { proxy } = getCurrentInstance();
 
   const tableColumn = ref([
@@ -311,6 +313,12 @@
           },
         },
         {
+          name: "闄勪欢",
+          clickFun: row => {
+            openWorkOrderFiles(row);
+          },
+        },
+        {
           name: "鎶ュ伐",
           clickFun: row => {
             showReportDialog(row);
@@ -330,6 +338,7 @@
   const transferCardQrUrl = ref("");
   const transferCardRowData = ref(null);
   const reportDialogVisible = ref(false);
+  const workOrderFilesRef = ref(null);
   const userOptions = ref([]);
   const reportForm = reactive({
     planQuantity: 0,
@@ -450,6 +459,10 @@
     reportDialogVisible.value = true;
   };
 
+  const openWorkOrderFiles = row => {
+    workOrderFilesRef.value?.openDialog(row);
+  };
+
   const handleReport = () => {
     if (reportForm.planQuantity <= 0) {
       ElMessageBox.alert("寰呯敓浜ф暟閲忎负0锛屾棤娉曟姤宸�", "鎻愮ず", {

--
Gitblit v1.9.3