From 474c2a6516139ccbafecd5fc3d139ee9104ecfd5 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 31 三月 2026 17:28:21 +0800
Subject: [PATCH] 军泰伟业app 1.销售台账、采购台账选择产品逻辑修改 2.新增生产订单时将产品那边的图纸带过来 3.生产订单增加退料功能

---
 src/views/procurementManagement/procurementLedger/index.vue |   59 +++-
 src/api/productionManagement/productionProductInput.js      |    9 
 src/views/basicData/product/ProductSelectDialog.vue         |   10 
 src/views/productionManagement/productionOrder/New.vue      |  119 +++++++++-
 src/views/productionManagement/productionOrder/index.vue    |  379 +++++++++++++++++++++++++++++++---
 src/views/salesManagement/salesLedger/index.vue             |   47 +++
 6 files changed, 537 insertions(+), 86 deletions(-)

diff --git a/src/api/productionManagement/productionProductInput.js b/src/api/productionManagement/productionProductInput.js
index f72cd9b..4aed421 100644
--- a/src/api/productionManagement/productionProductInput.js
+++ b/src/api/productionManagement/productionProductInput.js
@@ -9,3 +9,12 @@
         params: query,
     });
 }
+
+// 閫�鏂�
+export function returnMaterial(data) {
+    return request({
+        url: "/productionProductInput/returnMaterial",
+        method: "post",
+        data: data,
+    });
+}
diff --git a/src/views/basicData/product/ProductSelectDialog.vue b/src/views/basicData/product/ProductSelectDialog.vue
index 11a87b0..9be84fb 100644
--- a/src/views/basicData/product/ProductSelectDialog.vue
+++ b/src/views/basicData/product/ProductSelectDialog.vue
@@ -1,14 +1,12 @@
 <template>
   <el-dialog v-model="visible" title="閫夋嫨浜у搧" width="900px" destroy-on-close :close-on-click-modal="false">
     <el-form :inline="true" :model="query" class="mb-2">
+       <el-form-item label="鍥剧焊缂栧彿">
+        <el-input v-model="query.model" placeholder="杈撳叆鍥剧焊缂栧彿" clearable @keyup.enter="onSearch" />
+      </el-form-item>
       <el-form-item label="浜у搧澶х被">
         <el-input v-model="query.productName" placeholder="杈撳叆浜у搧澶х被" clearable @keyup.enter="onSearch" />
       </el-form-item>
-
-      <el-form-item label="鍥剧焊缂栧彿">
-        <el-input v-model="query.model" placeholder="杈撳叆鍥剧焊缂栧彿" clearable @keyup.enter="onSearch" />
-      </el-form-item>
-
       <el-form-item>
         <el-button type="primary" @click="onSearch">鎼滅储</el-button>
         <el-button @click="onReset">閲嶇疆</el-button>
@@ -20,8 +18,8 @@
       @selection-change="handleSelectionChange" @select="handleSelect">
       <el-table-column type="selection" width="55" />
       <el-table-column type="index" label="搴忓彿" width="60" />
-      <el-table-column prop="productName" label="浜у搧澶х被" min-width="160" />
       <el-table-column prop="model" label="鍥剧焊缂栧彿" min-width="200" />
+      <el-table-column prop="productName" label="浜у搧澶х被" min-width="160" />
       <el-table-column prop="unit" label="鍗曚綅" min-width="160" />
     </el-table>
 
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 54292cf..8ee2f15 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -539,33 +539,25 @@
                ref="productFormRef">
         <el-row :gutter="30">
           <el-col :span="24">
-            <el-form-item label="浜у搧澶х被锛�"
-                          prop="productId">
-              <el-tree-select v-model="productForm.productId"
-                              placeholder="璇烽�夋嫨"
-                              clearable
-                              check-strictly
-                              @change="getModels"
-                              :data="productOptions"
-                              :render-after-expand="false"
-                              filterable
-                              style="width: 100%" />
+            <el-form-item label="浜у搧閫夋嫨锛�"
+                          prop="productSelect">
+              <div style="display: flex; gap: 10px;">
+                <el-input
+                  v-model="productForm.productCategory"
+                  placeholder="璇烽�夋嫨浜у搧"
+                  disabled
+                  style="flex: 1;"
+                />
+                <el-button type="primary" @click="openProductSelectDialog">閫夋嫨</el-button>
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="30">
           <el-col :span="24">
             <el-form-item label="鍥剧焊缂栧彿锛�"
