|
|
@@ -0,0 +1,519 @@
|
|
|
+<template>
|
|
|
+ <div class="ele-body">
|
|
|
+ <el-card shadow="never">
|
|
|
+ <ele-split-layout
|
|
|
+ width="260px"
|
|
|
+ allow-collapse
|
|
|
+ :resizable="true"
|
|
|
+ :min-size="200"
|
|
|
+ :max-size="-200"
|
|
|
+ :left-style="{
|
|
|
+ overflow: 'hidden',
|
|
|
+ width: '100%'
|
|
|
+ }"
|
|
|
+ :right-style="{ overflow: 'hidden' }"
|
|
|
+ :responsive="false"
|
|
|
+ >
|
|
|
+ <div class="ele-border-lighter sys-organization-list">
|
|
|
+ <div class="radio_box rx-cc">
|
|
|
+ <el-radio-group
|
|
|
+ size="small"
|
|
|
+ v-model="currentNodeData.bomType"
|
|
|
+ @change="bomChange"
|
|
|
+ >
|
|
|
+ <el-radio-button :label="1">PBOM </el-radio-button>
|
|
|
+ <el-radio-button
|
|
|
+ v-if="[1, 9].includes(rootPathIdParent)"
|
|
|
+ :label="2"
|
|
|
+ >MBOM</el-radio-button
|
|
|
+ >
|
|
|
+ <el-radio-button
|
|
|
+ v-if="[1, 9].includes(rootPathIdParent)"
|
|
|
+ :label="3"
|
|
|
+ >ABOM</el-radio-button
|
|
|
+ >
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ size="small"
|
|
|
+ placeholder="在结构中查找"
|
|
|
+ v-model="filterText"
|
|
|
+ >
|
|
|
+ </el-input>
|
|
|
+
|
|
|
+ <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>
|
|
|
+ <template v-slot:content>
|
|
|
+ <div class="pbom-box">
|
|
|
+ <div class="button-list">
|
|
|
+ <el-dropdown @command="handleDown">
|
|
|
+ <el-button type="primary" size="mini" icon="el-icon-plus">
|
|
|
+ 新建<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-dropdown-menu slot="dropdown" >
|
|
|
+ <el-dropdown-item command="a">新建BOM</el-dropdown-item>
|
|
|
+ <el-dropdown-item command="b">新建物料</el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </el-dropdown>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-if="
|
|
|
+ (currentNodeData.bomType == 2 ||
|
|
|
+ currentNodeData.bomType == 3) &&
|
|
|
+ currentNodeData.children?.length <= 0
|
|
|
+ "
|
|
|
+ type="danger"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-delete"
|
|
|
+ plain
|
|
|
+ @click="remove"
|
|
|
+ >删除</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="currentNodeData.bomType == 1"
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-download"
|
|
|
+ plain
|
|
|
+ >导出</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ @click="uploadFile"
|
|
|
+ v-if="currentNodeData.bomType == 1"
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-upload2"
|
|
|
+ plain
|
|
|
+ >导入</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-refresh"
|
|
|
+ plain
|
|
|
+ @click="transformation('M')"
|
|
|
+ v-if="currentNodeData.bomType == 1"
|
|
|
+ >转换MBOM</el-button
|
|
|
+ >
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-refresh"
|
|
|
+ plain
|
|
|
+ @click="transformation('A')"
|
|
|
+ v-if="currentNodeData.bomType == 1"
|
|
|
+ >转换ABOM</el-button
|
|
|
+ >
|
|
|
+
|
|
|
+ <div v-if="!noBack" class="back-btn">
|
|
|
+ <el-button size="mini" icon="el-icon-back" @click="back"
|
|
|
+ >返回</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <baseInfo :dataInfo="currentNodeData" />
|
|
|
+
|
|
|
+ <el-tabs
|
|
|
+ v-model="activeName"
|
|
|
+ class="tab-box"
|
|
|
+ type="border-card"
|
|
|
+ @tab-click="handleClick"
|
|
|
+ >
|
|
|
+ <el-tab-pane label="属性" name="属性">
|
|
|
+ <attribute :attributeData="currentNodeData"></attribute>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane
|
|
|
+ :label="
|
|
|
+ currentNodeData.bomType == 1
|
|
|
+ ? 'PBOM明细表'
|
|
|
+ : currentNodeData.bomType == 2
|
|
|
+ ? 'MBOM明细表'
|
|
|
+ : 'ABOM明细表'
|
|
|
+ "
|
|
|
+ name="明细表"
|
|
|
+ >
|
|
|
+ <!-- <document></document> -->
|
|
|
+ <detailedList :attributeData="currentNodeData"></detailedList>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane
|
|
|
+ label="工艺路线"
|
|
|
+ name="工艺路线"
|
|
|
+ v-if="
|
|
|
+ [1, 9].includes(rootPathIdParent) &&
|
|
|
+ currentNodeData.bomType != 1
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <routing
|
|
|
+ ref="routingRef"
|
|
|
+ :taskParam="currentNodeData"
|
|
|
+ ></routing>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane
|
|
|
+ label="工序配置"
|
|
|
+ name="工序配置"
|
|
|
+ v-if="
|
|
|
+ [1, 9].includes(rootPathIdParent) &&
|
|
|
+ currentNodeData.bomType != 1
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <workmanship
|
|
|
+ ref="workmanshipRef"
|
|
|
+ :taskParam="currentNodeData"
|
|
|
+ ></workmanship>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </ele-split-layout>
|
|
|
+ </el-card>
|
|
|
+ <bomTreeDialog ref="bomTreeDialogRef" @reload="bomTreeDialogReload" />
|
|
|
+
|
|
|
+ <importDialog
|
|
|
+ :defModule="moudleName"
|
|
|
+ ref="importDialogRef"
|
|
|
+ @success="reload"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ getBomTreeList,
|
|
|
+ getBomGetById,
|
|
|
+ convert,
|
|
|
+ convertABom,
|
|
|
+ convertCBom,
|
|
|
+ deleteBomTreeList
|
|
|
+ } from '@/api/material/BOM.js';
|
|
|
+ import { getTreeByGroup } from '@/api/classifyManage';
|
|
|
+ import attribute from './components/attribute.vue';
|
|
|
+ import routing from './components/routing.vue';
|
|
|
+ import baseInfo from './components/baseInfo.vue';
|
|
|
+ // import document from './components/document.vue';
|
|
|
+ import workmanship from './components/workmanship.vue';
|
|
|
+ import bomTreeDialog from './components/bomTreeDialog.vue';
|
|
|
+ import importDialog from './qualityTesting/import-dialog.vue';
|
|
|
+ import detailedList from './components/detailedList.vue';
|
|
|
+ export default {
|
|
|
+ name: 'BOMmanage',
|
|
|
+ components: {
|
|
|
+ attribute,
|
|
|
+ baseInfo,
|
|
|
+ // document,
|
|
|
+ workmanship,
|
|
|
+ bomTreeDialog,
|
|
|
+ routing,
|
|
|
+ importDialog,
|
|
|
+ detailedList
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activeName: '属性',
|
|
|
+ currentNodeData: {
|
|
|
+ bomType: 1,
|
|
|
+ children: []
|
|
|
+ },
|
|
|
+ taskParam: [],
|
|
|
+ current: {},
|
|
|
+ treeList: [],
|
|
|
+ treeLoading: false,
|
|
|
+ rootTreeId: null,
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'name'
|
|
|
+ },
|
|
|
+ loading: false,
|
|
|
+ filterText: null,
|
|
|
+ categoryId: 1,
|
|
|
+ versions: null,
|
|
|
+ loadingInstance: null,
|
|
|
+ noBack: false,
|
|
|
+ treeId: null,
|
|
|
+
|
|
|
+ moudleName: 'mainUser',
|
|
|
+ rootPathIdParent: null
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ // 监听$route.query对象的变化
|
|
|
+ '$route.query': {
|
|
|
+ immediate: true, // 启用立即执行
|
|
|
+ handler(newQuery, oldQuery) {
|
|
|
+ this.rootPathIdParent = Number(newQuery.categoryLevelPathIdParent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ activated() {
|
|
|
+ this.initData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ bomTreeDialogReload(versions) {
|
|
|
+ this.versions = versions;
|
|
|
+ if (!this.$route.query.versions) {
|
|
|
+ this.$router.replace({
|
|
|
+ path: '/material/BOMmanage/details',
|
|
|
+ query: { categoryId: this.categoryId, versions: versions }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.getTreeData();
|
|
|
+ },
|
|
|
+ initData() {
|
|
|
+ this.versions = this.$route.query.versions;
|
|
|
+ this.categoryId = this.$route.query.categoryId;
|
|
|
+ this.noBack = this.$route.query.noBack;
|
|
|
+
|
|
|
+ (this.currentNodeData = {
|
|
|
+ bomType: this.$route.query.bType || 1,
|
|
|
+ children: []
|
|
|
+ }),
|
|
|
+ this.getTreeData();
|
|
|
+ },
|
|
|
+ handleClick(tab) {
|
|
|
+ if (
|
|
|
+ tab.name === '工艺路线' &&
|
|
|
+ this.currentNodeData.children?.length < 1
|
|
|
+ ) {
|
|
|
+ this.$refs.routingRef.reload();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ tab.name === '工序配置' &&
|
|
|
+ this.currentNodeData.children?.length < 1
|
|
|
+ ) {
|
|
|
+ this.$refs.workmanshipRef.reload();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ remove() {
|
|
|
+ this.$confirm('是否确认删除?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ const loading = this.$loading({ lock: true });
|
|
|
+
|
|
|
+ deleteBomTreeList([this.currentNodeData.id])
|
|
|
+ .then((msg) => {
|
|
|
+ loading.close();
|
|
|
+ this.$message.success('删除' + msg);
|
|
|
+ this.getTreeData();
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ loading.close();
|
|
|
+ // this.$message.error(e.message);
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message({
|
|
|
+ type: 'info',
|
|
|
+ message: '已取消删除'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ bomChange(e) {
|
|
|
+ this.currentNodeData.bomType = e;
|
|
|
+ this.getTreeData();
|
|
|
+ },
|
|
|
+ back() {
|
|
|
+ this.$router.go(-1);
|
|
|
+ },
|
|
|
+ transformation(tt) {
|
|
|
+ this.loadingInstance = this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '转换中...',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)'
|
|
|
+ });
|
|
|
+ let ULR = tt == 'M' ? convert : tt == 'A' ? convertABom : '';
|
|
|
+ ULR({ versions: this.versions, categoryId: this.categoryId }).then(
|
|
|
+ (data) => {
|
|
|
+ if (data.code == '0') {
|
|
|
+ this.loadingInstance.close();
|
|
|
+ this.$message.success('转换成功');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ handleDown(command) {
|
|
|
+ if(command == 'b') {
|
|
|
+ this.add()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ add() {
|
|
|
+ this.$refs.bomTreeDialogRef.open(
|
|
|
+ this.currentNodeData.bomType,
|
|
|
+ this.versions,
|
|
|
+ this.categoryId,
|
|
|
+ this.treeId
|
|
|
+ );
|
|
|
+ },
|
|
|
+ async getTreeData() {
|
|
|
+ try {
|
|
|
+ this.treeLoading = true;
|
|
|
+ const res = await getBomTreeList({
|
|
|
+ categoryId: this.categoryId,
|
|
|
+ versions: this.versions,
|
|
|
+ bomType: this.currentNodeData.bomType
|
|
|
+ });
|
|
|
+ this.treeLoading = false;
|
|
|
+ if (res?.code === '0') {
|
|
|
+ if (res.data?.length > 0) {
|
|
|
+ this.treeList = res.data;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ // 默认高亮第一个
|
|
|
+ this.$refs.treeRef.setCurrentKey(res.data[0].id);
|
|
|
+ this.handleNodeClick(res.data[0]);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.treeList = [];
|
|
|
+ }
|
|
|
+ return this.treeList;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ this.treeLoading = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ handleNodeClick(data) {
|
|
|
+ this.treeId = data.id;
|
|
|
+ this.handBomDetails(data.id);
|
|
|
+ },
|
|
|
+
|
|
|
+ handBomDetails(id) {
|
|
|
+ if (id) {
|
|
|
+ getBomGetById(id).then((res) => {
|
|
|
+ // this.versions = res.data.versions;
|
|
|
+ this.currentNodeData = res.data;
|
|
|
+
|
|
|
+ if (
|
|
|
+ this.activeName == '工艺路线' &&
|
|
|
+ this.currentNodeData.children?.length < 1
|
|
|
+ ) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.routingRef.reload();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ this.activeName == '工序配置' &&
|
|
|
+ this.currentNodeData.children?.length < 1
|
|
|
+ ) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.workmanshipRef.reload();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.currentNodeData = {
|
|
|
+ bomType: 1,
|
|
|
+ children: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ uploadFile() {
|
|
|
+ this.$refs.importDialogRef.open();
|
|
|
+ },
|
|
|
+
|
|
|
+ reload(where) {
|
|
|
+ this.getTreeData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .sys-organization-list {
|
|
|
+ height: calc(100vh - 165px);
|
|
|
+ box-sizing: border-box;
|
|
|
+ border-width: 1px;
|
|
|
+ border-style: solid;
|
|
|
+ overflow: auto;
|
|
|
+ padding: 0 10px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ .treeData {
|
|
|
+ height: 0 1 auto;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .pbom-box,
|
|
|
+ .mbom-box {
|
|
|
+ height: calc(100vh - 165px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .tab-box {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ ::v-deep .el-tabs__content {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto !important;
|
|
|
+ .table_box {
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .radio_box {
|
|
|
+ margin: 12px 0;
|
|
|
+ ::v-deep .el-radio-group {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ .el-radio-button {
|
|
|
+ flex: 1;
|
|
|
+ > span {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .sys-organization-list :deep(.el-tree-node__content) {
|
|
|
+ height: 40px;
|
|
|
+
|
|
|
+ & > .el-tree-node__expand-icon {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .button-list {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background-color: #f4f4f4;
|
|
|
+ border: 1px solid #e3e5e5;
|
|
|
+ padding: 10px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border-bottom: 0;
|
|
|
+ .back-btn {
|
|
|
+ flex: 1;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|