diff --git a/src/store/modules/user.js b/src/store/modules/user.js index ab0a6fe..ae43c5a 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -2,95 +2,95 @@ import { login, logout, getInfo } from '@/api/login' import { getToken, setToken, removeToken } from '@/utils/auth' const user = { - state: { - token: getToken(), - name: '', - avatar: '', - roles: [], - permissions: [] - }, + state: { + token: getToken(), + name: '', + avatar: '', + roles: [], + permissions: [] + }, - mutations: { - SET_TOKEN: (state, token) => { - state.token = token + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_NAME: (state, name) => { + state.name = name + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + }, + SET_ROLES: (state, roles) => { + state.roles = roles + }, + SET_PERMISSIONS: (state, permissions) => { + state.permissions = permissions + } }, - SET_NAME: (state, name) => { - state.name = name - }, - SET_AVATAR: (state, avatar) => { - state.avatar = avatar - }, - SET_ROLES: (state, roles) => { - state.roles = roles - }, - SET_PERMISSIONS: (state, permissions) => { - state.permissions = permissions + + actions: { + // 登录 + Login({ commit }, userInfo) { + const username = userInfo.username.trim() + const password = userInfo.password + const code = userInfo.code + const uuid = userInfo.uuid + return new Promise((resolve, reject) => { + login(username, password, code, uuid).then(res => { + setToken(res.token) + commit('SET_TOKEN', res.token) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 获取用户信息 + GetInfo({ commit, state }) { + return new Promise((resolve, reject) => { + getInfo().then(res => { + const user = res.user + const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; + if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 + commit('SET_ROLES', res.roles) + commit('SET_PERMISSIONS', res.permissions) + } else { + commit('SET_ROLES', ['ROLE_DEFAULT']) + } + commit('SET_NAME', user.userName) + commit('SET_AVATAR', avatar) + resolve(res) + }).catch(error => { + reject(error) + }) + }) + }, + + // 退出系统 + LogOut({ commit, state }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + commit('SET_ROLES', []) + commit('SET_PERMISSIONS', []) + removeToken() + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 前端 登出 + FedLogOut({ commit }) { + return new Promise(resolve => { + commit('SET_TOKEN', '') + removeToken() + resolve() + }) + } } - }, - - actions: { - // 登录 - Login({ commit }, userInfo) { - const username = userInfo.username.trim() - const password = userInfo.password - const code = userInfo.code - const uuid = userInfo.uuid - return new Promise((resolve, reject) => { - login(username, password, code, uuid).then(res => { - setToken(res.token) - commit('SET_TOKEN', res.token) - resolve() - }).catch(error => { - reject(error) - }) - }) - }, - - // 获取用户信息 - GetInfo({ commit, state }) { - return new Promise((resolve, reject) => { - getInfo().then(res => { - const user = res.user - const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; - if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 - commit('SET_ROLES', res.roles) - commit('SET_PERMISSIONS', res.permissions) - } else { - commit('SET_ROLES', ['ROLE_DEFAULT']) - } - commit('SET_NAME', user.userName) - commit('SET_AVATAR', avatar) - resolve(res) - }).catch(error => { - reject(error) - }) - }) - }, - - // 退出系统 - LogOut({ commit, state }) { - return new Promise((resolve, reject) => { - logout(state.token).then(() => { - commit('SET_TOKEN', '') - commit('SET_ROLES', []) - commit('SET_PERMISSIONS', []) - removeToken() - resolve() - }).catch(error => { - reject(error) - }) - }) - }, - - // 前端 登出 - FedLogOut({ commit }) { - return new Promise(resolve => { - commit('SET_TOKEN', '') - removeToken() - resolve() - }) - } - } } -export default user +export default user \ No newline at end of file diff --git a/src/utils/request.js b/src/utils/request.js index 4aefbda..303a7eb 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -12,54 +12,54 @@ let downloadLoadingInstance; export let isRelogin = { show: false }; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' -// 创建axios实例 + // 创建axios实例 const service = axios.create({ - // axios中请求配置有baseURL选项,表示请求URL公共部分 - baseURL: process.env.VUE_APP_BASE_API, - // 超时 - timeout: 10000 + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: process.env.VUE_APP_BASE_API, + // 超时 + timeout: 10000 }) // request拦截器 service.interceptors.request.use(config => { - // 是否需要设置 token - const isToken = (config.headers || {}).isToken === false - // 是否需要防止数据重复提交 - const isRepeatSubmit = (config.headers || {}).repeatSubmit === false - if (getToken() && !isToken) { - config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - } - // get请求映射params参数 - if (config.method === 'get' && config.params) { - let url = config.url + '?' + tansParams(config.params); - url = url.slice(0, -1); - config.params = {}; - config.url = url; - } - if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { - const requestObj = { - url: config.url, - data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, - time: new Date().getTime() + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } - const sessionObj = cache.session.getJSON('sessionObj') - if (sessionObj === undefined || sessionObj === null || sessionObj === '') { - cache.session.setJSON('sessionObj', requestObj) - } else { - const s_url = sessionObj.url; // 请求地址 - const s_data = sessionObj.data; // 请求数据 - const s_time = sessionObj.time; // 请求时间 - const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 - if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { - const message = '数据正在处理,请勿重复提交'; - console.warn(`[${s_url}]: ` + message) - return Promise.reject(new Error(message)) - } else { - cache.session.setJSON('sessionObj', requestObj) - } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; } - } - return config + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + } + const sessionObj = cache.session.getJSON('sessionObj') + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj) + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交'; + console.warn(`[${s_url}]: ` + message) + return Promise.reject(new Error(message)) + } else { + cache.session.setJSON('sessionObj', requestObj) + } + } + } + return config }, error => { console.log(error) Promise.reject(error) @@ -67,92 +67,91 @@ service.interceptors.request.use(config => { // 响应拦截器 service.interceptors.response.use(res => { - // 未设置状态码则默认成功状态 - const code = res.data.code || 200; - // 获取错误信息 - const msg = errorCode[code] || res.data.msg || errorCode['default'] - // 二进制数据则直接返回 - if(res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer'){ - return res.data - } - if (code === 401) { - if (!isRelogin.show) { - isRelogin.show = true; - MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' + // 未设置状态码则默认成功状态 + const code = res.data.code || 200; + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res.data } - ).then(() => { - isRelogin.show = false; - store.dispatch('LogOut').then(() => { - location.href = '/index'; + if (code === 401) { + if (!isRelogin.show) { + isRelogin.show = true; + MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + isRelogin.show = false; + store.dispatch('LogOut').then(() => { + location.href = '/index'; + }) + }).catch(() => { + isRelogin.show = false; + }); + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + Message({ + message: msg, + type: 'error' + }) + return Promise.reject(new Error(msg)) + } else if (code === 600) { + return Promise.reject(new Error(msg)) + } else if (code !== 200) { + Notification.error({ + title: msg + }) + return Promise.reject('error') + } else { + return res.data + } + }, + error => { + console.log('err' + error) + let { message } = error; + if (message == "Network Error") { + message = "后端接口连接异常"; + } else if (message.includes("timeout")) { + message = "系统接口请求超时"; + } else if (message.includes("Request failed with status code")) { + message = "系统接口" + message.substr(message.length - 3) + "异常"; + } + Message({ + message: message, + type: 'error', + duration: 5 * 1000 }) - }).catch(() => { - isRelogin.show = false; - }); + return Promise.reject(error) } - return Promise.reject('无效的会话,或者会话已过期,请重新登录。') - } else if (code === 500) { - Message({ - message: msg, - type: 'error' - }) - return Promise.reject(new Error(msg)) - } else if (code !== 200) { - Notification.error({ - title: msg - }) - return Promise.reject('error') - } else { - return res.data - } - }, - error => { - console.log('err' + error) - let { message } = error; - if (message == "Network Error") { - message = "后端接口连接异常"; - } - else if (message.includes("timeout")) { - message = "系统接口请求超时"; - } - else if (message.includes("Request failed with status code")) { - message = "系统接口" + message.substr(message.length - 3) + "异常"; - } - Message({ - message: message, - type: 'error', - duration: 5 * 1000 - }) - return Promise.reject(error) - } ) // 通用下载方法 export function download(url, params, filename) { - downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) - return service.post(url, params, { - transformRequest: [(params) => { return tansParams(params) }], - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - responseType: 'blob' - }).then(async (data) => { - const isLogin = await blobValidate(data); - if (isLogin) { - const blob = new Blob([data]) - saveAs(blob, filename) - } else { - const resText = await data.text(); - const rspObj = JSON.parse(resText); - const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] - Message.error(errMsg); - } - downloadLoadingInstance.close(); - }).catch((r) => { - console.error(r) - Message.error('下载文件出现错误,请联系管理员!') - downloadLoadingInstance.close(); - }) + downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob' + }).then(async(data) => { + const isLogin = await blobValidate(data); + if (isLogin) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg); + } + downloadLoadingInstance.close(); + }).catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close(); + }) } -export default service +export default service \ No newline at end of file diff --git a/src/views/login.vue b/src/views/login.vue index 31f5a5f..5dca2a3 100644 --- a/src/views/login.vue +++ b/src/views/login.vue @@ -13,7 +13,7 @@ type="text" auto-complete="off" placeholder="账号" - style="width: 310px" + style="width: 310px" > import { getCodeImg } from "@/api/login"; import Cookies from "js-cookie"; -import { encrypt, decrypt } from '@/utils/jsencrypt' +import { encrypt, decrypt } from "@/utils/jsencrypt"; export default { name: "Login", @@ -109,23 +108,23 @@ export default { password: "admin123", rememberMe: false, code: "", - uuid: "" + uuid: "", }, loginRules: { username: [ - { required: true, trigger: "blur", message: "请输入您的账号" } + { required: true, trigger: "blur", message: "请输入您的账号" }, ], password: [ - { required: true, trigger: "blur", message: "请输入您的密码" } + { required: true, trigger: "blur", message: "请输入您的密码" }, ], - code: [{ required: true, trigger: "change", message: "请输入验证码" }] + code: [{ required: true, trigger: "change", message: "请输入验证码" }], }, loading: false, // 验证码开关 captchaOnOff: true, // 注册开关 register: false, - redirect: undefined + redirect: undefined, }; }, watch: { @@ -133,8 +132,8 @@ export default { handler: function (route) { this.redirect = route.query && route.query.redirect; }, - immediate: true - } + immediate: true, + }, }, created() { this.getCode(); @@ -142,8 +141,9 @@ export default { }, methods: { getCode() { - getCodeImg().then(res => { - this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff; + getCodeImg().then((res) => { + this.captchaOnOff = + res.captchaOnOff === undefined ? true : res.captchaOnOff; if (this.captchaOnOff) { this.codeUrl = "data:image/gif;base64," + res.img; this.loginForm.uuid = res.uuid; @@ -153,38 +153,49 @@ export default { getCookie() { const username = Cookies.get("username"); const password = Cookies.get("password"); - const rememberMe = Cookies.get('rememberMe') + const rememberMe = Cookies.get("rememberMe"); this.loginForm = { username: username === undefined ? this.loginForm.username : username, - password: password === undefined ? this.loginForm.password : decrypt(password), - rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) + password: + password === undefined ? this.loginForm.password : decrypt(password), + rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), }; }, handleLogin() { - this.$refs.loginForm.validate(valid => { + this.$refs.loginForm.validate((valid) => { if (valid) { this.loading = true; if (this.loginForm.rememberMe) { Cookies.set("username", this.loginForm.username, { expires: 30 }); - Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); - Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); + Cookies.set("password", encrypt(this.loginForm.password), { + expires: 30, + }); + Cookies.set("rememberMe", this.loginForm.rememberMe, { + expires: 30, + }); } else { Cookies.remove("username"); Cookies.remove("password"); - Cookies.remove('rememberMe'); + Cookies.remove("rememberMe"); } - this.$store.dispatch("Login", this.loginForm).then(() => { - this.$router.push({ path: this.redirect || "/" }).catch(() => { }); - }).catch(() => { - this.loading = false; - if (this.captchaOnOff) { - this.getCode(); - } - }); + this.$store + .dispatch("Login", this.loginForm) + .then(() => { + this.$router.push({ path: this.redirect || "/" }).catch(() => {}); + setTimeout(() => { + this.loading = false; + }, 1500); + }) + .catch(() => { + this.loading = false; + if (this.captchaOnOff) { + this.getCode(); + } + }); } }); - } - } + }, + }, }; @@ -192,14 +203,14 @@ export default { // .login .el-input::v-deep .el-input__inner { // width: 300px; // background-color: #F8F8F8; - + // border: none; // } -.el-input--medium ::v-deep .el-input__inner{ - height: 50px; - line-height: 36px; - background-color: #F8F8F6; - border: none; +.el-input--medium ::v-deep .el-input__inner { + height: 50px; + line-height: 36px; + background-color: #f8f8f6; + border: none; border-radius: 10px; } .login { @@ -215,7 +226,7 @@ export default { text-align: center; color: #707070; } -.login-form .el-input{ +.login-form .el-input { border: none; } .login-form {