From 6448ec15bfe0b65fb822a662105bceddc23b58d8 Mon Sep 17 00:00:00 2001
From: yubo <autumnal_wind@yeah.net>
Date: 星期一, 06 四月 2026 21:34:44 +0800
Subject: [PATCH] feat(user): 新增员工档案管理视图组件

---
 src/views/dashboard/lzUser.vue        |   22 
 src/views/remind/retirement.vue       |   17 
 src/views/login/index.vue             |   11 
 src/views/remind/contract.vue         |   18 
 src/views/dashboard/ctUser.vue        |   43 
 src/views/user/search.vue             |  139 +---
 src/views/yunpan/fujian.vue           |   58 -
 src/views/dashboard/zzUser.vue        |   15 
 src/settings_server.js                |   38 +
 src/views/dashboard/ygUser.vue        |   41 
 src/views/remind/probation.vue        |   18 
 src/views/dashboard/HtUser.vue        |   16 
 src/views/user/Informationinput.vue   |  125 +---
 src/utils/dictMixin.js                |   27 
 src/views/dashboard/onTheJobUser.vue  |   67 +
 src/views/dashboard/tjUser.vue        |   23 
 src/views/dashboard/qjUser.vue        |   23 
 src/views/dashboard/ywUser.vue        |   21 
 src/views/remind/insurance5.vue       |   98 --
 src/views/user/archivesChange.vue     |  183 ++----
 src/settings_local.js                 |   30 
 nginx.conf                            |  120 ++-
 src/views/user/inemployees.vue        |  132 +---
 src/settings.js                       |   34 
 src/views/user/outemployess.vue       |   46 -
 src/views/dashboard/sbUser.vue        |   29 
 src/views/dashboard/insuranceUser.vue |   15 
 src/views/dashboard/tgUser.vue        |   17 
 src/utils/request.js                  |    3 
 src/store/modules/dict.js             |   83 ++
 src/views/user/archivesEdit.vue       |  128 +---
 .env.production                       |    2 
 src/api/data.js                       |    7 
 src/views/dashboard/gsUser.vue        |   19 
 34 files changed, 722 insertions(+), 946 deletions(-)

diff --git a/.env.production b/.env.production
index 2c521fe..5248da6 100644
--- a/.env.production
+++ b/.env.production
@@ -2,5 +2,5 @@
 ENV = 'production'
 
 # base api
-VUE_APP_BASE_API = 'http://120.24.23.155:8301/'
+VUE_APP_BASE_API = '/api/'
 
