From 4ccf803bfff08d76653376c99d8cb862a7030157 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 27 三月 2026 16:56:03 +0800
Subject: [PATCH] 军泰伟业 1.已发货数量等于总数量时,状态为已发货。已发货数量小于总数量时,状态建议新增发货中 2.产品清除工艺路线点击确定后,仍然回显绑定的工艺路线 3.新增退货单时,退一部分货后,继续对此退货单进行退货操作,展示数据有误

---
 src/views/productionManagement/productionOrder/New.vue |  745 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 674 insertions(+), 71 deletions(-)

diff --git a/src/views/productionManagement/productionOrder/New.vue b/src/views/productionManagement/productionOrder/New.vue
index c9c478b..2109385 100644
--- a/src/views/productionManagement/productionOrder/New.vue
+++ b/src/views/productionManagement/productionOrder/New.vue
@@ -3,59 +3,87 @@
     <el-dialog
         v-model="isShow"
         title="鏂板鐢熶骇璁㈠崟"
-        width="800"
+        width="1500"
+        :close-on-click-modal="false"
         @close="closeModal"
+        class="production-order-dialog"
     >
-      <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
-        <el-form-item
-            label="浜у搧鍚嶇О"
-            prop="productModelId"
-            :rules="[
-                {
-                required: true,
-                message: '璇烽�夋嫨浜у搧',
-                trigger: 'change',
-              }
-            ]"
-        >
-          <el-button type="primary" @click="showProductSelectDialog = true">
-            {{ formState.productName ? formState.productName : '閫夋嫨浜у搧' }}
-          </el-button>
-        </el-form-item>
-
-        <el-form-item
-            label="瑙勬牸"
-            prop="productModelName"
-        >
-          <el-input v-model="formState.productModelName"  disabled />
-        </el-form-item>
-
-        <el-form-item
-            label="鍗曚綅"
-            prop="unit"
-        >
-          <el-input v-model="formState.unit"  disabled />
-        </el-form-item>
-
-        <el-form-item label="宸ヨ壓璺嚎">
-          <el-select v-model="formState.routeId"
-                     placeholder="璇烽�夋嫨宸ヨ壓璺嚎"
-                     style="width: 100%;"
-                     :loading="bindRouteLoading">
-            <el-option v-for="item in routeOptions"
-                       :key="item.id"
-                       :label="`${item.processRouteCode || ''}`"
-                       :value="item.id" />
-          </el-select>
-        </el-form-item>
-
-        <el-form-item
-            label="闇�姹傛暟閲�"
-            prop="quantity"
-        >
-          <el-input-number v-model="formState.quantity" :step="1" :min="1" style="width: 100%" />
-        </el-form-item>
-      </el-form>
+      <!-- 鍩烘湰淇℃伅 -->
+      <div class="section-card">
+        <div class="section-header">
+          <span class="section-icon">馃搵</span>
+          <span class="section-title-text">鍩烘湰淇℃伅</span>
+        </div>
+        <el-form label-width="100px" :model="formState" label-position="right" ref="formRef" class="compact-form">
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item
+                  label="浜у搧鍚嶇О"
+                  prop="productModelId"
+                  :rules="[{ required: true, message: '璇烽�夋嫨浜у搧', trigger: 'change' }]"
+              >
+                <el-button type="primary" @click="showProductSelectDialog = true" class="select-btn">
+                  {{ formState.productName ? formState.productName : '閫夋嫨浜у搧' }}
+                </el-button>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍥剧焊缂栧彿" prop="model">
+                <el-input v-model="formState.model" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="鍗曚綅" prop="unit">
+                <el-input v-model="formState.unit" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="闇�姹傛暟閲�" prop="quantity">
+                <el-input-number v-model="formState.quantity" :step="1" :min="1" style="width: 100%" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="浜や粯鏃ユ湡" prop="deliveryDate">
+                <el-date-picker
+                    v-model="formState.deliveryDate"
+                    type="date"
+                    placeholder="閫夋嫨浜や粯鏃ユ湡"
+                    style="width: 100%"
+                    format="YYYY-MM-DD"
+                    value-format="YYYY-MM-DD"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鍥剧焊涓婁紶">
+                <el-upload
+                    v-model:file-list="fileList"
+                    :action="upload.url"
+                    :headers="upload.headers"
+                    :data="upload.data"
+                    :on-success="handleDrawingUploadSuccess"
+                    :on-remove="handleDrawingRemove"
+                    :before-upload="handleDrawingBeforeUpload"
+                    :limit="5"
+                    accept=".pdf,.jpg,.jpeg,.png,.dwg"
+                    list-type="picture-card"
+                >
+                  <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
+                  <template #tip>
+                    <div class="el-upload__tip">
+                      鏀寔 pdf銆乯pg銆乯peg銆乸ng銆乨wg 鏍煎紡锛屽ぇ灏忎笉瓒呰繃 10MB
+                    </div>
+                  </template>
+                </el-upload>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
 
       <!-- 浜у搧閫夋嫨寮圭獥 -->
       <ProductSelectDialog
