zhouqi пре 1 година
родитељ
комит
239afe9a17

+ 18 - 0
src/api/productionPlan/index.js

@@ -163,3 +163,21 @@ export async function homogeneityInspectMerge(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+// PBOM树
+export async function getBomRoot(data) {
+  const res = await request.post(`/aps/productionplan/getBomRoot`,  data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// PBOM 齐套性检查
+export async function pbomHomogeneityInspect(data) {
+  const res = await request.post(`/aps/productionplan/pbomHomogeneityInspect`,  data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 68 - 24
src/views/productionPlan/components/homogeneityInspectDialog.vue

@@ -1,32 +1,52 @@
 <template>
   <div>
   <ele-modal
-    width="80vw"
+    width="90vw"
     :visible.sync="visible"
     :close-on-click-modal="false"
     row-key="code"
     custom-class="ele-dialog-form"
     :title="'齐套性检查'"
+    :maxable="true"
   >
     <div class="form-wrapper">
       <div v-if="leftShow" :style="{width: leftWidth}">
-        <el-card class="box-card">
-<!--          <div v-for="o in 4" :key="o" class="text item">-->
-<!--            {{'列表内容 ' + o }}-->
-<!--          </div>-->
-        </el-card>
+        <el-tree :expand-on-click-node="false" :data="cardList" :props="treeProps" @node-click="handleNodeClick"></el-tree>
       </div>
       <div :style="{width: rightWidth}">
-        <div class="planInfo">
-          <div></div>
-          <div></div>
+        <div v-if="!leftShow" class="planInfo">
+          <el-row style="width: 100%;">
+            <el-col :span="planInfo.salesCode ? 6 : planInfo.salesCode.length * 6">
+              <div style="color: blue; display: flex;">
+                <div>销售单号:</div><div v-if="planInfo.salesCode"><span v-for="item in planInfo.salesCode"> {{item}}</span></div>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              计划编号:{{planInfo.code}}
+            </el-col>
+            <el-col :span="6">
+              批次号:{{planInfo.batchNo}}
+            </el-col>
+            <el-col :span="6">
+              名称:{{planInfo.productName}}
+            </el-col>
+            <el-col :span="6">
+              规格:{{planInfo.specification}}
+            </el-col>
+            <el-col :span="6">
+              型号:{{planInfo.model}}
+            </el-col>
+            <el-col :span="6">
+              计划数量:{{planInfo.productNum}}
+            </el-col>
+          </el-row>
         </div>
         <div>
           <ele-pro-table
             ref="table"
             :needPage="false"
             :columns="columns"
-            :key="activeName"
+            key="checkTable"
             :init-load="false"
             :datasource="datasource"
           >
@@ -199,19 +219,33 @@
         leftShow: false,
         leftWidth: '0%',
         rightWidth: '100%',
+        cardList: [],
+        treeProps: {
+          label: 'code',
+          children: 'children',
+        },
+        planInfo: {
+          salesCode: '',
+        },
       };
     },
     watch: {
       leftShow(newVal, oldVal){
         if(newVal){
-          this.leftWidth = '30%';
-          this.rightWidth = '70%';
+          this.leftWidth = '15%';
+          this.rightWidth = '85%';
+        } else {
+          this.leftWidth = '0%';
+          this.rightWidth = '100%';
         }
       }
     },
     mounted() {
     },
     methods: {
+      handleNodeClick(data){
+        this.reload({planIds: [data.id]});
+      },
       reload(where) {
         this.$nextTick(() => {
           this.$refs.table.reload({ page: 1, where });
@@ -233,11 +267,27 @@
        },
       open(dataList) {
          this.visible = true;
+         this.cardList = dataList || [];
+         for(let item of this.cardList){
+           let children = [];
+           if(item.salesCode){
+
+             for(let ele of item.salesCode){
+               children.push({code: ele, id: item.id});
+             }
+           }
+           item.children = children;
+         }
+         this.planInfo = dataList.length > 0 ? dataList[0] : null;
+         console.log(this.planInfo);
          if(dataList.length > 1){
            this.leftShow = true;
          } else {
            this.leftShow = false;
          }
+         if(this.planInfo){
+           this.reload({planIds: [this.planInfo.id]});
+         }
       },
       cancel() {
         this.formData = {};
@@ -248,20 +298,10 @@
         this.visible = false;
       },
       async merge(){
-        if(this.activeName == 'first'){
-          this.reload({planIds: this.ids, productType: 1, merge: 2});
-        }
-        if(this.activeName == 'second'){
-          this.reload({planIds: this.ids, productType: 2, merge: 2});
-        }
+        this.reload({planIds: this.ids, productType: 1, merge: 2});
       },
       tabClick(){
-        if(this.activeName == 'first'){
-          this.reload({planIds: this.ids, productType: 1});
-        }
-        if(this.activeName == 'second'){
-          this.reload({planIds: this.ids, productType: 2});
-        }
+        this.reload({planIds: this.ids, productType: 1});
       }
     }
   };
@@ -289,4 +329,8 @@
   .form-wrapper{
     display: flex;
   }
+  .planInfo{
+    display: flex;
+    font-size: 16px;
+  }
 </style>

+ 423 - 0
src/views/productionPlan/components/homogeneityInspectInstallDialog.vue

@@ -0,0 +1,423 @@
+<template>
+  <div>
+    <el-drawer
+      title="齐套性检查"
+      :visible.sync="visible"
+      direction="rtl"
+      :append-to-body="true"
+      size="100%"
+    >
+      <div class="form-wrapper">
+        <div style="width: 20%">
+          <el-card class="box-card">
+            <div class="ele-border-lighter sys-organization-list">
+              <el-radio-group
+                size="small"
+                v-model="currentNodeData.bomType"
+                @change="bomChange"
+              >
+                <el-radio-button :label="1">PBOM </el-radio-button>
+                <el-radio-button :label="3">ABOM </el-radio-button>
+              </el-radio-group>
+
+              <el-tree
+                class="treeData"
+                :data="treeList"
+                :expand-on-click-node="false"
+                :props="defaultProps"
+                ref="treeRef"
+                :default-expanded-keys="
+                  current && current.id ? [current.id] : []
+                "
+                :highlight-current="true"
+                node-key="id"
+                @node-click="handleNodeClick"
+              >
+                <span class="custom-tree-node" slot-scope="{ node, data }">
+                  {{ node.label }} / {{ data.code }}
+                </span>
+              </el-tree>
+            </div>
+          </el-card>
+        </div>
+        <div style="width: 80%">
+          <el-card class="box-card">
+            <ele-pro-table
+              ref="table"
+              :needPage="false"
+              :columns="columns"
+              :init-load="false"
+              :datasource="datasource"
+            >
+              <template v-slot:stockCount="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="stockDetail(row)"
+                >
+                  {{ row.stockCount }}
+                </el-link>
+              </template>
+              <template v-slot:currentCount="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="currentDetail(row)"
+                >
+                  {{ row.currentCount }}
+                </el-link>
+              </template>
+              <template v-slot:stockColor="{ row }">
+                <div :class="{ statusRed: row.stockStatus == '缺料' }">
+                  {{ row.stockStatus }}
+                </div>
+              </template>
+              <template v-slot:currentColor="{ row }">
+                <div :class="{ statusRed: row.currentStatus == '缺料' }">
+                  {{ row.currentStatus }}
+                </div>
+              </template>
+              <template v-slot:finishColor="{ row }">
+                <div :class="{ statusRed: row.finishStatus == '缺料' }">
+                  {{ row.finishStatus }}
+                </div>
+              </template>
+              <template v-slot:finishCount="{ row }">
+                <div>
+                  <div v-if="row.finishCount > 0">{{ row.finishCount }}</div>
+                  <div v-else>-</div>
+                </div>
+              </template>
+            </ele-pro-table>
+          </el-card>
+        </div>
+      </div>
+      <div slot="footer">
+        <el-button plain @click="cancel">取消</el-button>
+        <el-button type="primary" @click="confirm">确定</el-button>
+      </div>
+    </el-drawer>
+
+    <stockDetailDialog ref="stockDetailDialog" />
+
+    <currentDetailDialog ref="currentDetailDialog" />
+  </div>
+</template>
+
+<script>
+  import {
+    pbomHomogeneityInspect,
+    getBomRoot
+  } from '@/api/productionPlan/index.js';
+  import stockDetailDialog from './stockDetailDialog.vue';
+  import currentDetailDialog from './currentDetailDialog.vue';
+  export default {
+    components: {
+      stockDetailDialog,
+      currentDetailDialog
+    },
+    data() {
+      return {
+        visible: false,
+
+        isFullscreen: true,
+        formData: {},
+        requestData: {
+          deviceCode: '',
+          deviceName: '',
+          deviceId: ''
+        },
+        requiredFormingNum: 0,
+
+        // form: {
+        //   homogeneityInspect: []
+        // },
+
+        rules: {},
+
+        columns: [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'productCode',
+            label: '计划编号',
+            align: 'center',
+            minWidth: 100,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'opCode',
+            label: '工序编码',
+            align: 'center',
+            minWidth: 100,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'opName',
+            label: '工序名称',
+            align: 'center',
+            minWidth: 100
+          },
+          {
+            prop: 'bomCode',
+            label: '物料编码',
+            align: 'center',
+            minWidth: 100,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'bomName',
+            label: '物料名称',
+            align: 'center',
+            minWidth: 100
+          },
+          {
+            prop: 'count',
+            label: '定额数量',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'stockCount',
+            prop: 'stockCount',
+            label: '库存数量',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'stockColor',
+            prop: 'stockStatus',
+            label: '库存状态',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'currentCount',
+            prop: 'currentCount',
+            label: '在途数量',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'currentColor',
+            prop: 'currentStatus',
+            label: '在途状态',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'finishCount',
+            prop: 'finishCount',
+            label: '最终缺料数量',
+            align: 'center',
+            minWidth: 80
+          },
+          {
+            slot: 'finishColor',
+            prop: 'finishStatus',
+            label: '最终状态',
+            align: 'center',
+            minWidth: 80
+          }
+        ],
+        ids: [],
+        leftShow: true,
+        leftWidth: '0%',
+        rightWidth: '100%',
+
+        versList: [],
+        searchObj: {
+          versions: '',
+          categoryId: '',
+          isProduct: false,
+          isTemp: 0
+        },
+        current: {},
+        currentNodeData: {
+          bomType: 1,
+          children: []
+        },
+
+        treeId: '',
+        treeList: [],
+        defaultProps: {
+          children: 'children',
+          label: 'name'
+        },
+        planIds: [],
+      };
+    },
+    watch: {
+      leftShow(newVal, oldVal) {
+        if (newVal) {
+          this.leftWidth = '30%';
+          this.rightWidth = '70%';
+        }
+      }
+    },
+    mounted() {},
+    methods: {
+      reload(where) {
+        this.$nextTick(() => {
+          this.$refs.table.reload({ page: 1, where });
+        });
+      },
+      /* 表格数据源 */
+      datasource({ page, limit, where }) {
+        return pbomHomogeneityInspect({
+          pageNum: page,
+          size: limit,
+          ...where
+        });
+      },
+
+      stockDetail(row) {
+        this.$refs.stockDetailDialog.open(row);
+      },
+      currentDetail(row) {
+        this.$refs.currentDetailDialog.open(row);
+      },
+      async open(data) {
+        this.visible = true;
+        data.map(ele => {
+          this.planIds.push(ele.id);
+        });
+        this.treeList = [];
+        this.treeList = await getBomRoot({planIds: this.planIds, bomType: this.currentNodeData.bomType});
+        if(this.treeList && this.treeList.length > 0){
+          let bomIds = [];
+          this.getTreeIds(this.treeList[0], bomIds)
+          this.reload({bomIds: bomIds, planId: this.treeList[0].planId});
+        }
+
+      },
+      handleClose() {
+        this.searchObj = {
+          versions: '',
+          categoryId: '',
+          isProduct: false,
+          isTemp: 0
+        };
+        this.activeName = '属性';
+        this.drawer = false;
+      },
+
+      handleFull() {
+        this.isFullscreen = !this.isFullscreen;
+        this.$forceUpdate();
+      },
+      async bomChange(e) {
+        console.log(e, 'e');
+        this.searchObj.versions = '';
+        this.currentNodeData.bomType = e;
+        this.treeList = [];
+        this.treeList = await getBomRoot({planIds: this.planIds, bomType: this.currentNodeData.bomType});
+        if(this.treeList && this.treeList.length > 0){
+          let bomIds = [];
+          this.getTreeIds(this.treeList[0], bomIds)
+          this.reload({bomIds: bomIds, planId: this.treeList[0].planId});
+        }
+      },
+      handleNodeClick(data) {
+        this.treeId = data.id;
+        let bomIds = [];
+        this.getTreeIds(data, bomIds);
+        this.reload({bomIds: bomIds, planId: data.planId})
+      },
+      cancel() {
+        this.formData = {};
+        this.visible = false;
+      },
+
+      confirm() {
+        this.visible = false;
+      },
+      getTreeIds(tree, list){
+        if(tree){
+          if(tree.id){
+            list.push(tree.id);
+          }
+          if(tree.children && tree.children.length > 0){
+            for(let item of tree.children){
+              this.getTreeIds(item, list);
+            }
+          }
+        }
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .mt20 {
+    margin-top: 20px;
+  }
+
+  .el-form-item {
+    margin-bottom: 0 !important;
+  }
+  .optionButton {
+    display: flex;
+    justify-content: flex-end;
+    padding-bottom: 3px;
+  }
+  .statusRed {
+    color: red;
+  }
+  .form-wrapper {
+    display: flex;
+  }
+  /* 自定义全屏样式 */
+  ::v-deep .is-fullscreen {
+    width: 100vw !important;
+    height: 100vh !important;
+    overflow: hidden !important; /* 隐藏滚动条 */
+  }
+  ::v-deep .not-fullscreen {
+    width: calc(100vw - 260px) !important;
+    height: 100vh !important;
+    overflow: hidden !important; /* 隐藏滚动条 */
+  }
+
+  .custom-drawer-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 4px 15px;
+    background-color: #f5f7fa; /* 自定义背景色 */
+    border-bottom: 1px solid #ebeef5; /* 自定义边框,与抽屉内容分隔 */
+  }
+
+  .drawer_content {
+    margin: 10px 20px;
+    box-sizing: border-box;
+  }
+  .sys-organization-list {
+    height: calc(100vh - 100px);
+    box-sizing: border-box;
+    border-width: 1px;
+    border-style: solid;
+    overflow: auto;
+    padding: 10px;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .treeData {
+      height: 0 1 auto;
+      overflow-y: auto;
+      height: calc(100vh - 125px);
+    }
+  }
+
+  .tab-box {
+    margin-top: 12px;
+  }
+</style>

+ 1 - 1
src/views/productionPlan/components/productionPlan-search.vue

@@ -186,7 +186,7 @@
           <el-select
                   size="mini"
                   clearable
-                  v-model="where.productType"
+                  v-model="where.produceType"
                   placeholder="请选择"
                   class="w100"
           >

+ 14 - 2
src/views/productionPlan/index.vue

@@ -204,6 +204,7 @@
     <unpackDetails ref="DetailsRef"></unpackDetails>
 
     <homogeneityInspectDialog ref="homogeneityInspectDialog" @success="reload" />
+    <homogeneityInspectInstallDialog ref="homogeneityInspectInstallDialog" @success="reload" />
 
     <disassemblePlanPop
       ref="disassemblePlanRef"
@@ -225,6 +226,7 @@
   import unpackDialog from './components/unpackDialog.vue';
   import mergeDialog from './components/mergeDialog.vue';
   import homogeneityInspectDialog from './components/homogeneityInspectDialog.vue';
+  import homogeneityInspectInstallDialog from './components/homogeneityInspectInstallDialog.vue';
   import unpackDetails from './components/unpackDetails.vue';
   import disassemblePlanPop from './components/disassemblePlanPop.vue';
   import factoryAdd from './components/factoryAdd/index.vue';
@@ -240,7 +242,8 @@
       unpackDetails,
       disassemblePlanPop,
       factoryAdd,
-      homogeneityInspectDialog
+      homogeneityInspectDialog,
+      homogeneityInspectInstallDialog,
     },
     props: {
       timeDimensionPlanType: { type: Number, default: 1 }
@@ -610,7 +613,9 @@
           return;
         }
         let flag = false;
+        let type = 0;
         for(let item of this.selection){
+          type = item.produceType;
           for(let ele of this.selection){
             if(item.produceType != ele.produceType){
               flag = true;
@@ -622,7 +627,14 @@
           this.$message.warning('请选择加工方式相同的计划!');
           return;
         }
-        this.$refs.homogeneityInspectDialog.open(this.selection);
+        console.log(type);
+        if(type == 2){
+          this.$refs.homogeneityInspectDialog.open(this.selection);
+        } else if(type == 3){
+          this.$refs.homogeneityInspectInstallDialog.open(this.selection);
+        } else {
+          this.$message.warning('请确认加工方式!');
+        }
       },
       statusFormatter(status) {
         const obj = this.statusOpt[this.activeName].find(