若依Vue(若依前后端分离版)--01

(该文章整理于网络,仅用于学习记录,如有侵权,请联系删除)

介绍

RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。比较好用。

 快速了解  

   可参考官网。

环境部署

部署Java:多模块springboot ,通过宝塔创建springboot项目,再通过nginx反向代理即可。

部署Vue :打包部署。

war部署方式
ruoyi/pom.xml中的packaging修改为war,放入tomcat服务器webapps

SpringBoot去除内嵌Tomcat(PS:此步骤不重要,因为不排除也能在容器中部署war

项目介绍

若依Vue(若依前后端分离版)--01_第1张图片

1. 注解:需要通过反射来进行解析,参考excle注解。如果没解析器就没有任何意义。

 若依Vue(若依前后端分离版)--01_第2张图片

 2. ruoyi配置,通过该类读取yml配置文件:(

@Component
@ConfigurationProperties(prefix = "ruoyi")

3. constant常量

4. core: 基本的control 封装公共。

5.公共的实体:如loginbody.

6.封装的page.

7. redis操作的方法。

bbbub{},“aaa”====》

debug讲解

登陆讲解:

获取验证码,获取配置默认的验证码类型。

验证码存放到redis ,并且返回一个uuuid到前台用于验证(有时效),如果要使用,可以临时去取。

若依Vue(若依前后端分离版)--01_第3张图片

登陆逻辑梳理:

  public void validateCaptcha(String username, String code, String uuid)
    {
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
    }

登陆debug:

注意是封装的第三方组件。

模拟登陆若依

      通过API POST 或者 IDEA 的HTTP客户端发起请求,获取图片后 ,解析到答案。

     或者直接根据UUID去redis查询到结果:

  1. 获取验证码,得到UUID

  2. 向后端发送login请求,带上username,password,uuid,code(验证码)
    若依Vue(若依前后端分离版)--01_第4张图片

  3. 登录成功 获取TOKEN token解密后,并缓存到redis.
    若依Vue(若依前后端分离版)--01_第5张图片

     4. 发起其他请求,需要带上token进行认证。(两种均可)
    若依Vue(若依前后端分离版)--01_第6张图片

    若依Vue(若依前后端分离版)--01_第7张图片

后台手册

复习反射注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

内置的注解

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解是

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

作用在其他注解的注解(或者说 元注解)是:

  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。

  • @Documented - 标记这些注解是否包含在用户文档中。

  • @Target - 标记这个注解应该是哪种 Java 成员。

  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

从 Java 7 开始,额外添加了 3 个注解:

  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。

  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。


    获取并设置字段
    若依Vue(若依前后端分离版)--01_第8张图片


获取注解,比如或用户名称上的注解信息:(注意soutv的使用)

若依Vue(若依前后端分离版)--01_第9张图片

通过反射获取构造函数并实例化,获取成员方法并调用:如下:

 若依Vue(若依前后端分离版)--01_第10张图片

 

导入导出

  • 导入

  • 导出

分页

  • 前端实现

    // 一般在查询参数中定义分页变量
    queryParams: {
      pageNum: 1,
      pageSize: 10
    },
    ​
    // 页面添加分页组件,传入分页变量
    
    ​
    // 调用后台方法,传入参数 获取结果
    listUser(this.queryParams).then(response => {
        this.userList = response.rows;
        this.total = response.total;
      }
    );
  • 后端实现

    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(User user)
    {
        startPage();  // 此方法配合前端完成自动分页
        List list = userService.selectUserList(user);
        return getDataTable(list);
    }

上传下载

  • 上传

    drop table if exists sys_file_info;
    create table sys_file_info (
      file_id           int(11)          not null auto_increment       comment '文件id',
      file_name         varchar(50)      default ''                    comment '文件名称',
      file_path         varchar(255)     default ''                    comment '文件路径',
      primary key (file_id)
    ) engine=innodb auto_increment=1 default charset=utf8 comment = '文件信息表';
    
      选取文件
      上传到服务器
      
    只能上传jpg/png文件,且不超过500kb
    import { getToken } from "@/utils/auth";
    // 上传参数
    upload: {
      // 是否禁用上传
      isUploading: false,
      // 设置上传的请求头部
      headers: { Authorization: "Bearer " + getToken() },
      // 上传的地址
      url: process.env.VUE_APP_BASE_API + "/common/upload",
      // 上传的文件列表
      fileList: []
    },
    handleAdd() {
      ...
      this.upload.fileList = [];
    }
    ​
    handleUpdate(row) {
      ...
      this.upload.fileList = [{ name: this.form.fileName, url: this.form.filePath }];
    }
    // 文件提交处理
    submitUpload() {
      this.$refs.upload.submit();
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.isUploading = false;
      this.form.filePath = response.url;
      this.msgSuccess(response.msg);
    }
  • 下载

权限控制

  • 授之以渔。

  • 菜单-角色-用户-权限:

    ​
    1、xxx:xxx:list意思是能不能进入这个菜单进行对表增删改查,如果没有这个权限,前端不能进入菜单。
    2、xxx:xxx:add,remove,edit,query,意思是对前端的增删改查实现,往往会在前端的组件多加一个指令v-hasPermi(若依封装),如果没有这个权限,则组件将不会显示。
    ​
    3、后端执行某个controller若需要某个权限才能执行,则需要加上注解@PreAuthorize("@ss.hasPermi('system:user:list')")
    这个注解是若依+SpringSecurity框架共同实现的,它会先去执行方法ss.hasPermi('system:user:list')来判断是否能去执行相关的controller。
    4、在登录的时候,每次点击全局页面刷新的时候,都会执行getInfo方法去获取权限,这个权限会被vuex进行管理,从而方便在每一个界面判断是否展示某个组件/按钮。
    ​
  • 数据权限 ---留到后面再讲

    • 所谓数据权限,就是某个用户能查询哪些数据,来看一下若依给我们的解释:

      在实际开发中,需要设置用户只能查看哪些部门的数据,这种情况一般称为数据权限。 例如对于销售,财务的数据,它们是非常敏感的,因此要求对数据权限进行控制, 对于基于集团性的应用系统而言,就更多需要控制好各自公司的数据了。如设置只能看本公司、或者本部门的数据,对于特殊的领导,可能需要跨部门的数据, 因此程序不能硬编码那个领导该访问哪些数据,需要进行后台的权限和数据权限的控制。

事务管理

同SpringBoot,主要注解:@Transactional

异常处理

全局异常处理。通过一个全局异常处理类来进行处理GlobalExceptionHandler,这里面有两个重要的注解叫:@RestControllerAdvice,@ExceptionHandler(BaseException.class),用AOP的方法去增强方法,若发生异常将由ExceptionHandler注解的方法去处理这个异常,一般都是给前端返回一个错误的信息。这里BaseException.class就是指定某个异常,当这个异常发生,就会执行相关方法,例如:

/**
 * 基础异常
 */
@ExceptionHandler(BaseException.class)
public AjaxResult baseException(BaseException e)
{
    return AjaxResult.error(e.getMessage());
}

这个方法就会去处理发生了BaseException的控制器。

系统日志

  • 登录日志(需要线程池知识)

    • 登录日志带大家debug,在com/ruoyi/framework/web/service/SysLoginService.java这个类中的login方法中能找到相关的日志打印信息,例如:

                  AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
      ​
  • 控制器操作日志

    • AOP切面实现逻辑-debug。

    • 案例-自定义自己的操作日志。

数据权限

在实际开发中,需要设置用户只能查看哪些部门的数据,这种情况一般称为数据权限。 例如对于销售,财务的数据,它们是非常敏感的,因此要求对数据权限进行控制, 对于基于集团性的应用系统而言,就更多需要控制好各自公司的数据了。如设置只能看本公司、或者本部门的数据,对于特殊的领导,可能需要跨部门的数据, 因此程序不能硬编码那个领导该访问哪些数据,需要进行后台的权限和数据权限的控制。

针对角色设置的-去角色管理进行设置每一个角色的数据权限。

这个数据权限是AOP来实现的,主要注解是@Before(前置切入),通过对维护的param属性对应的HashMap中dataScope健存入一段SQL,这段SQL最终将加在查询语句的后边,mybatis中引用:${param.dataScope}。如何拼装的SQL在切面类(DataScopeAspect)中debug可以看到。

多数据源

前置知识 -> 如何实现多数据源?,实现多数据源的ThreadLocal类作用是什么呢?

主要通过继承AbstractRoutingDataSource类来实现。

ThreadLocal是存储线程独立局部变量用的,多个线程之间互不干扰。

前端手册

组件文档

项目扩展

视频教程

更新日志

其它

  • 常见问题

公共基础:

获取当前用户逻辑

  • 前端获取方法:var userName = this.$store.state.user.name; 那么 什么时候这里面有值的呢?

  • 后端获取方法

    • 方法一:工具类获取
      String userName = SecurityUtils.getUsername();
    • @Autowired
      private TokenService tokenService;
          
      LoginUser loginUser = tokenService.getLoginUser();
      // 获取当前的用户名称
      String userName = loginUser.getUsername();

前端获取路由逻辑

Excel导入逻辑 * 讲过

Excel导出逻辑 不讲

登录逻辑 * 讲过

鉴权(权限)逻辑 -- 讲了

sys_config表是个什么玩意?

对应前端参数设置的值。

redis存的一些值是什么玩意?怎么项目一启动就有值的?

值来自sys-config表

作业:

Excel导入,顺带导入角色,在模板中给用户以提示。

你可能感兴趣的:(#,ruoyi框架,java,spring,boot,restful)