疯狂的狮子li
2020-05-20 98941acd2aadf435058412b4abe61fb6437433e8
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
已修改17个文件
已添加1个文件
180 ■■■■■ 文件已修改
README.md 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/dept.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/errorCode.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/request.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/job/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/logininfor/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/operlog/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dept/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobLogController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi/src/main/resources/application.yml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -1,18 +1,12 @@
## å¹³å°ç®€ä»‹
一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的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)  
## å†…置功能
@@ -33,12 +27,13 @@
15. æœåŠ¡ç›‘æŽ§ï¼šç›‘è§†å½“å‰ç³»ç»ŸCPU、内存、磁盘、堆栈等相关信息。
16. åœ¨çº¿æž„建器:拖动表单元素生成相应的HTML代码。
17. è¿žæŽ¥æ± ç›‘视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
## åœ¨çº¿ä½“验
> admin/admin123
> é™†é™†ç»­ç»­æ”¶åˆ°ä¸€äº›æ‰“赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
- admin/admin123
- é™†é™†ç»­ç»­æ”¶åˆ°ä¸€äº›æ‰“赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址:http://vue.ruoyi.vip  
文档地址:http://doc.ruoyi.vip
## æ¼”示图
ruoyi-ui/src/api/system/dept.js
@@ -9,6 +9,14 @@
  })
}
// æŸ¥è¯¢éƒ¨é—¨åˆ—表(排除节点)
export function listDeptExcludeChild(deptId) {
  return request({
    url: '/system/dept/list/exclude/' + deptId,
    method: 'get'
  })
}
// æŸ¥è¯¢éƒ¨é—¨è¯¦ç»†
export function getDept(deptId) {
  return request({
ruoyi-ui/src/utils/errorCode.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
export default {
  '401': '认证失败,无法访问系统资源',
  '403': '当前操作没有权限',
  '404': '访问资源不存在',
  'default': '系统未知错误,请反馈给管理员'
}
ruoyi-ui/src/utils/request.js
@@ -2,6 +2,7 @@
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实例
@@ -12,22 +13,24 @@
  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(
        '登录状态已过期,您可以继续留在该页面,或者重新登录',
@@ -42,9 +45,15 @@
          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 {
ruoyi-ui/src/views/monitor/job/index.vue
@@ -397,7 +397,7 @@
          type: "warning"
        }).then(function() {
          return runJob(row.jobId, row.jobGroup);
        }).then(function() {
        }).then(() => {
          this.msgSuccess("执行成功");
        }).catch(function() {});
    },
ruoyi-ui/src/views/monitor/logininfor/index.vue
@@ -91,7 +91,7 @@
      <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" />
ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -110,7 +110,7 @@
      <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">
ruoyi-ui/src/views/system/dept/index.vue
@@ -138,7 +138,7 @@
</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";
@@ -220,12 +220,6 @@
        children: node.children
      };
    },
    /** æŸ¥è¯¢éƒ¨é—¨ä¸‹æ‹‰æ ‘结构 */
    getTreeselect() {
      listDept().then(response => {
        this.deptOptions = this.handleTree(response.data, "deptId");
      });
    },
    // å­—典状态字典翻译
    statusFormat(row, column) {
      return this.selectDictLabel(this.statusOptions, row.status);
@@ -256,22 +250,26 @@
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    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() {
ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
@@ -1,6 +1,6 @@
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;
@@ -8,6 +8,7 @@
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;
@@ -60,17 +61,12 @@
    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);
    }
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java
@@ -10,7 +10,9 @@
/**
 * è‡ªå®šä¹‰å¤šæ•°æ®æºåˆ‡æ¢æ³¨è§£
 *
 *
 * ä¼˜å…ˆçº§ï¼šå…ˆæ–¹æ³•,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
 *
 * @author ruoyi
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -33,9 +33,13 @@
    @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
@@ -45,8 +49,7 @@
    {
        return new Docket(DocumentationType.SWAGGER_2)
                // æ˜¯å¦å¯ç”¨Swagger
                .enable(swaggerEnable)
                .pathMapping("/dev-api")
                .enable(enabled)
                // ç”¨æ¥åˆ›å»ºè¯¥API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // è®¾ç½®å“ªäº›æŽ¥å£æš´éœ²ç»™Swagger展示
@@ -54,13 +57,14 @@
                // æ‰«ææ‰€æœ‰æœ‰æ³¨è§£çš„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);
    }
    /**
@@ -72,7 +76,7 @@
        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
        return apiKeyList;
    }
    /**
     * å®‰å…¨ä¸Šä¸‹æ–‡
     */
@@ -86,7 +90,7 @@
                        .build());
        return securityContexts;
    }
    /**
     * é»˜è®¤çš„安全上引用
     */
ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java
@@ -67,6 +67,7 @@
    {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(new PageInfo(list).getTotal());
        return rspData;
ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java
@@ -22,7 +22,7 @@
    private int code;
    /** æ¶ˆæ¯å†…容 */
    private int msg;
    private String msg;
    /**
     * è¡¨æ ¼æ•°æ®å¯¹è±¡
@@ -73,12 +73,12 @@
        this.code = code;
    }
    public int getMsg()
    public String getMsg()
    {
        return msg;
    }
    public void setMsg(int msg)
    public void setMsg(String msg)
    {
        this.msg = msg;
    }
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysJobLogController.java
@@ -76,6 +76,9 @@
        return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
    }
    /**
     * æ¸…空定时任务调度日志
     */
    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
    @Log(title = "调度日志", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clean")
ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java
@@ -1,6 +1,8 @@
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;
@@ -46,6 +48,27 @@
    }
    /**
     * æŸ¥è¯¢éƒ¨é—¨åˆ—表(排除节点)
     */
    @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')")
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java
@@ -114,6 +114,7 @@
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
    @Override
    public int selectNormalChildrenDeptById(Long deptId)
    {
        return deptMapper.selectNormalChildrenDeptById(deptId);
ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java
@@ -124,6 +124,9 @@
        return AjaxResult.success();
    }
    /**
     * åˆ é™¤ä»£ç ç”Ÿæˆ
     */
    @PreAuthorize("@ss.hasPermi('tool:gen:remove')")
    @Log(title = "代码生成", businessType = BusinessType.DELETE)
    @DeleteMapping("/{tableIds}")
ruoyi/src/main/resources/application.yml
@@ -118,7 +118,10 @@
# Swagger配置
swagger:
  enable: true
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss: