精华内容
下载资源
问答
  • 若依前后端分离框架部署Linux服务器

    千次阅读 2020-07-10 17:59:52
    若依前后端分离框架部署Linux服务器 第一次使用若依框架进行部署Linux服务器,出现了很多的问题,也可能是自身对若依框架的不太熟悉导致接下来说一下我的部署 第一步:首先我们把我们的前端打包,如果不会打包的话...

    若依前后端分离框架部署Linux服务器

    第一次使用若依框架进行部署Linux服务器,出现了很多的问题,也可能是自身对若依框架的不太熟悉导致接下来说一下我的部署

    第一步:首先我们把我们的前端打包,如果不会打包的话若依官网有详细的说明----->若依前后端分离官网部署文档,打包完毕后找到dist文件夹,把dist文件夹上传到Linux中,下一步的nginx配置中需要这一条路径。
    第二步:Linux系统需要我们配置nginx,nginx中配置同一路径prod-api的统一前缀。1
    nginx的nginx.config配置如下

    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        
    	server {
    		listen 80; # 监听的端口
    		server_name 自己的服务器地址; # 域名或ip
    		
    		location / {	# 访问路径配置
    			root /usr/local/ruoyi/dist/;#若依的dist 根目录
    			try_files $uri $uri/ /index.html;
    			index index.html index.htm; # 默认首页
    		}		
    		location /prod-api/ {
    			proxy_set_header Host $http_host;
    			proxy_set_header X-Real-IP $remote_addr;
    			proxy_set_header REMOTE-HOST $remote_addr;
    			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    			proxy_pass http://localhost:8080/;
    		}
    	}
    }
    
    

    第三步:后台java代码打包
    我这里打的是jar包,上传到Linux系统,然后运行jar包

    nohup java -jar jar包名称 --server 端口号 >msg.log 2>&1 &
    

    这条命令是运行jar包,设定运行后的端口号,后台运行,日志打印到msg.log;
    第四步:我们现在测试一下链接是否可用
    在这里插入图片描述
    无法访问:但是发现在自己本地本地却能直接部署并且进行访问
    看一下我们的url是prod-api,自己本地运行url是dev-api,这两个prod-api是正式部署后的,dev-api是自己本地测试的,应该是没什么问题才对,于是进行了百度,查到了之前有同样的问题,但是解决方法没有,只有若依作者大佬写的是缺token
    在这里插入图片描述
    这就有点难受,现在是登录都登陆不上去,然后用postman进行了无数次的测试,发现问题在prod-api上面,java后台接收的url如果直接是login的话能跑通,但是如果是prod-api/login的话就不行,于是乎改后台的前缀,但是偶然间发现了一个参数,在我们的application.yml里面有个参数context-path,里面可以设置一级前缀,那么直接给这个参数赋值prod-api,就解决了,然后重新把控制台进行打包,部署,发现我们跑通了


    1. prod-api是部署后的统一前缀,部署服务器之前在本地测试的话是dev-api ↩︎

    展开全文
  • 文章目录一、本地准备1. 克隆项目到本地2. 前端项目3. 后端项目4. nginx配置文件二、Centos7 环境准备2.1. 安装mysql并启动2.2. 安装redis并启动2.3. 安装nginx 和配置nginx.conf文件三、测试验证3.1....
  • 上一篇写了下若依前后端分离框架中前端至弹出登陆界面的过程,本片来详细了解下登录的整个过程。     后端包含ruoyi-admin,ruoyi-common,ruoyi-framework等多个模块,ruoyi-admin为启动模块。...

        上一篇写了下若依前后端分离框架中前端至弹出登陆界面的过程,本片来详细了解下登录的整个过程。
        后端包含ruoyi-admin,ruoyi-common,ruoyi-framework等多个模块,ruoyi-admin为启动模块。先看一下ruoyi-admin/src/main/application.yml配置文件。

    # 开发环境配置
    server:
      # 服务器的HTTP端口,默认为8080
      port: 8080
    

        指定了服务端启动的端口8080。我们运行ruoyi-admin/src/main/java/com/ruoyi/
    RuoYiApplication.java即可启动后端,监听8080端口。
        我们回到前端的登录界面。 views/login.vue

    <template>
      <div class="login">
        <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
          <h3 class="title">若依后台管理系统</h3>
          <el-form-item prop="username">
            <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
              <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="loginForm.password"
              type="password"
              auto-complete="off"
              placeholder="密码"
              @keyup.enter.native="handleLogin"
            >
              <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
            </el-input>
          </el-form-item>
          <el-form-item prop="code">
            <el-input
              v-model="loginForm.code"
              auto-complete="off"
              placeholder="验证码"
              style="width: 63%"
              @keyup.enter.native="handleLogin"
            >
              <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
            </el-input>
            <div class="login-code">
              <img :src="codeUrl" @click="getCode" class="login-code-img"/>
            </div>
          </el-form-item>
          <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
          <el-form-item style="width:100%;">
            <el-button
              :loading="loading"
              size="medium"
              type="primary"
              style="width:100%;"
              @click.native.prevent="handleLogin"
            >
              <span v-if="!loading">登 录</span>
              <span v-else>登 录 中...</span>
            </el-button>
          </el-form-item>
        </el-form>
        <!--  底部  -->
        <div class="el-login-footer">
          <span>Copyright © 2018-2020 ruoyi.vip All Rights Reserved.</span>
        </div>
      </div>
    </template>
    
    <script>
    import { getCodeImg } from "@/api/login";
    import Cookies from "js-cookie";
    import { encrypt, decrypt } from '@/utils/jsencrypt'
    
    export default {
      name: "Login",
      data() {
        return {
          codeUrl: "",
          cookiePassword: "",
          loginForm: {
            username: "admin",
            password: "admin123",
            rememberMe: false,
            code: "",
            uuid: ""
          },
          loginRules: {
            username: [
              { required: true, trigger: "blur", message: "用户名不能为空" }
            ],
            password: [
              { required: true, trigger: "blur", message: "密码不能为空" }
            ],
            code: [{ required: true, trigger: "change", message: "验证码不能为空" }]
          },
          loading: false,
          redirect: undefined
        };
      },
      watch: {
        $route: {
          handler: function(route) {
            this.redirect = route.query && route.query.redirect;
          },
          immediate: true
        }
      },
      created() {
        this.getCode();
        this.getCookie();
      },
      methods: {
        getCode() {
          getCodeImg().then(res => {
            this.codeUrl = "data:image/gif;base64," + res.img;
            this.loginForm.uuid = res.uuid;
          });
        },
        getCookie() {
          const username = Cookies.get("username");
          const password = Cookies.get("password");
          const rememberMe = Cookies.get('rememberMe')
          this.loginForm = {
            username: username === undefined ? this.loginForm.username : username,
            password: password === undefined ? this.loginForm.password : decrypt(password),
            rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
          };
        },
        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');
              }
              this.$store
                .dispatch("Login", this.loginForm)
                .then(() => {
                  this.$router.push({ path: this.redirect || "/" });
                })
                .catch(() => {
                  this.loading = false;
                  this.getCode();
                });
            }
          });
        }
      }
    };
    </script>
    

        页面加载前,created()调用this.getCode()和this.getCookie()获取验证码和cookie。这里不详细说明。我们重点关注下handleLogin登录函数。this.$refs.loginForm.validate判断用户名、密码和验证码的合法性。this.loginForm.rememberMe判断是否选择了记住密码。如果记住密码,我们把用户名密码存进cookie,下次跳到登录界面就不需要输用户名密码。如果不选择记住密码,将清空cookie,下次跳到登录界面需要手动输入用户名和密码。
        this.$store.dispatch(“Login”, this.loginForm),这里是我们最需要关注的地方。调用store里的Login对应的函数,把loginForm作为参数。我们跳到src/store/modules/user.js。

    import { login, logout, getInfo } from '@/api/login'
    ......
    actions: {
        // 登录
        Login({ commit }, userInfo) {
          const username = userInfo.username.trim()
          const password = userInfo.password
          const code = userInfo.code
          const uuid = userInfo.uuid
          return new Promise((resolve, reject) => {
            login(username, password, code, uuid).then(res => {
              setToken(res.token)
              commit('SET_TOKEN', res.token)
              resolve()
            }).catch(error => {
              reject(error)
            })
          })
        },
        ......
     }
    

        这里新建了一个Promise,调用了login函数,login函数是从@/api/login引入的。我们再跳到src/api/login.js看一下这个函数:

    // 登录方法
    export function login(username, password, code, uuid) {
      const data = {
        username,
        password,
        code,
        uuid
      }
      return request({
        url: '/login',
        method: 'post',
        data: data
      })
    }
    

        这里构建了一个ajax的POST请求,url为/login,data为用户名、密码、验证码的结构数据。我们再简单看一下request对应的src/utils/request.js。

    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
    })
    // request拦截器
    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)
    })
    

        我们看到请求的地址是process.env.VUE_APP_BASE_API, 这是怎么访问到后端的的呢?我们回头看一下vue.config.js文件

    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
      },
    

        这里做了一个代理,把process.env.VUE_APP_BASE_API地址映射成了http://localhost:8080。所以我们login最终访问后端的地址就变为http://localhost:8080/login。
        现在看一下后端接收这个请求的代码。ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java。

    /**
         * 登录方法
         * 
         * @param loginBody 登录信息
         * @return 结果
         */
        @PostMapping("/login")
        public AjaxResult login(@RequestBody LoginBody loginBody)
        {
            AjaxResult ajax = AjaxResult.success();
            // 生成令牌
            String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                    loginBody.getUuid());
            ajax.put(Constants.TOKEN, token);
            return ajax;
        }
    

        接收到/login的POST请求后,调用loginService.login方法进行验证,并生成token返回给客户端。接下来,看一下loginService.login方法。

     /**
         * 登录验证
         * 
         * @param username 用户名
         * @param password 密码
         * @param code 验证码
         * @param uuid 唯一标识
         * @return 结果
         */
        public String login(String username, String password, String code, String uuid)
        {
            ......
                // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
                authentication = authenticationManager
                        .authenticate(new UsernamePasswordAuthenticationToken(username, password));
            ......
            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
            // 生成token
            return tokenService.createToken(loginUser);
        }
    

        这里牵扯到Spring Security 的知识,我们看一下Spring Security的配置ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java。

    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter
    { /**
         * 身份认证接口
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception
        {
            auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
        }
    }
    

        这里设置了userDetailService。UserDetailsServiceImpl实现了UserDetailService接口,实现了loadUserByUsername方法。我们再看一下UserDetailsServiceImpl.loadUserByUsername的实现:

    @Service
    public class UserDetailsServiceImpl implements UserDetailsService
    {
    @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
        {
            SysUser user = userService.selectUserByUserName(username);
            if (StringUtils.isNull(user))
            {
                log.info("登录用户:{} 不存在.", username);
                throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
            }
            else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
            {
                log.info("登录用户:{} 已被删除.", username);
                throw new BaseException("对不起,您的账号:" + username + " 已被删除");
            }
            else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
            {
                log.info("登录用户:{} 已被停用.", username);
                throw new BaseException("对不起,您的账号:" + username + " 已停用");
            }
    
            return createLoginUser(user);
        }
     }
    

        就是根据用户名去数据库查询用户信息并返回。然后 再调用Spring Security内部的认证代码进行认证。

    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
            if (authentication.getCredentials() == null) {
                this.logger.debug("Authentication failed: no credentials provided");
                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
            } else {
                String presentedPassword = authentication.getCredentials().toString();
                if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
                    this.logger.debug("Authentication failed: password does not match stored value");
                    throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
                }
            }
        }
    

    就是比较根据用户名获取到的用户的密码和认证信息参数中的密码进行比较。更为详细的过程,这里引用了一位大神的文章,介绍的很详细。
    https://blog.csdn.net/yuanlaijike/article/details/84703690
    认证完成后,根据用户的信息,构建token,进行返回。前端收到返回后,存储token,并跳转网页。this.$router.push({ path: this.redirect || “/” });
    在这里插入图片描述
        大体的登陆过程就是这样子。
        上一章,若依前后端分离框架学习-1:前端引入
        下一章,若依前后端分离框架学习-3:获取菜单

    展开全文
  • 最近在使用若依前后端分离框架,这里记录下自己的学习过程。主要是为了督促自己的学习,巩固自己对框架的理解。这里也提供下官方的介绍文档地址,毕竟我自己写的和人家的比就是个渣渣。 该项目用到的主要技术,前端...

        最近在使用若依前后端分离框架源码地址,这里记录下自己的学习过程。主要是为了督促自己的学习,巩固自己对框架的理解。这里也提供下官方的介绍文档地址,毕竟我自己写的和人家的比就是个渣渣。
        该项目用到的主要技术,前端:vue+element,后端springboot。
        前端目录为ruoyi-ui,为单页面模式,只有一个html文件public/index.html。vue-cli3之后为public/index.html, vue-cli2版本的是根目录下的index.html。主要代码如下:

        <div id="app">
    	    <div id="loader-wrapper">
    		    <div id="loader"></div>
    		    <div class="loader-section section-left"></div>
    		    <div class="loader-section section-right"></div>
    		    <div class="load_title">正在加载系统资源,请耐心等待</div>
            </div>
    	</div>
    

        我们重点关注id="app"这行代码,其他的都是引入css样式。这里的app用于关联src/main.js中的app。

    import App from './App'
    ......
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    })
    

        这里关联了src/App.vue文件。

    <template>
      <div id="app">
        <router-view />
      </div>
    </template>
    
    <script>
    export default  {
      name:  'App'
    }
    </script>
    

        在这个vue文件中,重点关注 router-view标签。该标签是vue的路由。读取src/router/index.js文件,根据用户请求的路径,跳转到相应的页面。可能用跳转页面不太合适,毕竟该项目前端理论上只有一个页面,应该是根据不同的请求路径,加载不同的内容。
    src/router/index.js内容如下:

    import Vue from 'vue'
    import Router from 'vue-router'
    
    Vue.use(Router)
    
    /* Layout */
    import Layout from '@/layout'
    
    /**
     * Note: 路由配置项
     *
     * hidden: true                   // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
     * alwaysShow: true               // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
     *                                // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
     *                                // 若你想不管路由下面的 children 声明的个数都显示你的根路由
     *                                // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
     * redirect: noRedirect           // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
     * name:'router-name'             // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
     * meta : {
        noCache: true                // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
        title: 'title'               // 设置该路由在侧边栏和面包屑中展示的名字
        icon: 'svg-name'             // 设置该路由的图标,对应路径src/assets/icons/svg
        breadcrumb: false            // 如果设置为false,则不会在breadcrumb面包屑中显示
      }
     */
    
    // 公共路由
    export const constantRoutes = [
      {
        path: '/redirect',
        component: Layout,
        hidden: true,
        children: [
          {
            path: '/redirect/:path(.*)',
            component: (resolve) => require(['@/views/redirect'], resolve)
          }
        ]
      },
      {
        path: '/login',
        component: (resolve) => require(['@/views/login'], resolve),
        hidden: true
      },
      {
        path: '/404',
        component: (resolve) => require(['@/views/error/404'], resolve),
        hidden: true
      },
      {
        path: '/401',
        component: (resolve) => require(['@/views/error/401'], resolve),
        hidden: true
      },
      {
        path: '',
        component: Layout,
        redirect: 'index',
        children: [
          {
            path: 'index',
            component: (resolve) => require(['@/views/index'], resolve),
            name: '首页',
            meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
          }
        ]
      },
    ......
    ]
    
    export default new Router({
      mode: 'history', // 去掉url中的#
      scrollBehavior: () => ({ y: 0 }),
      routes: constantRoutes
    })
    
    

        我们以/login为例,用户请求http://ip:port/login, 就会加载views/login.vue这个界面,显示登录界面。那么这个ip:port是怎么来的呢?这里我们关注下vue-config.js文件

    const port = process.env.port || process.env.npm_config_port || 80 // 端口
    
    // 这里只列一部分,具体配置参考文档
    module.exports = {
      ......
      devServer: {
        host: '0.0.0.0',
        port: port,
        ......
      }
    }
    

        自己电脑上跑这个程序,默认就可以是http://localhost:80。接下来,我们前端执行npm run dev把项目跑起来,看一下具体效果。效果如下图:
    在这里插入图片描述
        我们看到,输入地址之后,默认跳转到了登录界面,并且url为http://localhost:81/login?redirect=%2Findex。为什么端口号是81呢,我们配置的是80。是 vue-cli-service 内部依赖了一个叫 portfinder 的库,发现80端口被占用了,自动加1。我们回头看一下router/index.js根路径的路由。

    {
        path: '',
        component: Layout,
        redirect: 'index',
        children: [
          {
            path: 'index',
            component: (resolve) => require(['@/views/index'], resolve),
            name: '首页',
            meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
          }
        ]
      },
    

        根据这条路由,页面应该加载views/index.vue啊。为什么路径变成了/login,加载了views/login.vue呢?这是因为路由守卫,请看permission.js文件:

    const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
    
    router.beforeEach((to, from, next) => {
      NProgress.start()
      if (getToken()) {
        ......
      } else {
        // 没有token
        if (whiteList.indexOf(to.path) !== -1) {
          // 在免登录白名单,直接进入
          next()
        } else {
          next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
          NProgress.done()
        }
      }
    })
    

        这个文件是在src/main.js进行引入的。
        router.beforeEach就可以理解为每一个路由请求之前,先干点啥。因为我们还没有登录过,getToken肯定无法返回,“/”请求也不在白名单中,所以最后会走到next(/login?redirect=${to.fullPath}), 也就和我们的地址http://localhost:81/login?redirect=%2Findex对应起来了。这里的%2F是/的URL编码。这就是显示登录界面的整个流程啦。
        作为一个程序员,平常都是根据框架,添加新功能或者修改原来的代码。大部分时间都是复制、粘贴、修改,原理性的东西都不能深入的去理解。这样对于自己的成长很不利,我也是深受其害,因此决定厚着脸皮写个博客,只是为了督促自己。也希望大家多多指教。
        下一章,若依前后端分离框架学习-2:登录过程

    展开全文
  • 前面三章,介绍了下若依前后端分离框架的登录过程中前端和后端的代码流程。本章,我们学习下如何创建自己的业务模块。 第一步,右键后端项目名称,新建模块 第二步,选择Maven项目 第三步,填写项目名称 第四步,...

        前面三章,介绍了下若依前后端分离框架的登录过程中前端和后端的代码流程。本章,我们学习下如何创建自己的业务模块。
    第一步,右键后端项目名称,新建模块
    在这里插入图片描述
    第二步,选择Maven项目
    在这里插入图片描述
    第三步,填写项目名称
    在这里插入图片描述
    第四步,填写模块名称,这里默认为xxx,并且下面的路径都只是到…\RuoYi-Vue, 我们可以直接改成…\RuoyiVue\ruoyi-xxx,这样模块名称也会跟着改变。
    在这里插入图片描述
        然后我们修改ruoyi-xxx下的pom的xml添加描述和依赖。

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>ruoyi</artifactId>
            <groupId>com.ruoyi</groupId>
            <version>3.2.0</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>xxx</artifactId>
    
        <description>
            xxx测试模块
        </description>
    
        <dependencies>
    
            <!-- SpringBoot Web容器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-system</artifactId>
            </dependency>
    
        </dependencies>
    </project>
    

        因为框架需要我们这个模块,我们需要把这个模块添加到框架的pom.xml中。 根目录下的pom.xml

    	<dependencies>
    		......
            <!-- xxx测试模块 -->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-xxx</artifactId>
            </dependency>
    
        </dependencies>
        <modules>
            <module>ruoyi-admin</module>
            <module>ruoyi-framework</module>
            <module>ruoyi-system</module>
            <module>ruoyi-quartz</module>
            <module>ruoyi-generator</module>
            <module>ruoyi-common</module>
            <module>ruoyi-xxx</module>
        </modules>
    

        这个有可能自动给添加上了,如果没自动添加,需要手动添加。
        该项目的启动项是ruoyi-admin,所以ruoyi-admin下的pom.xml需要添加我们新建模块的依赖。

    	<dependencies>
    		......
            <!-- xxx测试模块 -->
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-xxx</artifactId>
            </dependency>
    
        </dependencies>
    

        到这里我们整个项目就已经添加完毕了。接下来我们创建个表,实现增删改查。
    在这里插入图片描述
        在系统管理->菜单管理,新增一个目录,内容如图
    在这里插入图片描述

        添加完之后,在测试项后新增菜单,这里添加了组件路径和权限标识,具体内容如图
    在这里插入图片描述
        添加完之后,刷新就可以看到左侧的测试目录啦
    在这里插入图片描述
        菜单生成之后,我们用该框架自带的功能去生成代码。系统工具->代码生成,点击导入选择我们要生成代码的表。导入之后进行配置,具体效果如图。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
        最后点击生成代码,可生成代码的压缩包,并自动下载。分别将代码拷贝到前后端对应的目录,代码可直接运行。具体效果如图。
    在这里插入图片描述
        这样从模块的创建,到代码的生成,最后界面的显示就都可以正常运行啦。
        上一章,若依前后端分离框架学习-3:获取菜单
        下一章,若依前后端分离框架学习-5:权限管理

    展开全文
  • 把自己个人网站的服务器部署像流水账这样写一遍也还是很有收获的,那就是很好的找出了自己不懂地方(苦笑),那些说不清楚的地方其实就是还没有真正弄懂的地方。因为部署服务器涉及的东西太多太杂,一时半会想弄清也不...
  • 若依(前端分离版本)系统测试接口使用方法 若依(前端分离版本)系统测试接口说明(项目源码地址:https://gitee.com/y_project/RuoYi-Vue) 1. 生成验证码 2、登录获取token信息 3、测试接口 1. 生成验证码 ...
  • 文章目录一. 问题背景二....前面玩过了本地电脑启动若依前后分离的项目,今天将他部署到生产环境上(Linux服务器上面) 二. 前期准备 可以先简单看看本地电脑启动若依前后分离的项目,有一个认知 Linux上面:
  • 若依前后端分离版本地搭建开发环境并运行项目的教程: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662 在此基础上,如果想在某页面上添加一个按钮,点击此按钮页面跳转到新的页面,并设置...
  • 若依前后端分离集成Mybatis-Plus

    千次阅读 2021-03-15 12:46:56
    MyBatis-Plus(opens new window)(简称 MP)是一个MyBatis(opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 特性: 无侵入:只做增强不做改变,引入它不会对现有...
  • RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成...
  • 若依前后端分离项目 Docker 部署

    千次阅读 2020-12-21 22:15:06
    一、环境准备 服务器 阿里云服务器 1核+2GB即可 软件 本次部署采用... 此时,我们只需运行生成的镜像即可 docker run -d -p 7777:7777 --name nflj-vue ruoyi-vue 至此,我们就完成了前后端分离 使用Docker部署若依项目
  • 若依前后端分离框架 前端学习

    千次阅读 2020-04-02 16:07:13
    npm install --registry=https://registry.npm.taobao.org # 本地开发 启动项目 npm run dev 打开浏览器,输入:http://localhost:80 (默认账户 admin/admin123) 能正确展示登录页面,并能成功登录,菜单及...
  • 若依前后端分离,去除验证码登录

    千次阅读 2021-01-26 23:04:03
    后端验证, 前端的验证,去掉就ok
  • 使用若依前后端分离版,,其默认的图标和标题等如下 如果想要修改为自己想要的标题和图标,实现类似下面的效果 注: 博客:https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取...
  • 一、关于若依 RuoYi是一款基于SpringBoot+Bootstrap的极速后台开发框架。 RuoYi 官网地址:http://ruoyi.vip RuoYi 在线文档:http://doc.ruoyi.vip RuoYi 源码下载:...二、前后端.
  • 1. 后端验证去掉验证码验证 2. 前端验证,删除掉 3. 启动
  • RuoYi-Vue是一款基于SpringBoot+Vue的前后端分离极速后台开发框架。 RuoYi 官网地址:http://ruoyi.vip RuoYi 在线文档:http://doc.ruoyi.vip RuoYi 源码下载:https://gitee.com/y_project/RuoYi-Vue RuoYi 在线...
  • 上一章自己创建了一个模块,我们注意到前端代码中对于按钮有v-hasPermi="[‘xxx:testxxx:add’]“这种代码。服务端有@PreAuthorize(”@ss.hasPermi(‘xxx:testxxx:add’... 上一章,若依前后端分离框架学习-4:创建模块
  • 我测试的原因是,浏览器保存了cookie之类的东西,记录了上一次登录的状态,但是因为角色不同,能看到的页面权限也不同,可能现在登录的用户角色权限看不到上一个用户退出登录之前没有关闭的页面,就会报404,这个...
  • 使用若依前后端分离版,怎样使用其代码生成实现对单表的增删改查导出的业务。 注: 博客:https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。 ...
  • controller: @PreAuthorize("@ss.hasPermi('system:role:list')") //和数据库中的menu中的字段有关系 @GetMapping("list") public TableDataInfo list(SysRole role){ startPage(); List<SysRole>...
  • IDEA如何导入若依项目以及Git的安装 首先,导入项目之前需要下载Git,下面我将把安装Git的详细教程给你们,按照我的步骤一步一步来吧!!! 安装环境:Windows10 64bit 下载 Git网址 :...
  • 文章目录 一、软件安装部署 1. 安装jdk 2. mysql8安装部署 3. redis安装 4. nginx 安装部署 5. 克隆项目 二、后端项目 2.1.... 效果图 下一篇:RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 多机版本)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 104,095
精华内容 41,638
关键字:

若依前后端分离