@@ -63,6 +91,174 @@
           @confirm="handleProductSelect"
           single
       />
+
+      <!-- 鐢ㄦ枡浜у搧閫夋嫨寮圭獥 -->
+      <ProductSelectDialog
+          v-model="showMaterialProductDialog"
+          @confirm="handleMaterialProductSelect"
+      />
+
+      <!-- BOM閫夋嫨寮圭獥 -->
+      <el-dialog
+          v-model="showBomDialog"
+          title="閫夋嫨BOM"
+          width="500"
+          append-to-body
+      >
+        <el-table :data="bomList" border size="small" @row-click="handleBomSelect" highlight-current-row style="margin-bottom: 10px;">
+          <el-table-column type="index" label="搴忓彿" width="60" />
+          <el-table-column label="BOM缂栧彿" prop="bomNo" min-width="120" />
+          <el-table-column label="鐗堟湰" prop="version" min-width="80" />
+          <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="100" />
+        </el-table>
+      </el-dialog>
+
+      <!-- 宸ュ簭 -->
+      <div class="section-card">
+        <div class="section-header">
+          <span class="section-icon">馃敡</span>
+          <span class="section-title-text">宸ュ簭</span>
+          <el-button type="primary" size="small" @click="addProductionTask" class="add-btn">
+            <el-icon><Plus /></el-icon> 娣诲姞浠诲姟
+          </el-button>
+        </div>
+        <div class="table-container">
+          <el-table :data="processRouteItems" border size="small" class="compact-table">
+        <el-table-column type="index" label="搴忓彿" width="60" />
+        <el-table-column label="宸ュ簭鍚嶇О" min-width="150">
+          <template #default="{ row }">
+            <el-select 
+              v-model="row.processId" 
+              placeholder="璇烽�夋嫨宸ュ簭" 
+              style="width: 100%"
+              @change="(val) => handleProcessChange(val, row)"
+            >
+              <el-option
+                v-for="item in processRouteItemsOptions"
+                :key="item.id"
+                :label="item.processName"
+                :value="item.processId"
+              />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎶ュ伐鏉冮檺" min-width="180">
+          <template #default="{ row }">
+            <el-select 
+              v-model="row.userPower" 
+              multiple 
+              collapse-tags 
+              collapse-tags-tooltip
+              placeholder="璇烽�夋嫨鎶ュ伐鏉冮檺" 
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in userOptions"
+                :key="item.userId"
+                :label="item.nickName"
+                :value="item.nickName"
+              />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column label="璁″垝鏁�" min-width="100">
+          <template #default="{ row }">
+            <el-input-number v-model="row.planNum" :min="1" size="small" style="width: 100%" />
+          </template>
+        </el-table-column>
+        <el-table-column label="鏄惁璐ㄦ" min-width="100">
+          <template #default="{ row }">
+            <el-switch v-model="row.isQuality" :active-value="true" :inactive-value="false" size="small" />
+          </template>
+        </el-table-column>
+        <el-table-column label="璁″垝寮�濮嬫椂闂�" min-width="180">
+          <template #default="{ row }">
+            <el-date-picker
+                v-model="row.planStartTime"
+                type="date"
+                placeholder="閫夋嫨寮�濮嬫椂闂�"
+                style="width: 100%"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="璁″垝缁撴潫鏃堕棿" min-width="180">
+          <template #default="{ row }">
+            <el-date-picker
+                v-model="row.planEndTime"
+                type="date"
+                placeholder="閫夋嫨缁撴潫鏃堕棿"
+                style="width: 100%"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="80" fixed="right" align="center">
+          <template #default="{ $index }">
+            <el-button type="danger" link size="small" @click="removeProcessRouteItem($index)">
+              <el-icon><Delete /></el-icon>
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div v-if="processRouteItems.length === 0" class="empty-tip">
+        <el-empty description="鏆傛棤宸ュ簭锛岀偣鍑讳笂鏂规寜閽坊鍔�" :image-size="60" />
+      </div>
+        </div>
+      </div>
+
+      <!-- 鐢ㄦ枡娓呭崟 -->
+      <div class="section-card">
+        <div class="section-header">
+          <span class="section-icon">馃摝</span>
+          <span class="section-title-text">鐢ㄦ枡娓呭崟</span>
+          <el-button type="primary" size="small" @click="addMaterialItem" class="add-btn">
+            <el-icon><Plus /></el-icon> 娣诲姞鐢ㄦ枡
+          </el-button>
+        </div>
+        <div class="table-container">
+          <el-table :data="productStructureRecords" border size="small" class="compact-table">
+            <el-table-column type="index" label="搴忓彿" width="50" align="center" />
+            <el-table-column label="鍥剧焊缂栧彿" prop="model" min-width="120" />
+            <el-table-column label="浜у搧鍚嶇О" prop="productName" min-width="120" />
+            <el-table-column label="鍗曚綅浜у嚭闇�瑕佹暟閲�" min-width="140">
+              <template #default="{ row }">
+                <el-input-number 
+                  v-model="row.unitQuantity" 
+                  :min="0" 
+                  :precision="2" 
+                  size="small" 
+                  style="width: 100%" 
+                  @change="(val) => handleUnitQuantityChange(val, row)"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column label="闇�姹傛暟閲�" min-width="120">
+              <template #default="{ row }">
+                <el-input-number v-model="row.demandedQuantity" :min="0" :precision="2" size="small" style="width: 100%" />
+              </template>
+            </el-table-column>
+            <el-table-column label="鍗曚綅" min-width="80">
+              <template #default="{ row }">
+                <el-input v-model="row.unit" placeholder="璇疯緭鍏�" size="small" />
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="80" fixed="right" align="center">
+              <template #default="{ $index }">
+                <el-button type="danger" link size="small" @click="removeProductStructureRecord($index)">
+                  <el-icon><Delete /></el-icon>
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div v-if="productStructureRecords.length === 0" class="empty-tip">
+            <el-empty description="鏆傛棤鐢ㄦ枡娓呭崟锛岀偣鍑讳笂鏂规寜閽坊鍔�" :image-size="60" />
+          </div>
+        </div>
+      </div>
+
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="handleSubmit">纭</el-button>
@@ -74,9 +270,15 @@
 </template>
 
 <script setup>
