若依Ruoyi-Vue学习笔记

0. 前言

Ruoyi前后端分离版:SpringBoot + Vue

官网:https://ruoyi.vip

参考视频:【开源项目学习】若依前后端分离版,通俗易懂,快速上手

目标

学习开源项目的目标:

  1. 用,减少自己的工作量
  2. 学习优秀开源项目的底层编程思想、设计思路,提升自己的编程能力

使用、学习开源项目的流程:

  1. 下载并运行
  2. 看懂业务流程
  3. 进行二次开发

功能的基本流程

  1. 加载Vue页面
  2. 请求后端

环境要求

  1. JDK1.8+
  2. MySQL8+
  3. Redis
  4. Maven
  5. Vue

1. 运行Ruoyi

1.1 下载

从Gitee官网复制url在IDEA中打开(后端),注意前端Vue项目ruoyi-ui需要额外使用一个idea打开。

1.2 配置数据库

表:直接执行/sql下的两个sql文件,在本地创建表

1M367v

数据源:修改配置文件中数据源配置

KMH4ro

1.3 配置Redis

使用Docker启动Redis

修改Redis配置

BgGIRe

Q0VaOV

1.4 日志

需要在ruoyi-admin/src/main/resources/logback.xml中修改日志存放位置:

v74wUN

1.5 启动后端

启动admin中的springboot启动类

(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  
 .-------.       ____     __        
 |  _ _   \      \   \   /  /    
 | ( ' )  |       \  _. /  '       
 |(_ o _) /        _( )_ .'         
 | (_,_).' __  ___(_ o _)'          
 |  |\ \  |  ||   |(_,_)'         
 |  | \ `'   /|   `-'  /           
 |  |  \    /  \      /           
 ''-'   `'-'    `-..-'    

iw0ge8

1.6 启动前端

根据ruoyi-ui项目中的README.md文件进行配置安装依赖,然后启动

# 克隆项目
git clone https://gitee.com/y_project/RuoYi-Vue

# 进入项目目录
cd ruoyi-ui

# 安装依赖
npm install

# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com

# 启动服务
npm run dev

2. 登陆功能

2.1 验证码

基本思路

简而言之:前端让后端出一道算术题,后端把题目告诉前端,并把答案放入后端的Redis中,前端计算完结果后去后端的Redis中比对答案。

每次需要登录时,会在后端自动生成验证码,如“1+1=?@2”,验证码“1+1=?”会被转成图片传到前端登陆页面,答案“2”会被存储进Redis中(@是用于分割问题和答案的标记符号)。当前端输入完账号密码和验证码后,系统会拿验证码“2”和Redis中的答案“2”进行比较,成功则再验证账号密码。Redis中的key值会被传到前端,如果有多人登陆,每个客户端可根据自己的key值查询redis中的value值(答案)。

如果通过Docker启动的Redis,可通过交互模式进入Redis容器,然后进入Redis客户端查看验证码答案。

YLhnzM

# 通过交互模式进入Redis容器
docker exec -it 6ce bash

# 进入Redis
redis-cli

# 查看所有key
keys *

# 查看验证码答案
127.0.0.1:6379> get captcha_codes:aecd3ba23ab94614b2a7840e2625107c
"\"35\""

XUOJzC

前端实现

请求的封装

验证码的代码实现在ruoyi-ui/src/views/login.vue中。

基本流程概括:打开登陆页面,向后端请求验证码图片和一个uuid(Redis的key)

nzypT0

前端Vue和后端Springboot交互时通常使用axios(ajax),而这里看不到axios的调用是因为进行了多次封装。如果再深入追溯,可进入getCodeImg()方法,然后发现还有封装:

eF0FX6

进入login.js找到getCodeImg(),发现了ajax的基本写法:url、请求类型、超时时间,注意至此还是在request封装中,依旧没有看到axios。

// 获取验证码
export function getCodeImg() {
   
  return request({
   
    url: '/captchaImage',
    headers: {
   
      isToken: false
    },
    method: 'get',
    timeout: 20000
  })
}

接着进入ruoyi-ui/src/utils/request.js,找到axios:

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
   
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})

其中VUE_APP_BASE_API定义在了配置文件.env.development中:

# 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'

这样任何请求都添加前缀’/dev-api’。

统一前缀是为了区分开发环境和生产环境。

反向代理
YVdP8f

此时注意一个点:Vue获取图片时,前端项目的端口是1024;后端项目的端口是8080。理论上对验证码的信息的请求应该是对后端发起请求,但是url中实际还是对前端1024端口请求。

原因:反向代理,url在前端请求前端,进行代理,映射到后端,如此操作是为了解决跨域问题。跨域问题在后端的解决方式是Springboot添加一个配置类;前端的解决方式是反向代理。跨域问题在前端或者后端解决都可。

反向代理的配置在ruoyi-ui/vue.config.js中:

// webpack-dev-server 相关配置
  devServer: {
   
    host: '0.0.0.0',
    port: port,
    open: true,
    proxy: {
   
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
   
        target: `http://localhost:8080`,
        changeOrigin: true,
        pathRewrite: {
   
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    },
    disableHostCheck: true
  },

上面的pathRewrite里,会把前面的请求前缀替换为空,即’',再映射到后端的端口,即target。如此请求url从http://localhost:1024/dev-api/captchaImage变成了http://localhost:8080/captchaImage

后端实现

首先先定位到验证码功能的控制器,使用全局搜索(ctrl+shift+F)对admin项目搜索captchaImage,找到CaptchaController

		/**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    public AjaxResult getCode(HttpServletResponse response) throws IOException
    {
   
        // 最终需要返回给前端的ajax结果(封装版)
        AjaxResult ajax = AjaxResult.success();
        // 检查是否开启验证码
        boolean captchaOnOff = configService.selectCaptchaOnOff();
        ajax.put("captchaOnOff", captchaOnOff);
        if (!captchaOnOff)
        {
   
            return ajax;
        }

        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        // 拼接一个key,用于放入redis,如“captcha_codes:aecd3ba23ab94614b2a7840e2625107c”
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;

        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        String captchaType = RuoYiConfig.getCaptchaType();
        if ("math".equals(captchaType))
        {
   
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
   
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }
				// 将key和value存入redis,并设置缓存时间
        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
   
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
   
            return AjaxResult.error(e.getMessage());
        }

        ajax.put("uuid", uuid);
        ajax.put("img", Base64.encode(os.toByteArray()));
        return ajax;
    }

这个AjaxResult就是后端给前端返回的数据对象,通常称为VO或ResultVO或R(前端与后端交互时的统一数据模型)。

2.2 登陆

前端实现

登陆的前端实现和验证码一样,依旧使用了前端反向代理。

登陆功能的前端实现主要是由handleLogin()方法实现的。

handleLogin() {
   
      this.$refs.loginForm.validate(valid => {
   
        if (valid) {
   
          this.loading = true;
          if (this.loginForm.rememberMe) {
   
            Cookies.set("username", this.loginForm.username, {
    expires: 30 });
            Cookies.set("password", encrypt(this.loginForm.password), {
    expires: 30 });
            Cookies.set('rememberMe', this.loginForm.rememberMe, {
    expires: 30 });
          } else {
   
            Cookies.remove("username");
            Cookies.remove("password");
            Cookies.remove('rememberMe')</
  • 13
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值