mushencc 2 éve
szülő
commit
b1aa3bc99e

+ 2 - 2
src/axios/index.js

@@ -19,7 +19,7 @@ instance.interceptors.request.use(
 
       Vue.prototype.$loading.show();
     }
-    let token = localStorage.getItem("token");
+    let token = localStorage.getItem("jf2_token");
     // let proxy_url = 'http://121.37.173.82:82'; //打包上线时请改用此处
     let proxy_url = process.env.VUE_APP_BASE_URL; //打包上线时请改用此处
     // let proxy_url = '/proxy'//打包上线时此处请注释掉
@@ -45,7 +45,7 @@ instance.interceptors.response.use(
       } else {
         //若code 非 200
         if (res.data.code == 401) {
-          localStorage.removeItem("token");
+          localStorage.removeItem("jf2_token");
           return location.reload();
         }
         Vue.prototype.$Message.error(res.data.msg || "未知错误");

+ 14 - 0
src/components/HaveSideMenu/index.vue

@@ -24,6 +24,9 @@
           :menuList="menuList"
           @handleMenuClick="handleMenuClick"
         ></MyTree> -->
+        <div class="left_add_title" @click="handleAddBM">
+          <Icon type="md-add" />
+        </div>
         <el-tree
           :data="menuList"
           node-key="id"
@@ -132,6 +135,9 @@ export default {
     }
   },
   methods: {
+    handleAddBM() {
+      this.$emit('handleAddBM', {});
+    },
     handleNodeClick(data, node) {
       this.$emit('handleNodeClick', { data, node });
     },
@@ -211,4 +217,12 @@ export default {
   font-size: 14px;
   padding-right: 8px;
 }
+.left_add_title {
+  cursor: pointer;
+  width: 90%;
+  border-radius: 5px;
+  text-align: center;
+  border: 1px solid #409eff;
+  margin: 4px auto;
+}
 </style>

+ 15 - 1
src/components/PageTab/index.vue

@@ -17,7 +17,11 @@
             class="el-icon-close"
             @click.stop="onClose(item)"
             @contextmenu.prevent.stop=""
-            :style="openedPageRouters.length <= 1 ? 'width:0;' : ''"
+            :style="
+              openedPageRouters.length <= 1 && item.meta.title == '首页'
+                ? 'width:0;'
+                : ''
+            "
           ></span>
         </div>
       </div>
@@ -158,6 +162,7 @@ export default {
     },
     //重载页面
     reload() {
+      console.log(this.contextMenuTargetPageRoute, 111);
       this.delRouteCache(this.contextMenuTargetPageRoute.fullPath);
       if (this.contextMenuTargetPageRoute.fullPath === this.$route.fullPath) {
         this.$router.replace({ name: this.blankRouteName }).then(() => {
@@ -220,15 +225,24 @@ export default {
     //删除页面
     delPageRoute(route) {
       let routeIndex = this.openedPageRouters.indexOf(route);
+      if (routeIndex == 0 && this.openedPageRouters.length == 1) {
+        this.$router.push('/cms/home');
+      }
+
       if (routeIndex >= 0) {
         this.openedPageRouters.splice(routeIndex, 1);
+
       }
+      console.log(routeIndex);
       this.delRouteCache(route.fullPath);
+
+
     },
     //删除页面缓存
     delRouteCache(key) {
       let cache = this.keepAliveComponentInstance.cache;
       let keys = this.keepAliveComponentInstance.keys;
+      console.log(this.keepAliveComponentInstance, 111);
       for (let i = 0; i < keys.length; i++) {
         if (keys[i] == key) {
           keys.splice(i, 1);

+ 3 - 3
src/components/header/index.vue

@@ -66,7 +66,7 @@ export default {
         nickname: "",
         avatar: "",
       },
-      headers: { Authorization: localStorage.getItem("token") },
+      headers: { Authorization: localStorage.getItem("jf2_token") },
       visible: false,
     };
   },
@@ -84,7 +84,7 @@ export default {
       this.axios.post("/api/login_out").then((res) => {
         if (res.code == 200) {
           this.$Message.success(res.msg || "已退出登录");
-          localStorage.removeItem("token");
+          localStorage.removeItem("jf2_token");
           localStorage.removeItem("autoLogin");
           setTimeout(() => this.$router.push({ name: "Login" }), 500);
         }
@@ -119,7 +119,7 @@ export default {
               if (res.code == 200) {
                 this.$Message.success(res.msg);
                 this.replacePassword = false;
-                localStorage.removeItem("token");
+                localStorage.removeItem("jf2_token");
                 setTimeout(() => this.$router.push({ name: "Login" }), 500);
               }
             });

+ 11 - 11
src/route/index.js

@@ -37,17 +37,17 @@ const router = new VueRoute({
 // document.title = '久方软件'
 
 router.beforeEach((to, from, next) => {
-  // if(to.path === '/'){
-  //   next();
-  // }else{
-  //   let token = localStorage.getItem('token');
-  //   if(!token) {
-  //     next('/');
-  //   }else{
-  //     next();
-  //   }
-  // }
-  next();
+  if (to.path === '/') {
+    next();
+  } else {
+    let token = localStorage.getItem('jf2_token');
+    if (!token) {
+      next('/');
+    } else {
+      next();
+    }
+  }
+  // next();
 });
 
 export default router

+ 30 - 20
src/routerMap/index.js

@@ -81,26 +81,6 @@ const routerMap = [
     component: (resolve) => require(["@/views/BasicSettings/MaterialManage/index"], resolve),
   },
   {
-    path: "/cms/BasicSettings/MaterialManage/add",
-    name: "MaterialManageAdd", //新增物料
-    meta: {
-      index: 3,
-      title: '新增物料',
-      canMultipleOpen: true
-    },
-    component: (resolve) => require(["@/views/BasicSettings/MaterialManage/detail"], resolve),
-  },
-  {
-    path: "/cms/BasicSettings/MaterialManage/edit",
-    name: "MaterialManageEdit", //物料编辑
-    meta: {
-      index: 3,
-      title: '物料编辑',
-      canMultipleOpen: true
-    },
-    component: (resolve) => require(["@/views/BasicSettings/MaterialManage/detail"], resolve),
-  },
-  {
     path: "/cms/BasicSettings/MaterialManage/detail",
     name: "MaterialManageDetail", //物料详情
     meta: {
@@ -210,5 +190,35 @@ const routerMap = [
     },
     component: (resolve) => require(["@/views/BusinessManagement/Packing/detail"], resolve),
   },
+  {
+    path: "/cms/BasicSettings/ProcessLine/index",
+    name: "ProcessLine", //工艺路线
+    meta: {
+      index: 3,
+      title: '工艺路线',
+      canMultipleOpen: true
+    },
+    component: (resolve) => require(["@/views/BasicSettings/ProcessLine/index"], resolve),
+  },
+  {
+    path: "/cms/BasicSettings/ProcessManage/index",
+    name: "ProcessManage", //工序列表
+    meta: {
+      index: 3,
+      title: '工序列表',
+      canMultipleOpen: true
+    },
+    component: (resolve) => require(["@/views/BasicSettings/ProcessManage/index"], resolve),
+  },
+  {
+    path: "/cms/BasicSettings/ProcessManage/detail",
+    name: "ProcessManageDetail", //工序详情
+    meta: {
+      index: 3,
+      title: '工序列表详情',
+      canMultipleOpen: true
+    },
+    component: (resolve) => require(["@/views/BasicSettings/ProcessManage/detail"], resolve),
+  },
 ];
 export default routerMap;

+ 142 - 48
src/views/BasicSettings/MaterialManage/index.vue

@@ -24,6 +24,7 @@
       @append="append"
       @remove="remove"
       :searchHeight="searchHeight"
+      @handleAddBM="handleAddBM(false)"
     >
       <template #crt_time="{ row }">
         <span>{{ func.replaceDateNoHMS(row.crt_time) }}</span>
@@ -38,41 +39,29 @@
       </template>
       <template #form>
         <Form :label-width="80" style="display: flex; flex-wrap: wrap">
-          <FormItem label="物料">
-            <Input size="small" class="form_item" />
+          <FormItem label="物料名称">
+            <Input
+              size="small"
+              class="form_item"
+              v-model="searchData.title"
+              placeholder="请输入"
+            />
           </FormItem>
-          <FormItem label="物料">
-            <Input size="small" class="form_item" />
+          <FormItem label="创建日期">
+            <DatePicker
+              type="daterange"
+              size="small"
+              transfer
+              class="date_item"
+              placeholder="年/月/日"
+              v-model="searchData.crt_time"
+              @on-change="handleSelectTime"
+            />
           </FormItem>
-          <FormItem label="物料">
-            <Input size="small" class="form_item" />
-          </FormItem>
-          <FormItem label="班组">
-            <Select size="small" transfer class="form_item">
-              <Option :label="1" :value="1" />
-            </Select>
-          </FormItem>
-          <FormItem label="班组">
-            <Select size="small" transfer class="form_item">
-              <Option :label="1" :value="1" />
-            </Select>
-          </FormItem>
-          <FormItem label="班组">
-            <Select size="small" transfer class="form_item">
-              <Option :label="1" :value="1" />
-            </Select>
-          </FormItem>
-          <FormItem label="日期">
-            <DatePicker type="date" size="small" transfer class="date_item" />
-            <DatePicker type="date" size="small" transfer class="date_item" />
-          </FormItem>
-          <FormItem label="日期">
-            <DatePicker type="date" size="small" transfer class="date_item" />
-            <DatePicker type="date" size="small" transfer class="date_item" />
-          </FormItem>
-          <FormItem label="日期">
-            <DatePicker type="date" size="small" transfer class="date_item" />
-            <DatePicker type="date" size="small" transfer class="date_item" />
+          <FormItem :label-width="20">
+            <Button type="primary" ghost @click="handleSearch" size="small"
+              >查询</Button
+            >
           </FormItem>
         </Form>
       </template>
@@ -90,14 +79,64 @@
         <Button @click="handleSureBasic" type="primary">确认</Button>
       </div>
     </Modal>
+    <Modal
+      title="新增物料分类"
+      :closable="false"
+      :mask-closable="false"
+      v-model="is_addBM"
+      width="30"
+    >
+      <div style="max-height: 400px; overflow: auto">
+        <Form
+          :label-width="100"
+          v-for="(item, index) in modalData"
+          :key="index"
+          style="display: flex"
+        >
+          <FormItem label="物料分类名称" style="width: 70%">
+            <Input
+              clearable
+              placeholder="请输入"
+              v-model="item.title"
+              style="width: 100%"
+            />
+          </FormItem>
+          <FormItem :label-width="10" style="width: 20%">
+            <div class="icon">
+              <Icon
+                :size="20"
+                type="ios-add-circle-outline"
+                style="padding-right: 10px; cursor: pointer"
+                @click="handleModalAdd(index)"
+              />
+              <Icon
+                :size="20"
+                type="ios-remove-circle-outline"
+                style="cursor: pointer"
+                @click="handleModalRemove(index)"
+              />
+            </div>
+          </FormItem>
+        </Form>
+      </div>
+      <div slot="footer">
+        <Button style="margin-right: 10px" @click="is_addBM = false"
+          >取消</Button
+        >
+        <Button type="primary" @click="handleSureBM">确认</Button>
+      </div>
+    </Modal>
   </div>
 </template>
 <script>
 export default {
   data() {
     return {
+      is_addBM: false,
       show_basic: false,
       materialList: [],
+      proxyData: {},
+      searchData: {},
       // menuList: [{ name: 'hw', state: false, sideState: false, detailState: false, children: [{ name: 'a', state: false, sideState: false, detailState: false }, { name: 'b', state: false, detailState: false, sideState: false }, { name: 'b', state: false, detailState: false, sideState: false }, { name: 'b', state: false, detailState: false, sideState: false }] },
       // { name: '啊比', state: false, detailState: false, sideState: false, children: [{ name: 'a', state: false, detailState: false, sideState: false }, { name: 'b', state: false, detailState: false, sideState: false }, { name: 'c', state: false, detailState: false, sideState: false }, { name: 'd', state: false, detailState: false, sideState: false, children: [{ name: 'zuilicneg', state: false, detailState: false, sideState: false, children: [{ name: '99999999', state: false, detailState: false, sideState: false, children: [{ name: '88888', state: false, sideState: false, detailState: false }] }] }] }] },
       // {
@@ -117,6 +156,8 @@ export default {
       pageSize: 10,
       searchHeight: '0px',
       showText: false,
+      modalData: [],
+      selectID: ''
     }
   },
   created() {
@@ -129,6 +170,49 @@ export default {
     this.initData();
   },
   methods: {
+    handleSelectTime() {
+      this.$forceUpdate();
+    },
+    handleSearch() {
+      this.proxyData = JSON.parse(JSON.stringify(this.searchData));
+      this.pageIndex = 1;
+      this.proxyData.crt_time = [this.proxyData.crt_time[0] ? Date.parse(this.proxyData.crt_time[0]).toString().slice(0, 10) : '', this.proxyData.crt_time[1] ? Date.parse(this.proxyData.crt_time[1]).toString().slice(0, 10) : '']
+
+      this.initData(this.proxyData);
+    },
+    handleModalAdd(index) {
+      this.modalData.splice(index + 1, 0, { title: "" })
+    },
+    handleModalRemove(index) {
+      if (this.modalData.length == 1) {
+        return
+      } else {
+        this.modalData.splice(index, 1)
+      }
+
+    },
+    handleSureBM() {
+      let data = JSON.parse(JSON.stringify(this.modalData));
+      data.forEach(v => {
+        v.parent_id = this.selectID;
+      })
+      this.axios.post('/api/basicMaterialAdd', { data }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          this.getMaterial();
+          this.is_addBM = false;
+        }
+      })
+    },
+    handleAddBM(e) {
+      if (e) {
+        this.selectID = e;
+      } else {
+        this.selectID = 0;
+      }
+      this.is_addBM = true;
+      this.modalData = [{ title: '' }];
+    },
     handleShow() {
       if (this.searchHeight === 'auto') {
         this.searchHeight = '0px';
@@ -140,23 +224,23 @@ export default {
     },
     getMaterial() {
       this.axios.post('/api/basicMaterialList').then(res => {
-        this.materialList = this.handleSetState(res.data.data);
-        this.tapList = this.handleGetChildren(this.materialList);
+        this.materialList = this.handleSetState(res.data);
+        this.tapList = this.getArr(this.materialList);
       })
     },
-    handleGetChildren(arr) {
+    getArr(arr) {
       let data = [];
       arr.forEach(v => {
-        if (!v.children || v.children.length == 0) {
+        if (v.children.length == 0) {
           data.push(v);
         } else {
-          data = [...this.handleGetChildren(v.children)];
+          data = [...data, ...this.getArr(v.children)];
         }
       })
-      return data;
+      return data
     },
     append(data) {
-
+      this.handleAddBM(data.id);
     },
     remove(data) {
       this.axios.post('/api/basicMaterialDel', { id: data.data.id }).then(res => {
@@ -170,14 +254,14 @@ export default {
       // if (!this.clickID) {
       //   return this.$Message.warning('请先选择要新增的物料分类!');
       // }
-      this.$router.push({ path: '/cms/BasicSettings/MaterialManage/edit', query: { type: 2, title: '编辑物料', id: row.id } })
+      this.$router.push({ path: '/cms/BasicSettings/MaterialManage/detail', query: { type: 2, title: '编辑物料', id: row.id } })
     },
     handleSureBasic() {
       if (!this.tapList.find(v => (v.is_choose))) {
         return this.$Message.warning('请选择一个物料分类!')
       }
       this.show_basic = false;
-      this.$router.push({ path: '/cms/BasicSettings/MaterialManage/add', query: { type: 1, basicMaterial_id: this.tapList.find(v => (v.is_choose)).id, title: '新增物料' } })
+      this.$router.push({ path: '/cms/BasicSettings/MaterialManage/detail', query: { type: 1, basicMaterial_id: this.tapList.find(v => (v.is_choose)).id, title: '新增物料' } })
 
     },
     handleAdd() {
@@ -197,7 +281,9 @@ export default {
           if (this.pageIndex != 1 && this.tableData.length == 1) {
             this.pageIndex--;
           }
-          this.clickID ? this.initData({ id: this.clickID }) : this.initData();
+          this.proxyData.b_m_id = this.clickID ? this.clickID : '';
+
+          this.initData(this.proxyData);
         }
       })
     },
@@ -209,13 +295,14 @@ export default {
     },
     handleMenuClick(e) {
       this.clickID = e.data.id;
-      this.initData({ id: e.id })
+      this.proxyData.b_m_id = e.data.id;
+      this.initData(this.proxyData);
     },
     handleSetState(arr) {
       arr.forEach(ele => {
         ele.label = ele.title;
-        if (ele.children && ele.children.length != 0) {
-          this.handleSetState(ele.children)
+        if (ele.children.length !== 0) {
+          this.handleSetState(ele.children);
         }
       });
       return arr;
@@ -270,9 +357,16 @@ export default {
 </script>
 <style lang="scss" scoped>
 .form_item {
-  width: 100px;
+  width: 150px;
 }
 .date_item {
-  width: 140px;
+  width: 200px;
+}
+.icon {
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  align-items: center;
+  height: 44px;
 }
 </style>

+ 405 - 0
src/views/BasicSettings/ProcessLine/index.vue

@@ -0,0 +1,405 @@
+<template>
+  <div>
+    <Toptitle>
+      <template #right>
+        <Button type="primary" ghost style="margin-right: 10px">导入</Button>
+        <Button type="primary" ghost style="margin-right: 10px">导出</Button>
+        <Button type="primary" ghost icon="md-add" @click="handleSet(null, 1)"
+          >新增工艺路线</Button
+        >
+      </template>
+    </Toptitle>
+    <Form :label-width="120" style="display: flex; flex-wrap: wrap">
+      <FormItem label="工艺路线名称">
+        <Input
+          clearable
+          placeholder="请输入"
+          v-model="searchData.title"
+          style="width: 200px"
+        />
+      </FormItem>
+      <FormItem :label-width="20">
+        <Button type="primary" ghost @click="handleSearch">查询</Button>
+      </FormItem>
+    </Form>
+    <div class="content">
+      <vxe-grid v-bind="gridOptions">
+        <template #set="{ row }">
+          <a @click="handleCopy(row)">复制</a>
+          <a style="margin-left: 10px" @click="handleSet(row, 2)">编辑</a>
+          <a style="margin-left: 10px" @click="handleSet(row, 3)">查看</a>
+          <a style="margin-left: 10px" @click="handleDel(row)">删除</a>
+        </template>
+      </vxe-grid>
+    </div>
+    <Footer
+      :pageSize="pageSize"
+      :pageIndex="pageIndex"
+      :total="total"
+      @changeSize="changeSize"
+      @changePage="changePage"
+    ></Footer>
+    <Modal
+      :title="
+        sort == 1 ? '新增工艺路线' : sort == 2 ? '编辑工艺路线' : '工艺路线详情'
+      "
+      :closable="false"
+      :mask-closable="false"
+      v-model="is_show"
+      fullscreen
+    >
+      <div class="m_title">
+        <Form :label-width="200" style="display: flex; flex-wrap: wrap">
+          <FormItem label="ID">
+            <Input
+              clearable
+              v-model="modalData.id"
+              placeholder="自动生成"
+              disabled
+            />
+          </FormItem>
+          <FormItem label="工艺路线名称">
+            <Input clearable v-model="modalData.title" placeholder="请输入" />
+          </FormItem>
+        </Form>
+      </div>
+      <div class="bd_route">
+        <div class="left">
+          <h3>已选:</h3>
+          <SlickList
+            :distance="10"
+            :lockToContainerEdges="true"
+            axis="x,y,xy"
+            lockAxis="xy"
+            v-model="haveChooseList"
+          >
+            <SlickItem
+              style="z-index: 9999"
+              v-for="(item, key) of haveChooseList"
+              :key="key"
+              :index="key"
+            >
+              <Tooltip>
+                <div slot="content">
+                  <p>工时:{{ item.time }}</p>
+                  <p>工价:{{ item.wages }}</p>
+                  <p>产能:{{ item.capacity }}</p>
+                </div>
+                <div class="tag-modal">
+                  <div class="before">{{ key + 1 }}</div>
+                  <Tag
+                    @on-close="closeTag(item.id, key)"
+                    color="primary"
+                    type="border"
+                    closable
+                    >{{ item.title }}</Tag
+                  >
+                </div>
+              </Tooltip>
+            </SlickItem>
+          </SlickList>
+          <div style="margin-top: 15px">
+            <h3>合计:</h3>
+            <p>{{ `工时:${totalTime}` }}</p>
+            <p>{{ `工价:${totalWages}` }}</p>
+            <p>{{ `产能:${totalCapacity}` }}</p>
+          </div>
+        </div>
+        <div class="right">
+          <div
+            v-for="item in routeList"
+            :key="item.id"
+            style="margin-bottom: 20px"
+          >
+            <h3>{{ item.title }}</h3>
+            <CheckboxGroup v-model="item.sub_id" @on-change="handleSelectRoute">
+              <Tooltip v-for="_item in item.sub" :key="_item.id">
+                <div slot="content">
+                  <p>工时:{{ _item.time }}</p>
+                  <p>工价:{{ _item.wages }}</p>
+                  <p>产能:{{ _item.capacity }}</p>
+                </div>
+                <Checkbox :label="_item.id" style="margin: 10px">
+                  <span>{{ _item.title }}</span>
+                </Checkbox>
+              </Tooltip>
+            </CheckboxGroup>
+          </div>
+        </div>
+      </div>
+      <div slot="footer">
+        <Button style="margin-right: 10px" @click="is_show = false"
+          >取消</Button
+        >
+        <Button type="primary" ghost @click="handleSure" v-show="sort != 3"
+          >确认</Button
+        >
+      </div>
+    </Modal>
+    <Modal
+      :closable="false"
+      :mask-closable="false"
+      v-model="is_copy"
+      title="复制工艺路线"
+      :width="30"
+    >
+      <Form :label-width="140">
+        <FormItem label="复制工艺路线的名称">
+          <Input clearable v-model="copyTitle" placeholder="请输入" />
+        </FormItem>
+      </Form>
+      <div slot="footer">
+        <Button @click="is_copy = false" style="margin-right: 10px"
+          >取消</Button
+        >
+        <Button type="primary" @click="handleCopySure">确认</Button>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+import { SlickList, SlickItem } from 'vue-slicksort'
+export default {
+  components: {
+    SlickList, SlickItem
+  },
+  data() {
+    return {
+      copy_id: '',
+      copyTitle: '',
+      is_copy: false,
+      haveChooseList: [],
+      is_show: false,
+      modalData: {
+        title: ""
+      },
+      pageSize: 10,
+      pageIndex: 1,
+      total: 0,
+      searchData: {},
+      proxyData: {},
+      gridOptions: {
+        border: true,
+        resizable: true,
+        maxHeight: 'auto',
+        showOverflow: true,
+        align: 'center',
+        columns: [
+          { type: 'seq', title: '序号', width: 100 },
+          { field: 'title', title: '工艺路线名称', showHeaderOverflow: true },
+          { field: 'set', title: '操作', showHeaderOverflow: true, width: 200, slots: { default: 'set' } },
+        ],
+        data: []
+      },
+      sort: '',
+      routeList: [],
+      totalTime: 0,
+      totalWages: 0,
+      totalCapacity: 0
+    }
+  },
+  created() {
+    //获取工序分类
+    this.axios.post('/api/basicProcessList').then(res => {
+      let arr = this.getArr(res.data);
+      this.axios.post('/api/processList').then(req => {
+        let sub = req.data.data;
+        sub.forEach(b => {
+          b.is_choose = false;
+        })
+        arr.forEach(v => {
+          v.sub_id = [];
+          v.sub = sub.filter(c => c.p_id == v.id);
+        })
+        this.routeList = arr;
+      })
+    })
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    handleCopySure() {
+      if (!this.copyTitle) {
+        return this.$Message.warning('请输入需要复制的工艺路线名称!')
+      }
+      this.axios.post('/api/technologyCopy', { title: this.copyTitle, id: this.copy_id }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          this.is_copy = false;
+          this.initData(this.proxyData);
+        }
+      })
+    },
+    handleCopy(row) {
+      this.copy_id = row.id;
+      this.copyTitle = '';
+      this.is_copy = true;
+    },
+    closeTag(e, index) {
+      this.haveChooseList.splice(index, 1);
+      this.routeList.forEach(v => {
+        if (v.sub_id.indexOf(e) != -1) {
+          v.sub_id.splice(v.sub_id.indexOf(e), 1);
+        }
+      })
+    },
+    handleSelectRoute() {
+      this.haveChooseList = [];
+      this.routeList.forEach(v => {
+        if (v.sub_id.length != 0) {
+          v.sub.forEach(c => {
+            if (v.sub_id.indexOf(c.id) != -1) {
+              this.haveChooseList.push(c);
+            }
+          })
+
+        }
+      })
+      this.getTotal();
+    },
+    getTotal() {
+      this.totalCapacity = 0;
+      this.totalTime = 0;
+      this.totalWages = 0;
+      this.haveChooseList.forEach(v => {
+        this.totalCapacity += v.capacity * 1;
+        this.totalTime += v.time * 1;
+        this.totalWages += v.wages * 1;
+      })
+    },
+    handleSearch() {
+      this.proxyData = JSON.parse(JSON.stringify(this.searchData));
+      this.pageIndex = 1;
+      this.initData(this.proxyData);
+    },
+    getArr(arr) {
+      let data = [];
+      arr.forEach(ele => {
+        if (ele.children.length == 0) {
+          data.push(ele);
+        } else {
+          data = [...data, ...this.getArr(ele.children)];
+        }
+      });
+      return data
+    },
+    handleSure() {
+      let process_id = this.haveChooseList.map(v => v.id).toString();
+      let data = JSON.parse(JSON.stringify(this.modalData));
+      data.process_id = process_id;
+      if (this.sort == 1) {
+        this.axios.post('/api/technologyAdd', { ...data }).then(res => {
+          if (res.code == 200) {
+            this.$Message.success(res.msg);
+            this.is_show = false;
+            this.initData();
+          }
+        })
+      } else {
+        this.axios.post('/api/technologyEdit', { ...data }).then(res => {
+          if (res.code == 200) {
+            this.$Message.success(res.msg);
+            this.is_show = false;
+            this.initData();
+          }
+        })
+      }
+
+    },
+    handleSet(row, type) {
+      this.is_show = true;
+      this.sort = type;
+      switch (type) {
+        case 1:
+          break;
+        case 2:
+        case 3:
+          this.modalData.title = row.title;
+          this.modalData.id = row.id;
+          let process_id = row.process_id.split(',').map(v => v * 1);
+          this.routeList.forEach(v => {
+            v.sub_id = [];
+            v.sub.forEach(c => {
+              if (process_id.indexOf(c.id) != -1) {
+                v.sub_id.push(c.id);
+              }
+            })
+          })
+          this.handleSelectRoute();
+          break;
+      }
+    },
+    handleDel(row) {
+      this.axios.post('/api/technologyDel', { id: row.id }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          if (this.gridOptions.data.length == 1 && this.pageIndex != 1) {
+            this.pageIndex--;
+          }
+          this.initData(this.proxyData);
+        }
+      })
+    },
+    changeSize(e) {
+      this.pageSize = e;
+      this.pageIndex = 1;
+      this.initData(this.proxyData);
+    },
+    changePage(e) {
+      this.pageIndex = e;
+      this.initData(this.proxyData);
+    },
+    initData(row) {
+      this.axios.post('/api/technologyList', { ...row, page_size: this.pageSize, page_index: this.pageIndex }).then(res => {
+        this.gridOptions.data = res.data.data;
+        this.total = res.data.total;
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.m_title {
+  border-bottom: 1px solid #e1dddd;
+  margin-top: -10px;
+}
+.content {
+  height: calc(100% - 100px);
+  border: 1px solid #fff;
+}
+.bd_route {
+  height: calc(100% - 40px);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20px 0 0 0;
+  .left {
+    width: 20%;
+    border-right: 1px solid;
+    height: 100%;
+    padding: 0 0 0 20px;
+    overflow: auto;
+  }
+  .right {
+    width: 80%;
+    height: 100%;
+    padding: 0 0 0 20px;
+    overflow: auto;
+  }
+}
+.tag-modal {
+  display: flex;
+  align-items: center;
+  .before {
+    width: 20px;
+    background: #3764ff;
+    height: 24px;
+    border-radius: 5px 0 0 5px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+  }
+}
+</style>

+ 138 - 0
src/views/BasicSettings/ProcessManage/detail.vue

@@ -0,0 +1,138 @@
+<template>
+  <div>
+    <Toptitle>
+      <template #right>
+        <Button
+          style="margin-right: 10px"
+          @click="$router.push('/cms/BasicSettings/ProcessManage/index')"
+          >返回</Button
+        >
+        <Button type="primary" ghost @click="handleSave" v-show="type != 3"
+          >保存</Button
+        >
+      </template>
+    </Toptitle>
+    <Form :label-width="120">
+      <FormItem label="ID" class="form_item">
+        <Input
+          style="width: 80%"
+          clearable
+          v-model="formData.id"
+          disabled
+          placeholder="自动生成"
+        />
+      </FormItem>
+      <FormItem label="工序名称" class="form_item">
+        <Input
+          clearable
+          v-model="formData.title"
+          placeholder="请输入"
+          style="width: 80%"
+        />
+      </FormItem>
+      <FormItem label="工时" class="form_item">
+        <Input
+          clearable
+          v-model="formData.time"
+          placeholder="请输入"
+          style="width: 80%"
+        >
+          <span slot="append">小时</span>
+        </Input>
+      </FormItem>
+      <FormItem label="产能" class="form_item">
+        <Input
+          clearable
+          v-model="formData.capacity"
+          placeholder="请输入"
+          style="width: 80%"
+        />
+      </FormItem>
+      <FormItem label="工价" class="form_item">
+        <Select
+          filterable
+          clearable
+          v-model="formData.wages_unit"
+          style="width: 20%"
+        >
+          <Option :value="0" label="按件" />
+          <Option :value="1" label="按天" />
+        </Select>
+        <Input
+          clearable
+          placeholder="请输入价格"
+          v-model="formData.wages"
+          style="width: 60%"
+        />
+      </FormItem>
+      <FormItem label="默认班组" class="form_item">
+        <Select
+          clearable
+          filterable
+          v-model="formData.team_id"
+          style="width: 80%"
+        >
+          <Option
+            v-for="item in teamList"
+            :key="item.id"
+            :label="item.title"
+            :value="item.id"
+          />
+        </Select>
+      </FormItem>
+    </Form>
+  </div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      formData: {},
+      teamList: [],
+      type: ''
+    }
+  },
+  created() {
+    this.axios.post('/api/teamList').then(res => {
+      this.teamList = res.data.data;
+    })
+  },
+  mounted() {
+    this.type = this.$route.query.type;
+    if (this.type != 1) {
+      this.initData();
+    }
+  },
+  methods: {
+    initData() {
+      this.axios.post('/api/processDetail', { id: this.$route.query.id }).then(res => {
+        this.formData = res.data;
+      })
+    },
+    handleSave() {
+      let data = JSON.parse(JSON.stringify(this.formData));
+      data.p_id = this.$route.query.basicProcess_id;
+      if (this.type == 1) {
+        this.axios.post('/api/processAdd', { ...data }).then(res => {
+          if (res.code == 200) {
+            this.$Message.success(res.msg);
+            this.$router.push('/cms/BasicSettings/ProcessManage/index')
+          }
+        })
+      } else {
+        this.axios.post('/api/processEdit', { ...data }).then(res => {
+          if (res.code == 200) {
+            this.$Message.success(res.msg);
+            this.initData();
+          }
+        })
+      }
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.form_item {
+  margin: 20px !important;
+}
+</style>

+ 349 - 0
src/views/BasicSettings/ProcessManage/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div>
+    <!-- 角色管理 -->
+    <Toptitle>
+      <template #left>
+        <Button type="primary" @click="handleShow">{{
+          showText ? "收缩" : "展开"
+        }}</Button>
+      </template>
+      <template #right>
+        <Button type="primary" @click="handleAdd">新增工序</Button>
+      </template>
+    </Toptitle>
+    <HaveSideMenu
+      :columnList="columnList"
+      :tableData="tableData"
+      @handleNodeClick="handleMenuClick"
+      :menuList="processList"
+      :pageSize="pageSize"
+      :pageIndex="pageIndex"
+      :total="total"
+      @changeSize="changeSize"
+      @changePage="changePage"
+      @append="append"
+      @remove="remove"
+      :searchHeight="searchHeight"
+      @handleAddBM="handleAddBM(false)"
+    >
+      <template #crt_time="{ row }">
+        <span>{{ func.replaceDateNoHMS(row.crt_time) }}</span>
+      </template>
+      <template #upd_time="{ row }">
+        <span>{{ func.replaceDateNoHMS(row.upd_time) }}</span>
+      </template>
+      <template #set="{ row }">
+        <a style="margin-right: 10px" @click="handleEdit(row)">编辑</a>
+        <a style="margin-right: 10px" @click="handleDel(row)">删除</a>
+        <a @click="handleDetail(row)">详情</a>
+      </template>
+      <template #form>
+        <Form :label-width="80" style="display: flex; flex-wrap: wrap">
+          <FormItem label="工序名称">
+            <Input
+              size="small"
+              class="form_item"
+              v-model="searchData.title"
+              placeholder="请输入"
+            />
+          </FormItem>
+          <FormItem :label-width="20">
+            <Button type="primary" ghost @click="handleSearch" size="small"
+              >查询</Button
+            >
+          </FormItem>
+        </Form>
+      </template>
+    </HaveSideMenu>
+    <Modal
+      title="选择工序分类"
+      :closable="false"
+      :mask-closable="false"
+      v-model="show_basic"
+      width="30"
+    >
+      <ChooseTap :list="tapList" :is_one="true"></ChooseTap>
+      <div slot="footer">
+        <Button @click="show_basic = false">取消</Button>
+        <Button @click="handleSureBasic" type="primary">确认</Button>
+      </div>
+    </Modal>
+    <Modal
+      title="新增工序分类"
+      :closable="false"
+      :mask-closable="false"
+      v-model="is_addBM"
+      width="30"
+    >
+      <div style="max-height: 400px; overflow: auto">
+        <Form
+          :label-width="100"
+          v-for="(item, index) in modalData"
+          :key="index"
+          style="display: flex"
+        >
+          <FormItem label="工序分类名称" style="width: 70%">
+            <Input
+              clearable
+              placeholder="请输入"
+              v-model="item.title"
+              style="width: 100%"
+            />
+          </FormItem>
+          <FormItem :label-width="10" style="width: 20%">
+            <div class="icon">
+              <Icon
+                :size="20"
+                type="ios-add-circle-outline"
+                style="padding-right: 10px; cursor: pointer"
+                @click="handleModalAdd(index)"
+              />
+              <Icon
+                :size="20"
+                type="ios-remove-circle-outline"
+                style="cursor: pointer"
+                @click="handleModalRemove(index)"
+              />
+            </div>
+          </FormItem>
+        </Form>
+      </div>
+      <div slot="footer">
+        <Button style="margin-right: 10px" @click="is_addBM = false"
+          >取消</Button
+        >
+        <Button type="primary" @click="handleSureBM">确认</Button>
+      </div>
+    </Modal>
+  </div>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      is_addBM: false,
+      show_basic: false,
+      processList: [],
+      proxyData: {},
+      searchData: {},
+      clickID: null,
+      tapList: [],
+      tableData: [],
+      columnList: [
+        { type: 'seq', title: '序号' }, { field: 'title', title: '工序名称' }, { field: 'time', title: '工时' }, { field: 'wages', title: '工价' }, { field: 'capacity', title: '产能', }, { field: 'set', title: '操作', is_default: true, deSlot: 'set' }
+      ],
+      total: 0,
+      pageIndex: 1,
+      pageSize: 10,
+      searchHeight: '0px',
+      showText: false,
+      modalData: [],
+      selectID: ''
+    }
+  },
+  created() {
+    //获取工序分类
+    this.getprocess();
+  },
+  mounted() {
+    // window.addEventListener('beforeunload', (e) => this.beforeunloadHandler(e));
+    // window.addEventListener('unload', this.updateHandler);
+    this.initData();
+  },
+  methods: {
+    handleSearch() {
+      this.proxyData = JSON.parse(JSON.stringify(this.searchData));
+      this.pageIndex = 1;
+      this.initData(this.proxyData);
+    },
+    handleModalAdd(index) {
+      this.modalData.splice(index + 1, 0, { title: "" })
+    },
+    handleModalRemove(index) {
+      if (this.modalData.length == 1) {
+        return
+      } else {
+        this.modalData.splice(index, 1)
+      }
+
+    },
+    handleSureBM() {
+      let data = JSON.parse(JSON.stringify(this.modalData));
+      data.forEach(v => {
+        v.parent_id = this.selectID;
+      })
+      this.axios.post('/api/basicProcessAdd', { data }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          this.getprocess();
+          this.is_addBM = false;
+        }
+      })
+    },
+    handleAddBM(e) {
+      if (e) {
+        this.selectID = e;
+      } else {
+        this.selectID = 0;
+      }
+      console.log(e);
+      this.is_addBM = true;
+      this.modalData = [{ title: '' }];
+    },
+    handleShow() {
+      if (this.searchHeight === 'auto') {
+        this.searchHeight = '0px';
+        this.showText = false;
+      } else {
+        this.searchHeight = 'auto'
+        this.showText = true;
+      }
+    },
+    getprocess() {
+      this.axios.post('/api/basicProcessList').then(res => {
+        this.processList = this.handleSetState(res.data);
+        this.tapList = this.getArr(this.processList);
+      })
+    },
+    getArr(arr) {
+      let data = [];
+      arr.forEach(v => {
+        if (v.children.length == 0) {
+          data.push(v);
+        } else {
+          data = [...data, ...this.getArr(v.children)];
+        }
+      })
+      return data
+    },
+    append(data) {
+      this.handleAddBM(data.id);
+    },
+    remove(data) {
+      this.axios.post('/api/basicProcessDel', { id: data.data.id }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          this.getprocess();
+        }
+      })
+    },
+    handleEdit(row) {
+      // if (!this.clickID) {
+      //   return this.$Message.warning('请先选择要新增的工序分类!');
+      // }
+      this.$router.push({ path: '/cms/BasicSettings/ProcessManage/detail', query: { type: 2, title: '编辑工序', id: row.id, basicProcess_id: row.p_id } })
+    },
+    handleSureBasic() {
+      if (!this.tapList.find(v => (v.is_choose))) {
+        return this.$Message.warning('请选择一个工序分类!')
+      }
+      this.show_basic = false;
+      this.$router.push({ path: '/cms/BasicSettings/ProcessManage/detail', query: { type: 1, basicProcess_id: this.tapList.find(v => (v.is_choose)).id, title: '新增工序' } })
+
+    },
+    handleAdd() {
+      // if (!this.clickID) {
+      //   return this.$Message.warning('请先选择要新增的工序分类!');
+      // }
+      this.show_basic = true;
+
+    },
+    handleDetail(row) {
+      this.$router.push({ path: '/cms/BasicSettings/ProcessManage/detail', query: { type: 3, title: '工序详情', id: row.id, basicProcess_id: row.p_id } })
+    },
+    handleDel(row) {
+      this.axios.post('/api/processDel', { id: row.id }).then(res => {
+        if (res.code == 200) {
+          this.$Message.success(res.msg);
+          if (this.pageIndex != 1 && this.tableData.length == 1) {
+            this.pageIndex--;
+          }
+          this.proxyData.b_m_id = this.clickID ? this.clickID : '';
+
+          this.initData(this.proxyData);
+        }
+      })
+    },
+    initData(row) {
+      this.axios.post('/api/processList', { ...row, page_size: this.pageSize, page_index: this.pageIndex }).then(res => {
+        this.tableData = res.data.data;
+        this.total = res.data.total;
+      })
+    },
+    handleMenuClick(e) {
+      this.clickID = e.data.id;
+      this.proxyData.p_id = e.data.id;
+      this.initData(this.proxyData);
+    },
+    handleSetState(arr) {
+      arr.forEach(ele => {
+        ele.label = ele.title;
+        if (ele.children.length !== 0) {
+          this.handleSetState(ele.children);
+        }
+      });
+      return arr;
+    },
+    changeSize(e) {
+      this.pageSize = e;
+      this.pageIndex = 1;
+      this.initData({ id: this.clickID });
+    },
+    changePage(e) {
+      this.pageIndex = e;
+      this.initData({ id: this.clickID });
+    },
+    //   beforeunloadHandler(e) {
+    //     if (localStorage.getItem('personnelmanagement_tableData')) {
+    //       localStorage.removeItem('personnelmanagement_tableData');
+    //     }
+    //     localStorage.setItem('personnelmanagement_tableData', JSON.stringify(this.tableData));
+    //   },
+    //   updateHandler() {
+    //     if (localStorage.getItem('personnelmanagement_tableData')) {
+
+    //       this.tableData = JSON.parse(localStorage.getItem('personnelmanagement_tableData'));
+
+
+    //     }
+    //   },
+    //   handleTest() {
+    //     const num = this.$utils.merge({ a: 1 }, { b: 1 }, { c: 1 });
+    //     console.log(num);
+    //   }
+    // },
+    // beforeRouteLeave(to, from, next) {
+    //   if (localStorage.getItem('personnelmanagement_tableData')) {
+    //     localStorage.removeItem('personnelmanagement_tableData');
+    //   }
+    //   localStorage.setItem('personnelmanagement_tableData', JSON.stringify(this.tableData));
+    //   next();
+    // },
+    // beforeRouteEnter(to, from, next) {
+    //   if (localStorage.getItem('personnelmanagement_tableData')) {
+    //     next(vm => {
+    //       vm.tableData = JSON.parse(localStorage.getItem('personnelmanagement_tableData'));
+
+    //     })
+    //   } else {
+    //     next()
+    //   }
+
+  }
+}
+</script>
+<style lang="scss" scoped>
+.form_item {
+  width: 150px;
+}
+.date_item {
+  width: 200px;
+}
+.icon {
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  align-items: center;
+  height: 44px;
+}
+</style>

+ 6 - 0
src/views/cms.vue

@@ -28,10 +28,16 @@
         <div ref="keepAliveContainer" style="height: 95%">
           <keep-alive>
             <router-view
+              v-if="$route.meta.keepAlive"
               :key="$route.fullPath"
               :class="['router-style', 'router-style-page']"
             />
           </keep-alive>
+          <router-view
+            :key="$route.fullPath"
+            :class="['router-style', 'router-style-page']"
+            v-if="!$route.meta.keepAlive"
+          />
         </div>
       </div>
     </div>

+ 24 - 25
src/views/login.vue

@@ -19,11 +19,11 @@
     <div class="login-form">
       <p>登录</p>
       <Form ref="userInfo" :model="userInfo" :rules="rulesInfo">
-        <FormItem label="账号" prop="name">
+        <FormItem label="账号" prop="account">
           <Input
             size="large"
             placeholder="请输入您的账号"
-            v-model="userInfo.name"
+            v-model="userInfo.account"
           />
         </FormItem>
 
@@ -60,11 +60,11 @@ export default {
   data() {
     return {
       userInfo: {
-        name: '',
+        account: '',
         password: '',
       },
       rulesInfo: {
-        name: [
+        account: [
           { required: true, message: '请输入账号', trigger: 'blur' }
         ],
         password: [
@@ -106,29 +106,28 @@ export default {
     submit() {
       let userInfo = JSON.stringify(this.userInfo)
       localStorage.setItem('loginInfo', userInfo)
-      // this.loading = true
-      // this.axios.post('/api/login',this.userInfo).then(res=>{
-      //     this.loading = false
-      //     if(res.code == 200){
-      //         this.$Message.success(res.msg||'登陆成功')
-      //         if(res.data.token){
-      //             localStorage.setItem('token',res.data.token)
-      //             let user = JSON.stringify(res.data.user_info);
-      //             localStorage.setItem('user_info',user)
-      //             this.$router.push({path:'/cms/home',query:{title:'首页'}})
-      //         }
-      //     }
-      // })
-      this.$router.push({ path: '/cms/home', query: { title: '首页' } })
+      this.loading = true
+      this.axios.post('/api/login', this.userInfo).then(res => {
+        this.loading = false
+        if (res.code == 200) {
+          this.$Message.success(res.msg || '登陆成功')
+          if (res.data.token) {
+            localStorage.setItem('jf2_token', res.data.token)
+            let user = JSON.stringify(res.data.user_info);
+            localStorage.setItem('user_info', user)
+            this.$router.push({ path: '/cms/home', query: { title: '首页' } })
+          }
+        }
+      })
 
     },
-    handleSubmit(name) {
-      // this.$refs[name].validate((valid) => {
-      //   if (valid) {
-      //     this.submit()
-      //   }
-      // })
-      this.submit()
+    handleSubmit(account) {
+      this.$refs[account].validate((valid) => {
+        if (valid) {
+          this.submit()
+        }
+      })
+      // this.submit()
     },
     storageUserInfo() {
       localStorage.setItem('autoLogin', this.autoLogin)