README.md 23 KB

logo

RuoYi v3.5.0

基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构

端口占用说明 ----

常用 80/443 nginx 8848/9848/9849 nacos 4500/500 vpn 9000 docker可视化 8000 jenkins 27017 mongodb 8718 sentinel

60001 探访项目前端 60002 探访项目公众号 60003 探访项目大屏 30301 探访项目大屏后端 30101 探访项目后端 60044 一汽项目前端 30144 一汽项目后端

8080 考试系统网关 9200 考试系统认证 9100 考试系统监控 9300 考试系统文件上传 9202 考试系统代码生成器 9203 考试系统定时任务 9201 考试系统系统模块 8122 考试系统教育 8121 考试系统资源 800 考试系统前端 60077 考试系统uniapp 6378 考试redis

9090 民政系统网关 9400 民政系统认证 9101 民政系统监控 9399 民政系统文件上传 9402 民政系统代码生成器 9403 民政系统定时任务 9401 民政系统系统模块 8280 民政系统机构模块 8290 民政系统政务模块 801 民政系统前端 6379 民政redis

升级改造

1.首先在根目录的pom文件添加

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <!-- 环境标识,需要与配置文件的名称相对应 -->
            <profiles.active>dev</profiles.active>
            <nacos.server>139.9.138.217:8848</nacos.server>
            <nacos.discovery.group>MZ</nacos.discovery.group>
            <nacos.discovery.namespace>f4b2e449-3ed7-4338-8fcd-717e6066baf3</nacos.discovery.namespace>
            <nacos.config.group>MZ</nacos.config.group>
            <nacos.config.namespace>f4b2e449-3ed7-4338-8fcd-717e6066baf3</nacos.config.namespace>
        </properties>
        <activation>
            <!-- 默认环境 -->
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <profiles.active>prod</profiles.active>
            <nacos.server>139.9.138.217:8848</nacos.server>
            <nacos.discovery.group>MZ</nacos.discovery.group>
            <nacos.config.group>MZ</nacos.config.group>
        </properties>
    </profile>
</profiles>

2.复制docker文件夹,替换3.4 - 3.5 无变更 复制ruoyi-ui下的Dockerfile,nginx.conf到新工程 3.替换配置方式: sentinel的 127.0.0.1:8718 换成 139.9.138.217:8718 127.0.0.1:8848 换成 139.9.138.217:8848 active: dev 换 active: @profiles.active@

nacos:
  discovery:
    # 服务注册地址
    server-addr: 127.0.0.1:8848
  config:
    # 配置中心地址
    server-addr: 127.0.0.1:8848
    # 配置文件格式
    file-extension: yml
    # 共享配置
    shared-configs:
      - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

换成

nacos:
  # nacos 服务地址
  server-addr: @nacos.server@
  discovery:
    # 注册组
    group: @nacos.discovery.group@
    namespace: @nacos.discovery.namespace@
  config:
    # 配置组
    group: @nacos.config.group@
    namespace: @nacos.config.namespace@
    # 配置文件格式
    file-extension: yml
    # 共享配置
    shared-configs:
      - data-id: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
        group: MZ

每个需要启动的pom的build节点下添加

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <!--开启过滤,用指定的参数替换directory下的文件中的参数-->
        <filtering>true</filtering>
    </resource>
</resources>

4.替换gen生成相关类:复制保留使用新的 (1)com.ruoyi.common.core.constant.GenConstants (2)com.ruoyi.gen.domain.GenTableColumn (3)复制vm文件夹,使用新的

5.添加新依赖 gateway添加kinfe

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-ui</artifactId>
    <version>3.0.3</version>
</dependency>

添加mybaitsplus,lombok

6.修改系统部门角色相关 修改ruoyi-api-system下SysDept添加

/**行政区划id */
private String locationId;     //->mapper添加此字段
private String locationName;   

SysRole添加

/** 拥有分配角色能力的角色id集 */
private String powerRids;   // 角色和用户查询详情 mapper都添加次字段

SysUser添加,部门不能为空

/** 养老机构ID */
private String jgId; //mapper添加此字段    selectUserVo添加u.jg_id, r.power_rids,SysUserResult,SysRole对应字段

(1)SysDeptController.java 方法:excludeChild,roleDeptTreeselect 改造:deptService.selectDeptList(new SysDept());

改为new SysDept().setStatus("0");deptService.selectDeptList(dept);

(2)SysMenuController.java 方法:treeselect
改造: 添加menu.setStatus("0"); (2.1)SysMenuServiceImpl 方法selectMenuList(Long userId)

