一、若依是什么?


若依(RuoYi)是一款基于JavaEE技术的企业级快速开发平台让Java开发者用少量代码,就能快速搭建和开发出各种管理系统工具。

让Java开发者用少量代码,就能快速搭建和开发出各种管理系统工具。

二、若依搭建

1.若依版本

2.后端搭建步骤

git克隆并初始化项目

代码地址:https://gitee.com/y_project/RuoYi-Vue

 

MySQL导入与配置 

修改yml配置文件 ,配置成自己的数据库信息

启动Redis

运行后端启动程序 

3.前端搭建步骤 

git克隆并初始化项目

cmd输入 git clone https://github.com/yangzongzhuan/RuoYi-Vue3

cmd输入 code ./RuoYi-Vue3使用VScode打开项目

安装依赖

vscode终端输入下面指令安装依赖.

yarn --registry=https://registry.npmmirror.com
 

运行程序

vscode终端输入 yarn dev 指令运行程序,运行成功会自动打开网页

用户名和验证码已经默认输入好了,点击登录即可 

4.入门案例 

目标:利用若依代码生成器,生成课程管理的前后端代码

1)准备sql脚本并导入数据库

导入课程管理sql脚本

2)配置代码生成信息

选择系统工具->代码生成->导入 

到这里我踩了若依的第一个坑! 点导入后并没有出现建过的表的信息,检查数据库配置用户名、库名、密码,没有错误,检查表是否创建失败,没有问题,但是还是没有显示表信息,最后发现是后端Vue更新到3.8.8,项目构建里前端Vue3版本是3.8.7,更新前端代码代码地址

vue3:https://​github.com/yangzongzhuan/RuoYi-Vue3

最终显示

点击确定,然后点击编辑

 

 选择第一项基本信息,这里可以编辑基本信息,包括表的描述信息,对应的实体类信息,实体类名称默认表名首字母改为大写

选择第二个页面,也是最重要的页面,它将决定最终生成的页面效果 

选择第三部分生成信息

点击提交 

3)下载代码并导入项目 

点击下载按钮

将下载的问价解压出来得到三个文件

 首先导入sql:复制路径导入sql脚本

然后完成前端页面的导入:将Vue文件夹里的内容粘贴到对应的文件夹

最后完成后端部分的导入:将main文件夹里的内容粘贴到对应的文件夹

最后重新启动后端程序,刷新页面,我们可以看到,系统工具下面已经存在课程管理的动态菜单了

测试查询和新增、修改、删除信息,没有问题

三、功能详解 

1.系统管理

1)权限设置

权限控制
RBAC(基于角色的访问控制)是一种广泛使用的访问控制模型,通过角色来分配和管理用户的菜单权限

创建课研人员角色,分配查看课程管理统计分析页面的权限。

创建用户小智,角色给定课研人员,刷新页面,实现

2)数据字典 

数据字典
若依内置的数据字典,用于维护系统中常见的静态数据。例如:性别、状态...

目标:将课程管理学科设置成字典信息

步骤:添加字典类型和数据,修改代码生成信息,下载代码并导入

这里遇到第二个坑,自动生成的代码下拉框缩的很小,在views/course/course的文件的el-select标签里加上宽度,这是发现下拉框能显示了,但是数据查不到,我们此次修改学科表tb_course里面的subject列的内容,换成对应数字,点commit提交。最后显示正常

3)其他功能 

2.系统监控

1)监控相关

2)定时任务

3.系统工具 

1)表单构建

2)代码生成

3)系统接口

若依集成Swagger,可以接口测试

四、项目结构

后端结构

admin模块

common模块

 framework模块

其他模块

 项目中的配置 

模块依赖关系 

前端结构 

表结构 

前端源码阅读 

生成代码的views下的vue代码:

两个标签:

<template>用来放展示前端界面的组件标签 

<script> 放编写业务的逻辑代码

<template>标签:

搜索栏区域:

用到了el-form表单,里面有很多属性 ":model"是用来做双向绑定的,将前端文本框输入的条件封装给响应式对象"queryParams","v-show=showSearch"是用来控制搜索栏是显示还是隐藏,前端有个小放大镜的图表,点一下就能显示隐藏

