Просмотр исходного кода

Merge remote-tracking branch 'origin/dev' into dev

zhouqi 1 год назад
Родитель
Сommit
4be77398b1
36 измененных файлов с 2330 добавлено и 1282 удалено
  1. 12 32
      src/api/material/BOM.js
  2. 234 234
      src/layout/index.vue
  3. 27 15
      src/router/index.js
  4. 3 3
      src/router/routes.js
  5. 9 5
      src/store/modules/user.js
  6. 1 0
      src/styles/transition/common.scss
  7. 24 6
      src/views/material/BOMmanage/components/ProductModalMultiple.vue
  8. 3 3
      src/views/material/BOMmanage/components/baseInfo.vue
  9. 8 1
      src/views/material/BOMmanage/components/bomTreeDialog.vue
  10. 6 10
      src/views/material/BOMmanage/components/detailedList.vue
  11. 216 0
      src/views/material/BOMmanage/components/replaceMaterialPop.vue
  12. 230 349
      src/views/material/BOMmanage/components/workingProcedure.vue
  13. 51 4
      src/views/material/BOMmanage/components/workingStep.vue
  14. 1 0
      src/views/material/BOMmanage/components/workmanship.vue
  15. 20 15
      src/views/material/BOMmanage/detailsPop.vue
  16. 151 135
      src/views/material/product/components/CategoryDialog.vue
  17. 27 25
      src/views/material/product/components/index-data.vue
  18. 74 18
      src/views/material/product/detail.vue
  19. 231 141
      src/views/material/product/index.vue
  20. 211 119
      src/views/material/product/oneProduct.vue
  21. 1 1
      src/views/rulesManagement/components/programRulesDialog.vue
  22. 103 50
      src/views/rulesManagement/matterRules/components/ProductModal.vue
  23. 394 0
      src/views/rulesManagement/matterRules/components/bomDetailList.vue
  24. 57 4
      src/views/rulesManagement/matterRules/components/matter-add.vue
  25. 67 53
      src/views/rulesManagement/matterRules/components/matter-search.vue
  26. 1 1
      src/views/rulesManagement/meteringManagement/index.vue
  27. 39 0
      src/views/source/index.vue
  28. 95 27
      src/views/system/menu/components/menu-edit.vue
  29. 3 3
      src/views/system/role/components/role-search.vue
  30. 16 1
      src/views/system/unifiedPortal/dialog.vue
  31. 0 14
      src/views/technology/production/components/user-edit.vue
  32. 4 3
      src/views/technology/production/index.vue
  33. 7 5
      src/views/technology/route/components/production/components/user-edit.vue
  34. 1 1
      src/views/technology/version/components/user-edit.vue
  35. 1 1
      src/views/versionManage/index.vue
  36. 2 3
      vue.config.js

+ 12 - 32
src/api/material/BOM.js

@@ -120,7 +120,6 @@ export async function getBomTreeList(params) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
 // 查询BOM树 详情
 export async function getBomGetById(id) {
   const res = await request.get(`/main/bomCategory/getById/${id}`);
@@ -130,8 +129,6 @@ export async function getBomGetById(id) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 // 查询BOM 版本
 export async function versionList(params) {
   const res = await request.get(`/main/bomCategory/versionList`, { params });
@@ -141,10 +138,6 @@ export async function versionList(params) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
- 
-
 // 新增BOM树节点
 export async function saveBomTreeList(data) {
   const res = await request.post(`/main/bomCategory/save`, data);
@@ -163,7 +156,6 @@ export async function deleteBomTreeList(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
 // 保存BOM树节点
 export async function updateBatchBOM(data) {
   const res = await request.post(`/main/bomCategory/updateBatchBOM`, data);
@@ -173,8 +165,6 @@ export async function updateBatchBOM(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 // 获取产品BOM列表
 export async function getBomPageList(params) {
   const res = await request.get(`/main/bomCategory/page`, { params });
@@ -184,14 +174,20 @@ export async function getBomPageList(params) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
-
-
-
 // 获取产品BOM列表
 export async function getBomPageCategoryId(params) {
-  const res = await request.get(`/main/bomCategory/pageByCategoryId`, { params });
+  const res = await request.get(`/main/bomCategory/pageByCategoryId`, {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取BOM明细
+export async function getBom(params) {
+  const res = await request.get(`/main/bomCategory/getBom`, { params });
   if (res.data.code == 0) {
     return res.data.data;
   }
@@ -207,7 +203,6 @@ export async function bomCategoryUpdate(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
 // PBom转换 MBOM
 export async function convert(data) {
   const res = await request.post(`/main/bomCategory/convert`, data);
@@ -235,7 +230,6 @@ export async function convertEBOM(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
 // EBom转换为PBom
 export async function convertEBomToPBOM(data) {
   const res = await request.post(`/main/bomCategory/convertEBomToPBOM`, data);
@@ -245,11 +239,6 @@ export async function convertEBomToPBOM(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
-
-
-
 // 文档
 export async function getBomFilePageList(params) {
   const res = await request.get(`/main/bomfile/page`, { params });
@@ -275,7 +264,6 @@ export async function bomSubmit(data) {
   if (res && res.data.code == 0) {
     return res.data;
   }
-
 }
 
 // 嘉实医药提交
@@ -297,9 +285,6 @@ export async function deviceBomSubmit(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
-
 // 新增工序
 export async function workingProcedureSave(data) {
   const res = await request.post(`/main/categoryparam/save`, data);
@@ -372,8 +357,6 @@ export async function workingStepSave(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 // 供应商列表
 export async function contactList(params) {
   const res = await request.get(`/eom/contact/page`, { params });
@@ -383,8 +366,6 @@ export async function contactList(params) {
   return Promise.reject(new Error(res.data.message));
 }
 
-
-
 // 检查bom  (里面有几个草稿)
 
 export async function hasNewVersion(data) {
@@ -394,4 +375,3 @@ export async function hasNewVersion(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
-

+ 234 - 234
src/layout/index.vue

@@ -100,23 +100,160 @@
 </template>
 
 <script>
-  import { mapGetters } from 'vuex';
-  import { toggleFullscreen, isFullscreen } from 'ele-admin';
-  import RouterLayout from '@/components/RouterLayout/index.vue';
-  import HeaderTools from './components/header-tools.vue';
-  import PageFooter from './components/page-footer.vue';
-  import {
-    PROJECT_NAME,
-    HIDE_SIDEBARS,
-    HIDE_FOOTERS,
-    REPEATABLE_TABS,
-    HOME_TITLE,
-    HOME_PATH,
-    LAYOUT_PATH,
-    REDIRECT_PATH,
-    I18N_ENABLE
-  } from '@/config/setting';
-  import {
+import { mapGetters } from 'vuex';
+import { toggleFullscreen, isFullscreen } from 'ele-admin';
+import RouterLayout from '@/components/RouterLayout/index.vue';
+import HeaderTools from './components/header-tools.vue';
+import PageFooter from './components/page-footer.vue';
+import {
+  PROJECT_NAME,
+  HIDE_SIDEBARS,
+  HIDE_FOOTERS,
+  REPEATABLE_TABS,
+  HOME_TITLE,
+  HOME_PATH,
+  LAYOUT_PATH,
+  REDIRECT_PATH,
+  I18N_ENABLE
+} from '@/config/setting';
+import {
+  addPageTab,
+  removePageTab,
+  removeAllPageTab,
+  removeLeftPageTab,
+  removeRightPageTab,
+  removeOtherPageTab,
+  reloadPageTab,
+  setHomeComponents,
+  setPageTabs
+} from '@/utils/page-tab-util';
+import { secretLevelList } from '@/enum/dict';
+
+export default {
+  name: 'EleLayout',
+  components: {
+    RouterLayout,
+    HeaderTools
+  },
+  data() {
+    return {
+      PROJECT_NAME,
+      HIDE_SIDEBARS,
+      HIDE_FOOTERS,
+      REPEATABLE_TABS,
+      HOME_PATH,
+      HOME_TITLE,
+      LAYOUT_PATH,
+      REDIRECT_PATH,
+      // 是否全屏
+      fullscreen: false
+    };
+  },
+  computed: {
+    isQianKun() {
+      return window.__POWERED_BY_QIANKUN__;
+    },
+    // 当前语言
+    locale() {
+      return this.$i18n.locale;
+    },
+    // 菜单数据
+    menus() {
+      return this.$store.state.user.menus;
+    },
+    // 主题状态
+    ...mapGetters(['theme'])
+  },
+  methods: {
+    getSecretLevelStyle(item) {
+      return {
+        color: item.meta.secretLevel > 1 ? 'red' : 'green',
+        fontWeight: 'bold',
+        fontSize: '15px'
+      };
+    },
+    getSecretLevel(item) {
+      let find =
+        secretLevelList.find((i) => item.meta.secretLevel == i.value) || {};
+      return '(' + find.label + ')';
+    },
+    /* 侧栏折叠切换 */
+    updateCollapse(value) {
+      // console.log('value:', this.$store.state.user.menus);
+      this.$store.dispatch('theme/setCollapse', value);
+    },
+    /* 双侧栏一级折叠切换 */
+    updateSideNavCollapse(value) {
+      this.$store.dispatch('theme/setSideNavCollapse', value);
+    },
+    /* 内容区域全屏切换 */
+    updateBodyFullscreen(value) {
+      this.$store.dispatch('theme/setBodyFullscreen', value);
+    },
+    /* logo 点击事件 */
+    onLogoClick(isHome) {
+      isHome || this.$router.push(LAYOUT_PATH);
+    },
+    /* 监听屏幕尺寸改变 */
+    screenSizeChange() {
+      this.$store.dispatch('theme/updateScreenSize');
+      this.fullscreen = isFullscreen();
+    },
+    /* 全屏切换 */
+    onFullscreen() {
+      try {
+        this.fullscreen = toggleFullscreen();
+      } catch (e) {
+        this.$message.error('您的浏览器不支持全屏模式');
+      }
+    },
+    /* 页签右键菜单点击事件 */
+    onTabContextMenu({ key, tabKey, item, active }) {
+      switch (key) {
+        case 'reload': // 刷新
+          reloadPageTab({
+            isHome: !item,
+            fullPath: item?.fullPath ?? tabKey
+          });
+          break;
+        case 'close': // 关闭当前
+          removePageTab({
+            key: item?.fullPath ?? tabKey,
+            active
+          });
+          break;
+        case 'left': // 关闭左侧
+          removeLeftPageTab({
+            key: tabKey,
+            active
+          });
+          break;
+        case 'right': // 关闭右侧
+          removeRightPageTab({
+            key: tabKey,
+            active
+          });
+          break;
+        case 'other': // 关闭其他
+          removeOtherPageTab({
+            key: tabKey,
+            active
+          });
+          break;
+      }
+    },
+    /* 菜单标题国际化 */
+    i18n(_path, key) {
+      if (!I18N_ENABLE || !key) {
+        return;
+      }
+      const k = 'route.' + key + '._name';
+      const title = this.$t(k);
+      if (title !== k) {
+        return title;
+      }
+    },
+    //
     addPageTab,
     removePageTab,
     removeAllPageTab,
@@ -126,246 +263,109 @@
     reloadPageTab,
     setHomeComponents,
     setPageTabs
-  } from '@/utils/page-tab-util';
-  import { secretLevelList } from '@/enum/dict';
-
-  export default {
-    name: 'EleLayout',
-    components: {
-      RouterLayout,
-      HeaderTools
-    },
-    data() {
-      return {
-        PROJECT_NAME,
-        HIDE_SIDEBARS,
-        HIDE_FOOTERS,
-        REPEATABLE_TABS,
-        HOME_PATH,
-        HOME_TITLE,
-        LAYOUT_PATH,
-        REDIRECT_PATH,
-        // 是否全屏
-        fullscreen: false
-      };
-    },
-    computed: {
-      isQianKun() {
-        return window.__POWERED_BY_QIANKUN__;
-      },
-      // 当前语言
-      locale() {
-        return this.$i18n.locale;
-      },
-      // 菜单数据
-      menus() {
-        return this.$store.state.user.menus;
-      },
-      // 主题状态
-      ...mapGetters(['theme'])
-    },
-    methods: {
-      getSecretLevelStyle(item) {
-        return {
-          color: item.meta.secretLevel > 1 ? 'red' : 'green',
-          fontWeight: 'bold',
-          fontSize: '15px'
-        };
-      },
-      getSecretLevel(item) {
-        let find =
-          secretLevelList.find((i) => item.meta.secretLevel == i.value) || {};
-        return '(' + find.label + ')';
-      },
-      /* 侧栏折叠切换 */
-      updateCollapse(value) {
-        // console.log('value:', this.$store.state.user.menus);
-        this.$store.dispatch('theme/setCollapse', value);
-      },
-      /* 双侧栏一级折叠切换 */
-      updateSideNavCollapse(value) {
-        this.$store.dispatch('theme/setSideNavCollapse', value);
-      },
-      /* 内容区域全屏切换 */
-      updateBodyFullscreen(value) {
-        this.$store.dispatch('theme/setBodyFullscreen', value);
-      },
-      /* logo 点击事件 */
-      onLogoClick(isHome) {
-        isHome || this.$router.push(LAYOUT_PATH);
-      },
-      /* 监听屏幕尺寸改变 */
-      screenSizeChange() {
-        this.$store.dispatch('theme/updateScreenSize');
-        this.fullscreen = isFullscreen();
-      },
-      /* 全屏切换 */
-      onFullscreen() {
-        try {
-          this.fullscreen = toggleFullscreen();
-        } catch (e) {
-          this.$message.error('您的浏览器不支持全屏模式');
-        }
-      },
-      /* 页签右键菜单点击事件 */
-      onTabContextMenu({ key, tabKey, item, active }) {
-        switch (key) {
-          case 'reload': // 刷新
-            reloadPageTab({
-              isHome: !item,
-              fullPath: item?.fullPath ?? tabKey
-            });
-            break;
-          case 'close': // 关闭当前
-            removePageTab({
-              key: item?.fullPath ?? tabKey,
-              active
-            });
-            break;
-          case 'left': // 关闭左侧
-            removeLeftPageTab({
-              key: tabKey,
-              active
-            });
-            break;
-          case 'right': // 关闭右侧
-            removeRightPageTab({
-              key: tabKey,
-              active
-            });
-            break;
-          case 'other': // 关闭其他
-            removeOtherPageTab({
-              key: tabKey,
-              active
-            });
-            break;
-        }
-      },
-      /* 菜单标题国际化 */
-      i18n(_path, key) {
-        if (!I18N_ENABLE || !key) {
-          return;
-        }
-        const k = 'route.' + key + '._name';
-        const title = this.$t(k);
-        if (title !== k) {
-          return title;
-        }
-      },
-      //
-      addPageTab,
-      removePageTab,
-      removeAllPageTab,
-      removeLeftPageTab,
-      removeRightPageTab,
-      removeOtherPageTab,
-      reloadPageTab,
-      setHomeComponents,
-      setPageTabs
-    }
-  };
+  }
+};
 </script>
 
 <style lang="scss">
-  .ele-admin-logo {
-    font-size: 18px !important;
-    justify-content: flex-start !important;
-    align-items: center !important;
-    img {
-      height: 35px !important;
-      max-width: 86px;
-      width: auto;
-      margin-right: 6px;
-    }
+.ele-admin-logo {
+  font-size: 18px !important;
+  justify-content: flex-start !important;
+  align-items: center !important;
+  img {
+    height: 35px !important;
+    max-width: 86px;
+    width: auto;
+    margin-right: 6px;
   }
-  // 侧栏菜单徽章样式,定位在右侧垂直居中并调小尺寸
-  .ele-menu-badge {
-    position: absolute;
-    top: 50%;
-    right: 14px;
-    line-height: 1;
-    margin-top: -9px;
-    font-size: 0;
+}
+// 侧栏菜单徽章样式,定位在右侧垂直居中并调小尺寸
+.ele-menu-badge {
+  position: absolute;
+  top: 50%;
+  right: 14px;
+  line-height: 1;
+  margin-top: -9px;
+  font-size: 0;
 
-    .el-badge__content {
-      height: 18px;
-      line-height: 18px;
-      border-radius: 9px;
-      border: none;
-      min-width: 18px;
-      padding: 0 4px;
-      box-sizing: border-box;
-    }
+  .el-badge__content {
+    height: 18px;
+    line-height: 18px;
+    border-radius: 9px;
+    border: none;
+    min-width: 18px;
+    padding: 0 4px;
+    box-sizing: border-box;
   }
+}
 
-  // 父级菜单标题中右侧多定位一点,避免与箭头重合
-  .el-submenu > .el-submenu__title .ele-menu-badge {
-    right: 36px;
-  }
+// 父级菜单标题中右侧多定位一点,避免与箭头重合
+.el-submenu > .el-submenu__title .ele-menu-badge {
+  right: 36px;
+}
 
-  // 折叠悬浮中样式调整
-  .el-menu--popup {
-    .el-submenu > .el-submenu__title .ele-menu-badge {
-      right: 20px;
-    }
+// 折叠悬浮中样式调整
+.el-menu--popup {
+  .el-submenu > .el-submenu__title .ele-menu-badge {
+    right: 20px;
   }
+}
 
-  // 侧栏折叠后样式调整
-  .ele-admin-collapse .ele-admin-sidebar-menus > .el-scrollbar {
-    & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
-      & > .el-menu-item,
-      & > .el-submenu > .el-submenu__title {
-        .ele-menu-badge {
-          top: 2px;
-          right: 2px;
-          margin: 0;
-        }
+// 侧栏折叠后样式调整
+.ele-admin-collapse .ele-admin-sidebar-menus > .el-scrollbar {
+  & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
+    & > .el-menu-item,
+    & > .el-submenu > .el-submenu__title {
+      .ele-menu-badge {
+        top: 2px;
+        right: 2px;
+        margin: 0;
       }
     }
   }
+}
 
-  // 顶栏菜单标题中样式调整
-  .ele-admin-header-nav > .el-scrollbar > .el-scrollbar__wrap {
-    & > .el-scrollbar__view > .el-menu {
-      & > .el-menu-item,
-      & > .el-submenu > .el-submenu__title {
-        .ele-menu-badge {
-          position: static;
-          right: auto;
-          top: auto;
-          display: inline-block;
-          vertical-align: 6px;
-          margin: 0 0 0 2px;
-        }
+// 顶栏菜单标题中样式调整
+.ele-admin-header-nav > .el-scrollbar > .el-scrollbar__wrap {
+  & > .el-scrollbar__view > .el-menu {
+    & > .el-menu-item,
+    & > .el-submenu > .el-submenu__title {
+      .ele-menu-badge {
+        position: static;
+        right: auto;
+        top: auto;
+        display: inline-block;
+        vertical-align: 6px;
+        margin: 0 0 0 2px;
       }
     }
   }
+}
 
-  // 双侧栏时一级侧栏菜单中样式调整,定位在右上角
-  .ele-admin-sidebar-nav-menu > .el-scrollbar > .el-scrollbar__wrap {
-    & > .el-scrollbar__view > .el-menu {
-      & > .el-menu-item,
-      & > .el-submenu > .el-submenu__title {
-        .ele-menu-badge {
-          top: 0;
-          right: 0;
-          margin: 0;
-        }
+// 双侧栏时一级侧栏菜单中样式调整,定位在右上角
+.ele-admin-sidebar-nav-menu > .el-scrollbar > .el-scrollbar__wrap {
+  & > .el-scrollbar__view > .el-menu {
+    & > .el-menu-item,
+    & > .el-submenu > .el-submenu__title {
+      .ele-menu-badge {
+        top: 0;
+        right: 0;
+        margin: 0;
       }
     }
   }
+}
 
-  // 双侧栏时一级侧栏菜单折叠后样式调整
-  .ele-admin-nav-collapse .ele-admin-sidebar-nav-menu > .el-scrollbar {
-    & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
-      & > .el-menu-item,
-      & > .el-submenu > .el-submenu__title {
-        .ele-menu-badge {
-          top: 0;
-          right: 0;
-        }
+// 双侧栏时一级侧栏菜单折叠后样式调整
+.ele-admin-nav-collapse .ele-admin-sidebar-nav-menu > .el-scrollbar {
+  & > .el-scrollbar__wrap > .el-scrollbar__view > .el-menu {
+    & > .el-menu-item,
+    & > .el-submenu > .el-submenu__title {
+      .ele-menu-badge {
+        top: 0;
+        right: 0;
       }
     }
   }
+}
 </style>

+ 27 - 15
src/router/index.js

@@ -28,9 +28,9 @@ const router = new VueRouter({
  * 路由守卫
  */
 router.beforeEach((to, from, next) => {
-  console.log(store.state.user);
-  console.log(to);
-  console.log(from);
+  // console.log(store.state.user);
+  // console.log(to, 999);
+  // console.log(from);
 
   if (!from.path.includes(REDIRECT_PATH)) {
     NProgress.start();
@@ -56,19 +56,31 @@ router.beforeEach((to, from, next) => {
                   path: '/bpm/definition',
                   component: 'bpm/definition',
                   name: '流程定义',
-                  meta: { title: '流程定义', hide: true, routePath: '/bpm/definition' }
+                  meta: {
+                    title: '流程定义',
+                    hide: true,
+                    routePath: '/bpm/definition'
+                  }
                 },
                 {
                   path: '/bpm/modelEditor',
                   component: 'bpm/model/modelEditor',
                   name: '设计流程',
-                  meta: { title: '设计流程', hide: true, routePath: '/bpm/modelEditor' }
+                  meta: {
+                    title: '设计流程',
+                    hide: true,
+                    routePath: '/bpm/modelEditor'
+                  }
                 },
                 {
                   path: '/bpm/processInstance',
                   component: 'bpm/processInstance/detail',
                   name: '流程详情',
-                  meta: { title: '流程详情', hide: true, routePath: '/bpm/processInstance' }
+                  meta: {
+                    title: '流程详情',
+                    hide: true,
+                    routePath: '/bpm/processInstance'
+                  }
                 }
               );
             }
@@ -86,7 +98,6 @@ router.beforeEach((to, from, next) => {
           next();
         });
     } else {
-      // console.log(router.getRoutes(), 'router', routes);
       if (routes.length >= router.getRoutes()?.length) {
         router.addRoute(
           getMenuRoutes([
@@ -121,18 +132,19 @@ router.roleChange = async ({ menus, homePath, authoritiesRouter }) => {
   const currentUser = JSON.parse(sessionStorage['currentUser']);
 
   if (menus && menus.length > 0) {
-    router.addRoute(
-      getMenuRoutes([...menus, ...authoritiesRouter], homePath)
-    );
+    router.addRoute(getMenuRoutes([...menus, ...authoritiesRouter], homePath));
     if (router.currentRoute.path != (menus[0].redirect || menus[0].path)) {
       await router.replace({
-        path: menus[0].redirect || menus[0].path,
-      })
+        path: menus[0].redirect || menus[0].path
+      });
     }
-    const newToken = await changeRole({ groupId: currentUser.currentGroupId, roleId: currentUser.currentRoleId })
-    setToken(newToken)
+    const newToken = await changeRole({
+      groupId: currentUser.currentGroupId,
+      roleId: currentUser.currentRoleId
+    });
+    setToken(newToken);
     setTimeout(() => {
-      window.location.reload()
+      window.location.reload();
     }, 100);
   }
 

+ 3 - 3
src/router/routes.js

@@ -17,7 +17,7 @@ export const routes = [
     path: '/forget',
     component: () => import('@/views/forget/index.vue'),
     meta: { title: '忘记密码' }
-  },
+  }
 
   // {
   //   path: '/bpm',
@@ -57,7 +57,7 @@ export const routes = [
  * @param menus 菜单数据
  * @param homePath 菜单数据的第一个页面地址
  */
-export function getMenuRoutes (menus, homePath) {
+export function getMenuRoutes(menus, homePath) {
   const routes = [
     // 用于刷新的路由
     {
@@ -85,7 +85,7 @@ export function getMenuRoutes (menus, homePath) {
  * 获取路由组件
  * @param component 组件名称
  */
-function getComponent (component) {
+function getComponent(component) {
   if (component) {
     return () => import('@/views/' + component);
   }

+ 9 - 5
src/store/modules/user.js

@@ -25,10 +25,11 @@ const formatRouter = (list) => {
         p.children = [];
       }
       p.meta = {
-        secretLevel: p.secretLevel
+        secretLevel: p.secretLevel,
+        source: p.source,
+        path: p.path
       };
       arr.push(p);
-      // }
     }
 
     return arr;
@@ -121,9 +122,12 @@ export default {
     //   return { menus, homePath };
     // },
     //动态路由
-    async fetchUserInfo({ commit,state }) {
-      let currentUser=JSON.parse(sessionStorage['currentUser'])
-      const result = await getResourcesTree({groupId:currentUser.currentGroupId,roleId:currentUser.currentRoleId}).catch(() => {});
+    async fetchUserInfo({ commit, state }) {
+      let currentUser = JSON.parse(sessionStorage['currentUser']);
+      const result = await getResourcesTree({
+        groupId: currentUser.currentGroupId,
+        roleId: currentUser.currentRoleId
+      }).catch(() => {});
       const list = result?.filter((i) => i.path === '/page-main-data');
       if (!list?.length) {
         return {};

+ 1 - 0
src/styles/transition/common.scss

@@ -194,3 +194,4 @@ table th .is-required::before{
   // height: 32px  !important;
   // line-height: 32px  !important;
 }
+

+ 24 - 6
src/views/material/BOMmanage/components/ProductModalMultiple.vue

@@ -53,9 +53,12 @@
 <script>
   import ProductSearch from '@/components/select/bom/product-search.vue';
   import { getMaterialList } from '@/api/material/list.js';
-  import { getTreeByGroup } from '@/api/classifyManage';
+  import { getTreeByGroup, getTreeByIds } from '@/api/classifyManage';
   export default {
     components: { ProductSearch },
+
+    props: {},
+
     data() {
       return {
         visible: false,
@@ -67,14 +70,17 @@
             columnKey: 'selection',
             type: 'selection',
             width: 45,
-            align: 'center'
+            align: 'center',
+            selectable: (row, index) => {
+              return !this.replaceMaterial.some((it) => it.id == row.id);
+            },
+            reserveSelection: true
           },
           {
             columnKey: 'index',
             type: 'index',
             width: 45,
             align: 'center',
-            reserveSelection: true
           },
           {
             prop: 'code',
@@ -165,7 +171,10 @@
         defaultProps: {
           children: 'children',
           label: 'name'
-        }
+        },
+
+        treeIds: [],
+        replaceMaterial: []
       };
     },
 
@@ -191,8 +200,10 @@
         this.isCategory = false;
         this.$refs.table.reload({ pageNum: 1, where: where });
       },
-      open(type) {
+      open(type, treeIds, replaceMaterial) {
         this.type = type;
+        this.treeIds = treeIds || [];
+        this.replaceMaterial = replaceMaterial || [];
         this.getTreeData();
         this.visible = true;
       },
@@ -200,8 +211,13 @@
       async getTreeData() {
         try {
           this.treeLoading = true;
+          let res = null;
+          if (this.type) {
+            res = await getTreeByGroup({ type: this.type });
+          } else {
+            res = await getTreeByIds({ ids: this.treeIds.join(',') });
+          }
 
-          const res = await getTreeByGroup({ type: this.type });
           this.treeLoading = false;
           if (res?.code === '0') {
             this.treeList = res.data;
@@ -266,4 +282,6 @@
   .topsearch {
     margin-bottom: 15px;
   }
+
+
 </style>

+ 3 - 3
src/views/material/BOMmanage/components/baseInfo.vue

@@ -34,7 +34,7 @@
           </el-form-item>
         </el-col>
         <el-col :span="4" label-width="80px">
-          <el-form-item label="状态:" prop="type">
+          <el-form-item label="审批状态:" prop="type">
             <el-select
               size="mini"
               style="width: 120px"
@@ -85,11 +85,11 @@
         baseInfoShow: false,
         statusOptions: [
           {
-            label: '已停用',
+            label: '审批通过',
             value: 2
           },
           {
-            label: '已发布',
+            label: '审批中',
             value: 1
           },
           {

+ 8 - 1
src/views/material/BOMmanage/components/bomTreeDialog.vue

@@ -248,15 +248,22 @@
       chooseStandardList(type, data) {
         if (type == 9 || type == 1) {
           this.category = data[0];
+          console.log(999,    this.category )
           this.attributeData.categoryId = data[0].id;
           this.$set(this.attributeData, 'code', data[0].code);
           this.$set(this.attributeData, 'name', data[0].name);
+          this.$set(this.attributeData, 'unit', data[0].measuringUnit);
           this.$forceUpdate();
         }
       },
 
       async open(type, versions, categoryId, treeId, isTemp) {
-        this.attributeData = {};
+        this.attributeData = {
+          dosage: 1,
+          bomTypeRouting: '',
+          unit: '',
+          remake: ''
+        };
         this.attributeData.bomType = type;
       
         this.attributeData.versions = versions;

+ 6 - 10
src/views/material/BOMmanage/components/detailedList.vue

@@ -40,10 +40,7 @@
         </el-input>
       </template>
 
-
-      <template v-slot:versions="{ row }">
-       V{{ row.versions }}.0
-      </template>
+      <template v-slot:versions="{ row }"> V{{ row.versions }}.0 </template>
 
       <template v-slot:produceType="{ row }">
         <el-select
@@ -286,8 +283,8 @@
       },
 
       isTemp: {
-         type: Number,
-         default: 0
+        type: Number,
+        default: 0
       }
     },
 
@@ -295,7 +292,6 @@
       treeId: {
         handler(val) {
           this.newTreeId = val;
-       
         },
         deep: true,
         immediate: true
@@ -303,9 +299,9 @@
 
       attributeData: {
         handler(val) {
-         this.$nextTick(() => {
-          this.reload()
-         })
+          this.$nextTick(() => {
+            this.reload();
+          });
         },
         deep: true,
         immediate: true

+ 216 - 0
src/views/material/BOMmanage/components/replaceMaterialPop.vue

@@ -0,0 +1,216 @@
+<template>
+  <el-dialog
+    title="替代料"
+    :visible.sync="visible"
+    v-if="visible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="90%"
+  >
+    <ele-pro-table
+      ref="replaceMaterialPop"
+      :columns="columns"
+      :datasource="replaceMaterial"
+      :need-page="false"
+      :immediate="true"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <el-button type="primary" v-if="!isView" @click="handAdd"
+          >添加</el-button
+        >
+      </template>
+
+      <template v-slot:unit="{ row }">
+        <div v-if="isView">{{ row.unit }}</div>
+        <div v-else>
+          <DictSelection dictName="计量单位" v-model="row.unit"></DictSelection>
+        </div>
+      </template>
+
+      <template v-slot:count="{ row }">
+        <div v-if="isView">{{ row.count }}</div>
+        <el-input
+          v-else
+          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:bomArtFiles="{ row }">
+        <fileUpload v-model="row.bomArtFiles" type="add" size="mini" />
+      </template>
+
+      <template v-slot:remark="{ row }">
+        <div v-if="isView">{{ row.remark }}</div>
+        <el-input v-else v-model="row.remark" placeholder="请输入"></el-input>
+      </template>
+
+      <template v-slot:action="{ row, $index }">
+        <el-link type="danger"  v-if="!isView" @click="handleDel(row, $index)">删除</el-link>
+      </template>
+    </ele-pro-table>
+
+    <div class="btns">
+      <el-button type="primary" size="small" @click="selected">选择</el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+
+    <ProductModalMultiple
+      ref="productMultipleRefs"
+      @selection="selectionList"
+    ></ProductModalMultiple>
+  </el-dialog>
+</template>
+<script>
+  import fileUpload from '@/components/addDoc/index.vue';
+  import ProductModalMultiple from './ProductModalMultiple.vue';
+  export default {
+    components: {
+      fileUpload,
+      ProductModalMultiple
+    },
+    props: {
+      isView: {
+        type: Boolean,
+        default: false
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        rootCategoryLevelId: null,
+        replaceMaterial: [],
+
+        columns: [
+          {
+            type: 'index',
+            width: 55,
+            align: 'center'
+          },
+
+          {
+            label: '物料名称',
+            prop: 'categoryName'
+          },
+
+          {
+            label: '编码',
+            prop: 'categoryCode'
+          },
+          {
+            label: '牌号',
+            prop: 'brandNum'
+          },
+          {
+            label: '型号',
+            prop: 'modelType'
+          },
+          {
+            prop: 'specification',
+            label: '规格',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            label: '数量',
+            slot: 'count',
+            action: 'count'
+          },
+          {
+            label: '单位',
+            slot: 'unit',
+            action: 'unit'
+          },
+
+          {
+            label: '附件',
+            slot: 'bomArtFiles',
+            action: 'bomArtFiles',
+            minWidth: 150
+          },
+
+          {
+            label: '备注',
+            slot: 'remark',
+            action: 'remark'
+          },
+
+          {
+            columnKey: 'action',
+            label: '操作',
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true
+          }
+        ]
+      };
+    },
+    methods: {
+      open(row) {
+        this.replaceId = row.id;
+        this.rootCategoryLevelId = row.rootCategoryLevelId;
+        if (Object.prototype.hasOwnProperty.call(row, 'replaceMaterial')) {
+          this.replaceMaterial = row.replaceMaterial;
+        } else {
+          this.replaceMaterial = [];
+        }
+        this.visible = true;
+      },
+      handAdd() {
+        this.$refs.productMultipleRefs.open(null, [this.rootCategoryLevelId], this.replaceMaterial);
+      },
+
+      selectionList(list) {
+        let array = [];
+        list.map((item, index) => {
+          array.push({
+            id: item.id,
+            categoryName: item.name,
+            categoryCode: item.categoryCode,
+            isReworkBom: 0,
+            brandNum: item.brandNum,
+            count: item.count || '',
+            modelType: item.modelType,
+            unit: item.measuringUnit,
+            bomArtFiles: [],
+            remark: '',
+            specification: item.specification,
+            rootCategoryLevelId: item.categoryLevelPathIdParent,
+            extInfo: item.extInfo
+          });
+        });
+        this.replaceMaterial = [...this.replaceMaterial, ...array] ;
+      },
+      handleDel(row, index) {
+        this.replaceMaterial.splice(index, 1);
+      },
+
+      selected() {
+        this.$emit('selected', this.replaceId, this.replaceMaterial);
+        this.visible = false;
+      },
+
+      handleClose() {
+        this.visible = false;
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .btns {
+    text-align: center;
+    padding: 10px 0;
+  }
+</style>

+ 230 - 349
src/views/material/BOMmanage/components/workingProcedure.vue

@@ -161,7 +161,7 @@
           <term :qualityParam="qualityParam" ref="qualityParamRef"></term>
         </el-tab-pane>
         <el-tab-pane label="生产节拍" name="生产节拍">
-          <el-form label-width="100px" ref="form" :model="beatParam">
+          <el-form label-width="140px" ref="form" :model="beatParam" style="width: 800px; margin: auto;">
             <el-row>
               <el-col :span="16" label-width="100px">
                 <el-form-item label="节拍生产数量" prop="beatNum">
@@ -175,12 +175,15 @@
               </el-col>
 
               <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="beatUnit">
+    
+                <el-form-item label="单位:" prop="unit">
                   <el-select
                     v-if="!isView"
-                    v-model="beatParam.beatUnit"
+                    v-model="beatParam.unit"
                     filterable
                     class="ele-block"
+                    @change="changeUnit"
+                  
                   >
                     <el-option
                       v-for="item in dictList"
@@ -189,248 +192,115 @@
                       :label="item.label"
                     ></el-option>
                   </el-select>
-                  <div v-else>{{ beatParam.beatUnit }}</div>
+                  <div v-else>{{ beatParam.unit }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-row>
-              <el-col :span="16" label-width="100px">
-                <el-form-item label="对应物料数量" prop="materielNum">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    v-model="beatParam.materielNum"
-                  ></el-input>
-                  <div v-else>{{ beatParam.materielNum }}</div>
-                </el-form-item>
-              </el-col>
+       
+         
 
-              <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="materielUnit">
-                  <el-select
-                    v-if="!isView"
-                    v-model="beatParam.materielUnit"
-                    filterable
-                    class="ele-block"
-                  >
-                    <el-option
-                      v-for="item in dictList"
-                      :key="item.value"
-                      :value="item.value"
-                      :label="item.label"
-                    ></el-option>
-                  </el-select>
-                  <div v-else>{{ beatParam.materielUnit }}</div>
-                </el-form-item>
-              </el-col>
-            </el-row>
             <el-row>
               <el-col :span="16" label-width="100px">
-                <el-form-item label="节拍时间" prop="beatTime">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    v-model="beatParam.beatTime"
-                  ></el-input>
-                  <div v-else>{{ beatParam.beatTime }}</div>
-                </el-form-item>
-              </el-col>
+                <el-form-item label="生产时长" prop="newBeatTime">
 
-              <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="beatTimeUnit">
-                  <el-select
-                    v-if="!isView"
-                    v-model="beatParam.beatTimeUnit"
-                    filterable
-                    class="ele-block"
-                  >
-                    <el-option
-                      v-for="item in dictList"
-                      :key="item.value"
-                      :value="item.value"
-                      :label="item.label"
-                    ></el-option>
-                  </el-select>
-                  <div v-else>{{ beatParam.beatTimeUnit }}</div>
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row>
-              <el-col :span="16" label-width="100px">
-                <el-form-item label="节拍准备时长" prop="name">
+             
                   <el-input
                     v-if="!isView"
                     placeholder=""
-                    v-model="beatParam.beatPrepareTime"
+                    v-model="beatParam.newBeatTime"
+                    @blur="convertVal(beatParam.newBeatTime, 'beatTime')"
+                     oninput="value = value.replace(/[^\d.]/g, '')"
+                   
                   ></el-input>
-                  <div v-else>{{ beatParam.beatPrepareTime }}</div>
+                
+               <div v-else>{{ beatParam.newBeatTime }}</div> 
                 </el-form-item>
               </el-col>
 
               <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="beatPrepareUnit">
-                  <el-select
-                    v-if="!isView"
-                    v-model="beatParam.beatPrepareUnit"
-                    filterable
-                    class="ele-block"
-                  >
-                    <el-option
-                      v-for="item in dictList"
-                      :key="item.value"
-                      :value="item.value"
-                      :label="item.label"
-                    ></el-option>
-                  </el-select>
-                  <div v-else>{{ beatParam.beatPrepareUnit }}</div>
+                <el-form-item label="单位:" prop="">
+                  <div >{{ beatParam.unit }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
             <el-row>
               <el-col :span="16" label-width="100px">
-                <el-form-item label="节拍休息时长" prop="name">
+                <el-form-item label="准备时长" prop="newBeatPrepareTime">
                   <el-input
                     v-if="!isView"
                     placeholder=""
-                    v-model="beatParam.beatRestTime"
+                    v-model="beatParam.newBeatPrepareTime"
+                     @blur="convertVal(beatParam.newBeatPrepareTime, 'beatPrepareTime')"
+                       oninput="value = value.replace(/[^\d.]/g, '')"
                   ></el-input>
-                  <div v-else>{{ beatParam.beatRestTime }}</div>
+                  <div v-else>{{ beatParam.newBeatPrepareTime }}</div>
                 </el-form-item>
               </el-col>
 
               <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="beatRestUnit">
-                  <el-select
-                    v-if="!isView"
-                    v-model="beatParam.beatRestUnit"
-                    filterable
-                    class="ele-block"
-                  >
-                    <el-option
-                      v-for="item in dictList"
-                      :key="item.value"
-                      :value="item.value"
-                      :label="item.label"
-                    ></el-option>
-                  </el-select>
-                  <div v-else>{{ beatParam.beatRestUnit }}</div>
+                <el-form-item label="单位:" prop="">
+                  <div>{{ beatParam.unit }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
             <el-row>
-              <el-col :span="24" label-width="100px">
-                <el-form-item label="备注" prop="remark">
+              <el-col :span="16" label-width="140px">
+                <el-form-item label="下道工序间隔时长" prop="newBeatRestTime">
                   <el-input
                     v-if="!isView"
                     placeholder=""
-                    v-model="beatParam.remark"
-                    type="textarea"
-                    :rows="4"
+                    v-model="beatParam.newBeatRestTime"
+                    @blur="convertVal(beatParam.newBeatRestTime, 'beatRestTime')"
+                       oninput="value = value.replace(/[^\d.]/g, '')"
                   ></el-input>
-                  <div v-else>{{ beatParam.remark }}</div>
-                </el-form-item>
-              </el-col>
-            </el-row>
-            <el-row>
-              <el-col :span="8" label-width="100px">
-                <el-form-item label="添加人" prop="name">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    disabled
-                    v-model="beatParam.createName"
-                  ></el-input>
-                  <div v-else>{{ beatParam.createName }}</div>
+                  <div v-else>{{ beatParam.newBeatRestTime }}</div>
                 </el-form-item>
               </el-col>
 
               <el-col :span="8" label-width="100px">
-                <el-form-item label="添加时间" prop="name">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    disabled
-                    v-model="beatParam.createTime"
-                  ></el-input>
-                  <div v-else>{{ beatParam.createTime }}</div>
+                <el-form-item label="单位:" prop="beatRestUnit">
+                  <div >{{ beatParam.unit }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-row>
-              <el-col :span="8" label-width="100px">
-                <el-form-item label="修改人" prop="name">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    disabled
-                    v-model="beatParam.updateName"
-                  ></el-input>
-                  <div v-else>{{ beatParam.updateName }}</div>
-                </el-form-item>
-              </el-col>
 
-              <el-col :span="8" label-width="100px">
-                <el-form-item label="最后修改时间" prop="name">
-                  <el-input
-                    v-if="!isView"
-                    placeholder=""
-                    disabled
-                    v-model="beatParam.updateTime"
-                  ></el-input>
-                  <div v-else>{{ beatParam.updateTime }}</div>
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </el-form>
-        </el-tab-pane>
-        <el-tab-pane label="标准工时" name="标准工时">
-          <el-form label-width="100px" ref="form" :model="normalHours">
             <el-row>
               <el-col :span="16" label-width="100px">
-                <el-form-item label="标准时长" prop="type">
+                <el-form-item label="标准时长" prop="newTime">
                   <el-input
                     v-if="!isView"
                     placeholder="标准时长"
-                    v-model="normalHours.time"
+                    v-model="beatParam.newTime"
+                    @blur="convertVal(beatParam.newTime, 'time')"
+                       oninput="value = value.replace(/[^\d.]/g, '')"
                   ></el-input>
-                  <div v-else>{{ normalHours.time }}</div>
+                  <div v-else>{{ beatParam.newTime }}</div>
                 </el-form-item>
               </el-col>
               <el-col :span="8" label-width="100px">
-                <el-form-item label="单位" prop="type">
-                  <el-select
-                    v-if="!isView"
-                    v-model="normalHours.unit"
-                    filterable
-                    class="ele-block"
-                  >
-                    <el-option
-                      v-for="item in dictList"
-                      :key="item.value"
-                      :value="item.value"
-                      :label="item.label"
-                    ></el-option>
-                  </el-select>
-                  <div v-else>{{ normalHours.unit }}</div>
+                <el-form-item label="单位:" prop="">
+                  <div >{{ beatParam.unit }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
+
             <el-row>
               <el-col :span="24" label-width="100px">
                 <el-form-item label="备注" prop="remark">
                   <el-input
                     v-if="!isView"
                     placeholder=""
-                    v-model="normalHours.remark"
+                    v-model="beatParam.remark"
                     type="textarea"
                     :rows="4"
                   ></el-input>
-                  <div v-else>{{ normalHours.remark }}</div>
+                  <div v-else>{{ beatParam.remark }}</div>
                 </el-form-item>
               </el-col>
             </el-row>
           </el-form>
         </el-tab-pane>
+
         <el-tab-pane label="材料定额" name="材料定额">
           <ele-pro-table
             ref="materialTable"
@@ -440,21 +310,34 @@
             :immediate="true"
           >
             <!-- 表头工具栏 -->
-            <template v-if="!isView" v-slot:toolbar>
-              <el-button type="primary" @click="add">添加</el-button>
+            <template v-slot:toolbar>
+              <el-button type="primary" v-if="!isView" @click="add"
+                >添加</el-button
+              >
               <div class="toolbar_box">
                 <div
                   ><span>基本数量</span>
-                  <el-input placeholder="请输入" v-model.number="baseCount">
+                  <el-input
+                    placeholder="请输入"
+                    :disabled="isView"
+                    v-model.number="baseCount"
+                  >
                   </el-input>
-                  <DictSelection dictName="计量单位" v-model="baseCountUnit"
+                  <DictSelection
+                    dictName="计量单位"
+                    :disabled="isView"
+                    v-model="baseCountUnit"
                 /></div>
               </div>
             </template>
             <template v-slot:action="{ row, $index }">
-              <el-link type="primary" @click="handleDel(row, $index)"
+              <el-link type="danger" @click="handleDel(row, $index)"
                 >删除</el-link
               >
+              <el-link type="primary" @click="handSubstitution(row)"
+                >替代料</el-link
+              >
+
             </template>
             <template v-slot:subCode="{ row }">
               <div v-if="isView">{{ row.subCode }}</div>
@@ -507,7 +390,7 @@
             </template>
 
             <template v-slot:categoryName="{ row, $index }">
-              <div v-if="isView">{{ row.categoryName }}</div>
+              <el-link type="primary" :underline="false" @click="handSubstitution(row)"  v-if="isView" >{{ row.categoryName }}</el-link>
               <div v-else
                 ><el-input
                   :value="row.categoryName"
@@ -518,11 +401,7 @@
             </template>
 
             <template v-slot:bomArtFiles="{ row }">
-              <fileUpload
-              v-model="row.bomArtFiles"
-              type="add"
-              size="mini"
-            />
+              <fileUpload v-model="row.bomArtFiles" type="add" size="mini" />
             </template>
 
             <template v-slot:remark="{ row }">
@@ -635,116 +514,7 @@
             </template>
 
             <template v-slot:bomArtFiles="{ row }">
-              <fileUpload
-              v-model="row.bomArtFiles"
-              type="add"
-              size="mini"
-            />
-            </template>
-
-            <template v-slot:remark="{ row }">
-              <div v-if="isView">{{ row.remark }}</div>
-              <el-input
-                v-else
-                v-model="row.remark"
-                placeholder="请输入"
-              ></el-input>
-            </template>
-          </ele-pro-table>
-        </el-tab-pane>
-        <el-tab-pane label="替代料" name="替代料">
-          <ele-pro-table
-            ref="replaceMaterialTable"
-            :columns="columns1"
-            :datasource="datasource"
-            :need-page="false"
-            :immediate="true"
-          >
-            <!-- 表头工具栏 -->
-            <template v-if="!isView" v-slot:toolbar>
-              <el-button type="primary" @click="add">添加</el-button>
-              <div class="toolbar_box">
-                <div
-                  ><span>基本数量</span>
-                  <el-input placeholder="请输入" v-model.number="baseCount2">
-                  </el-input>
-                  <DictSelection dictName="计量单位" v-model="baseCountUnit2"
-                /></div>
-              </div>
-            </template>
-
-            <template v-slot:action="{ row, $index }">
-              <el-link type="primary" @click="handleDel(row, $index)"
-                >删除</el-link
-              >
-            </template>
-            <template v-slot:subCode="{ row }">
-              <div v-if="isView">{{ row.subCode }}</div>
-              <el-input
-                v-else
-                v-model="row.subCode"
-                placeholder="请输入"
-              ></el-input>
-            </template>
-
-            <template v-slot:isReworkBom="{ row }">
-              <div v-if="isView">{{ isReworkBom[row.isReworkBom] }}</div>
-              <div v-else>
-                <el-select v-model="row.isReworkBom">
-                  <el-option
-                    v-for="item in isReworkBomList"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  >
-                  </el-option>
-                </el-select>
-              </div>
-            </template>
-
-            <template v-slot:unit="{ row }">
-              <div v-if="isView">{{ row.unit }}</div>
-              <div v-else>
-                <DictSelection
-                  dictName="计量单位"
-                  v-model="row.unit"
-                ></DictSelection>
-              </div>
-            </template>
-
-            <template v-slot:count="{ row }">
-              <div v-if="isView">{{ row.count }}</div>
-              <el-input
-                v-else
-                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, $index }">
-              <div v-if="isView">{{ row.categoryName }}</div>
-              <div v-else
-                ><el-input
-                  :value="row.categoryName"
-                  placeholder="请选择"
-                  @click.native="categorySelect(row, $index)"
-                ></el-input
-              ></div>
-            </template>
-
-            <template v-slot:bomArtFiles="{ row }">
-              <fileUpload
-              v-model="row.bomArtFiles"
-              type="add"
-              size="mini"
-            />
+              <fileUpload v-model="row.bomArtFiles" type="add" size="mini" />
             </template>
 
             <template v-slot:remark="{ row }">
@@ -757,6 +527,7 @@
             </template>
           </ele-pro-table>
         </el-tab-pane>
+  
         <el-tab-pane label="工种" name="工种">
           <ele-pro-table
             ref="jobTable"
@@ -798,9 +569,7 @@
               <el-link type="primary" @click="handleDel(row, $index)"
                 >删除</el-link
               >
-              <el-link type="primary"  @click="fileDetails(row)"
-                >详情</el-link
-              >
+              <el-link type="primary" @click="fileDetails(row)">详情</el-link>
             </template>
           </ele-pro-table>
         </el-tab-pane>
@@ -842,7 +611,9 @@
 
     <fileIndex v-if="fileShow" @close="fileClose"></fileIndex>
 
-    <fileBrowse  ref="browseRef"></fileBrowse>
+    <fileBrowse ref="browseRef"></fileBrowse>
+
+    <replaceMaterialPop ref="replaceMaterialRef" @selected="replaceSelected" :isView="isView"></replaceMaterialPop>
 
     <div class="btns">
       <el-button
@@ -877,7 +648,8 @@
   import standardOutput from './standardOutput.vue';
   import term from '../qualityTesting/term';
   import fileIndex from '../file/index.vue';
-    import fileBrowse from '../file/fileBrowse.vue'
+  import fileBrowse from '../file/fileBrowse.vue';
+  import replaceMaterialPop from './replaceMaterialPop.vue';
   export default {
     components: {
       userSearch,
@@ -889,7 +661,8 @@
       standardOutput,
       term,
       fileIndex,
-      fileBrowse
+      fileBrowse,
+      replaceMaterialPop
     },
     mixins: [dictMixins],
     data() {
@@ -1225,8 +998,17 @@
         treeData: {},
         currentIndex: 0,
         tableData: {},
-        beatParam: {},
-        normalHours: {},
+        beatParam: {
+            newTime: '',
+            time: '',
+              newBeatPrepareTime:'',
+              beatPrepareTime:  '',
+              newBeatTime: '',
+              beatTime: '',
+              newBeatRestTime: '',
+              beatRestTime: '',
+        },
+
         qualityParam: [],
         qualityPointParam: [],
 
@@ -1242,28 +1024,25 @@
         this.fileShow = true;
       },
       fileClose(val) {
-   
         if (val == false) {
           this.fileShow = false;
         } else {
           this.fileShow = false;
 
           this.$refs.fileTable.setData([
-          ...val,
-          ...this.$refs.fileTable.getData()
-        ]);
-        this.$set(
-          this.tableData.taskParam[this.currentIndex],
-          'fileParam',
-          this.$refs.fileTable.getData()
-        );
-
-         
+            ...val,
+            ...this.$refs.fileTable.getData()
+          ]);
+          this.$set(
+            this.tableData.taskParam[this.currentIndex],
+            'fileParam',
+            this.$refs.fileTable.getData()
+          );
         }
       },
 
       fileDetails(row) {
-         this.$refs.browseRef.setFileUrl(row)
+        this.$refs.browseRef.setFileUrl(row);
       },
       addJob() {
         this.$refs.jobRef.open();
@@ -1285,9 +1064,7 @@
           type = 'materialQuota';
         } else if (this.activeName === '制造资源') {
           type = 'resource';
-        } else if (this.activeName === '替代料') {
-          type = 'replaceMaterial';
-        }
+        } 
         if (title == '选择物料') {
           this.$set(
             this.tableData.taskParam[this.currentIndex][type][idx],
@@ -1347,8 +1124,6 @@
           type = 'materialQuota';
         } else if (this.activeName === '制造资源') {
           type = 'resource';
-        } else if (this.activeName === '替代料') {
-          type = 'replaceMaterial';
         } else if (this.activeName === '工种') {
           type = 'aptitudeParam';
         } else if (this.activeName === '工艺文件') {
@@ -1362,11 +1137,9 @@
         this.tableData.taskParam[this.currentIndex][type].splice(index, 1);
       },
       addProductList(list) {
-        console.log(list, 8888);
         let subCode = 0;
         let array = [];
         list.map((item, index) => {
- 
           let max = '';
           if (
             this.tableData.taskParam[this.currentIndex]['materialQuota']
@@ -1380,7 +1153,7 @@
               ) +
               10 * ++index +
               '';
-            console.log(max);
+
             if (max.length < 4) {
               max = new Array(4 - max.length).fill('0').join('') + max;
             }
@@ -1391,8 +1164,16 @@
             }
           }
 
+          console.log('item', this.isValueANumber(item.specification));
 
-
+          if (
+            item.categoryLevelPathIdParent == 8 &&
+            this.isValueANumber(this.baseCount) &&
+            this.isValueANumber(item.specification)
+          ) {
+            let num = this.baseCount / item.specification;
+            item.count = num == 'Infinity' ? '' : num.toFixed(3);
+          }
 
           subCode = max.substring(0, max.length - 1) + '0';
           array.push({
@@ -1402,28 +1183,63 @@
             categoryCode: item.categoryCode,
             isReworkBom: 0,
             brandNum: item.brandNum,
-            count: '',
+            count: item.count || '',
             modelType: item.modelType,
             unit: item.measuringUnit,
             bomArtFiles: [],
             remark: '',
             specification: item.specification,
             rootCategoryLevelId: item.categoryLevelPathIdParent,
-            extInfo:item.extInfo,
-     
-
+            extInfo: item.extInfo
           });
         });
-  
-        this.tableData.taskParam[this.currentIndex].materialQuota =
-          this.tableData.taskParam[this.currentIndex].materialQuota.concat(
-            array
-          );
-     
+
+            let _arr =   this.tableData.taskParam[this.currentIndex].materialQuota.concat(
+                    array
+                  );
+             let uniqueArray = []
+
+            uniqueArray = _arr.reduce((acc, current) => {
+            const existing = acc.find(item => item.id === current.id);
+            if (!existing) {
+                acc.push(current);
+            }
+            return acc;
+        }, []);
+
+
+
+        this.tableData.taskParam[this.currentIndex].materialQuota = uniqueArray
+       
+
+
+
         this.$refs.materialTable.setData(
           this.tableData.taskParam[this.currentIndex].materialQuota
         );
       },
+
+      isValueANumber(variable) {
+        if (variable === undefined || variable === null) {
+          return false; // 变量没有值
+        }
+        if (typeof variable === 'number') {
+          return true; // 基本类型的数字
+        }
+        if (
+          (typeof variable === 'string' &&
+            !isNaN(variable) &&
+            !variable.includes('.')) ||
+          (variable.includes('.') && !variable.endsWith('.'))
+        ) {
+          // 字符串类型的数字(注意:这个正则表达式判断较为简单,可能需要根据实际情况调整)
+          // 或者使用 Number.isFinite(parseFloat(variable)) 来代替这部分逻辑,但要注意性能开销和边缘情况
+          const num = Number(variable);
+          return !isNaN(num) && isFinite(num);
+        }
+        return false; // 其他类型
+      },
+
       add() {
         let subCode = '0010';
         let type = '';
@@ -1438,8 +1254,6 @@
           return;
         } else if (this.activeName === '制造资源') {
           type = 'resource';
-        } else if (this.activeName === '替代料') {
-          type = 'replaceMaterial';
         }
         console.log(this.tableData.taskParam[this.currentIndex]);
         if (this.tableData.taskParam[this.currentIndex][type].length) {
@@ -1485,12 +1299,11 @@
           this.qualityParam =
             this.tableData.taskParam[this.currentIndex].qualityParam || [];
         } else if (this.activeName === '生产节拍') {
-          console.log(this.tableData.taskParam[this.currentIndex].beatParam);
+      
           this.beatParam =
-            this.tableData.taskParam[this.currentIndex].beatParam || {};
-        } else if (this.activeName === '标准工时') {
-          this.normalHours =
-            this.tableData.taskParam[this.currentIndex].normalHours || {};
+            this.tableData.taskParam[this.currentIndex].beatParam || this.beatParam;
+
+
         } else if (this.activeName === '材料定额') {
           this.$refs.materialTable.setData(
             this.tableData.taskParam[this.currentIndex].materialQuota || []
@@ -1499,10 +1312,6 @@
           this.$refs.resourceTable.setData(
             this.tableData.taskParam[this.currentIndex].resource || []
           );
-        } else if (this.activeName === '替代料') {
-          this.$refs.replaceMaterialTable.setData(
-            this.tableData.taskParam[this.currentIndex].replaceMaterial || []
-          );
         } else if (this.activeName === '工种') {
           if (
             JSON.stringify(
@@ -1671,8 +1480,7 @@
           this.tableData.taskParam[this.currentIndex].beatParam =
             this.beatParam;
           // 保存标准工时
-          this.tableData.taskParam[this.currentIndex].normalHours =
-            this.normalHours;
+
           // 保存材料定额
           this.tableData.taskParam[this.currentIndex].baseCount =
             this.baseCount;
@@ -1714,8 +1522,81 @@
           acc.push({ value, label: value }); // 将 { value, label } 格式的对象添加到数组中
           return acc;
         }, []); // 初始值为空数组 []
-      }
+      },
+
+
+
+   convertToSeconds(time) {
+    switch (this.beatParam.unit) {
+        case '秒':
+            return time;
+        case '分钟':
+            return time * 60;
+        case '小时':
+            return time * 3600;
+        case '天':
+            return time * 86400; // 24小时 * 60分钟 * 60秒
+        case '月':
+            // 近似值,一个月按30天计算
+            return time * 86400 * 30; 
+        case '年':
+            // 近似值,一年按365天计算
+            return time * 86400 * 365; 
+        case '毫秒':
+            return time / 1000;
+        case '微秒':
+            return time / 1000000;
+        default:
+          this.$message.error('不支持的时间单位: ' + unit);
     }
+},
+
+convertVal(val, name) {
+  if(!this.beatParam.unit) {
+      return this.$message.error('请选择时间单位');
+  }
+  
+  const isNumeric = /^\d*(\.\d+)?$/.test(val);
+  if(isNumeric) {
+    this.beatParam[name] = this.convertToSeconds(val);
+  } else {
+    this.$message.error('请输入数字');
+    this.beatParam[name] = ''
+  }
+ 
+
+
+},
+
+changeUnit() {
+   this.beatParam.newTime = '';
+  this.beatParam.time = '';
+  this.beatParam.newBeatPrepareTime = '';
+  this.beatParam.beatPrepareTime = '';
+  this.beatParam.newBeatTime = '';
+  this.beatParam.beatTime = '';
+  this.beatParam.newBeatRestTime = '';
+  this.beatParam.beatRestTime = '';
+
+},
+
+handSubstitution(row) {
+    this.$refs.replaceMaterialRef.open(row);
+},
+replaceSelected(id, list) {
+
+ let _arr = []
+ _arr =  this.tableData.taskParam[this.currentIndex].materialQuota 
+ _arr.forEach(item => {
+  if(item.id === id) {
+    item.replaceMaterial = list;
+  }
+ })
+ this.tableData.taskParam[this.currentIndex].materialQuota = _arr
+
+}
+
+    } 
   };
 </script>
 

+ 51 - 4
src/views/material/BOMmanage/components/workingStep.vue

@@ -595,8 +595,17 @@
             :immediate="true"
           >
             <!-- 表头工具栏 -->
-            <template v-if="!isView" v-slot:toolbar>
-              <el-button type="primary" @click="add">添加</el-button>
+            <template  v-slot:toolbar>
+              <el-button type="primary" v-if="!isView" @click="add">添加</el-button>
+              <div class="toolbar_box">
+                <div
+                  ><span>基本数量</span>
+                  <el-input placeholder="请输入" v-model.number="baseCount">
+                  </el-input>
+                  <DictSelection dictName="计量单位" v-model="baseCountUnit"
+                /></div>
+              </div>
+          
             </template>
             <template v-slot:action="{ row, $index }">
               <el-link type="primary" @click="handleDel(row, $index)"
@@ -821,8 +830,18 @@
             :immediate="true"
           >
             <!-- 表头工具栏 -->
-            <template v-if="!isView" v-slot:toolbar>
-              <el-button type="primary" @click="add">添加</el-button>
+            <template v-slot:toolbar>
+              <el-button type="primary"  v-if="!isView" @click="add">添加</el-button>
+
+              <div class="toolbar_box">
+                <div
+                  ><span>基本数量</span>
+                  <el-input placeholder="请输入" v-model.number="baseCount2">
+                  </el-input>
+                  <DictSelection dictName="计量单位" v-model="baseCountUnit2"
+                /></div>
+              </div>
+              
             </template>
             <template v-slot:action="{ row, $index }">
               <el-link type="primary" @click="handleDel(row, $index)"
@@ -960,6 +979,11 @@
     },
     data() {
       return {
+        baseCount: '',
+        baseCountUnit: '',
+        baseCount2: '',
+        baseCountUnit2: '',
+
         isView: false,
         filedList: [],
         activeName: '工艺参数',
@@ -1309,6 +1333,13 @@
           this.rowData = data;
           this.treeData = JSON.parse(JSON.stringify(treeData));
           this.activeName = '工艺参数';
+
+          this.baseCount = rowData.baseCount;
+          this.baseCountUnit = rowData.baseCountUnit;
+
+         this.baseCount2 = rowData.baseCount2;
+         this.baseCountUnit2 = rowData.baseCountUnit2;
+
           this.visible = true;
           setTimeout(() => {
             // 工艺参数
@@ -1368,4 +1399,20 @@
   .downLoad {
     display: flex;
   }
+
+  .toolbar_box {
+    float: right;
+    margin-right: 10px;
+    > div {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      > span {
+        width: 150px;
+      }
+      > div {
+        margin-left: 10px;
+      }
+    }
+  }
 </style>

+ 1 - 0
src/views/material/BOMmanage/components/workmanship.vue

@@ -45,6 +45,7 @@
         ref="table"
         :columns="columns"
         :datasource="datasource"
+        
         :need-page="false"
         row-key="id"
       >

+ 20 - 15
src/views/material/BOMmanage/detailsPop.vue

@@ -10,27 +10,27 @@
       <!-- 自定义头部 -->
       <div class="custom-drawer-header" v-if="!isWt">
         <div class="radio_box rx-cc">
+           {{  clientEnvironmentId }}
           <el-radio-group
             size="small"
             v-model="currentNodeData.bomType"
             @change="bomChange"
           >
-            <el-radio-button :label="4">EBOM </el-radio-button>
-            <el-radio-button :label="1">PBOM </el-radio-button>
-            <el-radio-button
-              :label="2"
-              v-if="
+            <el-radio-button :label="4" v-if="clientEnvironmentId != 2">EBOM </el-radio-button>
+            <el-radio-button :label="1"  v-if="clientEnvironmentId != 2">PBOM </el-radio-button>
+
+            <!-- v-if="
                 searchObj.isProduct ||
                 [1, 9].includes(searchObj.rootPathIdParent)
-              "
+              " -->
+            <el-radio-button
+              :label="2"
+           
               >MBOM
             </el-radio-button>
             <el-radio-button
               :label="3"
-              v-if="
-                searchObj.isProduct ||
-                [1, 9].includes(searchObj.rootPathIdParent)
-              "
+              v-if="clientEnvironmentId != 2"
               >ABOM
             </el-radio-button>
           </el-radio-group>
@@ -283,11 +283,12 @@
                 label="工序配置"
                 name="工序配置"
                 v-if="
-                  currentNodeData.bomType != 4 && currentNodeData.bomType != 1  &&
-                  (searchObj.isProduct ||
-                    [1, 9].includes(searchObj.rootPathIdParent))
+                  currentNodeData.bomType != 4 && currentNodeData.bomType != 1  
+                
                 "
               >
+             <!-- && (searchObj.isProduct ||
+              [1, 9].includes(searchObj.rootPathIdParent)) -->
                 <workmanship
                   v-if="activeName == '工序配置'"
                   ref="workmanshipRef"
@@ -393,7 +394,7 @@
         isFullscreen: true,
 
         currentNodeData: {
-          bomType: 1,
+          bomType: this.clientEnvironmentId == 2 ?  2:  1,
           children: []
         },
 
@@ -455,6 +456,7 @@
 
         if (Object.prototype.hasOwnProperty.call(row, 'bomType')) {
           this.currentNodeData.bomType = row.bomType;
+        
         }
         this.drawer = true;
         this.getTreeData();
@@ -526,12 +528,15 @@
         if (id) {
           getBomGetById(id).then((res) => {
             this.currentNodeData = res.data;
+            if(this.clientEnvironmentId == 2) {
+              this.currentNodeData.bomType = 2;
+            }
             this.searchObj.versions = this.currentNodeData.versions;
             this.$forceUpdate();
           });
         } else {
           this.currentNodeData = {
-            bomType: 1,
+            bomType: this.clientEnvironmentId == 2 ?  2:  1,
             children: []
           };
         }

+ 151 - 135
src/views/material/product/components/CategoryDialog.vue

@@ -1,9 +1,25 @@
 <template>
-  <ele-modal :title="title" :visible.sync="treeVisible" :before-close="handleClose" :close-on-click-modal="false"
-    :close-on-press-escape="false" append-to-body width="30%">
+  <ele-modal
+    :title="title"
+    :visible.sync="treeVisible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="30%"
+  >
     <div class="ele-border-lighter sys-organization-list">
-      <el-tree :data="treeList" :props="defaultProps" v-loading="treeLoading" :node-key="nodeKey" ref="tree"
-        :highlight-current="true" :expand-on-click-node="false" @node-click="handleNodeClick" v-bind="$attrs">
+      <el-tree
+        :data="treeList"
+        :props="defaultProps"
+        v-loading="treeLoading"
+        :node-key="nodeKey"
+        ref="tree"
+        :highlight-current="true"
+        :expand-on-click-node="false"
+        @node-click="handleNodeClick"
+        v-bind="$attrs"
+      >
       </el-tree>
     </div>
     <template v-slot:footer>
@@ -14,156 +30,156 @@
 </template>
 
 <script>
-import { getTreeByGroup, getTreeByPid } from '@/api/classifyManage';
-export default {
-  data() {
-    return {
-      treeVisible: false,
-      treeList: [],
-      current: null,
-      title: '选择分类',
-      pathList: [],
-
-      oneProduct: null,
-
-      treeLoading: false,
-      nodeKey: 'id',
-      defaultProps: {
-        children: 'children',
-        value: 'id',
-        label: 'name'
-      }
-    }
-  },
-
-  watch: {
-
-  },
-  methods: {
-    open() {
-      this.treeVisible = true
-      this.oneProduct = this.$route.query.oneProduct;
-      this.getTreeData()
-    },
-    handleClose() {
-      this.treeVisible = false
-      this.current = null
-    },
-    // 获取树结构数据
-    async getTreeData() {
-      try {
-        this.treeLoading = true;
-         let res 
-        if(this.oneProduct == 'false') {
-           res = await getTreeByGroup({ type: 5 });
-        } else if(this.oneProduct == 'true') {
-           res = await getTreeByPid(9)
-        } else {
-           res = await getTreeByGroup({ type: 1 });
+  import { getTreeByGroup, getTreeByPid } from '@/api/classifyManage';
+  export default {
+    data() {
+      return {
+        treeVisible: false,
+        treeList: [],
+        current: null,
+        title: '选择分类',
+        pathList: [],
+
+        oneProduct: null,
+
+        treeLoading: false,
+        nodeKey: 'id',
+        defaultProps: {
+          children: 'children',
+          value: 'id',
+          label: 'name'
         }
-
-      
-        this.treeLoading = false;
-        if (res?.code === '0') {
-          this.treeList = res.data;
-
-
-          return this.treeList;
-        }
-      } catch (error) { }
-      this.treeLoading = false;
-    },
-
-
-    handleNodeClick(data, node) {
-      this.$emit('handleNodeClick', data, node);
-      this.current = data
+      };
     },
 
-    selected() {
-      if (!this.current) {
-        return this.$message.warning(`请${this.title}`)
-      }
-      this.pathList = this.findParent([], this.current, this.treeList)
-
-
+    watch: {},
+    methods: {
+      open() {
+        this.treeVisible = true;
+        this.oneProduct = this.$route.query.oneProduct;
+        this.getTreeData();
+      },
+      handleClose() {
+        this.treeVisible = false;
+        this.current = null;
+      },
+      // 获取树结构数据
+      async getTreeData() {
+        try {
+          this.treeLoading = true;
+          let res;
+          if (this.oneProduct == 'false') {
+            res = await getTreeByGroup({ type: 5 });
+          } else if (this.oneProduct == 'true') {
+            res = await getTreeByPid(9);
+          } else {
+            res = await getTreeByGroup({ type: 1 });
+          }
 
-      let ruleCode = null
-      if (this.pathList.length == 0) {
-        ruleCode = this.current.ruleCode
+          this.treeLoading = false;
+          if (res?.code === '0') {
+            this.treeList = res.data;
 
-      } else {
-        ruleCode = this.pathList[this.pathList.length - 1] && this.pathList[this.pathList.length - 1].ruleCode
-      }
+            return this.treeList;
+          }
+        } catch (error) {}
+        this.treeLoading = false;
+      },
 
+      handleNodeClick(data, node) {
+        this.$emit('handleNodeClick', data, node);
+        this.current = data;
+      },
 
-      this.pathList.unshift(this.current)
-      const PathInfo = {
-        categoryLevelPath: '',
-        categoryLevelPathId: [],
-        rootCategoryLevelId: null
-      }
-      const pathName = []
-      this.pathList.map(item => {
-        pathName.unshift(item.name)
-        PathInfo.categoryLevelPathId.unshift(item.id)
-        PathInfo.rootCategoryLevelId = item.rootCategoryLevelId
-      })
-      PathInfo.categoryLevelPath = pathName.join('-')
-      PathInfo.categoryLevelPathId = PathInfo.categoryLevelPathId.join(',')
-
-      console.log(PathInfo)
-      this.$emit('chooseCategory', this.current, this.title, PathInfo, ruleCode)
-      this.handleClose()
-    },
+      selected() {
+        if (!this.current) {
+          return this.$message.warning(`请${this.title}`);
+        }
+        this.pathList = this.findParent([], this.current, this.treeList);
 
-    // parents:用于返回的数组,childNode:要查询的节点,treeList:json树形数据
-    findParent(parents, childNode, treeList) {
-      for (let i = 0; i < treeList.length; i++) {
-        // 父节点查询条件
-        if (treeList[i].id === childNode.parentId) {
-          // 如果找到结果,保存当前节点
-          parents.push(treeList[i])
-          // 用当前节点再去原数据查找当前节点的父节点
-          this.findParent(parents, treeList[i], this.treeList)
-          break
+        let ruleCode = null;
+        if (this.pathList.length == 0) {
+          ruleCode = this.current.ruleCode;
         } else {
-          if (treeList[i].children instanceof Array) {
-            //	没找到,遍历该节点的子节点
-            this.findParent(parents, childNode, treeList[i].children)
+          ruleCode =
+            this.pathList[this.pathList.length - 1] &&
+            this.pathList[this.pathList.length - 1].ruleCode;
+        }
+
+        this.pathList.unshift(this.current);
+        const PathInfo = {
+          categoryLevelPath: '',
+          categoryLevelPathId: [],
+          rootCategoryLevelId: null
+        };
+        const pathName = [];
+        this.pathList.map((item) => {
+          pathName.unshift(item.name);
+          PathInfo.categoryLevelPathId.unshift(item.id);
+          PathInfo.rootCategoryLevelId = item.rootCategoryLevelId;
+        });
+        PathInfo.categoryLevelPath = pathName.join('-');
+        PathInfo.categoryLevelPathId = PathInfo.categoryLevelPathId.join(',');
+
+        console.log(PathInfo);
+        this.$emit(
+          'chooseCategory',
+          this.current,
+          this.title,
+          PathInfo,
+          ruleCode
+        );
+        this.handleClose();
+      },
+
+      // parents:用于返回的数组,childNode:要查询的节点,treeList:json树形数据
+      findParent(parents, childNode, treeList) {
+        for (let i = 0; i < treeList.length; i++) {
+          // 父节点查询条件
+          if (treeList[i].id === childNode.parentId) {
+            // 如果找到结果,保存当前节点
+            parents.push(treeList[i]);
+            // 用当前节点再去原数据查找当前节点的父节点
+            this.findParent(parents, treeList[i], this.treeList);
+            break;
+          } else {
+            if (treeList[i].children instanceof Array) {
+              //	没找到,遍历该节点的子节点
+              this.findParent(parents, childNode, treeList[i].children);
+            }
           }
         }
+        return parents;
       }
-      return parents
     }
-
-  }
-}
+  };
 </script>
 
 <style lang="scss" scoped>
-.sys-organization-list {
-  height: calc(100vh - 264px);
-  box-sizing: border-box;
-  border-width: 1px;
-  border-style: solid;
-  overflow: auto;
-}
-
-.sys-organization-list :deep(.el-tree-node__content) {
-  height: 30px;
-
-  &>.el-tree-node__expand-icon {
-    margin-left: 10px;
+  .sys-organization-list {
+    height: calc(100vh - 264px);
+    box-sizing: border-box;
+    border-width: 1px;
+    border-style: solid;
+    overflow: auto;
   }
-}
 
+  .sys-organization-list :deep(.el-tree-node__content) {
+    height: 30px;
+
+    & > .el-tree-node__expand-icon {
+      margin-left: 10px;
+    }
+  }
 
-::v-deep .el-tree-node__content:hover{
-  background-color: #e6f7ff !important;
-}
+  ::v-deep .el-tree-node__content:hover {
+    background-color: #e6f7ff !important;
+  }
 
-::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
+  ::v-deep
+    .el-tree--highlight-current
+    .el-tree-node.is-current
+    > .el-tree-node__content {
     background-color: #40a9ff !important;
-}
+  }
 </style>

+ 27 - 25
src/views/material/product/components/index-data.vue

@@ -122,17 +122,17 @@
           </template>
         </el-popconfirm>
 
-        <el-link
+        <!-- <el-link
           type="primary"
           v-if="row.isProduct == 1"
           :underline="false"
           @click="openParam(row)"
         >
           工艺参数
-        </el-link>
+        </el-link> -->
 
         <el-link type="primary" :underline="false" @click="toBomManager(row)">
-          结构BOM
+          BOM
         </el-link>
 
         <!-- <el-link
@@ -274,7 +274,8 @@
 
       rootTreeId: [Number, String],
 
-      oneProduct: Boolean
+      oneProduct: Boolean,
+      currentData: Object
     },
     data() {
       return {
@@ -494,6 +495,7 @@
 
       /* 显示编辑 */
       openEdit(row, status) {
+        console.log(status, this.currentData, 'status');
         this.$router.push({
           path: '/material/product/detail',
           query: {
@@ -501,7 +503,9 @@
             status: status,
             rootId: this.rootId,
             oneProduct: this.oneProduct,
-            t: new Date().getTime()
+            t: new Date().getTime(),
+            rootTreeId: this.rootTreeId,
+            ...this.currentData
           }
         });
       },
@@ -510,13 +514,14 @@
         const loading = this.$loading({ lock: true });
         removeMaterial(row.id)
           .then((msg) => {
+            this.$refs.table.reload({
+              page: 1,
+              categoryLevelId: this.currentId
+            });
             loading.close();
-            this.$message.success('删除' + msg);
-            this.reload();
           })
           .catch((e) => {
             loading.close();
-            // this.$message.error(e.message);
           });
       },
 
@@ -581,27 +586,24 @@
         handler(route) {
           this.pageShow = false;
           if (route.query && route.query.isWt) {
-
             getBomGetById(route.query.businessId).then((res) => {
               let rowData = {
-              categoryId: res.data.categoryId,
-              categoryName: res.data.name,
-              code: res.data.categoryCode,
-              rootPathIdParent: res.data.rootCategoryLevelId,
-              isProduct: res.data.rootCategoryLevelId == 9 ? true : false,
-              versions: res.data.versions,
-              bomType: res.data.bomType,
-              isWt: true
-            };
-            this.$nextTick(() => {
-              this.$refs.bomDrawer.open(rowData);
-              this.pageShow = true; 
-            })
-
+                categoryId: res.data.categoryId,
+                categoryName: res.data.name,
+                code: res.data.categoryCode,
+                rootPathIdParent: res.data.rootCategoryLevelId,
+                isProduct: res.data.rootCategoryLevelId == 9 ? true : false,
+                versions: res.data.versions,
+                bomType: res.data.bomType,
+                isWt: true
+              };
+              this.$nextTick(() => {
+                this.$refs.bomDrawer.open(rowData);
+                this.pageShow = true;
+              });
             });
-
           } else {
-            this.pageShow = true; 
+            this.pageShow = true;
           }
         },
         immediate: true

+ 74 - 18
src/views/material/product/detail.vue

@@ -24,20 +24,16 @@
             </el-form-item>
           </el-col>
 
-          <el-col :span="8" v-if="ruleCode == '自定义'" key="1">
+          <el-col :span="8">
             <el-form-item label="编码" prop="code">
               <el-input
+                v-if="ruleCode == '自定义'"
                 v-model="form.code"
                 readonly
                 @click.native="openCode"
                 :disabled="status == 0"
               />
-            </el-form-item>
-          </el-col>
-
-          <el-col :span="8" v-else key="2">
-            <el-form-item label="编码" prop="code">
-              <el-input v-model="form.code" :disabled="status == 0" />
+              <el-input v-else v-model="form.code" :disabled="status == 0" />
             </el-form-item>
           </el-col>
 
@@ -54,7 +50,6 @@
           </el-col>
 
           <el-col :span="8">
-         
             <el-form-item label="生产类型" prop="produceType">
               <el-select
                 style="width: 100%"
@@ -74,7 +69,7 @@
 
           <el-col
             :span="8"
-            v-if="[1, 23, 9, 28].includes(Number(categoryLevelPathId))"
+            v-if="[1, 23, 9, 28].includes(Number(categoryLevelPathId  || $route.query.rootTreeId))"
           >
             <el-form-item label="加工类型" prop="isConsumable">
               <el-select
@@ -193,7 +188,7 @@
             <el-form-item :label="f.label">
               <template>
                 <div class="form-line">
-                  <component              
+                  <component
                     :is="f.tagType"
                     v-model="form.extField[f.prop]"
                     :disabled="f.extAttribute?.disabled"
@@ -391,7 +386,7 @@
           } else {
             this.form = {
               categoryLevelGroupName: '',
-              categoryLevelName: '',
+              // categoryLevelName: '',
               isConsumable: 1,
 
               extField: {}
@@ -421,9 +416,55 @@
         immediate: true
       }
     },
+    async activated() {
+      this.status = this.$route.query.status;
+      this.form.categoryLevelId = this.$route.query.categoryLevelId;
+      this.form.categoryLevelName = this.$route.query.categoryLevelName;
+      this.form.categoryLevelPath = this.$route.query.categoryLevelPath;
+      this.form.categoryLevelPathId = this.$route.query.categoryLevelPathId;
+
+      this.ruleCode = this.$route.query.ruleCode;
+      if (this.ruleCode && this.ruleCode != '自定义' && this.status != 0) {
+        const code = await getCode(this.ruleCode);
+        this.$set(this.form, 'code', code);
+      }
+
+      this.getFieldModel();
+
+      this.getDictList('productionType');
+    },
     async created() {
+      //新增
+
+      this.$set(
+        this.form,
+        'categoryLevelId',
+        this.$route.query.categoryLevelId
+      );
+      this.$set(
+        this.form,
+        'categoryLevelName',
+        this.$route.query.categoryLevelName
+      );
+      this.$set(
+        this.form,
+        'categoryLevelPath',
+        this.$route.query.categoryLevelPath
+      );
+      this.$set(
+        this.form,
+        'categoryLevelPathId',
+        this.$route.query.categoryLevelPathId
+      );
+
+      this.ruleCode = this.$route.query.ruleCode;
+      if (this.ruleCode && this.ruleCode != '自定义' && this.status != 0) {
+        const code = await getCode(this.ruleCode);
+        this.$set(this.form, 'code', code);
+      }
+
       this.getFieldModel();
-      this.status = this.$route.query.status;
+
       // if (this.$route.query.id) {
       //   this._getDetails();
       // }
@@ -440,7 +481,6 @@
         this.form = {
           ...info.category
         };
-   
 
         this.categoryLevelPathId = info.category.categoryLevelPathIdParent;
         this.judgeSet(info);
@@ -449,6 +489,8 @@
           rootCategoryCode(this.categoryLevelPathId).then((res) => {
             this.$set(this.form, 'code', res);
           });
+
+          this.form.createTime = null;
         }
 
         this.$forceUpdate();
@@ -549,7 +591,6 @@
             label: item[values[0]]
           };
         });
- 
       },
 
       openCategory() {
@@ -575,7 +616,7 @@
       submit() {
         this.$refs.manageForm.validate(async (valid) => {
           let productionValid = await this.$refs.productionRefs.getFormValid();
-          console.log(productionValid);
+
           if (!valid || !productionValid) {
             return false;
           }
@@ -693,13 +734,28 @@
               }
             );
           }
-
+          console.log('保存', this.$route.query.rootTreeId);
           addMaterial(data)
             .then((msg) => {
               this.loading = false;
               this.$message.success(msg);
-              reloadPageTab({ fullPath: '/material/product' });
-              this.$router.go(-1);
+              // reloadPageTab({ fullPath: '/material/product' });
+              // this.$router.go(-1);
+              if (this.$route.query.rootTreeId == 9) {
+                this.$router.push({
+                  path: '/product/oneProduct',
+                  query: {
+                    categoryLevelId: this.form.categoryLevelId
+                  }
+                });
+              } else {
+                this.$router.push({
+                  path: '/material/product',
+                  query: {
+                    categoryLevelId: this.form.categoryLevelId
+                  }
+                });
+              }
             })
             .catch((e) => {
               this.loading = false;

+ 231 - 141
src/views/material/product/index.vue

@@ -1,11 +1,21 @@
 <template>
   <div class="ele-body">
     <el-card shadow="never">
-      <ele-split-layout width="300px" allow-collapse :right-style="{ overflow: 'hidden' }">
+      <ele-split-layout
+        width="300px"
+        allow-collapse
+        :right-style="{ overflow: 'hidden' }"
+      >
         <div class="ele-border-lighter sys-organization-list">
-          <el-tree :data="treeList" :props="defaultProps" ref="treeRef"
-            :default-expanded-keys="current && current.id ? [current.id] : []" :highlight-current="true" node-key="id"
-            @node-click="handleNodeClick"></el-tree>
+          <el-tree
+            :data="treeList"
+            :props="defaultProps"
+            ref="treeRef"
+            :default-expanded-keys="current && current.id ? [current.id] : []"
+            :highlight-current="true"
+            node-key="id"
+            @node-click="handleNodeClick"
+          ></el-tree>
         </div>
 
         <template v-slot:content>
@@ -66,7 +76,16 @@
 
             <IndexSearch @search="reload" />
 
-            <IndexData ref="listData" v-if="current" :current-id="current.id" :data="current" :rootTreeId="rootTreeId" :rootId="rootId" :oneProduct="false" >
+            <IndexData
+              ref="listData"
+              v-if="current"
+              :current-id="current.id"
+              :data="current"
+              :rootTreeId="rootTreeId"
+              :rootId="rootId"
+              :oneProduct="false"
+              :currentData="currentData"
+            >
             </IndexData>
           </div>
         </template>
@@ -75,167 +94,238 @@
   </div>
 </template>
 <script>
-import IndexData from './components/index-data.vue';
-import IndexSearch from './components/index-search.vue';
-
-import dictMixins from '@/mixins/dictMixins';
-import { getTreeByGroup } from '@/api/classifyManage';
-
-import { getInfoById } from '@/api/classifyManage';
-
-export default {
-  components: {
-    IndexData,
-    IndexSearch
-  },
-  mixins: [dictMixins],
-  data() {
-    return {
-      loading: false,
-      current: {},
-      curNode: {},
-      treeList: [],
-      treeLoading: false,
-      formData: {},
-       rootTreeId: null,
-      defaultProps: {
-        children: 'children',
-        label: 'name'
-      }
-    };
-  },
+  import IndexData from './components/index-data.vue';
+  import IndexSearch from './components/index-search.vue';
 
-  computed: {
-    // 是否开启响应式布局
-    styleResponsive() {
-      return this.$store.state.theme.styleResponsive;
-    },
+  import dictMixins from '@/mixins/dictMixins';
+  import { getTreeByGroup } from '@/api/classifyManage';
+
+  import { getInfoById } from '@/api/classifyManage';
 
-    rootId() {
-      return this.$route.query.id;
+  import { reloadPageTab } from '@/utils/page-tab-util';
+
+  export default {
+    components: {
+      IndexData,
+      IndexSearch
+    },
+    mixins: [dictMixins],
+    data() {
+      return {
+        loading: false,
+        current: {},
+        curNode: {},
+        treeList: [],
+        treeLoading: false,
+        formData: {},
+        rootTreeId: null,
+        defaultProps: {
+          children: 'children',
+          label: 'name'
+        },
+        currentData: {}
+      };
     },
 
-    fullName() {
-      let str = '';
-      let codeStr = '';
-      let node = this.curNode;
-      while (node?.data?.name) {
-        str = node.data.name + '-' + str;
-        codeStr = node.data.code + '-' + codeStr;
-        node = node?.parent;
+    computed: {
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      },
+
+      rootId() {
+        return this.$route.query.id;
+      },
+
+      fullName() {
+        let str = '';
+        let codeStr = '';
+        let node = this.curNode;
+        while (node?.data?.name) {
+          str = node.data.name + '-' + str;
+          codeStr = node.data.code + '-' + codeStr;
+          node = node?.parent;
+        }
+
+        return str.substring(str, str.length - 1);
+        // return (
+        //   str.substring(str, str.length - 1) +
+        //   `(${codeStr.substring(str, str.length - 1)})`
+        // );
       }
+    },
+    created() {
+      this.getTreeData();
+    },
+    methods: {
+      async getTreeData() {
+        try {
+          this.treeLoading = true;
 
-      return str.substring(str, str.length - 1);
-      // return (
-      //   str.substring(str, str.length - 1) +
-      //   `(${codeStr.substring(str, str.length - 1)})`
-      // );
-    }
-  },
-  created() {
-    this.getTreeData();
-  },
-  methods: {
-    async getTreeData() {
-      try {
-        this.treeLoading = true;
-
-        const res = await getTreeByGroup({ type: 5 });
+          const res = await getTreeByGroup({ type: 5 });
+          this.treeLoading = false;
+          if (res?.code === '0') {
+            this.treeList = res.data;
+
+            if (!this.$route.query.categoryLevelId) {
+              this.$nextTick(() => {
+                //默认高亮第一级树节点;
+                if (this.treeList[0]) {
+                  this.rootTreeId = this.treeList[0].id;
+                  this.getDetail(this.treeList[0].id);
+                }
+              });
+            } else {
+              this.getDetail(this.$route.query.categoryLevelId);
+              this.$nextTick(() => {
+                this.$refs.treeRef.setCurrentKey(
+                  this.$route.query.categoryLevelId
+                );
+              });
+              const objByid = this.findNodeById(
+                this.treeList,
+                this.$route.query.categoryLevelId
+              );
+              console.log(objByid, '当前选择的物品');
+              this.publicfun(objByid);
+            }
+            return this.treeList;
+          }
+        } catch (error) {}
         this.treeLoading = false;
-        if (res?.code === '0') {
-          this.treeList = res.data;
+      },
 
+      async getDetail(id) {
+        this.loading = true;
+        const res = await getInfoById(id);
+        this.loading = false;
+        if (res.code == '0') {
+          this.current = res.data;
           this.$nextTick(() => {
-            // 默认高亮第一级树节点
-            if (this.treeList[0]) {
-              this.rootTreeId = this.treeList[0].id
-              this.getDetail(this.treeList[0].id);
-            }
+            this.$refs.treeRef.setCurrentKey(this.current.id);
           });
-          return this.treeList;
         }
-      } catch (error) { }
-      this.treeLoading = false;
-    },
+      },
+      findNodeById(tree, targetId) {
+        function traverse(nodes) {
+          for (let node of nodes) {
+            if (node.id === targetId) {
+              return node;
+            } else if (node.children && node.children.length > 0) {
+              const foundNode = traverse(node.children);
+              if (foundNode) {
+                return foundNode;
+              }
+            }
+          }
+          return null;
+        }
 
-    async getDetail(id) {
-      this.loading = true;
-      const res = await getInfoById(id);
-      this.loading = false;
-      if (res.code == '0') {
-        this.current = res.data;
-        this.$nextTick(() => {
-          this.$refs.treeRef.setCurrentKey(this.current.id);
-        });
-      }
-    },
+        return traverse(tree);
+      },
 
-    handleNodeClick(data, node) {
-      this.curNode = node;
-      this.pathList = this.findParent([], data, this.treeList)
-        this.rootTreeId = null
-      if (this.pathList.length == 0) {
-        this.rootTreeId  = data.id
+      async handleNodeClick(data, node) {
+        this.$route.query.categoryLevelId = '';
 
-      } else {
-        this.rootTreeId  = this.pathList[this.pathList.length - 1] && this.pathList[this.pathList.length - 1].id
-      }
+        this.curNode = node;
+        await this.publicfun(data);
+        await this.getDetail(data.id);
+      },
+      publicfun(data) {
+        this.pathList = this.findParent([], data, this.treeList);
+        this.rootTreeId = null;
+        if (this.pathList.length == 0) {
+          this.rootTreeId = data.id;
+        } else {
+          this.rootTreeId =
+            this.pathList[this.pathList.length - 1] &&
+            this.pathList[this.pathList.length - 1].id;
+        }
 
+        let ruleCode = null;
+        if (this.pathList.length == 0) {
+          ruleCode = data.ruleCode;
+        } else {
+          ruleCode =
+            this.pathList[this.pathList.length - 1] &&
+            this.pathList[this.pathList.length - 1].ruleCode;
+        }
 
-      this.getDetail(data.id);
-    },
+        this.pathList.unshift(data);
+        const PathInfo = {
+          categoryLevelPath: '',
+          categoryLevelPathId: [],
+          // rootCategoryLevelId: null,
+          categoryLevelId: '',
+          categoryLevelName: '',
+          ruleCode: ''
+        };
+        const pathName = [];
+        this.pathList.map((item) => {
+          pathName.unshift(item.name);
+          PathInfo.categoryLevelPathId.unshift(item.id);
+          // PathInfo.rootCategoryLevelId = item.rootCategoryLevelId;
+        });
+        PathInfo.categoryLevelPath = pathName.join('-');
+        PathInfo.categoryLevelPathId = PathInfo.categoryLevelPathId.join(',');
+        PathInfo.categoryLevelId = data.id;
+        PathInfo.categoryLevelName = data.name;
+        PathInfo.ruleCode = ruleCode;
 
-    /* 刷新表格 */
-    reload(where) {
-      this.$refs.listData.reload(where);
-    },
+        console.log(PathInfo, '点击物品分类');
+        this.currentData = PathInfo;
+      },
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.listData.reload(where);
+      },
 
-    // parents:用于返回的数组,childNode:要查询的节点,treeList:json树形数据
-    findParent(parents, childNode, treeList) {
-      for (let i = 0; i < treeList.length; i++) {
-        // 父节点查询条件
-        if (treeList[i].id === childNode.parentId) {
-          // 如果找到结果,保存当前节点
-          parents.push(treeList[i])
-          // 用当前节点再去原数据查找当前节点的父节点
-          this.findParent(parents, treeList[i], this.treeList)
-          break
-        } else {
-          if (treeList[i].children instanceof Array) {
-            //	没找到,遍历该节点的子节点
-            this.findParent(parents, childNode, treeList[i].children)
+      // parents:用于返回的数组,childNode:要查询的节点,treeList:json树形数据
+      findParent(parents, childNode, treeList) {
+        for (let i = 0; i < treeList.length; i++) {
+          // 父节点查询条件
+          if (treeList[i].id === childNode.parentId) {
+            // 如果找到结果,保存当前节点
+            parents.push(treeList[i]);
+            // 用当前节点再去原数据查找当前节点的父节点
+            this.findParent(parents, treeList[i], this.treeList);
+            break;
+          } else {
+            if (treeList[i].children instanceof Array) {
+              //	没找到,遍历该节点的子节点
+              this.findParent(parents, childNode, treeList[i].children);
+            }
           }
         }
+        return parents;
       }
-      return parents
     }
-  }
-};
+  };
 </script>
 <style lang="scss" scoped>
-.sys-organization-list {
-  height: calc(100vh - 165px);
-  box-sizing: border-box;
-  border-width: 1px;
-  border-style: solid;
-  overflow: auto;
-}
-
-.sys-organization-list :deep(.el-tree-node__content) {
-  height: 30px;
-
-  &>.el-tree-node__expand-icon {
-    margin-left: 10px;
+  .sys-organization-list {
+    height: calc(100vh - 165px);
+    box-sizing: border-box;
+    border-width: 1px;
+    border-style: solid;
+    overflow: auto;
+  }
+
+  .sys-organization-list :deep(.el-tree-node__content) {
+    height: 30px;
+
+    & > .el-tree-node__expand-icon {
+      margin-left: 10px;
+    }
   }
-}
 
-.form-content {
-  height: 50px;
-  border: 1px solid;
-  box-sizing: border-box;
-}
+  .form-content {
+    height: 50px;
+    border: 1px solid;
+    box-sizing: border-box;
+  }
 
-.form-wrapper {
-  padding: 12px 24px;
-}
+  .form-wrapper {
+    padding: 12px 24px;
+  }
 </style>

+ 211 - 119
src/views/material/product/oneProduct.vue

@@ -1,88 +1,109 @@
 <template>
-    <div class="ele-body">
-      <el-card shadow="never">
-        <ele-split-layout width="300px" allow-collapse :right-style="{ overflow: 'hidden' }">
-          <div class="ele-border-lighter sys-organization-list">
-            <el-tree :data="treeList" :props="defaultProps" ref="treeRef"
-              :default-expanded-keys="current && current.id ? [current.id] : []" :highlight-current="true" node-key="id"
-              @node-click="handleNodeClick"></el-tree>
-          </div>
-  
-          <template v-slot:content>
-            <div class="ele-border-lighter form-content" v-loading="loading">
-              <div class="form-wrapper">
-                <el-form size="mini" label-width="100px" class="ele-form-detail">
-                  <el-row :gutter="15" v-if="current.parentId == 0">
-                    <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
-                      <el-form-item label="类型编码:">
-                        <div class="ele-text-secondary">
-                          {{ current.code }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-                    <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
-                      <el-form-item label="类型名称:">
-                        <div class="ele-text-secondary">
-                          {{ current.name }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-  
-                    <el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
-                      <el-form-item label="描述:">
-                        <div class="ele-text-secondary">
-                          {{ current.remark }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-                  </el-row>
-                  <el-row :gutter="15" v-else>
-                    <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
-                      <el-form-item label="节点编码:">
-                        <div class="ele-text-secondary">
-                          {{ current.code }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-  
-                    <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
-                      <el-form-item label="节点名称:">
-                        <div class="ele-text-secondary">
-                          {{ current.name }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-  
-                    <el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
-                      <el-form-item label="层级全览:">
-                        <div class="ele-text-secondary">
-                          {{ fullName }}
-                        </div>
-                      </el-form-item>
-                    </el-col>
-                  </el-row>
-                </el-form>
-              </div>
-  
-              <IndexSearch @search="reload" />
-  
-              <IndexData ref="listData" v-if="current" :current-id="current.id" :data="current" :rootTreeId="rootTreeId" :rootId="rootId" :oneProduct="true">
-              </IndexData>
+  <div class="ele-body">
+    <el-card shadow="never">
+      <ele-split-layout
+        width="300px"
+        allow-collapse
+        :right-style="{ overflow: 'hidden' }"
+      >
+        <div class="ele-border-lighter sys-organization-list">
+          <el-tree
+            :data="treeList"
+            :props="defaultProps"
+            ref="treeRef"
+            :default-expanded-keys="current && current.id ? [current.id] : []"
+            :highlight-current="true"
+            node-key="id"
+            @node-click="handleNodeClick"
+          ></el-tree>
+        </div>
+
+        <template v-slot:content>
+          <div class="ele-border-lighter form-content" v-loading="loading">
+            <div class="form-wrapper">
+              <el-form size="mini" label-width="100px" class="ele-form-detail">
+                <el-row :gutter="15" v-if="current.parentId == 0">
+                  <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
+                    <el-form-item label="类型编码:">
+                      <div class="ele-text-secondary">
+                        {{ current.code }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                  <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
+                    <el-form-item label="类型名称:">
+                      <div class="ele-text-secondary">
+                        {{ current.name }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+
+                  <el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
+                    <el-form-item label="描述:">
+                      <div class="ele-text-secondary">
+                        {{ current.remark }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                <el-row :gutter="15" v-else>
+                  <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
+                    <el-form-item label="节点编码:">
+                      <div class="ele-text-secondary">
+                        {{ current.code }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+
+                  <el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
+                    <el-form-item label="节点名称:">
+                      <div class="ele-text-secondary">
+                        {{ current.name }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+
+                  <el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
+                    <el-form-item label="层级全览:">
+                      <div class="ele-text-secondary">
+                        {{ fullName }}
+                      </div>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-form>
             </div>
-          </template>
-        </ele-split-layout>
-      </el-card>
-    </div>
-  </template>
-  <script>
+
+            <IndexSearch @search="reload" />
+
+            <IndexData
+              ref="listData"
+              v-if="current"
+              :current-id="current.id"
+              :data="current"
+              :rootTreeId="rootTreeId"
+              :currentData="currentData"
+              :rootId="rootId"
+              :oneProduct="true"
+            >
+            </IndexData>
+          </div>
+        </template>
+      </ele-split-layout>
+    </el-card>
+  </div>
+</template>
+<script>
   import IndexData from './components/index-data.vue';
   import IndexSearch from './components/index-search.vue';
-  
+
   import dictMixins from '@/mixins/dictMixins';
   import { getTreeByPid } from '@/api/classifyManage';
-  
+
   import { getInfoById } from '@/api/classifyManage';
-  
+
+  import { deepClone } from '@/utils';
+
   export default {
     components: {
       IndexData,
@@ -94,27 +115,28 @@
         loading: false,
         current: {},
         curNode: {},
+        currentData: {},
         treeList: [],
         treeLoading: false,
         formData: {},
-         rootTreeId: null,
+        rootTreeId: null,
         defaultProps: {
           children: 'children',
           label: 'name'
         }
       };
     },
-  
+
     computed: {
       // 是否开启响应式布局
       styleResponsive() {
         return this.$store.state.theme.styleResponsive;
       },
-  
+
       rootId() {
         return this.$route.query.id;
       },
-  
+
       fullName() {
         let str = '';
         let codeStr = '';
@@ -124,7 +146,7 @@
           codeStr = node.data.code + '-' + codeStr;
           node = node?.parent;
         }
-  
+
         return str.substring(str, str.length - 1);
       }
     },
@@ -135,25 +157,41 @@
       async getTreeData() {
         try {
           this.treeLoading = true;
-  
+
           const res = await getTreeByPid(9);
           this.treeLoading = false;
           if (res?.code === '0') {
             this.treeList = res.data;
-  
-            this.$nextTick(() => {
-              // 默认高亮第一级树节点
-              if (this.treeList[0]) {
-                this.rootTreeId = this.treeList[0].id
-                this.getDetail(this.treeList[0].id);
-              }
-            });
+
+            if (!this.$route.query.categoryLevelId) {
+              this.$nextTick(() => {
+                //默认高亮第一级树节点;
+                if (this.treeList[0]) {
+                  this.rootTreeId = this.treeList[0].id;
+                  this.getDetail(this.treeList[0].id);
+                  console.log(this.treeList[0].id, 'rootTreeId');
+                }
+              });
+            } else {
+              this.getDetail(this.$route.query.categoryLevelId);
+              this.$nextTick(() => {
+                this.$refs.treeRef.setCurrentKey(
+                  this.$route.query.categoryLevelId
+                );
+              });
+              const objByid = this.findNodeById(
+                this.treeList,
+                this.$route.query.categoryLevelId
+              );
+              console.log(objByid, '当前选择的产品');
+              this.publicfun(objByid);
+            }
             return this.treeList;
           }
-        } catch (error) { }
+        } catch (error) {}
         this.treeLoading = false;
       },
-  
+
       async getDetail(id) {
         this.loading = true;
         const res = await getInfoById(id);
@@ -165,50 +203,105 @@
           });
         }
       },
-  
+
+      findNodeById(tree, targetId) {
+        function traverse(nodes) {
+          for (let node of nodes) {
+            if (node.id === targetId) {
+              return node;
+            } else if (node.children && node.children.length > 0) {
+              const foundNode = traverse(node.children);
+              if (foundNode) {
+                return foundNode;
+              }
+            }
+          }
+          return null;
+        }
+
+        return traverse(tree);
+      },
       handleNodeClick(data, node) {
+        this.$route.query.categoryLevelId = '';
         this.curNode = node;
-        this.pathList = this.findParent([], data, this.treeList)
-          this.rootTreeId = null
+        this.publicfun(data);
+
+        this.getDetail(data.id);
+      },
+
+      publicfun(data) {
+        this.pathList = this.findParent([], data, this.treeList);
+        this.rootTreeId = null;
         if (this.pathList.length == 0) {
-          this.rootTreeId  = data.id
-  
+          this.rootTreeId = data.id;
         } else {
-          this.rootTreeId  = this.pathList[this.pathList.length - 1] && this.pathList[this.pathList.length - 1].id
+          this.rootTreeId =
+            this.pathList[this.pathList.length - 1] &&
+            this.pathList[this.pathList.length - 1].id;
         }
-  
-  
-        this.getDetail(data.id);
+
+        let ruleCode = null;
+        if (this.pathList.length == 0) {
+          ruleCode = data.ruleCode;
+        } else {
+          ruleCode =
+            this.pathList[this.pathList.length - 1] &&
+            this.pathList[this.pathList.length - 1].ruleCode;
+        }
+
+        this.pathList.unshift(data);
+        const PathInfo = {
+          categoryLevelPath: '',
+          categoryLevelPathId: [],
+          // rootCategoryLevelId: null,
+          categoryLevelId: '',
+          categoryLevelName: '',
+          ruleCode: ''
+        };
+        const pathName = [];
+        this.pathList.map((item) => {
+          pathName.unshift(item.name);
+          PathInfo.categoryLevelPathId.unshift(item.id);
+          // PathInfo.rootCategoryLevelId = item.rootCategoryLevelId;
+        });
+        PathInfo.categoryLevelPath = pathName.join('-');
+        PathInfo.categoryLevelPathId = PathInfo.categoryLevelPathId.join(',');
+        PathInfo.categoryLevelId = data.id;
+        PathInfo.categoryLevelName = data.name;
+        PathInfo.ruleCode = ruleCode;
+
+        this.currentData = deepClone(PathInfo);
+        console.log(this.currentData, '选中的产品分类');
       },
-  
+
       /* 刷新表格 */
       reload(where) {
         this.$refs.listData.reload(where);
       },
-  
+
       // parents:用于返回的数组,childNode:要查询的节点,treeList:json树形数据
       findParent(parents, childNode, treeList) {
         for (let i = 0; i < treeList.length; i++) {
           // 父节点查询条件
           if (treeList[i].id === childNode.parentId) {
             // 如果找到结果,保存当前节点
-            parents.push(treeList[i])
+            parents.push(treeList[i]);
             // 用当前节点再去原数据查找当前节点的父节点
-            this.findParent(parents, treeList[i], this.treeList)
-            break
+            this.findParent(parents, treeList[i], this.treeList);
+            break;
           } else {
             if (treeList[i].children instanceof Array) {
               //	没找到,遍历该节点的子节点
-              this.findParent(parents, childNode, treeList[i].children)
+              this.findParent(parents, childNode, treeList[i].children);
             }
           }
         }
-        return parents
+        return parents;
       }
     }
   };
-  </script>
-  <style lang="scss" scoped>
+</script>
+<style lang="scss" scoped>
   .sys-organization-list {
     height: calc(100vh - 165px);
     box-sizing: border-box;
@@ -216,23 +309,22 @@
     border-style: solid;
     overflow: auto;
   }
-  
+
   .sys-organization-list :deep(.el-tree-node__content) {
     height: 30px;
-  
-    &>.el-tree-node__expand-icon {
+
+    & > .el-tree-node__expand-icon {
       margin-left: 10px;
     }
   }
-  
+
   .form-content {
     height: 50px;
     border: 1px solid;
     box-sizing: border-box;
   }
-  
+
   .form-wrapper {
     padding: 12px 24px;
   }
-  </style>
-  
+</style>

+ 1 - 1
src/views/rulesManagement/components/programRulesDialog.vue

@@ -705,7 +705,7 @@
                   deviceInfo: item.equipmentList.map((item) => {
                     return {
                       substanceId: this.dialogTitle.includes('新增')
-                        ? item.position[0].substanceId
+                        ? item.position[0]?.substanceId
                         : item.id,
                       // 前端回显字段
                       id: item.id,

+ 103 - 50
src/views/rulesManagement/matterRules/components/ProductModal.vue

@@ -1,63 +1,86 @@
 <template>
-  <el-dialog
-    :title="title"
-    :visible.sync="visible"
-    :before-close="handleClose"
-    class="productModal_dialog"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    width="70%"
-  >
-    <el-card shadow="never">
-      <ProductSearch @search="reload" ref="searchRef" />
+  <div>
+    <el-dialog
+      :title="title"
+      :visible.sync="visible"
+      :before-close="handleClose"
+      class="productModal_dialog"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      width="70%"
+    >
+      <el-card shadow="never">
+        <ProductSearch @search="reload" ref="searchRef" />
 
-      <ele-split-layout
-        width="244px"
-        allow-collapse
-        :right-style="{ overflow: 'hidden' }"
-      >
-        <div class="ele-border-lighter split-layout-right-content">
-          <el-tree
-            :data="treeList"
-            :props="defaultProps"
-            ref="treeRef"
-            :default-expanded-keys="categoryId ? [categoryId] : []"
-            :highlight-current="true"
-            node-key="id"
-            @node-click="handleNodeClick"
-          ></el-tree>
-        </div>
+        <ele-split-layout
+          width="244px"
+          allow-collapse
+          :right-style="{ overflow: 'hidden' }"
+        >
+          <div class="ele-border-lighter split-layout-right-content">
+            <el-tree
+              :data="treeList"
+              :props="defaultProps"
+              ref="treeRef"
+              :default-expanded-keys="categoryId ? [categoryId] : []"
+              :highlight-current="true"
+              node-key="id"
+              @node-click="handleNodeClick"
+            ></el-tree>
+          </div>
 
-        <!-- 数据表格 -->
-        <template v-slot:content>
-          <ele-pro-table
-            style="min-height: 400px"
-            ref="table"
-            :columns="columns"
-            :datasource="datasource"
-            :selection.sync="selection"
-            row-key="id"
-          >
-          </ele-pro-table>
-        </template>
-      </ele-split-layout>
-    </el-card>
+          <!-- 数据表格 -->
+          <template v-slot:content>
+            <ele-pro-table
+              style="min-height: 400px"
+              ref="table"
+              :columns="columns"
+              :datasource="datasource"
+              :selection.sync="selection"
+              row-key="id"
+            >
+              <template v-slot:action="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  v-if="receiveValue == '零部件'"
+                  @click="openBOMForm(row)"
+                  >BOM</el-link
+                >
+              </template>
+            </ele-pro-table>
+          </template>
+        </ele-split-layout>
+      </el-card>
 
-    <div class="rx-sc">
-      <el-button type="primary" size="small" @click="selected">选择</el-button>
-      <el-button size="small" @click="handleClose">关闭</el-button>
-    </div>
-  </el-dialog>
+      <div class="rx-sc">
+        <el-button type="primary" size="small" @click="selected"
+          >选择</el-button
+        >
+        <el-button size="small" @click="handleClose">关闭</el-button>
+      </div>
+    </el-dialog>
+
+    <bomDetail
+      v-if="bomDetailDialogFlag"
+      :bomDetailDialogFlag.sync="bomDetailDialogFlag"
+      ref="bomDialogRef"
+      :rowDataBom="rowDataBom"
+      @chooseRadio="chooseRadio"
+    ></bomDetail>
+  </div>
 </template>
 
 <script>
   import ProductSearch from './product-search.vue';
   import { getTreeByGroup } from '@/api/classifyManage';
   import { getList } from '@/api/classifyManage/itemInformation.js';
+  import bomDetail from '../components/bomDetailList.vue';
   export default {
     components: {
-      ProductSearch
+      ProductSearch,
+      bomDetail
     },
     data() {
       return {
@@ -131,6 +154,11 @@
           {
             label: '数量',
             prop: 'count'
+          },
+          {
+            label: '操作',
+            columnKey: 'action',
+            slot: 'action'
           }
         ],
 
@@ -138,7 +166,10 @@
         selection: [],
 
         processData: [],
-        current: null
+        current: null,
+        receiveValue: '',
+        receiveIndex: '',
+        bomDetailDialogFlag: false
       };
     },
 
@@ -154,9 +185,26 @@
         });
         return res;
       },
+      openBOMForm(row) {
+        this.bomDetailDialogFlag = true;
+        row.fIndex = this.receiveIndex;
+        this.rowDataBom = row;
+        console.log(this.rowDataBom, 'rowDataBom');
+        /*      this.$nextTick(() => {
+          this.$refs.bomDialogRef.open3(row);
+        }); */
+      },
+      open2(rowData, index, name) {
+        console.log(rowData, index, name, '222222222222');
+        this.processData = [];
+        this.visible = true;
+        this.getTreeData();
+        this.receiveIndex = index;
+        this.receiveValue = name;
+      },
 
       open(item) {
-        this.processData = item || [];
+        this.processData = Array.isArray(item) ? item : [];
         this.visible = true;
 
         this.getTreeData();
@@ -218,6 +266,11 @@
 
         this.$emit('chooseModal', _arr);
         this.handleClose();
+      },
+      chooseRadio(row) {
+        console.log(row, '勾选');
+        this.visible = false;
+        this.$emit('chooseRadio', row);
       }
     }
   };

+ 394 - 0
src/views/rulesManagement/matterRules/components/bomDetailList.vue

@@ -0,0 +1,394 @@
+<template>
+  <div>
+    <el-dialog
+      title="选择明细"
+      custom-class="ele-dialog-form long-dialog-form"
+      :visible.sync="bomDetailDialogFlag"
+      :before-close="handleClose"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :modal="false"
+      width="55%"
+    >
+      <el-card shadow="never">
+        <BOMSearch @search="reload" :statusOpt="statusOpt" />
+        <!-- 数据表格 -->
+        <ele-pro-table
+          ref="table"
+          :needPage="false"
+          :columns="columns"
+          :datasource="bomList"
+          class="dict-table"
+          tool-class="ele-toolbar-actions"
+          :selection.sync="selection"
+          row-key="id"
+        >
+          <template v-slot:toolbar>
+            <div class="toolbar_box"> </div>
+          </template>
+
+          <template v-slot:dosage="{ row }">
+            <el-input
+              v-model="row.dosage"
+              placeholder="请输入"
+              size="mini"
+              style="width: 68px"
+            >
+            </el-input>
+          </template>
+
+          <template v-slot:versions="{ row }"> V{{ row.versions }}.0 </template>
+
+          <template v-slot:produceType="{ row }">
+            <el-select
+              v-model="row.produceType"
+              filterable
+              multiple
+              collapse-tags
+              class="ele-block"
+              size="mini"
+            >
+              <el-option
+                v-for="item in dictList"
+                :key="item.value"
+                :value="item.value"
+                :label="item.label"
+              ></el-option>
+            </el-select>
+          </template>
+
+          <template v-slot:materielDesignation="{ row }">
+            <el-input
+              v-model="row.materielDesignation"
+              placeholder="请输入物料代号"
+              size="mini"
+              style="width: 120px"
+            >
+            </el-input>
+          </template>
+
+          <template v-slot:supplierId="{ row }">
+            <el-select
+              v-model="row.supplierId"
+              size="mini"
+              clearable
+              class="ele-block"
+              filterable
+              placeholder="请选择供应商"
+            >
+              <el-option
+                v-for="(item, index) in gysList"
+                :key="item.id + index"
+                :value="item.id"
+                :label="item.name"
+              ></el-option>
+            </el-select>
+          </template>
+
+          <template v-slot:factories="{ row }">
+            <el-input
+              v-model="row.factories"
+              placeholder="请输入生产厂家"
+              size="mini"
+              style="width: 120px"
+            >
+            </el-input>
+          </template>
+
+          <!-- 表头工具栏 -->
+        </ele-pro-table>
+      </el-card>
+
+      <div class="btns" slot="footer">
+        <el-button type="primary" size="small" @click="selected"
+          >选择</el-button
+        >
+        <el-button size="small" @click="handleClose">关闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import BOMSearch from '@/views/material/BOMmanage/components/BOM-search.vue';
+  import {
+    getBom,
+    contactList,
+    deleteBomTreeList,
+    updateBatchBOM
+  } from '@/api/material/BOM';
+  import { getByCode } from '@/api/system/dictionary-data';
+
+  export default {
+    name: 'bomDetailList',
+    components: {
+      BOMSearch
+    },
+    props: {
+      projectTeamDialogFlag: {
+        default: false,
+        type: Boolean
+      },
+      bomDetailDialogFlag: {
+        type: Boolean,
+        default: false
+      },
+      rowDataBom: {
+        type: Object,
+        default: () => {}
+      }
+    },
+    data() {
+      return {
+        currentIndex: null,
+        columns: [
+          {
+            columnKey: 'selection',
+            type: 'selection',
+            width: 45,
+            align: 'center',
+            reserveSelection: true,
+            fixed: 'left'
+          },
+          {
+            label: '序号',
+            columnKey: 'index',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'code',
+            label: '编码',
+            showOverflowTooltip: true,
+            width: 120
+          },
+          {
+            prop: 'name',
+            label: '名称',
+            width: 150
+          },
+
+          {
+            prop: 'level',
+            label: '层级'
+          },
+
+          {
+            prop: 'brandNum',
+            label: '牌号'
+          },
+
+          {
+            prop: 'modelType',
+            label: '型号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'specification',
+            label: '规格',
+            align: 'center',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'dosage',
+            slot: 'dosage',
+            label: '用量',
+            width: 100
+          },
+
+          {
+            prop: 'measuringUnit',
+            label: '计量单位',
+            showOverflowTooltip: true
+          },
+
+          {
+            prop: 'produceType',
+            slot: 'produceType',
+            label: '生产类型',
+            width: 160
+          },
+
+          {
+            prop: 'materielDesignation',
+            slot: 'materielDesignation',
+            label: '物料代号',
+            width: 150
+          },
+
+          {
+            prop: 'supplierId',
+            slot: 'supplierId',
+            label: '供应商',
+            width: 150
+          },
+
+          {
+            prop: 'factories',
+            slot: 'factories',
+            label: '生产厂家',
+            width: 180
+          },
+
+          {
+            prop: 'versions',
+            slot: 'versions',
+            label: '版本'
+          },
+
+          {
+            prop: 'status ',
+            label: '状态',
+            formatter: (row) => {
+              return this.statusOpt[+row.status];
+            }
+          },
+
+          {
+            prop: 'createName',
+            label: '创建人',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'createTime',
+            label: '创建日期',
+            width: 160
+          }
+        ],
+        statusOpt: {
+          '': '全部',
+          0: '草稿',
+          1: '已发布'
+        },
+
+        gysList: [],
+
+        newTreeId: null,
+
+        dictList: [],
+        radio: null,
+        selection: [],
+        bomList: []
+      };
+    },
+
+    created() {
+      this.getDictList('productionType');
+
+      this.getBomList();
+
+      this.getContactList();
+    },
+
+    methods: {
+      /* 表格数据源 */
+
+      getBomList() {
+        let params = {
+          pageNum: 1,
+          bomType: 1,
+          categoryId: this.rowDataBom.id,
+          size: -1
+        };
+        getBom(params).then((res) => {
+          this.bomList = res?.bomList || [];
+          console.log(res, 'res');
+        });
+      },
+      selected() {
+        let _arr = [];
+        if (!this.selection.length) {
+          this.$message.error('请至少选择一条数据');
+          return;
+        }
+
+        _arr = this.selection.map((m) => {
+          m.findex = this.rowDataBom.fIndex;
+          m.categoryId = m.id;
+          delete m.id;
+          return {
+            ...m
+          };
+        });
+
+        this.$emit('chooseRadio', _arr);
+        this.handleClose();
+      },
+
+      async getDictList(code) {
+        let { data: res } = await getByCode(code);
+        this.dictList = res.map((item) => {
+          let values = Object.keys(item);
+          return {
+            value: Number(values[0]),
+            label: item[values[0]]
+          };
+        });
+      },
+
+      getContactList() {
+        let param = {
+          pageNum: 1,
+          type: 2,
+          size: -1,
+          status: 1
+        };
+        contactList(param).then((res) => {
+          this.gysList = res.list;
+        });
+      },
+      bomClose() {
+        this.$nextTick(() => {
+          this.$refs.table.reload({
+            pageNum: 1
+          });
+        });
+      },
+
+      /* 刷新表格 */
+      reload(where) {
+        this.$refs.table.reload({ where, size: 1, pageNum: 10 });
+      },
+
+      handleClose() {
+        this.$emit('update:bomDetailDialogFlag', false);
+      }
+    }
+  };
+</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>

+ 57 - 4
src/views/rulesManagement/matterRules/components/matter-add.vue

@@ -90,7 +90,27 @@
               >
             </template>
           </el-table-column>
-          <el-table-column prop="name" label="事项" width="200">
+          <el-table-column prop="categoryCode" label="零部件编码" width="160">
+            <template slot-scope="scope">
+              <el-input
+                @click.native="
+                  openpartDialog(scope.row, scope.$index, '零部件')
+                "
+                v-model="scope.row.categoryCode"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column prop="categoryName" label="零部件名称" width="160">
+            <template slot-scope="scope">
+              <el-input
+                @click.native="
+                  openpartDialog(scope.row, scope.$index, '零部件')
+                "
+                v-model="scope.row.categoryName"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column prop="name" label="事项" width="240">
             <template slot-scope="scope">
               <el-form-item
                 :prop="'ruleItems.' + scope.$index + '.name'"
@@ -197,6 +217,8 @@
       </template>
     </ele-modal>
     <operation-guideDialog ref="operationGuideDialog" @save="saveEdit" />
+    <!-- 零部件 -->
+    <ProductModal ref="productRefs" @chooseRadio="chooseRadio" />
   </div>
 </template>
 <script>
@@ -209,8 +231,10 @@
     getDetail
   } from '@/api/ruleManagement/matter';
 
+  import ProductModal from './ProductModal.vue';
+
   export default {
-    components: { RuleCycle, OperationGuideDialog },
+    components: { RuleCycle, OperationGuideDialog, ProductModal },
     props: {
       pageType: {
         type: String,
@@ -291,6 +315,11 @@
     },
     watch: {},
     methods: {
+      openpartDialog(row, index, type) {
+        this.$nextTick(() => {
+          this.$refs.productRefs.open2(row, index, type);
+        });
+      },
       saveEdit(data, index) {
         console.log(data);
         console.log(index);
@@ -340,7 +369,7 @@
           this.formData.ruleItems.push({
             name: '', // 巡点检事项
             content: '', // 巡点检内容
-            norm: '', // 巡点检标准
+            norm: '正常', // 巡点检标准
             // 操作指导
             operationGuide: {
               toolList: [],
@@ -353,7 +382,7 @@
             {
               name: '', // 巡点检事项
               content: '', // 巡点检内容
-              norm: '', // 巡点检标准
+              norm: '正常', // 巡点检标准
               // 操作指导
               operationGuide: {
                 toolList: [],
@@ -371,6 +400,8 @@
           let name = row.name;
           let content = row.content;
           let norm = row.norm;
+          /*  let categoryCode = row.categoryCode;
+          let categoryName = row.categoryName; */
           flag = name && content && norm;
           this.$refs.contentConfigForm.validate((valid) => {
             if (valid || flag) {
@@ -401,6 +432,7 @@
 
       // 保存
       dataKeep() {
+        console.log(this.formData, '123');
         let form = deepClone(this.formData);
         console.log(this.$refs.cycleMultipleRef);
         form.cycle = this.$refs.cycleMultipleRef.ruleCycleList;
@@ -499,6 +531,27 @@
         } else {
           this.$message.error('请添加事项内容!');
         }
+      },
+      chooseRadio(val) {
+        if (val.length > 0) {
+          const findex = val[0].findex;
+          const items = val.map((item) => ({
+            ...this.formData.ruleItems[findex],
+            categoryCode: item.code,
+            categoryName: item.name
+          }));
+          this.formData.ruleItems.splice(findex + 1, 0, ...items);
+          this.formData.ruleItems.splice(findex, 1);
+        }
+        /*  for (let i = 0; i < this.formData.ruleItems.length; i++) {
+          for (let j = 0; j < val.length; j++) {
+            const element2 = val[j].findex;
+            if (element2 == i) {
+              this.formData.ruleItems[i].categoryCode = val[j].code;
+              this.formData.ruleItems[i].categoryName = val[j].name;
+            }
+          }
+        } */
       }
     }
   };

+ 67 - 53
src/views/rulesManagement/matterRules/components/matter-search.vue

@@ -11,58 +11,75 @@
         <el-form-item label="规则名称:">
           <el-input clearable v-model.trim="where.name" placeholder="请输入" />
         </el-form-item>
-		<el-form-item label="规则状态:">
-		  <DictSelection dictName="规则状态" clearable v-model.trim="where.status">
-		  </DictSelection>
-		</el-form-item>
+        <el-form-item label="规则状态:">
+          <DictSelection
+            dictName="规则状态"
+            clearable
+            v-model.trim="where.status"
+          >
+          </DictSelection>
+        </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="规则编码:">
           <el-input clearable v-model.trim="where.code" placeholder="请输入" />
         </el-form-item>
         <el-form-item label="创建时间:">
-            <el-date-picker
-              style="width: 100%;"
-                v-model="time"
-                type="daterange"
-                range-separator="至"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-				value-format="yyyy-MM-dd HH:mm:ss"
-				:default-time="['00:00:00', '23:59:59']"
-        	  >
-            </el-date-picker>
+          <el-date-picker
+            style="width: 100%"
+            v-model="time"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            :default-time="['00:00:00', '23:59:59']"
+          >
+          </el-date-picker>
         </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="规则类型:">
-          <DictSelection dictName="规则类型" clearable v-model.trim="where.type">
+          <DictSelection
+            dictName="规则类型"
+            clearable
+            v-model.trim="where.type"
+          >
           </DictSelection>
         </el-form-item>
         <el-form-item label="组织机构:">
-          <auth-selection v-model.trim="where.deptIds" style="width: 100%"></auth-selection>
+          <auth-selection
+            v-model.trim="where.deptIds"
+            style="width: 100%"
+          ></auth-selection>
         </el-form-item>
       </el-col>
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="创建人:">
-          <el-input clearable v-model.trim="where.userName" placeholder="请输入" />
+          <el-input
+            clearable
+            v-model.trim="where.userName"
+            placeholder="请输入"
+          />
         </el-form-item>
-		<div class="ele-form-actions">
-		  <el-button
-		    type="primary"
-		    icon="el-icon-search"
-		    class="ele-btn-icon"
-		    @click="search"
-		    size="small"
-		  >
-		    查询
-		  </el-button>
-		   <el-button @click="reset"
-		     icon="el-icon-refresh-left"
-		     size="small"
-		     type="primary"
-		   >重置</el-button>
-		</div>
+        <div class="ele-form-actions">
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            class="ele-btn-icon"
+            @click="search"
+            size="small"
+          >
+            查询
+          </el-button>
+          <el-button
+            @click="reset"
+            icon="el-icon-refresh-left"
+            size="small"
+            type="primary"
+            >重置</el-button
+          >
+        </div>
       </el-col>
     </el-row>
   </el-form>
@@ -76,17 +93,17 @@
       const defaultWhere = {
         name: '',
         code: '',
-        userName:'',
-        type:'',
-		status:'',
-		startTime:'',
-		endTime:''
+        userName: '',
+        type: '',
+        status: '',
+        startTime: '',
+        endTime: ''
       };
       return {
         // 表单数据
         where: { ...defaultWhere },
-        treeData:[],
-		time:[]
+        treeData: [],
+        time: []
       };
     },
     computed: {
@@ -95,20 +112,17 @@
         return this.$store.state.theme.styleResponsive;
       }
     },
-    created(){
-    },
+    created() {},
     methods: {
       /* 搜索 */
       search() {
-		if(this.time.length){
-			this.where.startTime = this.time[0]
-			this.where.endTime = this.time[1]
-		}
+        this.where.startTime = this.time ? this.time[0] : '';
+        this.where.endTime = this.time ? this.time[1] : '';
         this.$emit('search', this.where);
       },
       /*  重置 */
       reset() {
-		this.time = []
+        this.time = [];
         this.where = { ...this.defaultWhere };
         this.search();
       }
@@ -116,9 +130,9 @@
   };
 </script>
 <style lang="scss" scoped>
-    .ele-form-actions{
-		display:flex;
-		align-items: center;
-		justify-content: flex-end;
-	}
+  .ele-form-actions {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+  }
 </style>

+ 1 - 1
src/views/rulesManagement/meteringManagement/index.vue

@@ -32,7 +32,7 @@
       <div class="list">
         <div class="search_bar">
           <el-input
-            placeholder="请输入关键词"
+            placeholder="请输入编码或名称关键词"
             v-model="name"
             clearable
             class="input-with-select"

+ 39 - 0
src/views/source/index.vue

@@ -0,0 +1,39 @@
+<template>
+  <div>
+    <iframe style="width: 100%; height: 100vh" :src="link + `?token=${token}`">
+    </iframe>
+  </div>
+</template>
+  
+  <script>
+import { getToken } from '@/utils/token-util';
+export default {
+  data() {
+    return {
+      link: '',
+      token: ''
+    };
+  },
+  mounted() {
+    // if (this.$route.query && this.$route.query.link) {
+    //   this.link = this.$route.query.link;
+    // }
+  },
+  watch: {
+    // 监视搜索词变化
+    '$route.query.link': {
+      immediate: true,
+      handler() {
+        // console.log(2222);
+        this.link = this.$route.query.link;
+        this.token = getToken();
+      }
+    }
+  },
+  methods: {}
+};
+</script>
+  
+  <style lang="scss" scoped>
+</style>
+  

+ 95 - 27
src/views/system/menu/components/menu-edit.vue

@@ -1,61 +1,117 @@
 <!-- 编辑弹窗 -->
 <template>
-  <ele-modal width="720px" :visible="visible" :close-on-click-modal="false" custom-class="ele-dialog-form"
-    :title="isUpdate ? '修改菜单' : '添加菜单'" @update:visible="updateVisible">
+  <ele-modal
+    width="720px"
+    :visible="visible"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    :title="isUpdate ? '修改菜单' : '添加菜单'"
+    @update:visible="updateVisible"
+  >
     <el-form ref="form" :model="form" :rules="rules" label-width="100px">
       <el-row>
-
-
         <el-col :span="12">
           <el-form-item label="上级菜单:">
-            <ele-tree-select clearable v-model="form.parentId" :data="menuList" label-key="name" value-key="id"
-              default-expand-all placeholder="请选择上级菜单" />
+            <ele-tree-select
+              clearable
+              v-model="form.parentId"
+              :data="menuList"
+              label-key="name"
+              value-key="id"
+              default-expand-all
+              placeholder="请选择上级菜单"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="菜单名称:" prop="name">
-            <el-input clearable v-model="form.name" placeholder="请输入菜单名称" />
+            <el-input
+              clearable
+              v-model="form.name"
+              placeholder="请输入菜单名称"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="菜单来源:" prop="source">
+            <el-radio-group v-model="form.source" @input="sourceChange">
+              <el-radio :label="1">内部地址</el-radio>
+              <el-radio :label="2">外部地址</el-radio>
+            </el-radio-group>
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="路由地址:" prop="url">
-            <el-input clearable v-model="form.url" placeholder="请输入路由地址" />
+            <el-input
+              :disabled="form.source == 2"
+              clearable
+              v-model="form.url"
+              placeholder="请输入路由地址"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="组件地址:" prop="component">
-            <el-input clearable v-model="form.component" placeholder="请输入路由地址" />
+          <el-form-item
+            :label="form.source == 1 ? '组件地址' : '外链地址'"
+            :prop="form.source == 2 ? 'component' : ''"
+          >
+            <el-input
+              clearable
+              v-model="form.component"
+              :placeholder="
+                form.source == 1 ? '请输入组件地址' : '请输入外链地址'
+              "
+            />
           </el-form-item>
         </el-col>
-
         <el-col :span="12">
           <el-form-item label="权限编码:" prop="permissionCode">
-            <el-input clearable v-model="form.permissionCode" placeholder="请输入路由地址" />
+            <el-input
+              clearable
+              v-model="form.permissionCode"
+              placeholder="请输入路由地址"
+            />
           </el-form-item>
         </el-col>
 
-
         <el-col :span="12">
           <el-form-item v-if="form.rootId != 99999" label="菜单图标:">
-            <ele-icon-picker v-model="form.icon" placeholder="请选择菜单图标" :disabled="form.type === 2" />
+            <ele-icon-picker
+              v-model="form.icon"
+              placeholder="请选择菜单图标"
+              :disabled="form.type === 2"
+            />
           </el-form-item>
 
           <el-form-item v-if="form.rootId == 99999" label="菜单图标:">
-            <el-input clearable v-model="form.icon" placeholder="请输入pda图标" />
+            <el-input
+              clearable
+              v-model="form.icon"
+              placeholder="请输入pda图标"
+            />
           </el-form-item>
-
         </el-col>
         <el-col :span="12">
           <el-form-item label="密级:" prop="secretLevel">
-           <el-select v-model="form.secretLevel" style="width: 100%">
-             <el-option v-for="item in secretLevelList()" :key="item.value" :label="item.label" :value="item.value"></el-option>
-           </el-select>
+            <el-select v-model="form.secretLevel" style="width: 100%">
+              <el-option
+                v-for="item in secretLevelList()"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="排序号:" prop="sort">
-            <el-input-number :min="0" v-model="form.sort" placeholder="请输入排序号" controls-position="right"
-              class="ele-fluid ele-text-left" />
+            <el-input-number
+              :min="0"
+              v-model="form.sort"
+              placeholder="请输入排序号"
+              controls-position="right"
+              class="ele-fluid ele-text-left"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12">
@@ -83,7 +139,7 @@
 <script>
 import { EleIconPicker } from 'ele-admin';
 import { saveOrUpdate } from '@/api/system/menu';
-import {secretLevelList} from "@/enum/dict";
+import { secretLevelList } from '@/enum/dict';
 
 export default {
   components: { EleIconPicker },
@@ -103,13 +159,14 @@ export default {
       parentId: '',
       name: '',
       type: 1,
+      source: 1,
       icon: '',
       url: '/',
       component: '',
       sort: null,
       rootId: null,
       permissionCode: 1,
-      secretLevel: 1,
+      secretLevel: 1
     };
     return {
       defaultForm,
@@ -117,11 +174,12 @@ export default {
       form: { ...defaultForm },
       // 表单验证规则
       rules: {
-        name: [
-          { required: true, message: '请输入菜单名称', trigger: 'blur' }
-        ],
+        name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
         sort: [{ required: true, message: '请输入排序号', trigger: 'blur' }],
         url: [{ required: true, message: '请输入菜单路由', trigger: 'blur' }],
+        component: [
+          { required: true, message: '请输入组件地址', trigger: 'blur' }
+        ],
         type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }]
       },
       // 提交状态
@@ -144,7 +202,15 @@ export default {
   },
   methods: {
     secretLevelList() {
-      return secretLevelList
+      return secretLevelList;
+    },
+    sourceChange(e) {
+      if (e == 2) {
+        this.form.url =
+          '/sourceLink' + Math.floor(10000 + Math.random() * 90000);
+      } else {
+        this.form.url = '/';
+      }
     },
     /* 保存编辑 */
     save() {
@@ -242,6 +308,7 @@ export default {
             parentId: this.data.parentId == 0 ? '' : this.data.parentId ?? ''
           });
           this.isUpdate = true;
+          // this.sourceChange(this.form.source);
         } else {
           this.form.parentId = this.parentId ?? '';
           this.isUpdate = false;
@@ -249,6 +316,7 @@ export default {
       } else {
         this.$refs.form.clearValidate();
         this.form = { ...this.defaultForm };
+        // this.sourceChange(this.form.source);
       }
     }
   }

+ 3 - 3
src/views/system/role/components/role-search.vue

@@ -12,11 +12,11 @@
           <el-input clearable v-model.trim="where.name" placeholder="请输入" />
         </el-form-item>
       </el-col>
-      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
+      <!-- <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="组织名称:">
           <el-input clearable v-model.trim="where.groupName" placeholder="请输入" />
         </el-form-item>
-      </el-col>
+      </el-col> -->
       <!-- <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="备注:">
           <el-input clearable v-model.trim="where.comments" placeholder="请输入" />
@@ -45,7 +45,7 @@
       // 默认表单数据
       const defaultWhere = {
         name: '',
-        groupName: ''
+        // groupName: ''
       };
       return {
         // 表单数据

+ 16 - 1
src/views/system/unifiedPortal/dialog.vue

@@ -62,7 +62,17 @@
       </el-form-item>
       <el-form-item label="链接" required>
         <el-input placeholder="请输入内容" v-model="form.linkUrl">
-          <template slot="prepend">https://</template>
+          <!--  <template slot="prepend">https://</template> -->
+          <el-select
+            v-model="select"
+            slot="prepend"
+            placeholder="请选择"
+            style="width: 100px"
+            @change="changeSelect"
+          >
+            <el-option label="http://" value="http://"></el-option>
+            <el-option label="https://" value="https://"></el-option>
+          </el-select>
         </el-input>
       </el-form-item>
       <el-form-item label="链接类型" required>
@@ -107,6 +117,7 @@
           linkType: '1',
           architType: '1'
         },
+        select: '',
         imageUrl: '',
         options: [
           {
@@ -165,6 +176,10 @@
           this.file = file.raw; //赋值文件对象,用于上传操作
         }
       },
+      changeSelect() {
+        let urlWithoutProtocol = this.form.linkUrl.replace(/^https?:\/\//, '');
+        this.form.linkUrl = `${this.select}${urlWithoutProtocol}`;
+      },
       async config() {
         if (!this.form.name) {
           return this.$message.error('请输入名称');

+ 0 - 14
src/views/technology/production/components/user-edit.vue

@@ -69,20 +69,6 @@
         </el-col>
 
 
-        <el-col :span="12">
-          <el-form-item label="对应物料基本数量" label-width="140px" prop="categoryNum">
-            <el-row>
-              <el-col :span="16">
-                <el-input placeholder="请输入" v-model.number="form.workBeat.categoryNum">
-                </el-input></el-col>
-              <el-col :span="1">&nbsp;</el-col>
-              <el-col :span="7">
-                <DictSelection dictName="计量单位" v-model="form.workBeat.categoryUnit" />
-              </el-col>
-            </el-row>
-          </el-form-item>
-        </el-col>
-
 
 
 

+ 4 - 3
src/views/technology/production/index.vue

@@ -173,17 +173,18 @@ export default {
         // {
         //   value: 2,
         //   label: '抽样质检'
-        // }, 
+        // },
+        
         {
           value: 3,
-          label: '普通质检'
+          label: '抽样质检'
         }, {
           value: 4,
           label: '包装工序'
         },
         {
           value: 6,
-          label: '常规质检'
+          label: '全量质检'
         },
       ],
 

+ 7 - 5
src/views/technology/route/components/production/components/user-edit.vue

@@ -274,19 +274,21 @@
           value: 1,
           label: '普通工序'
         },
+        // {
+        //   value: 2,
+        //   label: '抽样质检'
+        // },
+        
         {
-          value: 2,
-          label: '抽样质检'
-        }, {
           value: 3,
-          label: '普通质检'
+          label: '抽样质检'
         }, {
           value: 4,
           label: '包装工序'
         },
         {
           value: 6,
-          label: '常规质检'
+          label: '全量质检'
         },
       ],
       };

+ 1 - 1
src/views/technology/version/components/user-edit.vue

@@ -8,7 +8,7 @@
 
         <el-col :span="8">
           <el-form-item label="版本编码:" prop="code">
-            <el-input clearable v-model="form.code" placeholder="请输入版本编码" />
+            <el-input clearable v-model="form.code" :disabled="isUpdate" placeholder="请输入版本编码" />
           </el-form-item>
         </el-col>
 

+ 1 - 1
src/views/versionManage/index.vue

@@ -318,7 +318,7 @@ export default {
     removeBatch() {
       if (!this.selection.length) return this.$message.error('请至少选择一条数据');
       if (this.selection.some(item => item.status == 1)) return this.$message.error('启用状态的规则不允许删除!请检查');
-      this.$confirm('确定要删除选中的资质吗?', '提示', {
+      this.$confirm('确定要删除选中的规则吗?', '提示', {
         type: 'warning'
       }).then(() => {
         const loading = this.$loading({lock: true});

+ 2 - 3
vue.config.js

@@ -31,10 +31,9 @@ module.exports = {
     proxy: {
       // 当我们的本地的请求 有/api的时候,就会代理我们的请求地址向另外一个服务器发出请求
       '/api': {
-        target: 'http://192.168.1.125:18086',
-        // target: 'http://192.168.1.147:18086',
+        // target: 'http://192.168.1.125:18086',
+        target: 'http://192.168.1.116:18086',
         // target: 'http://192.168.1.176:18086',
-        // target: 'http://192.168.1.105:18086',
 
         changeOrigin: true, // 只有这个值为true的情况下 才表示开启跨域
         pathRewrite: {