-import {ref, computed, getCurrentInstance} from "vue";
+import {ref, computed, getCurrentInstance, watch} from "vue";
+import { Plus, Delete, Upload } from '@element-plus/icons-vue';
 import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
-import {addProductOrder, listProcessRoute} from "@/api/productionManagement/productionOrder.js";
+import {addProductOrder} from "@/api/productionManagement/productionOrder.js";
+import {listDeptUserTree} from "@/api/basicData/productProcess.js";
+import {findProcessRouteItemList} from "@/api/productionManagement/processRouteItem.js";
+import {listPage as listProductBom} from "@/api/productionManagement/productBom.js";
+import {listByBomIdIsParent} from "@/api/productionManagement/productStructure.js";
+import { getToken } from "@/utils/auth.js";
 
 const props = defineProps({
   visible: {
@@ -99,9 +301,31 @@
   productModelId: undefined,
   routeId: undefined,
   productName: "",
-  productModelName: "",
+  model: "",
   unit: "",
+  drawingNumber: "",
   quantity: 0,
+  deliveryDate: "",
+  tempFileIds: [],
+  salesLedgerFiles: [],
+});
+
+// 宸ュ簭璺嚎鏄庣粏鍒楄〃
+ const processRouteItems = ref([]);
+ 
+ // 鐗╂枡娓呭崟鍒楄〃
+ const productStructureRecords = ref([]);
+
+// 鐢ㄦ埛鍒楄〃
+const userOptions = ref([]);
+
+// 鏂囦欢鍒楄〃
+const fileList = ref([]);
+
+const upload = reactive({
+  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+  headers: { Authorization: "Bearer " + getToken() },
+  data: { type: 14 },
 });
 
 const isShow = computed({
@@ -114,6 +338,34 @@
 });
 
 const showProductSelectDialog = ref(false);
+const showMaterialProductDialog = ref(false);
+
+// 鑾峰彇鐢ㄦ埛鍒楄〃
+const fetchUserOptions = () => {
+  listDeptUserTree().then(res => {
+    const users = [];
+    const extractUsers = (nodes) => {
+      nodes.forEach(node => {
+        if (node.userList && node.userList.length > 0) {
+          node.userList.forEach(user => {
+            users.push({
+              userId: user.userId,
+              nickName: user.nickName || user.userName
+            });
+          });
+        }
+        if (node.childrenList && node.childrenList.length > 0) {
+          extractUsers(node.childrenList);
+        }
+      });
+    };
+    extractUsers(res.data || []);
+    userOptions.value = users;
+  });
+};
+
+// 缁勪欢鎸傝浇鏃惰幏鍙栨暟鎹�
+fetchUserOptions();
 
 let { proxy } = getCurrentInstance()
 
@@ -124,9 +376,18 @@
     productModelId: undefined,
     routeId: undefined,
     productName: "",
-    productModelName: "",
-    quantity: '',
+    drawingNumber: "",
+    model: "",
+    unit: "",
+    quantity: 0,
+    deliveryDate: "",
+    tempFileIds: [],
+    salesLedgerFiles: [],
   };