然后我们看第一个表单项,工位号,里面有个标签和一个文本框,"v-mode"绑定的是用户输入的工位绑定queryParams的里面的tango,placeholder是灰色的文本占位符信息,clearable用于清理用户输入的信息恢复成文本占位符状态,keyup.enter回车事件绑定"handQuery"方法等同于我们点击搜索按钮.  

<div class="app-container">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="工位号" prop="tagno">
        <el-input
          v-model="queryParams.tagno"
          placeholder="请输入工位号"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="区域" prop="area">
        <el-input
          v-model="queryParams.area"
          placeholder="请输入区域"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="线体" prop="productionlinebody">
        <el-input
          v-model="queryParams.productionlinebody"
          placeholder="请输入线体"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

搜索按钮我们点击以后会触发handleQuery方法,完成搜索条件的查询.重置按钮点击触发将所有输入信息清空

我们看下新增按钮区域的内容还是点击绑定handleAdd添加时间

修改按钮比新增多了一个disabled属性,这个属性是控制该按钮是否可用的,比如勾选复选框,才可用

<el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="Plus"
          @click="handleAdd"
          v-hasPermi="['screeninfo:screeninfo:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="Edit"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['screeninfo:screeninfo:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="Delete"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['screeninfo:screeninfo:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          @click="handleExport"
          v-hasPermi="['screeninfo:screeninfo:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

最后这个自定义组件"right-toolbar",该组件控制这两按钮,第一个按钮会触发showSeach属性修改,决定了搜索栏是否隐藏,queryTable则会触发getList方法重新将表格展示出数据

