Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue into dev
Conflicts:
pom.xml
ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
ruoyi-ui/src/layout/components/Settings/index.vue
ruoyi-ui/src/plugins/download.js
ruoyi-ui/src/store/modules/permission.js
ruoyi-ui/src/views/index.vue
ruoyi-ui/src/views/monitor/server/index.vue
ruoyi-ui/src/views/system/role/index.vue
ry.bat
| | |
| | | /** |
| | | * æç¤ºæ¶æ¯ |
| | | */ |
| | | String message() default "ä¸å
许éå¤æäº¤ï¼è¯·ç¨ååè¯"; |
| | | String message() default "ä¸å
许éå¤æäº¤ï¼è¯·ç¨ååè¯"; |
| | | |
| | | } |
| | |
| | | * åæ¢çº¿ç¨æ± |
| | | * å
使ç¨shutdown, åæ¢æ¥æ¶æ°ä»»å¡å¹¶å°è¯å®æææå·²åå¨ä»»å¡. |
| | | * 妿è¶
æ¶, åè°ç¨shutdownNow, åæ¶å¨workQueueä¸Pendingçä»»å¡,并䏿ææé»å¡å½æ°. |
| | | * 妿ä»äººè¶
æï¼åå¼·å¶éåº. |
| | | * 妿ä»ç¶è¶
æï¼åå¼·å¶éåº. |
| | | * å¦å¯¹å¨shutdownæ¶çº¿ç¨æ¬èº«è¢«è°ç¨ä¸æåäºå¤ç. |
| | | */ |
| | | public static void shutdownAndAwaitTermination(ExecutorService pool) { |
| | |
| | | * @return |
| | | */ |
| | | public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { |
| | | response.addHeader("Access-Control-Allow-Origin", "*"); |
| | | response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); |
| | | |
| | | String percentEncodedFileName = percentEncode(realFileName); |
| | | |
| | | StringBuilder contentDispositionValue = new StringBuilder(); |
| | |
| | | .append("utf-8''") |
| | | .append(percentEncodedFileName); |
| | | |
| | | response.addHeader("Access-Control-Allow-Origin", "*"); |
| | | response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); |
| | | response.setHeader("Content-disposition", contentDispositionValue.toString()); |
| | | response.setHeader("download-filename", percentEncodedFileName); |
| | | } |
| | |
| | | * @param userId ç¨æ·ID |
| | | * @return éä¸è§è²IDå表 |
| | | */ |
| | | List<Integer> selectRoleListByUserId(Long userId); |
| | | List<Long> selectRoleListByUserId(Long userId); |
| | | |
| | | /** |
| | | * æ ¹æ®ç¨æ·IDæ¥è¯¢è§è² |
| | |
| | | * @param userId ç¨æ·ID |
| | | * @return éä¸è§è²IDå表 |
| | | */ |
| | | List<Integer> selectRoleListByUserId(Long userId); |
| | | List<Long> selectRoleListByUserId(Long userId); |
| | | |
| | | /** |
| | | * éè¿è§è²IDæ¥è¯¢è§è² |
| | |
| | | * @return éä¸è§è²IDå表 |
| | | */ |
| | | @Override |
| | | public List<Integer> selectRoleListByUserId(Long userId) { |
| | | public List<Long> selectRoleListByUserId(Long userId) { |
| | | return baseMapper.selectRoleListByUserId(userId); |
| | | } |
| | | |
| | |
| | | this.sideTheme = val; |
| | | }, |
| | | saveSetting() { |
| | | this.$modal.loading("æ£å¨ä¿åå°æ¬å°ï¼è¯·ç¨å..."); |
| | | this.$modal.loading("æ£å¨ä¿åå°æ¬å°ï¼è¯·ç¨å..."); |
| | | this.$cache.local.set( |
| | | "layout-setting", |
| | | `{ |
| | |
| | | setTimeout(this.$modal.closeLoading(), 1000) |
| | | }, |
| | | resetSetting() { |
| | | this.$modal.loading("æ£å¨æ¸
é¤è®¾ç½®ç¼åå¹¶å·æ°ï¼è¯·ç¨å..."); |
| | | this.$modal.loading("æ£å¨æ¸
é¤è®¾ç½®ç¼åå¹¶å·æ°ï¼è¯·ç¨å..."); |
| | | this.$cache.local.remove("layout-setting") |
| | | setTimeout("window.location.reload()", 1000) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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)
|
| | | })
|
| | | }
|
| | | }
|
| | |
| | | import { saveAs } from 'file-saver' |
| | | import axios from 'axios' |
| | | import { getToken } from '@/utils/auth' |
| | | import { Message } from 'element-ui' |
| | | |
| | | const baseURL = process.env.VUE_APP_BASE_API |
| | | |
| | |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then(res => { |
| | | const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) |
| | | this.saveAs(blob, decodeURI(res.headers['download-filename'])) |
| | | }).then(async (res) => { |
| | | const isLogin = await this.blobValidate(res.data); |
| | | if (isLogin) { |
| | | const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) |
| | | this.saveAs(blob, decodeURI(res.headers['download-filename'])) |
| | | } else { |
| | | Message.error('æ æçä¼è¯ï¼æè
ä¼è¯å·²è¿æï¼è¯·éæ°ç»å½ã'); |
| | | } |
| | | }) |
| | | }, |
| | | oss(ossId) { |
| | |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then(res => { |
| | | const blob = new Blob([res.data], { type: 'application/octet-stream' }) |
| | | this.saveAs(blob, decodeURI(res.headers['download-filename'])) |
| | | }).then(async (res) => { |
| | | const isLogin = await this.blobValidate(res.data); |
| | | if (isLogin) { |
| | | const blob = new Blob([res.data], { type: 'application/octet-stream' }) |
| | | this.saveAs(blob, decodeURI(res.headers['download-filename'])) |
| | | } else { |
| | | Message.error('æ æçä¼è¯ï¼æè
ä¼è¯å·²è¿æï¼è¯·éæ°ç»å½ã'); |
| | | } |
| | | }) |
| | | }, |
| | | zip(url, name) { |
| | |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then(res => { |
| | | const blob = new Blob([res.data], { type: 'application/zip' }) |
| | | this.saveAs(blob, name) |
| | | }).then(async (res) => { |
| | | const isLogin = await this.blobValidate(res.data); |
| | | 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); |
| | | } |
| | | }, |
| | | async blobValidate(data) { |
| | | try { |
| | | const text = await data.text(); |
| | | JSON.parse(text); |
| | | return false; |
| | | } catch (error) { |
| | | return true; |
| | | } |
| | | }, |
| | | } |
| | | |
| | |
| | | import auth from './auth'
|
| | | import cache from './cache'
|
| | | import modal from './modal'
|
| | | import download from './download'
|
| | |
|
| | | export default {
|
| | | install(Vue) {
|
| | | // 认è¯å¯¹è±¡
|
| | | Vue.prototype.$auth = auth
|
| | | // ç¼å对象
|
| | | Vue.prototype.$cache = cache
|
| | | // æ¨¡ææ¡å¯¹è±¡
|
| | |
| | | var children = [] |
| | | childrenMap.forEach((el, index) => { |
| | | if (el.children && el.children.length) { |
| | | if (el.component === 'ParentView') { |
| | | if (el.component === 'ParentView' && !lastRouter) { |
| | | el.children.forEach(c => { |
| | | c.path = el.path + '/' + c.path |
| | | if (c.children && c.children.length) { |
| | |
| | | return children |
| | | } |
| | | |
| | | export const loadView = (view) => { // è·¯ç±æå è½½ |
| | | return (resolve) => require([`@/views/${view}`], resolve) |
| | | export const loadView = (view) => { |
| | | if (process.env.NODE_ENV === 'development') { |
| | | return (resolve) => require([`@/views/${view}`], resolve) |
| | | } else { |
| | | // ä½¿ç¨ import å®ç°ç产ç¯å¢çè·¯ç±æå è½½ |
| | | return () => import(`@/views/${view}`) |
| | | } |
| | | } |
| | | |
| | | export default permission |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | export default { |
| | | name: "Index", |
| | | data() { |
| | |
| | | },
|
| | | // æå¼å è½½å±
|
| | | openLoading() {
|
| | | this.$modal.loading("æ£å¨å è½½ç¼åçæ§æ°æ®ï¼è¯·ç¨åï¼");
|
| | | this.$modal.loading("æ£å¨å è½½ç¼åçæ§æ°æ®ï¼è¯·ç¨åï¼");
|
| | | },
|
| | | },
|
| | | };
|
| | |
| | | ref="menu" |
| | | node-key="id" |
| | | :check-strictly="!form.menuCheckStrictly" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | :props="defaultProps" |
| | | ></el-tree> |
| | | </el-form-item> |
| | |
| | | ref="dept" |
| | | node-key="id" |
| | | :check-strictly="!form.deptCheckStrictly" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | :props="defaultProps" |
| | | ></el-tree> |
| | | </el-form-item> |
| | |
| | | @echo off |
| | | |
| | | rem jar平级ç®å½ |
| | | rem jarƽ��Ŀ¼ |
| | | set AppName=ruoyi-admin.jar |
| | | |
| | | rem JVMåæ° |
| | | set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" |
| | | rem JVM���� |
| | | set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" |
| | | |
| | | |
| | | ECHO. |
| | | ECHO. [1] å¯å¨%AppName% |
| | | ECHO. [2] å
³é%AppName% |
| | | ECHO. [3] éå¯%AppName% |
| | | ECHO. [4] å¯å¨ç¶æ %AppName% |
| | | ECHO. [5] é åº |
| | | ECHO. |
| | | ECHO. |
| | | ECHO. [1] ����%AppName% |
| | | ECHO. [2] �ر�%AppName% |
| | | ECHO. [3] ����%AppName% |
| | | ECHO. [4] ����״̬ %AppName% |
| | | ECHO. [5] �� �� |
| | | ECHO. |
| | | |
| | | ECHO.请è¾å
¥éæ©é¡¹ç®çåºå·: |
| | | ECHO.������ѡ����Ŀ�����: |
| | | set /p ID= |
| | | IF "%id%"=="1" GOTO start |
| | | IF "%id%"=="2" GOTO stop |
| | | IF "%id%"=="3" GOTO restart |
| | | IF "%id%"=="1" GOTO start |
| | | IF "%id%"=="2" GOTO stop |
| | | IF "%id%"=="3" GOTO restart |
| | | IF "%id%"=="4" GOTO status |
| | | IF "%id%"=="5" EXIT |
| | | PAUSE |
| | | PAUSE |
| | | :start |
| | | for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( |
| | | set pid=%%a |
| | | set image_name=%%b |
| | | ) |
| | | if defined pid ( |
| | | echo %%is running |
| | | PAUSE |
| | | ) |
| | | echo %%is running |
| | | PAUSE |
| | | ) |
| | | |
| | | start javaw -jar %JAVA_OPTS% ruoyi-admin.jar |
| | | start javaw %JAVA_OPTS% -jar %AppName% |
| | | |
| | | echo startingâ¦â¦ |
| | | echo starting���� |
| | | echo Start %AppName% success... |
| | | goto:eof |
| | | |
| | | rem 彿°stopéè¿jpså½ä»¤æ¥æ¾pidå¹¶ç»æè¿ç¨ |
| | | rem ����stopͨ��jps�������pid���������� |
| | | :stop |
| | | for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( |
| | | set pid=%%a |
| | |
| | | if not defined pid (echo process %AppName% does not exists) else ( |
| | | echo prepare to kill %image_name% |
| | | echo start kill %pid% ... |
| | | rem æ ¹æ®è¿ç¨IDï¼killè¿ç¨ |
| | | rem ���ݽ���ID��kill���� |
| | | taskkill /f /pid %pid% |
| | | ) |
| | | goto:eof |
| | |
| | | if not defined pid (echo process %AppName% is dead ) else ( |
| | | echo %image_name% is running |
| | | ) |
| | | goto:eof |
| | | goto:eof |
| | |
| | | #!/bin/sh |
| | | # author ruoyi |
| | | # ./ry.sh start å¯å¨ |
| | | # ./ry.sh stop 忢 |
| | | # ./ry.sh restart éå¯ |
| | | # ./ry.sh status ç¶æ |
| | | # ./ry.sh start å¯å¨ stop 忢 restart éå¯ status ç¶æ |
| | | AppName=ruoyi-admin.jar |
| | | |
| | | # JVMåæ° |
| | | JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" |
| | | JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" |
| | | APP_HOME=`pwd` |
| | | LOG_PATH=$APP_HOME/logs/$AppName.log |
| | | |
| | |
| | | if [ x"$PID" != x"" ]; then |
| | | echo "$AppName is running..." |
| | | else |
| | | nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 & |
| | | nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 & |
| | | echo "Start $AppName success..." |
| | | fi |
| | | } |