diff --git a/nginx.conf b/nginx.conf
index bb37410..ca94e62 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -1,65 +1,83 @@
-worker_processes  auto;
-
-error_log   /var/log/nginx/error.log;
-pid   /run/nginx.pid;
+worker_processes 1;
 
 events {
-    worker_connections  1024;
+    worker_connections 1024;
 }
 
 http {
-        include mime.types;
-        default_type  application/octet-stream;
+    include mime.types;
+    default_type application/octet-stream;
+    sendfile on;
+    keepalive_timeout 65;
 
-        server_names_hash_bucket_size 512;
-        client_header_buffer_size 32k;
-        large_client_header_buffers 4 32k;
-        client_max_body_size 50m;
-
-        sendfile   on;
-        tcp_nopush on;
-
-        keepalive_timeout 60;
-        tcp_nodelay on;
-
-        fastcgi_connect_timeout 300;
-        fastcgi_send_timeout 300;
-        fastcgi_read_timeout 300;
-        fastcgi_buffer_size 64k;
-        fastcgi_buffers 4 64k;
-        fastcgi_busy_buffers_size 128k;
-        fastcgi_temp_file_write_size 256k;
-        fastcgi_intercept_errors on;
-
-        gzip on;
-        gzip_min_length  1k;
-        gzip_buffers     16 8k;
-        gzip_http_version 1.1;
-        gzip_comp_level 6;
-        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
-        gzip_vary on;
-        gzip_proxied   expired no-cache no-store private auth;
-        gzip_disable   "MSIE [1-6]\.";
-
-        limit_conn_zone $binary_remote_addr zone=perip:10m;
-        limit_conn_zone $server_name zone=perserver:10m;
-
-        server_tokens off;
-        access_log off;
-
-
+    # 当后端连接数达到上限时,新请求将进入队列等待
+    proxy_connect_timeout 5s;
+    # 限制每个后端 Worker 的队列长度
+    limit_conn_zone $server_name zone=conn_zone:10m;
+    limit_conn conn_zone 10;
+	
+    # ========== 你的域名配置(直接写在 http 内部)==========
+    
+    # HTTP 重定向
     server {
-        listen       80;
-        server_name  localhost;
+        listen 80;
+        server_name zbyt.esunsail.com;
+        return 301 https://$server_name$request_uri;
+    }
+
+    # HTTPS 配置
+    server {
+        listen 443 ssl;
+		http2 on;
+        server_name zbyt.esunsail.com;
+
+        ssl_certificate     C:/inetpub/win-acme/certs/zbyt.esunsail.com/zbyt.esunsail.com.pem;
+        ssl_certificate_key C:/inetpub/win-acme/certs/zbyt.esunsail.com/zbyt.esunsail.com.key;
+
+        ssl_protocols TLSv1.2 TLSv1.3;
+       # ssl_ciphers HIGH:!aNULL:!MD5;
+	    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...'; # 使用较新的套件
+        ssl_prefer_server_ciphers on;
+        ssl_session_cache   shared:SSL:10m; # 10M共享内存,可存储约8万个会话
+        ssl_session_timeout 10m;
+		ssl_session_tickets on;
 
         charset utf-8;
+        access_log logs/zbyt.esunsail.com.access.log;
+        error_log logs/zbyt.esunsail.com.error.log;
 
         location / {
-            root   html;
-            index  index.html index.htm;
+            proxy_pass http://127.0.0.1:8000;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto $scheme;
+            proxy_connect_timeout 60s;
+            proxy_send_timeout 60s;
+            proxy_read_timeout 60s;
         }
-        location = /50x.html {
-            root   html;
+
+        location /api/ {
+            proxy_pass http://127.0.0.1:8301/;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto $scheme;
+            proxy_connect_timeout 30s;
+            proxy_send_timeout 30s;
+            proxy_read_timeout 30s;
+            proxy_no_cache 1;
+            proxy_cache_bypass 1;
+            add_header Cache-Control "no-cache, no-store, must-revalidate";
+            
+            # 允许上传最大100MB的文件
+            client_max_body_size 100m;
+        }
+
+        location /health {
+            access_log off;
+            return 200 "OK\n";
+            add_header Content-Type text/plain;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/api/data.js b/src/api/data.js
index adb8e65..fceebdb 100644
--- a/src/api/data.js
+++ b/src/api/data.js
@@ -10,3 +10,10 @@
   }
 }
 
+// 获取所有字典项
+export function getAllDicitemsAll() {
+  return request({
+    url: 'system/dicItem/getAllDicitemsAll',
+    method: 'get'
+  })
+}
diff --git a/src/settings.js b/src/settings.js
index d90d265..9fd6cde 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -3,36 +3,36 @@
   // 获取令牌时,请求头信息(Basic Base64.encode(client_id:client_secret))
   authorizationValue: 'Basic ZmViczoxMjM0NTY=',
   // 社交登录后台地址
-  socialLoginUrl: 'http://localhost:8301/auth/social/login',
+  socialLoginUrl: '/api/auth/social/login',
   // 请替换为您的实际地址
   pages: {
     // FEBS-Admin 控制台地址
-    springBootAdminUrl: 'http://localhost:8401/login',
+    springBootAdminUrl: 'http://120.24.23.155:8401/login',
     // kibana 控制台地址
-    kibanaUrl: 'http://localhost:5601',
+    kibanaUrl: 'http://120.24.23.155:5601',
     // nacos 控制台地址
-    nacosUrl: 'http://localhost:8001/nacos',
+    nacosUrl: 'http://120.24.23.155:8001/nacos',
     // skywalking地址
-    skywalkingUrl: 'http://localhost:8080/',
+    skywalkingUrl: 'http://120.24.23.155:8080/',
     // 文档中心
-    docUrl: 'http://localhost:8301/doc.html',
+    docUrl: '/api/doc.html',
     // Granfana控制台
-    grafanaUrl: 'http://localhost:8404/',
+    grafanaUrl: 'http://120.24.23.155:8404/',
     // tx-manager控制台
-    txUrl: 'http://localhost:8501/admin/index.html#/login',
+    txUrl: 'http://120.24.23.155:8501/admin/index.html#/login',
     // 文件上传地址
-    filesUploadUrl: 'http://localhost:8301/hr/filesUpload',
+    filesUploadUrl: '/api/hr/filesUpload',
     // 个人文件上传地址
-    uploadSinglePath: 'http://localhost:8301/hr/empAccessory',
+    uploadSinglePath: '/api/hr/empAccessory',
     // 个人文件上传地址
-    getEmpBaseInfoImage: 'http://localhost:8301/hr/empBaseInfo/image/',
+    getEmpBaseInfoImage: '/api/hr/empBaseInfo/image/',
     // 下载员工导入模版
-    downloadEmpExcel: 'http://localhost:8000/员工信息.xls',
+    downloadEmpExcel: 'http://120.24.23.155:8000/员工信息.xls',
     // 导入员工
-    uploadEmpExcel: 'http://localhost:8301/hr/empBaseInfo/importEmp',
-    // 获取图片
-    getFilesUploadImage: 'http://localhost:8301/hr/filesUpload/image/',
-    // 获取图片
-    getAccessoryImage: 'http://localhost:8301/hr/empAccessory/image/'
+    uploadEmpExcel: '/api/hr/empBaseInfo/importEmp',
+    // 获取图片(使用相对路径通过API代理,避免Mixed Content问题)
+    getFilesUploadImage: '/api/hr/filesUpload/image/',
+    // 获取图片(使用相对路径通过API代理,避免Mixed Content问题)
+    getAccessoryImage: '/api/hr/empAccessory/image/'
   }
 }
diff --git a/src/settings_local.js b/src/settings_local.js
index cc7036b..d90d265 100644
--- a/src/settings_local.js
+++ b/src/settings_local.js
@@ -3,36 +3,36 @@
   // 获取令牌时,请求头信息(Basic Base64.encode(client_id:client_secret))
   authorizationValue: 'Basic ZmViczoxMjM0NTY=',
   // 社交登录后台地址
-  socialLoginUrl: 'http://120.24.23.155:8301/auth/social/login',
+  socialLoginUrl: 'http://localhost:8301/auth/social/login',
   // 请替换为您的实际地址
   pages: {
     // FEBS-Admin 控制台地址
-    springBootAdminUrl: 'http://120.24.23.155:8401/login',
+    springBootAdminUrl: 'http://localhost:8401/login',
     // kibana 控制台地址
-    kibanaUrl: 'http://120.24.23.155:5601',
+    kibanaUrl: 'http://localhost:5601',
     // nacos 控制台地址
-    nacosUrl: 'http://120.24.23.155:8001/nacos',
+    nacosUrl: 'http://localhost:8001/nacos',
     // skywalking地址
-    skywalkingUrl: 'http://120.24.23.155:8080/',
+    skywalkingUrl: 'http://localhost:8080/',
     // 文档中心
-    docUrl: 'http://120.24.23.155:8301/doc.html',
+    docUrl: 'http://localhost:8301/doc.html',
     // Granfana控制台
-    grafanaUrl: 'http://120.24.23.155:8404/',
+    grafanaUrl: 'http://localhost:8404/',
     // tx-manager控制台
-    txUrl: 'http://120.24.23.155:8501/admin/index.html#/login',
+    txUrl: 'http://localhost:8501/admin/index.html#/login',
     // 文件上传地址
-    filesUploadUrl: 'http://120.24.23.155:8301/hr/filesUpload',
+    filesUploadUrl: 'http://localhost:8301/hr/filesUpload',
     // 个人文件上传地址
-    uploadSinglePath: 'http://120.24.23.155:8301/hr/empAccessory',
+    uploadSinglePath: 'http://localhost:8301/hr/empAccessory',
     // 个人文件上传地址
-    getEmpBaseInfoImage: 'http://120.24.23.155:8301/hr/empBaseInfo/image/',
+    getEmpBaseInfoImage: 'http://localhost:8301/hr/empBaseInfo/image/',
     // 下载员工导入模版
-    downloadEmpExcel: 'http://120.24.23.155:8000/员工信息.xls',
+    downloadEmpExcel: 'http://localhost:8000/员工信息.xls',
     // 导入员工
-    uploadEmpExcel: 'http://120.24.23.155:8301/hr/empBaseInfo/importEmp',
+    uploadEmpExcel: 'http://localhost:8301/hr/empBaseInfo/importEmp',
     // 获取图片
-    getFilesUploadImage: 'http://120.24.23.155:8301/hr/filesUpload/image/',
+    getFilesUploadImage: 'http://localhost:8301/hr/filesUpload/image/',
     // 获取图片
-    getAccessoryImage: 'http://120.24.23.155:8301/hr/empAccessory/image/'
+    getAccessoryImage: 'http://localhost:8301/hr/empAccessory/image/'
   }
 }
