mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2025-09-10 06:09:12 +00:00
Merge branch 'master' of https://gitee.com/y_project/RuoYi-Cloud
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -17,7 +17,7 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<spring-boot.version>2.5.5</spring-boot.version>
|
<spring-boot.version>2.5.6</spring-boot.version>
|
||||||
<spring-cloud.version>2020.0.4</spring-cloud.version>
|
<spring-cloud.version>2020.0.4</spring-cloud.version>
|
||||||
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
||||||
<alibaba.nacos.version>2.0.3</alibaba.nacos.version>
|
<alibaba.nacos.version>2.0.3</alibaba.nacos.version>
|
||||||
|
@@ -14,6 +14,7 @@ import com.ruoyi.system.api.model.LoginUser;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
|
* 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
|
||||||
|
* 注意:此拦截器会同时验证当前用户有效期自动刷新有效期
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
|
@@ -59,7 +59,7 @@ public class AuthFilter implements GlobalFilter, Ordered
|
|||||||
Claims claims = JwtUtils.parseToken(token);
|
Claims claims = JwtUtils.parseToken(token);
|
||||||
if (claims == null)
|
if (claims == null)
|
||||||
{
|
{
|
||||||
return unauthorizedResponse(exchange, "token已过期或验证不正确!");
|
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
|
||||||
}
|
}
|
||||||
String userkey = JwtUtils.getUserKey(claims);
|
String userkey = JwtUtils.getUserKey(claims);
|
||||||
boolean islogin = redisService.hasKey(getTokenKey(userkey));
|
boolean islogin = redisService.hasKey(getTokenKey(userkey));
|
||||||
|
@@ -17,7 +17,7 @@ public class SentinelFallbackHandler implements WebExceptionHandler
|
|||||||
{
|
{
|
||||||
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
|
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
|
||||||
{
|
{
|
||||||
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍后再试");
|
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -162,7 +162,7 @@ export default {
|
|||||||
this.sideTheme = val;
|
this.sideTheme = val;
|
||||||
},
|
},
|
||||||
saveSetting() {
|
saveSetting() {
|
||||||
this.$modal.loading("正在保存到本地,请稍后...");
|
this.$modal.loading("正在保存到本地,请稍候...");
|
||||||
this.$cache.local.set(
|
this.$cache.local.set(
|
||||||
"layout-setting",
|
"layout-setting",
|
||||||
`{
|
`{
|
||||||
@@ -178,7 +178,7 @@ export default {
|
|||||||
setTimeout(this.$modal.closeLoading(), 1000)
|
setTimeout(this.$modal.closeLoading(), 1000)
|
||||||
},
|
},
|
||||||
resetSetting() {
|
resetSetting() {
|
||||||
this.$modal.loading("正在清除设置缓存并刷新,请稍后...");
|
this.$modal.loading("正在清除设置缓存并刷新,请稍候...");
|
||||||
this.$cache.local.remove("layout-setting")
|
this.$cache.local.remove("layout-setting")
|
||||||
setTimeout("window.location.reload()", 1000)
|
setTimeout("window.location.reload()", 1000)
|
||||||
}
|
}
|
||||||
|
60
ruoyi-ui/src/plugins/auth.js
Normal file
60
ruoyi-ui/src/plugins/auth.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import store from '@/store'
|
||||||
|
|
||||||
|
function authPermission(permission) {
|
||||||
|
const all_permission = "*:*:*";
|
||||||
|
const permissions = store.getters && store.getters.permissions
|
||||||
|
if (permission && permission.length > 0) {
|
||||||
|
return permissions.some(v => {
|
||||||
|
return all_permission === v || v === permission
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function authRole(role) {
|
||||||
|
const super_admin = "admin";
|
||||||
|
const roles = store.getters && store.getters.roles
|
||||||
|
if (role && role.length > 0) {
|
||||||
|
return roles.some(v => {
|
||||||
|
return super_admin === v || v === role
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 验证用户是否具备某权限
|
||||||
|
hasPermi(permission) {
|
||||||
|
return authPermission(permission);
|
||||||
|
},
|
||||||
|
// 验证用户是否含有指定权限,只需包含其中一个
|
||||||
|
hasPermiOr(permissions) {
|
||||||
|
return permissions.some(item => {
|
||||||
|
return authPermission(item)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 验证用户是否含有指定权限,必须全部拥有
|
||||||
|
hasPermiAnd(permissions) {
|
||||||
|
return permissions.every(item => {
|
||||||
|
return authPermission(item)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 验证用户是否具备某角色
|
||||||
|
hasRole(role) {
|
||||||
|
return authRole(role);
|
||||||
|
},
|
||||||
|
// 验证用户是否含有指定角色,只需包含其中一个
|
||||||
|
hasRoleOr(roles) {
|
||||||
|
return roles.some(item => {
|
||||||
|
return authRole(item)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 验证用户是否含有指定角色,必须全部拥有
|
||||||
|
hasRoleAnd(roles) {
|
||||||
|
return roles.every(item => {
|
||||||
|
return authRole(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
import { saveAs } from 'file-saver'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { blobValidate } from "@/utils/ruoyi";
|
||||||
|
|
||||||
const baseURL = process.env.VUE_APP_BASE_API
|
const baseURL = process.env.VUE_APP_BASE_API
|
||||||
|
|
||||||
@@ -12,9 +14,14 @@ export default {
|
|||||||
url: url,
|
url: url,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||||
}).then(res => {
|
}).then(async (res) => {
|
||||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
const isLogin = await blobValidate(res.data);
|
||||||
this.saveAs(blob, name)
|
if (isLogin) {
|
||||||
|
const blob = new Blob([res.data], { type: 'application/zip' })
|
||||||
|
this.saveAs(blob, name)
|
||||||
|
} else {
|
||||||
|
Message.error('无效的会话,或者会话已过期,请重新登录。');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
saveAs(text, name, opts) {
|
saveAs(text, name, opts) {
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
|
import auth from './auth'
|
||||||
import cache from './cache'
|
import cache from './cache'
|
||||||
import modal from './modal'
|
import modal from './modal'
|
||||||
import download from './download'
|
import download from './download'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
|
// 认证对象
|
||||||
|
Vue.prototype.$auth = auth
|
||||||
// 缓存对象
|
// 缓存对象
|
||||||
Vue.prototype.$cache = cache
|
Vue.prototype.$cache = cache
|
||||||
// 模态框对象
|
// 模态框对象
|
||||||
|
@@ -3,7 +3,7 @@ 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 } from "@/utils/ruoyi";
|
import { tansParams, blobValidate } from "@/utils/ruoyi";
|
||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
|
|
||||||
let downloadLoadingInstance;
|
let downloadLoadingInstance;
|
||||||
@@ -43,6 +43,10 @@ service.interceptors.response.use(res => {
|
|||||||
const code = res.data.code || 200;
|
const code = res.data.code || 200;
|
||||||
// 获取错误信息
|
// 获取错误信息
|
||||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
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 (code === 401) {
|
||||||
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||||
confirmButtonText: '重新登录',
|
confirmButtonText: '重新登录',
|
||||||
@@ -93,15 +97,19 @@ service.interceptors.response.use(res => {
|
|||||||
|
|
||||||
// 通用下载方法
|
// 通用下载方法
|
||||||
export function download(url, params, filename) {
|
export function download(url, params, filename) {
|
||||||
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍后", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
|
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
|
||||||
return service.post(url, params, {
|
return service.post(url, params, {
|
||||||
transformRequest: [(params) => { return tansParams(params) }],
|
transformRequest: [(params) => { return tansParams(params) }],
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
}).then((data) => {
|
}).then(async (data) => {
|
||||||
const content = data
|
const isLogin = await blobValidate(data);
|
||||||
const blob = new Blob([content])
|
if (isLogin) {
|
||||||
saveAs(blob, filename)
|
const blob = new Blob([data])
|
||||||
|
saveAs(blob, filename)
|
||||||
|
} else {
|
||||||
|
Message.error('无效的会话,或者会话已过期,请重新登录。');
|
||||||
|
}
|
||||||
downloadLoadingInstance.close();
|
downloadLoadingInstance.close();
|
||||||
}).catch((r) => {
|
}).catch((r) => {
|
||||||
console.error(r)
|
console.error(r)
|
||||||
|
@@ -214,3 +214,14 @@ export function tansParams(params) {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证是否为blob格式
|
||||||
|
export async function blobValidate(data) {
|
||||||
|
try {
|
||||||
|
const text = await data.text();
|
||||||
|
JSON.parse(text);
|
||||||
|
return false;
|
||||||
|
} catch (error) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -199,7 +199,7 @@
|
|||||||
ref="menu"
|
ref="menu"
|
||||||
node-key="id"
|
node-key="id"
|
||||||
:check-strictly="!form.menuCheckStrictly"
|
:check-strictly="!form.menuCheckStrictly"
|
||||||
empty-text="加载中,请稍后"
|
empty-text="加载中,请稍候"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
></el-tree>
|
></el-tree>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
ref="dept"
|
ref="dept"
|
||||||
node-key="id"
|
node-key="id"
|
||||||
:check-strictly="!form.deptCheckStrictly"
|
:check-strictly="!form.deptCheckStrictly"
|
||||||
empty-text="加载中,请稍后"
|
empty-text="加载中,请稍候"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
></el-tree>
|
></el-tree>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
Reference in New Issue
Block a user