解决以子路径方式部署时的两个问题:1、登录后跳转到404页面 2、退出登录后直接跳转到/index页面,而不带子路径前缀

pull/410/head
mccreexu 4 months ago
parent 725033e361
commit 828aaeacc7

@ -1,208 +1,210 @@
<template> <template>
<div class="navbar"> <div class="navbar">
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container" /> <breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container" />
<top-nav v-if="topNav" id="topmenu-container" class="topmenu-container" /> <top-nav v-if="topNav" id="topmenu-container" class="topmenu-container" />
<div class="right-menu"> <div class="right-menu">
<template v-if="device!=='mobile'"> <template v-if="device!=='mobile'">
<search id="header-search" class="right-menu-item" /> <search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom"> <el-tooltip content="源码地址" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip> </el-tooltip>
<el-tooltip content="文档地址" effect="dark" placement="bottom"> <el-tooltip content="文档地址" effect="dark" placement="bottom">
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" /> <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
</el-tooltip> </el-tooltip>
<screenfull id="screenfull" class="right-menu-item hover-effect" /> <screenfull id="screenfull" class="right-menu-item hover-effect" />
<el-tooltip content="布局大小" effect="dark" placement="bottom"> <el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" /> <size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip> </el-tooltip>
</template> </template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover"> <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img :src="avatar" class="user-avatar"> <img :src="avatar" class="user-avatar">
<span class="user-nickname"> {{ nickName }} </span> <span class="user-nickname"> {{ nickName }} </span>
</div> </div>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<router-link to="/user/profile"> <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item> <el-dropdown-item>个人中心</el-dropdown-item>
</router-link> </router-link>
<el-dropdown-item divided @click.native="logout"> <el-dropdown-item divided @click.native="logout">
<span>退出登录</span> <span>退出登录</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
<div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting"> <div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting">
<svg-icon icon-class="more-up" /> <svg-icon icon-class="more-up" />
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb' import Breadcrumb from '@/components/Breadcrumb'
import TopNav from '@/components/TopNav' import TopNav from '@/components/TopNav'
import Hamburger from '@/components/Hamburger' import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull' import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect' import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch' import Search from '@/components/HeaderSearch'
import RuoYiGit from '@/components/RuoYi/Git' import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc' import RuoYiDoc from '@/components/RuoYi/Doc'
export default { export default {
emits: ['setLayout'], emits: ['setLayout'],
components: { components: {
Breadcrumb, Breadcrumb,
TopNav, TopNav,
Hamburger, Hamburger,
Screenfull, Screenfull,
SizeSelect, SizeSelect,
Search, Search,
RuoYiGit, RuoYiGit,
RuoYiDoc RuoYiDoc
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'sidebar', 'sidebar',
'avatar', 'avatar',
'device', 'device',
'nickName' 'nickName'
]), ]),
setting: { setting: {
get() { get() {
return this.$store.state.settings.showSettings return this.$store.state.settings.showSettings
} }
}, },
topNav: { topNav: {
get() { get() {
return this.$store.state.settings.topNav return this.$store.state.settings.topNav
} }
} }
}, },
methods: { methods: {
toggleSideBar() { toggleSideBar() {
this.$store.dispatch('app/toggleSideBar') this.$store.dispatch('app/toggleSideBar')
}, },
setLayout(event) { setLayout(event) {
this.$emit('setLayout') this.$emit('setLayout')
}, },
logout() { logout() {
this.$confirm('确定注销并退出系统吗?', '提示', { this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$store.dispatch('LogOut').then(() => { this.$store.dispatch('LogOut').then(() => {
location.href = '/index' // 使 BASE_PATH
}) const basePath = process.env.VUE_APP_BASE_PATH || '/'; //
}).catch(() => {}) location.href = `${basePath}index`;
} })
} }).catch(() => {})
} }
</script> }
}
<style lang="scss" scoped> </script>
.navbar {
height: 50px; <style lang="scss" scoped>
overflow: hidden; .navbar {
position: relative; height: 50px;
background: #fff; overflow: hidden;
box-shadow: 0 1px 4px rgba(0,21,41,.08); position: relative;
background: #fff;
.hamburger-container { box-shadow: 0 1px 4px rgba(0,21,41,.08);
line-height: 46px;
height: 100%; .hamburger-container {
float: left; line-height: 46px;
cursor: pointer; height: 100%;
transition: background .3s; float: left;
-webkit-tap-highlight-color:transparent; cursor: pointer;
transition: background .3s;
&:hover { -webkit-tap-highlight-color:transparent;
background: rgba(0, 0, 0, .025)
} &:hover {
} background: rgba(0, 0, 0, .025)
}
.breadcrumb-container { }
float: left;
} .breadcrumb-container {
float: left;
.topmenu-container { }
position: absolute;
left: 50px; .topmenu-container {
} position: absolute;
left: 50px;
.errLog-container { }
display: inline-block;
vertical-align: top; .errLog-container {
} display: inline-block;
vertical-align: top;
.right-menu { }
float: right;
height: 100%; .right-menu {
line-height: 50px; float: right;
height: 100%;
&:focus { line-height: 50px;
outline: none;
} &:focus {
outline: none;
.right-menu-item { }
display: inline-block;
padding: 0 8px; .right-menu-item {
height: 100%; display: inline-block;
font-size: 18px; padding: 0 8px;
color: #5a5e66; height: 100%;
vertical-align: text-bottom; font-size: 18px;
color: #5a5e66;
&.hover-effect { vertical-align: text-bottom;
cursor: pointer;
transition: background .3s; &.hover-effect {
cursor: pointer;
&:hover { transition: background .3s;
background: rgba(0, 0, 0, .025)
} &:hover {
} background: rgba(0, 0, 0, .025)
} }
}
.avatar-container { }
margin-right: 0px;
padding-right: 0px; .avatar-container {
margin-right: 0px;
.avatar-wrapper { padding-right: 0px;
margin-top: 10px;
position: relative; .avatar-wrapper {
margin-top: 10px;
.user-avatar { position: relative;
cursor: pointer;
width: 30px; .user-avatar {
height: 30px; cursor: pointer;
border-radius: 50%; width: 30px;
} height: 30px;
border-radius: 50%;
.user-nickname{ }
position: relative;
bottom: 10px; .user-nickname{
font-size: 14px; position: relative;
font-weight: bold; bottom: 10px;
} font-size: 14px;
font-weight: bold;
.el-icon-caret-bottom { }
cursor: pointer;
position: absolute; .el-icon-caret-bottom {
right: -20px; cursor: pointer;
top: 25px; position: absolute;
font-size: 12px; right: -20px;
} top: 25px;
} font-size: 12px;
} }
} }
} }
</style> }
}
</style>