+  // 閲嶇疆宸ュ簭璺嚎鏄庣粏鍜岀墿鏂欐竻鍗�
+  processRouteItems.value = [];
+  productStructureRecords.value = [];
+  fileList.value = [];
   isShow.value = false;
 };
 
@@ -136,28 +397,244 @@
     const product = products[0];
     formState.value.productId = product.productId;
     formState.value.productName = product.productName;
-    formState.value.productModelName = product.model;
+    formState.value.drawingNumber = product.drawingNumber;
+    formState.value.model = product.model;
     formState.value.productModelId = product.id;
     formState.value.unit = product.unit;
+    formState.value.routeId = product.routeId;
     showProductSelectDialog.value = false;
-    fetchRouteOptions( product.id);
+    
+    // 1. 閫氳繃浜у搧鑷甫鐨剅outeId鑾峰彇宸ュ簭鍒楄〃
+    if (product.routeId) {
+      fetchProcessRouteItems(product.routeId);
+    }
+    
+    // 2. 閫氳繃浜у搧id鏌ヨBOM鍒楄〃
+    fetchBomList(product.id);
+    
     // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
     proxy.$refs["formRef"]?.validateField('productModelId');
   }
 };
 
-const routeOptions = ref([]);
-const bindRouteLoading = ref(false);
-const fetchRouteOptions = (productModelId) => {
-  formState.value.routeId = undefined;
-  routeOptions.value = []
-  bindRouteLoading.value = true;
-  listProcessRoute({ productModelId: productModelId }).then(res => {
-    routeOptions.value = res.data || [];
-  }).finally(() => {
-    bindRouteLoading.value = false;
-  })
-}
+// 宸ヨ壓璺嚎宸ュ簭鍒楄〃
+const processRouteItemsOptions = ref([]);
+
+const fetchProcessRouteItems = (routeId) => {
+  processRouteItemsOptions.value = [];
+  findProcessRouteItemList({ routeId: routeId }).then(res => {
+    const items = res.data || [];
+    processRouteItemsOptions.value = items;
+    
+    // 鑷姩娣诲姞宸ュ簭锛岃鍒掓暟浣跨敤鍩烘湰淇℃伅鐨勯渶姹傛暟閲�
+    const demandQty = formState.value.quantity || 1;
+    processRouteItems.value = items.map(item => ({
+      processId: item.processId,
+      processName: item.processName,
+      productModelId: item.productModelId,
+      userPower: item.userPower ? item.userPower.split(',') : [],
+      planStartTime: "",
+      planEndTime: "",
+      planNum: demandQty,
+      isQuality: item.isQuality || false,
+    }));
+  });
+};
+
+// BOM鍒楄〃寮圭獥鐩稿叧
+const showBomDialog = ref(false);
+const bomList = ref([]);
+const currentProductId = ref(null);
+
+const fetchBomList = (productModelId) => {
+  currentProductId.value = productModelId;
+  listProductBom({ productModelId: productModelId }).then(res => {
+    const bomData = res.data?.records || [];
+    if (bomData.length === 1) {
+      // 鍙湁涓�涓狟OM锛岀洿鎺ユ煡璇㈢墿鏂欐竻鍗�
+      fetchMaterialList(bomData[0].id);
+    } else if (bomData.length > 1) {
+      // 澶氫釜BOM锛屽脊鍑洪�夋嫨妗�
+      bomList.value = bomData;
+      showBomDialog.value = true;
+    }
+  });
+};
+
+const handleBomSelect = (bom) => {
+  showBomDialog.value = false;
+  fetchMaterialList(bom.id);
+};
+
+const fetchMaterialList = (bomId) => {
+  listByBomIdIsParent(bomId).then(res => {
+    const materials = res.data || [];
+    const demandQty = formState.value.quantity || 1;
+    productStructureRecords.value = materials.map(item => ({
+      parentId: item.parentId,
+      productModelId: item.productModelId,
+      model: item.model || '',
+      productName: item.productName || '',
+      productOrderId: undefined,
+      processId: undefined,
+      unitQuantity: item.unitQuantity || 1,
+      demandedQuantity: (item.unitQuantity || 1) * demandQty,
+      unit: item.unit || '',
+      bomId: item.bomId,
+    }));
+  });
+};
+
+// 鐩戝惉鐗╂枡娓呭崟鍙樺寲锛屽綋鍗曚綅浜у嚭闇�瑕佹暟閲忓彉鍖栨椂閲嶆柊璁$畻闇�姹傛暟閲�
+watch(() => productStructureRecords.value, (newRecords, oldRecords) => {
+  if (oldRecords && oldRecords.length > 0) {
+    oldRecords.forEach((oldItem, index) => {
+      const newItem = newRecords[index];
+      if (oldItem && newItem && newItem.unitQuantity !== oldItem.unitQuantity) {
+        newItem.demandedQuantity = (newItem.unitQuantity || 1) * (formState.value.quantity || 1);
+      }
+    });
+  }
+}, { deep: true });
+
+// 鐩戝惉闇�姹傛暟閲忓彉鍖栵紝閲嶆柊璁$畻鐗╂枡闇�姹傛暟閲忓拰宸ュ簭璁″垝鏁�
+watch(() => formState.value.quantity, (newQty) => {
+  // 鏇存柊鐗╂枡娓呭崟鐨勯渶姹傛暟閲�
+  if (productStructureRecords.value.length > 0 && newQty) {
+    productStructureRecords.value.forEach(item => {
+      item.demandedQuantity = (item.unitQuantity || 1) * newQty;
+    });
+  }
+  // 鏇存柊宸ュ簭鐨勮鍒掓暟
+  if (processRouteItems.value.length > 0 && newQty) {
+    processRouteItems.value.forEach(item => {
+      item.planNum = newQty;
+    });
+  }
+});
+
+// 鍗曚綅浜у嚭闇�瑕佹暟閲忓彉鍖栧鐞�
+const handleUnitQuantityChange = (val, row) => {
+  row.demandedQuantity = (val || 1) * (formState.value.quantity || 1);
+};
+
+// 宸ュ簭閫夋嫨鍙樺寲澶勭悊
+const handleProcessChange = (processId, row) => {
+  const selectedProcess = processRouteItemsOptions.value.find(item => item.processId === processId);
+  if (selectedProcess) {
+    row.processName = selectedProcess.processName;
+    row.productModelId = selectedProcess.productModelId;
+    row.isQuality = selectedProcess.isQuality || false;
+    // userPower鏄�楀彿鍒嗛殧鐨勭敤鎴峰悕锛岃浆鎹负鏁扮粍
+    if (selectedProcess.userPower) {
+      row.userPower = selectedProcess.userPower.split(',');
+    } else {
+      row.userPower = [];
+    }
+  }
+};
+
+// 娣诲姞宸ュ簭
+const addProductionTask = () => {
+  if (!formState.value.productModelId) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨浜у搧");
+    return;
+  }
+  if (processRouteItemsOptions.value.length === 0) {
+    proxy.$modal.msgWarning("璇峰厛閫夋嫨浜у搧浠ヨ幏鍙栧伐搴忓垪琛�");
+    return;
+  }
+  processRouteItems.value.push({
+    processId: undefined,
+    processName: "",
+    processNo: "",
+    productModelId: undefined,
+    userPower: [],
+    planStartTime: "",
+    planEndTime: "",
+    planNum: 1,
+    isQuality: false,
+  });
+};
+
+// 鍒犻櫎宸ュ簭璺嚎鏄庣粏
+const removeProcessRouteItem = (index) => {
+  processRouteItems.value.splice(index, 1);
+};
+
+// 娣诲姞鐢ㄦ枡 - 寮瑰嚭浜у搧閫夋嫨妗�
+const addMaterialItem = () => {
+  showMaterialProductDialog.value = true;
+};
+
+// 澶勭悊鐢ㄦ枡浜у搧閫夋嫨
+const handleMaterialProductSelect = (products) => {
+  if (products && products.length > 0) {
+    products.forEach(product => {
+      productStructureRecords.value.push({
+        productModelId: product.id,
+        parentId: undefined,
+        productOrderId: undefined,
+        processId: undefined,
+        model: product.model || '',
+        productName: product.productName || '',
+        unitQuantity: 1,
+        demandedQuantity: 1,
+        unit: product.unit,
+        bomId: undefined,
+      });
+    });
+  }
+  showMaterialProductDialog.value = false;
+};
+
+// 鍒犻櫎鐗╂枡娓呭崟
+const removeProductStructureRecord = (index) => {
+  productStructureRecords.value.splice(index, 1);
+};
+
+const handleDrawingBeforeUpload = (file) => {
+  const isAllowed = [
+    'application/pdf',
+    'image/jpeg',
+    'image/jpg',
+    'image/png',
+    'application/dwg'
+  ].includes(file.type) || file.name.endsWith('.dwg');
+  const isLt10M = file.size / 1024 / 1024 < 10;
+  
+  if (!isAllowed) {
+    proxy.$modal.msgError("鍙兘涓婁紶 pdf銆乯pg銆乯peg銆乸ng銆乨wg 鏍煎紡鐨勬枃浠讹紒");
+    return false;
+  }
+  if (!isLt10M) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB锛�");
+    return false;
+  }
+  return true;
+};
+
+const handleDrawingUploadSuccess = (response, file, fileList) => {
+  console.log('涓婁紶鎴愬姛鍝嶅簲', response);
+  console.log('response.data', response.data);
+  if (response.code === 200) {
+    formState.value.tempFileIds = [response.data?.tempId];
+    formState.value.salesLedgerFiles = [{
+      tempId: response.data?.tempId,
+      originalName: response.data?.originalName || file.name,
+      tempPath: response.data?.tempPath,
+      type: response.data?.type || 14
+    }];
+    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+  } else {
+    proxy.$modal.msgError(response.msg || "涓婁紶澶辫触");
+  }
+};
+
+const handleDrawingRemove = (file) => {
+  formState.value.tempFileIds = [];
+  formState.value.salesLedgerFiles = [];
+};
 
 const handleSubmit = () => {
   proxy.$refs["formRef"].validate(valid => {
@@ -172,7 +649,21 @@
         return;
       }
 
-      addProductOrder(formState.value).then(res => {
+      // 澶勭悊鎻愪氦鏁版嵁 - 灏唘serPower鏁扮粍杞崲涓洪�楀彿鍒嗛殧鐨勫瓧绗︿覆
+      const processedProcessRouteItems = processRouteItems.value.map(item => ({
+        ...item,
+        userPower: Array.isArray(item.userPower) ? item.userPower.join(',') : item.userPower
+      }));
+
+      // 缁勮鎻愪氦鏁版嵁
+      const submitData = {
+        ...formState.value,
+        processRouteItems: processedProcessRouteItems,
+        productStructureRecords: productStructureRecords.value,
+        files: formState.value.salesLedgerFiles,
+      };
+
+      addProductOrder(submitData).then(res => {
         // 鍏抽棴妯℃�佹
         isShow.value = false;
         // 鍛婄煡鐖剁粍浠跺凡瀹屾垚
@@ -190,3 +681,115 @@
   isShow,
 });
 </script>
+
+<style scoped>
+.production-order-dialog :deep(.el-dialog__body) {
+  padding: 15px 20px;
+  max-height: 70vh;
+  overflow-y: auto;
+}
+
+.section-card {
+  background: #f8f9fa;
+  border-radius: 8px;
+  padding: 15px;
+  margin-bottom: 15px;
+}
+
+.section-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 10px;
+  border-bottom: 1px solid #e4e7ed;
+}
+
+.section-icon {
+  font-size: 18px;
+  margin-right: 8px;
+}
+
+.section-title-text {
+  font-size: 15px;
+  font-weight: 600;
+  color: #303133;
+  flex: 1;
+}
+
+.add-btn {
+  margin-left: auto;
+}
+
+.compact-form :deep(.el-form-item) {
+  margin-bottom: 12px;
+}
+
+.compact-form :deep(.el-form-item__label) {
+  font-size: 13px;
+  color: #606266;
+}
+
+.select-btn {
+  width: 100%;
+  justify-content: flex-start;
+}
+
+.table-container {
+  background: #fff;
+  border-radius: 4px;
+  padding: 10px;
+}
+
+.compact-table :deep(.el-table__cell) {
+  padding: 4px 0;
+}
+
+.compact-table :deep(.el-input__wrapper),
+.compact-table :deep(.el-input-number) {
+  width: 100%;
+}
+
+.empty-tip {
+  padding: 20px 0;
+}
+
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 148px;
+  height: 148px;
+  text-align: center;
+  line-height: 148px;
+}
+
+:deep(.el-upload--picture-card) {
+  width: 148px;
+  height: 148px;
+}
+
+:deep(.el-upload-list__item) {
+  width: 148px;
+  height: 148px;
+}
+
+:deep(.el-upload__tip) {
+  font-size: 12px;
+  color: #909399;
+  margin-top: 8px;
+}
+
+.upload-inline :deep(.el-upload) {
+  display: inline-flex;
+}
+
+.upload-inline :deep(.el-upload__tip) {
+  margin-top: 4px;
+  font-size: 12px;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: center;
+  gap: 10px;
+}
+</style>

--
Gitblit v1.9.3