diff --git a/src/settings_server.js b/src/settings_server.js
new file mode 100644
index 0000000..fed8293
--- /dev/null
+++ b/src/settings_server.js
@@ -0,0 +1,38 @@
+module.exports = {
+  title: '中保亚太人力资源管理系统',
+  // 获取令牌时,请求头信息(Basic Base64.encode(client_id:client_secret))
+  authorizationValue: 'Basic ZmViczoxMjM0NTY=',
+  // 社交登录后台地址
+  socialLoginUrl: '/api/auth/social/login',
+  // 请替换为您的实际地址
+  pages: {
+    // FEBS-Admin 控制台地址
+    springBootAdminUrl: 'http://120.24.23.155:8401/login',
+    // kibana 控制台地址
+    kibanaUrl: 'http://120.24.23.155:5601',
+    // nacos 控制台地址
+    nacosUrl: 'http://120.24.23.155:8001/nacos',
+    // skywalking地址
+    skywalkingUrl: 'http://120.24.23.155:8080/',
+    // 文档中心
+    docUrl: '/api/doc.html',
+    // Granfana控制台
+    grafanaUrl: 'http://120.24.23.155:8404/',
+    // tx-manager控制台
+    txUrl: 'http://120.24.23.155:8501/admin/index.html#/login',
+    // 文件上传地址
+    filesUploadUrl: '/api/hr/filesUpload',
+    // 个人文件上传地址
+    uploadSinglePath: '/api/hr/empAccessory',
+    // 个人文件上传地址
+    getEmpBaseInfoImage: '/api/hr/empBaseInfo/image/',
+    // 下载员工导入模版
+    downloadEmpExcel: 'http://120.24.23.155:8000/员工信息.xls',
+    // 导入员工
+    uploadEmpExcel: '/api/hr/empBaseInfo/importEmp',
+    // 获取图片
+    getFilesUploadImage: '/api/hr/filesUpload/image/',
+    // 获取图片
+    getAccessoryImage: '/api/hr/empAccessory/image/'
+  }
+}
diff --git a/src/store/modules/dict.js b/src/store/modules/dict.js
new file mode 100644
index 0000000..138890d
--- /dev/null
+++ b/src/store/modules/dict.js
@@ -0,0 +1,83 @@
+import { getAllDicitemsAll } from '@/api/data'
+import db from '@/utils/localstorage'
+
+const DICT_STORAGE_KEY = 'ALL_DICT_DATA'
+
+// 从 localStorage 恢复字典数据
+const restoreDictFromStorage = () => {
+  return db.get(DICT_STORAGE_KEY, [])
+}
+
+const state = {
+  allDictData: restoreDictFromStorage(),
+  dictLoaded: restoreDictFromStorage().length > 0,
+  loading: false // 添加 loading 锁,防止并发请求
+}
+
+const mutations = {
+  SET_ALL_DICT_DATA(state, data) {
+    state.allDictData = data
+    state.dictLoaded = true
+    // 持久化到 localStorage
+    db.save(DICT_STORAGE_KEY, data)
+  },
+  SET_LOADING(state, loading) {
+    state.loading = loading
+  }
+}
+
+const actions = {
+  // 获取所有字典数据
+  async LoadAllDicts({ commit, state }) {
+    // 已加载直接返回
+    if (state.dictLoaded && state.allDictData.length > 0) {
+      return state.allDictData
+    }
+    // 如果正在加载中,等待加载完成
+    if (state.loading) {
+      // 轮询等待加载完成
+      return new Promise((resolve) => {
+        const checkLoaded = setInterval(() => {
+          if (!state.loading && state.dictLoaded) {
+            clearInterval(checkLoaded)
+            resolve(state.allDictData)
+          }
+        }, 100)
+      })
+    }
+    // 开始加载
+    commit('SET_LOADING', true)
+    try {
+      const response = await getAllDicitemsAll()
+      const data = response || []
+      commit('SET_ALL_DICT_DATA', data)
+      return data
+    } catch (error) {
+      console.error('加载字典数据失败:', error)
+      return []
+    } finally {
+      commit('SET_LOADING', false)
+    }
+  }
+}
+
+const getters = {
+  // 根据类型获取字典
+  getDictByType: (state) => (dictType) => {
+    // console.log('dicType=', dictType)
+    //  console.log('data', state.allDictData)
+    return state.allDictData.filter(item => item.dicCode === dictType)
+  },
+  // 获取所有字典数据
+  allDictData: state => state.allDictData,
+  // 是否已加载
+  dictLoaded: state => state.dictLoaded
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+  getters
+}
diff --git a/src/utils/dictMixin.js b/src/utils/dictMixin.js
new file mode 100644
index 0000000..a07587c
--- /dev/null
+++ b/src/utils/dictMixin.js
@@ -0,0 +1,27 @@
+import { mapGetters } from 'vuex'
+
+export default {
+  data() {
+    return {
+      // 字典选项数据
+      dictOptions: {}
+    }
+  },
+  computed: {
+    ...mapGetters('dict', ['getDictByType', 'dictLoaded'])
+  },
+  methods: {
+    // 初始化指定类型的字典 - 直接从 Vuex 获取,不再发起请求
+    // 字典数据已在登录时预加载到 Vuex 和 localStorage
+    initDictTypes(dictTypes) {
+      dictTypes.forEach(type => {
+        this.$set(this.dictOptions, type, this.getDictByType(type))
+      })
+    },
+
+    // 获取指定类型的字典选项
+    getDictOptions(dictType) {
+      return this.dictOptions[dictType] || []
+    }
+  }
+}
diff --git a/src/utils/request.js b/src/utils/request.js
index 8a386cf..fbb3469 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -133,7 +133,8 @@
         return tansParams(params)
       }],
       headers: {
-        'Authorization': authorizationValue
+        'Authorization': authorizationValue,
+        'Content-Type': 'application/x-www-form-urlencoded'
       }
     })
   },
diff --git a/src/views/dashboard/HtUser.vue b/src/views/dashboard/HtUser.vue
index 39d4850..da39e9b 100644
--- a/src/views/dashboard/HtUser.vue
+++ b/src/views/dashboard/HtUser.vue
@@ -58,10 +58,13 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
+
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -97,7 +100,7 @@
         size: 15,
         num: 1
       },
-      contractStatusOptions: [],
+
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -132,14 +135,13 @@
     // 是否为到期合同(number=12)
     isExpireContract() {
       return this.queryParams.number === '12' || this.queryParams.number === 12
-    }
+    },
+    // 字典选项计算属性
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('CONTRACTSTATUS').then(response => {
-        this.contractStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['CONTRACTSTATUS'])
   },
   methods: {
     contractStatusFormat(row, column) {
diff --git a/src/views/dashboard/ctUser.vue b/src/views/dashboard/ctUser.vue
index a1165b9..0e3df11 100644
--- a/src/views/dashboard/ctUser.vue
+++ b/src/views/dashboard/ctUser.vue
@@ -66,10 +66,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -84,6 +86,7 @@
       default: false
     }
   },