SysMenu menu = new SysMenu();
menu.setStatus("0");
return selectMenuList(menu, userId);

(2.2)SysMenuMapper添加selectMenuByIds

<select id="selectMenuByIds" resultMap="SysMenuResult">
    <include refid="selectMenuVo"/>
    WHERE menu_id in
    <foreach collection="array" item="id" index="index" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

(3)SysDeptServiceImpl 添加

@Autowired
private SysDeptJlMapper sysDeptJlMapper;    

selectDeptById方法 添加locationname回显

SysDept sysDept = deptMapper.selectDeptById(deptId);
SysDeptJl sysDeptJl = sysDeptJlMapper.selectSysDeptJlById(sysDept.getLocationId());
if (sysDeptJl!=null){
    sysDept.setLocationName(sysDeptJl.getName());
}
return sysDept;

insertDept方法

if (dept.getParentId() == 0){
    return deptMapper.insertDept(dept);
}
    SysDept info = deptMapper.selectDeptById(dept.getParentId());
// 如果父节点不为正常状态,则不允许新增子节点
if (!UserConstants.DEPT_NORMAL.equals(info.getStatus()))
{
    throw new ServiceException("部门停用,不允许新增");
}
if (StringUtils.isBlank(info.getAncestors())){
    dept.setAncestors(""+dept.getParentId());
}else{
    dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
}
return deptMapper.insertDept(dept);

(4)SysRoleServiceImpl selectRoleList方法 注释数据权限

@Autowired
private SysMenuMapper sysMenuMapper;
@Autowired
private ISysUserService sysUserService;
if (SecurityUtils.isAdmin(SecurityUtils.getUserId())){
    Map<String, Object> params = role.getParams();
    params.put("ids",null);
    role.setParams(params);
    return roleMapper.selectRoleList(role);
}else{
    //查看当前人的角色
    SysUser sysUser = sysUserService.selectUserById(SecurityUtils.getUserId());
    List<String> ids = new ArrayList<>();
    sysUser.getRoles().stream().forEach(r -> {
        String powerRids = r.getPowerRids();
        if (!StringUtils.isBlank(powerRids)) {
            ids.addAll(Arrays.asList(powerRids.split(",")));
        }
    });
    if (ids.size() == 0){
        return new ArrayList<>();
    }else{
        Map<String, Object> params = role.getParams();
        params.put("ids",ids);
        role.setParams(params);
        return roleMapper.selectRoleList(role);
    }
}

添加一个检测是否能授权角色的方法 接口和实现类都写

/**
 * 检查角色是否存在
 *
 * @param role 角色信息
 */
public void checkRolesExist(SysRole role);
/**
 * 检查角色是否存在
 *
 * @param role 角色信息
 */
@Override
public void checkRolesExist(SysRole role) {
    // 检查是否拥有角色分配权限
    Long[] menuIds = role.getMenuIds();
    List<SysMenu> sysMenus = sysMenuMapper.selectMenuByIds(menuIds);
    boolean hasRoleAuth = sysMenus.stream().anyMatch(sysMenu -> "角色分配".equals(sysMenu.getMenuName()));
    if (hasRoleAuth){
        String powerRids = role.getPowerRids();
        if (!StringUtils.isBlank(powerRids)){
            String[] ids = powerRids.split(",");
            for (String id : ids) {
                checkRoleAllowed(new SysRole(Long.parseLong(id)));
            }
            Map<String, Object> params = role.getParams();
            params.put("ids",ids);
            role.setParams(params);
            SysRole sysRole = new SysRole();
            sysRole.setParams(params);
            List<SysRole> sysRoles = roleMapper.selectRoleList(sysRole);
            boolean b = sysRoles.size() == ids.length;
            if (!b){
                throw new ServiceException("分配的角色不符合规范");
            }
        }
    }else{
        role.setPowerRids("");
    }
}

(4.1)SysRoleMapper修改selectRoleList

