From ac8813cde64f7bf9882657416a1d102191aae960 Mon Sep 17 00:00:00 2001
From: helongyang <647556386@qq.com>
Date: 星期六, 19 七月 2025 17:32:59 +0800
Subject: [PATCH] Merge branch 'master' of http://115.159.85.185:8098/r/MeiRuiAn/HuaiAn

---
 代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue |  444 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 444 insertions(+), 0 deletions(-)

diff --git "a/\344\273\243\347\240\201\347\256\241\347\220\206/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue" "b/\344\273\243\347\240\201\347\256\241\347\220\206/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue"
new file mode 100644
index 0000000..b379641
--- /dev/null
+++ "b/\344\273\243\347\240\201\347\256\241\347\220\206/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue"
@@ -0,0 +1,444 @@
+<template>
+  <div>
+    <vol-box
+      v-model="showDetialBox"
+      :lazy="true"
+      width="1300px"
+      height="700px"
+      :padding="20"
+      title="娣诲姞鎴愬搧瓒呮湡鎶ュ簾鏄庣粏"
+    >
+      <div style="max-height: 700px; overflow-y: auto;">
+        <el-form ref="form" :model="form" label-width="130px">
+          <!-- 浠撳簱閫夋嫨 -->
+          <el-form-item required label="鎵�灞炰粨搴擄細">
+            <el-select
+              v-model="form.warehouseId"
+              filterable
+              placeholder="璇烽�夋嫨浠撳簱"
+              @change="handleWarehouseChange"
+              style="width: 100%;"
+            >
+              <el-option
+                v-for="item in warehouses"
+                :key="item.key"
+                :label="item.value"
+                :value="item.key"
+              >
+                <span style="float: left">{{ item.value }}</span>
+                <span style="float: right; color: #8492a6; font-size: 13px">{{ item.key }}</span>
+              </el-option>
+            </el-select>
+          </el-form-item>
+
+          <!-- 鍗曟嵁缂栧彿锛堝彧璇伙級 -->
+          <el-form-item required label="鍗曟嵁缂栧彿锛�">
+            <el-input
+              v-model="form.proScrapSheetOrderNo"
+              placeholder="绯荤粺灏嗚嚜鍔ㄧ敓鎴�"
+              readonly
+              style="width: 100%;"
+            ></el-input>
+          </el-form-item>
+
+          <!-- 鏄庣粏鍒楄〃 -->
+          <el-form-item label="鎶ュ簾鏄庣粏锛�">
+            <div v-for="(detail, index) in detailList" :key="index" class="detail-item">
+              <div class="detail-header">
+                <span>鏄庣粏 {{ index + 1 }}</span>
+                <el-button
+                  type="text"
+                  size="mini"
+                  color="#f56c6c"
+                  @click="removeDetail(index)"
+                  :disabled="detailList.length <= 1"
+                >
+                  鍒犻櫎
+                </el-button>
+              </div>
+
+              <el-row :gutter="20" class="detail-row">
+                <el-col :span="6">
+                  <el-form-item
+                    required
+                    :prop="'detailList.' + index + '.scrapProCode'"
+                    :rules="{ required: true, message: '璇烽�夋嫨浜у搧缂栫爜', trigger: 'blur' }"
+                  >
+                    <el-select
+                      v-model="detail.scrapProCode"
+                      filterable
+                      placeholder="浜у搧缂栫爜"
+                      @change="handleProCodeChange(detail, index)"
+                      clearable
+                      style="width: 100%;"
+                    >
+                      <el-option
+                        v-for="(code, index) in proCodeOptions"
+                        :key="index"
+                        :label="code"
+                        :value="code"
+                      ></el-option>
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+
+                <el-col :span="5">
+                  <el-form-item
+                    required
+                    :prop="'detailList.' + index + '.scrapProVersion'"
+                    :rules="{ required: true, message: '璇烽�夋嫨鐗堟湰', trigger: 'blur' }"
+                  >
+                    <el-select
+                      v-model="detail.scrapProVersion"
+                      filterable
+                      placeholder="鐗堟湰"
+                      clearable
+                      style="width: 100%;"
+                    >
+                      <el-option
+                        v-for="item in detail.versionOptions"
+                        :key="item"
+                        :label="item"
+                        :value="item"
+                      ></el-option>
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+
+                <el-col :span="5">
+                  <el-form-item
+                    required
+                    :prop="'detailList.' + index + '.scrapProLotNo'"
+                    :rules="{ required: true, message: '璇烽�夋嫨鎵规鍙�', trigger: 'blur' }"
+                  >
+                    <el-select
+                      v-model="detail.scrapProLotNo"
+                      filterable
+                      placeholder="鎵规鍙�"
+                      clearable
+                      style="width: 100%;"
+                    >
+                      <el-option
+                        v-for="item in detail.lotNoOptions"
+                        :key="item"
+                        :label="item"
+                        :value="item"
+                      ></el-option>
+                    </el-select>
+                  </el-form-item>
+                </el-col>
+
+                <el-col :span="4">
+                  <el-form-item
+                    required
+                    :prop="'detailList.' + index + '.scrapPcsQty'"
+                    :rules="{ 
+                      required: true, 
+                      message: '璇疯緭鍏CS鏁伴噺', 
+                      trigger: 'blur',
+                      validator: validateNumber // 鑷畾涔夋暟瀛楁牎楠�
+                    }"
+                  >
+                    <el-input
+                      v-model="detail.scrapPcsQty"
+                      placeholder="PCS鏁伴噺"
+                      style="width: 100%;"
+                      @blur="formatNumber(detail, 'scrapPcsQty')"
+                    ></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+
+              <el-row :gutter="20" class="detail-row">
+                <el-col :span="24">
+                  <el-form-item label="澶囨敞锛�">
+                    <el-input
+                      v-model="detail.remark"
+                      placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                      type="textarea"
+                      rows="2"
+                      style="width: 100%;"
+                    ></el-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </div>
+
+            <!-- 娣诲姞鏄庣粏鎸夐挳 -->
+            <el-button
+              type="dashed"
+              size="small"
+              class="add-detail-btn"
+              @click="addDetail"
+              :disabled="detailList.length >= 10"
+              style="width: 100%; margin-top: 15px;"
+            >
+              <i class="el-icon-plus"></i> 娣诲姞鏄庣粏
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+
+      <!-- 搴曢儴鎸夐挳 -->
+      <template #footer>
+        <el-button type="primary" size="mini" @click="submitForm" style="padding: 8px 20px;">纭鎻愪氦</el-button>
+        <el-button type="danger" size="mini" @click="close" style="padding: 8px 20px; margin-left: 10px;">鍏抽棴</el-button>
+      </template>
+    </vol-box>
+  </div>
+</template>
+
+<script>
+import VolBox from "@/components/basic/VolBox.vue";
+export default {
+  components: { VolBox },
+  data() {
+    const validateNumber = (rule, value, callback) => {
+      if (!value) {
+        return callback(new Error('璇疯緭鍏ユ暟閲�'));
+      }
+      const numberRegex = /^\d+(\.\d+)?$/;
+      if (!numberRegex.test(value)) {
+        return callback(new Error('璇疯緭鍏ユ湁鏁堢殑鏁板瓧'));
+      }
+      if (parseFloat(value) <= 0) {
+        return callback(new Error('鏁伴噺蹇呴』澶т簬0'));
+      }
+      callback();
+    };
+
+    return {
+      showDetialBox: false,
+      warehouses: [],
+      proCodeOptions: [],
+      form: {
+        warehouseId: "",
+        proScrapSheetOrderNo: ""
+      },
+
+      detailList: [
+        {
+          scrapProCode: "",
+          scrapProVersion: "",
+          scrapProLotNo: "",
+          scrapPcsQty: "",  
+          remark: "",
+          versionOptions: [],
+          lotNoOptions: []
+        }
+      ],
+      validateNumber
+    };
+  },
+  methods: {
+    // 鎵撳紑寮圭獥
+    open() {
+      this.initForm();
+      this.showDetialBox = true;
+    },
+
+    // 鍒濆鍖栬〃鍗�
+    initForm() {
+      this.form = {
+        warehouseId: "",
+        proScrapSheetOrderNo: ""
+      };
+      this.detailList = [this.createEmptyDetail()];
+      
+      // 鍔犺浇浠撳簱鍒楄〃
+      if (this.warehouses.length === 0) {
+        this.getWarehouseList();
+      }
+    },
+
+    // 鍒涘缓绌烘槑缁�
+    createEmptyDetail() {
+      return {
+        scrapProCode: "",
+        scrapProVersion: "",
+        scrapProLotNo: "",
+        scrapPcsQty: "",  
+        remark: "",
+        versionOptions: [],
+        lotNoOptions: []
+      };
+    },
+
+    // 鑾峰彇浠撳簱鍒楄〃
+    getWarehouseList() {
+      this.http
+        .post("api/Warehouse/GetWarehouseDicByUser", null, "鍔犺浇浠撳簱鏁版嵁涓�")
+        .then((res) => {
+          if (!res.status) return this.$message.error(res.message);
+          this.warehouses = res.data || [];
+          // 鑻ュ彧鏈変竴涓粨搴擄紝鑷姩閫変腑
+          if (this.warehouses.length === 1) {
+            this.form.warehouseId = this.warehouses[0].key;
+            this.handleWarehouseChange(this.warehouses[0].key);
+          }
+        });
+    },
+
+    // 浠撳簱鍙樻洿浜嬩欢
+    handleWarehouseChange(warehouseId) {
+      if (!warehouseId) return;
+      // 鏍规嵁浠撳簱ID鍔犺浇浜у搧缂栫爜鍒楄〃
+      this.http
+        .post(`api/ProStockInfo/GetProCodeByWarehouse?warehouseId=${this.form.warehouseId}`,null, "鍔犺浇浜у搧鏁版嵁涓�")
+        .then((res) => {
+          if (res.status) {
+            this.proCodeOptions = [...new Set(res.data)];
+          } else {
+            this.$message.error(res.message);
+          }
+        });
+    },
+
+    // 浜у搧缂栫爜鍙樻洿浜嬩欢
+    handleProCodeChange(detail, index) {
+      if (!detail.scrapProCode) {
+        detail.versionOptions = [];
+        detail.lotNoOptions = [];
+        return;
+      }
+
+      // 鏍规嵁浜у搧缂栫爜鍔犺浇鐗堟湰鍒楄〃
+      this.http
+      .post(
+        `api/ProStockInfo/GetProVersionByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "鍔犺浇鐗堟湰鏁版嵁涓�")
+        .then((res) => {
+          if (res.status) {
+            detail.versionOptions = [...new Set(res.data)];
+          }
+        });
+
+      // 鏍规嵁浜у搧缂栫爜鍔犺浇鎵规鍙峰垪琛�
+      this.http
+        .post(`api/ProStockInfo/GetProLotNoByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "鍔犺浇鎵规鏁版嵁涓�")
+        .then((res) => {
+          if (res.status) {
+            detail.lotNoOptions = [...new Set(res.data)];
+          }
+        });
+    },
+
+    formatNumber(detail, field) {
+      if (!detail[field]) return;
+      
+      let value = detail[field].replace(/[^0-9.]/g, '');
+      
+      const decimalIndex = value.indexOf('.');
+      if (decimalIndex !== -1) {
+        value = value.substring(0, decimalIndex + 1) + value.substring(decimalIndex + 1).replace(/\./g, '');
+      }
+      
+      const parts = value.split('.');
+      if (parts.length > 1 && parts[1].length > 2) {
+        parts[1] = parts[1].substring(0, 2);
+        value = parts.join('.');
+      }
+      
+      detail[field] = value;
+    },
+
+    // 娣诲姞鏄庣粏
+    addDetail() {
+      this.detailList.push(this.createEmptyDetail());
+    },
+
+    // 鍒犻櫎鏄庣粏
+    removeDetail(index) {
+      this.detailList.splice(index, 1);
+    },
+
+    // 鎻愪氦琛ㄥ崟
+    submitForm() {
+  if (!this.form.warehouseId) {
+    return this.$message.error("璇烽�夋嫨鎵�灞炰粨搴�");
+  }
+
+  const invalidDetail = this.detailList.find(item => 
+    !item.scrapProCode || !item.scrapProVersion || !item.scrapProLotNo || !item.scrapPcsQty  || isNaN(parseFloat(item.scrapPcsQty))|| parseFloat(item.scrapPcsQty) <= 0
+  );
+  
+  if (invalidDetail) {
+    return this.$message.error("璇蜂负鎵�鏈夋槑缁嗚緭鍏ユ湁鏁堢殑鏁伴噺鍊硷紙澶т簬0鐨勬暟瀛楋級");
+  }
+
+  const submitData = {
+    warehouseId: this.form.warehouseId,
+    details: this.detailList.map(item => ({
+      scrapProCode: item.scrapProCode,
+      scrapProVersion: item.scrapProVersion,
+      scrapProLotNo: item.scrapProLotNo,
+      scrapPcsQty: parseFloat(item.scrapPcsQty),
+      remark: item.remark
+    }))
+  };
+
+  this.http
+    .post("api/ErpProScrapSheet/Save", submitData, "鎻愪氦涓�")
+    .then((res) => {
+          if (!res.status) return this.$message.error(res.message);
+          this.$message.success("鎿嶄綔鎴愬姛");
+          this.close();
+          this.$emit("parentCall", ($vue) => {
+            $vue.refresh();
+          });
+        });
+    },
+
+    // 鍏抽棴寮圭獥
+    close() {
+      this.showDetialBox = false;
+    }
+  },
+  created() {
+    // 鍒濆鍖栨椂棰勫姞杞戒粨搴撴暟鎹�
+    if (this.warehouses.length === 0) {
+      this.getWarehouseList();
+    }
+  }
+};
+</script>
+
+<style scoped>
+.detail-item {
+  border: 1px solid #e4e7ed;
+  border-radius: 6px;
+  padding: 15px;
+  margin-bottom: 20px;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
+}
+
+.detail-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 10px;
+  border-bottom: 1px dashed #e4e7ed;
+  font-weight: 500;
+}
+
+.detail-row {
+  margin-bottom: 15px;
+}
+
+.add-detail-btn {
+  height: 40px;
+  line-height: 38px;
+}
+
+::-webkit-scrollbar {
+  width: 8px;
+  height: 8px;
+}
+::-webkit-scrollbar-thumb {
+  background-color: #ddd;
+  border-radius: 4px;
+}
+::-webkit-scrollbar-track {
+  background-color: #f5f5f5;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3