From ebb32a8cf09d44edf386c076653f2052a1807cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=97=E6=B5=94?= <2919054393@qq.com> Date: Thu, 12 Jun 2025 18:58:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=90=8E=E5=8F=B0=E6=A1=86?= =?UTF-8?q?=E6=9E=B6=E5=8F=8A=E8=B7=AF=E7=94=B1=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 17 +++ package.json | 1 + src/main.js | 1 - src/request/api.js | 6 +- src/router/index.js | 35 ++++- src/store/index.js | 4 +- src/store/modules/userinfo.js | 60 +++++++++ src/utils/intercaptors/response/refresh.js | 40 +++--- src/views/auth/Login.vue | 17 ++- src/views/layout/Home.vue | 147 +++++++-------------- src/views/layout/Users.vue | 0 vue.config.js | 6 +- 12 files changed, 209 insertions(+), 125 deletions(-) create mode 100644 src/store/modules/userinfo.js create mode 100644 src/views/layout/Users.vue diff --git a/package-lock.json b/package-lock.json index 3e1ad42..861da61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "blueimp-md5": "^2.19.0", "bootstrap": "^5.3.6", "core-js": "^3.8.3", + "feather-icons": "^4.29.2", "jquery": "^3.7.1", "perfect-scrollbar": "^1.5.6", "vue": "^2.6.14", @@ -3788,6 +3789,12 @@ "node": ">=6.0" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz", @@ -5428,6 +5435,16 @@ "node": ">=0.8.0" } }, + "node_modules/feather-icons": { + "version": "4.29.2", + "resolved": "https://registry.npmmirror.com/feather-icons/-/feather-icons-4.29.2.tgz", + "integrity": "sha512-0TaCFTnBTVCz6U+baY2UJNKne5ifGh7sMG4ZC2LoBWCZdIyPa+y6UiR4lEYGws1JOFWdee8KAsAIvu0VcXqiqA==", + "license": "MIT", + "dependencies": { + "classnames": "^2.2.5", + "core-js": "^3.1.3" + } + }, "node_modules/figures": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/figures/-/figures-2.0.0.tgz", diff --git a/package.json b/package.json index c1c0eb4..c5c65f4 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "blueimp-md5": "^2.19.0", "bootstrap": "^5.3.6", "core-js": "^3.8.3", + "feather-icons": "^4.29.2", "jquery": "^3.7.1", "perfect-scrollbar": "^1.5.6", "vue": "^2.6.14", diff --git a/src/main.js b/src/main.js index 4bf5105..213ff61 100644 --- a/src/main.js +++ b/src/main.js @@ -24,7 +24,6 @@ Vue.use(Alert) async function initApp() { //初始化请求系统配置信息 await store.dispatch('config/fetch_config') - new Vue({ router, store, diff --git a/src/request/api.js b/src/request/api.js index 6f7dd14..347fb8f 100644 --- a/src/request/api.js +++ b/src/request/api.js @@ -11,9 +11,13 @@ const register = async (param)=> await request.post('/api/Auth/Register',param) //获取所有系统配置 const getAllConfig = async ()=> await request.get('/api/systemconfig/getallsystemconfig') + //获取用户个人信息 +const getUserInfo = async () => await request.get('/api/User/UserInfo') + export default { login, register, SendValidateCode, - getAllConfig + getAllConfig, + getUserInfo } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index 15199bd..92ebd93 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -34,12 +34,45 @@ const routes = [ path: '/layout', component: () => import('@/views/layout/Home.vue'), children: [ - { path: 'index', component: () => import('@/views/layout/Dashboard.vue') } + { + path: 'index', + component: () => import('@/views/layout/Dashboard.vue'), + meta: { + title: '主页', + icon: 'home', + showInMenu: true, + showInUser:false, + isHome:true + } + }, + { + path: 'users', + component: () => import('@/views/layout/Users.vue'), + meta: { + title: '用户管理', + icon: 'users', + showInMenu: true, + showInUser:false, + isHome:false + } + }, + { + path: 'test', + component: () => import('@/views/layout/Users.vue'), + meta: { + title: '用户管理', + icon: 'inbox', + showInMenu: true, + showInUser:false, + isHome:false + } + }, ] } ] const router = new VueRouter({ + mode: 'history', routes }) diff --git a/src/store/index.js b/src/store/index.js index 3434cb0..513a385 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2,11 +2,13 @@ import Vue from 'vue' import Vuex from 'vuex' import config from './modules/config' +import userinfo from './modules/userinfo' Vue.use(Vuex) export default new Vuex.Store({ modules:{ - config + config, + userinfo } }) \ No newline at end of file diff --git a/src/store/modules/userinfo.js b/src/store/modules/userinfo.js new file mode 100644 index 0000000..47e0495 --- /dev/null +++ b/src/store/modules/userinfo.js @@ -0,0 +1,60 @@ +import api from '@/request/api' + +const state = { + user: JSON.parse(localStorage.getItem('USER_INFO') || null) +} + +const mutations = { + /** + * 储存当前登录用户信息 + * @param {*} state + * @param {*} userinfo 用户信息 + */ + SET_USERINFO(state,userinfo){ + state.user = userinfo + localStorage.setItem('USER_INFO',JSON.stringify(userinfo)) + state.loaded = true + }, + /** + * 退出登录清除用户数据 + * @param {*} state + */ + LOGOUT(state){ + state.user = null + localStorage.removeItem('USER_INFO') + } +} + +const actions = { + async fetchUserInfo({ commit, state }) { + if (state.user) return + try { + const res = await api.getUserInfo() + if(res.code == 1000){ + commit('SET_USERINFO', res.data) + }else{ + console.error('获取用户信息失败') + } + } catch (e) { + console.error('获取用户信息失败', e) + } + } +} + +const getters = { + /** + * 用户是否为管理员 + * @param {*} state + * @returns + */ + isAdmin:state => state.user.roles.some(x => x.role == 'Admin') +} + + +export default { + namespaced:true, + state, + mutations, + actions, + getters +} \ No newline at end of file diff --git a/src/utils/intercaptors/response/refresh.js b/src/utils/intercaptors/response/refresh.js index 7bd8295..3b1b20d 100644 --- a/src/utils/intercaptors/response/refresh.js +++ b/src/utils/intercaptors/response/refresh.js @@ -21,30 +21,34 @@ function runqueque(token) { * @returns */ export function handlerefresherror(response) { - const { config, data } = response - if (data.code == 2009 && !config._retry) { + const { config, data, status } = response + if ((data.code == 2009 || status == 401 && config.url != "/api/auth/refresh") && !config._retry) { config._retry = true if (!isrefreshing) { isrefreshing = true - return request.post('/auth/refreshToken', { + return request.post('/api/auth/refresh', { userid: auth.getUserId(), refreshtoken: auth.getRefreshToken() }) - .then(r => { - const {Token , RefreshToken} = r.data.data - auth.setAccessToken(Token) - auth.setRefreshToken(RefreshToken) - runqueque(Token) - // 用新 token 重做原始请求 - config.headers['Authorization'] = `Bearer ${Token}` - return request(config) - }) - .catch(err => { - auth.clear() - window.location.href = '/auth/login' - return Promise.reject(err) - }) - .finally(() => isrefreshing = false) + .then(r => { + if (r.code != 1000) { + window.location.href = '/auth/login' + return Promise.reject(r.data) + } + const { token, refreshToken } = r.data + auth.setAccessToken(token) + auth.setRefreshToken(refreshToken) + runqueque(token) + // 用新 token 重做原始请求 + config.headers['Authorization'] = `Bearer ${token}` + return request(config) + }) + .catch(err => { + auth.clear() + window.location.href = '/auth/login' + return Promise.reject(err) + }) + .finally(() => isrefreshing = false) } // 刷新中:队列化 diff --git a/src/views/auth/Login.vue b/src/views/auth/Login.vue index d8363e4..26c2b3b 100644 --- a/src/views/auth/Login.vue +++ b/src/views/auth/Login.vue @@ -71,6 +71,7 @@ export default { try { const res = await this.$api.login(this.formdata) let msg = '' + let type = 'danger' switch (res.code) { case 2000: msg = '登录成功'; break case 2001: msg = '用户名或密码错误'; break @@ -82,12 +83,18 @@ export default { //储存登录凭证 auth.setAccessToken(res.data.token) auth.setRefreshToken(res.data.refreshToken) + auth.setUserId(res.data.userInfo.id) + this.$store.commit('userinfo/SET_USERINFO', res.data.userInfo) + type = 'success' + this.$alert(msg, type) + this.$router.push('/layout/index') + }else{ + this.$alert(msg, type) } - this.$alert(msg,'success') - //this.$router.push() + } catch (e) { console.log(e) - alert('未知错误') + this.$alert('未知错误', 'error') } finally { //还原密码文本 this.formdata.password = passwordOld @@ -104,6 +111,4 @@ export default { - \ No newline at end of file + \ No newline at end of file diff --git a/src/views/layout/Home.vue b/src/views/layout/Home.vue index 57e6b74..ed61ac7 100644 --- a/src/views/layout/Home.vue +++ b/src/views/layout/Home.vue @@ -5,16 +5,16 @@ @@ -136,100 +136,16 @@
@@ -242,8 +158,47 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/views/layout/Users.vue b/src/views/layout/Users.vue new file mode 100644 index 0000000..e69de29 diff --git a/vue.config.js b/vue.config.js index bbf25d9..d8208ab 100644 --- a/vue.config.js +++ b/vue.config.js @@ -2,7 +2,11 @@ const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ publicPath: process.env.BRANCH_PATH || '/', // 👈 支持动态子路径部署 - transpileDependencies: true + transpileDependencies: true, + dev: { + devtool: 'source-map', + } + })