Selaa lähdekoodia

出货计划重构

cz 1 vuosi sitten
vanhempi
commit
b5f254b3a3

+ 210 - 7
src/components/process/EHSD/Contract.vue

@@ -543,7 +543,7 @@
                       :precision="0"
                       :controls="false"
                       :min="0"
-                      @change="calculationAmount()"
+                      @change="calculationAmount('quantity')"
                     />
                   </el-form-item>
                 </div>
@@ -748,7 +748,7 @@
         </div>
       </template>
       <template #shipment>
-        <div style="width: 100%">
+        <!-- <div style="width: 100%">
           <el-table
             :data="formData.data.contractShipmentList"
             style="width: 100%; margin-top: 16px"
@@ -810,6 +810,93 @@
               </template>
             </el-table-column>
           </el-table>
+        </div> -->
+
+        <div style="width: 100%">
+          <el-row>
+            <el-col :span="10">
+              <el-form-item label="出货日期" required>
+                <el-date-picker
+                  v-model="formData.data.shipmentTime"
+                  type="date"
+                  placeholder="请选择出货日期"
+                  value-format="YYYY-MM-DD"
+                />
+              </el-form-item>
+              <el-table
+                :data="formData.data.contractWaitShipmentList"
+                @selection-change="handleSelectionChange"
+                ref="tableDom"
+                style="margin: 15px 0"
+              >
+                <el-table-column type="selection" width="55" />
+                <el-table-column prop="productCode" label="商品编号" />
+                <el-table-column prop="productName" label="商品名称" />
+                <el-table-column label="出货数量" width="160">
+                  <template #default="{ row, $index }">
+                    <div style="width: 100%">
+                      <el-form-item
+                        :prop="
+                          'contractWaitShipmentList.' + $index + '.quantity'
+                        "
+                        :inline-message="true"
+                      >
+                        <el-input-number
+                          onmousewheel="return false;"
+                          v-model="row.quantity"
+                          placeholder="请输入数量"
+                          style="width: 100%"
+                          :precision="0"
+                          :controls="false"
+                          :min="0"
+                        />
+                      </el-form-item>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="waitQuantity" label="剩余数量" />
+              </el-table>
+              <div style="text-align: center">
+                <el-button type="primary" @click="handleAddShipment"
+                  >添加</el-button
+                >
+              </div>
+            </el-col>
+            <el-col :span="14">
+              <div style="padding-left: 10px">
+                <el-table
+                  :data="formData.data.contractShipmentList"
+                  :span-method="objectSpanMethod"
+                >
+                  <el-table-column
+                    prop="shipmentTime"
+                    label="出货日期"
+                    width="155"
+                  >
+                  </el-table-column>
+                  <el-table-column prop="productCode" label="商品编码" />
+                  <el-table-column prop="productName" label="商品名称" />
+                  <el-table-column prop="quantity" label="出货数量" width="160">
+                  </el-table-column>
+                  <el-table-column
+                    align="center"
+                    label="操作"
+                    width="80"
+                    fixed="right"
+                  >
+                    <template #default="{ row, $index }">
+                      <el-button
+                        type="primary"
+                        link
+                        @click="clickDelete($index)"
+                        >删除</el-button
+                      >
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </el-col>
+          </el-row>
         </div>
       </template>
     </byForm>
@@ -862,7 +949,7 @@ import selectCity from "@/components/selectCity/index.vue";
 import { useRoute } from "vue-router";
 import SelectContract from "@/components/contractCom/selectContract.vue";
 import useUserStore from "@/store/modules/user";
-import { watch } from "vue";
+import { nextTick, watch } from "vue";
 const userInfo = useUserStore();
 
 const route = useRoute();
@@ -894,6 +981,7 @@ const formData = reactive({
     fileList: [],
     packageFileList: [],
     contractShipmentList: [],
+    contractWaitShipmentList: [],
   },
 });
 const submit = ref(null);
@@ -1465,13 +1553,21 @@ const selectProduct = (goods) => {
         },
       ];
     }
-    formData.data.contractShipmentList.push({
+    //左侧待出货列表
+    formData.data.contractWaitShipmentList.push({
       productCode: goods.code,
       productId: goods.id,
       productName: goods.nameEnglish,
-      shipmentTime: "",
       quantity: undefined,
+      waitQuantity: "",
     });
+    // formData.data.contractShipmentList.push({
+    //   productCode: goods.code,
+    //   productId: goods.id,
+    //   productName: goods.nameEnglish,
+    //   shipmentTime: "",
+    //   quantity: undefined,
+    // });
     ElMessage({
       message: "添加成功!",
       type: "success",
@@ -1492,7 +1588,7 @@ const handleRemove = async (index, row) => {
   await formData.data.contractProductList.splice(index, 1);
   totalAmount();
 };
-const calculationAmount = () => {
+const calculationAmount = (att = "") => {
   nextTick(() => {
     if (
       formData.data.contractProductList &&
@@ -1511,6 +1607,10 @@ const calculationAmount = () => {
         }
         formData.data.contractProductList[i].amount = money;
       }
+      // 重新计算待出货数量
+      if (att) {
+        changeWaitQuantity();
+      }
     }
     nextTick(() => {
       totalAmount();
@@ -1733,6 +1833,7 @@ const clickSplit = (item) => {
 };
 const clickDelete = (index) => {
   formData.data.contractShipmentList.splice(index, 1);
+  changeWaitQuantity();
 };
 
 // 判断当前用户有无销售合同页面权限
@@ -1843,7 +1944,9 @@ const judgeStatusOne = () => {
 watch(
   () => props.queryData,
   (val) => {
-    formOption.disabled = judgeStatusOne();
+    nextTick(() => {
+      formOption.disabled = judgeStatusOne();
+    });
     if (val.businessId && val.processType) {
       let businessId = val.businessId;
       proxy.post("/contract/detail", { id: businessId }).then((res) => {
@@ -1925,6 +2028,7 @@ watch(
   },
   {
     deep: true,
+    immediate: true,
   }
 );
 
@@ -2046,6 +2150,105 @@ const selectContract = (businessId) => {
     type: "success",
   });
 };
+
+const selectShipmentData = ref([]);
+const tableDom = ref(null);
+const handleSelectionChange = (data) => {
+  selectShipmentData.value = data;
+};
+const handleAddShipment = () => {
+  if (formData.data.shipmentTime) {
+    if (selectShipmentData.value && selectShipmentData.value.length > 0) {
+      // 校验
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        if (!Number(e.quantity)) {
+          return ElMessage("请输入出货数量");
+        }
+        if (Number(e.quantity) > Number(e.waitQuantity)) {
+          return ElMessage(`${e.productName} 出货数量不能超过剩余数量`);
+        }
+      }
+      // push
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        formData.data.contractShipmentList.push({
+          productId: e.productId,
+          productCode: e.productCode,
+          productName: e.productName,
+          quantity: e.quantity,
+          shipmentTime: formData.data.shipmentTime,
+        });
+        e.quantity = 0;
+      }
+      // 清空选择的数据
+      tableDom.value.clearSelection();
+      formData.data.shipmentTime = "";
+      changeWaitQuantity();
+    } else {
+      ElMessage("请勾选数据");
+    }
+  } else {
+    ElMessage("请选择出货日期");
+  }
+};
+const changeWaitQuantity = () => {
+  for (let i = 0; i < formData.data.contractProductList.length; i++) {
+    if (formData.data.contractProductList[i].quantity) {
+      formData.data.contractWaitShipmentList[i].waitQuantity =
+        formData.data.contractProductList[i].quantity;
+    }
+  }
+  if (
+    formData.data.contractShipmentList &&
+    formData.data.contractShipmentList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.contractWaitShipmentList.length; i++) {
+      const e = formData.data.contractWaitShipmentList[i];
+      let arr = formData.data.contractShipmentList.filter(
+        (x) => x.productId === e.productId
+      );
+      let quantity = 0;
+      for (let j = 0; j < arr.length; j++) {
+        quantity += arr[j].quantity;
+      }
+      e.waitQuantity = e.waitQuantity - quantity;
+    }
+  }
+};
+const flitterData = (arr) => {
+  let spanOneArr = [];
+  let concatOne = 0;
+  arr.forEach((item, index) => {
+    if (index === 0) {
+      spanOneArr.push(1);
+    } else {
+      //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
+      if (item.shipmentTime === arr[index - 1].shipmentTime) {
+        //第一列需合并相同内容的判断条件
+        spanOneArr[concatOne] += 1;
+        spanOneArr.push(0);
+      } else {
+        spanOneArr.push(1);
+        concatOne = index;
+      }
+    }
+  });
+  return {
+    one: spanOneArr,
+  };
+};
+
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if (columnIndex === 0) {
+    const _row = flitterData(formData.data.contractShipmentList).one[rowIndex];
+    const _col = _row > 0 ? 1 : 0;
+    return {
+      rowspan: _row,
+      colspan: _col,
+    };
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 222 - 5
src/components/process/EHSD/ContractChange.vue

@@ -531,7 +531,7 @@
                       :precision="0"
                       :controls="false"
                       :min="0"
-                      @change="calculationAmount()"
+                      @change="calculationAmount('quantity')"
                     />
                   </el-form-item>
                 </div>
@@ -737,7 +737,7 @@
         </div>
       </template>
       <template #shipment>
-        <div style="width: 100%">
+        <!-- <div style="width: 100%">
           <el-table
             :data="formData.data.contractShipmentList"
             style="width: 100%; margin-top: 16px"
@@ -799,6 +799,92 @@
               </template>
             </el-table-column>
           </el-table>
+        </div> -->
+        <div style="width: 100%">
+          <el-row>
+            <el-col :span="10">
+              <el-form-item label="出货日期" required>
+                <el-date-picker
+                  v-model="formData.data.shipmentTime"
+                  type="date"
+                  placeholder="请选择出货日期"
+                  value-format="YYYY-MM-DD"
+                />
+              </el-form-item>
+              <el-table
+                :data="formData.data.contractWaitShipmentList"
+                @selection-change="handleSelectionChange"
+                ref="tableDom"
+                style="margin: 15px 0"
+              >
+                <el-table-column type="selection" width="55" />
+                <el-table-column prop="productCode" label="商品编号" />
+                <el-table-column prop="productName" label="商品名称" />
+                <el-table-column label="出货数量" width="160">
+                  <template #default="{ row, $index }">
+                    <div style="width: 100%">
+                      <el-form-item
+                        :prop="
+                          'contractWaitShipmentList.' + $index + '.quantity'
+                        "
+                        :inline-message="true"
+                      >
+                        <el-input-number
+                          onmousewheel="return false;"
+                          v-model="row.quantity"
+                          placeholder="请输入数量"
+                          style="width: 100%"
+                          :precision="0"
+                          :controls="false"
+                          :min="0"
+                        />
+                      </el-form-item>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="waitQuantity" label="剩余数量" />
+              </el-table>
+              <div style="text-align: center">
+                <el-button type="primary" @click="handleAddShipment"
+                  >添加</el-button
+                >
+              </div>
+            </el-col>
+            <el-col :span="14">
+              <div style="padding-left: 10px">
+                <el-table
+                  :data="formData.data.contractShipmentList"
+                  :span-method="objectSpanMethod"
+                >
+                  <el-table-column
+                    prop="shipmentTime"
+                    label="出货日期"
+                    width="155"
+                  >
+                  </el-table-column>
+                  <el-table-column prop="productCode" label="商品编码" />
+                  <el-table-column prop="productName" label="商品名称" />
+                  <el-table-column prop="quantity" label="出货数量" width="160">
+                  </el-table-column>
+                  <el-table-column
+                    align="center"
+                    label="操作"
+                    width="80"
+                    fixed="right"
+                  >
+                    <template #default="{ row, $index }">
+                      <el-button
+                        type="primary"
+                        link
+                        @click="clickDelete($index)"
+                        >删除</el-button
+                      >
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </el-col>
+          </el-row>
         </div>
       </template>
     </byForm>
@@ -870,6 +956,7 @@ const formData = reactive({
     fileList: [],
     packageFileList: [],
     contractShipmentList: [],
+    contractWaitShipmentList: [],
   },
 });
 const submit = ref(null);
@@ -1435,13 +1522,21 @@ const selectProduct = (goods) => {
         },
       ];
     }
-    formData.data.contractShipmentList.push({
+    //左侧待出货列表
+    formData.data.contractWaitShipmentList.push({
       productCode: goods.code,
       productId: goods.id,
       productName: goods.nameEnglish,
-      shipmentTime: "",
       quantity: undefined,
+      waitQuantity: "",
     });
+    // formData.data.contractShipmentList.push({
+    //   productCode: goods.code,
+    //   productId: goods.id,
+    //   productName: goods.nameEnglish,
+    //   shipmentTime: "",
+    //   quantity: undefined,
+    // });
     ElMessage({
       message: "添加成功!",
       type: "success",
@@ -1462,7 +1557,7 @@ const handleRemove = async (index, row) => {
   await formData.data.contractProductList.splice(index, 1);
   totalAmount();
 };
-const calculationAmount = () => {
+const calculationAmount = (att = "") => {
   nextTick(() => {
     if (
       formData.data.contractProductList &&
@@ -1481,6 +1576,10 @@ const calculationAmount = () => {
         }
         formData.data.contractProductList[i].amount = money;
       }
+      // 重新计算待出货数量
+      if (att) {
+        changeWaitQuantity();
+      }
     }
     nextTick(() => {
       totalAmount();
@@ -1703,6 +1802,7 @@ const clickSplit = (item) => {
 };
 const clickDelete = (index) => {
   formData.data.contractShipmentList.splice(index, 1);
+  changeWaitQuantity();
 };
 
 // 判断当前用户有无销售合同页面权限
@@ -1846,6 +1946,24 @@ onMounted(() => {
         formData.data.contractProductList &&
         formData.data.contractProductList.length > 0
       ) {
+        if (
+          (formData.data.contractWaitShipmentList &&
+            formData.data.contractWaitShipmentList.length == 0) ||
+          formData.data.contractWaitShipmentList == undefined
+        ) {
+          formData.data.contractWaitShipmentList = [];
+          for (let i = 0; i < formData.data.contractProductList.length; i++) {
+            const e = formData.data.contractProductList[i];
+            formData.data.contractWaitShipmentList.push({
+              productCode: e.productCode,
+              productId: e.productId,
+              productName: e.productName,
+              quantity: undefined,
+              waitQuantity: e.quantity,
+            });
+          }
+          changeWaitQuantity();
+        }
         for (let i = 0; i < formData.data.contractProductList.length; i++) {
           const e = formData.data.contractProductList[i];
           if (e.ehsdJson) {
@@ -1912,6 +2030,105 @@ const checkShow = () => {
     showAllData.value = false;
   }
 };
+
+const selectShipmentData = ref([]);
+const tableDom = ref(null);
+const handleSelectionChange = (data) => {
+  selectShipmentData.value = data;
+};
+const handleAddShipment = () => {
+  if (formData.data.shipmentTime) {
+    if (selectShipmentData.value && selectShipmentData.value.length > 0) {
+      // 校验
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        if (!Number(e.quantity)) {
+          return ElMessage("请输入出货数量");
+        }
+        if (Number(e.quantity) > Number(e.waitQuantity)) {
+          return ElMessage(`${e.productName} 出货数量不能超过剩余数量`);
+        }
+      }
+      // push
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        formData.data.contractShipmentList.push({
+          productId: e.productId,
+          productCode: e.productCode,
+          productName: e.productName,
+          quantity: e.quantity,
+          shipmentTime: formData.data.shipmentTime,
+        });
+        e.quantity = 0;
+      }
+      // 清空选择的数据
+      tableDom.value.clearSelection();
+      formData.data.shipmentTime = "";
+      changeWaitQuantity();
+    } else {
+      ElMessage("请勾选数据");
+    }
+  } else {
+    ElMessage("请选择出货日期");
+  }
+};
+const changeWaitQuantity = () => {
+  for (let i = 0; i < formData.data.contractProductList.length; i++) {
+    if (formData.data.contractProductList[i].quantity) {
+      formData.data.contractWaitShipmentList[i].waitQuantity =
+        formData.data.contractProductList[i].quantity;
+    }
+  }
+  if (
+    formData.data.contractShipmentList &&
+    formData.data.contractShipmentList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.contractWaitShipmentList.length; i++) {
+      const e = formData.data.contractWaitShipmentList[i];
+      let arr = formData.data.contractShipmentList.filter(
+        (x) => x.productId === e.productId
+      );
+      let quantity = 0;
+      for (let j = 0; j < arr.length; j++) {
+        quantity += arr[j].quantity;
+      }
+      e.waitQuantity = e.waitQuantity - quantity;
+    }
+  }
+};
+const flitterData = (arr) => {
+  let spanOneArr = [];
+  let concatOne = 0;
+  arr.forEach((item, index) => {
+    if (index === 0) {
+      spanOneArr.push(1);
+    } else {
+      //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
+      if (item.shipmentTime === arr[index - 1].shipmentTime) {
+        //第一列需合并相同内容的判断条件
+        spanOneArr[concatOne] += 1;
+        spanOneArr.push(0);
+      } else {
+        spanOneArr.push(1);
+        concatOne = index;
+      }
+    }
+  });
+  return {
+    one: spanOneArr,
+  };
+};
+
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if (columnIndex === 0) {
+    const _row = flitterData(formData.data.contractShipmentList).one[rowIndex];
+    const _col = _row > 0 ? 1 : 0;
+    return {
+      rowspan: _row,
+      colspan: _col,
+    };
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 205 - 6
src/components/process/EHSD/Sample.vue

@@ -517,7 +517,7 @@
                       :precision="0"
                       :controls="false"
                       :min="0"
-                      @change="calculationAmount()"
+                      @change="calculationAmount('quantity')"
                     />
                   </el-form-item>
                 </div>
@@ -735,7 +735,7 @@
         </div>
       </template>
       <template #shipment>
-        <div style="width: 100%">
+        <!-- <div style="width: 100%">
           <el-table
             :data="formData.data.sampleShipmentList"
             style="width: 100%; margin-top: 16px"
@@ -797,6 +797,90 @@
               </template>
             </el-table-column>
           </el-table>
+        </div> -->
+        <div style="width: 100%">
+          <el-row>
+            <el-col :span="10">
+              <el-form-item label="出货日期" required>
+                <el-date-picker
+                  v-model="formData.data.shipmentTime"
+                  type="date"
+                  placeholder="请选择出货日期"
+                  value-format="YYYY-MM-DD"
+                />
+              </el-form-item>
+              <el-table
+                :data="formData.data.sampleWaitShipmentList"
+                @selection-change="handleSelectionChange"
+                ref="tableDom"
+                style="margin: 15px 0"
+              >
+                <el-table-column type="selection" width="55" />
+                <el-table-column prop="productCode" label="商品编号" />
+                <el-table-column prop="productName" label="商品名称" />
+                <el-table-column label="出货数量" width="160">
+                  <template #default="{ row, $index }">
+                    <div style="width: 100%">
+                      <el-form-item
+                        :prop="'sampleWaitShipmentList.' + $index + '.quantity'"
+                        :inline-message="true"
+                      >
+                        <el-input-number
+                          onmousewheel="return false;"
+                          v-model="row.quantity"
+                          placeholder="请输入数量"
+                          style="width: 100%"
+                          :precision="0"
+                          :controls="false"
+                          :min="0"
+                        />
+                      </el-form-item>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="waitQuantity" label="剩余数量" />
+              </el-table>
+              <div style="text-align: center">
+                <el-button type="primary" @click="handleAddShipment"
+                  >添加</el-button
+                >
+              </div>
+            </el-col>
+            <el-col :span="14">
+              <div style="padding-left: 10px">
+                <el-table
+                  :data="formData.data.sampleShipmentList"
+                  :span-method="objectSpanMethod"
+                >
+                  <el-table-column
+                    prop="shipmentTime"
+                    label="出货日期"
+                    width="155"
+                  >
+                  </el-table-column>
+                  <el-table-column prop="productCode" label="商品编码" />
+                  <el-table-column prop="productName" label="商品名称" />
+                  <el-table-column prop="quantity" label="出货数量" width="160">
+                  </el-table-column>
+                  <el-table-column
+                    align="center"
+                    label="操作"
+                    width="80"
+                    fixed="right"
+                  >
+                    <template #default="{ row, $index }">
+                      <el-button
+                        type="primary"
+                        link
+                        @click="clickDelete($index)"
+                        >删除</el-button
+                      >
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </el-col>
+          </el-row>
         </div>
       </template>
     </byForm>
@@ -869,6 +953,7 @@ const formData = reactive({
     fileList: [],
     packageFileList: [],
     sampleShipmentList: [],
+    sampleWaitShipmentList: [],
   },
 });
 const submit = ref(null);
@@ -1353,13 +1438,21 @@ const selectProduct = (goods) => {
         },
       ];
     }
-    formData.data.sampleShipmentList.push({
+    //左侧待出货列表
+    formData.data.sampleWaitShipmentList.push({
       productCode: goods.code,
       productId: goods.id,
       productName: goods.nameEnglish,
-      shipmentTime: "",
       quantity: undefined,
+      waitQuantity: "",
     });
+    // formData.data.sampleShipmentList.push({
+    //   productCode: goods.code,
+    //   productId: goods.id,
+    //   productName: goods.nameEnglish,
+    //   shipmentTime: "",
+    //   quantity: undefined,
+    // });
     ElMessage({
       message: "添加成功!",
       type: "success",
@@ -1378,7 +1471,7 @@ const handleRemove = async (index, row) => {
   await formData.data.sampleProductList.splice(index, 1);
   totalAmount();
 };
-const calculationAmount = () => {
+const calculationAmount = (att = "") => {
   nextTick(() => {
     if (
       formData.data.sampleProductList &&
@@ -1397,6 +1490,10 @@ const calculationAmount = () => {
         }
         formData.data.sampleProductList[i].amount = money;
       }
+      // 重新计算待出货数量
+      if (att) {
+        changeWaitQuantity();
+      }
     }
     nextTick(() => {
       totalAmount();
@@ -1617,6 +1714,7 @@ const clickSplit = (item) => {
 };
 const clickDelete = (index) => {
   formData.data.sampleShipmentList.splice(index, 1);
+  changeWaitQuantity();
 };
 onMounted(() => {
   formOption.disabled = judgeStatus();
@@ -1712,7 +1810,9 @@ const judgeStatusOne = () => {
 watch(
   () => props.queryData,
   (val) => {
-    formOption.disabled = judgeStatusOne();
+    nextTick(() => {
+      formOption.disabled = judgeStatusOne();
+    });
     if (val && val.processType) {
       let businessId = val.businessId;
       proxy.post("/sample/detail", { id: businessId }).then((res) => {
@@ -1789,8 +1889,107 @@ watch(
   },
   {
     deep: true,
+    immediate: true,
   }
 );
+const selectShipmentData = ref([]);
+const tableDom = ref(null);
+const handleSelectionChange = (data) => {
+  selectShipmentData.value = data;
+};
+const handleAddShipment = () => {
+  if (formData.data.shipmentTime) {
+    if (selectShipmentData.value && selectShipmentData.value.length > 0) {
+      // 校验
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        if (!Number(e.quantity)) {
+          return ElMessage("请输入出货数量");
+        }
+        if (Number(e.quantity) > Number(e.waitQuantity)) {
+          return ElMessage(`${e.productName} 出货数量不能超过剩余数量`);
+        }
+      }
+      // push
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        formData.data.sampleShipmentList.push({
+          productId: e.productId,
+          productCode: e.productCode,
+          productName: e.productName,
+          quantity: e.quantity,
+          shipmentTime: formData.data.shipmentTime,
+        });
+        e.quantity = 0;
+      }
+      // 清空选择的数据
+      tableDom.value.clearSelection();
+      formData.data.shipmentTime = "";
+      changeWaitQuantity();
+    } else {
+      ElMessage("请勾选数据");
+    }
+  } else {
+    ElMessage("请选择出货日期");
+  }
+};
+const changeWaitQuantity = () => {
+  for (let i = 0; i < formData.data.sampleProductList.length; i++) {
+    if (formData.data.sampleProductList[i].quantity) {
+      formData.data.sampleWaitShipmentList[i].waitQuantity =
+        formData.data.sampleProductList[i].quantity;
+    }
+  }
+  if (
+    formData.data.sampleShipmentList &&
+    formData.data.sampleShipmentList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.sampleWaitShipmentList.length; i++) {
+      const e = formData.data.sampleWaitShipmentList[i];
+      let arr = formData.data.sampleShipmentList.filter(
+        (x) => x.productId === e.productId
+      );
+      let quantity = 0;
+      for (let j = 0; j < arr.length; j++) {
+        quantity += arr[j].quantity;
+      }
+      e.waitQuantity = e.waitQuantity - quantity;
+    }
+  }
+};
+const flitterData = (arr) => {
+  let spanOneArr = [];
+  let concatOne = 0;
+  arr.forEach((item, index) => {
+    if (index === 0) {
+      spanOneArr.push(1);
+    } else {
+      //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
+      if (item.shipmentTime === arr[index - 1].shipmentTime) {
+        //第一列需合并相同内容的判断条件
+        spanOneArr[concatOne] += 1;
+        spanOneArr.push(0);
+      } else {
+        spanOneArr.push(1);
+        concatOne = index;
+      }
+    }
+  });
+  return {
+    one: spanOneArr,
+  };
+};
+
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if (columnIndex === 0) {
+    const _row = flitterData(formData.data.sampleShipmentList).one[rowIndex];
+    const _col = _row > 0 ? 1 : 0;
+    return {
+      rowspan: _row,
+      colspan: _col,
+    };
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 221 - 5
src/components/process/EHSD/SampleChange.vue

@@ -517,7 +517,7 @@
                       :precision="0"
                       :controls="false"
                       :min="0"
-                      @change="calculationAmount()"
+                      @change="calculationAmount('quantity')"
                     />
                   </el-form-item>
                 </div>
@@ -736,7 +736,7 @@
         </div>
       </template>
       <template #shipment>
-        <div style="width: 100%">
+        <!-- <div style="width: 100%">
           <el-table
             :data="formData.data.sampleShipmentList"
             style="width: 100%; margin-top: 16px"
@@ -798,6 +798,91 @@
               </template>
             </el-table-column>
           </el-table>
+        </div> -->
+
+        <div style="width: 100%">
+          <el-row>
+            <el-col :span="10">
+              <el-form-item label="出货日期" required>
+                <el-date-picker
+                  v-model="formData.data.shipmentTime"
+                  type="date"
+                  placeholder="请选择出货日期"
+                  value-format="YYYY-MM-DD"
+                />
+              </el-form-item>
+              <el-table
+                :data="formData.data.sampleWaitShipmentList"
+                @selection-change="handleSelectionChange"
+                ref="tableDom"
+                style="margin: 15px 0"
+              >
+                <el-table-column type="selection" width="55" />
+                <el-table-column prop="productCode" label="商品编号" />
+                <el-table-column prop="productName" label="商品名称" />
+                <el-table-column label="出货数量" width="160">
+                  <template #default="{ row, $index }">
+                    <div style="width: 100%">
+                      <el-form-item
+                        :prop="'sampleWaitShipmentList.' + $index + '.quantity'"
+                        :inline-message="true"
+                      >
+                        <el-input-number
+                          onmousewheel="return false;"
+                          v-model="row.quantity"
+                          placeholder="请输入数量"
+                          style="width: 100%"
+                          :precision="0"
+                          :controls="false"
+                          :min="0"
+                        />
+                      </el-form-item>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="waitQuantity" label="剩余数量" />
+              </el-table>
+              <div style="text-align: center">
+                <el-button type="primary" @click="handleAddShipment"
+                  >添加</el-button
+                >
+              </div>
+            </el-col>
+            <el-col :span="14">
+              <div style="padding-left: 10px">
+                <el-table
+                  :data="formData.data.sampleShipmentList"
+                  :span-method="objectSpanMethod"
+                >
+                  <el-table-column
+                    prop="shipmentTime"
+                    label="出货日期"
+                    width="155"
+                  >
+                  </el-table-column>
+                  <el-table-column prop="productCode" label="商品编码" />
+                  <el-table-column prop="productName" label="商品名称" />
+                  <el-table-column prop="quantity" label="出货数量" width="160">
+                  </el-table-column>
+                  <el-table-column
+                    align="center"
+                    label="操作"
+                    width="80"
+                    fixed="right"
+                  >
+                    <template #default="{ row, $index }">
+                      <el-button
+                        type="primary"
+                        link
+                        @click="clickDelete($index)"
+                        >删除</el-button
+                      >
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </el-col>
+          </el-row>
         </div>
       </template>
     </byForm>
@@ -873,6 +958,7 @@ const formData = reactive({
     fileList: [],
     packageFileList: [],
     sampleShipmentList: [],
+    sampleWaitShipmentList: [],
   },
 });
 const submit = ref(null);
@@ -1364,13 +1450,21 @@ const selectProduct = (goods) => {
         },
       ];
     }
-    formData.data.sampleShipmentList.push({
+    //左侧待出货列表
+    formData.data.sampleWaitShipmentList.push({
       productCode: goods.code,
       productId: goods.id,
       productName: goods.nameEnglish,
-      shipmentTime: "",
       quantity: undefined,
+      waitQuantity: "",
     });
+    // formData.data.sampleShipmentList.push({
+    //   productCode: goods.code,
+    //   productId: goods.id,
+    //   productName: goods.nameEnglish,
+    //   shipmentTime: "",
+    //   quantity: undefined,
+    // });
     ElMessage({
       message: "添加成功!",
       type: "success",
@@ -1389,7 +1483,7 @@ const handleRemove = async (index, row) => {
   await formData.data.sampleProductList.splice(index, 1);
   totalAmount();
 };
-const calculationAmount = () => {
+const calculationAmount = (att = "") => {
   nextTick(() => {
     if (
       formData.data.sampleProductList &&
@@ -1408,6 +1502,10 @@ const calculationAmount = () => {
         }
         formData.data.sampleProductList[i].amount = money;
       }
+      // 重新计算待出货数量
+      if (att) {
+        changeWaitQuantity();
+      }
     }
     nextTick(() => {
       totalAmount();
@@ -1629,6 +1727,7 @@ const clickSplit = (item) => {
 };
 const clickDelete = (index) => {
   formData.data.sampleShipmentList.splice(index, 1);
+  changeWaitQuantity();
 };
 onMounted(() => {
   checkShow();
@@ -1747,6 +1846,24 @@ onMounted(() => {
         formData.data.sampleProductList &&
         formData.data.sampleProductList.length > 0
       ) {
+        if (
+          (formData.data.sampleWaitShipmentList &&
+            formData.data.sampleWaitShipmentList.length == 0) ||
+          formData.data.sampleWaitShipmentList == undefined
+        ) {
+          formData.data.sampleWaitShipmentList = [];
+          for (let i = 0; i < formData.data.sampleProductList.length; i++) {
+            const e = formData.data.sampleProductList[i];
+            formData.data.sampleWaitShipmentList.push({
+              productCode: e.productCode,
+              productId: e.productId,
+              productName: e.productName,
+              quantity: undefined,
+              waitQuantity: e.quantity,
+            });
+          }
+          changeWaitQuantity();
+        }
         for (let i = 0; i < formData.data.sampleProductList.length; i++) {
           const e = formData.data.sampleProductList[i];
           if (e.ehsdJson) {
@@ -1793,6 +1910,105 @@ const checkShow = () => {
     showAllData.value = false;
   }
 };
+
+const selectShipmentData = ref([]);
+const tableDom = ref(null);
+const handleSelectionChange = (data) => {
+  selectShipmentData.value = data;
+};
+const handleAddShipment = () => {
+  if (formData.data.shipmentTime) {
+    if (selectShipmentData.value && selectShipmentData.value.length > 0) {
+      // 校验
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        if (!Number(e.quantity)) {
+          return ElMessage("请输入出货数量");
+        }
+        if (Number(e.quantity) > Number(e.waitQuantity)) {
+          return ElMessage(`${e.productName} 出货数量不能超过剩余数量`);
+        }
+      }
+      // push
+      for (let i = 0; i < selectShipmentData.value.length; i++) {
+        const e = selectShipmentData.value[i];
+        formData.data.sampleShipmentList.push({
+          productId: e.productId,
+          productCode: e.productCode,
+          productName: e.productName,
+          quantity: e.quantity,
+          shipmentTime: formData.data.shipmentTime,
+        });
+        e.quantity = 0;
+      }
+      // 清空选择的数据
+      tableDom.value.clearSelection();
+      formData.data.shipmentTime = "";
+      changeWaitQuantity();
+    } else {
+      ElMessage("请勾选数据");
+    }
+  } else {
+    ElMessage("请选择出货日期");
+  }
+};
+const changeWaitQuantity = () => {
+  for (let i = 0; i < formData.data.sampleProductList.length; i++) {
+    if (formData.data.sampleProductList[i].quantity) {
+      formData.data.sampleWaitShipmentList[i].waitQuantity =
+        formData.data.sampleProductList[i].quantity;
+    }
+  }
+  if (
+    formData.data.sampleShipmentList &&
+    formData.data.sampleShipmentList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.sampleWaitShipmentList.length; i++) {
+      const e = formData.data.sampleWaitShipmentList[i];
+      let arr = formData.data.sampleShipmentList.filter(
+        (x) => x.productId === e.productId
+      );
+      let quantity = 0;
+      for (let j = 0; j < arr.length; j++) {
+        quantity += arr[j].quantity;
+      }
+      e.waitQuantity = e.waitQuantity - quantity;
+    }
+  }
+};
+const flitterData = (arr) => {
+  let spanOneArr = [];
+  let concatOne = 0;
+  arr.forEach((item, index) => {
+    if (index === 0) {
+      spanOneArr.push(1);
+    } else {
+      //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
+      if (item.shipmentTime === arr[index - 1].shipmentTime) {
+        //第一列需合并相同内容的判断条件
+        spanOneArr[concatOne] += 1;
+        spanOneArr.push(0);
+      } else {
+        spanOneArr.push(1);
+        concatOne = index;
+      }
+    }
+  });
+  return {
+    one: spanOneArr,
+  };
+};
+
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if (columnIndex === 0) {
+    const _row = flitterData(formData.data.sampleShipmentList).one[rowIndex];
+    const _col = _row > 0 ? 1 : 0;
+    return {
+      rowspan: _row,
+      colspan: _col,
+    };
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 277 - 0
src/views/connect/E-mail/signature/index.vue

@@ -0,0 +1,277 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :action-list="[
+          {
+            text: '添加签名',
+            action: () => openModal(),
+          },
+        ]"
+        @moreSearch="moreSearch"
+        @get-list="getList"
+      >
+        <template #total="{ item }">
+          <div style="width: 100%">
+            <a
+              style="color: #409eff; cursor: pointer"
+              @click="pushProcessApproval(item)"
+              >{{ item.currency }}{{ item.total }}</a
+            >
+          </div>
+        </template>
+      </byTable>
+    </div>
+
+    <el-dialog
+      :title="submitType == 'add' ? '添加模板' : '编辑模板'"
+      v-if="addDialog"
+      v-model="addDialog"
+      width="60%"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #remark>
+          <div style="width: 100%">
+            <Editor
+              :value="formData.data.remark"
+              @updateValue="updateHandover"
+            />
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="addDialog = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import Editor from "@/components/Editor/index.vue";
+
+const loading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    type: "",
+    keyword: "",
+  },
+});
+const { proxy } = getCurrentInstance();
+const selectConfig = computed(() => {
+  return [];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "模板名称",
+        prop: "corporationName",
+        width: 180,
+      },
+    },
+    {
+      attrs: {
+        label: "签名内容",
+        prop: "deptName",
+        slot: "deptName",
+      },
+    },
+    {
+      attrs: {
+        label: "创建时间",
+        prop: "type",
+        width: 155,
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "180",
+        align: "center",
+        fixed: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "预览",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              openModal(row);
+            },
+          },
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickPrint(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              // 弹窗提示是否删除
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
+                // 删除
+                proxy
+                  .post("/warehouse/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/accountRequestFunds/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "corporationId",
+      label: "模板名称",
+    },
+    {
+      type: "slot",
+      prop: "remark",
+      label: "签名内容",
+      slotName: "remark",
+    },
+  ];
+});
+let rules = ref({
+  productClassifyId: [
+    { required: true, message: "请选择物料分类", trigger: "change" },
+  ],
+  remark: [{ required: true, message: "请输入签名内容", trigger: "blur" }],
+});
+const submitType = ref("add");
+const addDialog = ref(false);
+const submitLoading = ref(false);
+const byform = ref(null);
+const openModal = () => {
+  submitType.value = "add";
+  formData.data = {
+    remark: "",
+  };
+  addDialog.value = true;
+};
+
+const updateHandover = (val) => {
+  formData.data.remark = val;
+};
+const submitForm = () => {
+  byform.value.handleSubmit(() => {
+    submitLoading.value = true;
+    proxy.post("/accountPayment/add", formData.data).then(
+      () => {
+        ElMessage({
+          message: "打款成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      () => {
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/warehouse/detail", { id: row.id }).then((res) => {
+    res.type = res.type + "";
+    dialogVisible.value = true;
+    formData.data = res;
+  });
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+.ql-editor {
+  padding: 0px;
+}
+</style>

+ 78 - 0
src/views/finance/fundManage/funds/index.vue

@@ -37,6 +37,13 @@
             >
           </div>
         </template>
+        <template #file="{ item }">
+          <div style="width: 100%">
+            <el-button type="primary" text @click="handleOpenFile(item)"
+              >查看</el-button
+            >
+          </div>
+        </template>
       </byTable>
     </div>
 
@@ -141,6 +148,41 @@
         >
       </template>
     </el-dialog>
+
+    <el-dialog
+      title="关联附件"
+      v-if="openFileDialog"
+      v-model="openFileDialog"
+      width="500"
+    >
+      <byForm
+        :formConfig="fileConfig"
+        :formOption="formOption"
+        v-model="fileData.data"
+      >
+        <template #fundsFile>
+          <div
+            style="width: 100%"
+            v-if="fileData.data && fileData.data.fileList.length > 0"
+          >
+            <div v-for="(item, index) in fileData.data.fileList" :key="index">
+              <div
+                style="cursor: pointer; color: #409eff"
+                @click="openFile(item)"
+              >
+                {{ item.fileName }}
+              </div>
+            </div>
+          </div>
+          <div v-else>暂无关联</div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openFileDialog = false" size="large"
+          >取 消</el-button
+        >
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -279,6 +321,14 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "关联附件",
+        slot: "file",
+        width: 80,
+        align: "left",
+      },
+    },
+    {
+      attrs: {
         label: "付款方式",
         prop: "paymentMethod",
         width: 120,
@@ -629,6 +679,34 @@ const printObj = ref({
     "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
   extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
 });
+
+const fileData = reactive({
+  data: {},
+});
+const fileConfig = computed(() => [
+  {
+    type: "slot",
+    slotName: "fundsFile",
+    // label: "业务附件",
+  },
+]);
+const openFileDialog = ref(false);
+const handleOpenFile = (row) => {
+  fileData.data = {
+    fileList: [],
+  };
+  proxy
+    .post("/fileInfo/getList", { businessIdList: [row.id] })
+    .then((fileObj) => {
+      if (fileObj[row.id] && fileObj[row.id].length > 0) {
+        fileData.data.fileList = fileObj[row.id];
+      }
+    });
+  openFileDialog.value = true;
+};
+const openFile = (item) => {
+  window.open(item.fileUrl, "_blank");
+};
 </script>
 
 <style lang="scss" scoped>