-                          prop="productModelId">
-              <el-select v-model="productForm.productModelId"
-                         placeholder="璇烽�夋嫨"
-                         clearable
-                         @change="getProductModel">
-                <el-option v-for="item in modelOptions"
-                           :key="item.id"
-                           :label="item.model"
-                           :value="item.id" />
-              </el-select>
+                          prop="specificationModel">
+              <el-input v-model="productForm.specificationModel" placeholder="璇疯緭鍏ュ浘绾哥紪鍙�" disabled />
             </el-form-item>
           </el-col>
         </el-row>
@@ -694,11 +686,19 @@
       v-model="fileListDialogVisible"
       title="闄勪欢鍒楄〃"
     />
+
+    <!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
+    <ProductSelectDialog
+      v-model="productSelectVisible"
+      :single="true"
+      @confirm="handleProductSelect"
+    />
   </div>
 </template>
 
 <script setup>
   import { getToken } from "@/utils/auth";
+  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
   import pagination from "@/components/PIMTable/Pagination.vue";
   import {
     ref,
@@ -947,6 +947,7 @@
   const productOperationType = ref("");
   const productOperationIndex = ref("");
   const currentId = ref("");
+  const productSelectVisible = ref(false);
   const productFormData = reactive({
     productForm: {
       productId: "",
@@ -1667,6 +1668,22 @@
     proxy.resetForm("productFormRef");
     productFormVisible.value = false;
   };
+
+  // 鎵撳紑浜у搧閫夋嫨瀵硅瘽妗�
+  const openProductSelectDialog = () => {
+    productSelectVisible.value = true;
+  };
+
+  // 澶勭悊浜у搧閫夋嫨
+  const handleProductSelect = (selectedProducts) => {
+    if (selectedProducts && selectedProducts.length > 0) {
+      const product = selectedProducts[0];
+      productForm.value.productCategory = product.productName;
+      productForm.value.specificationModel = product.model;
+      productForm.value.unit = product.unit;
+    }
+  };
+
   // 瀵煎嚭
   const handleOut = () => {
     ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
diff --git a/src/views/productionManagement/productionOrder/New.vue b/src/views/productionManagement/productionOrder/New.vue
index 2109385..e5831e2 100644
--- a/src/views/productionManagement/productionOrder/New.vue
+++ b/src/views/productionManagement/productionOrder/New.vue
@@ -402,6 +402,28 @@
     formState.value.productModelId = product.id;
     formState.value.unit = product.unit;
     formState.value.routeId = product.routeId;
+    
+    // 淇濆瓨浜у搧鍘熸湁鐨勫浘绾告枃浠�
+    if (product.salesLedgerFiles && product.salesLedgerFiles.length > 0) {
+      formState.value.salesLedgerFiles = product.salesLedgerFiles.map(file => ({
+        id: file.id,
+        name: file.name,
+        url: file.url,
+        type: file.type,
+        isExisting: true // 鏍囪涓哄凡瀛樺湪鐨勬枃浠�
+      }));
+      // 鍚屾鍒癴ileList鐢ㄤ簬鍙嶆樉
+      fileList.value = formState.value.salesLedgerFiles.map(file => ({
+        id: file.id,
+        name: file.name,
+        url: file.url,
+        isExisting: true
+      }));
+    } else {
+      formState.value.salesLedgerFiles = [];
+      fileList.value = [];
+    }
+    
     showProductSelectDialog.value = false;
     
     // 1. 閫氳繃浜у搧鑷甫鐨剅outeId鑾峰彇宸ュ簭鍒楄〃
@@ -614,26 +636,66 @@
   return true;
 };
 
-const handleDrawingUploadSuccess = (response, file, fileList) => {
+const handleDrawingUploadSuccess = (response, file, uploadFileList) => {
   console.log('涓婁紶鎴愬姛鍝嶅簲', response);
   console.log('response.data', response.data);
   if (response.code === 200) {
-    formState.value.tempFileIds = [response.data?.tempId];
-    formState.value.salesLedgerFiles = [{
+    // 灏嗘柊涓婁紶鐨勬枃浠舵坊鍔犲埌salesLedgerFiles涓�
+    const newFile = {
       tempId: response.data?.tempId,
-      originalName: response.data?.originalName || file.name,
+      name: response.data?.originalName || file.name,
       tempPath: response.data?.tempPath,
-      type: response.data?.type || 14
-    }];
+      type: response.data?.type || 14,
+      isNew: true // 鏍囪涓烘柊涓婁紶鐨勬枃浠�
+    };
+    
+    // 娣诲姞鏂版枃浠跺埌salesLedgerFiles
+    if (!formState.value.salesLedgerFiles) {
+      formState.value.salesLedgerFiles = [];
+    }
+    formState.value.salesLedgerFiles.push(newFile);
+    
+    // 鏇存柊tempFileIds
+    formState.value.tempFileIds = formState.value.salesLedgerFiles
+      .filter(f => f.tempId)
+      .map(f => f.tempId);
+    
     proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
   } else {
     proxy.$modal.msgError(response.msg || "涓婁紶澶辫触");
   }
 };
 
-const handleDrawingRemove = (file) => {
-  formState.value.tempFileIds = [];
-  formState.value.salesLedgerFiles = [];
+const handleDrawingRemove = (file, uploadFileList) => {
+  // 浠巗alesLedgerFiles涓Щ闄ゅ搴旂殑鏂囦欢
+  if (formState.value.salesLedgerFiles) {
+    const index = formState.value.salesLedgerFiles.findIndex(item => {
+      // 鏍规嵁id鎴杢empId鍖归厤
+      if (file.id && item.id === file.id) return true;
+      if (file.response?.data?.tempId && item.tempId === file.response.data.tempId) return true;
+      if (file.name && item.name === file.name) return true;
+      return false;
+    });
+    
+    if (index > -1) {
+      const removedFile = formState.value.salesLedgerFiles[index];
+      // 鏍囪涓哄凡鍒犻櫎锛堢敤浜庡悗绔鐞嗭級
+      if (removedFile.id) {
+        removedFile.isDeleted = true;
+      } else {
+        // 鏂颁笂浼犵殑鏂囦欢鐩存帴绉婚櫎
+        formState.value.salesLedgerFiles.splice(index, 1);
+      }
+    }
+  }
+  
+  // 鏇存柊tempFileIds
+  formState.value.tempFileIds = formState.value.salesLedgerFiles
+    .filter(f => f.tempId && !f.isDeleted)
+    .map(f => f.tempId);
+  
+  // 鍚屾鏇存柊fileList
+  fileList.value = uploadFileList || [];
 };
 
 const handleSubmit = () => {
@@ -644,10 +706,6 @@
         proxy.$modal.msgError("璇烽�夋嫨浜у搧");
         return;
       }
-      if (!formState.value.productModelId) {
-        proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
-        return;
-      }
 
       // 澶勭悊鎻愪氦鏁版嵁 - 灏唘serPower鏁扮粍杞崲涓洪�楀彿鍒嗛殧鐨勫瓧绗︿覆
       const processedProcessRouteItems = processRouteItems.value.map(item => ({
@@ -655,12 +713,45 @@
         userPower: Array.isArray(item.userPower) ? item.userPower.join(',') : item.userPower
       }));
 
+      // 澶勭悊鏂囦欢鏁版嵁 - 鍖呭惈宸插瓨鍦ㄧ殑銆佹柊涓婁紶鐨勫拰宸插垹闄ょ殑
+      const processedFiles = (formState.value.salesLedgerFiles || []).map(file => {
+        if (file.isNew) {
+          // 鏂颁笂浼犵殑鏂囦欢
+          return {
+            tempId: file.tempId,
+            name: file.name,
+            tempPath: file.tempPath,
+            type: file.type,
+            isNew: true
+          };
+        } else if (file.isDeleted) {
+          // 宸插垹闄ょ殑鍘熸湁鏂囦欢
+          return {
+            id: file.id,
+            name: file.name,
+            url: file.url,
+            type: file.type,
+            isDeleted: true
+          };
+        } else {
+          // 淇濈暀鐨勫師鏈夋枃浠�
+          return {
+            id: file.id,
+            name: file.name,
+            url: file.url,
+            type: file.type,
+            isExisting: true
+          };
+        }
+      });
+
       // 缁勮鎻愪氦鏁版嵁
       const submitData = {
         ...formState.value,
         processRouteItems: processedProcessRouteItems,
         productStructureRecords: productStructureRecords.value,
-        files: formState.value.salesLedgerFiles,
+        salesLedgerFiles: processedFiles,
+        files: processedFiles,
       };
 
       addProductOrder(submitData).then(res => {
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 40f3ba1..7984915 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -39,6 +39,19 @@
             :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''"
           />
         </template>
+        <template #productWorkOrders="{ row }">
+          <div class="work-order-circles">
+            <div
+              v-for="(workOrder, index) in row.productWorkOrders"
+              :key="index"
+              class="work-order-circle"
+              :class="getWorkOrderColorClass(workOrder.color)"
+              :title="workOrder.processName || workOrder.workOrderNo"
+            >
+              {{ workOrder.processName ? workOrder.processName.substring(0, 2) : index + 1 }}
+            </div>
+          </div>
+        </template>
       </PIMTable>
     </div>
     <el-dialog v-model="bindRouteDialogVisible"
@@ -72,19 +85,46 @@
 
     <!-- 鏌ョ湅鎶曞叆寮规 -->
     <el-dialog v-model="inputDialogVisible"
-               title="鎶曞叆"
-               width="1000px">
-      <PIMTable
-        rowKey="id"
-        :column="inputTableColumn"
-        :tableData="inputTableData"
-        :page="inputPage"
-        :tableLoading="inputTableLoading"
-        @pagination="handleInputPagination"
-      />
+               title="鎶曞叆涓庨��鏂�"
+               width="1200px"
+               :close-on-click-modal="false">
+      <el-table
+        :data="inputTableData"
+        border
+        size="small"
+        @selection-change="handleInputSelectionChange"
+        :header-cell-style="{ background: '#f5f7fa' }"
+        show-summary
+        :summary-method="summarizeInputTable"
+      >
+        <el-table-column type="selection" width="50" align="center" />
+        <el-table-column label="鎶曞叆浜у搧鍚嶇О" prop="productName" min-width="120" />
+        <el-table-column label="鍥剧焊缂栧彿" prop="model" min-width="100" />
+        <el-table-column label="鎶曞叆鏁伴噺" prop="quantity" min-width="100" align="center" />
+        <el-table-column label="宸查��鏂欐暟閲�" prop="returnQuantity" min-width="100" align="center" />
+        <el-table-column label="鍗曚綅" prop="unit" min-width="80" align="center" />
+        <el-table-column label="鏈閫�鏂欐暟閲�" min-width="180" align="center" prop="currentReturnQuantity">
+          <template #default="{ row }">
+            <el-input-number
+              v-model="row.currentReturnQuantity"
+              :min="0"
+              :max="row.quantity - (row.returnQuantity || 0)"
+              :precision="0"
+              size="small"
+              style="width: 160px"
+              @change="(val) => handleInputReturnQuantityChange(val, row)"
+            />
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="picking-footer-info">
+        <span>宸查�� {{ inputSelectedRows.length }} 鏉�</span>
+        <span>{{ inputTableData.length }} 鏉¤褰�</span>
+      </div>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="inputDialogVisible = false">鍏抽棴</el-button>
+          <el-button type="warning" @click="handleReturnSubmit">纭閫�鏂�</el-button>
+          <el-button @click="inputDialogVisible = false">鍏抽棴</el-button>
         </div>
       </template>
     </el-dialog>
@@ -138,13 +178,47 @@
       </template>
     </el-dialog>
 
+    <!-- 鏌ョ湅鍥剧焊寮圭獥 -->
+    <el-dialog
+      v-model="drawingDialogVisible"
+      title="鏌ョ湅鍥剧焊"
+      width="800px"
+      :close-on-click-modal="false"
+    >
+      <div class="drawing-container">
+        <div v-if="currentDrawingFiles.length === 0" class="empty-drawing">
+          <el-empty description="鏆傛棤鍥剧焊" />
+        </div>
+        <div v-else class="drawing-list">
+          <div v-for="(file, index) in currentDrawingFiles" :key="index" class="drawing-item">
+            <el-image
+              v-if="isImage(file.name)"
+              :src="getFileUrl(file)"
+              :preview-src-list="imagePreviewList"
+              fit="cover"
+              style="width: 150px; height: 150px; border-radius: 4px; cursor: pointer;"
+            />
+            <div v-else class="file-item" @click="downloadFile(file)">
+              <el-icon :size="50"><Document /></el-icon>
+              <span class="file-name">{{ file.name }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="drawingDialogVisible = false">鍏抽棴</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
   </div>
 </template>
 
 <script setup>
   import { onMounted, ref, computed } from "vue";
   import { ElMessageBox } from "element-plus";
-  import { Setting } from '@element-plus/icons-vue';
+  import { Setting, Document } from '@element-plus/icons-vue';
   import dayjs from "dayjs";
   import { useRouter } from "vue-router";
   import {
@@ -154,7 +228,7 @@
 } from "@/api/productionManagement/productionOrder.js";
 import { listPage as getProcessRouteList } from "@/api/productionManagement/processRoute.js";
   import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
-  import { productionProductInputListPage } from "@/api/productionManagement/productionProductInput.js";
+  import { productionProductInputListPage, returnMaterial } from "@/api/productionManagement/productionProductInput.js";
   import { listPage as listProductStructureRecord, pick as pickMaterial } from "@/api/productionManagement/productStructureRecord.js";
 
   import {fileDel} from "@/api/financialManagement/revenueManagement.js";
@@ -165,6 +239,66 @@
 
   const router = useRouter();
   const isShowNewModal = ref(false);
+
+  // 鏌ョ湅鍥剧焊鐩稿叧
+  const drawingDialogVisible = ref(false);
+  const currentDrawingFiles = ref([]);
+
+  // 鍒ゆ柇鏄惁涓哄浘鐗�
+  const isImage = (fileName) => {
+    if (!fileName) return false;
+    const ext = fileName.toLowerCase().split('.').pop();
+    return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext);
+  };
+
+  // 鑾峰彇鏂囦欢URL
+  const getFileUrl = (file) => {
+    if (file.url) {
+      if (file.url.startsWith('http')) {
+        return file.url;
+      }
+      return import.meta.env.VITE_APP_BASE_API + file.url;
+    }
+    return '';
+  };
+
+  // 鍥剧墖棰勮鍒楄〃
+  const imagePreviewList = computed(() => {
+    return currentDrawingFiles.value
+      .filter(file => isImage(file.name))
+      .map(file => getFileUrl(file));
+  });
+
+  // 涓嬭浇鏂囦欢
+  const downloadFile = (file) => {
+    const url = getFileUrl(file);
+    if (url) {
+      const link = document.createElement('a');
+      link.href = url;
+      link.download = file.name;
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+    }
+  };
+
+  // 鏄剧ず鏌ョ湅鍥剧焊寮圭獥
+  const showDrawingDialog = (row) => {
+    currentDrawingFiles.value = row.salesLedgerFiles || [];
+    drawingDialogVisible.value = true;
+  };
+
+  // 鑾峰彇宸ュ崟鍦嗗湀棰滆壊绫诲悕
+  // color: 1-鐏拌壊 2-榛勮壊 3-缁胯壊 4-绾㈣壊
+  const getWorkOrderColorClass = (color) => {
+    const colorMap = {
+      1: 'gray',
+      2: 'yellow',
+      3: 'green',
+      4: 'red'
+    };
+    return colorMap[color] || 'gray';
+  };
 
   const tableColumn = ref([
     {
@@ -201,6 +335,13 @@
     },
     {
       dataType: "slot",
+      label: "宸ュ簭",
+      prop: "productWorkOrders",
+      slot: "productWorkOrders",
+      width: 200,
+    },
+    {
+      dataType: "slot",
       label: "瀹屾垚杩涘害",
       prop: "completionStatus",
       slot: "completionStatus",
@@ -229,7 +370,7 @@
       label: "鎿嶄綔",
       align: "center",
       fixed: "right",
-      width: 360,
+      width: 420,
       operation: [
         {
           name: "寮�濮�",
@@ -277,10 +418,18 @@
           },
         },
         {
-          name: "鏌ョ湅鎶曞叆",
+          name: "鎶曞叆/閫�鏂�",
           type: "text",
           clickFun: row => {
             showInputDialog(row);
+          },
+        },
+        {
+          name: "鏌ョ湅鍥剧焊",
+          type: "text",
+          showHide: row => row.salesLedgerFiles && row.salesLedgerFiles.length > 0,
+          clickFun: row => {
+            showDrawingDialog(row);
           },
         },
       ],
@@ -300,29 +449,12 @@
   const inputTableData = ref([]);
   const inputTableLoading = ref(false);
   const inputCurrentRow = ref(null);
+  const inputSelectedRows = ref([]);
   const inputPage = reactive({
     current: 1,
     size: 100,
     total: 0,
   });
-  const inputTableColumn = ref([
-    {
-      label: '鎶曞叆浜у搧鍚嶇О',
-      prop: 'productName',
-    },
-    {
-      label: '鍥剧焊缂栧彿',
-      prop: 'model'
-    },
-    {
-      label: '鎶曞叆鏁伴噺',
-      prop: 'quantity',
-    },
-    {
-      label: '鍗曚綅',
-      prop: 'unit',
-    },
-  ]);
 
   // 棰嗘枡鐩稿叧
   const pickingDialogVisible = ref(false);
@@ -331,6 +463,8 @@
   const pickingForm = reactive({
     orderId: null,
   });
+
+
 
   const data = reactive({
     searchForm: {
@@ -577,11 +711,12 @@
   const handleConfirmRoute = () => {};
 
   // 鏄剧ず鏌ョ湅鎶曞叆寮规
-  const showInputDialog = (row) => {
+  const showInputDialog = async (row) => {
     inputCurrentRow.value = row;
     inputDialogVisible.value = true;
     inputPage.current = 1;
     inputPage.total = 0;
+    inputSelectedRows.value = [];
     fetchInputData();
   };
 
@@ -599,7 +734,10 @@
     productionProductInputListPage(params)
       .then(res => {
         inputTableLoading.value = false;
-        inputTableData.value = res.data.records;
+        inputTableData.value = res.data.records.map(item => ({
+          ...item,
+          currentReturnQuantity: 0,
+        }));
         inputPage.total = res.data.total;
       })
       .catch(err => {
@@ -687,6 +825,58 @@
     ]);
   };
 
+  // 鎶曞叆琛ㄦ牸閫夋嫨鍙樺寲
+  const handleInputSelectionChange = (selection) => {
+    inputSelectedRows.value = selection;
+  };
+
+  // 鎶曞叆閫�鏂欐暟閲忓彉鍖栧鐞�
+  const handleInputReturnQuantityChange = (val, row) => {
+    const maxReturn = row.quantity - (row.returnQuantity || 0);
+    if (val > maxReturn) {
+      proxy.$modal.msgWarning("鏈閫�鏂欐暟閲忎笉鑳借秴杩囧墿浣欏彲閫�鏁伴噺");
+      row.currentReturnQuantity = maxReturn;
+    }
+  };
+
+  // 纭閫�鏂�
+  const handleReturnSubmit = async () => {
+    if (inputSelectedRows.value.length === 0) {
+      proxy.$modal.msgWarning("璇烽�夋嫨瑕侀��鏂欑殑鐗╂枡");
+      return;
+    }
+    // 鏍¢獙閫�鏂欐暟閲�
+    const invalidRows = inputSelectedRows.value.filter(row => !row.currentReturnQuantity || row.currentReturnQuantity <= 0);
+    if (invalidRows.length > 0) {
+      proxy.$modal.msgWarning("璇峰~鍐欐湰娆¢��鏂欐暟閲�");
+      return;
+    }
+
+    const returnData = inputSelectedRows.value.map(row => ({
+      ...row,
+      returnQuantity: row.currentReturnQuantity,
+    }));
+
+    try {
+      await returnMaterial(returnData);
+      proxy.$modal.msgSuccess("閫�鏂欐垚鍔�");
+      inputDialogVisible.value = false;
+      getList();
+    } catch (e) {
+      console.error("閫�鏂欏け璐ワ細", e);
+      proxy.$modal.msgError("閫�鏂欏け璐�");
+    }
+  };
+
+  // 鎶曞叆琛ㄦ牸鍚堣鏂规硶
+  const summarizeInputTable = (param) => {
+    return proxy.summarizeTable(param, [
+      "quantity",
+      "returnQuantity",
+      "currentReturnQuantity",
+    ]);
+  };
+
   onMounted(() => {
     getList();
   });
@@ -721,4 +911,123 @@
   color: #606266;
 }
 
+.drawing-container {
+  min-height: 200px;
+}
+
+.empty-drawing {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-height: 200px;
+}
+
+.drawing-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  padding: 10px;
+}
+
+.drawing-item {
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  overflow: hidden;
+  transition: all 0.3s;
+  
+  &:hover {
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  }
+}
+
+.file-item {
+  width: 150px;
+  height: 150px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background: #f5f7fa;
+  cursor: pointer;
+  padding: 10px;
+  
+  .file-name {
+    font-size: 12px;
+    color: #606266;
+    margin-top: 10px;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    max-width: 130px;
+  }
+  
+  &:hover {
+    background: #e4e7ed;
+  }
+}
+
+// 宸ュ崟鍦嗗湀鏍峰紡
+.work-order-circles {
+  display: flex;
+  gap: 8px;
+  flex-wrap: wrap;
+  align-items: center;
+}
+
+.work-order-circle {
+  width: 32px;
+  height: 32px;
+  border-radius: 6px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  font-weight: 500;
+  color: #fff;
+  cursor: pointer;
+  transition: all 0.2s ease;
+  
+  // 鐏拌壊 - 寰呭紑濮�
+  &.gray {
+    background-color: #909399;
+    
+    &:hover {
+      background-color: #a6a9ad;
+    }
+  }
+  
+  // 榛勮壊 - 杩涜涓�
+  &.yellow {
+    background-color: #e6a23c;
+    
+    &:hover {
+      background-color: #ebb563;
+    }
+  }
+  
+  // 缁胯壊 - 宸插畬鎴�
+  &.green {
+    background-color: #67c23a;
+    
+    &:hover {
+      background-color: #85ce61;
+    }
+  }
+  
+  // 绾㈣壊 - 寮傚父/鏆傚仠
+  &.red {
+    background-color: #f56c6c;
+    
+    &:hover {
+      background-color: #f78989;
+    }
+  }
+  
+  &:hover {
+    transform: translateY(-2px);
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
+  }
+}
+
 </style>
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index c7e7617..bdd2d94 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -323,21 +323,23 @@
 			<el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
 				<el-row :gutter="30">
 					<el-col :span="24">
-						<el-form-item label="浜у搧澶х被锛�" prop="productCategory">
-							<!-- <el-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable>
-								<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
-							</el-select> -->
-							<el-tree-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable check-strictly
-															@change="getModels" :data="productOptions" :render-after-expand="false" filterable style="width: 100%" />
+						<el-form-item label="浜у搧閫夋嫨锛�" prop="productSelect">
+							<div style="display: flex; gap: 10px;">
+								<el-input
+									v-model="productForm.productCategory"
+									placeholder="璇烽�夋嫨浜у搧"
+									disabled
+									style="flex: 1;"
+								/>
+								<el-button type="primary" @click="openProductSelectDialog">閫夋嫨</el-button>
+							</div>
 						</el-form-item>
 					</el-col>
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="24">
-						<el-form-item label="鍥剧焊缂栧彿锛�" prop="productModelId">
-							<el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable @change="getProductModel" filterable>
-								<el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
-							</el-select>
+						<el-form-item label="鍥剧焊缂栧彿锛�" prop="specificationModel">
+							<el-input v-model="productForm.specificationModel" placeholder="璇疯緭鍏ュ浘绾哥紪鍙�" disabled />
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -615,6 +617,13 @@
 				</div>
 			</template>
 		</el-dialog>
+
+		<!-- 浜у搧閫夋嫨瀵硅瘽妗� -->
+		<ProductSelectDialog
+			v-model="productSelectVisible"
+			:single="true"
+			@confirm="handleProductSelect"
+		/>
 	</div>
 </template>
 
@@ -622,6 +631,7 @@
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
 import {onMounted, ref, getCurrentInstance} from "vue";
+import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
 import { ElMessageBox, ElMessage } from "element-plus";
 import { UploadFilled, Download } from "@element-plus/icons-vue";
@@ -701,6 +711,7 @@
 const productFormVisible = ref(false);
 const productOperationType = ref("");
 const currentId = ref("");
+const productSelectVisible = ref(false);
 const productFormData = reactive({
 	productForm: {
 		productCategory: "",
@@ -1317,6 +1328,22 @@
 	proxy.resetForm("productFormRef");
 	productFormVisible.value = false;
 };
+
+// 鎵撳紑浜у搧閫夋嫨瀵硅瘽妗�
+const openProductSelectDialog = () => {
+	productSelectVisible.value = true;
+};
+
+// 澶勭悊浜у搧閫夋嫨
+const handleProductSelect = (selectedProducts) => {
+	if (selectedProducts && selectedProducts.length > 0) {
+		const product = selectedProducts[0];
+		productForm.value.productCategory = product.productName;
+		productForm.value.specificationModel = product.model;
+		productForm.value.unit = product.unit;
+	}
+};
+
 // 瀵煎叆
 const handleImport = () => {
 	importUpload.title = "瀵煎叆閿�鍞彴璐�";

--
Gitblit v1.9.3