民政大平台

sckj aee6bff5fc Merge branch '老人查询和用餐信息进行限制' of sckj/mz-cloud into master 2 hete
.github 29fac802f3 update donate 2 éve
bin 961825d25c update bin 2 éve
docker bc791769fb 1 6 hónapja
node_modules 5e91fae1cd 图标数据 1 éve
ruoyi-api d539f39526 20240829_sun 3 hete
ruoyi-auth d539f39526 20240829_sun 3 hete
ruoyi-common 271219058a 20240820_sun加密解密工具类修改 1 hónapja
ruoyi-gateway 2c3b15d864 增加小程序不用校验验证码的登录接口 5 hónapja
ruoyi-modules 85406e5b2e Merge branch '20240829_sun' of sckj/mz-cloud into master 3 hete
ruoyi-ui 892f246c23 默认一个月 2 hete
ruoyi-visual 0678a93104 nacos 用户验证 1 éve
ruoyi-web adf0fb52e5 地图界面调整 1 éve
ruoyi-yldt 38d830a2e8 大屏 1 éve
sql 6ea24cd45c 20220916_sun修正等级评定流程 2 éve
.gitignore 101a225b61 ignore 2 éve
LICENSE 989976b237 Initial commit 4 éve
README.md 145a405500 提交 1 éve
package-lock.json 54fecccf59 高龄补贴统计 1 éve
package.json 54fecccf59 高龄补贴统计 1 éve
pom.xml fabc79952e XY 4 hónapja

README.md

logo

RuoYi v3.6.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 6379 redis

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

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

9090 民政系统网关 9400 民政系统认证 9101 民政系统监控 9399 民政系统文件上传 9402 民政系统代码生成器 9403 民政系统定时任务 9401 民政系统系统模块 8280 民政系统机构模块 8290 民政系统政务模块 8340 民政系统搜索模块 8345 民政系统门户模块 8600 民政系统数据同步模块 801 民政系统前端

7070 智能养老系统网关 7200 智能养老系统认证 7201 智能养老系统模块 8131 智能养老业务模块 802 智能养老系统前端

6060 OKC系统后端 803 OKC系统前端

升级改造

0.由于很多项目都使用若伊框架开发,如果放在同一个服务器上,那么cookies和redis的存储会重叠,因此这边做了处理

// 前端在appjs把cookie存储的方法加上前缀
import Cookies from 'js-cookie'

let get_method = Cookies.get
let set_method = Cookies.set
let remove_method = Cookies.remove
Cookies.get = (key) => {
  return get_method('mz_' + key)
}
Cookies.set = (key, value, attributes) => {
  return set_method('mz_' + key, value, attributes)
}
Cookies.remove = (key, attributes) => {
  return remove_method('mz_' + key, attributes)
}
// 后端在redis配置里添加key前缀
@Component
public class RedisKeySerializer implements RedisSerializer<String>
{
    private final Charset charset;
    public final static String key = "mz";

    public RedisKeySerializer()
    {
        this(Charset.forName("UTF8"));
    }

    public RedisKeySerializer(Charset charset)
    {
        Assert.notNull(charset, "字符集不允许为NULL");
        this.charset = charset;
    }

    @Override
    public byte[] serialize(String string) throws SerializationException
    {
        // 通过项目名称ruoyi.name来定义Redis前缀,用于区分项目缓存
        return new StringBuilder(key).append(":").append(string).toString().getBytes(charset);
    }

    @Override
    public String deserialize(byte[] bytes) throws SerializationException
    {
        return (bytes == null ? null : new String(bytes, charset));
    }
}