+
   data() {
     return {
       gzdStateList: {
@@ -113,12 +116,12 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      educationOptions: [],
-      nativePlaceOptions: [],
-      sexOptions: [],
-      empTypeOptions: [],
-      nationOptions: []
+      }
+      // educationOptions: [],
+      // nativePlaceOptions: [],
+      // sexOptions: [],
+      // empTypeOptions: [],
+      // nationOptions: []
     }
   },
   computed: {
@@ -126,26 +129,18 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    empStatusOptions() { return this.getDictOptions('empStatus') },
+    empTypeOptions() { return this.getDictOptions('EMPTYPE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    nationOptions() { return this.getDictOptions('NATION') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('EDUCATION').then(response => {
-        this.educationOptions = response.data
-      })
-      this.getDicts('NATIVEPLACE').then(response => {
-        this.nativePlaceOptions = response.data
-      })
-      this.getDicts('sex').then(response => {
-        this.sexOptions = response.data
-      })
-      this.getDicts('empType').then(response => {
-        this.empTypeOptions = response.data
-      })
-      this.getDicts('NATION').then(response => {
-        this.nationOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['sex', 'empStatus', 'EMPTYPE', 'EDUCATION', 'NATIVEPLACE', 'NATION'])
   },
   methods: {
     educationFormat(row, column) {
diff --git a/src/views/dashboard/gsUser.vue b/src/views/dashboard/gsUser.vue
index 9ee195f..9baeea1 100644
--- a/src/views/dashboard/gsUser.vue
+++ b/src/views/dashboard/gsUser.vue
@@ -102,8 +102,8 @@
         size: 15,
         num: 1
       },
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
+      // hospitalizatioFlagOptions: [],
+      // settleStatusOptions: [],
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -116,17 +116,14 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('hospitalizatioFlag').then(response => {
-        this.hospitalizatioFlagOptions = response.data
-      })
-      this.getDicts('settleStatus').then(response => {
-        this.settleStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['settleStatus', 'hospitalizatioFlag'])
   },
   methods: {
     hospitalizatioFlagFormat(row, column) {
diff --git a/src/views/dashboard/insuranceUser.vue b/src/views/dashboard/insuranceUser.vue
index a384ea4..9632be4 100644
--- a/src/views/dashboard/insuranceUser.vue
+++ b/src/views/dashboard/insuranceUser.vue
@@ -52,11 +52,13 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -92,7 +94,7 @@
         size: 15,
         num: 1
       },
-      probationStatusOptions: [],
+
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -125,14 +127,13 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    probationStatusOptions() { return this.getDictOptions('PROBATIONSTATUS') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('PROBATIONSTATUS').then(response => {
-        this.probationStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PROBATIONSTATUS'])
   },
   methods: {
     probationStatusFormat(row, column) {
diff --git a/src/views/dashboard/lzUser.vue b/src/views/dashboard/lzUser.vue
index 1c48697..cce2584 100644
--- a/src/views/dashboard/lzUser.vue
+++ b/src/views/dashboard/lzUser.vue
@@ -57,10 +57,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -75,6 +77,7 @@
       default: false
     }
   },
+
   data() {
     return {
       show: false,
@@ -95,8 +98,8 @@
         size: 15,
         num: 1
       },
-      archivesStatusOptions: [],
-      arbitrationTypeOptions: [],
+      // archivesStatusOptions: [],
+      // arbitrationTypeOptions: [],
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -109,17 +112,14 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('ZCTYPE').then(response => {
-        this.arbitrationTypeOptions = response.data
-      })
-      this.getDicts('archivesStatus').then(response => {
-        this.archivesStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['archivesStatus', 'ZCTYPE'])
   },
   methods: {
     arbitrationTypeFormat(row, column) {
diff --git a/src/views/dashboard/onTheJobUser.vue b/src/views/dashboard/onTheJobUser.vue
index e83ec62..afeef95 100644
--- a/src/views/dashboard/onTheJobUser.vue
+++ b/src/views/dashboard/onTheJobUser.vue
@@ -62,10 +62,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -109,13 +111,13 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      educationOptions: [],
-      nativePlaceOptions: [],
-      insuranceOptions: [],
-      sexOptions: [],
-      empTypeOptions: [],
-      nationOptions: []
+      }
+      // educationOptions: [],
+      // nativePlaceOptions: [],
+      // insuranceOptions: [],
+      // sexOptions: [],
+      // empTypeOptions: [],
+      // nationOptions: []
     }
   },
   computed: {
@@ -123,27 +125,40 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    // empStatusOptions() { return this.getDictOptions('empStatus') },
+    empTypeOptions() { return this.getDictOptions('EMPTYPE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    nationOptions() { return this.getDictOptions('NATION') }
   },
   mounted() {
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
+    this.initDictTypes([
+      'sex', 'NATION', 'EMPTYPE',
+      'EDUCATION', 'NATIVEPLACE',
+      'INSURANCETYPE'
+    ])
+    // this.getDicts('EDUCATION').then(response => {
+    //   this.educationOptions = response.data
+    // })
+    // this.getDicts('NATIVEPLACE').then(response => {
+    //   this.nativePlaceOptions = response.data
+    // })
+    // this.getDicts('sex').then(response => {
+    //   this.sexOptions = response.data
+    // })
+    // this.getDicts('empType').then(response => {
+    //   this.empTypeOptions = response.data
+    // })
+    // this.getDicts('NATION').then(response => {
+    //   this.nationOptions = response.data
+    // })
+    // this.getDicts('INSURANCETYPE').then(response => {
+    //   this.insuranceTypeOptions = response.data
+    // })
   },
   methods: {
     educationFormat(row, column) {
diff --git a/src/views/dashboard/qjUser.vue b/src/views/dashboard/qjUser.vue
index 73ca979..b924a28 100644
--- a/src/views/dashboard/qjUser.vue
+++ b/src/views/dashboard/qjUser.vue
@@ -57,10 +57,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -99,8 +101,8 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      leaveTypeOptions: []
+      }
+      // leaveTypeOptions: []
     }
   },
   computed: {
@@ -108,14 +110,19 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') }
+    // empStatusOptions() { return this.getDictOptions('empStatus') },
+    // empTypeOptions() { return this.getDictOptions('EMPTYPE') },
+    // educationOptions() { return this.getDictOptions('EDUCATION') },
+    // nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    // insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    // nationOptions() { return this.getDictOptions('NATION') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('LEAVETYPE').then(response => {
-        this.leaveTypeOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['LEAVETYPE'])
   },
   methods: {
     leaveTypeFormat(row, column) {
diff --git a/src/views/dashboard/sbUser.vue b/src/views/dashboard/sbUser.vue
index 7209054..44970f6 100644
--- a/src/views/dashboard/sbUser.vue
+++ b/src/views/dashboard/sbUser.vue
@@ -56,10 +56,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -98,10 +100,10 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: []
+      }
+      // insuranceGaersOptions: [],
+      // applayStatusOptions: [],
+      // reportStatusOptions: []
     }
   },
   computed: {
@@ -109,20 +111,15 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('INSURANCETYPE').then(response => {
-        this.insuranceGaersOptions = response.data
-      })
-      this.getDicts('applayStatus').then(response => {
-        this.applayStatusOptions = response.data
-      })
-      this.getDicts('reportStatus').then(response => {
-        this.reportStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['INSURANCETYPE', 'applayStatus', 'reportStatus'])
   },
   methods: {
     insuranceGaersFormat(row, column) {
diff --git a/src/views/dashboard/tgUser.vue b/src/views/dashboard/tgUser.vue
index 646759b..490cc93 100644
--- a/src/views/dashboard/tgUser.vue
+++ b/src/views/dashboard/tgUser.vue
@@ -56,10 +56,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -98,8 +100,8 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      changeTypeOptions: []
+      }
+      // changeTypeOptions: []
     }
   },
   computed: {
@@ -107,14 +109,13 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    changeTypeOptions() { return this.getDictOptions('changeType') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('changeType').then(response => {
-        this.changeTypeOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['changeType'])
   },
   methods: {
     changeTypeFormat(row, column) {
diff --git a/src/views/dashboard/tjUser.vue b/src/views/dashboard/tjUser.vue
index 9a8e2ce..d69f86b 100644
--- a/src/views/dashboard/tjUser.vue
+++ b/src/views/dashboard/tjUser.vue
@@ -58,10 +58,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -100,9 +102,9 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      ecgOptions: [],
-      physicalExamTypeOptions: []
+      }
+      // ecgOptions: [],
+      // physicalExamTypeOptions: []
     }
   },
   computed: {
@@ -110,17 +112,14 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    ecgOptions() { return this.getDictOptions('ECG') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('PHYSICALEXAMTYPE').then(response => {
-        this.physicalExamTypeOptions = response.data
-      })
-      this.getDicts('ECG').then(response => {
-        this.ecgOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PHYSICALEXAMTYPE', 'ECG'])
   },
   methods: {
     typeFormat(row, column) {
diff --git a/src/views/dashboard/ygUser.vue b/src/views/dashboard/ygUser.vue
index dd23216..4bfb651 100644
--- a/src/views/dashboard/ygUser.vue
+++ b/src/views/dashboard/ygUser.vue
@@ -63,10 +63,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -110,12 +112,12 @@
       defaultProps: {
         children: 'children',
         label: 'label'
-      },
-      educationOptions: [],
-      nativePlaceOptions: [],
-      sexOptions: [],
-      empTypeOptions: [],
-      nationOptions: []
+      }
+      // educationOptions: [],
+      // nativePlaceOptions: [],
+      // sexOptions: [],
+      // empTypeOptions: [],
+      // nationOptions: []
     }
   },
   computed: {
@@ -123,26 +125,17 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('EDUCATION') },
+    empStatusOptions() { return this.getDictOptions('NATIVEPLACE') },
+    empTypeOptions() { return this.getDictOptions('sex') },
+    educationOptions() { return this.getDictOptions('EMPTYPE') },
+    nativePlaceOptions() { return this.getDictOptions('NATION') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('EDUCATION').then(response => {
-        this.educationOptions = response.data
-      })
-      this.getDicts('NATIVEPLACE').then(response => {
-        this.nativePlaceOptions = response.data
-      })
-      this.getDicts('sex').then(response => {
-        this.sexOptions = response.data
-      })
-      this.getDicts('empType').then(response => {
-        this.empTypeOptions = response.data
-      })
-      this.getDicts('NATION').then(response => {
-        this.nationOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['sex', 'NATION', 'EMPTYPE', 'EDUCATION', 'NATIVEPLACE'])
   },
   methods: {
     educationFormat(row, column) {
diff --git a/src/views/dashboard/ywUser.vue b/src/views/dashboard/ywUser.vue
index a433452..9bd1db1 100644
--- a/src/views/dashboard/ywUser.vue
+++ b/src/views/dashboard/ywUser.vue
@@ -64,10 +64,12 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -102,8 +104,8 @@
         size: 15,
         num: 1
       },
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
+      // hospitalizatioFlagOptions: [],
+      // settleStatusOptions: [],
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -116,17 +118,14 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('hospitalizatioFlag').then(response => {
-        this.hospitalizatioFlagOptions = response.data
-      })
-      this.getDicts('settleStatus').then(response => {
-        this.settleStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['hospitalizatioFlag', 'settleStatus'])
   },
   methods: {
     hospitalizatioFlagFormat(row, column) {
diff --git a/src/views/dashboard/zzUser.vue b/src/views/dashboard/zzUser.vue
index 95c2618..d674485 100644
--- a/src/views/dashboard/zzUser.vue
+++ b/src/views/dashboard/zzUser.vue
@@ -51,11 +51,13 @@
 <script>
 // 引用翻页组件
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -90,7 +92,7 @@
         size: 15,
         num: 1
       },
-      probationStatusOptions: [],
+
       list: [], // 给table显示的数据
       defaultProps: {
         children: 'children',
@@ -122,14 +124,13 @@
       get() {
         return this.dialogVisible
       }
-    }
+    },
+    // 字典选项计算属性
+    probationStatusOptions() { return this.getDictOptions('PROBATIONSTATUS') }
   },
   mounted() {
-    setTimeout(() => {
-      this.getDicts('PROBATIONSTATUS').then(response => {
-        this.probationStatusOptions = response.data
-      })
-    }, 1000)
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PROBATIONSTATUS'])
   },
   methods: {
     probationStatusFormat(row, column) {
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index 0ef50e2..df7e7ad 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -351,23 +351,26 @@
       const expireTime = current.setTime(current.getTime() + 1000 * data.expires_in)
       this.$store.commit('account/setExpireTime', expireTime)
     },
-    getUserDetailInfo() {
-      this.$get('auth/user').then((r) => {
+    async getUserDetailInfo() {
+      try {
+        const r = await this.$get('auth/user')
         this.$store.commit('account/setUser', r.data.principal)
+        // 预加载字典数据到缓存
+        await this.$store.dispatch('dict/LoadAllDicts')
         this.$message({
           message: this.$t('tips.loginSuccess'),
           type: 'success'
         })
         this.loading = false
         this.$router.push('/')
-      }).catch((error) => {
+      } catch (error) {
         this.$message({
           message: this.$t('tips.loginFail'),
           type: 'error'
         })
         console.error(error)
         this.loading = false
-      })
+      }
     },
     loginSuccessCallback() {
       this.$get('system/user/success').catch((e) => { console.log(e) })
diff --git a/src/views/remind/contract.vue b/src/views/remind/contract.vue
index f6c487a..7441489 100644
--- a/src/views/remind/contract.vue
+++ b/src/views/remind/contract.vue
@@ -158,11 +158,13 @@
 import Pagination from '@/components/Pagination'
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import { dateDifference } from '@/utils/myUtil'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -215,8 +217,7 @@
         version: '',
         diffDay: 0
       },
-      sexOptions: [],
-      contractStatusOptions: [],
+
       dialogShowContract: false,
       contractRules: {
         empName: [{ required: true, message: '请选择员工', trigger: 'change' }],
@@ -246,14 +247,15 @@
       }
     }
   },
+  computed: {
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') }
+  },
   mounted() {
     this.fetch()
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['sex', 'CONTRACTSTATUS'])
   },
   methods: {
     search() {
diff --git a/src/views/remind/insurance5.vue b/src/views/remind/insurance5.vue
index e58b751..46d95c8 100644
--- a/src/views/remind/insurance5.vue
+++ b/src/views/remind/insurance5.vue
@@ -138,12 +138,14 @@
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import { calculateSeniority, toCardGetUserInfo } from '@/utils/myUtil'
 import ExportDialog from '@/components/ExportEmpBase.vue'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination,
     ExportDialog
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -186,9 +188,9 @@
         fileName: '社保四险员工列表.xls'
       },
       tableData: [],
-      sexOptions: [],
-      empStatusOptions: [],
-      insuranceTypeOptions: [],
+      // sexOptions: [],
+      // empStatusOptions: [],
+      // insuranceTypeOptions: [],
       searchInsuranceOptions: [{
         'dicItemName': '(非深户)四险一档',
         'dicItemCode': '7'
@@ -207,84 +209,23 @@
       }]
     }
   },
+  computed: {
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    empStatusOptions() { return this.getDictOptions('empStatus') },
+    empTypeOptions() { return this.getDictOptions('EMPTYPE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') }
+  },
   mounted() {
     this.fetch()
     this.initDept()
-    this.getDicts('ageStr').then(response => {
-      this.ageStrOptions = response.data
-    })
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empStatus').then(response => {
-      this.empStatusOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    this.initDictTypes([
+      'sex', 'empStatus', 'EMPTYPE',
+      'EDUCATION', 'NATIVEPLACE',
+      'INSURANCETYPE'
+    ])
     // this.initJob()
   },
   methods: {
@@ -325,6 +266,7 @@
       return this.selectDictLabel(this.physicalExamTypeOptions, row.physicalExamType)
     },
     empTypeFormat(row, column) {
+      console.log(this.empTypeOptions)
       return this.selectDictLabel(this.empTypeOptions, row.empType)
     },
     sexFormat(row, column) {
diff --git a/src/views/remind/probation.vue b/src/views/remind/probation.vue
index edde02d..8ec96f8 100644
--- a/src/views/remind/probation.vue
+++ b/src/views/remind/probation.vue
@@ -130,12 +130,14 @@
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import { dateDifference } from '@/utils/myUtil'
 import ExportDialog from '@/components/ExportEmpBase.vue'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination,
     ExportDialog
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -175,8 +177,7 @@
         probationDate: '',
         probationStatus: ''
       },
-      sexOptions: [],
-      contractStatusOptions: [],
+
       dialogTitle: '正常转正',
       dynamicDateLabel: '转正日期',
       dialogShowContract: false,
@@ -204,14 +205,15 @@
       }
     }
   },
+  computed: {
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') }
+  },
   mounted() {
     this.fetch()
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['sex', 'CONTRACTSTATUS'])
   },
   methods: {
     search() {
diff --git a/src/views/remind/retirement.vue b/src/views/remind/retirement.vue
index 5cb8fce..b46b933 100644
--- a/src/views/remind/retirement.vue
+++ b/src/views/remind/retirement.vue
@@ -157,12 +157,14 @@
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 import { dateDifference } from '@/utils/myUtil'
 import ExportDialog from '@/components/ExportEmpBase.vue'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination,
     ExportDialog
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -225,8 +227,6 @@
         version: '',
         diffDay: 0
       },
-      sexOptions: [],
-      contractStatusOptions: [],
       dialogShowContract: false,
       contractRules: {
         empName: [{ required: true, message: '请选择员工', trigger: 'change' }],
@@ -258,14 +258,15 @@
       }
     }
   },
+  computed: {
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') }
+  },
   mounted() {
     this.fetch()
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['sex', 'CONTRACTSTATUS'])
   },
   methods: {
     search() {
diff --git a/src/views/user/Informationinput.vue b/src/views/user/Informationinput.vue
index 2239cdd..1d3cffd 100644
--- a/src/views/user/Informationinput.vue
+++ b/src/views/user/Informationinput.vue
@@ -3527,107 +3527,40 @@
         empStatus: 0,
         remark: ''
       },
-      statusOptions: [],
-      empTypeOptions: [],
-      nationOptions: [],
-      marriageOptions: [],
-      educationOptions: [],
-      nativePlaceOptions: [],
-      archivesStatusOptions: [],
-      insuranceTypeOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      ecgOptions: [],
-      certificateListOptions: [],
-      physicalExamTypeOptions: [],
-      contractStatusOptions: [],
-      leaveTypeOptions: [],
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: [],
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
-      arbitrationTypeOptions: [],
-      changeTypeOptions: [],
-      dimissionTypeOptions: [],
-      sexOptions: [],
       permissions: {}
     }
   },
