zhengnaiwen_citu 6 mesiacov pred
rodič
commit
db8de26f44

+ 9 - 0
src/permission.js

@@ -43,6 +43,15 @@ router.beforeEach(async (to, from, next) => {
         await checkToken()
       }
     }
+    // 判断是否已经存在机构信息
+    if (!store.getters.organizationTree.length) {
+      store.dispatch('system/getOrganizationTree').catch(e => {
+        Vue.prototype.$message.error('获取机构信息失败')
+      }).finally(() => {
+        onFilterRoutes(to, next)
+      })
+      return
+    }
     onFilterRoutes(to, next)
   } catch (error) {
     Vue.prototype.$message.error(error)

+ 6 - 3
src/store/getters.js

@@ -2,13 +2,16 @@ const getters = {
   userInfo: state => state.user.userInfo,
   name: state => state.user.name,
   avatar: state => state.user.avatar,
+  employeeInfo: state => state.user.employeeInfo,
   // singleSignOn: state => state.user.singleSignOn,
+
   routes: state => state.menu.routes,
-  lang: state => state.system.lang,
-  systemInfo: state => state.system.systemInfo,
   refresh: state => state.menu.refresh,
   permission: state => state.menu.permission,
-  employeeInfo: state => state.user.employeeInfo
+
+  lang: state => state.system.lang,
+  systemInfo: state => state.system.systemInfo,
+  organizationTree: state => state.system.organizationTree
 }
 
 export default getters

+ 35 - 2
src/store/modules/system.js

@@ -1,8 +1,15 @@
 
+import {
+  getOrganizationTree as getOrganizationTreeApi
+} from '@/api/system'
+
+const organizationTree = localStorage.getItem('ORGANIZATION_TREE') ?? JSON.stringify([])
+
 const state = {
   lang: localStorage.getItem('lang') ?? 'zh',
   subTitleBgColor: '#eee', // 低级标题背景色
-  systemInfo: JSON.parse(localStorage.getItem('systemInfo'))
+  systemInfo: JSON.parse(localStorage.getItem('systemInfo')),
+  organizationTree: JSON.parse(organizationTree)
 }
 
 const mutations = {
@@ -14,10 +21,36 @@ const mutations = {
   SET_SYSTEM_INFO (state, data) {
     localStorage.setItem('systemInfo', JSON.stringify(data))
     state.systemInfo = data
+  },
+  SET_ORGANIZATION_TREE (state, data) {
+    localStorage.setItem('ORGANIZATION_TREE', JSON.stringify(data))
+    state.organizationTree = data
   }
 }
 
-const actions = {}
+const actions = {
+  getOrganizationTree ({ commit, dispatch }) {
+    return new Promise((resolve, reject) => {
+      getOrganizationTreeApi().then(({ data }) => {
+        commit('SET_ORGANIZATION_TREE', removeEmptyArray([data]))
+        resolve(data)
+      }).catch(error => {
+        reject(error)
+      })
+    })
+
+    function removeEmptyArray (arr) {
+      return arr.map(e => {
+        if (e.child && e.child.length) {
+          e.child = removeEmptyArray(e.child)
+        } else {
+          e.child = null
+        }
+        return e
+      })
+    }
+  }
+}
 
 export default {
   namespaced: true,

+ 0 - 29
src/utils/dict.js

@@ -1,8 +1,3 @@
-import Vue from 'vue'
-
-import {
-  getOrganizationTree as getOrganizationTreeApi
-} from '@/api/system'
 
 export const MENU_TYPE = {
   DIRECTORY: 0,
@@ -10,27 +5,3 @@ export const MENU_TYPE = {
   BUTTON: 2,
   COMPONENT: 3
 }
-
-let organizationTree = []
-export const getOrganizationTree = async (data) => {
-  try {
-    if (!organizationTree.length) {
-      const { data } = await getOrganizationTreeApi()
-      organizationTree = removeEmptyArray([data])
-    }
-    return organizationTree
-  } catch (error) {
-    Vue.$message.error(error.message)
-  }
-
-  function removeEmptyArray (arr) {
-    return arr.map(e => {
-      if (e.child && e.child.length) {
-        e.child = removeEmptyArray(e.child)
-      } else {
-        e.child = null
-      }
-      return e
-    })
-  }
-}

+ 2 - 14
src/views/bonus/allocation/index.vue

@@ -44,9 +44,6 @@ import {
   getAllocationStatistics,
   saveAllocation
 } from '@/api/bonus'
-import {
-  getOrganizationTree
-} from '@/utils/dict'
 import { STATUS_LIST } from '../utils'
 import { mapGetters } from 'vuex'
 export default {
@@ -68,12 +65,11 @@ export default {
       query: {},
       employeeCategoryItems: [],
       totalGrantPerformanceSalary: 0,
-      deptItems: [],
       loading: false
     }
   },
   computed: {
-    ...mapGetters(['employeeInfo']),
+    ...mapGetters(['employeeInfo', 'organizationTree']),
     totalAllocationPerformanceSalary () {
       return Object.values(this.values).reduce((r, v) => {
         return new Decimal(r).plus(v || 0)
@@ -103,7 +99,7 @@ export default {
           options: {
             clearable: true,
             placeholder: '请选择部门',
-            options: this.deptItems,
+            options: this.organizationTree,
             showAllLevels: false,
             props: {
               emitPath: false,
@@ -128,7 +124,6 @@ export default {
   },
   async created () {
     this.loading = true
-    this.onGetDept()
     await this.getEmployeeCategoryItems()
     this.searchValues.organizationNo = this.employeeInfo.organizationNo
     this.query = { ...this.searchValues }
@@ -159,13 +154,6 @@ export default {
       //   // this.$set(this.values, e.employeePerformanceId, e.allocationPerformanceSalary || null)
       // })
     },
-    async onGetDept () {
-      const data = await getOrganizationTree()
-      if (!data) {
-        return
-      }
-      this.deptItems = data
-    },
     async getEmployeeCategoryItems () {
       try {
         const { data } = await getAllocationEmployeeCategory({

+ 9 - 10
src/views/humanResources/organizationStructure/index.vue

@@ -3,7 +3,7 @@
     v-loading="loading"
     row-key="uuid"
     card-title="组织机构"
-    :items="items"
+    :items="organizationTree"
     :headers="headers"
     :page-size="total"
     :page-current="1"
@@ -21,34 +21,33 @@
 import {
   organizationDrill
 } from '@/api/system'
-import {
-  getOrganizationTree
-} from '@/utils/dict'
+import { mapGetters } from 'vuex'
+
 export default {
   name: 'organization-structure',
   data () {
     return {
       expandRowKeys: [],
       loading: false,
-      items: [],
       total: 0,
       headers: [
         { label: '机构名称', prop: 'organizationName' }
       ]
     }
   },
+  computed: {
+    ...mapGetters(['organizationTree'])
+  },
   created () {
     this.init()
   },
   methods: {
     async init () {
-      const data = await getOrganizationTree()
-      if (!data) {
+      if (!this.organizationTree.length) {
         return
       }
-      this.expandRowKeys = [data[0].uuid]
-      this.items = data
-      this.total = this.items.length
+      this.expandRowKeys = [this.organizationTree[0].uuid]
+      this.total = this.organizationTree.length
     },
     async load (tree, treeNode, resolve) {
       try {

+ 11 - 11
src/views/humanResources/panorama/index.vue

@@ -3,7 +3,7 @@
     <m-card class="content-left mr-3">
       <el-tree
         ref="tree"
-        :data="treeItems"
+        :data="organizationTree"
         :props="defaultProps"
         node-key="organizationNo"
         :expand-on-click-node="false"
@@ -66,10 +66,8 @@ import {
   getOrganizationDetails
 } from '@/api/system'
 
-import {
-  getOrganizationTree
-} from '@/utils/dict'
 import qs from 'qs'
+import { mapGetters } from 'vuex'
 export default {
   name: 'human-resources-panorama',
   data () {
@@ -84,7 +82,6 @@ export default {
         label: 'organizationName'
       },
       expandExpandedKeys: null,
-      treeItems: [],
       pageInfo: {
         current: 1,
         size: 10
@@ -101,20 +98,21 @@ export default {
       items: []
     }
   },
+  computed: {
+    ...mapGetters(['organizationTree'])
+  },
   created () {
     this.getDept()
   },
   methods: {
     async getDept () {
-      const data = await getOrganizationTree()
-      if (!data) {
+      if (!this.organizationTree.length) {
         return
       }
-      this.expandExpandedKeys = data[0].organizationNo
-      this.treeItems = data
-      this.handleNodeClick({ organizationNo: data[0].organizationNo })
+      this.expandExpandedKeys = this.organizationTree[0].organizationNo
+      this.handleNodeClick({ organizationNo: this.organizationTree[0].organizationNo })
       this.$nextTick(() => {
-        this.$refs.tree.setCurrentKey(data[0].organizationNo)
+        this.$refs.tree.setCurrentKey(this.organizationTree[0].organizationNo)
       })
     },
     async onInit () {
@@ -194,6 +192,8 @@ export default {
   }
 }
 .link {
+  color: #409eff;
+  text-decoration: underline;
   cursor: pointer;
   &:hover {
     color: #409eff;

+ 4 - 9
src/views/humanResources/panorama/panoramaDetails.vue

@@ -18,7 +18,7 @@
       </el-breadcrumb>
     </div>
     <div class="content-body">
-      <component :is="componentsPath" :key="$route.fullPath" ref="panorama" @hook:mounted="onMounted"></component>
+      <component :is="componentsPath" :key="$route.fullPath" :panorama="true" ref="panorama" @hook:mounted="onMounted"></component>
     </div>
   </div>
 </template>
@@ -27,7 +27,6 @@
 import { mapGetters } from 'vuex'
 import PanoramaDetailsMenu from './panoramaDetailsMenu.vue'
 
-import { getOrganizationTree } from '@/utils/dict'
 import {
   findPath
 } from '@/utils/panorama'
@@ -37,13 +36,13 @@ export default {
   components: { PanoramaDetailsMenu },
   data () {
     return {
-      activeIndex: 'humanResources/payroll',
+      activeIndex: 'humanResources/roster',
       breadcrumbs: [],
       componentsPath: null
     }
   },
   computed: {
-    ...mapGetters(['routes']),
+    ...mapGetters(['routes', 'organizationTree']),
     menuList () {
       return this.filterRoute(JSON.parse(JSON.stringify(this.routes)))
     },
@@ -66,11 +65,7 @@ export default {
   },
   methods: {
     async getDept () {
-      const data = await getOrganizationTree()
-      if (!data) {
-        return
-      }
-      this.breadcrumbs = findPath(data, this.$route.query.organizationNo)
+      this.breadcrumbs = findPath(this.organizationTree, this.$route.query.organizationNo)
       if (this.$route.query.employeeName && this.$route.query.employeeNo) {
         this.breadcrumbs.push({ value: this.$route.query.employeeNo, label: this.$route.query.employeeName })
       }

+ 48 - 19
src/views/humanResources/roster/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="white" :class="{ 'pa-3': !panorama.organizationNo }">
-    <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
+    <m-search v-if="!panorama.organizationNo" :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
       <template #button>
         <m-button type="primary" icon="el-icon-plus" plain @click="onAdd">新增</m-button>
         <el-upload class="el-button pa-0" action="#" :show-file-list="false" :http-request="onImport">
@@ -51,24 +51,6 @@ export default {
       exportLoading: false,
       downloadLoading: false,
       title: '',
-      searchItems: [
-        {
-          label: '员工名称',
-          options: {
-            placeholder: '请输入员工名称'
-          },
-          prop: 'employeeName',
-          type: 'input'
-        },
-        {
-          label: '机构名称',
-          options: {
-            placeholder: '请输入机构名称'
-          },
-          prop: 'organizationName',
-          type: 'input'
-        }
-      ],
       loading: false,
       searchValues: {
         employeeName: null
@@ -99,16 +81,63 @@ export default {
       total: 0
     }
   },
+  computed: {
+    searchItems () {
+      return [
+        {
+          label: '员工名称',
+          options: {
+            placeholder: '请输入员工名称'
+          },
+          prop: 'employeeName',
+          type: 'input'
+        },
+        {
+          label: '部门名称',
+          options: {
+            placeholder: '请输入机构名称'
+          },
+          prop: 'organizationName',
+          type: 'input'
+        }
+      ]
+    }
+  },
   created () {
+    // 全景视图终止自动调用
+    if (this.$attrs.panorama) {
+      return
+    }
     this.init()
   },
   methods: {
     // 执行全景初始化操作
     onInitPanorama (organizationNo, employeeNo) {
       this.panorama = { organizationNo, employeeNo }
+      if (employeeNo) {
+        this.searchValues = {
+          personnelCode: employeeNo
+        }
+        return
+      }
+      this.searchValues = {
+        organizationNo: organizationNo
+      }
+      this.init()
     },
     async init () {
       this.loading = true
+      const query = {}
+      if (this.searchValues.personnelCode) {
+        query.entity = {
+          personnelCode: this.searchValues.personnelCode
+        }
+      }
+      if (this.searchValues.organizationNo) {
+        Object.assign(query, {
+          organizationNo: this.searchValues.organizationNo
+        })
+      }
       try {
         const { data } = await getRosterList({
           page: { ...this.pageInfo, orders: this.orders },

+ 8 - 23
src/views/humanResources/welfare/welfareList/welfareRules.vue

@@ -1,6 +1,6 @@
 <template>
   <m-dialog ref="dialog" :title="itemData.subsidy?.subsidyName + ' 规则配置'" width="1000px" @sure="onSure">
-    <el-form ref="form" :model="formQuery">
+    <el-form ref="form" :model="formQuery" v-loading="loading">
       <m-table
         shadow="naver"
         :items="formQuery.items"
@@ -18,7 +18,7 @@
             v-model="formQuery.items[scope.$index].subsidyOrganizationNos"
             placeholder="请输入机构名称"
             :ref="'cascader' + scope.$index"
-            :options="options"
+            :options="organizationTree"
             :show-all-levels="false"
             collapse-tags
             :props="{
@@ -70,10 +70,8 @@ import {
   saveWelfare,
   getWelfareDetail
 } from '@/api/welfare'
+import { mapGetters } from 'vuex'
 
-import {
-  getOrganizationTree
-} from '@/utils/dict'
 export default {
   name: 'welfare-rules',
   data () {
@@ -95,12 +93,16 @@ export default {
         { label: '操作', prop: 'actions', width: 100 }
       ],
       itemData: {},
-      options: []
+      loading: false
     }
   },
+  computed: {
+    ...mapGetters(['organizationTree'])
+  },
   methods: {
     async open (item) {
       this.$refs.dialog.open()
+      this.loading = true
       try {
         const { data } = await getWelfareDetail({
           subsidyId: item.subsidyId
@@ -114,29 +116,12 @@ export default {
             subsidyCheck: e.subsidyCheck
           }
         })
-        await this.getDeptTree()
       } catch (error) {
         this.$message.error(error)
       } finally {
         this.loading = false
       }
     },
-    async getDeptTree () {
-      const data = await getOrganizationTree()
-      if (!data) {
-        return
-      }
-      this.options = this.assignData(data)
-    },
-    assignData (data) {
-      return data.map(res => {
-        const { child, ...e } = res
-        return {
-          ...e,
-          child: child && child.length ? this.assignData(child) : undefined
-        }
-      })
-    },
     onAdd () {
       this.formQuery.items.push({
         subsidyOrganizationNames: [],