@Configuration
@EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport
{
    @Bean
    @SuppressWarnings(value = { "unchecked", "rawtypes" })
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory,RedisKeySerializer redisKeySerializer)
    {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(redisKeySerializer);//template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(redisKeySerializer);//template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}

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文件夹 复制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: @nacos.config.group@
        namespace: @nacos.discovery.namespace@

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

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

4.添加新依赖 gateway添加kinfe

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

添加mybaitsplus,lombok

复制一份 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>

ruoyi-common-swagger添加

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

5.业务改造:
(0)本身业务只有用户管理和部门管理存在数据权限
(1)部门改为懒加载,并且新增行政区划表和部门表对应,部门区划选择 限制只能选择部门层级或者上一级(直属)
(2)角色增删改,不对外开放,数据权限去掉,改造为增加角色可分配权限的字段,由超管进行 角色分配后选择可分配角色进行下级角色分配,需要同步处理用户里角色选择的问题,非自己能分配的角色禁止分配,但是可以取消用户角色
(3)内部调用的服务 不走@requirePermissions相关注解

PreAuthorizeAspect.java
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable
{
    String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
    // 内部请求验证
    if (!StringUtils.equals(SecurityConstants.INNER, source))
    {
        // 注解鉴权
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        checkMethodAnnotation(signature.getMethod());
    }
    try
    {
        // 执行原有逻辑
        Object obj = joinPoint.proceed();
        return obj;
    }
    catch (Throwable e)
    {
        throw e;
    }

}

(3)用户管理左侧部门改为懒加载+触发搜索
(4)修改gen里的模板生成,添加注解验证等功能
(5)扩展数据权限为mybatisplus拦截器,并且做了多菜单分别对应不同的数据权限
(6)内置固定角色 养老机构用户,社区养老服务机构用户,评定专家用户, 内置角色不自由分配 指定业务进行授予,该3个内置角色授予后 根据业务不能改变部门和角色。可以扩展(指定内置角色和对应菜单关系,暂时未锁定),角色表添加字段,内置角色只允许更改菜单,其他功能代码做好逻辑限制(不允许修改其他,不允许外部分配,分配只分配指定类型)。
(7)扩展字典表 添加dict_parent_value 组成树形字典,默认框架字典为平级字典,通过该字段扩展为树形字典,一版规则为10是1x的父级
(8)查询系统表字段不存在注释得结果

SELECT * FROM `COLUMNS` WHERE TABLE_SCHEMA = 'mz-cloud' and TABLE_NAME  not LIKE '%act%' and TABLE_NAME  not LIKE '%www%' and TABLE_NAME  not LIKE '%v_%' and  COLUMN_COMMENT ='' and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state')  GROUP BY TABLE_NAME

(9)查询系统表字段是日期 但是长度不是8的

SELECT * FROM `COLUMNS` WHERE TABLE_SCHEMA = 'mz-cloud' and  COLUMN_COMMENT like '%日期%' and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state')  and CHARACTER_MAXIMUM_LENGTH != 8

(10)查询系统表字段是时间 但是长度不是14的

SELECT * FROM `COLUMNS` WHERE TABLE_SCHEMA = 'mz-cloud' and  COLUMN_COMMENT like '%时间%' and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state')  and CHARACTER_MAXIMUM_LENGTH != 14

(11)查询权限重复

SELECT count(1)as count ,perms FROM sys_menu GROUP BY perms HAVING count > 1

(12)查询涉及行政区划id的

SELECT * FROM COLUMNS WHERE TABLE_SCHEMA = 'mz-cloud' and  (COLUMN_COMMENT like '%行政%' or COLUMN_COMMENT like '%区划%' or COLUMN_COMMENT like '%居住%' or COLUMN_COMMENT like '%籍贯%' or COLUMN_COMMENT like '%户籍%' or COLUMN_COMMENT like '%现居%') and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state') 

(13)比较文档里缺少的表和字段

SELECT * FROM

(
SELECT a1.TABLE_NAME, a1.COLUMN_NAME,a1.COLUMN_COMMENT,a1.IS_NULLABLE,a1.DATA_TYPE,a1.CHARACTER_MAXIMUM_LENGTH,a1.COLUMN_KEY, a2.zdmc,a2.zdlx,a2.zdgs,a2.sfbx,a2.dictid,a2.dbtype,a2.dblength,a2.ispk,a2.bbb,a2.zdbs, 

case when a1.COLUMN_COMMENT = IF(a2.dictid = '' or a2.dictid is null,a2.zdmc,CONCAT(a2.zdmc,'(',a2.dictid,')')) then 'true' else 'false' end  as c1,
case when a1.IS_NULLABLE = case when a2.sfbx = 'Y' then 'NO' else 'YES' end then 'true' else 'false' end  as c2,
case when a1.DATA_TYPE = a2.dbtype then 'true' else 'false' end  as c3,
case when a1.CHARACTER_MAXIMUM_LENGTH = a2.dblength or a2.dbtype= 'int' or a2.dbtype = 'decimal' then 'true' else 'false' end  as c4,
case when a1.COLUMN_KEY = case when a2.ispk = '1' then 'PRI' else '' end then 'true' else 'false' end  as c5
FROM 
(SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'mz-cloud' and TABLE_NAME NOT like '%act%' and TABLE_NAME NOT like '%www%' and TABLE_NAME NOT like '%v_%' and TABLE_NAME NOT like '%qrtz%' and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state')) a1
LEFT JOIN
(SELECT b1.*,b2.bid as bbb,b2.bmc FROM ry.`columns` b1, ry.`tables` b2  WHERE b1.bid = b2.id) a2 
ON a2.bbb = a1.TABLE_NAME  and a2.zdbs = a1.COLUMN_NAME

) a
WHERE ISNULL(a.bbb)

(14)比较文档里现有字段和实际数据库不一致的地方

SELECT * FROM

(
SELECT a1.TABLE_NAME, a1.COLUMN_NAME,a1.COLUMN_COMMENT,a1.IS_NULLABLE,a1.DATA_TYPE,a1.CHARACTER_MAXIMUM_LENGTH,a1.COLUMN_KEY, a2.zdmc,a2.zdlx,a2.zdgs,a2.sfbx,a2.dictid,a2.dbtype,a2.dblength,a2.ispk,a2.bbb,a2.zdbs, 

case when a1.COLUMN_COMMENT = IF(a2.dictid = '' or a2.dictid is null,a2.zdmc,CONCAT(a2.zdmc,'(',a2.dictid,')')) then 'true' else 'false' end  as c1,
case when a1.IS_NULLABLE = case when a2.sfbx = 'Y' then 'NO' else 'YES' end then 'true' else 'false' end  as c2,
case when a1.DATA_TYPE = a2.dbtype then 'true' else 'false' end  as c3,
case when a1.CHARACTER_MAXIMUM_LENGTH = a2.dblength or a2.dbtype= 'int' or a2.dbtype = 'decimal' or ISNULL(a1.CHARACTER_MAXIMUM_LENGTH) then 'true' else 'false' end  as c4,
case when ((a1.COLUMN_KEY = (case when a2.ispk = '1' then 'PRI' else '' end) ) or (a1.COLUMN_KEY = (case when a2.ispk = '1' then 'PRI' else 'MUL' end) )) then 'true' else 'false' end  as c5
FROM 
(SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'mz-cloud' and TABLE_NAME NOT like '%act%' and TABLE_NAME NOT like '%www%' and TABLE_NAME NOT like '%v_%' and TABLE_NAME NOT like '%qrtz%' and COLUMN_NAME not IN('create_time_str','create_user_id','create_user_type','create_by','create_unit','create_unit_name','update_time_str','update_user_id','update_by','update_unit','update_unit_name','state')) a1
LEFT JOIN
(SELECT b1.*,b2.bid as bbb,b2.bmc FROM ry.`columns` b1, ry.`tables` b2  WHERE b1.bid = b2.id) a2 
ON a2.bbb = a1.TABLE_NAME  and a2.zdbs = a1.COLUMN_NAME

) a

WHERE a.bbb is not null and (c1 != 'true' or c2 !='true' or c3 != 'true' or c4 != 'true' or c5 != 'true') 

(15)开发完成后 数据库字段和代码字段的核对 待考虑 测试人员进行一次注解核对 还是自动化写个脚本进行核对,业务逻辑判断的核对需要用代码走查的形式,review

(16)该模式下的权限字符核对模式:也同样考虑 自动化脚本核对,但是如果改造成 自动生成权限+菜单则不需要核对。 (99)目前信息统计相关业务菜单权限 是 隐式的, 并且没有子集区分功能,如养老机构下 A类型统计单独控制菜单显示,接口权限由于采用共有接口 没做菜单和接口的对应权限关联 (100)针对目前系统里 业务里的非空项目 在库里没有设置非空的情况: 若是严格按照实体非空限制,最好采用kotlin 带有非空字段的定义,目前非移动端项目 js弱类型只需要考虑空情况和类型不匹配情况即可

平台简介

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

  • 采用前后端分离的模式,微服务版本前端(基于 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群 加入QQ群 点击按钮入群。