+  computed: {
+    // 字典选项计算属性
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    nationOptions() { return this.getDictOptions('NATION') },
+    marriageOptions() { return this.getDictOptions('MARRIAGE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    ecgOptions() { return this.getDictOptions('ECG') },
+    certificateListOptions() { return this.getDictOptions('certificateList') },
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') },
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') },
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') },
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') },
+    changeTypeOptions() { return this.getDictOptions('changeType') },
+    dimissionTypeOptions() { return this.getDictOptions('LZTYPE') },
+    sexOptions() { return this.getDictOptions('sex') }
+  },
   mounted() {
     this.permissions = JSON.parse(localStorage.getItem('PERMISSIONS'))
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceGaersOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PLITICAL', 'sex', 'empType', 'NATION', 'MARRIAGE', 'EDUCATION', 'NATIVEPLACE', 'archivesStatus', 'INSURANCETYPE', 'empCardStatus', 'handbookStatus', 'certificateList', 'PHYSICALEXAMTYPE', 'ECG', 'CONTRACTSTATUS', 'LEAVETYPE', 'applayStatus', 'reportStatus', 'hospitalizatioFlag', 'settleStatus', 'ZCTYPE', 'changeType', 'LZTYPE'])
     this.initDept()
     this.thisShowIndex = 1
     this.isShow(false, 0)
diff --git a/src/views/user/archivesChange.vue b/src/views/user/archivesChange.vue
index e1179ca..a5d9c4e 100644
--- a/src/views/user/archivesChange.vue
+++ b/src/views/user/archivesChange.vue
@@ -2677,10 +2677,12 @@
 import Pagination from '@/components/Pagination'
 import { getToken } from '@/utils/auth'
 import { pages } from '@/settings'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   name: 'ArchivesEdit',
   components: { Treeselect, Pagination },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -3558,34 +3560,35 @@
         { type: 'dic_credentials' },
         { type: 'password' },
         { type: 'implicit' }
-      ],
-      statusOptions: [],
-      empTypeOptions: [],
-      nationOptions: [],
-      marriageOptions: [],
-      educationOptions: [],
-      nativePlaceOptions: [],
-      archivesStatusOptions: [],
-      insuranceTypeOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      ecgOptions: [],
-      certificateListOptions: [],
-      physicalExamTypeOptions: [],
-      contractStatusOptions: [],
-      leaveTypeOptions: [],
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: [],
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
-      arbitrationTypeOptions: [],
-      changeTypeOptions: [],
-      dimissionTypeOptions: [],
-      sexOptions: []
+      ]
     }
   },
   computed: {
+    // 字典选项计算属性
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    nationOptions() { return this.getDictOptions('NATION') },
+    marriageOptions() { return this.getDictOptions('MARRIAGE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    certificateListOptions() { return this.getDictOptions('certificateList') },
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    ecgOptions() { return this.getDictOptions('ECG') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') },
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') },
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') },
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') },
+    changeTypeOptions() { return this.getDictOptions('changeType') },
+    dimissionTypeOptions() { return this.getDictOptions('LZTYPE') },
+    sexOptions() { return this.getDictOptions('sex') },
     isVisible: {
       get() {
         return this.dialogVisible
@@ -3598,79 +3601,8 @@
   },
   mounted() {
     this.initDept()
-    /* 政治面貌*/
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceGaersOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PLITICAL', 'sex', 'empType', 'NATION', 'MARRIAGE', 'EDUCATION', 'NATIVEPLACE', 'archivesStatus', 'INSURANCETYPE', 'empCardStatus', 'handbookStatus', 'certificateList', 'PHYSICALEXAMTYPE', 'ECG', 'CONTRACTSTATUS', 'LEAVETYPE', 'applayStatus', 'reportStatus', 'hospitalizatioFlag', 'settleStatus', 'ZCTYPE', 'changeType', 'LZTYPE'])
   },
   methods: {
     typeFormat(row, column) {
@@ -4100,22 +4032,45 @@
       this.physicalExamForm = { ...val }
       this.workExperienceForm = { ...val }
       this.badRecordForm = { ...val }
-      this.initlabel()
-      this.initphysicalExamData()
-      this.initList() // 工作经历
-      this.initjobChangeData() // 调岗记录
-      this.initdimissionLogData() // 入离职记录
-      this.initcontractInfoData() // 合同信息
-      this.initleaveInfoData() // 请假记录
-      this.initresignData() // 辞职申请
-      this.initunemploymentData() // 失业金领取
-      this.initinsuranceData() // 社保申请
-      this.initremarkInfoData() // 备注
-      this.initlaborTroubleData() // 仲裁案件
-      this.initoccupationalData() // 工伤案件
-      this.initbadRecordData() // 不良记录
-      this.initaccidentCasesData() // 意外险案件
-      this.initdimissionAttendData() // 考勤情况
+      // 分批加载数据,避免并发请求过多导致 503 错误
+      this.loadDataInBatches()
+    },
+    // 分批加载档案数据,控制并发请求数量
+    async loadDataInBatches() {
+      // 第1批:首屏可见数据(4个请求)
+      await Promise.all([
+        this.initlabel(),
+        this.initphysicalExamData(),
+        this.initList(),
+        this.initjobChangeData()
+      ])
+
+      // 延迟 200ms 后加载第2批
+      await new Promise(resolve => setTimeout(resolve, 200))
+      await Promise.all([
+        this.initdimissionLogData(),
+        this.initcontractInfoData(),
+        this.initleaveInfoData(),
+        this.initresignData()
+      ])
+
+      // 延迟 200ms 后加载第3批
+      await new Promise(resolve => setTimeout(resolve, 200))
+      await Promise.all([
+        this.initunemploymentData(),
+        this.initinsuranceData(),
+        this.initremarkInfoData(),
+        this.initlaborTroubleData()
+      ])
+
+      // 延迟 200ms 后加载第4批
+      await new Promise(resolve => setTimeout(resolve, 200))
+      await Promise.all([
+        this.initoccupationalData(),
+        this.initbadRecordData(),
+        this.initaccidentCasesData(),
+        this.initdimissionAttendData()
+      ])
     },
     initphysicalExamData(params = {}) {
       params.pageSize = this.pagination.size
diff --git a/src/views/user/archivesEdit.vue b/src/views/user/archivesEdit.vue
index b9fb72d..7062ee6 100644
--- a/src/views/user/archivesEdit.vue
+++ b/src/views/user/archivesEdit.vue
@@ -2973,10 +2973,12 @@
 import Pagination from '@/components/Pagination'
 import { getToken } from '@/utils/auth'
 import { pages } from '@/settings'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   name: 'ArchivesEdit',
   components: { Treeselect, Pagination },
+  mixins: [dictMixin],
   props: {
     dialogVisible: {
       type: Boolean,
@@ -3850,30 +3852,6 @@
         { type: 'password' },
         { type: 'implicit' }
       ],
-      statusOptions: [],
-      empTypeOptions: [],
-      nationOptions: [],
-      marriageOptions: [],
-      educationOptions: [],
-      nativePlaceOptions: [],
-      archivesStatusOptions: [],
-      insuranceTypeOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      ecgOptions: [],
-      certificateListOptions: [],
-      physicalExamTypeOptions: [],
-      contractStatusOptions: [],
-      leaveTypeOptions: [],
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: [],
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
-      arbitrationTypeOptions: [],
-      changeTypeOptions: [],
-      dimissionTypeOptions: [],
-      sexOptions: [],
       srcList: [],
       getImg: pages.getAccessoryImage
     }
@@ -3887,83 +3865,37 @@
         this.close()
         this.reset()
       }
-    }
+    },
+    // 字典选项计算属性
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    nationOptions() { return this.getDictOptions('NATION') },
+    marriageOptions() { return this.getDictOptions('MARRIAGE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    certificateListOptions() { return this.getDictOptions('certificateList') },
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    ecgOptions() { return this.getDictOptions('ECG') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') },
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') },
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') },
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') },
+    changeTypeOptions() { return this.getDictOptions('changeType') },
+    dimissionTypeOptions() { return this.getDictOptions('LZTYPE') },
+    sexOptions() { return this.getDictOptions('sex') }
   },
   mounted() {
     this.initDept()
-    /* 政治面貌*/
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceGaersOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['PLITICAL', 'sex', 'empType', 'NATION', 'MARRIAGE', 'EDUCATION', 'NATIVEPLACE', 'archivesStatus', 'INSURANCETYPE', 'empCardStatus', 'handbookStatus', 'certificateList', 'PHYSICALEXAMTYPE', 'ECG', 'CONTRACTSTATUS', 'LEAVETYPE', 'applayStatus', 'reportStatus', 'hospitalizatioFlag', 'settleStatus', 'ZCTYPE', 'changeType', 'LZTYPE'])
   },
   methods: {
     clickImg(node) {
diff --git a/src/views/user/inemployees.vue b/src/views/user/inemployees.vue
index 03d26f7..a2b78ee 100644
--- a/src/views/user/inemployees.vue
+++ b/src/views/user/inemployees.vue
@@ -1084,12 +1084,14 @@
 import { calculateSeniority, toCardGetUserInfo, dateToString } from '@/utils/myUtil'
 import ArchivesEdit from './archivesEdit'
 import { pages } from '@/settings'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     ArchivesEdit,
     Pagination, Treeselect
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -1337,113 +1339,43 @@
       checkedCities: [],
       tableData: [],
       selectDimissionType: 1,
-      statusOptions: [],
-      empTypeOptions: [],
       inTypeOptions: [],
-      nationOptions: [],
-      marriageOptions: [],
-      educationOptions: [],
-      nativePlaceOptions: [],
-      archivesStatusOptions: [],
-      insuranceTypeOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      ecgOptions: [],
-      certificateListOptions: [],
-      physicalExamTypeOptions: [],
-      contractStatusOptions: [],
-      leaveTypeOptions: [],
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: [],
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
-      arbitrationTypeOptions: [],
-      changeTypeOptions: [],
-      dimissionTypeOptions: [],
-      ageStrOptions: [],
-      sexOptions: [],
       openArchivesForm: {}
     }
+  },
+  computed: {
+    // 字典选项计算属性
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    nationOptions() { return this.getDictOptions('NATION') },
+    marriageOptions() { return this.getDictOptions('MARRIAGE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    certificateListOptions() { return this.getDictOptions('certificateList') },
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    ecgOptions() { return this.getDictOptions('ECG') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') },
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') },
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') },
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') },
+    changeTypeOptions() { return this.getDictOptions('changeType') },
+    dimissionTypeOptions() { return this.getDictOptions('LZTYPE') },
+    ageStrOptions() { return this.getDictOptions('ageStr') },
+    sexOptions() { return this.getDictOptions('sex') }
   },
   mounted() {
     this.fetch()
     this.initDept()
-    this.getDicts('ageStr').then(response => {
-      this.ageStrOptions = response.data
-    })
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceGaersOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['ageStr', 'PLITICAL', 'sex', 'empType', 'NATION', 'MARRIAGE', 'EDUCATION', 'NATIVEPLACE', 'archivesStatus', 'INSURANCETYPE', 'empCardStatus', 'handbookStatus', 'certificateList', 'PHYSICALEXAMTYPE', 'ECG', 'CONTRACTSTATUS', 'LEAVETYPE', 'applayStatus', 'reportStatus', 'hospitalizatioFlag', 'settleStatus', 'ZCTYPE', 'changeType', 'LZTYPE'])
     this.initJob()
   },
   methods: {
diff --git a/src/views/user/outemployess.vue b/src/views/user/outemployess.vue
index b73c7d7..9d402c6 100644
--- a/src/views/user/outemployess.vue
+++ b/src/views/user/outemployess.vue
@@ -1264,6 +1264,7 @@
 import Pagination from '@/components/Pagination'
 import ArchivesChange from './archivesChange'
 import Treeselect from '@riophae/vue-treeselect'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
@@ -1271,6 +1272,7 @@
     ArchivesChange,
     Pagination
   },
+  mixins: [dictMixin],
   data() {
     return {
       dialog: {
@@ -1316,43 +1318,25 @@
       baseicInformationForm: {
         openDate: new Date()
       },
-      educationOptions: [],
-      statusOptions: [],
-      ageStrOptions: [],
-      insuranceTypeOptions: [],
-      archivesStatusOptions: [],
-      sexOptions: [],
-      empTypeOptions: [],
       cityOptions: ['archivesNumb', 'allDeptName', 'jobName', 'empName', 'certificateNumb', 'certificateValidity', 'sexName', 'nationName', 'age', 'marriageName', 'stature', 'birthdate', 'politicsName', 'empTypeName', 'educationName', 'nativePlaceName', 'censusAddress', 'currentAddress', 'guardNumb', 'returnReceipt', 'archivesStatusName', 'bankName', 'bankNumb', 'telePhone', 'entryDate', 'insuranceTypeName', 'socialNumb', 'introducer', 'seniority', 'empCardStatusName', 'certificateListName', 'urgencyPhone', 'handbookStatusName', 'family', 'empStatusName', 'dimissionDate', 'entryTypeName', 'dimissionTypeName', 'empNumb', 'annualLeave'],
       checkedCities: []
     }
   },
+  computed: {
+    // 字典选项计算属性
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    ageStrOptions() { return this.getDictOptions('ageStr') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    sexOptions() { return this.getDictOptions('sex') },
+    empTypeOptions() { return this.getDictOptions('EMPTYPE') },
+    certificateListOptions() { return this.getDictOptions('certificateList') }
+  },
   mounted() {
     this.fetch()
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('ageStr').then(response => {
-      this.ageStrOptions = response.data
-    })
-    this.getDicts('EMPTYPE').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['INSURANCETYPE', 'archivesStatus', 'EDUCATION', 'sex', 'PLITICAL', 'ageStr', 'EMPTYPE', 'certificateList'])
     this.initDept()
   },
   methods: {
diff --git a/src/views/user/search.vue b/src/views/user/search.vue
index 5d7f6a7..01251d9 100644
--- a/src/views/user/search.vue
+++ b/src/views/user/search.vue
@@ -2198,10 +2198,13 @@
 </template>
 <script>
 import Pagination from '@/components/Pagination'
+import dictMixin from '../../utils/dictMixin'
+
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   data() {
     return {
       cityOptions: ['archivesNumb', 'allDeptName', 'jobName', 'empName', 'certificateNumb', 'certificateValidity', 'sexName', 'nationName', 'age', 'marriageName', 'stature', 'birthdate', 'politicsName', 'empTypeName', 'educationName', 'nativePlaceName', 'censusAddress', 'currentAddress', 'guardNumb', 'returnReceipt', 'archivesStatusName', 'bankName', 'bankNumb', 'telePhone', 'entryDate', 'InsuranceTypeName', 'socialNumb', 'introducer', 'seniority', 'empCardStatusName', 'certificateListName', 'urgencyPhone', 'handbookStatusName', 'family', 'empStatusName', 'dimissionDate', 'entryTypeName', 'dimissionTypeName', 'empNumb', 'annualLeave'],
@@ -2499,32 +2502,7 @@
           }
         ]
       },
-      statusOptions: [],
-      empTypeOptions: [],
-      nationOptions: [],
-      marriageOptions: [],
-      educationOptions: [],
-      nativePlaceOptions: [],
-      archivesStatusOptions: [],
-      insuranceTypeOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      ecgOptions: [],
-      certificateListOptions: [],
-      physicalExamTypeOptions: [],
-      contractStatusOptions: [],
-      leaveTypeOptions: [],
-      insuranceGaersOptions: [],
-      applayStatusOptions: [],
-      reportStatusOptions: [],
-      hospitalizatioFlagOptions: [],
-      settleStatusOptions: [],
-      arbitrationTypeOptions: [],
-      changeTypeOptions: [],
-      dimissionTypeOptions: [],
-      ageStrOptions: [],
-      attendYearOptions: [],
-      sexOptions: [],
+
       occupationalForm: {
         occupationalId: '',
         empId: '',
@@ -2576,87 +2554,40 @@
       }
     }
   },
+  computed: {
+    // 字典选项计算属性
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    nationOptions() { return this.getDictOptions('NATION') },
+    marriageOptions() { return this.getDictOptions('MARRIAGE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    nativePlaceOptions() { return this.getDictOptions('NATIVEPLACE') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    certificateListOptions() { return this.getDictOptions('certificateList') },
+    physicalExamTypeOptions() { return this.getDictOptions('PHYSICALEXAMTYPE') },
+    ecgOptions() { return this.getDictOptions('ECG') },
+    contractStatusOptions() { return this.getDictOptions('CONTRACTSTATUS') },
+    leaveTypeOptions() { return this.getDictOptions('LEAVETYPE') },
+    insuranceGaersOptions() { return this.getDictOptions('INSURANCETYPE') },
+    applayStatusOptions() { return this.getDictOptions('applayStatus') },
+    reportStatusOptions() { return this.getDictOptions('reportStatus') },
+    hospitalizatioFlagOptions() { return this.getDictOptions('hospitalizatioFlag') },
+    settleStatusOptions() { return this.getDictOptions('settleStatus') },
+    arbitrationTypeOptions() { return this.getDictOptions('ZCTYPE') },
+    changeTypeOptions() { return this.getDictOptions('changeType') },
+    dimissionTypeOptions() { return this.getDictOptions('LZTYPE') },
+    ageStrOptions() { return this.getDictOptions('ageStr') },
+    attendYearOptions() { return this.getDictOptions('attendYear') },
+    sexOptions() { return this.getDictOptions('sex') }
+  },
   mounted() {
     this.thisShowIndex = 1
     this.isShow(false, 0)
-    this.getDicts('ageStr').then(response => {
-      this.ageStrOptions = response.data
-    })
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('attendYear').then(response => {
-      this.attendYearOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('NATION').then(response => {
-      this.nationOptions = response.data
-    })
-    this.getDicts('MARRIAGE').then(response => {
-      this.marriageOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('NATIVEPLACE').then(response => {
-      this.nativePlaceOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
-    this.getDicts('PHYSICALEXAMTYPE').then(response => {
-      this.physicalExamTypeOptions = response.data
-    })
-    this.getDicts('ECG').then(response => {
-      this.ecgOptions = response.data
-    })
-    this.getDicts('CONTRACTSTATUS').then(response => {
-      this.contractStatusOptions = response.data
-    })
-    this.getDicts('LEAVETYPE').then(response => {
-      this.leaveTypeOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceGaersOptions = response.data
-    })
-    this.getDicts('applayStatus').then(response => {
-      this.applayStatusOptions = response.data
-    })
-    this.getDicts('reportStatus').then(response => {
-      this.reportStatusOptions = response.data
-    })
-    this.getDicts('hospitalizatioFlag').then(response => {
-      this.hospitalizatioFlagOptions = response.data
-    })
-    this.getDicts('settleStatus').then(response => {
-      this.settleStatusOptions = response.data
-    })
-    this.getDicts('ZCTYPE').then(response => {
-      this.arbitrationTypeOptions = response.data
-    })
-    this.getDicts('changeType').then(response => {
-      this.changeTypeOptions = response.data
-    })
-    this.getDicts('LZTYPE').then(response => {
-      this.dimissionTypeOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['ageStr', 'PLITICAL', 'attendYear', 'sex', 'empType', 'NATION', 'MARRIAGE', 'EDUCATION', 'NATIVEPLACE', 'archivesStatus', 'INSURANCETYPE', 'empCardStatus', 'handbookStatus', 'certificateList', 'PHYSICALEXAMTYPE', 'ECG', 'CONTRACTSTATUS', 'LEAVETYPE', 'applayStatus', 'reportStatus', 'hospitalizatioFlag', 'settleStatus', 'ZCTYPE', 'changeType', 'LZTYPE'])
   },
   methods: {
     typeFormat(row, column) {
diff --git a/src/views/yunpan/fujian.vue b/src/views/yunpan/fujian.vue
index 065361b..d4d7855 100644
--- a/src/views/yunpan/fujian.vue
+++ b/src/views/yunpan/fujian.vue
@@ -400,11 +400,13 @@
 <script>
 import Pagination from '@/components/Pagination'
 import { Loading } from 'element-ui'
+import dictMixin from '../../utils/dictMixin'
 
 export default {
   components: {
     Pagination
   },
+  mixins: [dictMixin],
   data() {
     return {
       sort: {}, // 排序
@@ -505,51 +507,27 @@
         label: 'label'
       },
       tableindex: 0,
-      rowitem: {},
-      sexOptions: [],
-      insuranceTypeOptions: [],
-      educationOptions: [],
-      statusOptions: [],
-      ageStrOptions: [],
-      archivesStatusOptions: [],
-      empCardStatusOptions: [],
-      handbookStatusOptions: [],
-      empTypeOptions: []
+      rowitem: {}
     }
+  },
+  computed: {
+    // 字典选项计算属性
+    sexOptions() { return this.getDictOptions('sex') },
+    insuranceTypeOptions() { return this.getDictOptions('INSURANCETYPE') },
+    educationOptions() { return this.getDictOptions('EDUCATION') },
+    statusOptions() { return this.getDictOptions('PLITICAL') },
+    ageStrOptions() { return this.getDictOptions('ageStr') },
+    archivesStatusOptions() { return this.getDictOptions('archivesStatus') },
+    empCardStatusOptions() { return this.getDictOptions('empCardStatus') },
+    handbookStatusOptions() { return this.getDictOptions('handbookStatus') },
+    empTypeOptions() { return this.getDictOptions('empType') },
+    certificateListOptions() { return this.getDictOptions('certificateList') }
   },
   mounted() {
     this.initLabel()
     this.fetch()
-    this.getDicts('empType').then(response => {
-      this.empTypeOptions = response.data
-    })
-    this.getDicts('empCardStatus').then(response => {
-      this.empCardStatusOptions = response.data
-    })
-    this.getDicts('handbookStatus').then(response => {
-      this.handbookStatusOptions = response.data
-    })
-    this.getDicts('sex').then(response => {
-      this.sexOptions = response.data
-    })
-    this.getDicts('EDUCATION').then(response => {
-      this.educationOptions = response.data
-    })
-    this.getDicts('PLITICAL').then(response => {
-      this.statusOptions = response.data
-    })
-    this.getDicts('ageStr').then(response => {
-      this.ageStrOptions = response.data
-    })
-    this.getDicts('archivesStatus').then(response => {
-      this.archivesStatusOptions = response.data
-    })
-    this.getDicts('INSURANCETYPE').then(response => {
-      this.insuranceTypeOptions = response.data
-    })
-    this.getDicts('certificateList').then(response => {
-      this.certificateListOptions = response.data
-    })
+    // 字典数据已在登录时预加载,直接从 Vuex 获取
+    this.initDictTypes(['empType', 'empCardStatus', 'handbookStatus', 'sex', 'EDUCATION', 'PLITICAL', 'ageStr', 'archivesStatus', 'INSURANCETYPE', 'certificateList'])
   },
   methods: {
     changeSort(val) {

--
Gitblit v1.8.0