3 Commits

Author SHA1 Message Date
暮光:城中城
421575583d !17 升级fastjson版本到1.2.83,1.2.83版本之前存在代码执行漏洞风险,CVE-2022-25845
Merge pull request !17 from test5/N/A
2023-03-27 00:23:58 +00:00
test5
f88b55acbe 升级fastjson版本到1.2.83,1.2.83版本之前存在代码执行漏洞风险,CVE-2022-25845
升级fastjson版本到1.2.83,1.2.83版本之前存在代码执行漏洞风险,CVE-2022-25845

Signed-off-by: test5 <12512785+test5sdssd@user.noreply.gitee.com>
2023-03-26 14:41:27 +00:00
暮光:城中城
a050e5a991 无须登陆的db模块版本 2020-04-29 11:55:08 +08:00
481 changed files with 27570 additions and 52945 deletions

71
.gitignore vendored
View File

@@ -1,70 +1,5 @@
tmlog*.lck
dependency-reduced-pom.xml
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
# Created by .ignore support plugin (hsz.mobi)
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
!*/build/*.java
!*/build/*.html
!*/build/*.xml
### VS Code ###
.vscode/
# rebel
rebel.xml
### gradle构建 ###
*.gradle
### office ###
# 忽略office文件打开临时文件 #
[~$]*.*
tmlog.lck
zyplayer-doc-es/src/test/
zyplayer-doc-manage/tmlog.lck
zyplayer-doc-other/src/
zyplayer-doc-other/zyplayer-doc-annotation/src/main/resources/
zyplayer-doc-other/zyplayer-doc-annotation/src/test/
zyplayer-doc-other/zyplayer-doc-dubbo-libs/dependency-reduced-pom.xml
zyplayer-doc-other/zyplayer-doc-dubbo-libs/src/
zyplayer-doc-other/zyplayer-doc-test/src/main/java/com/zyplayer/doc/test/db/
zyplayer-doc-other/zyplayer-doc-test/src/test/
tmlog*.lck
tmlog*.log

118
README.md
View File

@@ -1,64 +1,96 @@
# zyplayer-doc
## 项目介绍
zyplayer-doc是一款在线文档工具现有swagger 文档、dubbo文档、数据库文档、WIKI文档、ElasticSearch文档管理端具有人员管理、权限管理功能等功能。项目后端使用spring-boot、mybatis-plus等框架前端使用zui、Vue、element-ui等框架。为开发者服务欢迎有想法的一起来写给个Star鼓励下呗您的一个Star是快速迭代的动力源泉
#### 项目介绍
定位为所有文档的管理项目,swagger文档、dubbo文档、数据库文档、wiki、ElasticSearch文档....等,提供一整套的解决方案,为开发者服务欢迎有想法的一起来写给个Star鼓励下呗您的一个Star是快速迭代的动力源泉
欢迎加群讨论QQ群号466363173
体验地址:[http://doc.zyplayer.com](http://doc.zyplayer.com/zyplayer-doc-manage/) 账号zyplayer 密码123456
体验地址:[http://doc.zyplayer.com](http://doc.zyplayer.com/zyplayer-doc-manage/) 需登录 账号zyplayer 密码123456 未运行dubbo服务不能体验dubbo文档调试
各模块的详细使用文档地址,部署必看:
[详细部署文档](http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb)
[http://doc.zyplayer.com/zyplayer-doc-manage/open-wiki.html?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb](http://doc.zyplayer.com/zyplayer-doc-manage/open-wiki.html?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb)
## 功能介绍
### 一、zyplayer-doc-manage 文档管理后台
1. 具有项目模块导航,人员及权限管理功能,分组管理等功能。
2. 集成了本项目内的各个子模块功能,是各模块的协调管理模块。
### 二、zyplayer-doc-db 数据库文档
1. 支持MySQL、SQLServer、Oracle、PostgreSQL数据库。
2. 支持数据库表、字段文档查看修改表文档导出、建表语句DDL导出。
3. 支持SQL执行、表数据预览、不同数据库之间的数据互导支持多数据源管理。
4. 支持按人员、按数据源对用户授权,可给用户 库表注释查看、注释修改、SQL执行、函数修改等粒度的授权。
5. 支持库函数和存储过程的增删改查,修改记录查询等。
6. 目标是取代Navicat做一个小而精的开源免费的在线数据库管理工具。
#### 软件架构
##### 一、zyplayer-doc-core 一些核心、公用的类
###、zyplayer-doc-wiki wiki文档工具
1. 在线管理公司、项目及任意形式的文档
2. 文档支持按空间划分,按人员分组授权,支持空间收藏和空间内的文档开放访问。
3. 文档支持编辑、查看、评论、上传附件、历史版本查看、页面权限控制、文档搜索等功能。
4. 文档编辑支持html富文本方式编辑和markdown的方式编辑。
5. 本工具使用的开源工具有vue、element-ui、mavon-editor、wangeditor等。
6. 参考学习了Atlassian Confluence文档工具进行开发争取作为该软件的开源免费替代产品同时作为内部文档管理工具最好的存在。
##### 二、zyplayer-doc-db 数据库文档
> 原[zyplayer-doc-db](https://gitee.com/zyplayer/zyplayer-doc-db),具有数据库文档的查看、管理、导出等功能
###、zyplayer-doc-swagger swagger的UI及整套解决方案
1. 支持swagger的文档展示接口调试文档导出等解析速度快界面设计走心。
2. 支持将所有的swagger文档进行统一管理支持全局参数设置请求参数缓存下次自动填充等。
3. 目标是解决swagger官方文档查看及接口调试不方便的问题。
##### 三、zyplayer-doc-manage 可以单独部署的文档管理后台
> 后端使用spring-boot、mybatis-plus、springfox-swagger等框架前端使用[zui](http://zui.sexy/)、[Vue](https://cn.vuejs.org/)、[element-ui](http://element-cn.eleme.io)等框架
### 五、zyplayer-doc-dubbo 将dubbo的文档在线化管理
1. 支持zookeeper、nacos的注册中心文档获取支持在线调试接口
> 已集成三套优秀swagger文档前端[zyplayer-doc-swagger](https://gitee.com/zyplayer/zyplayer-doc)、[swagger-bootstrap-ui](https://gitee.com/xiaoym/swagger-bootstrap-ui)、[springfox-swagger-ui](https://github.com/springfox/springfox/tree/master/springfox-swagger-ui)
### 六、zyplayer-doc-es ElasticSearch文档工具
1. 支持ElasticSearch的文档查看和执行DSL查询的功能
> 已集成本项目内的各子模块,可直接使用
### 七、其他
1. zyplayer-doc-ui 前面各模块的前端UI源码
2. zyplayer-doc-core 一些核心、公用的类
3. zyplayer-doc-data 数据库层面的交互
4. zyplayer-doc-grpc grpc文档工具
5. zyplayer-doc-other 一些测试
##### 四、zyplayer-doc-swagger 原[swagger-mg-ui](https://gitee.com/zyplayer/swagger-mg-ui)swagger的UI及整套解决方案
> 具有 后端存储、代理请求、模拟返回、所有文档管理 等一系列原创功能不止UI
## 运行方式
##### 五、zyplayer-doc-dubbo 将dubbo的文档在线化管理
> 支持zookeeper、nacos的注册中心文档获取支持在线调试接口
1. 创建数据库zyplayer_doc_manage执行脚本[全量建表语句.sql](https://gitee.com/zyplayer/zyplayer-doc/blob/master/zyplayer-doc-manage/src/main/resources/sql/全量建表语句.sql)
##### 六、zyplayer-doc-wiki wiki文档工具
> 支持文档创建、展示,文件上传、下载,空间隔离,开放文档访问等
##### 七、zyplayer-doc-grpc grpc文档工具
> 用比较变态的方式实现了grpc的文档和在线调试功能通过http的方式来请求grpc的接口
> 默认未开启此功能如需使用需要在zyplayer-doc-manage项目中开启@EnableDocGrpc注解
##### 八、zyplayer-doc-es ElasticSearch文档工具
> 支持ElasticSearch的文档查看和执行DSL查询的功能
#### 运行方式
1. 创建数据库zyplayer_doc_manage执行脚本[zyplayer_doc_manage.1.0.4.sql](https://gitee.com/zyplayer/zyplayer-doc/blob/master/zyplayer-doc-manage/src/main/resources/sql/zyplayer_doc_manage.1.0.4.sql)
2. 修改zyplayer-doc-manage项目的application.yml配置文件里面的数据库账号密码
3. 启动zyplayer-doc-manage项目访问地址http://127.0.0.1:8083/zyplayer-doc-manage/
更多详细的使用部署文档http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb
#### 模块介绍
##### 一、zyplayer-doc-swagger
1.`zyplayer-doc-swagger`->`文档管理`->`文档地址管理` 页可以管理`任意地址`的文档在集成的三套UI中都可以直接查看和调试这里配置的文档不用对UI做任何调整只要标准的UI集成进来也可以直接用
2. 文档展示配置,`自动填充请求参数`:可配置填充级别,`强制重写域名`:文档在本地想调试线上接口的好帮手,`自动保存请求参数`:不用每次输入
3. 可配置`全局参数`放在header或param里的
4. 可对`调试数据`进行管理
5. `模拟返回`:前端自行调试接口的好帮手
6. 私人强迫症级定制化文档展示,清晰明了,参数支持批量编辑,每一条线的间距都考量了半天,支持`文件上传`的调试需要指定dataType = `File``MultipartFile`,例:
@ApiImplicitParam(name = "file", value = "文件", dataType = "File", allowMultiple = true)
7. 后端代理请求,后端存储,不会存在任何跨域问题
##### 二、zyplayer-doc-db
1. 支持Mysql、SQLserver的数据库表、字段文档查看修改导出展示关系图等功能
2. 支持多数据源,在`zyplayer-doc-manage` -> `application.yml` -> `zyplayer.doc.db.dbConfigList` 处配置多个数据库连接即可
##### 三、zyplayer-doc-dubbo
1. `zyplayer-doc-manage` -> `application.yml` -> `zyplayer.dubbo.zookeeper.url` 配置zookeeper地址
2. `zyplayer-doc-manage` -> `application.yml` -> `zyplayer.dubbo.nacos.url` 配置nacos服务地址
3. 默认找zookeeper未配置再找nacos的配置
4. 支持文档查找、文档编辑、在线调试接口
5. 自动获取参数列表需要指定的类存在,所以请在 pom.xml -> dependencies 最后加上服务所在的包后端才能通过Class.forName("xx");来找到参数列表,减少录入成本
6. 数组或List参数调试参数录入格式例[1,2] 后端通过JSON工具转成指定类型有不支持的类型时欢迎反馈
##### 四、zyplayer-doc-manage
1. 整合了上面两个功能到此项目,较少熟悉成本,`git clone`下来即可运行
2. 具有简单的`权限管理``人员管理`功能
3. 使用最新的一些技术框架,很简单,初学者拿来学习也是很不错的
更多详细的使用部署文档http://doc.zyplayer.com/zyplayer-doc-manage/open-wiki.html?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb
#### 界面展示
![主页面](https://images.gitee.com/uploads/images/2020/0516/125840_d6284954_596905.png "主页面.png")
![数据库文档](https://images.gitee.com/uploads/images/2020/0516/130017_254f9559_596905.png "数据库文档.png")
![wiki文档](https://images.gitee.com/uploads/images/2020/0516/130119_bc2f5021_596905.png "wiki文档.png")

View File

@@ -4,7 +4,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc</artifactId>
<version>1.0.8</version>
<version>1.0.4</version>
<packaging>pom</packaging>
<name>zyplayer-doc</name>
@@ -14,7 +14,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<fastjson.version>1.2.53</fastjson.version>
<fastjson.version>1.2.83</fastjson.version>
<elasticsearch.version>7.2.0</elasticsearch.version>
</properties>

View File

@@ -1,15 +1,12 @@
# update
# 本文件用于已部署好的系统检测自己是否需要升级使用,怕有人担心安全一类的问题,所以不提供服务器接口来做
lastVersion=1.0.8
upgradeContent=1、控制台支持对用户进行分组管理\
2、WIKI文档的空间改为独立页面管理支持对分组进行授权\
3、WIKI文档的空间支持收藏可只展示收藏的空间\
4、WIKI文档搜索时忽略大小写 #I2CG72\
5、WIKI文档开放wiki页文档样式修改支持图片预览\
6、数据库模块在库表导出页面增加导出整个库的DDL建表语句功能\
7、数据库模块增加对postgresql的支持感谢群成员“辽宁-天平”提供;\
8、数据库模块支持存储过程和函数的增删改查增加函数修改授权\
9、数据库模块优化数据源管理优化查看页面
lastVersion=1.0.4
upgradeContent=1、swagger文档支持给文档地址重命名下拉时方便查看\
2、swagger文档去掉“文档地址管理”页管理统一改为“详细地址管理”\
3、数据库文档增加权限控制分为库表查看权注释修改权SQL执行权\
4、数据库文档增加SQL执行器可直接执行SQL\
5、数据库文档表信息增加表的状态信息展示\
6、缓存及其他细节优化;
upgradeUrl=https://gitee.com/zyplayer/zyplayer-doc/releases
nextStep=
nextStep=1、ElasticSearch文档优化

View File

@@ -5,5 +5,5 @@
模块的详细使用文档地址,部署必看:
http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb
http://doc.zyplayer.com/zyplayer-doc-manage/open-wiki.html?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb

View File

@@ -6,7 +6,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-core</artifactId>
<version>1.0.8</version>
<version>1.0.4</version>
<name>zyplayer-doc-core</name>
<url>http://maven.apache.org</url>
@@ -52,10 +52,5 @@
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0.6</version>
</dependency>
</dependencies>
</dependencies>
</project>

View File

@@ -1,227 +1,214 @@
package com.zyplayer.doc.core.json;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiModelProperty;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;
/**
* 文档返回数据格式
*
* @author 暮光:城中城
* @since 2018年8月21日
*/
public class DocResponseJson<T> implements ResponseJson<T> {
private static SerializeConfig mapping = new SerializeConfig();
static {
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
}
@ApiModelProperty(value = "状态码")
private Integer errCode;
@ApiModelProperty(value = "返回值说明")
private String errMsg;
@ApiModelProperty(value = "返回数据")
private Object data;
@ApiModelProperty(value = "")
private Long total;
@ApiModelProperty(value = "当前页")
private Integer pageNum;
@ApiModelProperty(value = "每页条")
private Integer pageSize;
@ApiModelProperty(value = "总页数")
private Integer totalPage;
public DocResponseJson() {
this.errCode = 200;
}
public DocResponseJson(Object data) {
this.setData(data);
this.errCode = 200;
}
public DocResponseJson(int errCode, String errMsg) {
super();
this.errCode = errCode;
this.errMsg = errMsg;
}
public DocResponseJson(int errCode, String errMsg, Object data) {
super();
this.setData(data);
this.errCode = errCode;
this.errMsg = errMsg;
}
public DocResponseJson(Integer errCode) {
super();
this.errCode = errCode;
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Object getData() {
return data;
}
public void setData(Object data) {
if (null != data) {
if (data instanceof PageInfo) {
PageInfo<?> pageInfo = (PageInfo<?>) data;
this.data = pageInfo.getList();
this.total = pageInfo.getTotal();
this.pageNum = pageInfo.getPageNum();
this.pageSize = pageInfo.getPageSize();
this.totalPage = pageInfo.getPages();
} else if (data instanceof IPage) {
IPage<?> iPage = (IPage<?>) data;
this.data = iPage.getRecords();
this.total = iPage.getTotal();
this.pageNum = (int) iPage.getCurrent();
this.pageSize = (int) iPage.getSize();
this.totalPage = (int) iPage.getPages();
} else {
this.data = data;
}
}
}
/**
* 提示语
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> warn(String errMsg) {
return new DocResponseJson<T>(300, errMsg);
}
/**
* 错误
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> error(String errMsg) {
return new DocResponseJson<T>(500, errMsg);
}
/**
* 失败
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> failure(int errCode, String errMsg) {
return new DocResponseJson<T>(errCode, errMsg);
}
/**
* 成功的返回方法
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> ok() {
return new DocResponseJson<>();
}
/**
* 成功的返回方法
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> ok(Object data) {
if (data == null) {
return DocResponseJson.ok();
}
DocResponseJson<T> responseJson = new DocResponseJson<>();
responseJson.setData(data);
return responseJson;
}
public String toJson() {
return JSON.toJSONString(this, mapping);
}
public void send(HttpServletResponse response) {
try {
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().write(toJson());
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isOk() {
return Objects.equals(this.errCode, 200);
}
@Override
public String toString() {
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
}
}
package com.zyplayer.doc.core.json;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiModelProperty;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
/**
* 文档返回数据格式
*
* @author 暮光:城中城
* @since 2018年8月21日
*/
public class DocResponseJson<T> implements ResponseJson<T> {
private static SerializeConfig mapping = new SerializeConfig();
static {
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
}
@ApiModelProperty(value = "状态码")
private Integer errCode;
@ApiModelProperty(value = "返回值说明")
private String errMsg;
@ApiModelProperty(value = "返回数据")
private Object data;
@ApiModelProperty(value = "总数")
private Long total;
@ApiModelProperty(value = "当前页")
private Integer pageNum;
@ApiModelProperty(value = "每页条")
private Integer pageSize;
@ApiModelProperty(value = "总页")
private Integer totalPage;
public DocResponseJson() {
this.errCode = 200;
}
public DocResponseJson(Object data) {
this.setData(data);
this.errCode = 200;
}
public DocResponseJson(int errCode, String errMsg) {
super();
this.errCode = errCode;
this.errMsg = errMsg;
}
public DocResponseJson(int errCode, String errMsg, Object data) {
super();
this.setData(data);
this.errCode = errCode;
this.errMsg = errMsg;
}
public DocResponseJson(Integer errCode) {
super();
this.errCode = errCode;
}
public Integer getErrCode() {
return errCode;
}
public void setErrCode(Integer errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Object getData() {
return data;
}
public void setData(Object data) {
if (null != data) {
if (data instanceof PageInfo) {
PageInfo<?> pageInfo = (PageInfo<?>) data;
this.data = pageInfo.getList();
this.total = pageInfo.getTotal();
this.pageNum = pageInfo.getPageNum();
this.pageSize = pageInfo.getPageSize();
this.totalPage = pageInfo.getPages();
} else {
this.data = data;
}
}
}
/**
* 提示语
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> warn(String errMsg) {
return new DocResponseJson<T>(300, errMsg);
}
/**
* 错误
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> error(String errMsg) {
return new DocResponseJson<T>(500, errMsg);
}
/**
* 失败
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> failure(int errCode, String errMsg) {
return new DocResponseJson<T>(errCode, errMsg);
}
/**
* 成功的返回方法
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> ok() {
return new DocResponseJson<>();
}
/**
* 成功的返回方法
*
* @author 暮光:城中城
* @since 2018年8月7日
* @return
*/
public static <T> DocResponseJson<T> ok(Object data) {
if (data == null) {
return DocResponseJson.ok();
}
DocResponseJson<T> responseJson = new DocResponseJson<>();
responseJson.setData(data);
return responseJson;
}
public String toJson() {
return JSON.toJSONString(this, mapping);
}
public void send(HttpServletResponse response) {
try {
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().write(toJson());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
}
}

View File

@@ -5,5 +5,5 @@
模块的详细使用文档地址,部署必看:
http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb
http://doc.zyplayer.com/zyplayer-doc-manage/open-wiki.html?pageId=1&space=23f3f59a60824d21af9f7c3bbc9bc3cb

View File

@@ -6,7 +6,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-data</artifactId>
<version>1.0.8</version>
<version>1.0.4</version>
<parent>
<groupId>org.springframework.boot</groupId>
@@ -23,7 +23,7 @@
<velocity.engine.core.version>2.0</velocity.engine.core.version>
<dozer.core.version>6.1.0</dozer.core.version>
<alibaba.druid.version>1.1.9</alibaba.druid.version>
<zyplayer.doc.version>1.0.8</zyplayer.doc.version>
<zyplayer.doc.version>1.0.4</zyplayer.doc.version>
<elasticsearch.version>7.2.0</elasticsearch.version>
</properties>
@@ -67,11 +67,6 @@
<artifactId>ojdbc6</artifactId>
<version>12.1.0.1-atlassian-hosted</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>

View File

@@ -44,7 +44,7 @@ public class AuthAspect {
HttpServletRequest request = ThreadLocalUtil.getHttpServletRequest();
StringBuffer requestURL = request.getRequestURL();
String requestURLStr = URLEncoder.encode(requestURL.toString(), "utf-8");
return new ModelAndView("redirect:./#/user/login?redirect=" + requestURLStr);
return new ModelAndView("redirect:#/user/login?redirect=" + requestURLStr);
} else if (returnType.isAssignableFrom(Map.class)) {
return Maps.newHashMap();
}

View File

@@ -20,7 +20,7 @@ import javax.servlet.http.HttpServletResponse;
@Component
public class DocLoginOriginInterceptor implements HandlerInterceptor {
@Value("${zyplayer.doc.manage.originDomainRegex:}")
@Value("${zyplayer.doc.manage.originDomainRegex:''}")
private String originDomainRegex;
@Override

View File

@@ -13,7 +13,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;
@@ -55,19 +54,17 @@ public class MybatisPlusConfig {
private String username;
@Value("${zyplayer.doc.manage.datasource.password}")
private String password;
@Resource
private PaginationInterceptor paginationInterceptor;
@Bean(name = "manageDatasource")
public DataSource manageDatasource() throws Exception {
return DruidDataSourceUtil.createDataSource(driverClassName, url, username, password, false);
public DataSource manageDatasource() {
return DruidDataSourceUtil.createDataSource(driverClassName, url, username, password);
}
@Bean(name = "manageSqlSessionFactory")
public MybatisSqlSessionFactoryBean manageSqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(manageDatasource());
sqlSessionFactoryBean.setPlugins(new Interceptor[]{SQL_LOG_INTERCEPTOR, MYSQL_PAGE_HELPER, paginationInterceptor});
sqlSessionFactoryBean.setPlugins(new Interceptor[]{SQL_LOG_INTERCEPTOR, MYSQL_PAGE_HELPER});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/manage/*Mapper.xml"));

View File

@@ -1,10 +1,7 @@
package com.zyplayer.doc.data.config.security;
import com.zyplayer.doc.data.utils.CachePrefix;
import com.zyplayer.doc.data.utils.CacheUtil;
import java.util.Set;
/**
* 用户工具类
* @author 暮光:城中城
@@ -57,21 +54,6 @@ public class DocUserUtil {
public static void setCurrentUser(String accessToken, DocUserDetails docUser) {
DOC_USER_DETAILS.set(docUser);
CacheUtil.put(accessToken, docUser);
CacheUtil.put(CachePrefix.LOGIN_USER_ID_TOKEN + docUser.getUserId(), accessToken);
}
/**
* 设置当前用户权限
*/
public static void setUserAuth(Long userId, Set<String> userAuthSet) {
String userToken = CacheUtil.get(CachePrefix.LOGIN_USER_ID_TOKEN + userId);
if (userToken != null) {
DocUserDetails docUser = CacheUtil.get(userToken);
if (docUser != null) {
docUser.setAuthorities(userAuthSet);
CacheUtil.put(userToken, docUser);
}
}
}
/**

View File

@@ -69,11 +69,6 @@ public class DbDatasource implements Serializable {
*/
private String name;
/**
* 数据源分组
*/
private String groupName;
public Long getId() {
return id;
}
@@ -160,12 +155,4 @@ public class DbDatasource implements Serializable {
public void setName(String name) {
this.name = name;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
}

View File

@@ -1,158 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 数据库函数修改日志
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public class DbProcLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 数据源ID
*/
private Long datasourceId;
/**
* 所属数据库
*/
private String procDb;
/**
* 名字
*/
private String procName;
/**
* 类型
*/
private String procType;
/**
* 函数创建SQL
*/
private String procBody;
/**
* 保存状态 1=成功 2=失败
*/
private Integer status;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getDatasourceId() {
return datasourceId;
}
public void setDatasourceId(Long datasourceId) {
this.datasourceId = datasourceId;
}
public String getProcDb() {
return procDb;
}
public void setProcDb(String procDb) {
this.procDb = procDb;
}
public String getProcName() {
return procName;
}
public void setProcName(String procName) {
this.procName = procName;
}
public String getProcType() {
return procType;
}
public void setProcType(String procType) {
this.procType = procType;
}
public String getProcBody() {
return procBody;
}
public void setProcBody(String procBody) {
this.procBody = procBody;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "DbProcLog{" +
"id=" + id +
", datasourceId=" + datasourceId +
", procDb=" + procDb +
", procName=" + procName +
", procType=" + procType +
", procBody=" + procBody +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
"}";
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -1,106 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户组
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public class UserGroup implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 分组名
*/
private String name;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroup{" +
"id=" + id +
", name=" + name +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -1,145 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户组在各项目内的授权关系
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class UserGroupAuth implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群ID
*/
private Long groupId;
/**
* 授权数据的ID
*/
private Long dataId;
/**
* 授权类型,依据各项目自己定义
*/
private Integer authType;
/**
* 项目类型 1=WIKI模块 2=数据库模块
*/
private Integer projectType;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public Long getDataId() {
return dataId;
}
public void setDataId(Long dataId) {
this.dataId = dataId;
}
public Integer getProjectType() {
return projectType;
}
public void setProjectType(Integer projectType) {
this.projectType = projectType;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroupAuth{" +
"id=" + id +
", groupId=" + groupId +
", dataId=" + dataId +
", projectType=" + projectType +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
public Integer getAuthType() {
return authType;
}
public void setAuthType(Integer authType) {
this.authType = authType;
}
}

View File

@@ -1,118 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户和用户组关系表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public class UserGroupRelation implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 群ID
*/
private Long groupId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserGroupRelation{" +
"id=" + id +
", groupId=" + groupId +
", userId=" + userId +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -1,197 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户消息表
* </p>
*
* @author 暮光:城中城
* @since 2020-06-23
*/
public class UserMessage implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 系统类型 1=manage 2=wiki 3=db
*/
private Integer sysType;
/**
* 消息类型 1=普通文本消息 2=wiki文档创建 3=wiki文档删除 4=wiki文档编辑 5=wiki文档权限修改 6=wiki文档评论 7=wiki文档删除评论
*/
private Integer msgType;
/**
* 消息关联的数据ID
*/
private Long dataId;
/**
* 消息关联的数据说明
*/
private String dataDesc;
/**
* 消息内容
*/
private String msgContent;
/**
* 消息状态 0=未读 1=已读 2=已删除
*/
private Integer msgStatus;
/**
* 操作人用户ID
*/
private Long operatorUserId;
/**
* 操作人用户名
*/
private String operatorUserName;
/**
* 影响用户ID
*/
private Long affectUserId;
/**
* 影响人用户名
*/
private String affectUserName;
/**
* 接收人用户ID
*/
private Long acceptUserId;
/**
* 创建时间
*/
private Date creationTime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getSysType() {
return sysType;
}
public void setSysType(Integer sysType) {
this.sysType = sysType;
}
public Integer getMsgType() {
return msgType;
}
public void setMsgType(Integer msgType) {
this.msgType = msgType;
}
public Long getDataId() {
return dataId;
}
public void setDataId(Long dataId) {
this.dataId = dataId;
}
public String getDataDesc() {
return dataDesc;
}
public void setDataDesc(String dataDesc) {
this.dataDesc = dataDesc;
}
public Integer getMsgStatus() {
return msgStatus;
}
public void setMsgStatus(Integer msgStatus) {
this.msgStatus = msgStatus;
}
public Long getOperatorUserId() {
return operatorUserId;
}
public void setOperatorUserId(Long operatorUserId) {
this.operatorUserId = operatorUserId;
}
public String getOperatorUserName() {
return operatorUserName;
}
public void setOperatorUserName(String operatorUserName) {
this.operatorUserName = operatorUserName;
}
public Long getAcceptUserId() {
return acceptUserId;
}
public void setAcceptUserId(Long acceptUserId) {
this.acceptUserId = acceptUserId;
}
public Date getCreationTime() {
return creationTime;
}
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
}
@Override
public String toString() {
return "UserMessage{" +
"id=" + id +
", sysType=" + sysType +
", msgType=" + msgType +
", dataId=" + dataId +
", dataDesc=" + dataDesc +
", msgStatus=" + msgStatus +
", operatorUserId=" + operatorUserId +
", operatorUserName=" + operatorUserName +
", acceptUserId=" + acceptUserId +
", creationTime=" + creationTime +
"}";
}
public String getMsgContent() {
return msgContent;
}
public void setMsgContent(String msgContent) {
this.msgContent = msgContent;
}
public Long getAffectUserId() {
return affectUserId;
}
public void setAffectUserId(Long affectUserId) {
this.affectUserId = affectUserId;
}
public String getAffectUserName() {
return affectUserName;
}
public void setAffectUserName(String affectUserName) {
this.affectUserName = affectUserName;
}
}

View File

@@ -1,105 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户设置表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class UserSetting implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 设置的名字
*/
private String name;
/**
* 设置的值
*/
private String value;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "UserSetting{" +
"id=" + id +
", userId=" + userId +
", name=" + name +
", value=" + value +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -98,11 +98,6 @@ public class WikiPage implements Serializable {
* 顺序
*/
private Integer seqNo;
/**
* 编辑框类型 1=HTML 2=Markdown
*/
private Integer editorType;
public Long getId() {
return id;
@@ -238,12 +233,4 @@ public class WikiPage implements Serializable {
", seqNo=" + seqNo +
"}";
}
public Integer getEditorType() {
return editorType;
}
public void setEditorType(Integer editorType) {
this.editorType = editorType;
}
}

View File

@@ -84,11 +84,6 @@ public class WikiPageFile implements Serializable {
*/
private Integer downloadNum;
/**
* 文件大小
*/
private Long fileSize;
public Long getId() {
return id;
}
@@ -199,12 +194,4 @@ public class WikiPageFile implements Serializable {
public void setDownloadNum(Integer downloadNum) {
this.downloadNum = downloadNum;
}
public Long getFileSize() {
return fileSize;
}
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
}

View File

@@ -1,118 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author 暮光:城中城
* @since 2020-09-05
*/
public class WikiPageHistory implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 页面ID
*/
private Long pageId;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人名字
*/
private String createUserName;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
/**
* git提交记录ID
*/
private String gitCommitId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getPageId() {
return pageId;
}
public void setPageId(Long pageId) {
this.pageId = pageId;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
public String getGitCommitId() {
return gitCommitId;
}
public void setGitCommitId(String gitCommitId) {
this.gitCommitId = gitCommitId;
}
@Override
public String toString() {
return "WikiPageHistory{" +
"id=" + id +
", pageId=" + pageId +
", createUserId=" + createUserId +
", createUserName=" + createUserName +
", createTime=" + createTime +
", delFlag=" + delFlag +
", gitCommitId=" + gitCommitId +
"}";
}
}

View File

@@ -1,92 +0,0 @@
package com.zyplayer.doc.data.repository.manage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
/**
* <p>
* 用户空间收藏记录表
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public class WikiSpaceFavorite implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键自增ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 空间ID
*/
private Long spaceId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除标记 0=正常 1=已删除
*/
private Integer delFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getSpaceId() {
return spaceId;
}
public void setSpaceId(Long spaceId) {
this.spaceId = spaceId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getDelFlag() {
return delFlag;
}
public void setDelFlag(Integer delFlag) {
this.delFlag = delFlag;
}
@Override
public String toString() {
return "WikiSpaceFavorite{" +
"id=" + id +
", spaceId=" + spaceId +
", userId=" + userId +
", createTime=" + createTime +
", delFlag=" + delFlag +
"}";
}
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 数据库函数修改日志 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public interface DbProcLogMapper extends BaseMapper<DbProcLog> {
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import org.apache.ibatis.annotations.Select;
/**
* <p>
* 用户组在各项目内的授权关系 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserGroupAuthMapper extends BaseMapper<UserGroupAuth> {
@Select("select a.id from user_group_auth a join user_group_relation b on a.group_id=b.group_id and b.user_id=#{userId} " +
"where a.project_type=#{projectType} and a.auth_type=#{authType} and a.data_id=#{spaceId} and b.del_flag=0")
Long haveAuth(Long spaceId, Integer projectType, Integer authType, Long userId);
}

View File

@@ -1,23 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 用户组 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupMapper extends BaseMapper<UserGroup> {
@Select("select b.id, b.user_no, b.email, b.phone, b.sex, b.user_name, b.avatar from user_group_relation a join user_info b on b.id=a.user_id where a.group_id=#{groupId} and a.del_flag=0 and b.del_flag=0")
List<UserInfo> groupUserList(@Param("groupId") Long groupId);
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户和用户组关系表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupRelationMapper extends BaseMapper<UserGroupRelation> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserMessage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户消息表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2020-06-23
*/
public interface UserMessageMapper extends BaseMapper<UserMessage> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户设置表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserSettingMapper extends BaseMapper<UserSetting> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.WikiPageHistory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2020-09-05
*/
public interface WikiPageHistoryMapper extends BaseMapper<WikiPageHistory> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.repository.manage.mapper;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 用户空间收藏记录表 Mapper 接口
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface WikiSpaceFavoriteMapper extends BaseMapper<WikiSpaceFavorite> {
}

View File

@@ -3,7 +3,6 @@ package com.zyplayer.doc.data.repository.manage.vo;
import java.util.Date;
public class SpaceNewsVo {
private String space;
private Long spaceId;
private Long pageId;
private Integer zanNum;
@@ -104,12 +103,4 @@ public class SpaceNewsVo {
public void setSpaceId(Long spaceId) {
this.spaceId = spaceId;
}
public String getSpace() {
return space;
}
public void setSpace(String space) {
this.space = space;
}
}

View File

@@ -5,8 +5,4 @@ public class DocAuthConst {
public static final String WIKI = "WIKI_";
public static final String DB_DATASOURCE_MANAGE = "DB_DATASOURCE_MANAGE";
public static final String ES_DATASOURCE_MANAGE = "ES_DATASOURCE_MANAGE";
public static final String USER_MANAGE = "USER_MANAGE";
public static final String AUTH_MANAGE = "AUTH_MANAGE";
public static final String AUTH_ASSIGN = "AUTH_ASSIGN";
}

View File

@@ -1,21 +0,0 @@
package com.zyplayer.doc.data.repository.support.consts;
public enum UserMsgSysType {
// 系统类型 1=manage 2=wiki 3=db
MANAGE(1), WIKI(2), DB(2),
;
UserMsgSysType(int type) {
this.type = type;
}
private int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -1,25 +0,0 @@
package com.zyplayer.doc.data.repository.support.consts;
public enum UserMsgType {
// 消息类型 1=普通文本消息 2=wiki文档创建 3=wiki文档删除 4=wiki文档编辑 5=wiki文档权限修改
// 6=wiki文档评论 7=wiki文档删除评论 8=wiki文档上传附件 9=wiki文档修改了父级 10=wiki文档点赞 11=wiki文档附件删除
SIMPLE(1), WIKI_PAGE_CREATE(2), WIKI_PAGE_DELETE(3), WIKI_PAGE_UPDATE(4), WIKI_PAGE_AUTH(5),
WIKI_PAGE_COMMENT(6), WIKI_PAGE_COMMENT_DEL(7), WIKI_PAGE_UPLOAD(8), WIKI_PAGE_PARENT(9), WIKI_PAGE_ZAN(10), WIKI_PAGE_FILE_DEL(11),
WIKI_PAGE_ZAN_CANCEL(12),
// 增加类型的时候需要在zyplayer-doc-ui/wiki-ui/src/components/layouts/GlobalLayout.vue showUserMessage()方法添加类型支持
;
UserMsgType(int type) {
this.type = type;
}
private int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -1,5 +0,0 @@
package com.zyplayer.doc.data.repository.support.consts;
public class UserSettingConst {
public static final String WIKI_ONLY_SHOW_FAVORITE = "wiki_only_show_favorite";
}

View File

@@ -13,15 +13,15 @@ import java.util.ArrayList;
import java.util.List;
public class CodeGenerator {
public static void main(String[] args) {
final String moduleName = "manage";
// final String[] tableName = { "zyplayer_storage", "auth_info", "user_auth", "user_info", "db_datasource" };
// final String[] tableName = { "wiki_space", "wiki_page", "wiki_page_content", "wiki_page_file", "wiki_page_comment", "wiki_page_zan" };
// final String[] tableName = { "db_datasource", "es_datasource", "db_favorite" };
final String[] tableName = {"db_proc_log"};
final String[] tableName = { "db_transfer_task" };
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
@@ -35,7 +35,7 @@ public class CodeGenerator {
gc.setServiceName("%sService");
gc.setControllerName("Generator%sController");
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/zyplayer_doc_manage?useUnicode=true&useSSL=false&characterEncoding=utf8");
@@ -44,7 +44,7 @@ public class CodeGenerator {
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
// 包配置
final PackageConfig pc = new PackageConfig();
pc.setModuleName(null);
@@ -55,7 +55,7 @@ public class CodeGenerator {
pc.setService("service.manage");
pc.setServiceImpl("service.manage.impl");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
@@ -73,7 +73,7 @@ public class CodeGenerator {
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
@@ -90,5 +90,5 @@ public class CodeGenerator {
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}

View File

@@ -24,11 +24,11 @@ import java.util.concurrent.ConcurrentHashMap;
public class ElasticSearchUtil {
private static Logger logger = LoggerFactory.getLogger(ElasticSearchUtil.class);
@Value(value = "${zyplayer.doc.manage.elasticsearch.hostPort:}")
@Value(value = "${zyplayer.doc.manage.elasticsearch.hostPort:''}")
private String hostAndPort;
@Value(value = "${zyplayer.doc.manage.elasticsearch.scheme:}")
@Value(value = "${zyplayer.doc.manage.elasticsearch.scheme:''}")
private String esScheme;
@Value("${zyplayer.doc.manage.elasticsearch.open:}")
@Value("${zyplayer.doc.manage.elasticsearch.open:''}")
private String elasticsearchOpen;
private static final Object createLock = new Object();

View File

@@ -37,7 +37,6 @@ import java.util.concurrent.TimeUnit;
/**
* es抽象类
*
* @author 暮光:城中城
* @since 2019-07-07
*/
@@ -102,7 +101,6 @@ public abstract class EsAbstractService<T> {
/**
* 多条件 模糊查询查询前100条
*
* @param condition 查询条件
*/
public List<T> getDataByCondition(List<EsQueryColumn> condition) {
@@ -111,10 +109,9 @@ public abstract class EsAbstractService<T> {
/**
* 多条件 模糊查询
*
* @param condition 查询条件
* @param condition 查询条件
* @param startIndex 开始行
* @param pageSize 每页数量
* @param pageSize 每页数量
*/
public EsPage<T> getDataByCondition(List<EsQueryColumn> condition, String[] fields, Integer startIndex, Integer pageSize) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
@@ -150,13 +147,11 @@ public abstract class EsAbstractService<T> {
});
return this.getDataByQuery(boolQueryBuilder, fields, startIndex, pageSize);
}
/**
* 多条件 模糊查询
*
* @param queryBuilders 查询条件
* @param startIndex 开始行
* @param pageSize 每页数量
* @param startIndex 开始行
* @param pageSize 每页数量
*/
public EsPage<T> getDataByQuery(QueryBuilder queryBuilders, String[] fields, Integer startIndex, Integer pageSize) {
// 设置高亮标签
@@ -213,5 +208,5 @@ public abstract class EsAbstractService<T> {
esPage.setData(tableList);
return esPage;
}
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 数据库函数修改日志 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
public interface DbProcLogService extends IService<DbProcLog> {
}

View File

@@ -3,8 +3,6 @@ package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Set;
/**
* <p>
* 用户权限表 服务类
@@ -14,6 +12,5 @@ import java.util.Set;
* @since 2019-05-31
*/
public interface UserAuthService extends IService<UserAuth> {
Set<String> getUserAuthSet(Long id);
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户组在各项目内的授权关系 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserGroupAuthService extends IService<UserGroupAuth> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户和用户组关系表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupRelationService extends IService<UserGroupRelation> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户组 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
public interface UserGroupService extends IService<UserGroup> {
}

View File

@@ -1,22 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.repository.manage.entity.UserMessage;
import com.zyplayer.doc.data.repository.support.consts.UserMsgSysType;
import com.zyplayer.doc.data.repository.support.consts.UserMsgType;
/**
* <p>
* 用户消息表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2020-06-23
*/
public interface UserMessageService extends IService<UserMessage> {
void addWikiMessage(UserMessage userMessage);
UserMessage createUserMessage(DocUserDetails currentUser, Long pageId, String dataDesc, UserMsgSysType sysType, UserMsgType msgType);
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户设置表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface UserSettingService extends IService<UserSetting> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.WikiPageHistory;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author 暮光:城中城
* @since 2020-09-05
*/
public interface WikiPageHistoryService extends IService<WikiPageHistory> {
}

View File

@@ -1,16 +0,0 @@
package com.zyplayer.doc.data.service.manage;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户空间收藏记录表 服务类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
public interface WikiSpaceFavoriteService extends IService<WikiSpaceFavorite> {
}

View File

@@ -1,11 +1,9 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
import com.zyplayer.doc.data.repository.manage.mapper.DbHistoryMapper;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -27,13 +25,10 @@ public class DbHistoryServiceImpl extends ServiceImpl<DbHistoryMapper, DbHistory
@Override
public void saveHistory(String content, Long datasourceId) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
DbHistory dbHistory = new DbHistory();
dbHistory.setDatasourceId(datasourceId);
dbHistory.setContent(content);
dbHistory.setCreateTime(new Date());
dbHistory.setCreateUserId(currentUser.getUserId());
dbHistory.setCreateUserName(currentUser.getUsername());
dbHistory.setYn(1);
this.save(dbHistory);
// 删除多余的数据

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.zyplayer.doc.data.repository.manage.mapper.DbProcLogMapper;
import com.zyplayer.doc.data.service.manage.DbProcLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 数据库函数修改日志 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-04-26
*/
@Service
public class DbProcLogServiceImpl extends ServiceImpl<DbProcLogMapper, DbProcLog> implements DbProcLogService {
}

View File

@@ -1,18 +1,11 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserAuthMapper;
import com.zyplayer.doc.data.service.manage.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 用户权限表 服务实现类
@@ -23,25 +16,5 @@ import java.util.stream.Collectors;
*/
@Service
public class UserAuthServiceImpl extends ServiceImpl<UserAuthMapper, UserAuth> implements UserAuthService {
@Resource
AuthInfoService authInfoService;
@Override
public Set<String> getUserAuthSet(Long id) {
QueryWrapper<UserAuth> authWrapper = new QueryWrapper<>();
authWrapper.eq("user_id", id).eq("del_flag", "0");
List<UserAuth> userAuthList = this.list(authWrapper);
Set<String> userAuthSet = Collections.emptySet();
if (userAuthList != null && userAuthList.size() > 0) {
List<Long> authIdList = userAuthList.stream().map(UserAuth::getAuthId).collect(Collectors.toList());
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authIdList);
Map<Long, String> authNameMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
userAuthSet = userAuthList.stream().map(val -> {
String authName = Optional.ofNullable(authNameMap.get(val.getAuthId())).orElse("");
return authName + Optional.ofNullable(val.getAuthCustomSuffix()).orElse("");
}).collect(Collectors.toSet());
}
return userAuthSet;
}
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupAuth;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper;
import com.zyplayer.doc.data.service.manage.UserGroupAuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户组在各项目内的授权关系 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class UserGroupAuthServiceImpl extends ServiceImpl<UserGroupAuthMapper, UserGroupAuth> implements UserGroupAuthService {
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroupRelation;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupRelationMapper;
import com.zyplayer.doc.data.service.manage.UserGroupRelationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户和用户组关系表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
@Service
public class UserGroupRelationServiceImpl extends ServiceImpl<UserGroupRelationMapper, UserGroupRelation> implements UserGroupRelationService {
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserGroup;
import com.zyplayer.doc.data.repository.manage.mapper.UserGroupMapper;
import com.zyplayer.doc.data.service.manage.UserGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户组 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-08
*/
@Service
public class UserGroupServiceImpl extends ServiceImpl<UserGroupMapper, UserGroup> implements UserGroupService {
}

View File

@@ -1,118 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.repository.manage.entity.UserMessage;
import com.zyplayer.doc.data.repository.manage.mapper.UserMessageMapper;
import com.zyplayer.doc.data.repository.support.consts.UserMsgSysType;
import com.zyplayer.doc.data.repository.support.consts.UserMsgType;
import com.zyplayer.doc.data.service.manage.UserMessageService;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Objects;
/**
* <p>
* 用户消息表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2020-06-23
*/
@Service
public class UserMessageServiceImpl extends ServiceImpl<UserMessageMapper, UserMessage> implements UserMessageService {
@Override
public UserMessage createUserMessage(DocUserDetails currentUser, Long dataId, String dataDesc, UserMsgSysType sysType, UserMsgType msgType) {
UserMessage userMessage = new UserMessage();
userMessage.setDataId(dataId);
userMessage.setDataDesc(dataDesc);
userMessage.setSysType(sysType.getType());
userMessage.setMsgType(msgType.getType());
userMessage.setOperatorUserId(currentUser.getUserId());
userMessage.setOperatorUserName(currentUser.getUsername());
return userMessage;
}
@Override
public void addWikiMessage(UserMessage userMessage) {
// 初始值,操作人的消息默认为已读
userMessage.setMsgStatus(1);
userMessage.setCreationTime(new Date());
// 操作人
userMessage.setAcceptUserId(userMessage.getOperatorUserId());
this.setWikiMsgContentForOperator(userMessage);
this.save(userMessage);
// 影响人
if (userMessage.getAffectUserId() != null && !Objects.equals(userMessage.getAffectUserId(), userMessage.getOperatorUserId())) {
userMessage.setId(null);
// 收影响人的消息为未读
userMessage.setMsgStatus(0);
userMessage.setAcceptUserId(userMessage.getAffectUserId());
this.setWikiMsgContentForAffect(userMessage);
this.save(userMessage);
}
// 后期可以添加文档的关注人等
}
/**
* 给操作人发通知的内容
*
* @param userMessage
*/
private void setWikiMsgContentForOperator(UserMessage userMessage) {
if (Objects.equals(UserMsgType.WIKI_PAGE_UPLOAD.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您在‘%s文档内上传了一个附件", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_AUTH.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您修改了‘%s文档内%s的权限", userMessage.getDataDesc(), userMessage.getAffectUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_COMMENT.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您评论了‘%s", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_COMMENT_DEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您删除了‘%s文档的评论", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_PARENT.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您修改了‘%s文档的父级", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_DELETE.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您删除了‘%s", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_CREATE.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您创建了‘%s", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_UPDATE.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您修改了‘%s", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_ZAN.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您赞同了‘%s", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_FILE_DEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您删除了‘%s文档的一个附件", userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_ZAN_CANCEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您取消了对‘%s文档的赞同", userMessage.getDataDesc()));
}
}
/**
* 给影响人发通知的内容
*
* @param userMessage
*/
private void setWikiMsgContentForAffect(UserMessage userMessage) {
if (Objects.equals(UserMsgType.WIKI_PAGE_UPLOAD.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("%s为您的文档%s上传了附件", userMessage.getOperatorUserName(), userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_AUTH.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您在‘%s文档内的权限被%s修改了", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_COMMENT.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档收到了来自%s的评论", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_COMMENT_DEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("%s删除了您的文档%s的一条评论", userMessage.getOperatorUserName(), userMessage.getDataDesc()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_PARENT.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档被%s修改了父级", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_DELETE.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档被%s删除了", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_UPDATE.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档被%s修改了", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_ZAN.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档收到了%s的赞同", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_FILE_DEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("您的‘%s文档被%s删除了一个附件", userMessage.getDataDesc(), userMessage.getOperatorUserName()));
} else if (Objects.equals(UserMsgType.WIKI_PAGE_ZAN_CANCEL.getType(), userMessage.getMsgType())) {
userMessage.setMsgContent(String.format("%s取消了对文档%s的赞同", userMessage.getOperatorUserName(), userMessage.getDataDesc()));
}
}
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.UserSetting;
import com.zyplayer.doc.data.repository.manage.mapper.UserSettingMapper;
import com.zyplayer.doc.data.service.manage.UserSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户设置表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class UserSettingServiceImpl extends ServiceImpl<UserSettingMapper, UserSetting> implements UserSettingService {
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.WikiPageHistory;
import com.zyplayer.doc.data.repository.manage.mapper.WikiPageHistoryMapper;
import com.zyplayer.doc.data.service.manage.WikiPageHistoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2020-09-05
*/
@Service
public class WikiPageHistoryServiceImpl extends ServiceImpl<WikiPageHistoryMapper, WikiPageHistory> implements WikiPageHistoryService {
}

View File

@@ -2,14 +2,8 @@ package com.zyplayer.doc.data.service.manage.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.UserMessage;
import com.zyplayer.doc.data.repository.manage.entity.WikiPage;
import com.zyplayer.doc.data.repository.manage.mapper.WikiPageMapper;
import com.zyplayer.doc.data.repository.support.consts.UserMsgSysType;
import com.zyplayer.doc.data.repository.support.consts.UserMsgType;
import com.zyplayer.doc.data.service.manage.UserMessageService;
import com.zyplayer.doc.data.service.manage.WikiPageService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
@@ -31,8 +25,6 @@ public class WikiPageServiceImpl extends ServiceImpl<WikiPageMapper, WikiPage> i
@Resource
WikiPageMapper wikiPageMapper;
@Resource
UserMessageService userMessageService;
@Override
public void changeParent(WikiPage wikiPage, Integer beforeSeq, Integer afterSeq) {
@@ -51,28 +43,10 @@ public class WikiPageServiceImpl extends ServiceImpl<WikiPageMapper, WikiPage> i
wikiPage.setSeqNo(lastSeq + 1);
}
this.updateById(wikiPage);
// 给相关人发送消息
WikiPage wikiPageSel = this.getById(wikiPage.getId());
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
UserMessage userMessage = userMessageService.createUserMessage(currentUser, wikiPageSel.getId(), wikiPageSel.getName(), UserMsgSysType.WIKI, UserMsgType.WIKI_PAGE_PARENT);
userMessage.setAffectUserId(wikiPageSel.getCreateUserId());
userMessage.setAffectUserName(wikiPageSel.getCreateUserName());
userMessageService.addWikiMessage(userMessage);
}
@Override
public void deletePage(WikiPage wikiPage) {
// 给相关人发送消息
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
UserMessage userMessage = userMessageService.createUserMessage(currentUser, wikiPage.getId(), wikiPage.getName(), UserMsgSysType.WIKI, UserMsgType.WIKI_PAGE_DELETE);
userMessage.setAffectUserId(wikiPage.getCreateUserId());
userMessage.setAffectUserName(wikiPage.getCreateUserName());
userMessageService.addWikiMessage(userMessage);
// 递归删除
this.deletePageAndSon(wikiPage);
}
private void deletePageAndSon(WikiPage wikiPage) {
wikiPage.setDelFlag(1);
this.updateById(wikiPage);
@@ -86,7 +60,7 @@ public class WikiPageServiceImpl extends ServiceImpl<WikiPageMapper, WikiPage> i
// 递归删除子页面
for (WikiPage page : wikiPageList) {
wikiPage.setId(page.getId());
this.deletePageAndSon(wikiPage);
this.deletePage(wikiPage);
}
}
}

View File

@@ -50,7 +50,7 @@ public class WikiPageZanServiceImpl extends ServiceImpl<WikiPageZanMapper, WikiP
wikiPageZan.setCreateUserName(currentUser.getUsername());
this.save(wikiPageZan);
}
int numAdd = Objects.equals(wikiPageZan.getYn(), 1) ? 1 : -1;
int numAdd = wikiPageZan.getYn() == 1 ? 1 : -1;
wikiPageMapper.updateZanNum(wikiPageZan.getPageId(), numAdd);
}
}

View File

@@ -1,20 +0,0 @@
package com.zyplayer.doc.data.service.manage.impl;
import com.zyplayer.doc.data.repository.manage.entity.WikiSpaceFavorite;
import com.zyplayer.doc.data.repository.manage.mapper.WikiSpaceFavoriteMapper;
import com.zyplayer.doc.data.service.manage.WikiSpaceFavoriteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户空间收藏记录表 服务实现类
* </p>
*
* @author 暮光:城中城
* @since 2021-02-09
*/
@Service
public class WikiSpaceFavoriteServiceImpl extends ServiceImpl<WikiSpaceFavoriteMapper, WikiSpaceFavorite> implements WikiSpaceFavoriteService {
}

View File

@@ -3,5 +3,4 @@ package com.zyplayer.doc.data.utils;
public class CachePrefix {
public static final String WIKI_LOCK_PAGE = "WIKI_LOCK_PAGE_";
public static final String DB_EDITOR_DATA_CACHE = "DB_EDITOR_DATA_CACHE_";
public static final String LOGIN_USER_ID_TOKEN = "LOGIN_USER_ID_TOKEN_";
}

View File

@@ -10,37 +10,41 @@ public class DruidDataSourceUtil {
private static AtomicLong nameId = new AtomicLong(0);
public static DruidDataSource createDataSource(String driverClassName, String url, String username, String password, boolean breakAfterAcquireFailure) throws Exception {
// 数据源配置
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(2);
dataSource.setMinIdle(2);
dataSource.setMaxActive(50);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setValidationQuery("select 1");
dataSource.setMaxWait(3000);
dataSource.setTimeBetweenEvictionRunsMillis(60000);
dataSource.setMinEvictableIdleTimeMillis(3600000);
// 重试3次失败退出源码里是errorCount > connectionErrorRetryAttempts所以写成2就是3次、、、
// CreateConnectionThread 源码在这个类里面
dataSource.setConnectionErrorRetryAttempts(2);
dataSource.setBreakAfterAcquireFailure(breakAfterAcquireFailure);// false连接出错后不退出等待下个定时周期重试true失败不再重试
dataSource.setTimeBetweenConnectErrorMillis(180000);// 连接出错后重试时间间隔3分钟
dataSource.setName("zyplayer-doc-db-" + nameId.incrementAndGet());
if (url.contains("oracle")) {
dataSource.setValidationQuery("select 1 from dual");
public static DruidDataSource createDataSource(String driverClassName, String url, String username, String password){
try {
// 数据源配置
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(2);
dataSource.setMinIdle(2);
dataSource.setMaxActive(50);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setValidationQuery("select 1");
dataSource.setMaxWait(3000);
dataSource.setTimeBetweenEvictionRunsMillis(60000);
dataSource.setMinEvictableIdleTimeMillis(3600000);
// 重试3次失败退出源码里是errorCount > connectionErrorRetryAttempts所以写成2就是3次、、、
// CreateConnectionThread 源码在这个类里面
dataSource.setConnectionErrorRetryAttempts(2);
dataSource.setBreakAfterAcquireFailure(true);
dataSource.setName("zyplayer-doc-db-" + nameId.incrementAndGet());
if (url.contains("oracle")) {
dataSource.setValidationQuery("select 1 from dual");
}
DruidPooledConnection connection = dataSource.getConnection(3000);
if (connection == null) {
throw new ConfirmException("尝试获取该数据源连接失败:" + url);
}
connection.recycle();
return dataSource;
} catch (Throwable e) {
e.printStackTrace();
}
DruidPooledConnection connection = dataSource.getConnection(3000);
if (connection == null) {
throw new ConfirmException("尝试获取该数据源连接失败:" + url);
}
connection.recycle();
return dataSource;
return null;
}
}

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.DbProcLogMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupAuthMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserGroupRelationMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserMessageMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.UserSettingMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.WikiPageHistoryMapper">
</mapper>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.data.repository.manage.mapper.WikiSpaceFavoriteMapper">
</mapper>

View File

@@ -1,6 +1,53 @@
# zyplayer-doc-db
#### 项目介绍
数据库文档、管理工具,对表注释、字段注释进行查看、修改、导出等操作,支持字段或注释的模糊查询
数据库文档工具,网页方式管理,只需两步即可对表注释、字段注释进行查看、修改、导出等操作,支持字段或注释的模糊查询,只有一个单独的页面,方便集成到已有的管理系统里面,本工具不对数据源进行管理,因为后台管理系统肯定是已有的数据源,没必要再来创建,只需要注入数据源即可管理
支持MySQL、SQLServer、Oracle数据源支持数据库表、字段文档查看修改表文档导出SQL执行、表数据预览、不同数据库之间的数据互导支持多数据源管理。支持按人员、按数据源对用户授权可给用户 库表注释查看、注释修改、SQL执行 粒度的授权。目标是取代Navicat做一个开源免费的在线数据库管理工具。
按照指定的格式可展示表的关系图,展示样式见下图
本关系图不是通过外键生成,所以需要在字段注释最后按规则添加外键关系才能生成图表,支持的格式有:
1. T:表XXX(字段注释)T:user_info
2. T:表.关联IDXXX(字段注释)T:user_info.id
3. T:库.表.关联IDXXX(字段注释)T:order_db.user_info.id
关系图为实验功能,有更好的建议或展示方式欢迎提交建议!
当前支持SqlServer、mysql的管理后期加上oracle和其他数据库的支持
#### 使用方式
1. 添加注解:@EnableDocDb
2. 注入Bean
```
// 注入已有的数据源
@Resource DataSource orderDatasource;
@Resource DataSource userDatasource;
//....
@Bean
public DatabaseRegistrationBean databaseRegistrationBean() {
DatabaseRegistrationBean bean = new DatabaseRegistrationBean();
List<DataSource> dataSourceList = new LinkedList<>();
// 设置需要展示的数据源
dataSourceList.add(orderDatasource);
dataSourceList.add(userDatasource);
bean.setDataSourceList(dataSourceList);
return bean;
}
```
3. 打开网页访问域名地址+doc-db.html即可http://192.168.0.100:8080/doc-db.html
#### 界面展示
基本界面:
![](https://images.gitee.com/uploads/images/2018/0918/190615_af5e8cdb_596905.jpeg "31.jpg")
模糊查询:
![](https://images.gitee.com/uploads/images/2018/0918/190721_872b2d76_596905.png "03.png")
表注释修改:
![](https://images.gitee.com/uploads/images/2018/0918/190739_afe7ba53_596905.jpeg "50.jpg")
文档导出:
![](https://images.gitee.com/uploads/images/2018/0920/223122_172d1fc2_596905.png "21.png")
导出文档查看:
![](https://images.gitee.com/uploads/images/2018/0920/223223_b899b367_596905.png "54.png")
表关联关系图:
![](https://images.gitee.com/uploads/images/2018/0925/214544_14b1b6eb_596905.jpeg "08.jpg")

View File

@@ -5,7 +5,7 @@
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>1.0.8</version>
<version>1.0.4</version>
<packaging>jar</packaging>
<name>zyplayer-doc-db</name>
<description>数据库文档工具</description>
@@ -67,18 +67,13 @@
<artifactId>easyexcel</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<zyplayer.doc.version>1.0.8</zyplayer.doc.version>
<zyplayer.doc.version>1.0.4</zyplayer.doc.version>
<!-- 打包跳过单元测试 -->
<skipTests>true</skipTests>
<elasticsearch.version>7.2.0</elasticsearch.version>

View File

@@ -1,14 +1,15 @@
package com.zyplayer.doc.db.controller;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import com.zyplayer.doc.data.utils.CachePrefix;
@@ -16,28 +17,30 @@ import com.zyplayer.doc.data.utils.CacheUtil;
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean.DatabaseProduct;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import com.zyplayer.doc.db.framework.db.dto.*;
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
import com.zyplayer.doc.db.framework.db.mapper.mysql.MysqlMapper;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.framework.utils.PoiUtil;
import com.zyplayer.doc.db.service.DbBaseFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 文档控制器
@@ -45,7 +48,6 @@ import java.util.stream.Stream;
* @author 暮光:城中城
* @since 2018年8月8日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/doc-db")
public class DatabaseDocController {
@@ -56,30 +58,19 @@ public class DatabaseDocController {
DbDatasourceService dbDatasourceService;
@Resource
UserAuthService userAuthService;
@Resource
DbBaseFactory dbBaseFactory;
@PostMapping(value = "/getDataSourceList")
public ResponseJson getDataSourceList() {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
wrapper.eq("yn", 1);
// 没管理权限只返回有权限的数据源
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)) {
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.likeRight("auth_custom_suffix", DocAuthConst.DB);
updateWrapper.eq("del_flag", 0);
updateWrapper.eq("user_id", currentUser.getUserId());
List<UserAuth> userAuthList = userAuthService.list(updateWrapper);
if (userAuthList == null || userAuthList.isEmpty()) {
return DocDbResponseJson.ok();
}
List<Long> userAuthDbIds = userAuthList.stream().map(val -> NumberUtils.toLong(val.getAuthCustomSuffix().replace(DocAuthConst.DB, ""))).collect(Collectors.toList());
wrapper.in("id", userAuthDbIds);
}
wrapper.select("id", "name", "group_name");
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
return DocDbResponseJson.ok(datasourceList);
List<DatabaseFactoryBean> dataSourceList = datasourceList.stream().map(val -> {
DatabaseFactoryBean bean = new DatabaseFactoryBean();
bean.setCnName(val.getName());
bean.setId(val.getId());
return bean;
}).collect(Collectors.toList());
return DocDbResponseJson.ok(dataSourceList);
}
/**
@@ -91,154 +82,234 @@ public class DatabaseDocController {
*/
@PostMapping(value = "/getEditorData")
public ResponseJson getEditorData(Long sourceId) {
// 没权限,返回空
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
return DocDbResponseJson.ok();
}
String cacheKey = CachePrefix.DB_EDITOR_DATA_CACHE + sourceId;
Object resultObj = CacheUtil.get(cacheKey);
if (resultObj != null) {
return DocDbResponseJson.ok(resultObj);
}
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
Map<String, Object> dbResultMap = dbBaseService.getEditorData(sourceId);
BaseMapper baseMapper = this.getBaseMapper(sourceId);
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getFactoryById(sourceId);
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
Map<String, List<TableInfoDto>> dbTableMap = new HashMap<>();
Map<String, List<TableColumnDescDto>> tableColumnsMap = new HashMap<>();
Map<String, List<TableInfoDto>> tableMapList = new HashMap<>();
// MYSQL可以一次性查询所有库表
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.MYSQL) {
List<TableInfoDto> dbTableList = baseMapper.getTableList(null);
tableMapList = dbTableList.stream().collect(Collectors.groupingBy(TableInfoDto::getDbName));
}
for (DatabaseInfoDto infoDto : dbNameDtoList) {
List<TableInfoDto> tableInfoDtoList = tableMapList.get(infoDto.getDbName());
// SQLSERVER必须要库才能查
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
tableInfoDtoList = baseMapper.getTableList(infoDto.getDbName());
}
if (CollectionUtils.isEmpty(tableInfoDtoList)) {
continue;
}
dbTableMap.put(infoDto.getDbName(), tableInfoDtoList);
// 小于10个库查所有库否则只查询当前链接的库防止库表太多数据量太大
// 如果觉得没必要就自己改吧!
Map<String, List<TableColumnDescDto>> columnDescDtoMap = new HashMap<>();
if (dbNameDtoList.size() <= 10 || Objects.equals(databaseFactoryBean.getDbName(), infoDto.getDbName())) {
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(infoDto.getDbName(), null);
columnDescDtoMap = columnDescDto.stream().collect(Collectors.groupingBy(TableColumnDescDto::getTableName));
}
for (TableInfoDto tableInfoDto : tableInfoDtoList) {
List<TableColumnDescDto> descDtoList = columnDescDtoMap.get(tableInfoDto.getTableName());
if (CollectionUtils.isNotEmpty(descDtoList)) {
tableColumnsMap.put(tableInfoDto.getTableName(), descDtoList);
}
}
}
Map<String, Object> dbResultMap = new HashMap<>();
dbResultMap.put("db", dbNameDtoList);
dbResultMap.put("table", dbTableMap);
dbResultMap.put("column", tableColumnsMap);
// 缓存10分钟如果10分钟内库里面增删改了表或字段则提示不出来
CacheUtil.put(cacheKey, dbResultMap, 6000);
return DocDbResponseJson.ok(dbResultMap);
}
@PostMapping(value = "/getTableDdl")
public ResponseJson getTableDdl(Long sourceId, String dbName, String tableName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
TableDdlVo tableDdlVo = dbBaseService.getTableDdl(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableDdlVo);
}
@PostMapping(value = "/getDatabaseList")
public ResponseJson getDatabaseList(Long sourceId) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
List<DatabaseInfoDto> databaseList = dbBaseService.getDatabaseList(sourceId);
return DocDbResponseJson.ok(databaseList);
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
return DocDbResponseJson.ok(dbNameDtoList);
}
@PostMapping(value = "/getTableStatus")
public ResponseJson getTableStatus(Long sourceId, String dbName, String tableName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
TableStatusVo tableStatusVo = dbBaseService.getTableStatus(sourceId, dbName, tableName);
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
TableStatusVo tableStatusVo = baseMapper.getTableStatus(dbName, tableName);
return DocDbResponseJson.ok(tableStatusVo);
}
@PostMapping(value = "/getTableList")
public ResponseJson getTableList(Long sourceId, String dbName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
List<TableInfoDto> tableList = dbBaseService.getTableList(sourceId, dbName);
return DocDbResponseJson.ok(tableList);
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
return DocDbResponseJson.ok(dbTableList);
}
@PostMapping(value = "/getTableColumnList")
public ResponseJson getTableColumnList(Long sourceId, String dbName, String tableName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getFactoryById(sourceId);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
return DocDbResponseJson.ok(tableColumnVo);
}
@PostMapping(value = "/getTableColumnDescList")
public ResponseJson getTableColumnDescList(Long sourceId, String tableName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
List<TableColumnDescDto> columnDescDto = dbBaseService.getTableColumnDescList(sourceId, tableName);
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableAndColumnBySearch")
public ResponseJson getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
if (StringUtils.isBlank(searchText)) {
return DocDbResponseJson.ok();
}
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
List<QueryTableColumnDescDto> columnDescDto = dbBaseService.getTableAndColumnBySearch(sourceId, dbName, searchText);
searchText = "%" + searchText + "%";
List<QueryTableColumnDescDto> columnDescDto = baseMapper.getTableAndColumnBySearch(dbName, searchText);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableDescList")
public ResponseJson getTableDescList(Long sourceId, String dbName, String tableName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
List<TableDescDto> tableDescList = dbBaseService.getTableDescList(sourceId, dbName, tableName);
return DocDbResponseJson.ok(tableDescList);
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(dbName, tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/updateTableDesc")
public ResponseJson updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表注释的权限");
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
dbBaseService.updateTableDesc(sourceId, dbName, tableName, newDesc);
BaseMapper baseMapper = this.getBaseMapper(sourceId);
baseMapper.updateTableDesc(dbName, tableName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/updateTableColumnDesc")
public ResponseJson updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表字段注释的权限");
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
dbBaseService.updateTableColumnDesc(sourceId, dbName, tableName, columnName, newDesc);
BaseMapper baseMapper = this.getBaseMapper(sourceId);
ColumnInfoDto columnInfo = null;
// mysql要同时修改类型默认值等所以先查出来
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
if (mysqlMapper != null) {
columnInfo = mysqlMapper.getColumnInfo(dbName, tableName, columnName);
String isNullable = Optional.ofNullable(columnInfo.getIsNullable()).orElse("");
columnInfo.setIsNullable("yes".equalsIgnoreCase(isNullable) ? "null" : "not null");
String columnDefault = columnInfo.getColumnDefault();
if (StringUtils.isNotBlank(columnDefault)) {
columnInfo.setColumnDefault("DEFAULT " + columnDefault);
} else {
columnInfo.setColumnDefault("");
}
String extra = columnInfo.getExtra();
columnInfo.setExtra(StringUtils.isBlank(extra) ? "" : extra);
}
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, columnInfo);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType, Integer exportFormat) {
@GetMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType) {
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
if (StringUtils.isBlank(tableNames)) {
return DocDbResponseJson.warn("请选择需要导出的表");
}
List<String> tableNameList = Stream.of(tableNames.split(",")).filter(StringUtils::isNotBlank).collect(Collectors.toList());
if (Objects.equals(exportType, 1)) {
return this.exportForTableDoc(response, sourceId, dbName, tableNameList, exportFormat);
} else if (Objects.equals(exportType, 2)) {
return this.exportForTableDdl(response, sourceId, dbName, tableNameList, exportFormat);
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getFactoryById(sourceId);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
return DocDbResponseJson.ok();
}
private DocDbResponseJson exportForTableDdl(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
Map<String, String> ddlSqlMap = new HashMap<>();
for (String tableName : tableNameList) {
TableDdlVo tableDdlVo = dbBaseService.getTableDdl(sourceId, dbName, tableName);
ddlSqlMap.put(tableName, tableDdlVo.getTableDDLByType());
}
try {
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
DatabaseProduct databaseProduct = databaseFactoryBean.getDatabaseProduct();
PoiUtil.exportByDdl(ddlSqlMap, dbName, databaseProduct.name(), response);
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.error("导出失败:" + e.getMessage());
}
return DocDbResponseJson.ok();
}
private DocDbResponseJson exportForTableDoc(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
// 数据组装
List<TableInfoVo> tableList = new LinkedList<>();
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
for (String tableName : tableNameList) {
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
String[] tableNameArr = tableNames.split(",");
for (String tableName : tableNameArr) {
if (StringUtils.isBlank(tableName)) {
continue;
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
columnList.put(tableName, tableColumnVo.getColumnList());
tableList.add(tableColumnVo.getTableInfo());
}
try {
DatabaseExportVo exportVo = new DatabaseExportVo(columnList, tableList);
if (Objects.equals(exportFormat, 1)) {
PoiUtil.exportByText(exportVo, response);
} else if (Objects.equals(exportFormat, 2)) {
PoiUtil.exportByXlsx(exportVo, response);
} else if (Objects.equals(exportFormat, 3)) {
PoiUtil.exportByDocx(dbName, exportVo, response);
DatabaseExportVo exportVo = new DatabaseExportVo();
exportVo.setColumnList(columnList);
exportVo.setTableList(tableList);
String content = JSON.toJSONString(exportVo);
content = "var docDbDatabase = " + content;
if (Objects.equals(exportType, 1)) {
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=database.js");
response.setCharacterEncoding("utf-8");
// 将文件输入流写入response的输出流中
try {
IoUtil.write(response.getOutputStream(), "utf-8", true, content);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("数据库表导出", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "表信息").head(TableInfoVo.class).build();
excelWriter.write(tableList, writeSheet);
int index = 1;
for (Map.Entry<String, List<TableColumnDescDto>> entry : columnList.entrySet()) {
writeSheet = EasyExcel.writerSheet(index++, entry.getKey()).head(TableColumnDescDto.class).build();
excelWriter.write(entry.getValue(), writeSheet);
}
excelWriter.finish();
} catch (IOException e) {
e.printStackTrace();
}
return DocDbResponseJson.error("导出失败:请先选择导出类型");
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.error("导出失败:" + e.getMessage());
}
return DocDbResponseJson.ok();
}
private TableColumnVo getTableColumnVo(DatabaseFactoryBean databaseFactoryBean, String dbName, String tableName) {
SqlSessionTemplate sessionTemplate = databaseFactoryBean.getSqlSessionTemplate();
BaseMapper baseMapper = sessionTemplate.getMapper(BaseMapper.class);
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(dbName, tableName);
// SQLSERVER要单独查字段注释
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
List<TableColumnDescDto> columnDescList = baseMapper.getTableColumnDescList(tableName);
Map<String, TableColumnDescDto> columnMap = columnDescDto.stream().collect(Collectors.toMap(TableColumnDescDto::getName, val -> val));
// 字段注释
for (TableColumnDescDto descDto : columnDescList) {
TableColumnDescDto tempDesc = columnMap.get(descDto.getName());
if (tempDesc != null) {
tempDesc.setDescription(descDto.getDescription());
}
}
}
TableColumnVo tableColumnVo = new TableColumnVo();
tableColumnVo.setColumnList(columnDescDto);
// 表注释
TableInfoVo tableInfoVo = new TableInfoVo();
List<TableDescDto> tableDescList = baseMapper.getTableDescList(dbName, tableName);
String description = null;
if (tableDescList.size() > 0) {
TableDescDto descDto = tableDescList.get(0);
description = descDto.getDescription();
}
description = Optional.ofNullable(description).orElse("");
tableInfoVo.setDescription(description);
tableInfoVo.setTableName(tableName);
tableColumnVo.setTableInfo(tableInfoVo);
return tableColumnVo;
}
/**
@@ -247,10 +318,36 @@ public class DatabaseDocController {
* @author 暮光:城中城
*/
private void judgeAuth(Long sourceId, String authName, String noAuthInfo) {
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(authName, DocAuthConst.DB + sourceId)) {
throw new ConfirmException(noAuthInfo);
}
/**
* 获取BaseMapper
*
* @author 暮光:城中城
*/
private BaseMapper getBaseMapper(Long sourceId) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
throw new ConfirmException("未找到对应的数据库连接");
}
return baseMapper;
}
/**
* 判断查看权和获取BaseMapper
*
* @author 暮光:城中城
*/
private BaseMapper getViewAuthBaseMapper(Long sourceId) {
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
return this.getBaseMapper(sourceId);
}
public static void main(String[] args) {
//File zipFile = ZipUtil.zip("d:/aaa");
File zipFile = new File("d:/111.zip");
ZipUtil.zip(zipFile, true, new File("d:/111.txt"),
new File("d:/222.txt"), new File("d:/aaa"));
}
}

View File

@@ -1,12 +1,8 @@
package com.zyplayer.doc.db.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
@@ -26,7 +22,6 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 数据库权限控制器
@@ -35,7 +30,6 @@ import java.util.stream.Stream;
* @since 2019年8月18日
*/
@RestController
@AuthMan(DocAuthConst.DB_DATASOURCE_MANAGE)
@RequestMapping("/zyplayer-doc-db/auth")
public class DbDataSourceAuthController {
private static Logger logger = LoggerFactory.getLogger(DbDataSourceAuthController.class);
@@ -49,60 +43,7 @@ public class DbDataSourceAuthController {
@PostMapping("/assign")
public ResponseJson<Object> assign(Long sourceId, String authList) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
List<String> authNameList = Stream.of(DbAuthType.values()).map(DbAuthType::getName).collect(Collectors.toList());
QueryWrapper<AuthInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.in("auth_name", authNameList);
Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper);
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
// 先删除所有用户的权限
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
updateWrapper.eq("del_flag", 0);
userAuthService.remove(updateWrapper);
List<UserDbAuthVo> authVoList = JSON.parseArray(authList, UserDbAuthVo.class);
for (UserDbAuthVo authVo : authVoList) {
List<UserAuth> userAuthList = new LinkedList<>();
Integer executeAuth = Optional.ofNullable(authVo.getExecuteAuth()).orElse(0);
if (executeAuth <= 0) {
Long authId = authInfoMap.get(DbAuthType.NO_AUTH.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 1) {
Long authId = authInfoMap.get(DbAuthType.VIEW.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 2) {
Long authId = authInfoMap.get(DbAuthType.SELECT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 3) {
Long authId = authInfoMap.get(DbAuthType.UPDATE.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (Objects.equals(authVo.getDescEditAuth(), 1)) {
Long authId = authInfoMap.get(DbAuthType.DESC_EDIT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (Objects.equals(authVo.getProcEditAuth(), 1)) {
Long authId = authInfoMap.get(DbAuthType.PROC_EDIT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (userAuthList.size() <= 0) {
continue;
}
// 保存权限,重新登录后可用,后期可以考虑在这里直接修改缓存里的用户权限
userAuthService.saveBatch(userAuthList);
}
return DocResponseJson.ok();
return DocResponseJson.warn("不支持的方法");
}
@PostMapping("/list")
@@ -126,6 +67,7 @@ public class DbDataSourceAuthController {
userAuthGroup.forEach((key, value) -> {
Set<String> authNameSet = value.stream().map(auth -> authInfoMap.get(auth.getAuthId())).collect(Collectors.toSet());
UserDbAuthVo authVo = new UserDbAuthVo();
authVo.setExecuteAuth(0);
if (this.haveAuth(authNameSet, DbAuthType.UPDATE) == 1) {
authVo.setExecuteAuth(3);
} else if (this.haveAuth(authNameSet, DbAuthType.SELECT) == 1) {
@@ -134,7 +76,6 @@ public class DbDataSourceAuthController {
authVo.setExecuteAuth(1);
}
authVo.setDescEditAuth(this.haveAuth(authNameSet, DbAuthType.DESC_EDIT));
authVo.setProcEditAuth(this.haveAuth(authNameSet, DbAuthType.PROC_EDIT));
authVo.setUserId(key);
authVo.setUserName(userInfoMap.get(key));
authVoList.add(authVo);

View File

@@ -1,30 +1,20 @@
package com.zyplayer.doc.db.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
import com.zyplayer.doc.db.framework.configuration.DatasourceUtil;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* 数据源控制器
@@ -33,7 +23,6 @@ import java.util.stream.Collectors;
* @since 2019年6月29日
*/
@RestController
@AuthMan(DocAuthConst.DB_DATASOURCE_MANAGE)
@RequestMapping("/zyplayer-doc-db/datasource")
public class DbDatasourceController {
@@ -43,55 +32,14 @@ public class DbDatasourceController {
DbDatasourceService dbDatasourceService;
@PostMapping(value = "/list")
public ResponseJson list(Integer pageNum, Integer pageSize, String name, String groupName) {
public ResponseJson list() {
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
wrapper.eq("yn", 1);
wrapper.eq(StringUtils.isNotBlank(groupName), "group_name", groupName);
wrapper.like(StringUtils.isNotBlank(name), "name", "%" + name + "%");
IPage<DbDatasource> page = new Page<>(pageNum, pageSize, pageNum == 1);
dbDatasourceService.page(page, wrapper);
for (DbDatasource dbDatasource : page.getRecords()) {
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
for (DbDatasource dbDatasource : datasourceList) {
dbDatasource.setSourcePassword("***");
}
return DocDbResponseJson.ok(page);
}
@PostMapping(value = "/groups")
public ResponseJson groups() {
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
wrapper.eq("yn", 1);
wrapper.isNotNull("group_name");
wrapper.select("group_name");
wrapper.groupBy("group_name");
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
if (CollectionUtils.isEmpty(datasourceList)) {
return DocDbResponseJson.ok();
}
Set<String> groupNameSet = datasourceList.stream().map(DbDatasource::getGroupName).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
return DocDbResponseJson.ok(groupNameSet);
}
@PostMapping(value = "/test")
public ResponseJson test(DbDatasource dbDatasource) {
// 验证新的数据源
try {
// 获取原始密码
if (Objects.equals("***", dbDatasource.getSourcePassword()) && dbDatasource.getId() != null) {
DbDatasource dbDatasourceSel = dbDatasourceService.getById(dbDatasource.getId());
if (dbDatasourceSel != null) {
dbDatasource.setSourcePassword(dbDatasourceSel.getSourcePassword());
}
}
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasource, true);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("获取数据源失败,请检查配置是否正确");
}
databaseFactoryBean.getDataSource().close();
} catch (Exception e) {
e.printStackTrace();
return DocDbResponseJson.warn(ExceptionUtils.getFullStackTrace(e));
}
return DocDbResponseJson.ok();
return DocDbResponseJson.ok(datasourceList);
}
@PostMapping(value = "/update")
@@ -117,16 +65,37 @@ public class DbDatasourceController {
Long sourceId = Optional.ofNullable(dbDatasource.getId()).orElse(0L);
if (sourceId > 0) {
dbDatasourceService.updateById(dbDatasource);
// 关闭旧数据源
databaseRegistrationBean.closeDatasource(dbDatasource.getId());
} else {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
dbDatasource.setCreateTime(new Date());
dbDatasource.setCreateUserId(currentUser.getUserId());
dbDatasource.setCreateUserName(currentUser.getUsername());
dbDatasource.setYn(1);
dbDatasourceService.save(dbDatasource);
}
DbDatasource dbDatasourceSel = dbDatasourceService.getById(dbDatasource.getId());
List<DatabaseFactoryBean> newFactoryBeanList = new LinkedList<>();
List<DatabaseFactoryBean> databaseFactoryBeanList = databaseRegistrationBean.getDatabaseFactoryBeanList();
for (DatabaseFactoryBean factoryBean : databaseFactoryBeanList) {
if (Objects.equals(factoryBean.getId(), sourceId)) {
try {
// 关闭旧的数据源
factoryBean.getDataSource().close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
newFactoryBeanList.add(factoryBean);
}
}
if (Optional.ofNullable(dbDatasourceSel.getYn()).orElse(0) == 1) {
// 创建新的数据源
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasourceSel);
if (databaseFactoryBean != null) {
newFactoryBeanList.add(databaseFactoryBean);
}
databaseRegistrationBean.setDatabaseFactoryBeanList(newFactoryBeanList);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("创建数据源失败,请检查配置是否正确");
}
}
return DocDbResponseJson.ok();
}
}

View File

@@ -1,222 +0,0 @@
package com.zyplayer.doc.db.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.repository.manage.entity.DbProcLog;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbProcLogService;
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.dto.ProcedureDto;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.service.DbBaseFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* 存储过程管理控制器
*
* @author 暮光:城中城
* @since 2021年4月24日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/procedure")
public class DbProcedureController {
private static Logger logger = LoggerFactory.getLogger(DbProcedureController.class);
@Resource
DbBaseFactory dbBaseFactory;
@Resource
DbProcLogService dbProcLogService;
/**
* 存储过程列表
*
* @param procedureParam 参数
* @return 列表
*/
@PostMapping(value = "/list")
public ResponseJson list(ProcedureListParam procedureParam) {
try {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(procedureParam.getSourceId());
procedureParam.setOffset((procedureParam.getPageNum() - 1) * procedureParam.getPageSize());
List<ProcedureDto> procedureDtoList = dbBaseService.getProcedureList(procedureParam);
DocDbResponseJson responseJson = DocDbResponseJson.ok(procedureDtoList);
if (procedureParam.getPageNum() == 1) {
responseJson.setTotal(dbBaseService.getProcedureCount(procedureParam));
}
return responseJson;
} catch (Exception e) {
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
}
}
/**
* 获取函数详情
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 详情
*/
@PostMapping(value = "/detail")
public ResponseJson detail(Long sourceId, String dbName, String typeName, String procName) {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
try {
ProcedureDto procedureDto = dbBaseService.getProcedureDetail(sourceId, dbName, typeName, procName);
return DocDbResponseJson.ok(procedureDto);
} catch (Exception e) {
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
}
}
/**
* 删除函数
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 结果
*/
@PostMapping(value = "/delete")
public ResponseJson delete(Long sourceId, String dbName, String typeName, String procName) {
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, "删除函数操作");
try {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
dbBaseService.deleteProcedure(sourceId, dbName, typeName, procName);
return DocDbResponseJson.ok();
} catch (Exception e) {
dbProcLog.setStatus(2);
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
} finally {
dbProcLogService.save(dbProcLog);
}
}
/**
* 保存函数
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @param procSql 存储过程创建SQL
* @return 结果
*/
@PostMapping(value = "/save")
public ResponseJson save(Long sourceId, String dbName, String typeName, String procName, String procSql) {
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, procSql);
try {
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
ExecuteResult executeResult = dbBaseService.saveProcedure(sourceId, dbName, typeName, procName, procSql);
if (StringUtils.isNotBlank(executeResult.getErrMsg())) {
dbProcLog.setStatus(2);
}
return DocDbResponseJson.ok(executeResult);
} catch (Exception e) {
dbProcLog.setStatus(2);
// 一般是数据库的帐号没权限查存储过程
return DocDbResponseJson.error(e.getMessage());
} finally {
dbProcLogService.save(dbProcLog);
}
}
/**
* 存储过程修改日志列表
*
* @param sourceId 数据源ID
* @param dbName 数据库名
* @param typeName 类型名
* @param procName 函数名
* @return 列表
*/
@PostMapping(value = "/log/list")
public ResponseJson logList(Integer pageNum, Integer pageSize, Long sourceId, String dbName, String typeName, String procName) {
QueryWrapper<DbProcLog> wrapper = new QueryWrapper<>();
wrapper.eq("datasource_id", sourceId);
wrapper.eq("proc_db", dbName);
wrapper.eq("proc_name", procName);
wrapper.eq("proc_type", typeName);
wrapper.orderByDesc("id");
wrapper.select("id", "proc_body", "create_user_name", "create_time", "status");
IPage<DbProcLog> page = new Page<>(pageNum, pageSize, pageNum == 1);
dbProcLogService.page(page, wrapper);
return DocDbResponseJson.ok(page);
}
/**
* 存储过程修改日志详情
*
* @param logId 日志ID
* @return 详情
*/
@PostMapping(value = "/log/detail")
public ResponseJson logDetail(Long logId) {
DbProcLog dbProcLog = dbProcLogService.getById(logId);
return DocDbResponseJson.ok(dbProcLog);
}
/**
* 权限判断
*
* @author 暮光:城中城
*/
private void judgeAuth(Long sourceId, String authName, String noAuthInfo) {
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(authName, DocAuthConst.DB + sourceId)) {
throw new ConfirmException(noAuthInfo);
}
}
/**
* 创建日志对象
* @param sourceId
* @param dbName
* @param typeName
* @param procName
* @param procSql
* @return
*/
public DbProcLog createDbProcLog(Long sourceId, String dbName, String typeName, String procName, String procSql) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
DbProcLog dbProcLog = new DbProcLog();
dbProcLog.setDatasourceId(sourceId);
dbProcLog.setCreateTime(new Date());
dbProcLog.setCreateUserId(currentUser.getUserId());
dbProcLog.setCreateUserName(currentUser.getUsername());
dbProcLog.setProcDb(dbName);
dbProcLog.setProcName(procName);
dbProcLog.setProcType(typeName);
dbProcLog.setProcBody(procSql);
dbProcLog.setStatus(1);
return dbProcLog;
}
}

View File

@@ -5,25 +5,18 @@ import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.core.util.StringUtil;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbFavorite;
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbFavoriteService;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -41,11 +34,9 @@ import java.util.Optional;
* @author 暮光:城中城
* @since 2019年8月18日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/executor")
public class DbSqlExecutorController {
private static Logger logger = LoggerFactory.getLogger(DbSqlExecutorController.class);
@Resource
SqlExecutor sqlExecutor;
@@ -59,12 +50,6 @@ public class DbSqlExecutorController {
if (StringUtils.isBlank(sql)) {
return DocDbResponseJson.warn("执行的SQL不能为空");
}
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
boolean select = DocUserUtil.haveCustomAuth(DbAuthType.SELECT.getName(), DocAuthConst.DB + sourceId);
boolean update = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + sourceId);
if (!manageAuth && !select && !update) {
return DocDbResponseJson.warn("没有该数据源的执行权限");
}
// 保留历史记录
dbHistoryService.saveHistory(sql.trim(), sourceId);
List<String> resultList = new LinkedList<>();
@@ -76,7 +61,7 @@ public class DbSqlExecutorController {
}
sqlItem = sqlItem.trim();
try {
ExecuteType executeType = (manageAuth || update) ? ExecuteType.ALL : ExecuteType.SELECT;
ExecuteType executeType = ExecuteType.ALL;
ExecuteParam executeParam = new ExecuteParam();
executeParam.setDatasourceId(sourceId);
executeParam.setExecuteId(executeId);
@@ -90,7 +75,6 @@ public class DbSqlExecutorController {
String resultJsonStr = JSON.toJSONString(executeResult, mapping, SerializerFeature.WriteMapNullValue);
resultList.add(resultJsonStr);
} catch (Exception e) {
logger.error("执行出错", e);
ExecuteResult executeResult = ExecuteResult.error(StringUtil.getException(e), sqlItem);
resultList.add(JSON.toJSONString(executeResult));
}
@@ -115,10 +99,8 @@ public class DbSqlExecutorController {
@PostMapping(value = "/favorite/list")
public ResponseJson favoriteList(Long sourceId) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
UpdateWrapper<DbFavorite> wrapper = new UpdateWrapper<>();
wrapper.eq(sourceId != null, "datasource_id", sourceId);
wrapper.eq("create_user_id", currentUser.getUserId());
wrapper.eq("yn", 1);
wrapper.orderByDesc("id");
List<DbFavorite> favoriteList = dbFavoriteService.list(wrapper);
@@ -134,13 +116,10 @@ public class DbSqlExecutorController {
}
dbFavorite.setContent(dbFavorite.getContent().trim());
}
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
if (dbFavorite.getId() != null && dbFavorite.getId() > 0) {
dbFavoriteService.updateById(dbFavorite);
} else {
dbFavorite.setCreateTime(new Date());
dbFavorite.setCreateUserId(currentUser.getUserId());
dbFavorite.setCreateUserName(currentUser.getUsername());
dbFavorite.setYn(1);
dbFavoriteService.save(dbFavorite);
}

View File

@@ -1,10 +1,7 @@
package com.zyplayer.doc.db.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbTransferTask;
import com.zyplayer.doc.data.service.manage.DbTransferTaskService;
import com.zyplayer.doc.db.framework.db.transfer.SqlParseUtil;
@@ -24,7 +21,6 @@ import java.util.List;
* @author 暮光:城中城
* @since 2019年9月28日
*/
@AuthMan
@RestController
@RequestMapping("/zyplayer-doc-db/transfer")
public class DbTransferDataController {
@@ -68,10 +64,7 @@ public class DbTransferDataController {
public ResponseJson update(DbTransferTask transferTask) {
DbTransferTask transferTaskUp = new DbTransferTask();
if (transferTask.getId() == null) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
transferTaskUp.setCreateTime(new Date());
transferTaskUp.setCreateUserId(currentUser.getUserId());
transferTaskUp.setCreateUserName(currentUser.getUsername());
transferTaskUp.setDelFlag(0);
} else {
transferTaskUp.setId(transferTask.getId());

View File

@@ -1,67 +0,0 @@
package com.zyplayer.doc.db.controller.param;
public class ProcedureListParam {
private Long sourceId;
private String dbName;
private Integer pageNum;
private Integer pageSize;
private Integer offset;
private String name;
private String type;
public Long getSourceId() {
return sourceId;
}
public void setSourceId(Long sourceId) {
this.sourceId = sourceId;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getOffset() {
return offset;
}
public void setOffset(Integer offset) {
this.offset = offset;
}
}

View File

@@ -11,12 +11,7 @@ public class DatabaseExportVo {
private Map<String, List<TableColumnDescDto>> columnList;
private List<TableInfoVo> tableList;
public DatabaseExportVo(Map<String, List<TableColumnDescDto>> columnList, List<TableInfoVo> tableList) {
this.columnList = columnList;
this.tableList = tableList;
}
public Map<String, List<TableColumnDescDto>> getColumnList() {
return columnList;
}

View File

@@ -1,61 +0,0 @@
package com.zyplayer.doc.db.controller.vo;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import java.util.Objects;
public class TableDdlVo {
private String current;
private String mysql;
private String sqlserver;
private String oracle;
private String postgresql;
public String getTableDDLByType() {
if (Objects.equals(current, DatabaseFactoryBean.DatabaseProduct.MYSQL.name().toLowerCase())) return mysql;
if (Objects.equals(current, DatabaseFactoryBean.DatabaseProduct.SQLSERVER.name().toLowerCase())) return sqlserver;
if (Objects.equals(current, DatabaseFactoryBean.DatabaseProduct.ORACLE.name().toLowerCase())) return oracle;
if (Objects.equals(current, DatabaseFactoryBean.DatabaseProduct.POSTGRESQL.name().toLowerCase())) return postgresql;
return null;
}
public String getCurrent() {
return current;
}
public void setCurrent(String current) {
this.current = current;
}
public String getMysql() {
return mysql;
}
public void setMysql(String mysql) {
this.mysql = mysql;
}
public String getSqlserver() {
return sqlserver;
}
public void setSqlserver(String sqlserver) {
this.sqlserver = sqlserver;
}
public String getOracle() {
return oracle;
}
public void setOracle(String oracle) {
this.oracle = oracle;
}
public String getPostgresql() {
return postgresql;
}
public void setPostgresql(String postgresql) {
this.postgresql = postgresql;
}
}

View File

@@ -21,7 +21,6 @@ public class TableStatusVo {
private String checksum;
private String createOptions;
private String comment;
private String dbType;
public String getName() {
return name;
@@ -166,12 +165,4 @@ public class TableStatusVo {
public void setComment(String comment) {
this.comment = comment;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
}

View File

@@ -5,7 +5,6 @@ public class UserDbAuthVo {
private Long userId;
private Integer executeAuth;
private Integer descEditAuth;
private Integer procEditAuth;
public String getUserName() {
return userName;
@@ -38,12 +37,4 @@ public class UserDbAuthVo {
public void setDescEditAuth(Integer descEditAuth) {
this.descEditAuth = descEditAuth;
}
public Integer getProcEditAuth() {
return procEditAuth;
}
public void setProcEditAuth(Integer procEditAuth) {
this.procEditAuth = procEditAuth;
}
}

View File

@@ -1,15 +1,40 @@
package com.zyplayer.doc.db.framework.configuration;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
@Component
public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> {
@Resource
DatabaseRegistrationBean databaseRegistrationBean;
@Resource
DbDatasourceService dbDatasourceService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
wrapper.eq("yn", 1);
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
for (DbDatasource dbDatasource : datasourceList) {
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasource);
if (databaseFactoryBean != null) {
databaseFactoryBeanList.add(databaseFactoryBean);
}
}
databaseRegistrationBean.setDatabaseFactoryBeanList(databaseFactoryBeanList);
}
}

View File

@@ -14,80 +14,70 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class DatasourceUtil {
private static SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
public static DatabaseFactoryBean createDatabaseFactoryBean(DbDatasource dbDatasource, boolean breakAfterAcquireFailure) throws Exception {
Resource[] resources = null;
// 描述连接信息的对象
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String dbUrl = dbDatasource.getSourceUrl();
if (dbUrl.contains("mysql")) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (dbUrl.contains("postgresql")) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.POSTGRESQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/postgresql/*.xml");
} else if (dbUrl.contains("sqlserver")) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
//String[] urlDbNameArr = urlParamArr[0].split("/");
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
public static DatabaseFactoryBean createDatabaseFactoryBean(DbDatasource dbDatasource){
try {
// 数据源配置
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword());
// 描述连接信息的对象
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
Resource[] resources = null;
String dbUrl = dbDatasource.getSourceUrl();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
if (dbUrl.contains("mysql")) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (dbUrl.contains("sqlserver")) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
//String[] urlDbNameArr = urlParamArr[0].split("/");
//databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
}
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.SQLSERVER);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
} else if (dbUrl.contains("oracle")) {
// jdbc:oracle:thin:@127.0.0.1:1521:user_info
// jdbc:oracle:thin:@127.0.0.1:1521/user_info
// 代码是写好的但还没有oracle的库让我测试过~
String[] urlParamArr = dbUrl.split("\\?")[0].split("@");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length <= 1) {
urlDbNameArr = urlParamArr[0].split(":");
}
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.ORACLE);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/oracle/*.xml");
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.SQLSERVER);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
} else if (dbUrl.contains("oracle")) {
// jdbc:oracle:thin:@127.0.0.1:1521:user_info
// jdbc:oracle:thin:@127.0.0.1:1521/user_info
// 代码是写好的但还没有oracle的库让我测试过~
String[] urlParamArr = dbUrl.split("\\?")[0].split("@");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length <= 1) {
urlDbNameArr = urlParamArr[0].split(":");
if (resources == null) {
return null;
}
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.ORACLE);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/oracle/*.xml");
// 创建sqlSessionTemplate
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(resources);
sqlSessionFactoryBean.setPlugins(new Interceptor[]{sqlLogInterceptor});
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject());
// 组装自定义的bean
databaseFactoryBean.setId(dbDatasource.getId());
databaseFactoryBean.setCnName(dbDatasource.getName());
databaseFactoryBean.setDataSource(dataSource);
databaseFactoryBean.setSqlSessionTemplate(sqlSessionTemplate);
databaseFactoryBean.setUrl(dbUrl);
return databaseFactoryBean;
} catch (Throwable e) {
e.printStackTrace();
}
if (resources == null) {
return null;
}
// 数据源配置
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), false);
if (breakAfterAcquireFailure) {
dataSource.close();
// 先关闭会自动关闭的数据源,再创建一个会重连的
dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), true);
}
// 创建sqlSessionTemplate
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(resources);
sqlSessionFactoryBean.setPlugins(new Interceptor[]{sqlLogInterceptor});
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject());
// 组装自定义的bean
databaseFactoryBean.setId(dbDatasource.getId());
databaseFactoryBean.setCnName(dbDatasource.getName());
databaseFactoryBean.setDataSource(dataSource);
databaseFactoryBean.setSqlSessionTemplate(sqlSessionTemplate);
databaseFactoryBean.setUrl(dbUrl);
return databaseFactoryBean;
return null;
}
}

View File

@@ -5,8 +5,7 @@ public enum DbAuthType {
VIEW(1, "DB_VIEW_"),
SELECT(2, "DB_SELECT_"),
UPDATE(3, "DB_UPDATE_"),
DESC_EDIT(4, "DB_DESC_EDIT_"),
PROC_EDIT(5, "DB_PROC_EDIT_"),
DESC_EDIT(3, "DB_DESC_EDIT_"),
;
private Integer type;
private String name;

View File

@@ -15,7 +15,6 @@ public class DatabaseFactoryBean {
private String url;
private String dbName;
private String cnName;
private String groupName;
private DatabaseProduct databaseProduct;
public Long getId() {
@@ -34,16 +33,8 @@ public class DatabaseFactoryBean {
this.cnName = cnName;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public static enum DatabaseProduct {
MYSQL, SQLSERVER, ORACLE, POSTGRESQL
MYSQL, SQLSERVER, ORACLE
}
public DruidDataSource getDataSource() {

View File

@@ -1,41 +1,41 @@
package com.zyplayer.doc.db.framework.db.bean;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
import com.zyplayer.doc.db.framework.configuration.DatasourceUtil;
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
/**
* 所有的数据源管理类
* 需要声明注入的对象只需要设置dbConfigList即可
* databaseFactoryBeanList是后面生成的
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
@Repository
public class DatabaseRegistrationBean {
@Resource
DbDatasourceService dbDatasourceService;
// 注入此对象必须配置的参数
// 配置的数据源连接、账号密码等信息,通过注入得到
private List<DbConfigBean> dbConfigList = new LinkedList<>();
// 描述连接信息的对象列表
private Map<Long, DatabaseFactoryBean> databaseFactoryBeanMap = new ConcurrentHashMap<>();
private List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
public List<DatabaseFactoryBean> getDatabaseFactoryBeanList() {
return databaseFactoryBeanList;
}
public void setDatabaseFactoryBeanList(List<DatabaseFactoryBean> databaseFactoryBeanList) {
this.databaseFactoryBeanList = databaseFactoryBeanList;
}
public BaseMapper getBaseMapper(Long sourceId) {
return getBaseMapper(sourceId, BaseMapper.class);
}
/**
* 获取BaseMapper
*
* @param sourceId 数据源ID
* @param cls 指定类
* @return BaseMapper
*/
public <T> T getBaseMapper(Long sourceId, Class<T> cls) {
DatabaseFactoryBean factoryBean = getOrCreateFactoryById(sourceId);
DatabaseFactoryBean factoryBean = getFactoryById(sourceId);
if (factoryBean != null) {
SqlSessionTemplate sessionTemplate = factoryBean.getSqlSessionTemplate();
try {
@@ -47,14 +47,17 @@ public class DatabaseRegistrationBean {
return null;
}
/**
* 获取BaseMapper
*
* @param sourceId 数据源ID
* @return BaseMapper
*/
public DatabaseFactoryBean getFactoryById(Long sourceId) {
for (DatabaseFactoryBean databaseFactoryBean : databaseFactoryBeanList) {
if (Objects.equals(databaseFactoryBean.getId(), sourceId)) {
return databaseFactoryBean;
}
}
return null;
}
public BaseMapper getBaseMapperById(Long sourceId) {
DatabaseFactoryBean databaseFactoryBean = this.getOrCreateFactoryById(sourceId);
DatabaseFactoryBean databaseFactoryBean = this.getFactoryById(sourceId);
if (databaseFactoryBean == null) {
return null;
}
@@ -67,59 +70,11 @@ public class DatabaseRegistrationBean {
return null;
}
/**
* 关闭数据源
*
* @param sourceId 数据源ID
*/
public void closeDatasource(Long sourceId) {
DatabaseFactoryBean factoryBean = databaseFactoryBeanMap.remove(sourceId);
if (factoryBean != null) {
try {
// 关闭数据源
factoryBean.getDataSource().close();
} catch (Exception e) {
e.printStackTrace();
}
}
public List<DbConfigBean> getDbConfigList() {
return dbConfigList;
}
/**
* 通过数据源ID获取或创建新的数据源
*
* @param sourceId 数据源ID
* @return 数据源对象
*/
public DatabaseFactoryBean getOrCreateFactoryById(Long sourceId) {
DatabaseFactoryBean factoryBean = databaseFactoryBeanMap.get(sourceId);
if (factoryBean != null) return factoryBean;
return this.createFactoryById(sourceId);
}
/**
* 创建数据源的同步方法
*
* @param sourceId 数据源ID
* @return 新数据源对象
*/
private synchronized DatabaseFactoryBean createFactoryById(Long sourceId) {
DatabaseFactoryBean factoryBean = databaseFactoryBeanMap.get(sourceId);
if (factoryBean != null) {
return factoryBean;
}
DbDatasource dbDatasource = dbDatasourceService.getById(sourceId);
if (dbDatasource == null) {
throw new ConfirmException("未找到指定数据源配置信息");
}
try {
DatabaseFactoryBean databaseFactoryBean = DatasourceUtil.createDatabaseFactoryBean(dbDatasource, false);
if (databaseFactoryBean == null) {
throw new ConfirmException("获取数据源失败");
}
databaseFactoryBeanMap.put(sourceId, databaseFactoryBean);
return databaseFactoryBean;
} catch (Exception e) {
throw new ConfirmException("创建数据源失败", e);
}
public void setDbConfigList(List<DbConfigBean> dbConfigList) {
this.dbConfigList = dbConfigList;
}
}

View File

@@ -1,79 +0,0 @@
package com.zyplayer.doc.db.framework.db.dto;
/**
* 存储过程信息
*/
public class ProcedureDto {
private String db;
private String name;
private String type;
private String definer;
private String body;
private String paramList;
private String returns;
private String created;
public String getDb() {
return db;
}
public void setDb(String db) {
this.db = db;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDefiner() {
return definer;
}
public void setDefiner(String definer) {
this.definer = definer;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getParamList() {
return paramList;
}
public void setParamList(String paramList) {
this.paramList = paramList;
}
public String getReturns() {
return returns;
}
public void setReturns(String returns) {
this.returns = returns;
}
}

View File

@@ -21,7 +21,7 @@ public class TableColumnDescDto {
private String type;
@ColumnWidth(10)
@ExcelProperty("空值")
@ExcelProperty("NULL")
private String nullable;
@ColumnWidth(10)

View File

@@ -1,163 +1,104 @@
package com.zyplayer.doc.db.framework.db.mapper.base;
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
import com.zyplayer.doc.db.framework.db.dto.*;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 数据库的mapper持有对象接口
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
public interface BaseMapper {
/**
* 获取库列表
*
* @return 数据库列表
* @author 暮光:城中城
* @since 2018年8月8日
*/
Map<String, String> getTableDdl(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 获取库列表
*
* @return 数据库列表
* @author 暮光:城中城
* @since 2018年8月8日
*/
List<DatabaseInfoDto> getDatabaseList();
/**
* 获取表列表
*
* @param dbName 数据库名
* @return 数据库表列表
* @author 暮光:城中城
* @since 2018年8月8日
* @param dbName 数据库名
* @return 数据库表列表
*/
List<TableInfoDto> getTableList(@Param("dbName") String dbName);
List<TableInfoDto> getTableList(@Param("dbName")String dbName);
/**
* 获取字段列表
*
* @param dbName 数据库名
* @author 暮光:城中城
* @since 2018年8月8日
* @param dbName 数据库名
* @param tableName 表名
* @return 字段列表
* @author 暮光:城中城
* @since 2018年8月8日
*/
List<TableColumnDescDto> getTableColumnList(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 获取字段注释
*
* @param tableName 表名
* @return 表字段注释
* @author 暮光:城中城
* @since 2018年8月8日
* @param tableName 表名
* @return 表字段注释
*/
List<TableColumnDescDto> getTableColumnDescList(@Param("tableName") String tableName);
/**
* 模糊搜索表和字段
*
* @param dbName 数据库名
* @param searchText 搜索内容
* @return 表和字段信息
* @author 暮光:城中城
* @since 2018年8月8日
* @param dbName 数据库名
* @param searchText 搜索内容
* @return 表和字段信息
*/
List<QueryTableColumnDescDto> getTableAndColumnBySearch(@Param("dbName") String dbName, @Param("searchText") String searchText);
/**
* 获取表注释
*
* @author 暮光:城中城
* @since 2018年8月8日
* @param tableName 可不传,传了只查询指定表的注释
* @return 表注释
* @author 暮光:城中城
* @since 2018年8月8日
*/
List<TableDescDto> getTableDescList(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 增加表注释
*
* @param tableName 表名
* @param newDesc 新的注释
* @author 暮光:城中城
* @since 2018年8月8日
* @param tableName 表名
* @param newDesc 新的注释
*/
void updateTableDesc(@Param("dbName") String dbName, @Param("tableName") String tableName, @Param("newDesc") String newDesc);
/**
* 增加字段注释
*
* @param dbName 数据库名
* @param tableName 表名
* @param columnName 字段名
* @param newDesc 新的注释
* @param columnInfo 字段信息
* @author 暮光:城中城
* @since 2018年8月8日
* @param dbName 数据库名
* @param tableName 表名
* @param columnName 字段名
* @param newDesc 新的注释
* @param columnInfo 字段信息
*/
void updateTableColumnDesc(@Param("dbName") String dbName, @Param("tableName") String tableName,
@Param("columnName") String columnName, @Param("newDesc") String newDesc,
@Param("columnInfo") ColumnInfoDto columnInfo);
@Param("columnName") String columnName, @Param("newDesc") String newDesc,
@Param("columnInfo") ColumnInfoDto columnInfo);
/**
* 获取表基本信息
*
* @param dbName 数据库名
* @param tableName 表名
* @author 暮光:城中城
* @since 2019年9月1日
* @param dbName 数据库名
* @param tableName 表名
*/
TableStatusVo getTableStatus(@Param("dbName") String dbName, @Param("tableName") String tableName);
/**
* 获取存储过程总条数
*
* @param procedureParam 参数
* @author 暮光:城中城
* @since 2020年4月24日
*/
Long getProcedureCount(@Param("param") ProcedureListParam procedureParam);
/**
* 获取存储过程列表
*
* @param procedureParam 参数
* @author 暮光:城中城
* @since 2020年4月24日
*/
List<ProcedureDto> getProcedureList(@Param("param") ProcedureListParam procedureParam);
/**
* 获取存储过程详情
*
* @param dbName 数据库名
* @param typeName 类型名称 PROCEDURE、FUNCTION
* @param procName 过程名称
* @author 暮光:城中城
* @since 2020年4月24日
*/
ProcedureDto getProcedureDetail(@Param("dbName") String dbName, @Param("typeName") String typeName, @Param("procName") String procName);
/**
* 删除存储过程
*
* @param dbName 数据库名
* @param typeName 类型名称 PROCEDURE、FUNCTION
* @param procName 过程名称
* @author 暮光:城中城
* @since 2020年4月24日
*/
void deleteProcedure(@Param("dbName") String dbName, @Param("typeName") String typeName, @Param("procName") String procName);
}

View File

@@ -65,7 +65,7 @@ public class SqlExecutor {
* @since 2019年8月18日
*/
public ExecuteResult execute(ExecuteParam param) {
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(param.getDatasourceId());
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getFactoryById(param.getDatasourceId());
return this.execute(factoryBean, param, null);
}
@@ -134,7 +134,6 @@ public class SqlExecutor {
long useTime = System.currentTimeMillis() - startTime;
return new ExecuteResult(updateCount, resultList, useTime, executeParam.getSql());
} catch (Exception e) {
logger.error("执行出错", e);
throw new RuntimeException(e);
} finally {
statementMap.remove(executeParam.getExecuteId());

View File

@@ -42,32 +42,28 @@
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
select TABLE_SCHEMA dbName
from `information_schema`.tables
from information_schema.tables
<!--排除系统库-->
where TABLE_SCHEMA != 'information_schema'
group by TABLE_SCHEMA
</select>
<select id="getTableDdl" resultType="java.util.Map">
show create table `${dbName}`.${tableName}
</select>
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
select table_schema dbName,table_name tableName, table_comment as tableComment
from `information_schema`.tables
from information_schema.tables
<if test="dbName != null">where table_schema=#{dbName}</if>
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
SELECT table_name as TABLE_NAME,COLUMN_NAME NAME,column_comment DESCRIPTION,column_type TYPE,if(is_nullable='YES','允许','不允许') NULLABLE
FROM `INFORMATION_SCHEMA`.Columns
SELECT table_name as TABLE_NAME,COLUMN_NAME NAME,column_comment DESCRIPTION,column_type TYPE,if(is_nullable='YES',1,0) NULLABLE
FROM INFORMATION_SCHEMA.Columns
WHERE table_schema=#{dbName}
<if test="tableName != null">and table_name=#{tableName}</if>
ORDER BY ordinal_position
</select>
<select id="getTableStatus" resultMap="TableStatusDtoMap">
show table status from `${dbName}` like #{tableName}
show table status from ${dbName} like #{tableName}
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
@@ -76,13 +72,13 @@
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT TABLE_NAME, COLUMN_NAME, column_comment DESCRIPTION
FROM `INFORMATION_SCHEMA`.Columns
FROM INFORMATION_SCHEMA.Columns
WHERE table_schema=#{dbName} AND (COLUMN_NAME like #{searchText} or column_comment like #{searchText})
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select table_name tableName, table_comment as description
from `information_schema`.tables
from information_schema.tables
<where>
<if test="dbName != null">and table_schema=#{dbName}</if>
<if test="tableName != null">and table_name=#{tableName}</if>
@@ -90,38 +86,13 @@
</select>
<insert id="updateTableDesc">
alter table `${dbName}`.${tableName} comment #{newDesc}
alter table ${dbName}.${tableName} comment #{newDesc}
</insert>
<insert id="updateTableColumnDesc">
alter table `${dbName}`.${tableName} modify column ${columnName}
alter table ${dbName}.${tableName} modify column ${columnName}
${columnInfo.columnType} ${columnInfo.isNullable} ${columnInfo.columnDefault} ${columnInfo.extra}
comment #{newDesc}
</insert>
<select id="getProcedureCount" resultType="java.lang.Long">
select count(1) from mysql.proc
<include refid="ProcedureListCondition"/>
</select>
<select id="getProcedureList" resultType="com.zyplayer.doc.db.framework.db.dto.ProcedureDto">
select `db`, `name`, `type`, `definer`, `created` from mysql.proc
<include refid="ProcedureListCondition"/>
limit #{param.pageSize} offset #{param.offset}
</select>
<select id="getProcedureDetail" resultType="com.zyplayer.doc.db.framework.db.dto.ProcedureDto">
select `db`, `name`, `type`, `definer`, `created`, `body`, `param_list` as paramList, `returns` from mysql.proc where db=#{dbName} and `type`=#{typeName} and name=#{procName}
</select>
<delete id="deleteProcedure">
DROP ${typeName} IF EXISTS `${dbName}`.`${procName}`
</delete>
<sql id="ProcedureListCondition">
where db=#{param.dbName}
<if test="param.name != null and param.name != ''">and `name` like #{param.name}</if>
<if test="param.type != null and param.type != ''">and `type` = #{param.type}</if>
</sql>
</mapper>

View File

@@ -21,10 +21,6 @@
select USERNAME dbName from all_users
</select>
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
select 1
</select>
<!-- 获取表列表 -->
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
select t.OWNER as dbName,t.TABLE_NAME as tableName,c.COMMENTS as tableComment from all_tables t left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
@@ -35,7 +31,7 @@
<!-- 获取表字段集合 -->
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then '允许' when 'N' then '不允许' end NULLABLE, c.COMMENTS
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then 1 when 'N' then 0 end NULLABLE, c.COMMENTS
from user_tab_columns t left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
<where>
t.table_name in (select table_name from all_tables where owner = #{dbName} )

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper">
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR"/>
<result column="NAME" property="name" jdbcType="VARCHAR"/>
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR"/>
<result column="TYPE" property="type" jdbcType="VARCHAR"/>
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR"/>
<result column="LENGTH" property="length" jdbcType="VARCHAR"/>
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR"/>
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR"/>
</resultMap>
<resultMap id="QueryTableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto">
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR"/>
<result column="COLUMN_NAME" property="columnName" jdbcType="VARCHAR"/>
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR"/>
</resultMap>
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
SELECT distinct table_schema as dbName
FROM information_schema.tables ORDER BY 1
</select>
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
SELECT relname as name, reltuples as rows
FROM pg_class r JOIN pg_namespace n
ON (relnamespace = n.oid)
WHERE relkind = 'r' AND n.nspname = #{dbName} and relname = #{tableName}
</select>
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
select relname as tableName,cast(obj_description(relfilenode,'pg_class') as varchar) as tableComment from pg_class c
where relname in (select tablename from pg_tables where schemaname=#{dbName} and position('_2' in tablename)=0)
order by 1
</select>
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
SELECT table_name as TABLE_NAME,a.COLUMN_NAME as NAME,b.DESCRIPTION as DESCRIPTION,udt_name as TYPE,case when is_nullable ='YES' then '允许' else '不允许' end as NULLABLE , case when character_maximum_length>0 then character_maximum_length else numeric_precision end LENGTH
FROM information_schema.columns a
left join (SELECT a.attname as COLUMN_NAME,col_description(a.attrelid,a.attnum) as DESCRIPTION
FROM pg_class as c,pg_attribute as a, pg_namespace as n
where a.attrelid = c.oid and a.attnum>0
and c.relnamespace = n.oid AND n.nspname = #{dbName} and c.relname = #{tableName}) b on a.COLUMN_NAME= b.COLUMN_NAME
WHERE table_schema=#{dbName} and table_name=#{tableName}
ORDER BY ordinal_position
</select>
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
SELECT
col_description (A .attrelid, A .attnum) AS COMMENT,
format_type (A .atttypid, A .atttypmod) AS TYPE,
A .attname AS NAME,
A .attnotnull AS NOTNULL
FROM
pg_class AS C,
pg_attribute AS A
WHERE
C .relname =#{tableName}
AND A .attrelid = C .oid
AND A .attnum > 0
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT
col_description (A .attrelid, A .attnum) AS COMMENT,
format_type (A .atttypid, A .atttypmod) AS TYPE,
A .attname AS NAME,
A .attnotnull AS NOTNULL
FROM
pg_class AS C,
pg_attribute AS A
WHERE
C .relnamelike #{searchText}
AND A .attrelid = C .oid
AND A .attnum > 0
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select t.relname as tableName ,description as description
from pg_description d,pg_class c,pg_stat_all_tables t
where d.objoid=c.oid and objsubid=0 and t.relname=c.relname and t.schemaname=#{dbName}
<if test="tableName != null">
and t.relname=#{tableName}
</if>
</select>
</mapper>

View File

@@ -1,17 +0,0 @@
package com.zyplayer.doc.db.framework.db.mapper.postgresql;
import org.apache.ibatis.annotations.Param;
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
/**
* postgresql数据库的mapper持有对象
*
* @author 辽宁-天平
* @since 2021年1月5日
*/
public interface PostgresqlMapper {
ColumnInfoDto getColumnInfo(@Param("dbName") String dbName, @Param("tableName") String tableName, @Param("columnName") String columnName);
}

View File

@@ -46,7 +46,7 @@
SELECT (
SELECT IS_IDENTITY FROM SYS.ALL_COLUMNS
WHERE SYS.ALL_COLUMNS.NAME=SYSCOLUMNS.NAME AND OBJECT_ID = OBJECT_ID(#{tableName})
) ISIDENTITY,SYSCOLUMNS.NAME NAME,SYSTYPES.NAME TYPE,Iif(SYSCOLUMNS.ISNULLABLE=1,'允许','不允许') NULLABLE,SYSCOLUMNS.LENGTH LENGTH,PRIMARYINFO.ISPRAMARY
) ISIDENTITY,SYSCOLUMNS.NAME NAME,SYSTYPES.NAME TYPE,SYSCOLUMNS.ISNULLABLE NULLABLE,SYSCOLUMNS.LENGTH LENGTH,PRIMARYINFO.ISPRAMARY
FROM SYSCOLUMNS
LEFT JOIN PRIMARYINFO ON PRIMARYINFO.COLUMNNAME=NAME
LEFT JOIN SYSTYPES ON SYSCOLUMNS.XUSERTYPE = SYSTYPES.XUSERTYPE

View File

@@ -92,11 +92,11 @@ public class TransferDataServer {
boolean querySelect = DocUserUtil.haveCustomAuth(DbAuthType.SELECT.getName(), DocAuthConst.DB + transferTask.getQueryDatasourceId());
boolean queryUpdate = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + transferTask.getQueryDatasourceId());
if (!manageAuth && !querySelect && !queryUpdate) {
throw new ConfirmException("没有查询数据源的查询权限,创建任务失败");
throw new ConfirmException("没有数据源的查询权限,创建任务失败");
}
boolean storageUpdate = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + transferTask.getStorageDatasourceId());
if (!manageAuth && !storageUpdate) {
throw new ConfirmException("没有目标数据源的写入权限,创建任务失败");
throw new ConfirmException("没有数据源的写入权限,创建任务失败");
}
dbTransferTaskService.resetExecuteInfo(taskId);
// 提交任务
@@ -122,7 +122,7 @@ public class TransferDataServer {
String querySql = transferTask.getQuerySql();
String storageSql = transferTask.getStorageSql();
List<Map<String, Object>> selectResultList = new LinkedList<>();
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(querySourceId);
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getFactoryById(querySourceId);
ExecuteParam executeParam = new ExecuteParam();
executeParam.setDatasourceId(querySourceId);
executeParam.setExecuteType(ExecuteType.SELECT);
@@ -135,11 +135,13 @@ public class TransferDataServer {
ExecuteResult countResult = sqlExecutor.execute(executeParam);
if (CollectionUtils.isEmpty(countResult.getResult())) {
String executeInfo = String.format("[%s] 获取总条数失败", DateTime.now().toString());
logger.error(executeInfo);
dbTransferTaskService.addExecuteInfo(transferTask.getId(), TransferTaskStatus.ERROR.getCode(), executeInfo);
return;
}
Object transferCount = countResult.getResult().get(0).get("counts");
String executeInfo = String.format("[%s] 待处理总条数:%s查询总条数耗时%sms", DateTime.now().toString(), transferCount, System.currentTimeMillis() - executeStartTime);
logger.info(executeInfo);
dbTransferTaskService.addExecuteInfo(transferTask.getId(), TransferTaskStatus.EXECUTING.getCode(), executeInfo);
} else {
String executeInfo = String.format("[%s] 未开启查询总条数,跳过条数查询", DateTime.now().toString());
@@ -147,6 +149,7 @@ public class TransferDataServer {
}
AtomicLong readCount = new AtomicLong(0L);
executeParam.setSql(querySql);
// executeParam.setSql("select sleep(10)");
ExecuteResult executeResult = sqlExecutor.execute(factoryBean, executeParam, resultMap -> {
selectResultList.add(resultMap);
if (readCount.incrementAndGet() % executeCountLogNum == 0) {
@@ -164,6 +167,7 @@ public class TransferDataServer {
}
if (StringUtils.isNotBlank(executeResult.getErrMsg())) {
String executeInfo = String.format("[%s] 执行出错:%s", DateTime.now().toString(), executeResult.getErrMsg());
logger.error(executeInfo);
dbTransferTaskService.addExecuteInfo(transferTask.getId(), TransferTaskStatus.ERROR.getCode(), executeInfo);
} else {
String executeInfo = String.format("[%s] 任务执行成功,处理总条数:%s总耗时%sms", DateTime.now().toString(), readCount.get(), System.currentTimeMillis() - executeStartTime);

View File

@@ -3,8 +3,6 @@ package com.zyplayer.doc.db.framework.json;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import com.zyplayer.doc.core.json.ResponseJson;
import io.swagger.annotations.ApiModelProperty;
@@ -29,8 +27,6 @@ public class DocDbResponseJson implements ResponseJson {
private String errMsg;
@ApiModelProperty(value = "返回数据")
private Object data;
@ApiModelProperty(value = "总数")
private Long total;
public DocDbResponseJson() {
this.errCode = 200;
@@ -80,19 +76,7 @@ public class DocDbResponseJson implements ResponseJson {
}
public void setData(Object data) {
if (null != data) {
if (data instanceof PageInfo) {
PageInfo<?> pageInfo = (PageInfo<?>) data;
this.data = pageInfo.getList();
this.total = pageInfo.getTotal();
} else if (data instanceof IPage) {
IPage<?> iPage = (IPage<?>) data;
this.data = iPage.getRecords();
this.total = iPage.getTotal();
} else {
this.data = data;
}
}
this.data = data;
}
/**
@@ -162,12 +146,4 @@ public class DocDbResponseJson implements ResponseJson {
public String toString() {
return "DefaultResponseJson [errCode=" + errCode + ", errMsg=" + errMsg + ", data=" + data + "]";
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
}

Some files were not shown because too many files have changed in this diff Show More