<select id="selectRoleList" parameterType="SysRole" resultMap="SysRoleResult">
    select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly,
    r.status, r.del_flag, r.create_time, r.remark
    from sys_role r
    where r.del_flag = '0'
    <if test="params.ids != null and params.ids != ''">
        AND r.role_id in
        <foreach collection="params.ids" item="id" index="index" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </if>
    <if test="roleId != null and roleId != 0">
        AND r.role_id = #{roleId}
    </if>
    <if test="roleName != null and roleName != ''">
        AND r.role_name like concat('%', #{roleName}, '%')
    </if>
    <if test="status != null and status != ''">
        AND r.status = #{status}
    </if>
    <if test="roleKey != null and roleKey != ''">
        AND r.role_key like concat('%', #{roleKey}, '%')
    </if>
    <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
        and date_format(r.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
    </if>
    <if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
        and date_format(r.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
    </if>
    order by r.role_sort
</select>

(5)SysUserServiceImpl checkUserAllowed方法

if ((StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) ||
        (StringUtils.isNotNull(user.getUserId())  && SecurityUtils.getUserId().equals(user.getUserId())))
{
    throw new ServiceException("不允许操作该用户");
}

insertUser方法 添加jgId

user.setJgId(IdUtils.simpleUUID());

(6)ruoyi-ui/src/api/system/dict/type.js 添加

// 业务字典查询
export function objdictList(query) {
  return request({
    url: '/system/dict/type/objdict',
    method: 'get',
    params: query
  })
}
// 业务表查询
export function objtableList(query) {
  return request({
    url: '/system/dict/type/objtable',
    method: 'get',
    params: query
  })
}
// Tree数据查询
export function gettreedata(query) {
  return request({
    url: '/system/dict/type/gettreedata',
    method: 'get',
    params: query
  })
}
// 统计数据获取
export function getstatisticaldata(query) {
  return request({
    url: '/system/dict/type/getstatisticaldata',
    method: 'get',
    params: query
  })
}

(7)assets/styles/index.scss

//表格字多悬浮的样式
.el-tooltip__popper {
  max-width: 500px;
  line-height: 180%;
  white-space: pre-wrap;
}
//提高警告消息的层级
.el-message--warning{
  z-index: 3000 !important;
}

(7.1)vuex 的user

userData:'',
SET_USERDATA: (state, userData) => {
  state.userData = userData
},
获取用户信息
commit('SET_USERDATA', user)

main.js 以及utils下的工具类 (8)dept/index.vue

<el-row>
  <el-col :span="12">
    <el-form-item label="所属区划" prop="locationId" >
      <el-input v-model="form.locationName|| '无'" :disabled="true" v-if="form.deptId"/>
      <RegionCascaderSelect v-model="form.location" v-else></RegionCascaderSelect>
    </el-form-item>
  </el-col>
</el-row>

isExpandAll: false,
重置表单:
location:undefined,
locationId:"",
locationName:"",

提交
submitForm: function() {
  this.$refs["form"].validate(valid => {
    if (valid) {
      if (this.form.location){
        this.form.locationId = this.form.location[this.form.location.length-1];
      }

样式
<style scoped>
.formFlex {
  display: flex;
}
.contenrFlex{
  width: 100%;
  display: flex !important;
}
</style>      

(9)user/index.vue 去掉default-expand-all

//操作一栏判断条件增加
<template slot-scope="scope" v-if="scope.row.userId !== 1 && scope.row.userId != user.userData.userId">
</template>

import {mapState} from "vuex";
computed: {
    ...mapState(["user"]),
},

deptId: [
  { required: true, message: "用户归属部门不能为空", trigger: "blur" }
],

(10)role/index.vue

//198行tree添加
@check="roleNodeClick"

<el-form-item label="可分配角色" v-if="hasRoleAuth">
  <el-select v-model="form.rids" multiple placeholder="请选择角色">
    <el-option
      v-for="item in roleOptions"
      :key="item.roleId"
      :label="item.roleName"
      :value="item.roleId"
      :disabled="item.status == 1"
    ></el-option>
  </el-select>
</el-form-item>

import {getUser} from "@/api/system/user";
// 可分配角色选项
roleOptions: [],
hasRoleAuth: false,

roleNodeClick(data, node){
  this.hasRoleAuth = node.checkedNodes.some(item=>item.label == '角色分配');
},

handleAdd() {
  this.reset();
  this.getMenuTreeselect();
  this.open = true;
  this.title = "添加角色";
  getUser().then(response => {
    this.roleOptions = response.roles;
  });
},


handleUpdate(row) {
  this.reset();
  const roleId = row.roleId || this.ids
  const roleMenu = this.getRoleMenuTreeselect(roleId);
  getRole(roleId).then(response => {
    this.form = response.data;
    this.open = true;
    this.hasRoleAuth = false;
    this.$nextTick(() => {
      roleMenu.then(res => {
        let checkedKeys = res.checkedKeys
        checkedKeys.forEach((v) => {
            this.$nextTick(()=>{
                this.$refs.menu.setChecked(v, true ,false);
                let node = this.$refs.menu.getNode(v);
                if (node.label == '角色分配') {
                  this.hasRoleAuth = true;
                }
            })
        })
      });
    });
    this.title = "修改角色";
    getUser().then(response => {
      this.roleOptions = response.roles;
      if (this.form.powerRids){
        this.form.rids =this.form.powerRids.split(",").map(item=>parseInt(item));
      }
    });
  });
}

提交
submitForm: function() {
  this.$refs["form"].validate(valid => {
    if (valid) {
      if (this.form.rids && this.form.rids.join){
        this.form.powerRids = this.form.rids.join(",");
      }

(9)去除系统原生所有修改,删除按钮,批量替换全局的el-dialog添加 v-dialog-drag (10)复制module下自己的模块,如新开发就是复制system改造,添加进module的pom 复制:SysDeptJlC相关所有层业务 deptJL region 复制:SysDictTypeController 所有扩展方法 139行开始 复制:ISysDictTypeService SysDictTypeServiceImpl SysDictTypeMapper包括xml 所有扩展方法 最后一行开始 页面按钮和接口都删除: 用户单独授权相关接口insertAuthRole, 角色单独赋权用户相关接口allocatedList,unallocatedList,cancelAuthUser,cancelAuthUserAll,selectAuthUserAll

7.复制一份 ruoyi-api-system 添加ruoyi-api-ext模块
ruoyi-api-ext依赖tool工具库

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.5.8</version>
</dependency>

协调common其他模块(扩展用户字段) GlobalExceptionHandler,SecurityUtils DictUtils AjaxResult BaseEntity ExcelUtil JwtUtils DateUtils 复制对比

ruoyi-common-swagger添加

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

平台简介

若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。

  • 采用前后端分离的模式,微服务版本前端(基于 RuoYi-Vue)。
  • 后端采用Spring Boot、Spring Cloud & Alibaba。
  • 注册中心、配置中心选型Nacos,权限认证使用Redis。
  • 流量控制框架选型Sentinel,分布式事务选型Seata。
  • 提供了技术栈(Vue3 Element Plus Vite)版本RuoYi-Cloud-Vue3,保持同步更新。
  • 如需不分离应用,请移步 RuoYi,如需分离应用,请移步 RuoYi-Vue
  • 阿里云折扣场:点我进入,腾讯云秒杀场:点我进入  
  • 阿里云优惠券:点我领取,腾讯云优惠券:点我领取  

友情链接 若依/RuoYi-Cloud Ant Design版本。

系统模块

com.ruoyi     
├── ruoyi-ui              // 前端框架 [80]
├── ruoyi-gateway         // 网关模块 [8080]
├── ruoyi-auth            // 认证中心 [9200]
├── ruoyi-api             // 接口模块
│       └── ruoyi-api-system                          // 系统接口
├── ruoyi-common          // 通用模块
│       └── ruoyi-common-core                         // 核心模块
│       └── ruoyi-common-datascope                    // 权限范围
│       └── ruoyi-common-datasource                   // 多数据源
│       └── ruoyi-common-log                          // 日志记录
│       └── ruoyi-common-redis                        // 缓存服务
│       └── ruoyi-common-security                     // 安全模块
│       └── ruoyi-common-swagger                      // 系统接口
├── ruoyi-modules         // 业务模块
│       └── ruoyi-system                              // 系统模块 [9201]
│       └── ruoyi-gen                                 // 代码生成 [9202]
│       └── ruoyi-job                                 // 定时任务 [9203]
│       └── ruoyi-file                                // 文件服务 [9300]
├── ruoyi-visual          // 图形化管理模块
│       └── ruoyi-visual-monitor                      // 监控中心 [9100]
├──pom.xml                // 公共依赖

架构图

内置功能

  1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
  2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
  3. 岗位管理:配置系统用户所属担任职务。
  4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
  6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
  7. 参数管理:对系统动态配置常用参数。
  8. 通知公告:系统通知公告信息发布维护。
  9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
  10. 登录日志:系统登录日志记录查询包含登录异常。
  11. 在线用户:当前系统中活跃用户状态监控。
  12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
  13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
  14. 系统接口:根据业务代码自动生成相关的api接口文档。
  15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
  16. 在线构建器:拖动表单元素生成相应的HTML代码。
  17. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。

在线体验

  • admin/admin123
  • 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。

演示地址:http://ruoyi.vip
文档地址:http://doc.ruoyi.vip

演示图

若依微服务交流群

QQ群: 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 加入QQ群 点击按钮入群。