diff --git a/doc/docs/guide/README.md b/doc/docs/guide/README.md index 09d370d9..6af10628 100644 --- a/doc/docs/guide/README.md +++ b/doc/docs/guide/README.md @@ -12,8 +12,6 @@ ####   [在线体验](https://report.anji-plus.com/index.html "链接"): https://report.anji-plus.com/index.html  体验账号:guest 密码:guest -####   [在线文档](https://report.anji-plus.com/report-doc/ "doc"): https://report.anji-plus.com/report-doc/
- ####   [在线提问](https://gitee.com/anji-plus/report/issues "issue"): https://gitee.com/anji-plus/report/issues
## 发行版本 @@ -26,15 +24,11 @@    大屏设计(AJ-Report)是一个可视化拖拽编辑的,直观,酷炫,具有科技感的图表工具全开源项目。 内置的基础功能包括数据源,数据集,报表管理,项目部分截图如下。
-![操作](https://images.gitee.com/uploads/images/2021/0703/094742_c0243f70_1728982.gif "2021-07-03_09-43-50.gif") - -![视频](https://report.anji-plus.com/report-doc/static/Rhea.mp4)
- -**[更多社区大屏案例](https://report.anji-plus.com/report-doc/guide/bigScreenCase.html)**
+![shipin](../picture/shipin.gif) ## 数据流程图 -![An image](https://images.gitee.com/uploads/images/2021/0630/160451_31bb9052_1728982.png) +![liucheng](../picture/liucheng.png) ## 打包目录 @@ -45,7 +39,7 @@ │ ├── start.sh │ └── stop.sh ├── conf 配置文件目录 -│ └── bootstrap-dev.yml +│ └── bootstrap.yml ├── logs 启动日志目录 ├── cache 本地缓存目录 ├── lib 自定义扩展包&report-core核心包 diff --git a/doc/docs/guide/bigScreenCase.md b/doc/docs/guide/bigScreenCase.md index 2d074b26..e9accfd9 100644 --- a/doc/docs/guide/bigScreenCase.md +++ b/doc/docs/guide/bigScreenCase.md @@ -1,7 +1,22 @@ -## 案例一: +## 案例一 由社区 **[~无痕~@tengzhouboy](https://gitee.com/tengzhouboy)** 提供
[AJ-Report分享链接](https://report.anji-plus.com/index.html#/aj/mtwbjPot)
![img.png](../picture/bigScreenCase/img.png)
+## 案例二 + +由社区 **[心瘾丶 @yi_shan_liu](https://gitee.com/yi_shan_liu)** 提供
+[AJ-Report分享链接](https://report.anji-plus.com/index.html#/aj/hkBJgLW0)
+ +![img1](../picture/bigScreenCase/img1.png)
+ +[AJ-Report分享链接](https://report.anji-plus.com/index.html#/aj/Hgfi4pj5)
+![img2](../picture/bigScreenCase/img2.png)
+ +[AJ-Report分享链接](https://report.anji-plus.com/index.html#/aj/zJa5Wwey)
+![img3](../picture/bigScreenCase/img3.png)
+ +[AJ-Report分享链接](https://report.anji-plus.com/index.html#/aj/D0cpO4re)
+![img4](../picture/bigScreenCase/img4.png)
\ No newline at end of file diff --git a/doc/docs/guide/briefUsing.md b/doc/docs/guide/briefUsing.md index 53be87e1..089a9210 100644 --- a/doc/docs/guide/briefUsing.md +++ b/doc/docs/guide/briefUsing.md @@ -5,4 +5,5 @@ - +
+ \ No newline at end of file diff --git a/doc/docs/guide/charts.md b/doc/docs/guide/charts.md index a440aa20..f4e7a0fa 100644 --- a/doc/docs/guide/charts.md +++ b/doc/docs/guide/charts.md @@ -1,6 +1,6 @@ ## 图表和数据集之间的关系 -图表和数据集是强关联关系,一个图表需要什么样的数据才能进行展示下面都有说明,以柱状图举例,只能用俩个字段的数据集进行数据展示,那使用数据集有2个以上字段那肯定图表无法正常展示,反之有个数据集是3个字段,那就找能展示3个字段的图表,千万别搞小聪明定了好多个字段的数据集,然后从里面挑几个字段进行展示,不要在么干。
+图表和数据集是强关联关系,一个图表需要什么样的数据才能进行展示下面都有说明,以柱状图举例,只能用俩个字段的数据集进行数据展示,那使用数据集有2个以上字段那肯定图表无法正常展示,反之有个数据集是3个字段,那就找能展示3个字段的图表,千万别搞小聪明定了好多个字段的数据集,然后从里面挑几个字段进行展示,不要这么干。
## 文本框 @@ -42,7 +42,7 @@ ![img](../picture/dashboard/img_22.png)
表格字段对应的数据只选择“文本数字”。
![img14](../picture/dashboard/img_23.png)
-**注意:** 多个字段的时候,需要在“配置-新增”添加你选择数据集所对应的字段,类似于映射关系。
+**注意:** 多个字段的时候,需要在“配置-新增”添加你选择数据集所对应的字段,即“配置”中“表体设置”的“key值”要和你“动态数据对应的字段名”保持一致,类似于映射关系。
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ## 内联框架 @@ -52,6 +52,7 @@ ## 柱状图 柱状图数据集对应字典值需要选择一个“X轴”、“柱状”,只需要2个字段
+![img_13](../picture/charts/img_13.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ### 数据格式 @@ -65,7 +66,7 @@ ## 折线图 折线图数据集对应字典值需要选择一个“X轴”、“折线”,只需要2个字段
-![img_8.png](../picture/dashboard/img_8.png)
+![img14.png](../picture/charts/img_14.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ### 数据格式 @@ -74,14 +75,24 @@ ## 柱线图 -柱线图数据集对应字典值需要选择一个“X轴”、“柱状”、“折线”,需要3个字段
-![img9](../picture/dashboard/img_9.png)
+柱线图数据集对应字典值需要选择一个“X轴”、“柱状”、“折线”,需要3个字段,图例名称用 | 进行分隔。
+![img15](../picture/charts/img_15.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ### 数据格式 ![img5](../picture/charts/img_4.png)
+## 多柱线图 + +多柱线图对应数据字典需要选择一个“X轴”,剩下的字段可任意选择为“柱状”、“折线”,图例名称用 | 进行分隔。
+![img16](../picture/charts/img_16.png)
+**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** + +### 数据格式 + +![img17](../picture/charts/img_17.png)
+ ## 饼图 饼图的数据集选择的时候,只能选择饼图对应的字典,即“Name”、“Value”,不明白可以参考静态数据
@@ -95,7 +106,7 @@ ## 漏斗图 -![img13](../picture/dashboard/img_13.png)
+![img18](../picture/charts/img_18.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ### 数据格式 @@ -127,7 +138,7 @@ ## 百分百图 -![img16](../picture/dashboard/img_16.png)
+![img19](../picture/charts/img_19.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** ### 数据格式 @@ -146,7 +157,7 @@ ![img.17](../picture/dashboard/img_17.png)
**如有问题,请提交 [Issue](https://gitee.com/anji-plus/report/issues)
** -## 数据格式 +### 数据格式 ![img4](../picture/charts/img_3.png)
@@ -185,4 +196,13 @@ ## 装饰饼图 装饰用,可单独使用或者配合文本框等图表组件来使整个大屏立体、丰满。
-![img12](../picture/charts/img_12.png)
\ No newline at end of file +![img12](../picture/charts/img_12.png)
+ +## 词云图 + +最大最小角度都为0时则文字显示为正。所有词云颜色皆是随机产生,动态数据每请求一次数据,所有词云颜色皆改变一次。
+![img20](../picture/charts/img_20.png)
+ +### 数据格式 + +和饼图、南丁格尔玫瑰图数据保持一致。
\ No newline at end of file diff --git a/doc/docs/guide/dataset.md b/doc/docs/guide/dataset.md index 76b37d2e..00514cd3 100644 --- a/doc/docs/guide/dataset.md +++ b/doc/docs/guide/dataset.md @@ -1,7 +1,11 @@ -![img5](../picture/dateset/img_5.png) +![img5](../picture/dateset/img_5.png)
+ +[数据源数据集用法总结](https://my.oschina.net/u/4517014/blog/5270828)
## SQL数据集 +尽量不要使用 “select *”,以及展示很大的数据量,图表不一定能展示、页面可能会卡死
+ ### Mysql数据集 在数据源处添加了mysql的数据源后,即可使用。
diff --git a/doc/docs/guide/datasource.md b/doc/docs/guide/datasource.md index 01ee19dd..e6aa2a46 100644 --- a/doc/docs/guide/datasource.md +++ b/doc/docs/guide/datasource.md @@ -1,5 +1,7 @@ ## 介绍 +[数据源数据集用法总结](https://my.oschina.net/u/4517014/blog/5270828)
+ - 支持多数据源,内置mysql、elasticsearch、kudu等多种驱动
- 可动态扩展 ![source.png](../picture/datasource/img_1.png) @@ -23,10 +25,26 @@ ## 扩展 -- 以kudu impala 为例,在lib文件夹下加入kudu impala相关的JDBC连接相关的包,如图在数据库中新增数据源类型,参考数据源类型(上方) +### JDBC驱动类数据源添加 + +- 第一种,在report-core/lib目录下添加
+ 按照同样的层级将驱动包放置,使用build.sh脚本进行打包,前端页面选择jdbc数据源,填上对应的驱动类即可使用。
+ **注意:** 此方式添加的jar包只能使用build.sh进行编译后才会生效。
+ +
+ +- 第二种,在pom.xml中添加
+ 使用build.sh脚本编译或者maven package编译都可以,前端页面选择jdbc数据源,填上对应驱动。
+ +
+ +### 非JDBC驱动类数据源添加 -![An image](../picture/datasource/kudu-impala-lib.png) +例如原生ES、Redis之类。
+1、在源码中编写解析代码(datasource)
+2、使用页面生成数据字典
+3、添加对应驱动包
diff --git a/doc/docs/guide/question.md b/doc/docs/guide/question.md index 17952c46..3721505d 100644 --- a/doc/docs/guide/question.md +++ b/doc/docs/guide/question.md @@ -1,53 +1,74 @@ +## 其他 + +- 禁用flyway及切换底层数据库方案
+ [链接](https://my.oschina.net/u/4517014/blog/5269319)
+ +- 数据源数据集用法总结
+ [链接](https://my.oschina.net/u/4517014/blog/5270828)
+ - 使用Maven Install打包时报错
![img.png](../picture/qusetion/img.png)
- 请使用Maven Package进行打包
+ 使用Maven Package进行打包
+ +
-### 版本问题:[开发环境参考](https://report.anji-plus.com/report-doc/guide/quicklyDevelop.html) +## 版本问题:[开发环境参考](https://report.anji-plus.com/report-doc/guide/quicklyDevelop.html) - 底层数据库为Mysql8.0+时,flyway执行SQL报错
- Node.js是V16版本时 npm install失败
- jdk使用1.7或者11及以上时,编译打包不过
- ![img](../picture/qusetion/img_1.png)
+
+ ![img](../picture/qusetion/img_4.png)
+ +
+ +## 访问相关 -- MssSqlServer 2014及其上下版本数据源测试不过。以2014版本为例。
- ![img](../picture/qusetion/img_2.png)
- 将1.2.6改成1.2.0
+- 浏览器兼容性
+ 当前未对部分浏览器做兼容性适配,推荐使用谷歌浏览器进行访问。
+ 已知:IE白屏、部分版本的火狐浏览器拖动组件出现跳转新页面及无法返回的情况
-- 浏览器兼容性 当前未对部分浏览器做兼容性适配,推荐使用谷歌浏览器进行访问。
+
- 部署完进入系统,点击预览大屏,大屏提示:“执行sql失败“
![img](../picture/qusetion/img_3.png)
请先重置mysql数据源,将mysql数据源的账号密码修改为你当前系统的账号密码。
-- flyway执行报错1.0.10sql失败
- 错误提示:Caused by: org.flywaydb.core.api.FlywayException: Validate failed: Detected failed
- migration to version 1.0.10 (create report share)
- 请参考此 [Issue](https://gitee.com/anji-plus/report/issues/I47JNE) 解决此问题
+
-- 禁用flyway及切换底层数据库方案
- [链接](https://my.oschina.net/u/4517014/blog/5269319)
+- 页面提示“404”
+ 1、确保访问地址无误,根据部署方式的不同9095/9528 端口皆可以进入项目,如果一个不行试另一个端口
+ 2、确定前端是否启动
+ 3、确定后端是否启动 br> -- 数据源数据集用法总结
- [链接](https://my.oschina.net/u/4517014/blog/5270828)
+
-### 执行源码编译脚本(build.sh)报错 +## 执行源码编译脚本(build.sh)报错 - 提示:“*** report-ui/dist/* *** No such file or directory”
前端编译失败。
- 99%的原因是Node.js版本过高(高于14),导致前端编译失败,Nodejs在编译执行初始化时会去下载一些依赖,如果依赖下载不来,也会导致失败。
- 剩下极少数情况可能是你编译的linux系统问题。
+ 大部分原因是Node.js版本过高(高于V14),导致前端编译失败。
+ 另一部分是Nodejs在编译执行初始化时会去下载一些依赖,如果依赖下载不下来,也会导致失败。
+ +
- 提示:“report-core/target/aj-report-*.zip *** No such file or directory”
后端编译失败。
- 可能原因有:Mvn版本过低/过高,导致后端编译失败
+ 可能原因有:Maven版本过低/过高,导致后端编译失败
+ +
- 使用eclipse进行源码编译时失败
失败的提示有很多,这里建议换成IDEA
+
+ - 使用IDEA进行源码编译时提示:“*** openjdk-***”
请使用jdk1.8 -### 启动服务报错 +
+ +## 启动服务相关 - 提示“xxx The driver has not received any packets from the server”
连不上mysql。
@@ -55,11 +76,37 @@ 2、mysql版本不兼容,详细看上面关于版本兼容性
3、bootstrap.yml中配置的mysql地址ip不对
+
+ +- flyway执行报错1.0.10sql失败
+ 错误提示:Caused by: org.flywaydb.core.api.FlywayException: Validate failed: Detected failed
+ migration to version 1.0.10 (create report share)
+ 请参考此 [Issue](https://gitee.com/anji-plus/report/issues/I47JNE) 解决此问题
+ +
+ +## 数据集相关 + +- 系统异常,后台日志显示“** Data too long for colum ** ”
+ 1、建议不要使用 "select *"
+ 2、一张图表能承载的数据量是有限的,太多则图表展示不出来、页面卡死等
+ 3、必须使用 "select *" ,或者展示很多数据。解决方法,将测试预览的值删掉只剩一条,注意数据的结构 [{}]
+ +## 大屏图表组件相关 + +- 访问白屏
+ 设计完大屏,保存后进行预览,发现背景全白
+ 1、回到编辑页面,查看大屏背景颜色是否设置
+ 2、查看大屏的宽高,如果宽高都是0(大屏宽高在设计时,有概率性变成0,不知原因)大屏背景图片,颜色,皆无法显示
+ 3、大屏宽高改成 1920 1080
+ +
+ +- 文本框颜色无法改变
+ 使用文本框,改变颜色,无法改变。已知有概率性的出现无法修改文本框颜色的情况,因为无法重现,暂时不能排查到是哪里问题。解决方法有以下
+ 1、保存退出大屏,重新进入大屏修改文本框颜色
+ 2、删掉文本框,重新拖动一个
-- 提示“404”
- 1、确保访问地址无误,根据部署方式的不同9095/9528 端口皆可以进入项目,如果一个不行试另一个端口
- 2、确定前端是否启动
- 3、确定后端是否启动 br> diff --git a/doc/docs/guide/quicklyDistribution.md b/doc/docs/guide/quicklyDistribution.md index 0503de80..89b3a61d 100644 --- a/doc/docs/guide/quicklyDistribution.md +++ b/doc/docs/guide/quicklyDistribution.md @@ -23,7 +23,7 @@ ## 上传功能 -使用上传功能,必须修改此内容
+使用上传功能,必须修改此内容,注意路径格式,比如Win是 \ ,linux是 /
![file.png](../picture/quickly/img_15.png)
## 启动 diff --git a/doc/docs/guide/quicklySeparate.md b/doc/docs/guide/quicklySeparate.md index 88452dfe..d31a3557 100644 --- a/doc/docs/guide/quicklySeparate.md +++ b/doc/docs/guide/quicklySeparate.md @@ -1,5 +1,6 @@ -**前后端分离:请对自己有动手能力的小伙伴进行尝试** -**请根据自己的实际情况对下面的步骤和内容进行调整** +**前后端分离:**
+**请对自己有动手能力的小伙伴进行尝试**
+**请根据自己的实际情况对下面的步骤和内容进行调整**
``` linux: @@ -42,11 +43,12 @@ report-core --> src --> main --> resources --> bootstrap.yml
### 上传功能 -使用上传功能,必须修改此内容
+使用上传功能,必须修改此内容,注意路径格式,比如Win是 \ ,linux是 /
![file.png](../picture/quickly/img_15.png)
### maven打包 +**打包之前如果系统用的不止mysql数据源,需要自己在pom文件中加入对应的数据库的驱动,登陆系统之后,数据源提示无驱动,则选择通用JDBC数据源,这里不做演示了**
使用 maven package
**注**:不要使用maven install
![img10](../picture/quickly/img_10.png)
diff --git a/doc/docs/guide/quicklySource.md b/doc/docs/guide/quicklySource.md index d9e1cdee..867ff652 100644 --- a/doc/docs/guide/quicklySource.md +++ b/doc/docs/guide/quicklySource.md @@ -47,7 +47,7 @@ git clone https://gitee.com/anji-plus/report.git
## 上传功能 -使用上传功能,必须修改此内容
+使用上传功能,必须修改此内容,注意路径格式,比如Win是 \ ,linux是 /
![file.png](../picture/quickly/img_15.png) ## 启动 diff --git a/doc/docs/picture/bigScreenCase/img1.png b/doc/docs/picture/bigScreenCase/img1.png new file mode 100644 index 00000000..6755f73a Binary files /dev/null and b/doc/docs/picture/bigScreenCase/img1.png differ diff --git a/doc/docs/picture/bigScreenCase/img2.png b/doc/docs/picture/bigScreenCase/img2.png new file mode 100644 index 00000000..4894b04f Binary files /dev/null and b/doc/docs/picture/bigScreenCase/img2.png differ diff --git a/doc/docs/picture/bigScreenCase/img3.png b/doc/docs/picture/bigScreenCase/img3.png new file mode 100644 index 00000000..5082c3af Binary files /dev/null and b/doc/docs/picture/bigScreenCase/img3.png differ diff --git a/doc/docs/picture/bigScreenCase/img4.png b/doc/docs/picture/bigScreenCase/img4.png new file mode 100644 index 00000000..e121248b Binary files /dev/null and b/doc/docs/picture/bigScreenCase/img4.png differ diff --git a/doc/docs/picture/charts/img_13.png b/doc/docs/picture/charts/img_13.png new file mode 100644 index 00000000..989e930c Binary files /dev/null and b/doc/docs/picture/charts/img_13.png differ diff --git a/doc/docs/picture/charts/img_14.png b/doc/docs/picture/charts/img_14.png new file mode 100644 index 00000000..d25509a1 Binary files /dev/null and b/doc/docs/picture/charts/img_14.png differ diff --git a/doc/docs/picture/charts/img_15.png b/doc/docs/picture/charts/img_15.png new file mode 100644 index 00000000..c8402895 Binary files /dev/null and b/doc/docs/picture/charts/img_15.png differ diff --git a/doc/docs/picture/charts/img_16.png b/doc/docs/picture/charts/img_16.png new file mode 100644 index 00000000..284cea6d Binary files /dev/null and b/doc/docs/picture/charts/img_16.png differ diff --git a/doc/docs/picture/charts/img_17.png b/doc/docs/picture/charts/img_17.png new file mode 100644 index 00000000..ea50480a Binary files /dev/null and b/doc/docs/picture/charts/img_17.png differ diff --git a/doc/docs/picture/charts/img_18.png b/doc/docs/picture/charts/img_18.png new file mode 100644 index 00000000..e7efbfc0 Binary files /dev/null and b/doc/docs/picture/charts/img_18.png differ diff --git a/doc/docs/picture/charts/img_19.png b/doc/docs/picture/charts/img_19.png new file mode 100644 index 00000000..d4aa954e Binary files /dev/null and b/doc/docs/picture/charts/img_19.png differ diff --git a/doc/docs/picture/charts/img_20.png b/doc/docs/picture/charts/img_20.png new file mode 100644 index 00000000..c5f6f66d Binary files /dev/null and b/doc/docs/picture/charts/img_20.png differ diff --git a/doc/docs/picture/dashboard/img_13.png b/doc/docs/picture/dashboard/img_13.png deleted file mode 100644 index ccaca184..00000000 Binary files a/doc/docs/picture/dashboard/img_13.png and /dev/null differ diff --git a/doc/docs/picture/dashboard/img_16.png b/doc/docs/picture/dashboard/img_16.png deleted file mode 100644 index 8f0ab24a..00000000 Binary files a/doc/docs/picture/dashboard/img_16.png and /dev/null differ diff --git a/doc/docs/picture/dashboard/img_8.png b/doc/docs/picture/dashboard/img_8.png deleted file mode 100644 index eaf5956b..00000000 Binary files a/doc/docs/picture/dashboard/img_8.png and /dev/null differ diff --git a/doc/docs/picture/dashboard/img_9.png b/doc/docs/picture/dashboard/img_9.png deleted file mode 100644 index fb052970..00000000 Binary files a/doc/docs/picture/dashboard/img_9.png and /dev/null differ diff --git a/doc/docs/picture/qusetion/img_4.png b/doc/docs/picture/qusetion/img_4.png new file mode 100644 index 00000000..808f4fd0 Binary files /dev/null and b/doc/docs/picture/qusetion/img_4.png differ diff --git a/doc/docs/picture/qusetion/img_5.png b/doc/docs/picture/qusetion/img_5.png new file mode 100644 index 00000000..c33db50b Binary files /dev/null and b/doc/docs/picture/qusetion/img_5.png differ diff --git a/report-core/pom.xml b/report-core/pom.xml index c54d40ac..423b3b05 100644 --- a/report-core/pom.xml +++ b/report-core/pom.xml @@ -29,8 +29,27 @@ org.springframework.boot spring-boot-starter-web + + + org.apache.logging.log4j + log4j-to-slf4j + + + + org.apache.logging.log4j + log4j-to-slf4j + 2.15.0 + + + + org.apache.logging.log4j + log4j-api + 2.15.0 + + + org.springframework.boot spring-boot-starter-cache diff --git a/report-core/src/main/assembly/bin/start.sh b/report-core/src/main/assembly/bin/start.sh index 6cb986ce..fbb492a6 100755 --- a/report-core/src/main/assembly/bin/start.sh +++ b/report-core/src/main/assembly/bin/start.sh @@ -23,4 +23,4 @@ fi JAVA_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k " nohup java $JAVA_OPTS -Xbootclasspath/a:$LIB_JARS -jar -Dspring.config.location=$CONF_DIR/bootstrap.yml $LIB_DIR/aj-report-*.jar >/dev/null 2>&1 & -echo "The AJ-Report started!" +echo "AJ-Report 正在后台执行,请查看aj-report.log日志(tail -F ../logs/aj-report.log),确定软件运行情况" diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java index d748a558..e6595b68 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/TokenFilter.java @@ -4,8 +4,10 @@ package com.anjiplus.template.gaea.business.filter; import com.alibaba.fastjson.JSONObject; import com.anji.plus.gaea.bean.ResponseBean; import com.anji.plus.gaea.cache.CacheHelper; +import com.anji.plus.gaea.constant.GaeaConstant; import com.anji.plus.gaea.utils.JwtBean; import com.anjiplus.template.gaea.business.constant.BusinessConstant; +import com.anjiplus.template.gaea.business.modules.accessuser.controller.dto.GaeaUserDto; import com.anjiplus.template.gaea.business.util.JwtUtil; import org.apache.commons.lang3.StringUtils; import org.apache.http.entity.ContentType; @@ -14,13 +16,20 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.CollectionUtils; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static com.anji.plus.gaea.constant.GaeaConstant.URL_REPLACEMENT; /** * 简单的鉴权 @@ -33,6 +42,7 @@ public class TokenFilter implements Filter { private static final Pattern PATTERN = Pattern.compile(".*().*"); private static final String USER_GUEST = "guest"; private static final String SLASH = "/"; + private AntPathMatcher antPathMatcher = new AntPathMatcher(); @Autowired private CacheHelper cacheHelper; @@ -115,32 +125,53 @@ public class TokenFilter implements Filter { } String gaeaUserJsonStr = cacheHelper.stringGet(userKey); + //判断接口权限 + //请求路径 + String requestUrl = request.getRequestURI(); + String methodValue = request.getMethod(); + //请求方法+#+请求路径 + String urlKey = methodValue + GaeaConstant.URL_SPLIT + requestUrl; + + GaeaUserDto gaeaUserDto = JSONObject.parseObject(gaeaUserJsonStr, GaeaUserDto.class); + List authorities = gaeaUserDto.getAuthorities(); + Map applicationNameAllAuthorities = cacheHelper.hashGet(BusinessConstant.GAEA_SECURITY_AUTHORITIES); + AtomicBoolean authFlag = new AtomicBoolean(false); + //查询当前请求是否在对应的权限里。即:先精确匹配(保证当前路由是需要精确匹配还是模糊匹配,防止精确匹配的被模糊匹配) + // 比如:/user/info和/user/**同时存在,/user/info,被/user/**匹配掉 + if (applicationNameAllAuthorities.containsKey(urlKey)) { + String permissionCode = applicationNameAllAuthorities.get(urlKey); + if (authorities.contains(permissionCode)) { + authFlag.set(true); + } + } else { + List collect = applicationNameAllAuthorities.keySet().stream() + .filter(key -> StringUtils.isNotBlank(key) && key.contains(URL_REPLACEMENT)) + .filter(key -> antPathMatcher.match(key, urlKey)).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(collect)) { + authFlag.set(true); + }else { + collect.forEach(key -> { + String permissionCode = applicationNameAllAuthorities.getOrDefault(key, ""); + if (authorities.contains(permissionCode)) { + authFlag.set(true); + } + }); + } + } + + if (!authFlag.get()) { + //无权限 + authError(response); + return; + } + + + + // 延长有效期 cacheHelper.stringSetExpire(tokenKey, token, 3600); cacheHelper.stringSetExpire(userKey, gaeaUserJsonStr, 3600); - //在线体验版本 - if (USER_GUEST.equals(loginName) - && !uri.endsWith("/dataSet/testTransform") - && !uri.endsWith("/reportDashboard/getData") - && !uri.startsWith("/dict") - && !uri.endsWith("/reportExcel/preview") - ) { - //不允许删除 - String method = request.getMethod(); - if (HttpMethod.POST.name().equalsIgnoreCase(method) - || HttpMethod.PUT.name().equalsIgnoreCase(method) - || HttpMethod.DELETE.name().equalsIgnoreCase(method) - || uri.contains("/reportDashboard/export") - ) { - ResponseBean responseBean = ResponseBean.builder().code("50001") - .message("在线体验版本,不允许此操作。请自行下载本地运行").build(); - response.setContentType(ContentType.APPLICATION_JSON.getMimeType()); - response.getWriter().print(JSONObject.toJSONString(responseBean)); - return; - } - } - //执行 filterChain.doFilter(request, response); } @@ -180,4 +211,10 @@ public class TokenFilter implements Filter { response.setContentType(ContentType.APPLICATION_JSON.getMimeType()); response.getWriter().print(JSONObject.toJSONString(responseBean)); } + + private void authError(HttpServletResponse response) throws IOException { + ResponseBean responseBean = ResponseBean.builder().code("User.no.authority").message("没有权限").build(); + response.setContentType(ContentType.APPLICATION_JSON.getMimeType()); + response.getWriter().print(JSONObject.toJSONString(responseBean)); + } } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java new file mode 100644 index 00000000..0d79a3a0 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/filter/UrlDecodeFilter.java @@ -0,0 +1,77 @@ +package com.anjiplus.template.gaea.business.filter; + +import com.anji.plus.gaea.constant.GaeaConstant; +import org.apache.catalina.util.ParameterMap; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.ognl.IteratorEnumeration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.Enumeration; +import java.util.Map; +import java.util.Set; + +/** + * @author: Raod + * @since: 2022-01-26 + */ +@Component +@Order(Ordered.HIGHEST_PRECEDENCE + 1) +public class UrlDecodeFilter implements Filter { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + ParameterMap parameterMap = (ParameterMap) httpServletRequest.getParameterMap(); + ParamHttpServletRequestWrapper wrapper = new ParamHttpServletRequestWrapper(httpServletRequest, parameterMap); + + Enumeration parameterNames = wrapper.getParameterNames(); + while (parameterNames.hasMoreElements()) { + String paramName = parameterNames.nextElement(); + String parameter = httpServletRequest.getParameter(paramName); + if (StringUtils.isNotBlank(parameter)) { + String decode = URLDecoder.decode(parameter, GaeaConstant.CHARSET_UTF8); + parameterMap.setLocked(false); + parameterMap.put(paramName, new String[]{decode}); + } + } + filterChain.doFilter(wrapper, servletResponse); + } + + /** + * 参数 + */ + class ParamHttpServletRequestWrapper extends HttpServletRequestWrapper { + + private ParameterMap parameterMap; + + public ParamHttpServletRequestWrapper(HttpServletRequest request, ParameterMap parameterMap) { + super(request); + this.parameterMap = parameterMap; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } + + @Override + public Enumeration getParameterNames() { + + Set keySet = parameterMap.keySet(); + IteratorEnumeration iteratorEnumeration = new IteratorEnumeration(keySet.iterator()); + return iteratorEnumeration; + } + + @Override + public String[] getParameterValues(String name) { + return parameterMap.get(name); + } + } +} diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java index 4c8925db..06e73ba2 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java @@ -7,9 +7,12 @@ import com.anji.plus.gaea.bean.ResponseBean; import com.anjiplus.template.gaea.business.modules.dashboard.service.ReportDashboardService; import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ChartDto; import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.ReportDashboardObjectDto; +import com.anjiplus.template.gaea.business.modules.reportshare.controller.dto.ReportShareDto; +import com.anjiplus.template.gaea.business.modules.reportshare.service.ReportShareService; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -31,6 +34,9 @@ public class ReportDashboardController { @Autowired private ReportDashboardService reportDashboardService; + @Autowired + private ReportShareService reportShareService; + /** * 预览、查询大屏详情 * @param reportCode @@ -93,4 +99,10 @@ public class ReportDashboardController { return ResponseBean.builder().build(); } + @PostMapping("/share") + @GaeaAuditLog(pageTitle = "分享") + public ResponseBean share(@Validated @RequestBody ReportShareDto dto) { + return ResponseBean.builder().data(reportShareService.insertShare(dto)).build(); + } + } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java index a89fc060..fd3f2117 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java @@ -16,6 +16,7 @@ import com.anjiplus.template.gaea.business.modules.dashboard.service.ReportDashb import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile; import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService; import com.anjiplus.template.gaea.business.modules.file.util.FileUtils; +import com.anjiplus.template.gaea.business.modules.report.service.ReportService; import com.anjiplus.template.gaea.business.util.DateUtil; import com.anjiplus.template.gaea.business.modules.dashboardwidget.controller.dto.ReportDashboardWidgetDto; import com.anjiplus.template.gaea.business.modules.dashboardwidget.controller.dto.ReportDashboardWidgetValueDto; @@ -26,6 +27,7 @@ import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.DataSe import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.OriginalDataDto; import com.anjiplus.template.gaea.business.modules.dataset.service.DataSetService; import com.anjiplus.template.gaea.business.util.FileUtil; +import com.anjiplus.template.gaea.business.util.RequestUtil; import com.anjiplus.template.gaea.business.util.UuidUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -51,6 +53,7 @@ import java.io.File; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.*; +import java.util.concurrent.CompletableFuture; /** * @author Raod @@ -74,6 +77,9 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi @Autowired private GaeaFileService gaeaFileService; + @Autowired + private ReportService reportService; + @Value("${customer.file.downloadPath:''}") private String fileDownloadPath; @@ -272,6 +278,13 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi FileUtil.delete(path); log.info("删除临时文件:{},{}", zipPath, path); + //异步统计下载次数 + CompletableFuture.runAsync(() -> { + log.info("=======>ip:{} 下载模板:{}", RequestUtil.getIpAddr(request), reportCode); + reportService.downloadStatistics(reportCode); + }); + + return body; } @@ -316,11 +329,15 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(GaeaFile::getFileId, fileName); GaeaFile gaeaFile = gaeaFileService.selectOne(queryWrapper); + String uploadPath; if (null == gaeaFile) { GaeaFile upload = gaeaFileService.upload(imageFile, fileName); log.info("存入图片: {}", upload.getFilePath()); - fileMap.put(fileName, upload.getUrlPath()); + uploadPath = upload.getUrlPath(); + }else { + uploadPath = gaeaFile.getUrlPath(); } + fileMap.put(fileName, uploadPath); } } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/controller/ReportController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/controller/ReportController.java index 93745458..6269e7d0 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/controller/ReportController.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/controller/ReportController.java @@ -9,12 +9,12 @@ import com.anjiplus.template.gaea.business.modules.report.controller.dto.ReportD import com.anjiplus.template.gaea.business.modules.report.controller.param.ReportParam; import com.anjiplus.template.gaea.business.modules.report.dao.entity.Report; import com.anjiplus.template.gaea.business.modules.report.service.ReportService; -import com.anjiplus.template.gaea.business.modules.reportshare.controller.dto.ReportShareDto; -import com.anjiplus.template.gaea.business.modules.reportshare.service.ReportShareService; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** * TODO @@ -28,9 +28,6 @@ import org.springframework.web.bind.annotation.*; @RequestMapping("/report") public class ReportController extends GaeaBaseController { - @Autowired - private ReportShareService reportShareService; - @Autowired private ReportService reportService; @@ -56,11 +53,4 @@ public class ReportController extends GaeaBaseController { void delReport(ReportDto reportDto); + + /** + * 下载次数+1 + * @param reportCode + */ + void downloadStatistics(String reportCode); } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java index f0cfd30a..e5b32704 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/report/service/impl/ReportServiceImpl.java @@ -34,6 +34,27 @@ public class ReportServiceImpl implements ReportService { //... } + /** + * 下载次数+1 + * + * @param reportCode + */ + @Override + public void downloadStatistics(String reportCode) { + Report report = selectOne("report_code", reportCode); + if (null != report) { + Long downloadCount = report.getDownloadCount(); + if (null == downloadCount) { + downloadCount = 0L; + }else { + downloadCount++; + } + report.setDownloadCount(downloadCount); + update(report); + } + + } + @Override public void processBeforeOperation(Report entity, BaseOperationEnum operationEnum) throws BusinessException { diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java index 21117400..865dd7dd 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/service/impl/ReportExcelServiceImpl.java @@ -22,6 +22,7 @@ import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.Re import com.anjiplus.template.gaea.business.modules.reportexcel.dao.ReportExcelMapper; import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel; import com.anjiplus.template.gaea.business.modules.reportexcel.service.ReportExcelService; +import com.anjiplus.template.gaea.business.modules.reportexcel.util.CellType; import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsSheetUtil; import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -254,67 +255,333 @@ public class ReportExcelServiceImpl implements ReportExcelService { if (dbObject.containsKey("celldata") && null != dbObject.get("celldata")) { List celldata = new ArrayList<>(); celldata.addAll((List) dbObject.get("celldata")); + + //整理celldata数据,转换为map格式,方便后续使用单元格位置获取对应的cell对象 + Map cellDataMap = cellDataList2Map(celldata); + //清除原有的数据 + dbObject.getJSONArray("celldata").clear(); + //获取配置项中的合并属性 + JSONObject merge = dbObject.getJSONObject("config").getJSONObject("merge"); + if(merge != null) merge.clear(); + //定义存储每一列动态扩展的行数 + Map colAddCntMap = new HashMap<>(); // 遍历已存在的单元格,查看是否存在动态参数 for (int i = 0; i < celldata.size(); i++) { //单元格对象 JSONObject cellObj = celldata.get(i); //fastjson深拷贝问题 String cellStr = cellObj.toJSONString(); + analysisCellData(cellObj,setParam,colAddCntMap,cellStr,merge, dbObject,cellDataMap); + } + } + } - //行号 - Integer r = cellObj.getInteger("r"); - //列号 - Integer c = cellObj.getInteger("c"); - JSONObject cell = cellObj.getJSONObject("v"); - if (null != cell && cell.containsKey("v") && StringUtils.isNotBlank(cell.getString("v"))) { - String v = cell.getString("v"); - DataSetDto dataSet = getDataSet(v, setParam); - if (null != dataSet) { - OriginalDataDto originalDataDto = dataSetService.getData(dataSet); - if (null != originalDataDto.getData()) { - List data = originalDataDto.getData(); - - for (int j = 0; j < data.size(); j++) { - if (j == 0) { - //处理当前行 - //第一行,作为渲染参照数据 - JSONObject jsonObject = data.get(j); - String fieldLabel = jsonObject.getString(dataSet.getFieldLabel()); + /** + * 开始解析并渲染 cellData + * @param cellObject + */ + public void analysisCellData(JSONObject cellObject,String setParam,Map colAddCntMap,String cellStr, + JSONObject merge,JSONObject dbObject,Map cellDataMap){ + //获取行号 + Integer cellR = cellObject.getInteger("r"); + //获取列数 + Integer cellC = cellObject.getInteger("c"); + //获取此行已经动态增加的行数,默认0行 + int cnt = colAddCntMap.get(cellC) == null ? 0 : colAddCntMap.get(cellC); + //获取单元格类型 + CellType cellType = getCellType(cellObject); + switch (cellType){ + case BLACK: + //空数据单元格不处理 + break; + case DYNAMIC_MERGE: + case DYNAMIC: + //处理动态单元格 + String v = cellObject.getJSONObject("v").getString("v"); + DataSetDto dataSet = getDataSet(v, setParam); + handleDynamicCellObject(dataSet,v,cellStr,cnt,cellR,cellC,merge,dbObject,colAddCntMap); + break; + default: + //处理静态单元格 + handleStaticCellObject(cellStr,dbObject,cnt,cellR,cellC,cellDataMap,setParam,merge,colAddCntMap,cellType); + break; + } + } - String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); - dbObject.getJSONArray("celldata").getJSONObject(i).getJSONObject("v").put("v", replace); - dbObject.getJSONArray("celldata").getJSONObject(i).getJSONObject("v").put("m", replace); - } else { - //新增的行数据 - JSONObject addCell = data.get(j); - //字段 - String fieldLabel = addCell.getString(dataSet.getFieldLabel()); - String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + /** + * 处理动态数据单元格自动扩展 + * @param dataSet + * @param v + * @param cellStr + * @param cnt + * @param r + * @param c + * @param merge + * @param dbObject + * @param colAddCntMap + */ + public void handleDynamicCellObject(DataSetDto dataSet,String v,String cellStr,int cnt,int r,int c, + JSONObject merge,JSONObject dbObject,Map colAddCntMap){ + //获取动态数据 + OriginalDataDto originalDataDto = dataSetService.getData(dataSet); + List cellDynamicData = originalDataDto.getData(); + + if(cellDynamicData != null){ + //循环数据赋值 + for (int j = 0; j < cellDynamicData.size(); j++) { + //新增的行数据 + JSONObject addCell = cellDynamicData.get(j); + //字段 + String fieldLabel = addCell.getString(dataSet.getFieldLabel()); + String replace = v.replace("#{".concat(dataSet.getSetCode()).concat(".").concat(dataSet.getFieldLabel()).concat("}"), fieldLabel); + //转字符串,解决深拷贝问题 + JSONObject addCellData = JSONObject.parseObject(cellStr); + + addCellData.put("r", cnt + r + j); //行数增加 + addCellData.put("c", c); + addCellData.getJSONObject("v").put("v", replace); + addCellData.getJSONObject("v").put("m", replace); + JSONObject cellMc = addCellData.getJSONObject("v").getJSONObject("mc"); + //判断是否是合并单元格 + if(null != cellMc){ + //处理合并单元格 + Integer rs = cellMc.getInteger("rs"); + cellMc.put("r", cnt + r + rs*j); //行数增加 + cellMc.put("c", c); + addCellData.put("r", cnt + r + rs*j); + //合并单元格需要处理config.merge + merge.put(cellMc.getString("r")+"_"+cellMc.getString("c"),cellMc); + //处理单元格扩展之后此列扩展的总行数 + colAddCntMap.put(c,cnt + rs * cellDynamicData.size() - 1); + }else{ + //处理单元格扩展之后此列扩展的总行数 + colAddCntMap.put(c,cnt + cellDynamicData.size() - 1); + } + dbObject.getJSONArray("celldata").add(addCellData); + } + } + } - //转字符串,解决深拷贝问题 - JSONObject addCellData = JSONObject.parseObject(cellStr); + /** + * 处理静态单元格数据 + * @param cellStr + * @param dbObject + * @param cnt + * @param r + * @param c + * @param cellDataMap + * @param setParam + * @param merge + * @param colAddCntMap + * @param cellType + */ + public void handleStaticCellObject(String cellStr,JSONObject dbObject,int cnt,int r,int c, + Map cellDataMap,String setParam, + JSONObject merge,Map colAddCntMap,CellType cellType){ + //转字符串,解决深拷贝问题 + JSONObject addCellData = JSONObject.parseObject(cellStr); + int rows = 0; + switch(cellType){ + case STATIC: + case STATIC_MERGE: + //静态不扩展单元格只需要初始化位置就可以 + initCellPosition(addCellData,cnt,merge); + break; + case STATIC_AUTO: + //获取静态单元格右侧动态单元格的总行数 + rows = getRightDynamicCellRows(addCellData,cellDataMap,setParam,rows,cellType); + initCellPosition(addCellData,cnt,merge); + if(rows > 1){ + //需要把这个静态扩展单元格 改变为 静态合并扩展单元格,就是增加合并属性 mc 以及merge配置 + JSONObject mc = new JSONObject(); + mc.put("rs",rows); + mc.put("cs",1); + mc.put("r",addCellData.getIntValue("r")); + mc.put("c",addCellData.getIntValue("c")); + addCellData.getJSONObject("v").put("mc",mc); + //合并单元格需要处理config.merge + merge.put((mc.getInteger("r")) + "_" + mc.getString("c"),mc); + //处理单元格扩展之后此列扩展的总行数 + colAddCntMap.put(c,cnt + rows - 1); + } + break; + case STATIC_MERGE_AUTO: + //获取静态单元格右侧动态单元格的总行数 + rows = getRightDynamicCellRows(addCellData,cellDataMap,setParam,rows,cellType); + initCellPosition(addCellData,cnt,merge); + if(rows > 0){ + //需要修改单元格mc中的rs + JSONObject cellMc = addCellData.getJSONObject("v").getJSONObject("mc"); + int addCnt = cellMc.getInteger("rs"); + cellMc.put("rs",rows); + //合并单元格需要处理config.merge + merge.put((cellMc.getInteger("r")) + "_" + cellMc.getString("c"),cellMc); + //处理单元格扩展之后此列扩展的总行数 + colAddCntMap.put(c,cnt + rows - addCnt); + } + break; + } + dbObject.getJSONArray("celldata").add(addCellData); + } - addCellData.put("r", r + j); - addCellData.put("c", c); - addCellData.getJSONObject("v").put("v", replace); - addCellData.getJSONObject("v").put("m", replace); - dbObject.getJSONArray("celldata").add(addCellData); + /** + * 初始化单元格位置,主要是这一列已经动态增加的行数 + * @param addCellData + * @param cnt + * @param merge + */ + public void initCellPosition(JSONObject addCellData,int cnt,JSONObject merge){ + addCellData.put("r", cnt + addCellData.getInteger("r"));//行数增加 + //是否是合并单元格 + JSONObject mc = addCellData.getJSONObject("v").getJSONObject("mc"); + if(mc != null){ + mc.put("r",addCellData.getInteger("r")); + initCellMerge(merge,mc); + } + } - } + /** + * 初始化单元格合并属性的行数 + * @param merge + * @param mc + */ + public void initCellMerge(JSONObject merge,JSONObject mc){ + merge.put((mc.getInteger("r"))+"_"+mc.getString("c"),mc); + } - } + /** + * 获取合并单元格右侧的动态扩展行数,用来设置当前单元格的实际 + * @param addCellData + * @param cellDataMap + * @param setParam + * @param sumRows + * @param cellType + * @return + */ + public int getRightDynamicCellRows(JSONObject addCellData,Map cellDataMap,String setParam,int sumRows,CellType cellType){ + //1、获取此单元格右侧关联的所有单元格 + List rightCellList = getRightDynamicCell(addCellData,cellDataMap,cellType); + //2、循环获取每个单元格的扩展行数 + for (JSONObject rightCell : rightCellList) { + //首先判断这个单元格是否也是【静态扩展单元格】 + CellType rightCellType = getCellType(rightCell); + switch (rightCellType){ + case STATIC_AUTO: + case STATIC_MERGE_AUTO: + //递归查找 + sumRows = getRightDynamicCellRows(rightCell,cellDataMap,setParam,sumRows,rightCellType); + break; + case BLACK: + case STATIC: + sumRows++; + break; + case STATIC_MERGE: + sumRows += rightCell.getJSONObject("v").getJSONObject("mc").getInteger("rs"); + break; + default: + List cellDynamicData = getDynamicDataList(rightCell.getJSONObject("v").getString("v"),setParam); + if(cellDynamicData != null && cellDynamicData.size() > 1){ + int size = cellDynamicData.size(); + sumRows += size; + }else{ + sumRows++; + } + break; + } + } + return sumRows; + } - } + /** + * 获取扩展单元格右侧相邻的所有单元格实体 + * @param addCellData + * @param cellDataMap + * @param cellType + * @return + */ + public List getRightDynamicCell(JSONObject addCellData,Map cellDataMap,CellType cellType){ + //静态数据合并单元格需要根据右侧的单元格进行自动向下扩展 + //1、先获取右侧一列的关联的单元格,根据自身的位置,以及自己合并的合并的信息推断 + //如果自己位置是 2,5,并且本身合并 行数2,列数3,则需要推断出两个单元格的位置 + //分别是2,8 和 3,8 + Integer cellR = addCellData.getInteger("r"); + Integer cellC = addCellData.getInteger("c"); + Integer cellRs = 0; + Integer cellCs = 0; + switch (cellType){ + case STATIC_AUTO: + cellRs = 1; + cellCs = 1; + break; + case STATIC_MERGE_AUTO: + cellRs = addCellData.getJSONObject("v").getJSONObject("mc").getInteger("rs"); + cellCs = addCellData.getJSONObject("v").getJSONObject("mc").getInteger("cs"); + break; + } + List rightCells = new ArrayList<>(); + for(int nums = 0;nums < cellRs;nums++){ + int r = cellR + nums; + int c = cellC + cellCs; + String key = r + "," + c; + if(cellDataMap.containsKey(key)){ + JSONObject cellData = cellDataMap.get(r + "," + c); + rightCells.add(cellData); + } + } + return rightCells; + } + /** + * 判断单元格类型 + * @param cellObject + * @return + */ + public CellType getCellType(JSONObject cellObject){ + JSONObject cellV1 = cellObject.getJSONObject("v"); + if (null != cellV1 && cellV1.containsKey("v") && StringUtils.isNotBlank(cellV1.getString("v"))) { + String cellV2 = cellObject.getJSONObject("v").getString("v"); + String auto = cellObject.getJSONObject("v").getString("auto"); + JSONObject mc = cellObject.getJSONObject("v").getJSONObject("mc"); + if(cellV2.contains("#{") && cellV2.contains("}") ){ + //动态单元格 + if(mc != null){ + return CellType.DYNAMIC_MERGE; + }else{ + return CellType.DYNAMIC; + } + }else{ + //静态单元格 + if(mc != null && "1".equals(auto)){ + return CellType.STATIC_MERGE_AUTO; + }else { + if("1".equals(auto)){ + return CellType.STATIC_AUTO; + }else if(mc != null){ + return CellType.STATIC_MERGE; + }else{ + return CellType.STATIC; } } } - + }else{ + return CellType.BLACK; } - - } + /** + * list转为map结构,方便使用行列号查找对应cell对象 + * @param cellDataList + * @return + */ + public Map cellDataList2Map(List cellDataList){ + Map cellDataMap = new HashMap<>(); + for (JSONObject cellData : cellDataList) { + String r = cellData.getString("r"); + String c = cellData.getString("c"); + cellDataMap.put(r + "," + c, cellData); + } + return cellDataMap; + } /** * 解析 #{xxxx.xxxxx} 数据 @@ -341,6 +608,27 @@ public class ReportExcelServiceImpl implements ReportExcelService { return null; } + /** + * 获取单元格对应的动态数据集 + * @param v + * @param setParam + * @return + */ + private List getDynamicDataList(String v, String setParam){ + if(StringUtils.isNotBlank(v)){ + DataSetDto dataSet = getDataSet(v,setParam); + if(dataSet != null){ + OriginalDataDto originalDataDto = dataSetService.getData(dataSet); + List cellDynamicData = originalDataDto.getData(); + return cellDynamicData; + }else{ + return null; + } + }else{ + return null; + } + } + /** * 动态参数替换 * @param setParam diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/CellType.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/CellType.java new file mode 100644 index 00000000..0a86c309 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/CellType.java @@ -0,0 +1,39 @@ +package com.anjiplus.template.gaea.business.modules.reportexcel.util; + +/** + * 单元格类型 + */ +public enum CellType { + DYNAMIC_MERGE("DYNAMIC_MERGE","动态合并单元格"), + DYNAMIC("DYNAMIC","动态单元格"), + STATIC("STATIC","静态单元格"), + STATIC_AUTO("STATIC_AUTO","静态扩展单元格"), + STATIC_MERGE("STATIC_MERGE","静态合并单元格"), + STATIC_MERGE_AUTO("STATIC_MERGE_AUTO","静态合并扩展单元格"), + BLACK("BLACK","空白单元格"); + + private String code; + private String name; + + CellType(String code,String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } + + public void setCode(String code) { + this.code = code; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java index 0f30339d..a436002a 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/reportexcel/util/XlsSheetUtil.java @@ -653,7 +653,7 @@ public class XlsSheetUtil { } else { style.setDataFormat((short) 0); } - cell.setCellType(CellType.STRING); + cell.setCellType(org.apache.poi.ss.usermodel.CellType.STRING); break; } case "d": { @@ -692,7 +692,7 @@ public class XlsSheetUtil { } case "b": { //逻辑 - cell.setCellType(CellType.BOOLEAN); + cell.setCellType(org.apache.poi.ss.usermodel.CellType.BOOLEAN); if (_i >= 0) { style.setDataFormat(_i.shortValue()); } else { @@ -705,7 +705,7 @@ public class XlsSheetUtil { //数值 // cell.setCellType(CellType.NUMERIC); //数字转字符串 - cell.setCellType(CellType.STRING); + cell.setCellType(org.apache.poi.ss.usermodel.CellType.STRING); if (_i >= 0) { style.setDataFormat(_i.shortValue()); } else { @@ -728,7 +728,7 @@ public class XlsSheetUtil { } case "e": { //错误 - cell.setCellType(CellType.ERROR); + cell.setCellType(org.apache.poi.ss.usermodel.CellType.ERROR); if (_i >= 0) { style.setDataFormat(_i.shortValue()); } else { diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/util/RequestUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/util/RequestUtil.java new file mode 100644 index 00000000..dda02739 --- /dev/null +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/util/RequestUtil.java @@ -0,0 +1,50 @@ +package com.anjiplus.template.gaea.business.util; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author: Raod + * @since: 2022-01-21 + */ +public class RequestUtil { + + /**获取ip地址 + * @param request + * @return + */ + public static String getIpAddr(HttpServletRequest request) { + String Xip = request.getHeader("X-Real-IP"); + String XFor = request.getHeader("X-Forwarded-For"); + if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){ + //多次反向代理后会有多个ip值,第一个ip才是真实ip + int index = XFor.indexOf(","); + if(index != -1){ + return XFor.substring(0,index); + }else{ + return XFor; + } + } + XFor = Xip; + if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){ + return XFor; + } + if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { + XFor = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { + XFor = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { + XFor = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { + XFor = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { + XFor = request.getRemoteAddr(); + } + return XFor; + } +} diff --git a/report-core/src/main/resources/db/migration/V1.0.14__update_report.sql b/report-core/src/main/resources/db/migration/V1.0.14__update_report.sql new file mode 100644 index 00000000..334ddc8f --- /dev/null +++ b/report-core/src/main/resources/db/migration/V1.0.14__update_report.sql @@ -0,0 +1,68 @@ +use +aj_report; + +-- 增加字段 +ALTER TABLE `aj_report`.`gaea_report` ADD COLUMN `report_author` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '报表作者' AFTER `report_desc`; + +ALTER TABLE `aj_report`.`gaea_report` ADD COLUMN `download_count` bigint(11) NULL DEFAULT NULL COMMENT '报表下载次数' AFTER `report_author`; + +-- root权限更新 +delete from access_role_authority where role_code = 'root'; + +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'authorityManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'authorityManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'authorityManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'authorityManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'roleManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'roleManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'roleManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'roleManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'roleManage', 'grantAuthority'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'resetPassword'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'userManage', 'grantRole'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'datasourceManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'datasourceManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'datasourceManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'datasourceManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'resultsetManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'resultsetManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'resultsetManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'resultsetManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'reportManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'reportManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'reportManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'reportManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'bigScreenManage', 'share'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'bigScreenManage', 'view'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'bigScreenManage', 'design'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'bigScreenManage', 'export'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'bigScreenManage', 'import'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'excelManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'excelManage', 'view'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'excelManage', 'export'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'fileManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'fileManage', 'upload'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'fileManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'fileManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictManage', 'delete'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictManage', 'fresh'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictItemManage', 'query'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictItemManage', 'insert'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictItemManage', 'update'); +INSERT INTO `aj_report`.`access_role_authority`(`id`, `role_code`, `target`, `action`) VALUES (default, 'root', 'dictItemManage', 'delete'); + +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (237, 'report', 'excelManage', '表格报表', 'insert', '新建表格', 237, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (238, 'report', 'excelManage', '表格报表', 'update', '更新表格', 238, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (239, 'report', 'excelManage', '表格报表', 'view', '查看表格', 239, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); +INSERT INTO `aj_report`.`access_authority`(`id`, `parent_target`, `target`, `target_name`, `action`, `action_name`, `sort`, `enable_flag`, `delete_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `version`) VALUES (240, 'report', 'excelManage', '表格报表', 'export', '导出表格', 240, 1, 0, 'admin', '2019-07-23 15:59:40', 'admin', '2019-07-23 15:59:40', 1); + + + + diff --git a/report-ui/src/api/helpCenter/helpCenter.js b/report-ui/src/api/helpCenter/helpCenter.js deleted file mode 100644 index 31c0f14a..00000000 --- a/report-ui/src/api/helpCenter/helpCenter.js +++ /dev/null @@ -1,36 +0,0 @@ -import request from '@/api/axios' - -// 查询字典 -export function queryForCodeSelect(params={}) { - return request({ - url: '/auth-service/dict/queryForCodeSelect', - method: 'post', - data: params - }) -} - -// 查询标题 -export function querytitleByCategory(params) { - return request({ - url: '/auth-service/help/querytitleByCategory', - method: 'post', - data: params - }) -} - -// 关键词查询 -export function searchKeyWord(params = {}) { - return request({ - url: '/auth-service/help/searchKeyWord', - method: 'post', - data: params - }) -} - -export function queryById(data) { - return request({ - url: '/auth-service/help/queryById', - method: 'post', - data - }) -} diff --git a/report-ui/src/api/login.js b/report-ui/src/api/login/index.js similarity index 100% rename from report-ui/src/api/login.js rename to report-ui/src/api/login/index.js diff --git a/report-ui/src/api/reportShare.js b/report-ui/src/api/reportShare.js index 9967c31f..2a20d964 100644 --- a/report-ui/src/api/reportShare.js +++ b/report-ui/src/api/reportShare.js @@ -10,7 +10,7 @@ export function reportShareList(params) { export function reportShareAdd(data) { return request({ - url: 'report/share', + url: 'reportDashboard/share', method: 'post', data }) diff --git a/report-ui/src/assets/iconfont/demo_index.html b/report-ui/src/assets/iconfont/demo_index.html index 96501588..648de746 100644 --- a/report-ui/src/assets/iconfont/demo_index.html +++ b/report-ui/src/assets/iconfont/demo_index.html @@ -54,6 +54,12 @@
    +
  • + +
    词云图
    +
    &#xe7af;
    +
  • +
  • 导出
    @@ -786,9 +792,9 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.woff2?t=1629797734566') format('woff2'),
    -       url('iconfont.woff?t=1629797734566') format('woff'),
    -       url('iconfont.ttf?t=1629797734566') format('truetype');
    +  src: url('iconfont.woff2?t=1643094287456') format('woff2'),
    +       url('iconfont.woff?t=1643094287456') format('woff'),
    +       url('iconfont.ttf?t=1643094287456') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -814,6 +820,15 @@
      +
    • + +
      + 词云图 +
      +
      .iconciyuntu +
      +
    • +
    • @@ -1912,6 +1927,14 @@
        +
      • + +
        词云图
        +
        #iconciyuntu
        +
      • +
      • {{ getItemLabel(item, item.value) }}
        + {{ item[option] }} + + + + + diff --git a/report-ui/src/components/AnjiPlus/anji-cascader.vue b/report-ui/src/components/AnjiPlus/anji-cascader.vue new file mode 100644 index 00000000..db64d37c --- /dev/null +++ b/report-ui/src/components/AnjiPlus/anji-cascader.vue @@ -0,0 +1,313 @@ + + diff --git a/report-ui/src/components/AnjiPlus/anji-checkbox.vue b/report-ui/src/components/AnjiPlus/anji-checkbox.vue new file mode 100644 index 00000000..e78d4c67 --- /dev/null +++ b/report-ui/src/components/AnjiPlus/anji-checkbox.vue @@ -0,0 +1,126 @@ + + + diff --git a/report-ui/src/components/AnjiPlus/anji-contextMenu.vue b/report-ui/src/components/AnjiPlus/anji-contextMenu.vue new file mode 100644 index 00000000..f04babbe --- /dev/null +++ b/report-ui/src/components/AnjiPlus/anji-contextMenu.vue @@ -0,0 +1,50 @@ + + + + diff --git a/report-ui/src/components/AnjiPlus/anji-countryCity.vue b/report-ui/src/components/AnjiPlus/anji-countryCity.vue new file mode 100644 index 00000000..f98a3465 --- /dev/null +++ b/report-ui/src/components/AnjiPlus/anji-countryCity.vue @@ -0,0 +1,97 @@ + + + diff --git a/report-ui/src/components/AnjiPlus/anji-crud/anji-crud.vue b/report-ui/src/components/AnjiPlus/anji-crud/anji-crud.vue index bcc89183..74cdc33c 100644 --- a/report-ui/src/components/AnjiPlus/anji-crud/anji-crud.vue +++ b/report-ui/src/components/AnjiPlus/anji-crud/anji-crud.vue @@ -12,330 +12,357 @@ />
      - - - - - - - - - - - - - - - - - - - - 查询 - 重置 - - {{ queryParams.showMoreSearch == true ? "收起" : "展开" }} - - - - - - +
      + + +
      +
      + + + +
      - - - 新增 - 删除 +
      + + + {{ queryParams.showMoreSearch == true ? "展开" : "收起" }} + + 重置 + 查询 +
      +
      +
      + + +
      + + 新增 + 删除 + +
      +
      - - - - - - - - - - - - - diff --git a/report-ui/src/components/AnjiPlus/anji-crud/edit-form.vue b/report-ui/src/components/AnjiPlus/anji-crud/edit-form.vue index d186a84e..7fb7529e 100644 --- a/report-ui/src/components/AnjiPlus/anji-crud/edit-form.vue +++ b/report-ui/src/components/AnjiPlus/anji-crud/edit-form.vue @@ -1,11 +1,8 @@ -