@ -1,183 +1,186 @@
import Vue from 'vue' import Vue from 'vue'
import Router from 'vue-router' import Router from 'vue-router'
Vue.use(Router) Vue.use(Router)
/* Layout */ /* Layout */
import Layout from '@/layout' import Layout from '@/layout'
/** /**
* Note: 路由配置项 * Note: 路由配置项
* *
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1 * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面 * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由 * // 若你想不管路由下面的 children 声明的个数都显示你的根路由
* // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由 * // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题 * name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
* query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数
* roles: ['admin', 'common'] // 访问路由的角色权限 * roles: ['admin', 'common'] // 访问路由的角色权限
* permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限
* meta : { * meta : {
noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false) noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false)
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg
breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示 breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
} }
*/ */
// 公共路由 // 公共路由
export const constantRoutes = [ export const constantRoutes = [
{ {
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,
hidden: true, hidden: true,
children: [ children: [
{ {
path: '/redirect/:path(.*)', path: '/redirect/:path(.*)',
component: () => import('@/views/redirect') component: () => import('@/views/redirect')
} }
] ]
}, },
{ {
path: '/login', path: '/login',
component: () => import('@/views/login'), component: () => import('@/views/login'),
hidden: true hidden: true
}, },
{ {
path: '/register', path: '/register',
component: () => import('@/views/register'), component: () => import('@/views/register'),
hidden: true hidden: true
}, },
{ {
path: '/404', path: '/404',
component: () => import('@/views/error/404'), component: () => import('@/views/error/404'),
hidden: true hidden: true
}, },
{ {
path: '/401', path: '/401',
component: () => import('@/views/error/401'), component: () => import('@/views/error/401'),
hidden: true hidden: true
}, },
{ {
path: '', path: '',
component: Layout, component: Layout,
redirect: 'index', redirect: 'index',
children: [ children: [
{ {
path: 'index', path: 'index',
component: () => import('@/views/index'), component: () => import('@/views/index'),
name: 'Index', name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true } meta: { title: '首页', icon: 'dashboard', affix: true }
} }
] ]
}, },
{ {
path: '/user', path: '/user',
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: 'noredirect',
children: [ children: [
{ {
path: 'profile', path: 'profile',
component: () => import('@/views/system/user/profile/index'), component: () => import('@/views/system/user/profile/index'),
name: 'Profile', name: 'Profile',
meta: { title: '个人中心', icon: 'user' } meta: { title: '个人中心', icon: 'user' }
} }
] ]
} }
] ]
// 动态路由,基于用户权限动态去加载 // 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [ export const dynamicRoutes = [
{ {
path: '/system/user-auth', path: '/system/user-auth',
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['system:user:edit'], permissions: ['system:user:edit'],
children: [ children: [
{ {
path: 'role/:userId(\\d+)', path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'), component: () => import('@/views/system/user/authRole'),
name: 'AuthRole', name: 'AuthRole',
meta: { title: '分配角色', activeMenu: '/system/user' } meta: { title: '分配角色', activeMenu: '/system/user' }
} }
] ]
}, },
{ {
path: '/system/role-auth', path: '/system/role-auth',
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['system:role:edit'], permissions: ['system:role:edit'],
children: [ children: [
{ {
path: 'user/:roleId(\\d+)', path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'), component: () => import('@/views/system/role/authUser'),
name: 'AuthUser', name: 'AuthUser',
meta: { title: '分配用户', activeMenu: '/system/role' } meta: { title: '分配用户', activeMenu: '/system/role' }
} }
] ]
}, },
{ {
path: '/system/dict-data', path: '/system/dict-data',
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['system:dict:list'], permissions: ['system:dict:list'],
children: [ children: [
{ {
path: 'index/:dictId(\\d+)', path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data'), component: () => import('@/views/system/dict/data'),
name: 'Data', name: 'Data',
meta: { title: '字典数据', activeMenu: '/system/dict' } meta: { title: '字典数据', activeMenu: '/system/dict' }
} }
] ]
}, },
{ {
path: '/monitor/job-log', path: '/monitor/job-log',
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['monitor:job:list'], permissions: ['monitor:job:list'],
children: [ children: [
{ {
path: 'index/:jobId(\\d+)', path: 'index/:jobId(\\d+)',
component: () => import('@/views/monitor/job/log'), component: () => import('@/views/monitor/job/log'),
name: 'JobLog', name: 'JobLog',
meta: { title: '调度日志', activeMenu: '/monitor/job' } meta: { title: '调度日志', activeMenu: '/monitor/job' }
} }
] ]
}, },
{ {
path: '/tool/gen-edit', path: '/tool/gen-edit',
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['tool:gen:edit'], permissions: ['tool:gen:edit'],
children: [ children: [
{ {
path: 'index/:tableId(\\d+)', path: 'index/:tableId(\\d+)',
component: () => import('@/views/tool/gen/editTable'), component: () => import('@/views/tool/gen/editTable'),
name: 'GenEdit', name: 'GenEdit',
meta: { title: '修改生成配置', activeMenu: '/tool/gen' } meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
} }
] ]
} }
] ]
// 防止连续点击多次路由报错 // 防止连续点击多次路由报错
let routerPush = Router.prototype.push let routerPush = Router.prototype.push
let routerReplace = Router.prototype.replace let routerReplace = Router.prototype.replace
// push // push
Router.prototype.push = function push(location) { Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(err => err) return routerPush.call(this, location).catch(err => err)
} }
// replace // replace
Router.prototype.replace = function push(location) { Router.prototype.replace = function push(location) {
return routerReplace.call(this, location).catch(err => err) return routerReplace.call(this, location).catch(err => err)
} }
export default new Router({ export default new Router({
mode: 'history', // 去掉url中的# mode: 'history', // 去掉url中的#
scrollBehavior: () => ({ y: 0 }), // 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
routes: constantRoutes // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
}) base: process.env.NODE_ENV === "production" ? "/" : "/",
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})

