Commit 67bb8798 authored by trumansdo's avatar trumansdo
Browse files

done: 完成代码生成以外的功能

todo: 代码生成、前端架构调整、样式调整
parent e27ca5d7
# 功能列表
# springboot-plus ### 基础管理
用户管理 - 已完成
一个基于SpringBoot 2 的管理后台系统,有数十个基于此的商业应用,包含了用户管理,组织机构管理,角色管理,功能点管理,菜单管理,权限分配,数据权限分配,代码生成等功能 组织机构管理 - 已完成
相比其他开源的后台开发平台脚手架,SpringBoot-Plus 使用简单,可以轻易完成中型,大型系统开发。同时技术栈较为简单 角色管理 - 已完成
菜单项 - 已完成
如何判断一个开源开发平台适合自己 功能点管理 - 已完成
字典数据管理 - 已完成
* 要明白单体系统,系统拆分,微服务三个不同构建开发平台方式,plus支持单体和系统拆分,一般而言,后台管理系统适合单体和系统拆分。微服务并不适合系统管理,以我知道的互联网大厂,央企后台管理系统,还是以前俩个为多 角色功能授权
* 你需要的是技术框架还是开发平台,技术框架就是技术堆砌,开发平台必须具备一定复杂基础业务功能 角色数据授权
* 看权限模型,支持功能权限和数据权限。plus具备强大的功能权限和数据权限,且可以扩展n种数据权限
* 看用户是否能属于多个部门,用户兼职情况很常见 ### 代码生成
* 看数据字典是否支持级联,数据字典级联太常见了,平台需要提供数据和前端的支持。puls系统支持 未开始
* 看代码生成是否支持预览,为什么要预览,因为生成会覆盖,预览可以修改已经生成的代码
# 核心用户设计
Plus系统是一个使用简单,功能较为复杂的开源系统,已经数十家商业公司采用
以集团为一个最大组织,可切换集团。
系统基于Spring Boot2.1技术,前端采用了Layui2.4。数据库以MySQL/Oracle/Postgres/SQLServer为实例,理论上是跨数据库平台.
以功能点为核心,菜单和请求构成可分配功能。
基本技术栈来源于我为电子工业出版社编写的的[<<Spring Boot 2 精髓 >>](https://item.jd.com/12214143.html) (这本书每一章也有各种例子,但Springboot-plus 更偏向于应用而不是教学) 数据权限以组织为基准进行访问限制
该书的第二版电子版可以可以在[看云广场购买](https://www.kancloud.cn/xiandafu/springboot2-in-practice/), 包含基础篇,分布式篇和微服务篇,第二版也包含一章说明Plus系统
# 开发规范
- controller以ElController结尾
当前版本:1.3.0 - 以El开始的注解是前端视图类注解
- 所有的字典类型都从数据库中加载进缓存中。字典值以三种方式访问:
技术交流群:252010126 > 1. 以Dict注解的String类型字段(其值为字典value),调用 `CoreBaseService.handleStrDictValueField` 方法处理bean。其字典名称存入TailBean的ext中。
> 2. 以Dict注解的DictType类型字段,调用 `CoreBaseService.handleDictTypeField` 方法处理bean。其对应字典(name,value,type),存入该字段
免费视频介绍:https://pan.baidu.com/s/1dFPoaT7 > 3. 继承DictTypeEnum的枚举类型字典类(参考JobTypeEnum),已做SpringMVC的参数和Jackson序列化处理
\ No newline at end of file
![](https://oscimg.oschina.net/oscnet/ed05b8bb68eb40a3c55e19557e408fb07fb.jpg)
开源地址:https://gitee.com/xiandafu/springboot-plus
视频介绍:https://pan.baidu.com/s/1dFPoaT7
![doc/readme/user.png](doc/readme/user.png)
![doc/readme/user.png](doc/readme/role.png)
![doc/readme/user.png](doc/readme/data.png)
![doc/readme/user.png](doc/readme/codePorject.png)
![doc/readme/user.png](doc/readme/codeconfig.png)
![doc/readme/user.png](doc/readme/codegen.png)
![doc/readme/user.png](doc/readme/codegen2.png)
![doc/readme/user.png](doc/readme/excelExport.png)
# 1 使用说明
## 1.1 安装说明
> 建议在彻底熟悉plus系统之前,先暂时不要修改其他配置选项,免得系统无法访问
>
> 本系统基于Spring Boot 2 ,因此请务必使用JDK8,且打开编译选项[parameters(点击了解parameters)](http://www.mamicode.com/info-detail-2162647.html),<u> 并重新编译工程,如果你没有使用Java8的 parameters 特性,系统不能正常使用</u>
从Git上获取代码后,通过IDE导入此Maven工程,包含俩个子工程
* admin-core ,核心包,包含了缓存,数据权限,公用的JS和HTML页面。
* admin-console, 系统管理功能,包含了用户,组织机构,角色,权限,数据权限,代码生成等管理功能
com.ibeetl.admin.CosonleApplication 是系统启动类,在admin-console包下,在运行这个之前,还需要初始化数据库,位于doc/starter-mysql.sql,目前只提供mysql, oracle, postgresql脚本。理论上支持所有数据库
还需要修改SpringBoot配置文件application.properties,修改你的数据库地址和访问用户
~~~properties
spring.datasource.baseDataSource.url=jdbc:mysql://127.0.0.1:3306/starter?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&useInformationSchema=true
spring.datasource.baseDataSource.username=root
spring.datasource.baseDataSource.password=123456
spring.datasource.baseDataSource.driver-class-name=com.mysql.cj.jdbc.Driver
~~~
运行CosonleApplication,然后访问http://127.0.0.1:8080/ 输入admin/123456 则可以直接登录进入管理系统
如果成功启动后运行报错:变量userId未定义,位于第6行,那是因为你没有启用[parameters](http://www.mamicode.com/info-detail-2162647.html),启用后,需要clean&build整个工程
> 微信扫描付费查看安装和子系统生成视频(约25分钟)
>
> ![doc/readme/user.png](doc/readme/pay-install.png)
## 1.2 创建子系统
SpringBoot-plus 是一个适合大系统拆分成小系统的架构,或者是一个微服务系统,因此,如果你需要创建自己的业务系统,比如,一个CMS子系统,建议你不要在SpringBoot-Plus 添加代码,应该是新建立一个maven工程,依赖admin-core,或者依赖admin-console(如果你有后台管理需求,通常都有,但不是必须的)
创建子系统,可以进入代码生成>子系统生成, 输入maven项目路径,还有包名,就可以直接生成一个可运行的基于SpringBoot-Plus 的子系统,所有代码可以在个项目里些完成,直接运行MainApplication,
~~~java
@SpringBootApplication
@EnableCaching
@ComponentScan(basePackages= {"com.corp.xxx","com.ibeetl.admin"})
public class MainApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
~~~
子系统包含了admin-core和admin-console, 因此你可以直接在子系统里使用core和console提供的所有功能,通过子系统的console功能的代码生成来完成进一步开发
子系统可以单独运行和维护,也可以集成到nginx后构成一个庞大的企业应用系统
### 1.2.1 配置子系统
子系统不需要做任何配置即可在IDE里直接运行,如果你想打包jar方式运行,则需要添加
~~~xml
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
~~~
如果你想打包成war放到tomcat下运行,需要修改maven打包为war
~~~xmml
<packaging>war</packaging>
~~~
### 1.2.2 菜单系统
系统默认提供三种类型菜单
* 系统级菜单,出现在页面顶部,表示一个子系统
* 导航菜单,出现在页面左边,点击导航将打开其下所有菜单
* 菜单,点开菜单将定位到页面,菜单必须关联到一个功能点。
建议新建立一个子系统来放置新功能
SpringPlus-Boot 并非以菜单或者按钮来组织整个系统,而是以功能点来组织整个系统提供的功能。如果要使得菜单生效,你必须要先常见一个功能点并且功能点有一个访问地址,然后将此菜单关联到这个功能点
> SpringBoot-Plus 先建立功能点是个好习惯,功能点被组织成一颗树,代表了系统应该提供功能的功能,我们看代码就会看到,功能点跟菜单,跟权限,和数据权限都有密切关系
### 1.2.2 添加代码
可以参考1.3业务代码生成生成初始化的代码,业务代码生成了14个文件,包含前后端所有代码,可以通过生成来了解代码习作规范
## 1.3 业务代码生成
在介绍如何利用Plus开发系统之前,先介绍代码生成功能,此功能可以生成前后端代码总计14个文件,你可以通过预览功能了解如何开发这个系统
![doc/readme/user.png](doc/readme/codeconfig.png)
代码生成针对表进行代码生成,包括JS,JAVA,SQL和HTML,可以通过预览功能直接预览。在生成代码到本地前,有些参数需要修改,否则,代码生成后显示的都是英文
* 显示字段 : 当此实体显示在任何地方的时候,能代表此实体的名称,比如用户名,组织机构名
* 变量名:可以自己设定一个较短的名字,此变量名会用于前后端的变量
* urlBase:你规划的子系统,最后访问路径是urlBase+变量名字
* system: 存放sql目录的的名称
其他修改的地方有
是否包含导入导出,如果选择,则会生成导入导出的代码,导入导出模板则需要参考已有功能(比如数据字典)来完成
是否包含附件管理,如果选择,则业务对象可以关联一组附件,比如客户关联一组附件,或者申请信息关联一组附件。
字段信息的显示名字,这个用于前端列表,表单的显示,应当输入中文名字
作为搜索,可以勾选几个搜索条件,系统自动生成一个搜索配置类
如果字段关联数据字典,那么设置一个数据字典,这样,生成的界面将会变成一个下拉列表
### 1.3.1 前端代码
前端代码采用了layui的JS框架,使用了按需加载的方式,文档参考 http://www.layui.com/doc/base/infrastructure.html.
* index.js: 系统入口JS,包含了查询和表格
* add.js : 新增操作的所有JS
* edit.js: 编辑操作的所有JS
* del.js: 删除操作的所有JS
基础JS
* Common.js: 封装了通常JS功能,如jquery的post方法,layui的窗口方法
* Lib.js 封装了业务相关方法,如submitForm,loadOrgPanel等方法
### 1.3.2 HTML代码
页面采用layui,文档参考 http://www.layui.com/demo/
模板语言了使用Beetl,文档参考ibeetl.com
* index.html: 功能首页
* add.html: 新增首页
* edit.html: 编辑操作首页
> 采用layui的好处是自带了页面和组件还有JS的管理,能完成大多数业务需求
基础UI组件:
* orgInput.tag.html 组织机构输入框
* simpleDictSelect.tag.html 字典下拉列表
* simpleDataSelect.tag 包含key-value的下拉列表
* searchForm.tag.html 通用搜索表单
* submitButtons.tag.html 提交按钮
* accessButton.tag.html 普通按钮(含权限)
* attachment.tag.html 附件管理组件
* ....
# 2 单体系统,系统拆分和微服务
plus是一个适合单体系统,系统拆分的java快速开发平台,也可以经过改造成微服务平台(以前做一个版本,但觉得plus应该聚焦系统核心,而不是简单堆砌功能,所以放弃了)
以下是单体系统,小系统,和微服务的区别
单体系统是一种常见系统设计方式,也是这十几年年来最主要的设计方式。单体系统的所有功能都在一个工程里,打成一个war包,部署。这样有如下明显好处
- 单体系统开发方式简单,我们从刚开始学习编程,就是完成的单体系统,开发人员只要集中精力开发当前工程
- 容易修改,如果需要修改任何功能,都非常方便,只需要修改一个工程范围的代码
- 测试简单,单体系统测试不需要考虑别的系统,避免本书下册要提到的各种REST,MQ调用
- 部署也很容易:不需要考虑跟别的系统关系,直接打war包部署到Web服务器即可
- 性能容易扩展,可以通过Nginx,把一个应用部署到多个服务器上。
随着业务发展,重构,单体系统越来越多,在开发一个庞大的单体系统的时候,就会有如下弊病
- 单体系统庞大,越来越难理解单体系统,微小的改动牵涉面广泛导致开发小组小心谨慎,开发速度会越来越慢。另外,启动一个庞大的单体系统,可能需要3分钟,或者更多时间
- 多个功能在同一个单体系统上开发,导致测试越来越慢,比如,测试必须排期,串行测试
- 单体系统如果想对技术进行更新换代,那代价非常大,如果是个小系统构成,则可以选取一个小系统先做尝试。单体大系统是几乎不可能做技术升级的
- 单体系统的所有功能运行在同一个JVM里,功能会互相影响,比如一个统计上传word文档的页码的功能由于非常消耗CPU,因此,会因为调用统计功能,导致整个系统短暂都不可用,出现假死的现象
因此,越来越多的架构师在设计系统的时候,会考虑系统拆分成多个单体小系统甚至是微服务。对于传统企业应用,拆成小系统更合适,对互联网系统,使用微服务个更合适,这是因为
- 传统IT系统本质上还是会用一个数据库,而微服务提倡的是一个服务一个数据库
- 传统IT系统很少需要调用其他模块服务。传统IT系统通过工作流来串联其他子系统。而电商类的微服务则是通过RPC等方式进行交互,是一个轻量级协议。传统IT系统也可以通过SOA,JMS跟其他系统(非子系统)交互,采用重量级协议
- 微服务对系统的基础设施要求很高,比如微服务治理,弹性库等等,只要电商系统才有人力物力去做这种事情,而传统IT系统,及时财大气粗,也暂时不具备微服务那样的IT基础设置
因此,对于大多数传统IT应用来说,单体拆分小系统在技术上没有风险,是一个可以立即实施的架构。如下是一个单体系统拆分后的物理架构
![design](doc/readme/design.png)
对于用户来说,访问不同的菜单功能,讲定位到不同得子系统,提供服务。
> plus支持多数据库
# 功能列表
### 基础管理
用户管理 - 已完成
组织机构管理
角色管理
菜单项 - 已完成
功能点管理 - 已完成
字典数据管理
角色功能授权
角色数据授权
# 角色设计说明:关乎于路由表
以集团为一个最大组织,可切换集团。
以功能点为核心,菜单和请求构成可分配功能。
数据权限以组织为基准进行访问限制
# 开发规范
- controller以ElController结尾
- 以El开始的注解是前端视图类注解
- 所有的字典类型都从数据库中加载进缓存中,任何字典类型都应该以常量访问,任何的字典名称和值都应该以枚举访问。
\ No newline at end of file
...@@ -22,6 +22,6 @@ public class AuditConsoleService extends CoreBaseService<CoreAudit> { ...@@ -22,6 +22,6 @@ public class AuditConsoleService extends CoreBaseService<CoreAudit> {
*/ */
public void queryByCondtion(PageQuery<CoreAudit> query) { public void queryByCondtion(PageQuery<CoreAudit> query) {
PageQuery<CoreAudit> ret = auditConsoleDao.queryByCondtion(query); PageQuery<CoreAudit> ret = auditConsoleDao.queryByCondtion(query);
queryListAfter(ret.getList()); handleStrDictValueFields(ret.getList());
} }
} }
...@@ -30,7 +30,7 @@ public class DictConsoleService extends CoreBaseService<CoreDict> { ...@@ -30,7 +30,7 @@ public class DictConsoleService extends CoreBaseService<CoreDict> {
public PageQuery<CoreDict> queryByCondition(PageQuery query) { public PageQuery<CoreDict> queryByCondition(PageQuery query) {
PageQuery ret = dictDao.queryByCondition(query); PageQuery ret = dictDao.queryByCondition(query);
queryListAfter(ret.getList()); handleStrDictValueFields(ret.getList());
return ret; return ret;
} }
...@@ -47,7 +47,7 @@ public class DictConsoleService extends CoreBaseService<CoreDict> { ...@@ -47,7 +47,7 @@ public class DictConsoleService extends CoreBaseService<CoreDict> {
public List<CoreDict> queryExcel(PageQuery<CoreUser> query) { public List<CoreDict> queryExcel(PageQuery<CoreUser> query) {
// 同查询,不需要额外数据 // 同查询,不需要额外数据
PageQuery ret = dictDao.queryByCondition(query); PageQuery ret = dictDao.queryByCondition(query);
queryListAfter(ret.getList()); handleStrDictValueFields(ret.getList());
return ret.getList(); return ret.getList();
} }
/** /**
......
...@@ -93,7 +93,7 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> { ...@@ -93,7 +93,7 @@ public class FunctionConsoleService extends CoreBaseService<CoreFunction> {
functionConsoleDao.queryByCondtion(query); functionConsoleDao.queryByCondtion(query);
List<CoreFunction> list = query.getList(); List<CoreFunction> list = query.getList();
this.queryListAfter(list); this.handleStrDictValueFields(list);
// 处理父功能名称显示 // 处理父功能名称显示
FunctionItem root = corePlatformService.buildFunction(); FunctionItem root = corePlatformService.buildFunction();
for (CoreFunction function : list) { for (CoreFunction function : list) {
......
...@@ -38,7 +38,7 @@ public class MenuConsoleService extends CoreBaseService<CoreMenu> { ...@@ -38,7 +38,7 @@ public class MenuConsoleService extends CoreBaseService<CoreMenu> {
public void queryByCondtion(PageQuery<CoreMenu> query) { public void queryByCondtion(PageQuery<CoreMenu> query) {
menuDao.queryByCondtion(query); menuDao.queryByCondtion(query);
queryListAfter(query.getList()); handleStrDictValueFields(query.getList());
} }
public Long saveMenu(CoreMenu menu) { public Long saveMenu(CoreMenu menu) {
......
...@@ -33,7 +33,7 @@ public class OrgConsoleService extends CoreBaseService<CoreOrg> { ...@@ -33,7 +33,7 @@ public class OrgConsoleService extends CoreBaseService<CoreOrg> {
public void queryByCondtion(PageQuery<CoreOrg> query) { public void queryByCondtion(PageQuery<CoreOrg> query) {
orgDao.queryByCondtion(query); orgDao.queryByCondtion(query);
List<CoreOrg> list = query.getList(); List<CoreOrg> list = query.getList();
queryListAfter(list); handleStrDictValueFields(list);
OrgItem root = platformService.buildOrg(); OrgItem root = platformService.buildOrg();
// 处理父机构名称显示,没有用sql查询是考虑到跨数据库 // 处理父机构名称显示,没有用sql查询是考虑到跨数据库
for (CoreOrg org : list) { for (CoreOrg org : list) {
...@@ -46,7 +46,7 @@ public class OrgConsoleService extends CoreBaseService<CoreOrg> { ...@@ -46,7 +46,7 @@ public class OrgConsoleService extends CoreBaseService<CoreOrg> {
public void queryUserByCondition(PageQuery<CoreUser> query) { public void queryUserByCondition(PageQuery<CoreUser> query) {
orgDao.queryUserByCondtion(query); orgDao.queryUserByCondtion(query);
queryListAfter(query.getList()); handleStrDictValueFields(query.getList());
} }
/** /**
......
package com.ibeetl.admin.console.service; package com.ibeetl.admin.console.service;
import com.ibeetl.admin.core.entity.CoreOrg;
import java.util.List; import java.util.List;
import java.util.Optional;
import org.beetl.sql.core.SQLManager; import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.engine.PageQuery; import org.beetl.sql.core.engine.PageQuery;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -46,7 +44,6 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> { ...@@ -46,7 +44,6 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> {
/** /**
* 根据删标记获取全部角色集合 * 根据删标记获取全部角色集合
* *
* @param delFlagEnum 删除标记
* @return * @return
*/ */
public List<CoreRole> queryAllList() { public List<CoreRole> queryAllList() {
...@@ -60,7 +57,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> { ...@@ -60,7 +57,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> {
*/ */
public void queryByCondtion(PageQuery query) { public void queryByCondtion(PageQuery query) {
roleDao.queryByCondtion(query); roleDao.queryByCondtion(query);
super.queryListAfter(query.getList()); super.handleStrDictValueFields(query.getList());
} }
public PageQuery<CoreUser> queryRoleUser(PageQuery query) { public PageQuery<CoreUser> queryRoleUser(PageQuery query) {
...@@ -75,7 +72,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> { ...@@ -75,7 +72,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> {
user.set("orgId1Text", root.findChild((long) orgId1).getName()); user.set("orgId1Text", root.findChild((long) orgId1).getName());
} }
// 再次处理数据字典 // 再次处理数据字典
this.queryListAfter(list); this.handleStrDictValueFields(list);
return ret; return ret;
} }
...@@ -92,6 +89,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> { ...@@ -92,6 +89,7 @@ public class RoleConsoleService extends CoreBaseService<CoreRole> {
return role; return role;
} }
@Override
public boolean deleteById(List<Long> ids) { public boolean deleteById(List<Long> ids) {
if (ids == null || ids.isEmpty()) { if (ids == null || ids.isEmpty()) {
throw new PlatformException("删除数据ID不能为空"); throw new PlatformException("删除数据ID不能为空");
......
...@@ -52,7 +52,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> { ...@@ -52,7 +52,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
*/ */
public void queryByCondtion(PageQuery<CoreUser> query) { public void queryByCondtion(PageQuery<CoreUser> query) {
PageQuery<CoreUser> ret = userConsoleDao.queryByCondtion(query); PageQuery<CoreUser> ret = userConsoleDao.queryByCondtion(query);
queryListAfter(ret.getList()); handleStrDictValueFields(ret.getList());
} }
/** /**
......
...@@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("functions") @RequestMapping("admin/functions")
public class FunctionElController { public class FunctionElController {
@Autowired @Autowired
......
...@@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RequestMapping("menus") @RequestMapping("admin/menus")
@RestController @RestController
public class MenuElController { public class MenuElController {
......
package com.ibeetl.admin.console.web;
import com.ibeetl.admin.console.service.OrgConsoleService;
import com.ibeetl.admin.console.service.UserConsoleService;
import com.ibeetl.admin.console.web.query.OrgQuery;
import com.ibeetl.admin.console.web.query.OrgUserQuery;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.annotation.Query;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.AnnotationUtil;
import com.ibeetl.admin.core.util.ValidateConfig;
import com.ibeetl.admin.core.web.JsonResult;
import java.util.Date;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 描述: 组织机构 controller
*
* @author : xiandafu
*/
@Slf4j
@RequestMapping("/admin/orgs")
@Controller
public class OrgConsoleElController {
@Autowired
private OrgConsoleService orgConsoleService;
@Autowired
UserConsoleService userConsoleService;
@Autowired
CorePlatformService platformService;
/**
* 组织机构列表 分页
*
* @param condtion
* 查询条件
*/
@GetMapping("/list")
@Function("org.query")
@ResponseBody
public JsonResult<PageQuery<CoreOrg>> list(OrgQuery condtion) {
PageQuery page = condtion.getPageQuery();
orgConsoleService.queryByCondtion(page);
return JsonResult.success(page);
}
/**
* 获取列表查询条件
*/
@GetMapping("/list/condition")
@Function("org.query")
@ResponseBody
public JsonResult<List<Map<String, Object>>> listCondtion() {
List<Map<String, Object>> list = AnnotationUtil
.getInstance().getAnnotations(Query.class, OrgQuery.class);
return JsonResult.success(list);
}
/**
* 保存数据
*/
@PostMapping("/save")
@Function("org.save")
@ResponseBody
public JsonResult<Long> save(@Validated(ValidateConfig.ADD.class) @RequestBody CoreOrg org,
BindingResult result) {
if (result.hasErrors()) {
return JsonResult.failMessage(result.toString());
}
org.setCreateTime(new Date());
orgConsoleService.save(org);
platformService.clearOrgCache();
return JsonResult.success(org.getId());
}
/**
* 更新数据
*/
@PutMapping("/update")
@Function("org.update")
@ResponseBody
public JsonResult<String> update(
@Validated(ValidateConfig.UPDATE.class) @RequestBody CoreOrg org) {
boolean success = orgConsoleService.updateTemplate(org);
if (success) {
platformService.clearOrgCache();
return JsonResult.successMessage("保存成功");
} else {
return JsonResult.failMessage("保存失败");
}
}
/**
* 删除组织机构
*
* @param ids
* 组织id,多个用“,”隔开
*/
@DeleteMapping("/delete")
@Function("org.delete")
@ResponseBody
public JsonResult delete(@RequestBodyPlus("ids") List<Long> ids) {
orgConsoleService.deleteById(ids);
this.platformService.clearOrgCache();
return JsonResult.success();
}
@GetMapping("/user/list")
@Function("org.query")
@ResponseBody
public JsonResult<PageQuery<CoreUser>> getUsers(OrgUserQuery userQuery) {
PageQuery<CoreUser> page = userQuery.getPageQuery();
orgConsoleService.queryUserByCondition(page);
return JsonResult.success(page);
}
}
package com.ibeetl.admin.console.web; package com.ibeetl.admin.console.web;
import static com.ibeetl.admin.core.util.enums.FunctionTypeEnum.FN1;
import static com.ibeetl.admin.core.util.enums.FunctionTypeEnum.FN2;
import cn.hutool.core.util.StrUtil;
import com.ibeetl.admin.console.service.FunctionConsoleService; import com.ibeetl.admin.console.service.FunctionConsoleService;
import com.ibeetl.admin.console.service.OrgConsoleService;
import com.ibeetl.admin.console.service.RoleConsoleService; import com.ibeetl.admin.console.service.RoleConsoleService;
import com.ibeetl.admin.console.web.dto.RoleDataAccessFunction; import com.ibeetl.admin.console.web.dto.RoleDataAccessFunction;
import com.ibeetl.admin.console.web.query.RoleQuery; import com.ibeetl.admin.console.web.query.RoleQuery;
import com.ibeetl.admin.console.web.query.RoleUserQuery; import com.ibeetl.admin.console.web.query.RoleUserQuery;
import com.ibeetl.admin.console.web.vo.RoleDataFunctionVO;
import com.ibeetl.admin.core.annotation.Function; import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.annotation.Query; import com.ibeetl.admin.core.annotation.Query;
import com.ibeetl.admin.core.annotation.RequestBodyPlus; import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.entity.CoreRole; import com.ibeetl.admin.core.entity.CoreRole;
import com.ibeetl.admin.core.entity.CoreUser; import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.entity.ElCascaderData; import com.ibeetl.admin.core.entity.ElCascaderData;
import com.ibeetl.admin.core.rbac.DataAccess;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.service.CorePlatformService; import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.AnnotationUtil; import com.ibeetl.admin.core.util.AnnotationUtil;
import com.ibeetl.admin.core.util.ConvertUtil;
import com.ibeetl.admin.core.util.ValidateConfig; import com.ibeetl.admin.core.util.ValidateConfig;
import com.ibeetl.admin.core.web.JsonResult; import com.ibeetl.admin.core.web.JsonResult;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.engine.PageQuery; import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -37,27 +43,33 @@ import org.springframework.web.bind.annotation.RequestMapping; ...@@ -37,27 +43,33 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
/** 角色管理功能相关 */ /**
* 角色管理功能相关
*/
@Slf4j @Slf4j
@RequestMapping("/admin/roles") @RequestMapping("/admin/roles")
@RestController @RestController
public class RoleConsoleElController { public class RoleConsoleElController {
@Autowired private RoleConsoleService roleConsoleService; @Autowired
private RoleConsoleService roleConsoleService;
@Autowired private FunctionConsoleService functionConsoleService; @Autowired
private FunctionConsoleService functionConsoleService;
@Autowired CorePlatformService platformService; @Autowired
CorePlatformService platformService;
@Autowired
DataAccessFactory dataAccessFactory;
/** /**
* 列表页、 分页数据 * 列表页、 分页数据
*
* @param condtion
* @return
*/ */
@GetMapping("/list") @GetMapping("/list")
@Function("role.query") @Function("role.query")
public JsonResult<PageQuery> list(RoleQuery condtion) { public JsonResult<PageQuery> list(RoleQuery condtion) {
PageQuery page = condtion.getPageQuery(); PageQuery page = condtion.getPageQuery();
roleConsoleService.queryByCondtion(page); roleConsoleService.queryByCondtion(page);
return JsonResult.success(page); return JsonResult.success(page);
...@@ -66,18 +78,18 @@ public class RoleConsoleElController { ...@@ -66,18 +78,18 @@ public class RoleConsoleElController {
@GetMapping("/all") @GetMapping("/all")
@Function("role.query") @Function("role.query")
public JsonResult<List<CoreRole>> all() { public JsonResult<List<CoreRole>> all() {
List<CoreRole> list = roleConsoleService.queryAllPermissionList(); List<CoreRole> list = roleConsoleService.queryAllPermissionList();
return JsonResult.success(list); return JsonResult.success(list);
} }
/** /**
* 获取列表查询条件 * 获取列表查询条件
*
* @return
*/ */
@PostMapping("/list/condition") @PostMapping("/list/condition")
@Function("role.query") @Function("role.query")
public JsonResult<List<Map<String, Object>>> listCondtion() { public JsonResult<List<Map<String, Object>>> listCondtion() {
List<Map<String, Object>> list = List<Map<String, Object>> list =
AnnotationUtil.getInstance().getAnnotations(Query.class, RoleQuery.class); AnnotationUtil.getInstance().getAnnotations(Query.class, RoleQuery.class);
return JsonResult.success(list); return JsonResult.success(list);
...@@ -85,12 +97,11 @@ public class RoleConsoleElController { ...@@ -85,12 +97,11 @@ public class RoleConsoleElController {
/** /**
* 保存 * 保存
*
* @return
*/ */
@PostMapping("/add") @PostMapping("/add")
@Function("role.add") @Function("role.add")
public JsonResult addRole(@Validated(ValidateConfig.ADD.class) @RequestBody CoreRole role) { public JsonResult addRole(@Validated(ValidateConfig.ADD.class) @RequestBody CoreRole role) {
CoreRole role1 = roleConsoleService.queryByCode(role.getCode()); CoreRole role1 = roleConsoleService.queryByCode(role.getCode());
if (role1 != null) { if (role1 != null) {
return JsonResult.failMessage("用户编号已存在"); return JsonResult.failMessage("用户编号已存在");
...@@ -104,13 +115,11 @@ public class RoleConsoleElController { ...@@ -104,13 +115,11 @@ public class RoleConsoleElController {
/** /**
* 更新 * 更新
*
* @param role
* @return
*/ */
@PutMapping("/update") @PutMapping("/update")
@Function("role.edit") @Function("role.edit")
public JsonResult<String> update(@Validated(ValidateConfig.UPDATE.class) @RequestBody CoreRole role) { public JsonResult<String> update(
@Validated(ValidateConfig.UPDATE.class) @RequestBody CoreRole role) {
boolean success = roleConsoleService.update(role); boolean success = roleConsoleService.update(role);
...@@ -124,13 +133,11 @@ public class RoleConsoleElController { ...@@ -124,13 +133,11 @@ public class RoleConsoleElController {
/** /**
* 查询角色信息 * 查询角色信息
*
* @param id
* @return
*/ */
@GetMapping("/view") @GetMapping("/view")
@Function("role.query") @Function("role.query")
public JsonResult<CoreRole> queryInfo(Long id) { public JsonResult<CoreRole> queryInfo(Long id) {
CoreRole role = roleConsoleService.queryById(id); CoreRole role = roleConsoleService.queryById(id);
return JsonResult.success(role); return JsonResult.success(role);
} }
...@@ -138,28 +145,33 @@ public class RoleConsoleElController { ...@@ -138,28 +145,33 @@ public class RoleConsoleElController {
/** /**
* (批量)删除 * (批量)删除
* *
* @param ids 角色id * @param ids
* @return * 角色id
*/ */
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Function("role.delete") @Function("role.delete")
public JsonResult delete(@RequestBodyPlus("ids") List<Long> ids) { public JsonResult delete(@RequestBodyPlus("ids") List<Long> ids) {
roleConsoleService.deleteById(ids); roleConsoleService.deleteById(ids);
return JsonResult.success(); return JsonResult.success();
} }
/** 查询角色下授权用户列表 */ /**
* 查询角色下授权用户列表
*/
@PostMapping("/user/list") @PostMapping("/user/list")
@Function("role.user.query") @Function("role.user.query")
public JsonResult<PageQuery<CoreUser>> userList(RoleUserQuery query) { public JsonResult<PageQuery<CoreUser>> userList(RoleUserQuery query) {
PageQuery page = query.getPageQuery(); PageQuery page = query.getPageQuery();
PageQuery<CoreUser> pageQuery = roleConsoleService.queryRoleUser(page); PageQuery<CoreUser> pageQuery = roleConsoleService.queryRoleUser(page);
return JsonResult.success(page); return JsonResult.success(page);
} }
@PostMapping("/function/ids") @GetMapping("/function/ids")
@Function("role.function.query") @Function("role.function.query")
public JsonResult<List<Long>> getFunctionIdByRole(Long roleId) { public JsonResult<List<Long>> getFunctionIdByRole(Long roleId) {
List<Long> list = functionConsoleService.getFunctionByRole(roleId); List<Long> list = functionConsoleService.getFunctionByRole(roleId);
return JsonResult.success(list); return JsonResult.success(list);
} }
...@@ -167,24 +179,27 @@ public class RoleConsoleElController { ...@@ -167,24 +179,27 @@ public class RoleConsoleElController {
@GetMapping("/function/queryFunction") @GetMapping("/function/queryFunction")
@Function("role.function.query") @Function("role.function.query")
public JsonResult<List<RoleDataAccessFunction>> getQueryFunctionByRole(Long roleId) { public JsonResult<List<RoleDataAccessFunction>> getQueryFunctionByRole(Long roleId) {
List<RoleDataAccessFunction> list = functionConsoleService.getQueryFunctionByRole(roleId); List<RoleDataAccessFunction> list = functionConsoleService.getQueryFunctionByRole(roleId);
return JsonResult.success(list); return JsonResult.success(list);
} }
@PostMapping("/function/update") @PutMapping("/function/update")
@Function("role.function.edit") @Function("role.function.edit")
public JsonResult updateFunction(Long roleId, String ids) { public JsonResult updateRoleFunctions(@RequestBodyPlus("roleId") Long roleId,
List<Long> all = ConvertUtil.str2longs(ids); @NotNull @RequestBodyPlus("functions") List<CoreFunction> functions) {
//数据库只保存菜单功能和功能点功能
List<Long> all = functions.stream()
.filter(v -> StrUtil.equalsAny(v.getType(), FN2.getValue(), FN1.getValue()))
.map(CoreFunction::getId).collect(Collectors.toList());
List<Long> addIds = new ArrayList<Long>(); List<Long> addIds = new ArrayList<Long>();
List<Long> delIds = new ArrayList<Long>(); List<Long> delIds = new ArrayList<Long>();
List<Long> dbs = functionConsoleService.getFunctionByRole(roleId); List<Long> dbs = functionConsoleService.getFunctionByRole(roleId);
Iterator<Long> it = all.iterator();
for (Long id : all) { for (Long id : all) {
if (!dbs.contains(id)) { if (!dbs.contains(id)) {
addIds.add(id); addIds.add(id);
} }
} }
for (Long id : dbs) { for (Long id : dbs) {
if (!all.contains(id)) { if (!all.contains(id)) {
delIds.add(id); delIds.add(id);
...@@ -194,9 +209,37 @@ public class RoleConsoleElController { ...@@ -194,9 +209,37 @@ public class RoleConsoleElController {
return JsonResult.success(); return JsonResult.success();
} }
@PostMapping("/function/updateDataAccess") @GetMapping("/data_function/list")
@Function("role.function.updateDataAccess") @Function("role.function.updateDataAccess")
public JsonResult updateFunctionDataAccess(Long roleId, Long fnId, Integer accessType) { public JsonResult<List<RoleDataFunctionVO>> functionDataList(
Long roleId) {
List<RoleDataAccessFunction> list = functionConsoleService.getQueryFunctionByRole(roleId);
List<DataAccess> dataAccessList = dataAccessFactory.all();
List<RoleDataFunctionVO> roleDataFunctionVOList = new ArrayList<>();
for (RoleDataAccessFunction accessFunction : list) {
RoleDataFunctionVO vo = new RoleDataFunctionVO();
roleDataFunctionVOList.add(vo);
List<ElCascaderData> elCascaderDataList = new ArrayList<>(dataAccessList.size());
vo.setAccesses(elCascaderDataList);
vo.setLabel(accessFunction.getName());
for (DataAccess dataAccess : dataAccessList) {
ElCascaderData cascaderData = new ElCascaderData();
elCascaderDataList.add(cascaderData);
cascaderData.setTail(accessFunction);
cascaderData.setId(dataAccess.getType());
cascaderData.setLabel(dataAccess.getName());
cascaderData.setValue(dataAccess.getType());
}
}
return JsonResult.success(roleDataFunctionVOList);
}
@PostMapping("/data_function/updateDataAccess")
@Function("role.function.updateDataAccess")
public JsonResult updateFunctionDataAccess(@RequestBodyPlus("roleId") Long roleId,
@RequestBodyPlus("fnId") Long fnId, @RequestBodyPlus("accessType") Integer accessType) {
RoleDataAccessFunction data = new RoleDataAccessFunction(); RoleDataAccessFunction data = new RoleDataAccessFunction();
data.setRoleId(roleId); data.setRoleId(roleId);
data.setId(fnId); data.setId(fnId);
...@@ -209,9 +252,11 @@ public class RoleConsoleElController { ...@@ -209,9 +252,11 @@ public class RoleConsoleElController {
@PostMapping("/function/dataAccess.do") @PostMapping("/function/dataAccess.do")
@Function("role.function.updateDataAccess") @Function("role.function.updateDataAccess")
public ModelAndView datapage(Long roleId) { public ModelAndView datapage(Long roleId) {
List<RoleDataAccessFunction> list = functionConsoleService.getQueryFunctionByRole(roleId); List<RoleDataAccessFunction> list = functionConsoleService.getQueryFunctionByRole(roleId);
ModelAndView view = new ModelAndView("/admin/role/dataConfigPart.html"); ModelAndView view = new ModelAndView("/admin/role/dataConfigPart.html");
view.addObject("list", list); view.addObject("list", list);
return view; return view;
} }
} }
...@@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.ResponseBody; ...@@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@Validated @Validated
@RequestMapping("users") @RequestMapping("admin/users")
@RestController @RestController
public class UserConsoleElController { public class UserConsoleElController {
......
package com.ibeetl.admin.console.web.dto; package com.ibeetl.admin.console.web.dto;
import com.ibeetl.admin.core.entity.CoreFunction; import com.ibeetl.admin.core.entity.CoreFunction;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class RoleDataAccessFunction extends CoreFunction { public class RoleDataAccessFunction extends CoreFunction {
private Integer dataAccessType; private Integer dataAccessType;
private Long roleId; private Long roleId;
......
package com.ibeetl.admin.console.web.vo;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
/**
* element 对应的select组件数据模型
*/
@Data
public class ElSelectModel {
private Object id;
private String label;
private Object value;
/**
* 额外的数据
*/
private Map<String, Object> tail=new HashMap<>(3);
}
package com.ibeetl.admin.console.web.vo;
import com.ibeetl.admin.core.entity.ElCascaderData;
import java.util.List;
import lombok.Data;
@Data
public class RoleDataFunctionVO {
private String label;
private List<ElCascaderData> accesses;
}
...@@ -80,7 +80,7 @@ public class SpringWebMvcConfigurer implements WebMvcConfigurer, InitializingBea ...@@ -80,7 +80,7 @@ public class SpringWebMvcConfigurer implements WebMvcConfigurer, InitializingBea
registry.addInterceptor(new HttpRequestInterceptor()).addPathPatterns("/**"); registry.addInterceptor(new HttpRequestInterceptor()).addPathPatterns("/**");
registry registry
.addInterceptor(new SessionInterceptor(userService)) .addInterceptor(new SessionInterceptor(userService))
.excludePathPatterns("/user/login", "/error", "/user/logout") .excludePathPatterns("/**/login", "/**/error", "/**/logout")
.addPathPatterns("/**"); .addPathPatterns("/**");
} }
......
...@@ -90,6 +90,7 @@ public class BeetlConf { ...@@ -90,6 +90,7 @@ public class BeetlConf {
}; };
} }
/** /**
* 对BeetlSql 的多数据源中每个数据源单独自定义配置 * 对BeetlSql 的多数据源中每个数据源单独自定义配置
* *
......
...@@ -8,14 +8,17 @@ import org.beetl.sql.core.mapping.type.TypeParameter; ...@@ -8,14 +8,17 @@ import org.beetl.sql.core.mapping.type.TypeParameter;
/** /**
* 字典字段的映射处理器 * 字典字段的映射处理器
* */ */
public class DictTypeHandler extends JavaSqlTypeHandler { public class DictTypeHandler extends JavaSqlTypeHandler {
@Override @Override
public Object getValue(TypeParameter typePara) throws SQLException { public Object getValue(TypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) { if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null; return null;
} }
String val = typePara.getRs().getString(typePara.getIndex()); String val = typePara.getRs().getString(typePara.getIndex());
return new DictType(val); return new DictType(val);
} }
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment