lxf 1 anno fa
parent
commit
6d87d0fefa

+ 25 - 20
src/views/production/operation/batching/index.vue

@@ -102,6 +102,10 @@
         <el-button type="primary" v-print="printObj" size="large">打印</el-button>
       </template>
     </el-dialog>
+
+    <el-dialog title="快捷出库" v-if="openQuick" v-model="openQuick" width="90%">
+      <Quick :selectData="selectData" @clickCancel="clickCancel"></Quick>
+    </el-dialog>
   </div>
 </template>
 
@@ -109,6 +113,7 @@
 import byTable from "@/components/byTable/index";
 import { ElMessage } from "element-plus";
 import moment from "moment";
+import Quick from "@/views/production/operation/batching/quick";
 
 const { proxy } = getCurrentInstance();
 const activeName = ref("first");
@@ -365,14 +370,16 @@ const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
   proxy.post("/stockPreparation/uncompletedList", sourceList.value.pagination).then((res) => {
+    selectData.value = [];
     if (res && res.length > 0) {
       sourceList.value.data = Object.freeze(
-        res.map((item) => {
-          return {
-            ...item,
-            isCheck: true,
-          };
-        })
+        res
+          .map((item) => {
+            return {
+              ...item,
+              isCheck: true,
+            };
+          })
       );
     } else {
       sourceList.value.data = res;
@@ -482,25 +489,19 @@ const printObj = ref({
   extraCss: "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 openQuick = ref(false);
 const clickQuickDelivery = () => {
   if (selectData.value && selectData.value.length > 0) {
-    console.log(selectData.value, "快捷出库");
+    openQuick.value = true;
   } else {
     return ElMessage("请勾选需要快捷出库的数据");
   }
-  // if (selectData.value && selectData.value.length > 0) {
-  //   proxy
-  //     .post(
-  //       "/stockPreparation/submit",
-  //       selectData.value.map((item) => item.orderSkuId)
-  //     )
-  //     .then(() => {
-  //       ElMessage({ message: "提交完成", type: "success" });
-  //       getList();
-  //     });
-  // } else {
-  //   return ElMessage("请选择操作的数据");
-  // }
+};
+const clickCancel = (status) => {
+  openQuick.value = false;
+  if (status) {
+    getList();
+  }
 };
 </script>
 
@@ -526,4 +527,8 @@ const clickQuickDelivery = () => {
     }
   }
 }
+:deep(.el-dialog) {
+  margin-top: 10px !important;
+  margin-bottom: 10px !important;
+}
 </style>

+ 374 - 0
src/views/production/operation/batching/quick.vue

@@ -0,0 +1,374 @@
+<template>
+  <div>
+    <el-card class="box-card">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+        <template #basicInformation>
+          <div style="width: 100%">
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="事业部" prop="departmentId" style="width: 100%; margin-bottom: 18px">
+                  <el-select v-model="formData.data.departmentId" placeholder="请选择事业部" clearable style="width: 100%" @change="changeDepartment">
+                    <el-option v-for="item in departmentList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="出库类型" prop="detailType" style="width: 100%; margin-bottom: 18px">
+                  <el-select v-model="formData.data.detailType" placeholder="请选择出库类型" clearable style="width: 100%">
+                    <el-option v-for="item in useUserStore().allDict['come_stock_type']" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="申请人" prop="applicant" style="width: 100%; margin-bottom: 18px">
+                  <el-input v-model="formData.data.applicant" placeholder="请输入申请人" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="备注" prop="remark" style="width: 100%; margin-bottom: 18px">
+                  <el-input v-model="formData.data.remark" :rows="4" type="textarea" placeholder="请输入备注" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+        </template>
+        <template #inOutStorageBomList>
+          <div style="width: 100%; padding: 0 20px">
+            <el-table :data="formData.data.inOutStorageBomList" :row-style="{ height: '35px' }" header-row-class-name="tableHeader">
+              <el-table-column type="expand">
+                <template #default="props">
+                  <div style="padding: 0 80px 0 50px">
+                    <el-table
+                      :data="props.row.orderList"
+                      :cell-style="{ padding: '0' }"
+                      :row-style="{ height: '35px' }"
+                      v-loading="loading"
+                      header-row-class-name="tableHeader">
+                      <el-table-column label="订单号" prop="orderCode" width="200" />
+                      <el-table-column label="万里牛单号" prop="orderWlnCode" width="140" />
+                      <el-table-column label="SKU品号" prop="skuSpecCode" width="180" />
+                      <el-table-column label="SKU品名" prop="skuSpecName" min-width="180" />
+                      <el-table-column label="出库数量" width="140">
+                        <template #default="{ row }">
+                          <span>{{ row.quantity }}</span>
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="品号" prop="code" width="180" />
+              <el-table-column label="品名" prop="name" min-width="220" />
+              <el-table-column label="仓库" width="160">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="'inOutStorageBomList.' + $index + '.warehouseId'" :rules="rules.warehouseId" :inline-message="true" style="width: 100%">
+                    <el-select
+                      v-model="row.warehouseId"
+                      placeholder="请选择仓库"
+                      clearable
+                      style="width: 100%"
+                      @change="
+                        (val) => {
+                          return changeWarehouse(val, row, $index);
+                        }
+                      ">
+                      <el-option v-for="item in warehouseList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="剩余库存" prop="surplusStock" width="120" />
+              <el-table-column label="出库数量" width="140">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="'inOutStorageBomList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true" style="width: 100%">
+                    <el-input-number
+                      onmousewheel="return false;"
+                      v-model="row.quantity"
+                      placeholder="出库数量"
+                      style="width: 100%"
+                      :controls="false"
+                      :min="0"
+                      :precision="0"
+                      disabled />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" fixed="right" width="80">
+                <template #default="{ $index }">
+                  <el-button type="danger" @click="clickDelete($index)" text>删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <div style="width: 100%; text-align: center; margin: 10px">
+        <el-button @click="clickCancel()" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="large" v-preReClick>确 定</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import { ElMessage } from "element-plus";
+
+const { proxy } = getCurrentInstance();
+const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);
+const props = defineProps({
+  selectData: Array,
+});
+const warehouseList = ref([]);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: "100px",
+  itemWidth: 100,
+  rules: [],
+  labelPosition: "right",
+});
+const formData = reactive({
+  data: {
+    departmentId: "0",
+    type: 0,
+    applicant: proxy.useUserStore().user.nickName,
+    inOutStorageBomList: [],
+  },
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "出库信息",
+      label: "",
+    },
+    {
+      type: "slot",
+      slotName: "basicInformation",
+      label: "",
+    },
+    {
+      type: "title",
+      title: "物料信息",
+      label: "",
+    },
+    {
+      type: "slot",
+      slotName: "inOutStorageBomList",
+      label: "",
+    },
+  ];
+});
+const rules = ref({
+  departmentId: [{ required: true, message: "请选择事业部", trigger: "change" }],
+  warehouseId: [{ required: true, message: "请选择仓库", trigger: "change" }],
+  detailType: [{ required: true, message: "请选择出库类型", trigger: "change" }],
+  applicant: [{ required: true, message: "请输入申请人", trigger: "blur" }],
+  quantity: [{ required: true, message: "请输入出库数量", trigger: "blur" }],
+});
+const getDemandData = () => {
+  proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      departmentList.value = departmentList.value.concat(
+        res.rows.map((item) => {
+          return {
+            dictKey: item.id,
+            dictValue: item.name,
+          };
+        })
+      );
+    }
+  });
+};
+getDemandData();
+const clickDelete = (index) => {
+  formData.data.inOutStorageBomList.splice(index, 1);
+};
+const emit = defineEmits(["clickCancel"]);
+const duplicateRemoval = (arr) => {
+  let list = [];
+  return arr.filter((item) => !list.includes(item) && list.push(item));
+};
+const submitForm = () => {
+  submit.value.handleSubmit(async () => {
+    if (formData.data.inOutStorageBomList && formData.data.inOutStorageBomList.length > 0) {
+      for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
+        if (Number(formData.data.inOutStorageBomList[i].surplusStock) < Number(formData.data.inOutStorageBomList[i].quantity)) {
+          return ElMessage("出库数量大于剩余库存数量");
+        }
+      }
+      for (let i = 0; i < warehouseList.value.length; i++) {
+        let data = proxy.deepClone(formData.data);
+        data.inOutStorageBomList = data.inOutStorageBomList.filter((item) => item.warehouseId === warehouseList.value[i].dictKey);
+        if (data.inOutStorageBomList && data.inOutStorageBomList.length > 0) {
+          data.warehouseId = warehouseList.value[i].dictKey;
+          const res = await proxy.post("/inOutStorage/add", data);
+          let orderList = [];
+          for (let j = 0; j < data.inOutStorageBomList.length; j++) {
+            orderList = orderList.concat(data.inOutStorageBomList[j].orderList.map((itemOrder) => itemOrder.orderSkuId));
+          }
+          const resTwo = await proxy.post("/stockPreparation/submit", duplicateRemoval(orderList));
+        }
+      }
+      ElMessage({ message: "提交完成", type: "success" });
+      emit("clickCancel", true);
+    } else {
+      return ElMessage("请添加BOM");
+    }
+  });
+};
+const clickCancel = () => {
+  emit("clickCancel", false);
+};
+const delSomeObjValue = (arr, keyName, valueName) => {
+  const idArr = []; // 相同的id放在同一数组中
+  const resultArr = []; // 最终结果数组
+  for (let i = 0; i < arr.length; i++) {
+    const index = idArr.indexOf(arr[i][keyName]);
+    if (index > -1) {
+      resultArr[index][valueName] += Number(arr[i][valueName]); //取相同id的value累加
+    } else {
+      idArr.push(arr[i][keyName]);
+      resultArr.push(arr[i]);
+    }
+  }
+  return resultArr;
+};
+const getWarehouse = () => {
+  return proxy.post("/warehouse/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      warehouseList.value = res.rows
+        .filter((item) => ["2", "3"].includes(item.type))
+        .map((item) => {
+          return {
+            dictKey: item.id,
+            dictValue: item.name,
+          };
+        });
+    }
+  });
+};
+onMounted(() => {
+  Promise.all([getWarehouse()]).then(() => {
+    if (props.selectData && props.selectData.length > 0) {
+      formData.data.inOutStorageBomList = delSomeObjValue(
+        props.selectData.map((item) => {
+          let num = 0;
+          if (item.quantity) {
+            num = Number(item.quantity);
+          }
+          return {
+            bomSpecId: item.bomSpecId,
+            quantity: num,
+            name: item.bomSpecName,
+            code: item.bomSpecCode,
+            warehouseId: "",
+            surplusStock: 0,
+          };
+        }),
+        "bomSpecId",
+        "quantity"
+      ).map((item) => {
+        return {
+          ...item,
+          orderList: props.selectData
+            .map((item) => {
+              let num = 0;
+              if (item.quantity) {
+                num = Number(item.quantity);
+              }
+              return {
+                bomSpecId: item.bomSpecId,
+                quantity: num,
+                orderSkuId: item.orderSkuId,
+                orderCode: item.orderCode,
+                orderWlnCode: item.orderWlnCode,
+                skuSpecCode: item.skuSpecCode,
+                skuSpecName: item.skuSpecName,
+              };
+            })
+            .filter((itemSelect) => itemSelect.bomSpecId === item.bomSpecId),
+        };
+      });
+      if (formData.data.inOutStorageBomList && formData.data.inOutStorageBomList.length > 0) {
+        let bomSpecIdList = [];
+        bomSpecIdList = formData.data.inOutStorageBomList.map((item) => item.bomSpecId);
+        proxy
+          .post("/inventory/getQuantity", {
+            departmentId: formData.data.departmentId,
+            warehouseId: warehouseList.value[0].dictKey,
+            bomSpecIdList: bomSpecIdList,
+          })
+          .then((resInventory) => {
+            let bomSpecIdTwoList = [];
+            for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
+              if (resInventory[formData.data.inOutStorageBomList[i].bomSpecId]) {
+                formData.data.inOutStorageBomList[i].warehouseId = warehouseList.value[0].dictKey;
+                formData.data.inOutStorageBomList[i].surplusStock = resInventory[formData.data.inOutStorageBomList[i].bomSpecId];
+              } else {
+                bomSpecIdTwoList.push(formData.data.inOutStorageBomList[i].bomSpecId);
+              }
+            }
+            if (bomSpecIdTwoList && bomSpecIdTwoList.length > 0) {
+              proxy
+                .post("/inventory/getQuantity", {
+                  departmentId: formData.data.departmentId,
+                  warehouseId: warehouseList.value[1].dictKey,
+                  bomSpecIdList: bomSpecIdTwoList,
+                })
+                .then((inventoryTwo) => {
+                  for (let i = 0; i < formData.data.inOutStorageBomList.length; i++) {
+                    if (inventoryTwo[formData.data.inOutStorageBomList[i].bomSpecId]) {
+                      formData.data.inOutStorageBomList[i].warehouseId = warehouseList.value[0].dictKey;
+                      formData.data.inOutStorageBomList[i].surplusStock = inventoryTwo[formData.data.inOutStorageBomList[i].bomSpecId];
+                    }
+                  }
+                });
+            }
+          });
+      }
+    }
+  });
+});
+const changeWarehouse = (val, item, index) => {
+  if (val) {
+    if (formData.data.departmentId) {
+      proxy
+        .post("/inventory/getQuantity", {
+          departmentId: formData.data.departmentId,
+          warehouseId: val,
+          bomSpecIdList: [item.bomSpecId],
+        })
+        .then((res) => {
+          if (res[item.bomSpecId]) {
+            formData.data.inOutStorageBomList[index].surplusStock = res[item.bomSpecId];
+          } else {
+            formData.data.inOutStorageBomList[index].surplusStock = 0;
+          }
+        });
+    } else {
+      return ElMessage("请先选择事业部");
+    }
+  } else {
+    formData.data.inOutStorageBomList[index].surplusStock = 0;
+  }
+};
+const changeDepartment = () => {
+  if (formData.data.inOutStorageBomList && formData.data.inOutStorageBomList.length > 0) {
+    formData.data.inOutStorageBomList = formData.data.inOutStorageBomList.map((item) => {
+      return {
+        ...item,
+        warehouseId: "",
+        surplusStock: 0,
+      };
+    });
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+:deep(.el-dialog) {
+  margin-top: 10px !important;
+  margin-bottom: 10px !important;
+}
+</style>