Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue
Conflicts:
ruoyi-ui/src/api/system/dept.js
ruoyi-ui/src/utils/request.js
ruoyi-ui/src/views/monitor/job/index.vue
ruoyi-ui/src/views/monitor/logininfor/index.vue
ruoyi-ui/src/views/monitor/operlog/index.vue
ruoyi-ui/src/views/system/dept/index.vue
ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java
ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java
ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java
ruoyi/src/main/resources/application.yml
| | |
| | | ## å¹³å°ç®ä» |
| | | |
| | | ä¸ç´æ³å䏿¬¾åå°ç®¡çç³»ç»ï¼çäºå¾å¤ä¼ç§ç弿ºé¡¹ç®ä½æ¯åç°æ²¡æåéçãäºæ¯å©ç¨ç©ºé²ä¼æ¯æ¶é´å¼å§èªå·±åäºä¸å¥åå°ç³»ç»ã妿¤æäºè¥ä¾ã她å¯ä»¥ç¨äºææçWebåºç¨ç¨åºï¼å¦ç½ç«ç®¡çåå°ï¼ç½ç«ä¼åä¸å¿ï¼CMSï¼CRMï¼OAãææå端åå°ä»£ç å°è£
è¿åååç²¾ç®æä¸æï¼åºéæ¦çä½ãåæ¶æ¯æç§»å¨å®¢æ·ç«¯è®¿é®ãç³»ç»ä¼éç»æ´æ°ä¸äºå®ç¨åè½ã |
| | | |
| | | æ§å«ç·ï¼è¥ä¾æ¯ç»è¿æ²¡æåºç女å¿åçååï¼å¯æï¼ä½ è¥ä¸ç¦»ä¸å¼ï¼æå¿
çæ»ç¸ä¾ï¼ |
| | | |
| | | åèåå°æ¨¡æ¿[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) |
| | | |
| | | > é¿éäºæå¡å¨89å
/å¹´ï¼å12å¹´æ«ç¹æ ï¼ç款产åéæ¶1æ ï¼[ç¹æè¿å
¥](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link) |
| | | |
| | | > å¦éä¸å离åºç¨ï¼è¯·ç§»æ¥ [RuoYi](https://gitee.com/y_project/RuoYi) `(ä¿æåæ¥æ´æ°)`ï¼å¦éå
¶ä»çæ¬ï¼è¯·ç§»æ¥ [é¡¹ç®æ©å±](http://doc.ruoyi.vip/ruoyi/document/xmkz.html) `(ä¸å®æ¶æ´æ°)` |
| | | |
| | | > é¿éäºéç¨äºäº§å1888伿 å¸ ï¼[ç¹æé¢å](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) è
¾è®¯äºéç¨äºäº§å2860伿 å¸ ï¼[ç¹æé¢å](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) `(ä»
éæ°ç¨æ·)` |
| | | |
| | | > é¿éäºHiæ¼è´ ééçæ¬¾ ä½è³199å
/å¹´ [ç¹æè¿å
¥](https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof) `(ä»
éæ°ç¨æ·)` |
| | | * å端éç¨VueãElement UIãVue-Element-Adminã |
| | | * å端éç¨Spring BootãSpring SecurityãRedis & Jwtã |
| | | * æé认è¯ä½¿ç¨Jwtï¼æ¯æå¤ç»ç«¯è®¤è¯ç³»ç»ã |
| | | * æ¯æå è½½å¨ææéèåï¼å¤æ¹å¼è½»æ¾æéæ§å¶ã |
| | | * 髿çå¼åï¼ä½¿ç¨ä»£ç çæå¨å¯ä»¥ä¸é®çæåå端代ç ã |
| | | * ä¸åç¦»çæ¬ï¼è¯·ç§»æ¥[RuoYi](https://gitee.com/y_project/RuoYi)ï¼å¾®æå¡çæ¬ï¼è¯·ç§»æ¥[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud) |
| | | * é¿éäºä¼æ å¸ï¼[ç¹æè¿å
¥](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link)ï¼è
¾è®¯äºä¼æ å¸ï¼[ç¹æé¢å](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) |
| | | |
| | | ## å
ç½®åè½ |
| | | |
| | |
| | | 15. æå¡çæ§ï¼çè§å½åç³»ç»CPUãå
åãç£çãå æ çç¸å
³ä¿¡æ¯ã |
| | | 16. å¨çº¿æå»ºå¨ï¼æå¨è¡¨åå
ç´ çæç¸åºçHTML代ç ã |
| | | 17. è¿æ¥æ± çè§ï¼çè§å½åç³»ç»æ°æ®åºè¿æ¥æ± ç¶æï¼å¯è¿è¡åæSQLæ¾åºç³»ç»æ§è½ç¶é¢ã |
| | | |
| | | ## å¨çº¿ä½éª |
| | | > admin/admin123 |
| | | > ééç»ç»æ¶å°ä¸äºæèµï¼ä¸ºäºæ´å¥½çä½éªå·²ç¨äºæ¼ç¤ºæå¡å¨å级ã谢谢åä½å°ä¼ä¼´ã |
| | | |
| | | - admin/admin123 |
| | | - ééç»ç»æ¶å°ä¸äºæèµï¼ä¸ºäºæ´å¥½çä½éªå·²ç¨äºæ¼ç¤ºæå¡å¨å级ã谢谢åä½å°ä¼ä¼´ã |
| | | |
| | | æ¼ç¤ºå°åï¼http://vue.ruoyi.vip |
| | | |
| | | ææ¡£å°åï¼http://doc.ruoyi.vip |
| | | |
| | | ## æ¼ç¤ºå¾ |
| | |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ |
| | | export function listDeptExcludeChild(deptId) { |
| | | return request({ |
| | | url: '/system/dept/list/exclude/' + deptId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨è¯¦ç» |
| | | export function getDept(deptId) { |
| | | return request({ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | '401': '认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº', |
| | | '403': 'å½åæä½æ²¡ææé', |
| | | '404': '访é®èµæºä¸åå¨', |
| | | 'default': 'ç³»ç»æªç¥é误ï¼è¯·åé¦ç»ç®¡çå' |
| | | } |
| | |
| | | import { Notification, MessageBox, Message } from 'element-ui' |
| | | import store from '@/store' |
| | | import { getToken } from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | |
| | | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' |
| | | // å建axioså®ä¾ |
| | |
| | | timeout: 10000 |
| | | }) |
| | | // requestæ¦æªå¨ |
| | | service.interceptors.request.use( |
| | | config => { |
| | | if (getToken()) { |
| | | config.headers['Authorization'] = 'Bearer ' + getToken() // 让æ¯ä¸ªè¯·æ±æºå¸¦èªå®ä¹token è¯·æ ¹æ®å®é
æ
åµèªè¡ä¿®æ¹ |
| | | } |
| | | return config |
| | | }, |
| | | error => { |
| | | service.interceptors.request.use(config => { |
| | | // æ¯å¦éè¦è®¾ç½® token |
| | | const isToken = (config.headers || {}).isToken === false |
| | | if (getToken() && !isToken) { |
| | | config.headers['Authorization'] = 'Bearer ' + getToken() // 让æ¯ä¸ªè¯·æ±æºå¸¦èªå®ä¹token è¯·æ ¹æ®å®é
æ
åµèªè¡ä¿®æ¹ |
| | | } |
| | | return config |
| | | }, error => { |
| | | console.log(error) |
| | | Promise.reject(error) |
| | | } |
| | | ) |
| | | }) |
| | | |
| | | // ååºæ¦æªå¨ |
| | | service.interceptors.response.use(res => { |
| | | const code = res.data.code |
| | | // æªè®¾ç½®ç¶æç åé»è®¤æåç¶æ |
| | | const code = res.data.code || 200; |
| | | // è·åéè¯¯ä¿¡æ¯ |
| | | const message = errorCode[code] || res.data.msg || errorCode['default'] |
| | | if (code === 401) { |
| | | MessageBox.confirm( |
| | | 'ç»å½ç¶æå·²è¿æï¼æ¨å¯ä»¥ç»§ç»çå¨è¯¥é¡µé¢ï¼æè
éæ°ç»å½', |
| | |
| | | location.reload() // 为äºéæ°å®ä¾åvue-router对象 é¿å
bug |
| | | }) |
| | | }) |
| | | } else if (code === 500) { |
| | | Message({ |
| | | message: message, |
| | | type: 'error' |
| | | }) |
| | | return Promise.reject(new Error(message)) |
| | | } else if (code !== 200) { |
| | | Notification.error({ |
| | | title: res.data.msg |
| | | title: message |
| | | }) |
| | | return Promise.reject('error') |
| | | } else { |
| | |
| | | type: "warning" |
| | | }).then(function() { |
| | | return runJob(row.jobId, row.jobGroup); |
| | | }).then(function() { |
| | | }).then(() => { |
| | | this.msgSuccess("æ§è¡æå"); |
| | | }).catch(function() {}); |
| | | }, |
| | |
| | | <el-table-column label="访é®ç¼å·" align="center" prop="infoId" /> |
| | | <el-table-column label="ç¨æ·åç§°" align="center" prop="userName" /> |
| | | <el-table-column label="ç»å½å°å" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" /> |
| | | <el-table-column label="ç»å½ç¶æ" align="center" prop="status" :formatter="statusFormat" /> |
| | |
| | | <el-table-column label="è¯·æ±æ¹å¼" align="center" prop="requestMethod" /> |
| | | <el-table-column label="æä½äººå" align="center" prop="operName" /> |
| | | <el-table-column label="主æº" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½å°ç¹" align="center" prop="operLocation" /> |
| | | <el-table-column label="æä½å°ç¹" align="center" prop="operLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç¶æ" align="center" prop="status" :formatter="statusFormat" /> |
| | | <el-table-column label="æä½æ¥æ" align="center" prop="operTime" width="180"> |
| | | <template slot-scope="scope"> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { listDept, getDept, delDept, addDept, updateDept } from "@/api/system/dept"; |
| | | import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"; |
| | | import Treeselect from "@riophae/vue-treeselect"; |
| | | import "@riophae/vue-treeselect/dist/vue-treeselect.css"; |
| | | |
| | |
| | | children: node.children |
| | | }; |
| | | }, |
| | | /** æ¥è¯¢é¨é¨ä¸ææ ç»æ */ |
| | | getTreeselect() { |
| | | listDept().then(response => { |
| | | this.deptOptions = this.handleTree(response.data, "deptId"); |
| | | }); |
| | | }, |
| | | // åå
¸ç¶æåå
¸ç¿»è¯ |
| | | statusFormat(row, column) { |
| | | return this.selectDictLabel(this.statusOptions, row.status); |
| | |
| | | /** æ°å¢æé®æä½ */ |
| | | handleAdd(row) { |
| | | this.reset(); |
| | | this.getTreeselect(); |
| | | if (row != undefined) { |
| | | this.form.parentId = row.deptId; |
| | | } |
| | | this.open = true; |
| | | this.title = "æ·»å é¨é¨"; |
| | | listDept().then(response => { |
| | | this.deptOptions = this.handleTree(response.data, "deptId"); |
| | | }); |
| | | }, |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | handleUpdate(row) { |
| | | this.reset(); |
| | | this.getTreeselect(); |
| | | getDept(row.deptId).then(response => { |
| | | this.form = response.data; |
| | | this.open = true; |
| | | this.title = "ä¿®æ¹é¨é¨"; |
| | | }); |
| | | listDeptExcludeChild(row.deptId).then(response => { |
| | | this.deptOptions = this.handleTree(response.data, "deptId"); |
| | | }); |
| | | }, |
| | | /** æäº¤æé® */ |
| | | submitForm: function() { |
| | |
| | | package com.ruoyi.framework.aspectj; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.Objects; |
| | | import org.aspectj.lang.ProceedingJoinPoint; |
| | | import org.aspectj.lang.annotation.Around; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.core.annotation.AnnotationUtils; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.springframework.stereotype.Component; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | |
| | | public DataSource getDataSource(ProceedingJoinPoint point) |
| | | { |
| | | MethodSignature signature = (MethodSignature) point.getSignature(); |
| | | Class<? extends Object> targetClass = point.getTarget().getClass(); |
| | | DataSource targetDataSource = targetClass.getAnnotation(DataSource.class); |
| | | if (StringUtils.isNotNull(targetDataSource)) |
| | | DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); |
| | | if (Objects.nonNull(dataSource)) |
| | | { |
| | | return targetDataSource; |
| | | } |
| | | else |
| | | { |
| | | Method method = signature.getMethod(); |
| | | DataSource dataSource = method.getAnnotation(DataSource.class); |
| | | return dataSource; |
| | | } |
| | | |
| | | return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * èªå®ä¹å¤æ°æ®æºåæ¢æ³¨è§£ |
| | | * |
| | | * |
| | | * ä¼å
级ï¼å
æ¹æ³ï¼åç±»ï¼å¦ææ¹æ³è¦çäºç±»ä¸çæ°æ®æºç±»åï¼ä»¥æ¹æ³ç为åï¼å¦å以类ä¸ç为å |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Target({ ElementType.METHOD, ElementType.TYPE }) |
| | |
| | | @Autowired |
| | | private RuoYiConfig ruoyiConfig; |
| | | |
| | | /** Swaggerå¼å
³é
ç½® */ |
| | | @Value("${swagger.enable}") |
| | | private boolean swaggerEnable; |
| | | /** æ¯å¦å¼å¯swagger */ |
| | | @Value("${swagger.enabled}") |
| | | private boolean enabled; |
| | | |
| | | /** 设置请æ±çç»ä¸åç¼ */ |
| | | @Value("${swagger.pathMapping}") |
| | | private String pathMapping; |
| | | |
| | | /** |
| | | * å建API |
| | |
| | | { |
| | | return new Docket(DocumentationType.SWAGGER_2) |
| | | // æ¯å¦å¯ç¨Swagger |
| | | .enable(swaggerEnable) |
| | | .pathMapping("/dev-api") |
| | | .enable(enabled) |
| | | // ç¨æ¥å建该APIçåºæ¬ä¿¡æ¯ï¼å±ç¤ºå¨ææ¡£ç页é¢ä¸ï¼èªå®ä¹å±ç¤ºçä¿¡æ¯ï¼ |
| | | .apiInfo(apiInfo()) |
| | | // 设置åªäºæ¥å£æ´é²ç»Swaggerå±ç¤º |
| | |
| | | // æ«æææææ³¨è§£çapiï¼ç¨è¿ç§æ¹å¼æ´çµæ´» |
| | | .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) |
| | | // æ«ææå®å
ä¸çswagger注解 |
| | | //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) |
| | | // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) |
| | | // æ«æææ .apis(RequestHandlerSelectors.any()) |
| | | .paths(PathSelectors.any()) |
| | | .build() |
| | | /* 设置å®å
¨æ¨¡å¼ï¼swaggerå¯ä»¥è®¾ç½®è®¿é®token */ |
| | | .securitySchemes(securitySchemes()) |
| | | .securityContexts(securityContexts()); |
| | | .securityContexts(securityContexts()) |
| | | .pathMapping(pathMapping); |
| | | } |
| | | |
| | | /** |
| | |
| | | apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); |
| | | return apiKeyList; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * å®å
¨ä¸ä¸æ |
| | | */ |
| | |
| | | .build()); |
| | | return securityContexts; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * é»è®¤çå®å
¨ä¸å¼ç¨ |
| | | */ |
| | |
| | | { |
| | | TableDataInfo rspData = new TableDataInfo(); |
| | | rspData.setCode(HttpStatus.SUCCESS); |
| | | rspData.setMsg("æ¥è¯¢æå"); |
| | | rspData.setRows(list); |
| | | rspData.setTotal(new PageInfo(list).getTotal()); |
| | | return rspData; |
| | |
| | | private int code; |
| | | |
| | | /** æ¶æ¯å
容 */ |
| | | private int msg; |
| | | private String msg; |
| | | |
| | | /** |
| | | * è¡¨æ ¼æ°æ®å¯¹è±¡ |
| | |
| | | this.code = code; |
| | | } |
| | | |
| | | public int getMsg() |
| | | public String getMsg() |
| | | { |
| | | return msg; |
| | | } |
| | | |
| | | public void setMsg(int msg) |
| | | public void setMsg(String msg) |
| | | { |
| | | this.msg = msg; |
| | | } |
| | |
| | | return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); |
| | | } |
| | | |
| | | /** |
| | | * æ¸
ç©ºå®æ¶ä»»å¡è°åº¦æ¥å¿ |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('monitor:job:remove')") |
| | | @Log(title = "è°åº¦æ¥å¿", businessType = BusinessType.CLEAN) |
| | | @DeleteMapping("/clean") |
| | |
| | | package com.ruoyi.project.system.controller; |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import org.apache.commons.lang3.ArrayUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('system:dept:list')") |
| | | @GetMapping("/list/exclude/{deptId}") |
| | | public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) |
| | | { |
| | | List<SysDept> depts = deptService.selectDeptList(new SysDept()); |
| | | Iterator<SysDept> it = depts.iterator(); |
| | | while (it.hasNext()) |
| | | { |
| | | SysDept d = (SysDept) it.next(); |
| | | if (d.getDeptId().intValue() == deptId |
| | | || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")) |
| | | { |
| | | it.remove(); |
| | | } |
| | | } |
| | | return AjaxResult.success(depts); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®é¨é¨ç¼å·è·å详ç»ä¿¡æ¯ |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('system:dept:query')") |
| | |
| | | * @param deptId é¨é¨ID |
| | | * @return åé¨é¨æ° |
| | | */ |
| | | @Override |
| | | public int selectNormalChildrenDeptById(Long deptId) |
| | | { |
| | | return deptMapper.selectNormalChildrenDeptById(deptId); |
| | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | /** |
| | | * å é¤ä»£ç çæ |
| | | */ |
| | | @PreAuthorize("@ss.hasPermi('tool:gen:remove')") |
| | | @Log(title = "代ç çæ", businessType = BusinessType.DELETE) |
| | | @DeleteMapping("/{tableIds}") |
| | |
| | | |
| | | # Swaggeré
ç½® |
| | | swagger: |
| | | enable: true |
| | | # æ¯å¦å¼å¯swagger |
| | | enabled: true |
| | | # 请æ±åç¼ |
| | | pathMapping: /dev-api |
| | | |
| | | # 鲿¢XSSæ»å» |
| | | xss: |