quwangxin 2 lat temu
rodzic
commit
1f48386f93

+ 43 - 0
src/api/material/BOM.js

@@ -0,0 +1,43 @@
+import request from '@/utils/request';
+
+// 分页
+export async function getPage (params) {
+  const res = await request.get(`/main/bom/page`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 保存
+export async function bomSave (pid) {
+  const res = await request.post(`/main/bom/save`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 详情
+export async function getById (id) {
+  const res = await request.get(`/main/bom/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 删除
+export async function bomDelete (pid) {
+  const res = await request.get(`/main/bom/delete`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 详情分页
+export async function detailPage (pid) {
+  const res = await request.get(`/main/bom/detail/page`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 6 - 3
src/api/system/file/index.js

@@ -21,7 +21,10 @@ export async function uploadFile (data) {
  */
 export async function uploadBatch (data) {
   const formData = new FormData();
-  formData.append('multiPartFiles', data.multiPartFiles);
+  data.multiPartFiles.forEach((item, index) => {
+    formData.append(`multiPartFiles`, item);
+  });
+
   const res = await request.post(
     `/main/file/uploadBatch?module=${data.module}`,
     formData
@@ -35,13 +38,13 @@ export async function uploadBatch (data) {
 /**
  * 获取文件
  */
-export async function getFile (params) {
+export async function getFile (params, fileName) {
   const res = await request.get('/main/file/getFile', {
     params,
     responseType: 'blob'
   });
   const arr = params.objectName.split('/');
-  download(res.data, arr[arr.length - 1]);
+  download(res.data, fileName || arr[arr.length - 1]);
   // if (res.data.code === '0') {
   //   return res.data.data;
   // }

+ 73 - 0
src/components/CommomSelect/category-group-select.vue

@@ -0,0 +1,73 @@
+<template>
+  <el-select
+    v-model="selectVal"
+    filterable
+    style="width: 100%"
+    v-bind="$attrs"
+    v-on="$listeners"
+    clearable
+  >
+    <el-option
+      v-for="item in dictList"
+      :key="item.id"
+      :value="item.id"
+      :label="item.name"
+    ></el-option>
+  </el-select>
+</template>
+
+<script>
+  import { getGroupPage } from '@/api/material/list';
+  export default {
+    model: {
+      prop: 'value',
+      event: 'updateVal'
+    },
+    props: {
+      value: {
+        type: [String, Number, Array],
+        default: ''
+      },
+      init: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data () {
+      return {
+        dictList: []
+      };
+    },
+    computed: {
+      selectVal: {
+        set (val) {
+          this.$emit(
+            'selfChange',
+            val,
+            this.dictList.find((i) => i.id === val)
+          );
+          this.$emit('updateVal', val);
+        },
+        get () {
+          return this.value;
+        }
+      }
+    },
+    created () {
+      if (this.init) {
+        this.getList();
+      }
+    },
+    methods: {
+      async getList (params) {
+        let data = { pageNum: 1, size: -1 };
+        // 如果传了参数就是获取巡点检人员数据
+        if (params) {
+          data = Object.assign(data, params);
+        }
+        const res = await getGroupPage(data);
+        this.dictList = res.list;
+      }
+    }
+  };
+</script>

+ 1 - 1
src/components/CommomSelect/category-select.vue

@@ -1,4 +1,4 @@
-<!-- 部门树形选择下拉框 -->
+<!-- 分类树形选择下拉框 -->
 <template>
   <ele-tree-select
     clearable

+ 2 - 2
src/components/CommomSelect/dept-select.vue

@@ -35,8 +35,8 @@
       this.getData();
     },
     methods: {
-      async getData (parmas = {}) {
-        const data = await listOrganizations(parmas);
+      async getData (params = {}) {
+        const data = await listOrganizations(params);
         this.treeData = this.$util.toTreeData({
           data: data || [],
           idField: 'id',

+ 72 - 0
src/components/CommomSelect/factory-select.vue

@@ -0,0 +1,72 @@
+<template>
+  <el-select
+    v-model="selectVal"
+    filterable
+    style="width: 100%"
+    v-bind="$attrs"
+    v-on="$listeners"
+    clearable
+  >
+    <el-option
+      v-for="item in dictList"
+      :key="item.id"
+      :label="item.name"
+      :value="item.id"
+    ></el-option>
+  </el-select>
+</template>
+
+<script>
+  import route from '@/api/technology/route';
+  export default {
+    model: {
+      prop: 'value',
+      event: 'updateVal'
+    },
+    props: {
+      value: {
+        type: [String, Number, Array],
+        default: ''
+      },
+      init: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data () {
+      return {
+        dictList: []
+      };
+    },
+    computed: {
+      selectVal: {
+        set (val) {
+          this.$emit(
+            'selfChange',
+            val,
+            this.dictList.find((i) => i.id === val)
+          );
+          this.$emit('updateVal', val);
+        },
+        get () {
+          return this.value;
+        }
+      }
+    },
+    created () {
+      if (this.init) {
+        this.getList();
+      }
+    },
+    methods: {
+      async getList () {
+        const res = await route.Flist({
+          pageNum: 1,
+          size: -1,
+          type: 1
+        });
+        this.dictList = res.list;
+      }
+    }
+  };
+</script>

+ 229 - 0
src/components/SelectDialog/materialDialog.vue

@@ -0,0 +1,229 @@
+<template>
+  <el-dialog
+    title="选择物料"
+    :visible.sync="groupVisible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="60%"
+  >
+    <div>
+      <el-form label-width="80px">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="分类" prop="categoryLevelGroupId">
+              <categoryGroupSelect v-model="searchForm.categoryLevelGroupId" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="searchForm.code"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="名称" prop="name">
+              <el-input v-model="searchForm.name"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="牌号" prop="brandNum">
+              <el-input v-model="searchForm.brandNum"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="型号" prop="modelType">
+              <el-input v-model="searchForm.modelType"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <div class="ele-form-actions">
+              <el-button icon="icon-reset" @click="handleReset">重置</el-button>
+              <el-button
+                type="primary"
+                icon="el-icon-search"
+                @click="handleSearch"
+                >搜索</el-button
+              >
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div class="table_col">
+        <el-table
+          :data="tableData"
+          height="450"
+          ref="tableRef"
+          highlight-current-row
+          @row-click="single"
+        >
+          <el-table-column label="编码" prop="code"></el-table-column>
+          <el-table-column
+            label="名称"
+            prop="name"
+            width="200"
+          ></el-table-column>
+          <el-table-column
+            label="牌号"
+            prop="brandNum"
+            width="200"
+          ></el-table-column>
+          <el-table-column
+            label="型号"
+            prop="modelType"
+            width="200"
+          ></el-table-column>
+          <el-table-column label="分类树" prop="categoryLevelPath">
+            <template slot-scope="scope">
+              {{ scope.row.categoryLevelPath + '分类' }}
+            </template>
+          </el-table-column>
+          <el-table-column label="选择" align="center">
+            <template slot-scope="scope">
+              <el-radio class="radio" v-model="radio" :label="scope.row.id"
+                ><i></i
+              ></el-radio>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="pagination">
+          <el-pagination
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.size"
+            :current-page.sync="pagination.pageNum"
+            @current-change="handleCurrent"
+            @size-change="handleSize"
+          >
+          </el-pagination> </div
+      ></div>
+    </div>
+    <div class="btns">
+      <el-button type="primary" size="small" @click="selected">选择</el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import { getMaterialList } from '@/api/material/manage.js';
+  import categoryGroupSelect from '@/components/CommomSelect/category-group-select';
+  const defaultWhere = {
+    brandNum: null,
+    modelType: null,
+    name: null,
+    code: null,
+    categoryLevelGroupId: null
+  };
+  export default {
+    components: { categoryGroupSelect },
+    data () {
+      return {
+        groupVisible: false,
+        tableData: [],
+        searchForm: { ...defaultWhere },
+        pagination: {
+          pageNum: 1,
+          size: 10
+        },
+        total: 0,
+        radio: '',
+        current: null,
+        callBack: null
+      };
+    },
+
+    watch: {},
+    methods: {
+      open (item, callBack) {
+        this.callBack = callBack;
+        if (item) {
+          this.current = item;
+          this.radio = item.categoryId || item.id;
+        }
+        this.groupVisible = true;
+        this.getList();
+      },
+      handleSearch () {
+        this.pagination.pageNum = 1;
+        this.getList();
+      },
+      handleReset () {
+        this.searchForm = { ...defaultWhere };
+        this.handleSearch();
+      },
+
+      // 单击获取id
+      single (row) {
+        this.current = row;
+        this.radio = row.id;
+      },
+
+      handleClose () {
+        this.groupVisible = false;
+        this.current = null;
+        this.radio = '';
+      },
+      handleCurrent (page) {
+        this.pagination.pageNum = page;
+        this.getList();
+      },
+      handleSize (size) {
+        this.pagination.pageNum = 1;
+        this.pagination.size = size;
+        this.getList();
+      },
+      getList () {
+        let params = { ...this.pagination, ...this.searchForm };
+        getMaterialList(params).then((res) => {
+          this.tableData = res.list;
+          this.total = res.count;
+          this.$nextTick(() => {
+            this.tableData.find((i) => {
+              if (i.id === this.current?.categoryId) {
+                this.$refs.tableRef.setCurrentRow(i);
+              }
+            });
+          });
+        });
+      },
+      selected () {
+        if (!this.current) {
+          return this.$message.warning('请选择物料组');
+        }
+        this.callBack && this.callBack(this.current);
+        this.$emit('changeMaterial', this.current);
+        this.handleClose();
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .tree_col {
+    border: 1px solid #eee;
+    padding: 10px 0;
+    box-sizing: border-box;
+    height: 500px;
+    overflow: auto;
+  }
+  .table_col {
+    padding-left: 10px;
+    ::v-deep .el-table th.el-table__cell {
+      background: #f2f2f2;
+    }
+  }
+  .pagination {
+    text-align: right;
+    padding: 10px 0;
+  }
+  .btns {
+    text-align: center;
+    padding: 10px 0;
+  }
+  .topsearch {
+    margin-bottom: 15px;
+  }
+</style>

+ 224 - 0
src/components/SelectDialog/productDialog.vue

@@ -0,0 +1,224 @@
+<template>
+  <el-dialog
+    title="选择产品"
+    :visible.sync="groupVisible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="60%"
+  >
+    <div>
+      <el-form label-width="80px">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="分类" prop="categoryLevelId">
+              <categorySelect v-model="searchForm.categoryLevelId" pid="9" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="编码" prop="code">
+              <el-input v-model="searchForm.code"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="名称" prop="name">
+              <el-input v-model="searchForm.name"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="牌号" prop="brandNum">
+              <el-input v-model="searchForm.brandNum"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="型号" prop="modelType">
+              <el-input v-model="searchForm.modelType"></el-input
+            ></el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <div class="ele-form-actions">
+              <el-button icon="icon-reset" @click="handleReset">重置</el-button>
+              <el-button
+                type="primary"
+                icon="el-icon-search"
+                @click="handleSearch"
+                >搜索</el-button
+              >
+            </div>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div class="table_col">
+        <el-table
+          :data="tableData"
+          height="450"
+          ref="tableRef"
+          highlight-current-row
+          @row-click="single"
+        >
+          <el-table-column label="编码" prop="code"></el-table-column>
+          <el-table-column
+            label="名称"
+            prop="name"
+            width="200"
+          ></el-table-column>
+          <el-table-column
+            label="牌号"
+            prop="brandNum"
+            width="200"
+          ></el-table-column>
+          <el-table-column
+            label="型号"
+            prop="modelType"
+            width="200"
+          ></el-table-column>
+          <el-table-column label="选择" align="center">
+            <template slot-scope="scope">
+              <el-radio class="radio" v-model="radio" :label="scope.row.id"
+                ><i></i
+              ></el-radio>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="pagination">
+          <el-pagination
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+            :page-sizes="[10, 20, 50, 100]"
+            :page-size="pagination.size"
+            :current-page.sync="pagination.pageNum"
+            @current-change="handleCurrent"
+            @size-change="handleSize"
+          >
+          </el-pagination> </div
+      ></div>
+    </div>
+    <div class="btns">
+      <el-button type="primary" size="small" @click="selected">选择</el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import { getList } from '@/api/classifyManage/itemInformation';
+  import categorySelect from '@/components/CommomSelect/category-select';
+  const defaultWhere = {
+    brandNum: null,
+    modelType: null,
+    name: null,
+    code: null,
+    categoryLevelId: '9'
+  };
+  export default {
+    components: { categorySelect },
+    data () {
+      return {
+        groupVisible: false,
+        tableData: [],
+        searchForm: { ...defaultWhere },
+        pagination: {
+          pageNum: 1,
+          size: 10
+        },
+        total: 0,
+        radio: '',
+        current: null,
+        callBack: null
+      };
+    },
+
+    watch: {},
+    methods: {
+      open (item, callBack) {
+        this.callBack = callBack;
+        if (item) {
+          this.current = item;
+          this.radio = item.categoryId || item.id;
+        }
+        this.groupVisible = true;
+        this.getList();
+      },
+      handleSearch () {
+        this.pagination.pageNum = 1;
+        this.getList();
+      },
+      handleReset () {
+        this.searchForm = { ...defaultWhere };
+        this.handleSearch();
+      },
+
+      // 单击获取id
+      single (row) {
+        this.current = row;
+        this.radio = row.id;
+      },
+
+      handleClose () {
+        this.groupVisible = false;
+        this.current = null;
+        this.radio = '';
+      },
+      handleCurrent (page) {
+        this.pagination.pageNum = page;
+        this.getList();
+      },
+      handleSize (size) {
+        this.pagination.pageNum = 1;
+        this.pagination.size = size;
+        this.getList();
+      },
+      getList () {
+        let params = { ...this.pagination, ...this.searchForm };
+        getList(params).then((res) => {
+          this.tableData = res.list;
+          this.total = res.count;
+          this.$nextTick(() => {
+            this.tableData.find((i) => {
+              if (i.id === this.current?.categoryId) {
+                this.$refs.tableRef.setCurrentRow(i);
+              }
+            });
+          });
+        });
+      },
+      selected () {
+        if (!this.current) {
+          return this.$message.warning('请选择物料组');
+        }
+        this.callBack && this.callBack(this.current);
+        this.$emit('changeMaterial', this.current);
+        this.handleClose();
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .tree_col {
+    border: 1px solid #eee;
+    padding: 10px 0;
+    box-sizing: border-box;
+    height: 500px;
+    overflow: auto;
+  }
+  .table_col {
+    padding-left: 10px;
+    ::v-deep .el-table th.el-table__cell {
+      background: #f2f2f2;
+    }
+  }
+  .pagination {
+    text-align: right;
+    padding: 10px 0;
+  }
+  .btns {
+    text-align: center;
+    padding: 10px 0;
+  }
+  .topsearch {
+    margin-bottom: 15px;
+  }
+</style>

+ 2 - 1
src/enum/dict.js

@@ -24,5 +24,6 @@ export default {
   提前期单位: 'leadtime_unit',
   价格单位: 'price_unit',
   检验方案: 'inspection_scheme',
-  文件模块: 'file_module'
+  文件模块: 'file_module',
+  分类层级: 'bom_level'
 };

+ 9 - 11
src/views/documentManagement/docManagement/components/upload-dialog.vue

@@ -1,6 +1,6 @@
 <template>
   <!-- 上传 -->
-  <el-dialog title="文件上传" :visible.sync="uploadShow" width="40%">
+  <el-dialog title="文件上传" :visible.sync="dialogVisible" width="40%">
     <el-form label-width="110px" class="zw-criterion">
       <el-form-item label="选择文件">
         <el-upload
@@ -16,7 +16,7 @@
         </el-upload>
       </el-form-item>
       <el-form-item label="模块名">
-        <DictSelection v-model="module"></DictSelection>
+        <DictSelection v-model="module" dictName="文件模块"></DictSelection>
       </el-form-item>
       <el-form-item label="">
         <div class="imgs-box">
@@ -28,7 +28,7 @@
       </el-form-item>
     </el-form>
     <div slot="footer" class="dialog-footer">
-      <el-button size="small" @click="uploadShow = false">关 闭</el-button>
+      <el-button size="small" @click="dialogVisible = false">关 闭</el-button>
       <el-button size="small" @click="upload" type="primary">上 传</el-button>
     </div>
   </el-dialog>
@@ -74,22 +74,20 @@
         this.attaments.push(param.file);
       },
       // 文件上传
-      upload () {
+      async upload () {
         if (this.attaments.length == 0) {
           return this.$message.warning('文件不能为空!');
         }
         if (!this.module) {
           return this.$message.warning('模块名不能为空!');
         }
-        let res = uploadBatch({
+        await uploadBatch({
           module: this.module,
-          multiPartFiles: this.attaments.map((i) => i.file)
+          multiPartFiles: this.attaments
         });
-        if (res.success) {
-          this.$message.success('操作成功!');
-          this.uploadShow = false;
-          this.handleList(this.searchForm);
-        }
+        this.$message.success('操作成功!');
+        this.dialogVisible = false;
+        this.$emit('success');
       }
     }
   };

+ 3 - 3
src/views/documentManagement/docManagement/index.vue

@@ -19,7 +19,7 @@
         </template>
       </ele-pro-table>
     </el-card>
-    <uploadDialog ref="uploadDialogRef" />
+    <uploadDialog ref="uploadDialogRef" @success="reload" />
   </div>
 </template>
 
@@ -82,14 +82,14 @@
           size: limit
         });
       },
-      reload (where) {
+      reload (where = {}) {
         this.$refs.table.reload({ where });
       },
       handleUpload () {
         this.$refs.uploadDialogRef.open();
       },
       handleDownload (row) {
-        getFile({ objectName: row.storePath });
+        getFile({ objectName: row.storePath }, row.name);
       }
     }
   };

+ 30 - 18
src/views/material/materialBOM/components/BOM-search.vue

@@ -19,25 +19,40 @@
       </el-col>
       <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
         <el-form-item label="产品编码">
-          <el-input clearable v-model="where.code" placeholder="请输入" />
+          <el-input
+            clearable
+            v-model="where.categoryCode"
+            placeholder="请输入"
+          />
         </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
         <el-form-item label="产品名称">
-          <el-input clearable v-model="where.name" placeholder="请输入" />
-        </el-form-item>
-      </el-col>
-      <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
-        <el-form-item label="生产版本">
-          <el-input clearable v-model="where.name" placeholder="请输入" />
+          <el-input
+            clearable
+            v-model="where.categoryName"
+            placeholder="请输入"
+          />
         </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { md: 6 } : { span: 6 }">
         <el-form-item label="状态">
-          <el-input clearable v-model="where.name" placeholder="请输入" />
+          <el-select
+            clearable
+            v-model="where.status"
+            placeholder="请选择"
+            class="w100"
+          >
+            <el-option
+              v-for="item in Object.entries(statusOpt)"
+              :key="item[0]"
+              :label="item[1]"
+              :value="item[0]"
+            ></el-option>
+          </el-select>
         </el-form-item>
       </el-col>
-      <el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
+      <el-col v-bind="styleResponsive ? { md: 18 } : { span: 18 }">
         <div class="ele-form-actions">
           <el-button
             type="primary"
@@ -59,19 +74,19 @@
 
 <script>
   export default {
+    props: {
+      statusOpt: Object
+    },
     data () {
       // 默认表单数据
       const defaultWhere = {
         name: '',
         code: '',
-        appType: ''
+        categoryCode: '',
+        categoryName: '',
+        status: ''
       };
       return {
-        options: [
-          { value: 0, label: '全部' },
-          { value: 1, label: '业务字典' },
-          { value: 2, label: '数据字典' }
-        ],
         defaultWhere,
         // 表单数据
         where: { ...defaultWhere }
@@ -86,9 +101,6 @@
     methods: {
       /* 搜索 */
       search () {
-        if (this.where.appType === 0) {
-          this.where.appType = '';
-        }
         this.$emit('search', this.where);
       },
       /*  重置 */

+ 181 - 35
src/views/material/materialBOM/components/edit-dialog.vue

@@ -4,48 +4,84 @@
     <el-form label-width="100px">
       <el-row>
         <el-col :span="8">
-          <el-form-item label="BOM编码">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="BOM编码" prop="code">
+            <el-input
+              placeholder="自动生成"
+              disabled
+              v-model="formData.code"
+            ></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="BOM名称">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="BOM名称" prop="name">
+            <el-input placeholder="请输入" v-model="formData.name"></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="所属工厂">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="所属工厂" prop="factoryId">
+            <factorySelect v-model="formData.factoryId" />
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="产品编码">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="产品编码" prop="categoryCode">
+            <el-input
+              placeholder="请输入"
+              v-model="formData.categoryCode"
+              @click.native="selectProd"
+            ></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="产品名称">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="产品名称" prop="categoryName">
+            <el-input
+              placeholder="请选择"
+              disabled
+              v-model="formData.categoryName"
+            ></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="版本号">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="分类层级" prop="categoryType">
+            <el-input
+              placeholder="请输入"
+              v-model="formData.categoryType"
+            ></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="分类层级">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="基本数量" prop="baseCount">
+            <el-row>
+              <el-col :span="16">
+                <el-input
+                  placeholder="请输入"
+                  v-model.number="formData.baseCount"
+                >
+                </el-input
+              ></el-col>
+              <el-col :span="8"
+                ><DictSelection
+                  dictName="计量单位"
+                  v-model="formData.baseCountUnit"
+              /></el-col>
+            </el-row>
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="基本数量">
-            <el-input placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="状态">
-            <el-input placeholder="请输入"></el-input>
+          <el-form-item label="状态" prop="status">
+            <el-select
+              :disabled="title == '新建'"
+              clearable
+              v-model="formData.status"
+              placeholder="请选择"
+              class="w100"
+            >
+              <el-option
+                v-for="item in Object.entries(statusOpt)"
+                :key="item[0]"
+                :label="item[1]"
+                :value="item[0]"
+              ></el-option>
+            </el-select>
           </el-form-item>
         </el-col>
       </el-row>
@@ -53,16 +89,42 @@
     <ele-pro-table
       ref="table"
       :columns="columns"
-      :datasource="datasource"
+      :datasource="tableData"
       height="calc(100vh - 350px)"
       :need-page="false"
     >
       <!-- 表头工具栏 -->
       <template v-slot:toolbar>
-        <el-button type="primary">添加</el-button>
+        <el-button type="primary" @click="add">添加</el-button>
+      </template>
+      <template v-slot:action="{ $index }">
+        <el-link type="primary" @click="handleDel($index)">删除</el-link>
+      </template>
+      <template v-slot:subCode="{ row }">
+        <el-input v-model="row.subCode" placeholder="请输入"></el-input>
       </template>
-      <template v-slot:action>
-        <el-link type="primary">删除</el-link>
+      <template v-slot:unit="{ row }">
+        <DictSelection dictName="计量单位" v-model="row.unit"></DictSelection>
+      </template>
+      <template v-slot:count="{ row }">
+        <el-input
+          v-model="row.count"
+          placeholder="请输入"
+          @input="
+            (value) =>
+              (row.count = value.replace(
+                /^(-)*(\d+)\.(\d\d\d\d\d\d).*$/,
+                '$1$2.$3'
+              ))
+          "
+        ></el-input>
+      </template>
+      <template v-slot:categoryName="{ row }">
+        <el-input
+          :value="row.categoryName"
+          placeholder="请选择"
+          @click.native="categorySelect(row)"
+        ></el-input>
       </template>
     </ele-pro-table>
 
@@ -71,16 +133,39 @@
       <el-button type="primary" @click="save">发布</el-button>
       <el-button @click="cancel">返回</el-button>
     </div>
+    <materialDialog ref="materialDialogRef" />
+    <productDialog ref="productDialogRef" />
   </ele-modal>
 </template>
 
 <script>
+  import materialDialog from '@/components/SelectDialog/materialDialog';
+  import productDialog from '@/components/SelectDialog/productDialog';
+  import factorySelect from '@/components/CommomSelect/factory-select.vue';
+  import { getCode } from '@/api/codeManagement/index.js';
   export default {
+    components: { materialDialog, factorySelect, productDialog },
+    props: {
+      statusOpt: Object
+    },
     data () {
       return {
         visible: false,
         title: '',
         row: {},
+        formData: {
+          code: '',
+          name: '',
+          factoryId: '',
+          categoryCode: '',
+          categoryId: '',
+          categoryName: '',
+          categoryType: '',
+          baseCount: '',
+          baseCountUnit: '',
+          status: '-1'
+        },
+        tableData: [],
         columns: [
           {
             type: 'index',
@@ -88,22 +173,38 @@
             align: 'center'
           },
           {
-            label: '物料名称'
+            label: '子项编号',
+            prop: 'subCode',
+            slot: 'subCode',
+            action: 'subCode'
+          },
+          {
+            label: '物料名称',
+            prop: 'categoryName',
+            slot: 'categoryName',
+            action: 'categoryName'
           },
           {
-            label: '物料编码'
+            label: '物料编码',
+            prop: 'categoryId'
           },
           {
-            label: '牌号'
+            label: '牌号',
+            prop: 'brandNum'
           },
           {
-            label: '型号'
+            label: '型号',
+            prop: 'modelType'
           },
           {
-            label: '需量(子)'
+            label: '需量(子)',
+            slot: 'count',
+            action: 'count'
           },
           {
-            label: '单位'
+            label: '单位',
+            slot: 'unit',
+            action: 'unit'
           },
           {
             action: 'action',
@@ -118,12 +219,57 @@
         this.title = type;
         this.row = row;
         this.visible = true;
+        if (type == '新建') {
+          this._getCode();
+        }
+      },
+      add () {
+        let subCode = '0010';
+        if (this.tableData.length) {
+          let max = Math.max(...this.tableData.map((i) => i.subCode)) + 10 + '';
+
+          if (max.length < 4) {
+            max = new Array(4 - max.length).fill('0').join('') + max;
+          }
+          subCode = max.substring(0, max.length - 1) + '0';
+        }
+
+        this.tableData.push({
+          subCode,
+          categoryId: '',
+          categoryName: '',
+          brandNum: '',
+          count: '',
+          modelType: '',
+          unit: ''
+        });
+      },
+      async _getCode () {
+        const code = await getCode('bom_code');
+        this.formData.code = code;
+      },
+      selectProd () {
+        this.$refs.productDialogRef.open(this.formData, (res) => {
+          this.formData.categoryCode = res.code;
+          this.formData.categoryId = res.id;
+          this.formData.categoryName = res.name;
+          console.log(res);
+        });
+      },
+      categorySelect (row) {
+        this.$refs.materialDialogRef.open(row, (res) => {
+          row.categoryName = res.name;
+          row.categoryId = res.id;
+          row.unit = res.measuringUnit;
+          row.modelType = res.modelType;
+          row.brandNum = res.brandNum;
+        });
       },
       save () {},
-      cancel () {},
-      datasource () {
-        return Promise.resolve([]);
-      }
+      handleDel (index) {
+        this.tableData.splice(index, 1);
+      },
+      cancel () {}
     }
   };
 </script>

+ 156 - 0
src/views/material/materialBOM/components/view-dialog.vue

@@ -0,0 +1,156 @@
+<template>
+  <ele-modal
+    :visible.sync="visible"
+    title="BOM详情"
+    width="80%"
+    @close="cancel"
+  >
+    <headerTitle title="基本信息"></headerTitle>
+    <el-form label-width="100px">
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="BOM编码" prop="code">
+            {{ formData.code }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="BOM名称" prop="name">
+            {{ formData.name }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="所属工厂" prop="factoryId">
+            {{ formData.factoryName }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="产品编码" prop="categoryCode">
+            {{ formData.categoryCode }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="产品名称" prop="categoryName">
+            {{ formData.categoryName }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="分类层级" prop="categoryType">
+            {{ formData.categoryType }}
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          {{ formData.baseCount }}
+          {{ formData.baseCountUnit }}
+        </el-col>
+        <el-col :span="8">
+          {{ statusOpt[formData.status] }}
+        </el-col>
+      </el-row>
+    </el-form>
+    <ele-pro-table
+      ref="table"
+      :columns="columns"
+      :datasource="datasource"
+      height="calc(100vh - 350px)"
+      :initLoad="false"
+    >
+    </ele-pro-table>
+
+    <div slot="footer" class="footer">
+      <el-button @click="cancel">返回</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import factorySelect from '@/components/CommomSelect/factory-select.vue';
+  import { getById, detailPage } from '@/api/material/BOM';
+  export default {
+    components: { factorySelect },
+    props: {
+      statusOpt: Object
+    },
+    data () {
+      return {
+        visible: false,
+        row: {},
+        formData: {
+          code: '',
+          name: '',
+          factoryId: '',
+          categoryCode: '',
+          categoryId: '',
+          categoryName: '',
+          categoryType: '',
+          baseCount: '',
+          baseCountUnit: '',
+          status: '-1'
+        },
+        columns: [
+          {
+            type: 'index',
+            width: 55,
+            align: 'center'
+          },
+          {
+            label: '子项编号',
+            prop: 'subCode',
+            slot: 'subCode',
+            action: 'subCode'
+          },
+          {
+            label: '物料名称',
+            prop: 'categoryName',
+            slot: 'categoryName',
+            action: 'categoryName'
+          },
+          {
+            label: '物料编码',
+            prop: 'categoryId'
+          },
+          {
+            label: '牌号',
+            prop: 'brandNum'
+          },
+          {
+            label: '型号',
+            prop: 'modelType'
+          },
+          {
+            label: '需量(子)',
+            slot: 'count',
+            action: 'count'
+          },
+          {
+            label: '单位',
+            slot: 'unit',
+            action: 'unit'
+          },
+          {
+            action: 'action',
+            slot: 'action',
+            label: '操作'
+          }
+        ]
+      };
+    },
+    methods: {
+      open (row) {
+        this.visible = true;
+        this._getById(row.id);
+        this.$refs.table.reload({ bomId: row.id });
+      },
+      async _getById (id) {
+        const res = await getById(id);
+        this.formData = res.data;
+      },
+      datasource ({ page, limit, where }) {
+        return detailPage({
+          pageNum: page,
+          size: limit,
+          ...where
+        });
+      }
+    }
+  };
+</script>

+ 35 - 31
src/views/material/materialBOM/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="ele-body">
     <el-card shadow="never">
-      <BOMSearch @search="reload" />
+      <BOMSearch @search="reload" :statusOpt="statusOpt" />
       <ele-pro-table
         ref="table"
         :columns="columns"
@@ -10,7 +10,7 @@
         tool-class="ele-toolbar-actions"
       >
         <!-- 表头工具栏 -->
-        <template v-slot:toolbar>
+        <!-- <template v-slot:toolbar>
           <el-button type="primary" @click="handelEdit('新建')">新建</el-button>
           <el-button type="primary">复制</el-button>
         </template>
@@ -18,19 +18,18 @@
           <el-link type="primary" @click="handelEdit('编辑', row)"
             >编辑</el-link
           >
-          <!-- <el-link>查看历史版本</el-link> -->
-          <el-link type="primary">删除</el-link>
-        </template>
+          <el-link type="primary">删除</el-link> 
+        </template>-->
       </ele-pro-table>
     </el-card>
-    <EditDialog ref="editDialogRef" />
+    <EditDialog ref="editDialogRef" :statusOpt="statusOpt" />
   </div>
 </template>
 
 <script>
   import BOMSearch from './components/BOM-search.vue';
   import EditDialog from './components/edit-dialog.vue';
-  import { listDictionaries, removeDictionary } from '@/api/system/dictionary';
+  import { getPage } from '@/api/material/BOM';
 
   export default {
     name: 'SystemDictionary',
@@ -40,14 +39,15 @@
         // 表格列配置
         columns: [
           {
+            label: '序号',
             columnKey: 'index',
             type: 'index',
-            width: 45,
+            width: 55,
             align: 'center',
             showOverflowTooltip: true
           },
           {
-            prop: 'name',
+            prop: 'code',
             label: 'BOM编码',
             showOverflowTooltip: true
           },
@@ -57,57 +57,61 @@
             showOverflowTooltip: true
           },
           {
-            prop: 'name',
+            prop: 'categoryCode',
             label: '产品编码',
             showOverflowTooltip: true
           },
           {
-            prop: 'name',
+            prop: 'categoryName',
             label: '产品名称',
             showOverflowTooltip: true
           },
           {
-            prop: 'name',
-            label: '版本',
-            showOverflowTooltip: true
-          },
-          {
-            prop: 'name',
+            prop: 'status ',
             label: '状态',
-            showOverflowTooltip: true
+            formatter: (row) => {
+              return this.statusOpt[row.status];
+            }
           },
           {
-            prop: 'name',
+            prop: 'createUserName',
             label: '创建人',
             showOverflowTooltip: true
           },
           {
-            prop: 'name',
+            prop: 'createTime',
             label: '创建日期',
             showOverflowTooltip: true
-          },
-          {
-            action: 'action',
-            slot: 'action',
-            label: '操作'
           }
-        ]
+          // {
+          //   action: 'action',
+          //   slot: 'action',
+          //   label: '操作'
+          // }
+        ],
+        statusOpt: {
+          '-1': '草稿',
+          0: '已停用',
+          1: '已发布'
+        }
       };
     },
 
     methods: {
       /* 表格数据源 */
-      datasource () {
-        // return;
-        return listDictionaries();
+      datasource ({ where, page, limit }) {
+        return getPage({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
       },
       handelEdit (type, row) {
         this.$refs.editDialogRef.open(type, row);
       },
       /* 刷新表格 */
       reload (where) {
-        this.$refs.table.reload();
-        this.$refs.dictData.reload(where);
+        this.$refs.table.reload({ where });
       },
       /* 显示编辑 */
       openEdit (row) {},

+ 2 - 2
src/views/material/product/index.vue

@@ -104,8 +104,8 @@
         this.reload();
       },
       /* 刷新表格 */
-      reload () {
-        this.$refs.table.reload();
+      reload (where) {
+        this.$refs.table.reload({ where });
       },
       handleEdit ({ id }) {
         this.$router.push({