@ -1,152 +1,156 @@
import axios from 'axios' import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui' import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store' import store from '@/store'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode' import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi" import { tansParams, blobValidate } from "@/utils/ruoyi"
import cache from '@/plugins/cache' import cache from '@/plugins/cache'
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
let downloadLoadingInstance // 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 是否显示重新登录 // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
export let isRelogin = { show: false } export const BASE_PATH = '/'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' let downloadLoadingInstance
// 创建axios实例 // 是否显示重新登录
const service = axios.create({ export let isRelogin = { show: false }
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API, axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 超时 // 创建axios实例
timeout: 10000 const service = axios.create({
}) // axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// request拦截器 // 超时
service.interceptors.request.use(config => { timeout: 10000
// 是否需要设置 token })
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交 // request拦截器
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false service.interceptors.request.use(config => {
if (getToken() && !isToken) { // 是否需要设置 token
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 const isToken = (config.headers || {}).isToken === false
} // 是否需要防止数据重复提交
// get请求映射params参数 const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (config.method === 'get' && config.params) { if (getToken() && !isToken) {
let url = config.url + '?' + tansParams(config.params) config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
url = url.slice(0, -1) }
config.params = {} // get请求映射params参数
config.url = url if (config.method === 'get' && config.params) {
} let url = config.url + '?' + tansParams(config.params)
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { url = url.slice(0, -1)
const requestObj = { config.params = {}
url: config.url, config.url = url
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, }
time: new Date().getTime() if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
} const requestObj = {
const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小 url: config.url,
const limitSize = 5 * 1024 * 1024 // 限制存放数据5M data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
if (requestSize >= limitSize) { time: new Date().getTime()
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。') }
return config const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
} const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
const sessionObj = cache.session.getJSON('sessionObj') if (requestSize >= limitSize) {
if (sessionObj === undefined || sessionObj === null || sessionObj === '') { console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。')
cache.session.setJSON('sessionObj', requestObj) return config
} else { }
const s_url = sessionObj.url // 请求地址 const sessionObj = cache.session.getJSON('sessionObj')
const s_data = sessionObj.data // 请求数据 if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
const s_time = sessionObj.time // 请求时间 cache.session.setJSON('sessionObj', requestObj)
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交 } else {
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { const s_url = sessionObj.url // 请求地址
const message = '数据正在处理,请勿重复提交' const s_data = sessionObj.data // 请求数据
console.warn(`[${s_url}]: ` + message) const s_time = sessionObj.time // 请求时间
return Promise.reject(new Error(message)) const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
} else { if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
cache.session.setJSON('sessionObj', requestObj) const message = '数据正在处理,请勿重复提交'
} console.warn(`[${s_url}]: ` + message)
} return Promise.reject(new Error(message))
} } else {
return config cache.session.setJSON('sessionObj', requestObj)
}, error => { }
console.log(error) }
Promise.reject(error) }
}) return config
}, error => {
// 响应拦截器 console.log(error)
service.interceptors.response.use(res => { Promise.reject(error)
// 未设置状态码则默认成功状态 })
const code = res.data.code || 200
// 获取错误信息 // 响应拦截器
const msg = errorCode[code] || res.data.msg || errorCode['default'] service.interceptors.response.use(res => {
// 二进制数据则直接返回 // 未设置状态码则默认成功状态
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { const code = res.data.code || 200
return res.data // 获取错误信息
} const msg = errorCode[code] || res.data.msg || errorCode['default']
if (code === 401) { // 二进制数据则直接返回
if (!isRelogin.show) { if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
isRelogin.show = true return res.data
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { }
isRelogin.show = false if (code === 401) {
store.dispatch('LogOut').then(() => { if (!isRelogin.show) {
location.href = '/index' isRelogin.show = true
}) MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
}).catch(() => { isRelogin.show = false
isRelogin.show = false store.dispatch('LogOut').then(() => {
}) location.href = '/index'
} })
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') }).catch(() => {
} else if (code === 500) { isRelogin.show = false
Message({ message: msg, type: 'error' }) })
return Promise.reject(new Error(msg)) }
} else if (code === 601) { return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
Message({ message: msg, type: 'warning' }) } else if (code === 500) {
return Promise.reject('error') Message({ message: msg, type: 'error' })
} else if (code !== 200) { return Promise.reject(new Error(msg))
Notification.error({ title: msg }) } else if (code === 601) {
return Promise.reject('error') Message({ message: msg, type: 'warning' })
} else { return Promise.reject('error')
return res.data } else if (code !== 200) {
} Notification.error({ title: msg })
}, return Promise.reject('error')
error => { } else {
console.log('err' + error) return res.data
let { message } = error }
if (message == "Network Error") { },
message = "后端接口连接异常" error => {
} else if (message.includes("timeout")) { console.log('err' + error)
message = "系统接口请求超时" let { message } = error
} else if (message.includes("Request failed with status code")) { if (message == "Network Error") {
message = "系统接口" + message.substr(message.length - 3) + "异常" message = "后端接口连接异常"
} } else if (message.includes("timeout")) {
Message({ message: message, type: 'error', duration: 5 * 1000 }) message = "系统接口请求超时"
return Promise.reject(error) } 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, config) { }
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' }, export function download(url, params, filename, config) {
responseType: 'blob', downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
...config return service.post(url, params, {
}).then(async (data) => { transformRequest: [(params) => { return tansParams(params) }],
const isBlob = blobValidate(data) headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
if (isBlob) { responseType: 'blob',
const blob = new Blob([data]) ...config
saveAs(blob, filename) }).then(async (data) => {
} else { const isBlob = blobValidate(data)
const resText = await data.text() if (isBlob) {
const rspObj = JSON.parse(resText) const blob = new Blob([data])
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] saveAs(blob, filename)
Message.error(errMsg) } else {
} const resText = await data.text()
downloadLoadingInstance.close() const rspObj = JSON.parse(resText)
}).catch((r) => { const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
console.error(r) Message.error(errMsg)
Message.error('下载文件出现错误,请联系管理员!') }
downloadLoadingInstance.close() downloadLoadingInstance.close()
}) }).catch((r) => {
} console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
export default service downloadLoadingInstance.close()
})
}
export default service

Loading…
Cancel
Save