数据表格展示el-table标签

 <el-table v-loading="loading" :data="screeninfoList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="工位号" align="center" prop="tagno" />
      <el-table-column label="位置" align="center" prop="position" />
      <el-table-column label="屏幕编号" align="center" prop="screenno" />
      <el-table-column label="区域" align="center" prop="area" />
      <el-table-column label="线体" align="center" prop="productionlinebody" />
      <el-table-column label="模型编号" align="center" prop="viewmodenum" />
      <el-table-column label="IP地址" align="center" prop="ip" />
      <el-table-column label="验证时间" align="center" prop="lastchecked" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.lastchecked, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" prop="status">
        <template #default="scope">
          <div class="status-container">
            <span class="status-dot" :class="getStatusClass(scope.row.status)"></span>
            <span>{{ scope.row.status || '未定义' }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['screeninfo:screeninfo:edit']">修改</el-button>
          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['screeninfo:screeninfo:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

 "v-loading"是一个指令用于指定加载状态,网速慢时候表格显示转圈加载

data是个绑定属性",用于指定表格的数据源

selection-change,时间监听器,用于监听选中行的变化,这里比如每行前面的勾选框,调用handleSelectionChange方法执行后面处理逻辑

 <template #default="scope">
          <span>{{ parseTime(scope.row.lastchecked, '{y}-{m}-{d}') }}</span>
 </template>

这是模版插槽,通过scope 获取整个表格的数据,取出当前行拿到时间

操作这一列也是用的模版插槽,link,type,icon是控制css样式和按钮的图标,click是将当前行的数据传给当前方法

    <pagination
      v-show="total>0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />

分页区域v-show如果返回数据大于0行,那么显示分页栏

:total显示条数

pagination在切换页面条数和下一页时会调用getList方法查询数据

    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
      <el-form ref="screeninfoRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="工位号" prop="tagno">
          <el-input v-model="form.tagno" placeholder="请输入工位号" />
        </el-form-item>
        <el-form-item label="位置" prop="position">
          <el-input v-model="form.position" placeholder="请输入位置" />
        </el-form-item>
        <el-form-item label="屏幕编号" prop="screenno">
          <el-input v-model="form.screenno" placeholder="请输入屏幕编号" />
        </el-form-item>
        <el-form-item label="区域" prop="area">
          <el-input v-model="form.area" placeholder="请输入区域" />
        </el-form-item>
        <el-form-item label="线体" prop="productionlinebody">
          <el-input v-model="form.productionlinebody" placeholder="请输入线体" />
        </el-form-item>
        <el-form-item label="模型编号" prop="viewmodenum">
          <el-input v-model="form.viewmodenum" placeholder="请输入模型编号" />
        </el-form-item>
        <el-form-item label="IP地址" prop="ip">
          <el-input v-model="form.ip" placeholder="请输入IP地址" />
        </el-form-item>
        <el-form-item label="viewnum" prop="viewnum">
          <el-input v-model="form.viewnum" placeholder="请输入viewnum" />
        </el-form-item>
        <el-form-item label="版本" prop="programver">
          <el-input v-model="form.programver" placeholder="请输入版本" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option label="在线" value="online" />
            <el-option label="离线" value="offline" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="info">
          <el-input v-model="form.info" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

最后一部分区域是添加修改对话框

el-dialog标签,改标签默认在也面是隐藏的,我们通过点击新增和修改按钮后,通过双向绑定将open值改为true.让它显示出来

append-to-body默认将对话框元素添加到body元素就能显示了,同时对话框标题部分不是写死的,而是动态绑定

表单内通过;model双向绑定,rules表单校验规则,比如必填项不填的校验

JS代码

import { listScreeninfo, getScreeninfo, delScreeninfo, addScreeninfo, updateScreeninfo } from "@/api/screeninfo/screeninfo"

第一行引入了api接口文件,包含若干个方法,打开这个文件

import request from '@/utils/request'

第一行引入的是request工具类,内部封装了请求的拦截器和响应的拦截器

// 查询工位屏信息管理列表
export function listScreeninfo(query) {
  return request({
    url: '/screeninfo/screeninfo/list',
    method: 'get',
    params: query
  })
}

每个方法发起请求都是调用这个工具类,查询列表这个方法是将搜索栏里的多个条件封装给query

对象,调用工具类将参数传过去,向后台发送请求完成列表的查询,其他方法类似

我们回到视图组件

const { proxy } = getCurrentInstance()

调用了getCurrentInstance方法回去当前实例的代理对象proxy,这个代理对象的作用是访问整个视图组件的数据、方法

const screeninfoList = ref([])

通过ref定义的简单响应式对象

//是否显示弹窗
const open = ref(false);
//是否显示加载状态
const loading
    =ref(true);
//是否显示搜索栏
const showSearch = ref(true);
//复选框,被选中id的数组
const ids = ref([]);
//复选框,是否单选,用于高亮修改、删除按钮
const single=ref(true);
//复选框,是否多选,仅高亮删除按钮
const multiple=ref(true);
//总(记录)条数
const total = ref(0);
//用于区分新增、修改对话框标题
 const title =ref("");
//定义reactive响应式对象
const data=reactive({
    新增或修改表单数据
    form:(),
    //搜索条件参数
....}

为了方便操作将data对象的三个属性转化成了ref响应式对象

const { queryParams, form, rules } = toRefs(data)

下面使用方法操作这个几个属性

/** 查询工位屏信息管理列表 */
function getList() {
  //将loading设置为true,表格显示出来
  loading.value = true
  //调用api接口的查询列表方法,将我们参数作为条件向后台发起请求查询,响应的数据封装给response对象  
  listScreeninfo(queryParams.value).then(response => {
    //分别是列表和条数
    screeninfoList.value = response.rows
    total.value = response.total
    //再将表格loading值设置为false隐藏掉
    loading.value = false
  })
}

然后就是一些功能很容易理解 

后端源码阅读

  

/**
     * 查询工位屏信息管理列表
     */
    @PreAuthorize("@ss.hasPermi('screeninfo:screeninfo:list')")
    @GetMapping("/list")
    public TableDataInfo list(Screeninfo screeninfo)
    {
        startPage();
        List<Screeninfo> list = screeninfoService.selectScreeninfoList(screeninfo);
        return getDataTable(list);
    }

controller层每个方法都有个@PreAuthorize注解,这个注解是Spring Security用来做权限检查的,他在运行方法前先检验权限,权限够就放行,不够就拦截

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