lxc
2 years ago
3034 changed files with 994163 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<module type="JAVA_MODULE" version="4"> |
|||
<component name="NewModuleRootManager" inherit-compiler-output="true"> |
|||
<exclude-output /> |
|||
<content url="file://$MODULE_DIR$" /> |
|||
<orderEntry type="inheritedJdk" /> |
|||
<orderEntry type="sourceFolder" forTests="false" /> |
|||
</component> |
|||
</module> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="ProjectType"> |
|||
<option name="id" value="jpab" /> |
|||
</component> |
|||
</project> |
@ -0,0 +1,8 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="ProjectModuleManager"> |
|||
<modules> |
|||
<module fileurl="file://$PROJECT_DIR$/.idea/jeecg-boot3.4.iml" filepath="$PROJECT_DIR$/.idea/jeecg-boot3.4.iml" /> |
|||
</modules> |
|||
</component> |
|||
</project> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="VcsDirectoryMappings"> |
|||
<mapping directory="" vcs="Git" /> |
|||
</component> |
|||
</project> |
@ -0,0 +1,37 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project version="4"> |
|||
<component name="ChangeListManager"> |
|||
<list default="true" id="817e4fce-acf1-4e2d-a3cd-b53665c506e3" name="Changes" comment="" /> |
|||
<option name="SHOW_DIALOG" value="false" /> |
|||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> |
|||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> |
|||
<option name="LAST_RESOLUTION" value="IGNORE" /> |
|||
</component> |
|||
<component name="Git.Settings"> |
|||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> |
|||
</component> |
|||
<component name="MarkdownSettingsMigration"> |
|||
<option name="stateVersion" value="1" /> |
|||
</component> |
|||
<component name="ProjectId" id="2HKyytTGnARH6z4Hp0CVCP6tDif" /> |
|||
<component name="ProjectViewState"> |
|||
<option name="hideEmptyMiddlePackages" value="true" /> |
|||
<option name="showLibraryContents" value="true" /> |
|||
</component> |
|||
<component name="PropertiesComponent"> |
|||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> |
|||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> |
|||
<property name="last_opened_file_path" value="$PROJECT_DIR$" /> |
|||
</component> |
|||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" /> |
|||
<component name="TaskManager"> |
|||
<task active="true" id="Default" summary="Default task"> |
|||
<changelist id="817e4fce-acf1-4e2d-a3cd-b53665c506e3" name="Changes" comment="" /> |
|||
<created>1668048327303</created> |
|||
<option name="number" value="Default" /> |
|||
<option name="presentableId" value="Default" /> |
|||
<updated>1668048327303</updated> |
|||
</task> |
|||
<servers /> |
|||
</component> |
|||
</project> |
Binary file not shown.
@ -0,0 +1,5 @@ |
|||
*.js linguist-language=Java |
|||
*.css linguist-language=Java |
|||
*.html linguist-language=Java |
|||
*.vue linguist-language=Java |
|||
*.sql linguist-language=Java |
@ -0,0 +1,21 @@ |
|||
##### 版本号: |
|||
|
|||
|
|||
##### 前端版本:vue3版?还是 vue2版? |
|||
|
|||
|
|||
##### 问题描述: |
|||
|
|||
|
|||
##### 截图&代码: |
|||
|
|||
|
|||
|
|||
|
|||
#### 友情提示(为了提高issue处理效率): |
|||
- 未按格式要求发帖,会被直接删掉; |
|||
- 描述过于简单或模糊,导致无法处理的,会被直接删掉; |
|||
- 请自己初判问题描述是否清楚,是否方便我们调查处理; |
|||
- 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能; |
|||
|
|||
|
@ -0,0 +1,21 @@ |
|||
##### 版本号: |
|||
|
|||
|
|||
##### 前端版本:vue3版?还是 vue2版? |
|||
|
|||
|
|||
##### 问题描述: |
|||
|
|||
|
|||
##### 截图&代码: |
|||
|
|||
|
|||
|
|||
|
|||
#### 友情提示(为了提高issue处理效率): |
|||
- 未按格式要求发帖,会被直接删掉; |
|||
- 描述过于简单或模糊,导致无法处理的,会被直接删掉; |
|||
- 请自己初判问题描述是否清楚,是否方便我们调查处理; |
|||
- 针对问题请说明是Online在线功能(需说明用的主题模板),还是生成的代码功能; |
|||
|
|||
|
@ -0,0 +1,11 @@ |
|||
## ide |
|||
**/.idea |
|||
*.iml |
|||
rebel.xml |
|||
|
|||
## backend |
|||
**/target |
|||
**/logs |
|||
|
|||
## front |
|||
**/*.lock |
@ -0,0 +1,213 @@ |
|||
Apache License |
|||
Version 2.0, January 2004 |
|||
http://www.apache.org/licenses/ |
|||
|
|||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
|||
|
|||
1. Definitions. |
|||
|
|||
"License" shall mean the terms and conditions for use, reproduction, |
|||
and distribution as defined by Sections 1 through 9 of this document. |
|||
|
|||
"Licensor" shall mean the copyright owner or entity authorized by |
|||
the copyright owner that is granting the License. |
|||
|
|||
"Legal Entity" shall mean the union of the acting entity and all |
|||
other entities that control, are controlled by, or are under common |
|||
control with that entity. For the purposes of this definition, |
|||
"control" means (i) the power, direct or indirect, to cause the |
|||
direction or management of such entity, whether by contract or |
|||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
|||
outstanding shares, or (iii) beneficial ownership of such entity. |
|||
|
|||
"You" (or "Your") shall mean an individual or Legal Entity |
|||
exercising permissions granted by this License. |
|||
|
|||
"Source" form shall mean the preferred form for making modifications, |
|||
including but not limited to software source code, documentation |
|||
source, and configuration files. |
|||
|
|||
"Object" form shall mean any form resulting from mechanical |
|||
transformation or translation of a Source form, including but |
|||
not limited to compiled object code, generated documentation, |
|||
and conversions to other media types. |
|||
|
|||
"Work" shall mean the work of authorship, whether in Source or |
|||
Object form, made available under the License, as indicated by a |
|||
copyright notice that is included in or attached to the work |
|||
(an example is provided in the Appendix below). |
|||
|
|||
"Derivative Works" shall mean any work, whether in Source or Object |
|||
form, that is based on (or derived from) the Work and for which the |
|||
editorial revisions, annotations, elaborations, or other modifications |
|||
represent, as a whole, an original work of authorship. For the purposes |
|||
of this License, Derivative Works shall not include works that remain |
|||
separable from, or merely link (or bind by name) to the interfaces of, |
|||
the Work and Derivative Works thereof. |
|||
|
|||
"Contribution" shall mean any work of authorship, including |
|||
the original version of the Work and any modifications or additions |
|||
to that Work or Derivative Works thereof, that is intentionally |
|||
submitted to Licensor for inclusion in the Work by the copyright owner |
|||
or by an individual or Legal Entity authorized to submit on behalf of |
|||
the copyright owner. For the purposes of this definition, "submitted" |
|||
means any form of electronic, verbal, or written communication sent |
|||
to the Licensor or its representatives, including but not limited to |
|||
communication on electronic mailing lists, source code control systems, |
|||
and issue tracking systems that are managed by, or on behalf of, the |
|||
Licensor for the purpose of discussing and improving the Work, but |
|||
excluding communication that is conspicuously marked or otherwise |
|||
designated in writing by the copyright owner as "Not a Contribution." |
|||
|
|||
"Contributor" shall mean Licensor and any individual or Legal Entity |
|||
on behalf of whom a Contribution has been received by Licensor and |
|||
subsequently incorporated within the Work. |
|||
|
|||
2. Grant of Copyright License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
copyright license to reproduce, prepare Derivative Works of, |
|||
publicly display, publicly perform, sublicense, and distribute the |
|||
Work and such Derivative Works in Source or Object form. |
|||
|
|||
3. Grant of Patent License. Subject to the terms and conditions of |
|||
this License, each Contributor hereby grants to You a perpetual, |
|||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
|||
(except as stated in this section) patent license to make, have made, |
|||
use, offer to sell, sell, import, and otherwise transfer the Work, |
|||
where such license applies only to those patent claims licensable |
|||
by such Contributor that are necessarily infringed by their |
|||
Contribution(s) alone or by combination of their Contribution(s) |
|||
with the Work to which such Contribution(s) was submitted. If You |
|||
institute patent litigation against any entity (including a |
|||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
|||
or a Contribution incorporated within the Work constitutes direct |
|||
or contributory patent infringement, then any patent licenses |
|||
granted to You under this License for that Work shall terminate |
|||
as of the date such litigation is filed. |
|||
|
|||
4. Redistribution. You may reproduce and distribute copies of the |
|||
Work or Derivative Works thereof in any medium, with or without |
|||
modifications, and in Source or Object form, provided that You |
|||
meet the following conditions: |
|||
|
|||
(a) You must give any other recipients of the Work or |
|||
Derivative Works a copy of this License; and |
|||
|
|||
(b) You must cause any modified files to carry prominent notices |
|||
stating that You changed the files; and |
|||
|
|||
(c) You must retain, in the Source form of any Derivative Works |
|||
that You distribute, all copyright, patent, trademark, and |
|||
attribution notices from the Source form of the Work, |
|||
excluding those notices that do not pertain to any part of |
|||
the Derivative Works; and |
|||
|
|||
(d) If the Work includes a "NOTICE" text file as part of its |
|||
distribution, then any Derivative Works that You distribute must |
|||
include a readable copy of the attribution notices contained |
|||
within such NOTICE file, excluding those notices that do not |
|||
pertain to any part of the Derivative Works, in at least one |
|||
of the following places: within a NOTICE text file distributed |
|||
as part of the Derivative Works; within the Source form or |
|||
documentation, if provided along with the Derivative Works; or, |
|||
within a display generated by the Derivative Works, if and |
|||
wherever such third-party notices normally appear. The contents |
|||
of the NOTICE file are for informational purposes only and |
|||
do not modify the License. You may add Your own attribution |
|||
notices within Derivative Works that You distribute, alongside |
|||
or as an addendum to the NOTICE text from the Work, provided |
|||
that such additional attribution notices cannot be construed |
|||
as modifying the License. |
|||
|
|||
You may add Your own copyright statement to Your modifications and |
|||
may provide additional or different license terms and conditions |
|||
for use, reproduction, or distribution of Your modifications, or |
|||
for any such Derivative Works as a whole, provided Your use, |
|||
reproduction, and distribution of the Work otherwise complies with |
|||
the conditions stated in this License. |
|||
|
|||
5. Submission of Contributions. Unless You explicitly state otherwise, |
|||
any Contribution intentionally submitted for inclusion in the Work |
|||
by You to the Licensor shall be under the terms and conditions of |
|||
this License, without any additional terms or conditions. |
|||
Notwithstanding the above, nothing herein shall supersede or modify |
|||
the terms of any separate license agreement you may have executed |
|||
with Licensor regarding such Contributions. |
|||
|
|||
6. Trademarks. This License does not grant permission to use the trade |
|||
names, trademarks, service marks, or product names of the Licensor, |
|||
except as required for reasonable and customary use in describing the |
|||
origin of the Work and reproducing the content of the NOTICE file. |
|||
|
|||
7. Disclaimer of Warranty. Unless required by applicable law or |
|||
agreed to in writing, Licensor provides the Work (and each |
|||
Contributor provides its Contributions) on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|||
implied, including, without limitation, any warranties or conditions |
|||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
|||
PARTICULAR PURPOSE. You are solely responsible for determining the |
|||
appropriateness of using or redistributing the Work and assume any |
|||
risks associated with Your exercise of permissions under this License. |
|||
|
|||
8. Limitation of Liability. In no event and under no legal theory, |
|||
whether in tort (including negligence), contract, or otherwise, |
|||
unless required by applicable law (such as deliberate and grossly |
|||
negligent acts) or agreed to in writing, shall any Contributor be |
|||
liable to You for damages, including any direct, indirect, special, |
|||
incidental, or consequential damages of any character arising as a |
|||
result of this License or out of the use or inability to use the |
|||
Work (including but not limited to damages for loss of goodwill, |
|||
work stoppage, computer failure or malfunction, or any and all |
|||
other commercial damages or losses), even if such Contributor |
|||
has been advised of the possibility of such damages. |
|||
|
|||
9. Accepting Warranty or Additional Liability. While redistributing |
|||
the Work or Derivative Works thereof, You may choose to offer, |
|||
and charge a fee for, acceptance of support, warranty, indemnity, |
|||
or other liability obligations and/or rights consistent with this |
|||
License. However, in accepting such obligations, You may act only |
|||
on Your own behalf and on Your sole responsibility, not on behalf |
|||
of any other Contributor, and only if You agree to indemnify, |
|||
defend, and hold each Contributor harmless for any liability |
|||
incurred by, or claims asserted against, such Contributor by reason |
|||
of your accepting any such warranty or additional liability. |
|||
|
|||
END OF TERMS AND CONDITIONS |
|||
|
|||
APPENDIX: How to apply the Apache License to your work. |
|||
|
|||
To apply the Apache License to your work, attach the following |
|||
boilerplate notice, with the fields enclosed by brackets "[]" |
|||
replaced with your own identifying information. (Don't include |
|||
the brackets!) The text should be enclosed in the appropriate |
|||
comment syntax for the file format. We also recommend that a |
|||
file or class name and description of purpose be included on the |
|||
same "printed page" as the copyright notice for easier |
|||
identification within third-party archives. |
|||
|
|||
Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software. |
|||
|
|||
开源协议补充 |
|||
JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com |
|||
本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。 |
|||
|
|||
1.允许基于本平台软件开展业务系统开发。 |
|||
2.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。 |
|||
违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。 |
|||
解释权归:http://www.jeecg.com |
|||
|
@ -0,0 +1,467 @@ |
|||
|
|||
|
|||
![JEECG](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/logov3.png "JeecgBoot低代码开发平台") |
|||
|
|||
|
|||
|
|||
JEECG BOOT 低代码开发平台 |
|||
=============== |
|||
|
|||
当前最新版本: 3.4.1(发布日期:2022-08-12) |
|||
|
|||
|
|||
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE) |
|||
[![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://www.jeecg.com) |
|||
[![](https://img.shields.io/badge/Blog-官方博客-blue.svg)](https://my.oschina.net/jeecg) |
|||
[![](https://img.shields.io/badge/version-3.4.1-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot) |
|||
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot) |
|||
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot) |
|||
|
|||
|
|||
|
|||
项目介绍 |
|||
----------------------------------- |
|||
|
|||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3> |
|||
|
|||
JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端分离架构 SpringBoot2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot 引领新的低代码开发模式(OnlineCoding-> 代码生成器-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性! |
|||
|
|||
JeecgBoot 提供了一系列`低代码模块`,实现在线开发`真正的零代码`:Online表单开发、Online报表、报表配置能力、在线图表设计、大屏设计、移动配置能力、表单设计器、在线设计流程、流程自动化配置、插件能力(可插拔)等等! |
|||
|
|||
|
|||
`JEECG宗旨是:` 简单功能由OnlineCoding配置实现,做到`零代码开发`;复杂功能由代码生成器生成进行手工Merge 实现`低代码开发`,既保证了`智能`又兼顾`灵活`;实现了低代码开发的同时又支持灵活编码,解决了当前低代码产品普遍不灵活的弊端! |
|||
|
|||
`JEECG业务流程:` 采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。 |
|||
|
|||
|
|||
项目源码 |
|||
----------------------------------- |
|||
| 仓库 |前端 Vue3版 | 前端 Vue2版 | 后端源码 | |
|||
|-|-|-|-| |
|||
| Github | [jeecgboot-vue3](https://github.com/jeecgboot/jeecgboot-vue3) | [ant-design-vue-jeecg](https://github.com/jeecgboot/ant-design-vue-jeecg) | [jeecg-boot](https://github.com/jeecgboot/jeecg-boot) | |
|||
| 码云 | [jeecgboot-vue3](https://gitee.com/jeecg/jeecgboot-vue3) | [ant-design-vue-jeecg](https://gitee.com/jeecg/ant-design-vue-jeecg) | [jeecg-boot](https://gitee.com/jeecg/jeecg-boot) | |
|||
|
|||
|
|||
##### 项目说明 |
|||
|
|||
| 项目名 | 说明 | |
|||
|--------------------|------------------------| |
|||
| `jeecg-boot` | SpringBoot后台源码(支持微服务) | |
|||
| `ant-design-vue-jeecg` |Vue2版前端源码 | |
|||
| `jeecgboot-vue3` | Vue3+Ts版前端源码 | |
|||
| `jeecg-boot-starter` | stater依赖项目单独维护 [下载地址](https://gitee.com/jeecg/jeecg-boot-starter) | |
|||
|
|||
|
|||
|
|||
##### Star走势图 |
|||
![](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/star20220907.png) |
|||
|
|||
适用项目 |
|||
----------------------------------- |
|||
Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,尤其适合SAAS项目、企业信息管理系统(MIS)、内部办公系统(OA)、企业资源计划系统(ERP)、客户关系管理系统(CRM)等,其半智能手工Merge的开发方式,可以显著提高开发效率70%以上,极大降低开发成本。 |
|||
|
|||
|
|||
|
|||
技术文档 |
|||
----------------------------------- |
|||
|
|||
- 技术官网: [http://www.jeecg.com](http://www.jeecg.com) |
|||
|
|||
- 在线演示 : [Vue2版本](http://boot.jeecg.com) | [Vue3版本](http://boot3.jeecg.com) |
|||
|
|||
- 开发文档: [主项目文档](http://doc.jeecg.com) | [Vue3文档](http://vue3.jeecg.com) |
|||
|
|||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart) | [视频教程](https://space.bilibili.com/454617261/channel/series) | [常见问题 ](http://www.jeecg.com/doc/qa) | [技术支持](http://jeecg.com/doc/help) | [1分钟体验低代码](https://my.oschina.net/jeecg/blog/3083313) |
|||
|
|||
- 微服务开发: [单体升级为微服务](http://doc.jeecg.com/3043471) |
|||
|
|||
- QQ交流群 : ⑥730954414、VUE3群683903138、⑤860162132(满)、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满) |
|||
> ` 提醒:【QQ群是自助服务群,建议给帮助您解决问题的同学发送指定红包,表示感谢!】 ` |
|||
|
|||
|
|||
|
|||
|
|||
后台目录结构 |
|||
----------------------------------- |
|||
``` |
|||
项目结构 |
|||
├─jeecg-boot-parent(父POM: 项目依赖、modules组织) |
|||
│ ├─jeecg-boot-base-core(共通模块: 工具类、config、权限、查询过滤器、注解等) |
|||
│ ├─jeecg-module-demo 示例代码 |
|||
│ ├─jeecg-module-system System系统管理目录 |
|||
│ │ ├─jeecg-system-biz System系统管理权限等功能 |
|||
│ │ ├─jeecg-system-start System单体启动项目(8080) |
|||
│ │ ├─jeecg-system-api System系统管理模块对外api |
|||
│ │ │ ├─jeecg-system-cloud-api System模块对外提供的微服务接口 |
|||
│ │ │ ├─jeecg-system-local-api System模块对外提供的单体接口 |
|||
│ ├─jeecg-server-cloud --微服务模块 |
|||
├─jeecg-cloud-gateway --微服务网关模块(9999) |
|||
├─jeecg-cloud-nacos --Nacos服务模块(8848) |
|||
├─jeecg-system-cloud-start --System微服务启动项目(7001) |
|||
├─jeecg-demo-cloud-start --Demo微服务启动项目(7002) |
|||
├─jeecg-visual |
|||
├─jeecg-cloud-monitor --微服务监控模块 (9111) |
|||
├─jeecg-cloud-xxljob --微服务xxljob定时任务服务端 (9080) |
|||
├─jeecg-cloud-sentinel --sentinel服务端 (9000) |
|||
├─jeecg-cloud-test -- 微服务测试示例(各种例子) |
|||
├─jeecg-cloud-test-more -- 微服务测试示例(feign、熔断降级、xxljob、分布式锁) |
|||
├─jeecg-cloud-test-rabbitmq -- 微服务测试示例(rabbitmq) |
|||
├─jeecg-cloud-test-seata -- 微服务测试示例(seata分布式事务) |
|||
├─jeecg-cloud-test-shardingsphere -- 微服务测试示例(分库分表) |
|||
``` |
|||
|
|||
Docker启动项目 |
|||
----------------------------------- |
|||
- [Docker启动单体后台](http://doc.jeecg.com/2043889) |
|||
- [Docker启动微服务后台](http://doc.jeecg.com/3043472) |
|||
- [Docker启动Vue3前端](http://vue3.jeecg.com/3028878) |
|||
- [Docker启动Vue2前端](http://doc.jeecg.com/3043612) |
|||
|
|||
|
|||
|
|||
为什么选择JeecgBoot? |
|||
----------------------------------- |
|||
* 1.采用最新主流前后分离框架(Springboot+Mybatis+antd),容易上手; 代码生成器依赖性低,灵活的扩展能力,可快速实现二次开发; |
|||
* 2.支持微服务SpringCloud Alibaba(Nacos、Gateway、Sentinel、Skywalking),提供切换机制支持单体和微服务自由切换 |
|||
* 3.开发效率高,采用代码生成器,单表、树列表、一对多、一对一等数据模型,增删改查功能一键生成,菜单配置直接使用; |
|||
* 4.代码生成器提供强大模板机制,支持自定义模板,目前提供四套风格模板(单表两套、树模型一套、一对多三套) |
|||
* 5.代码生成器非常智能,在线业务建模、在线配置、所见即所得支持23种类控件,一键生成前后端代码,大幅度提升开发效率,不再为重复工作发愁。 |
|||
* 6.低代码能力:Online在线表单(无需编码,通过在线配置表单,实现表单的增删改查,支持单表、树、一对多、一对一等模型,实现人人皆可编码) |
|||
* 7.低代码能力:Online在线报表(无需编码,通过在线配置方式,实现数据报表,可以快速抽取数据,减轻开发压力,实现人人皆可编码) |
|||
* 8.低代码能力:Online在线图表(无需编码,通过在线配置方式,实现曲线图,柱状图,数据报表等,支持自定义排版布局,实现人人皆可编码) |
|||
* 9.封装完善的用户、角色、菜单、组织机构、数据字典、在线定时任务等基础功能,支持访问授权、按钮权限、数据权限等功能 |
|||
* 10.常用共通封装,各种工具类(定时任务,短信接口,邮件发送,Excel导入导出等),基本满足80%项目需求 |
|||
* 11.简易Excel导入导出,支持单表导出和一对多表模式导出,生成的代码自带导入导出功能 |
|||
* 12.集成简易报表工具,图像报表和数据导出非常方便,可极其方便的生成图形报表、pdf、excel、word等报表; |
|||
* 13.采用前后分离技术,页面UI风格精美,针对常用组件做了封装:时间、行表格控件、截取显示控件、报表组件,编辑器等等 |
|||
* 14.查询过滤器:查询功能自动生成,后台动态拼SQL追加查询条件;支持多种匹配方式(全匹配/模糊查询/包含查询/不匹配查询); |
|||
* 15.数据权限(精细化数据权限控制,控制到行级,列表级,表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段 |
|||
* 16.页面校验自动生成(必须输入、数字校验、金额校验、时间空间等); |
|||
* 17.支持SAAS服务模式,提供SaaS多租户架构方案。 |
|||
* 18.分布式文件服务,集成minio、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。 |
|||
* 19.主流数据库兼容,一套代码完全兼容Mysql、Postgresql、Oracle、Sqlserver、MariaDB、达梦等主流数据库。 |
|||
* 20.集成工作流activiti,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码; |
|||
* 21.低代码能力:在线流程设计,采用开源Activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转 |
|||
* 22.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据; |
|||
* 23.提供单点登录CAS集成方案,项目中已经提供完善的对接代码 |
|||
* 24.低代码能力:表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件 |
|||
* 25.专业接口对接机制,统一采用restful接口方式,集成swagger-ui在线接口文档,Jwt token安全验证,方便客户端对接 |
|||
* 26.接口安全机制,可细化控制接口授权,非常简便实现不同客户端只看自己数据等控制 |
|||
* 27.高级组合查询功能,在线配置支持主子表关联查询,可保存查询历史 |
|||
* 28.提供各种系统监控,实时跟踪系统运行情况(监控 Redis、Tomcat、jvm、服务器信息、请求追踪、SQL监控) |
|||
* 29.消息中心(支持短信、邮件、微信推送等等) |
|||
* 30.集成Websocket消息通知机制 |
|||
* 31.移动自适应效果优秀,提供APP发布方案: |
|||
* 32.支持多语言,提供国际化方案; |
|||
* 33.数据变更记录日志,可记录数据每次变更内容,通过版本对比功能查看历史变化 |
|||
* 34.平台UI强大,实现了移动自适应 |
|||
* 35.平台首页风格,提供多种组合模式,支持自定义风格 |
|||
* 36.提供简单易用的打印插件,支持谷歌、火狐、IE11+ 等各种浏览器 |
|||
* 37.示例代码丰富,提供很多学习案例参考 |
|||
* 38.采用maven分模块开发方式 |
|||
* 39.支持菜单动态路由 |
|||
* 40.权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制) |
|||
* 41.提供新行编辑表格JVXETable,轻松满足各种复杂ERP布局,拥有更高的性能、更灵活的扩展、更强大的功能 |
|||
|
|||
|
|||
|
|||
|
|||
技术架构: |
|||
----------------------------------- |
|||
#### 开发环境 |
|||
|
|||
- 语言:Java 8+ (小于17) |
|||
|
|||
- IDE(JAVA): IDEA (必须安装lombok插件 ) |
|||
|
|||
- IDE(前端): Vscode、WebStorm、IDEA |
|||
|
|||
- 依赖管理:Maven |
|||
|
|||
- 缓存:Redis |
|||
|
|||
- 数据库脚本:MySQL5.7+ & Oracle 11g & Sqlserver2017(其他数据库,[需要自己转](https://my.oschina.net/jeecg/blog/4905722)) |
|||
|
|||
|
|||
#### 后端 |
|||
|
|||
- 基础框架:Spring Boot 2.6.6 |
|||
|
|||
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0 |
|||
|
|||
- 持久层框架:MybatisPlus 3.5.1 |
|||
|
|||
- 报表工具: JimuReport 1.5.2 |
|||
|
|||
- 安全框架:Apache Shiro 1.8.0,Jwt 3.11.0 |
|||
|
|||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking |
|||
|
|||
- 数据库连接池:阿里巴巴Druid 1.1.22 |
|||
|
|||
- 日志打印:logback |
|||
|
|||
- 其他:autopoi, fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。 |
|||
|
|||
|
|||
#### 前端 |
|||
|
|||
- Vue2版本:`Vue2.6+@vue/cli+AntDesignVue+Viser-vue+Vuex等` [详细查看](https://github.com/jeecgboot/ant-design-vue-jeecg) |
|||
- Vue3版本:`Vue3.0+TypeScript+Vite+AntDesignVue+pinia+echarts等新方案` [详细查看](https://github.com/jeecgboot/jeecgboot-vue3) |
|||
|
|||
#### 支持库 |
|||
|
|||
| 数据库 | 支持 | |
|||
| --- | --- | |
|||
| MySQL | √ | |
|||
| Oracle11g | √ | |
|||
| Sqlserver2017 | √ | |
|||
| PostgreSQL | √ | |
|||
| MariaDB | √ | |
|||
| 达梦、人大金仓 | √ | |
|||
|
|||
|
|||
|
|||
## 微服务解决方案 |
|||
|
|||
|
|||
1、服务注册和发现 Nacos √ |
|||
|
|||
2、统一配置中心 Nacos √ |
|||
|
|||
3、路由网关 gateway(三种加载方式) √ |
|||
|
|||
4、分布式 http feign √ |
|||
|
|||
5、熔断降级限流 Sentinel √ |
|||
|
|||
6、分布式文件 Minio、阿里OSS √ |
|||
|
|||
7、统一权限控制 JWT + Shiro √ |
|||
|
|||
8、服务监控 SpringBootAdmin√ |
|||
|
|||
9、链路跟踪 Skywalking [参考文档](http://doc.jeecg.com/2350293) |
|||
|
|||
10、消息中间件 RabbitMQ √ |
|||
|
|||
11、分布式任务 xxl-job √ |
|||
|
|||
12、分布式事务 Seata |
|||
|
|||
13、分布式日志 elk + kafka |
|||
|
|||
14、支持 docker-compose、k8s、jenkins |
|||
|
|||
15、CAS 单点登录 √ |
|||
|
|||
16、路由限流 √ |
|||
|
|||
|
|||
#### 微服务架构图 |
|||
![微服务架构图](https://jeecgos.oss-cn-beijing.aliyuncs.com/files/jeecgboot_springcloud2022.png "在这里输入图片标题") |
|||
|
|||
### Jeecg Boot 产品功能蓝图 |
|||
![功能蓝图](https://jeecgos.oss-cn-beijing.aliyuncs.com/upload/test/Jeecg-Boot-lantu202005_1590912449914.jpg "在这里输入图片标题") |
|||
|
|||
|
|||
|
|||
|
|||
### 功能模块 |
|||
``` |
|||
├─系统管理 |
|||
│ ├─用户管理 |
|||
│ ├─角色管理 |
|||
│ ├─菜单管理 |
|||
│ ├─权限设置(支持按钮权限、数据权限) |
|||
│ ├─表单权限(控制字段禁用、隐藏) |
|||
│ ├─部门管理 |
|||
│ ├─我的部门(二级管理员) |
|||
│ └─字典管理 |
|||
│ └─分类字典 |
|||
│ └─系统公告 |
|||
│ └─职务管理 |
|||
│ └─通讯录 |
|||
│ └─多租户管理 |
|||
├─消息中心 |
|||
│ ├─消息管理 |
|||
│ ├─模板管理 |
|||
├─代码生成器(低代码) |
|||
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音) |
|||
│ ├─代码生成器模板(提供4套模板,分别支持单表和一对多模型,不同风格选择) |
|||
│ ├─代码生成器模板(生成代码,自带excel导入导出) |
|||
│ ├─查询过滤器(查询逻辑无需编码,系统根据页面配置自动生成) |
|||
│ ├─高级查询器(弹窗自动组合查询条件) |
|||
│ ├─Excel导入导出工具集成(支持单表,一对多 导入导出) |
|||
│ ├─平台移动自适应支持 |
|||
├─系统监控 |
|||
│ ├─Gateway路由网关 |
|||
│ ├─性能扫描监控 |
|||
│ │ ├─监控 Redis |
|||
│ │ ├─Tomcat |
|||
│ │ ├─jvm |
|||
│ │ ├─服务器信息 |
|||
│ │ ├─请求追踪 |
|||
│ │ ├─磁盘监控 |
|||
│ ├─定时任务 |
|||
│ ├─系统日志 |
|||
│ ├─消息中心(支持短信、邮件、微信推送等等) |
|||
│ ├─数据日志(记录数据快照,可对比快照,查看数据变更情况) |
|||
│ ├─系统通知 |
|||
│ ├─SQL监控 |
|||
│ ├─swagger-ui(在线接口文档) |
|||
│─报表示例 |
|||
│ ├─曲线图 |
|||
│ └─饼状图 |
|||
│ └─柱状图 |
|||
│ └─折线图 |
|||
│ └─面积图 |
|||
│ └─雷达图 |
|||
│ └─仪表图 |
|||
│ └─进度条 |
|||
│ └─排名列表 |
|||
│ └─等等 |
|||
│─大屏模板 |
|||
│ ├─作战指挥中心大屏 |
|||
│ └─物流服务中心大屏 |
|||
│─常用示例 |
|||
│ ├─自定义组件 |
|||
│ ├─对象存储(对接阿里云) |
|||
│ ├─JVXETable示例(各种复杂ERP布局示例) |
|||
│ ├─单表模型例子 |
|||
│ └─一对多模型例子 |
|||
│ └─打印例子 |
|||
│ └─一对多TAB例子 |
|||
│ └─内嵌table例子 |
|||
│ └─常用选择组件 |
|||
│ └─异步树table |
|||
│ └─接口模拟测试 |
|||
│ └─表格合计示例 |
|||
│ └─异步树列表示例 |
|||
│ └─一对多JEditable |
|||
│ └─JEditable组件示例 |
|||
│ └─图片拖拽排序 |
|||
│ └─图片翻页 |
|||
│ └─图片预览 |
|||
│ └─PDF预览 |
|||
│ └─分屏功能 |
|||
│─封装通用组件 |
|||
│ ├─行编辑表格JEditableTable |
|||
│ └─省略显示组件 |
|||
│ └─时间控件 |
|||
│ └─高级查询 |
|||
│ └─用户选择组件 |
|||
│ └─报表组件封装 |
|||
│ └─字典组件 |
|||
│ └─下拉多选组件 |
|||
│ └─选人组件 |
|||
│ └─选部门组件 |
|||
│ └─通过部门选人组件 |
|||
│ └─封装曲线、柱状图、饼状图、折线图等等报表的组件(经过封装,使用简单) |
|||
│ └─在线code编辑器 |
|||
│ └─上传文件组件 |
|||
│ └─验证码组件 |
|||
│ └─树列表组件 |
|||
│ └─表单禁用组件 |
|||
│ └─等等 |
|||
│─更多页面模板 |
|||
│ ├─各种高级表单 |
|||
│ ├─各种列表效果 |
|||
│ └─结果页面 |
|||
│ └─异常页面 |
|||
│ └─个人页面 |
|||
├─高级功能 |
|||
│ ├─系统编码规则 |
|||
│ ├─提供单点登录CAS集成方案 |
|||
│ ├─提供APP发布方案 |
|||
│ ├─集成Websocket消息通知机制 |
|||
├─Online在线开发(低代码) |
|||
│ ├─Online在线表单 - 功能已开放 |
|||
│ ├─Online代码生成器 - 功能已开放 |
|||
│ ├─Online在线报表 - 功能已开放 |
|||
│ ├─Online在线图表(未开源) |
|||
│ ├─Online图表模板配置(未开源) |
|||
│ ├─Online布局设计(未开源) |
|||
│ ├─多数据源管理 - 功能已开放 |
|||
├─积木报表设计器(低代码) |
|||
│ ├─打印设计器 |
|||
│ ├─数据报表设计 |
|||
│ ├─图形报表设计(支持echart) |
|||
│ ├─大屏设计器(未开源) |
|||
│─流程模块功能 (未开源) |
|||
│ ├─流程设计器 |
|||
│ ├─表单设计器 |
|||
├─大屏设计器 |
|||
├─门户设计/仪表盘设计器 |
|||
│ └─我的任务 |
|||
│ └─历史流程 |
|||
│ └─历史流程 |
|||
│ └─流程实例管理 |
|||
│ └─流程监听管理 |
|||
│ └─流程表达式 |
|||
│ └─我发起的流程 |
|||
│ └─我的抄送 |
|||
│ └─流程委派、抄送、跳转 |
|||
│ └─。。。 |
|||
│─OA办公组件 (未开源) |
|||
│ ├─更多功能 |
|||
│ └─。。。 |
|||
└─其他模块 |
|||
└─更多功能开发中。。 |
|||
|
|||
``` |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
系统效果 |
|||
---- |
|||
##### 大屏模板 |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201912/25133248_Ag1C.jpg "在这里输入图片标题") |
|||
|
|||
![输入图片说明](https://static.oschina.net/uploads/img/201912/25133301_k9Kc.jpg "在这里输入图片标题") |
|||
|
|||
##### PC端 |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14155402_AmlV.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160657_cHwb.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160813_KmXS.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160935_Nibs.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14161004_bxQ4.png "在这里输入图片标题") |
|||
|
|||
|
|||
##### 在线接口文档 |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201908/27095258_M2Xq.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160957_hN3X.png "在这里输入图片标题") |
|||
|
|||
|
|||
##### 报表 |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160828_pkFr.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160834_Lo23.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160842_QK7B.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160849_GBm5.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160858_6RAM.png "在这里输入图片标题") |
|||
|
|||
##### 流程 |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160623_8fwk.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160917_9Ftz.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160633_u59G.png "在这里输入图片标题") |
|||
![输入图片说明](https://static.oschina.net/uploads/img/201907/05165142_yyQ7.png "在这里输入图片标题") |
|||
|
|||
|
|||
##### 手机端 |
|||
![](https://oscimg.oschina.net/oscnet/da543c5d0d57baab0cecaa4670c8b68c521.jpg) |
|||
![](https://oscimg.oschina.net/oscnet/fda4bd82cab9d682de1c1fbf2060bf14fa6.jpg) |
|||
|
|||
##### PAD端 |
|||
![](https://oscimg.oschina.net/oscnet/e90fef970a8c33790ab03ffd6c4c7cec225.jpg) |
|||
![](https://oscimg.oschina.net/oscnet/d78218803a9e856a0aa82b45efc49849a0c.jpg) |
|||
![](https://oscimg.oschina.net/oscnet/0404054d9a12647ef6f82cf9cfb80a5ac02.jpg) |
|||
![](https://oscimg.oschina.net/oscnet/59c23b230f52384e588ee16309b44fa20de.jpg) |
|||
|
|||
|
|||
## 捐赠 |
|||
|
|||
如果觉得还不错,请作者喝杯咖啡吧 ☺ |
|||
|
|||
![](https://static.oschina.net/uploads/img/201903/08155608_0EFX.png) |
@ -0,0 +1,13 @@ |
|||
FROM mysql:8.0.19 |
|||
|
|||
MAINTAINER jeecgos@163.com |
|||
|
|||
ENV TZ=Asia/Shanghai |
|||
|
|||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone |
|||
|
|||
COPY ./tables_nacos.sql /docker-entrypoint-initdb.d |
|||
|
|||
COPY ./jeecgboot-mysql-5.7.sql /docker-entrypoint-initdb.d |
|||
|
|||
COPY ./tables_xxl_job.sql /docker-entrypoint-initdb.d |
File diff suppressed because one or more lines are too long
@ -0,0 +1,311 @@ |
|||
CREATE database if NOT EXISTS `nacos` default character set utf8mb4 collate utf8mb4_general_ci; |
|||
use `nacos`; |
|||
/* |
|||
Navicat Premium Data Transfer |
|||
|
|||
Source Server : mysql5.7 |
|||
Source Server Type : MySQL |
|||
Source Server Version : 50738 |
|||
Source Host : 127.0.0.1:3306 |
|||
Source Schema : nacos-os |
|||
|
|||
Target Server Type : MySQL |
|||
Target Server Version : 50738 |
|||
File Encoding : 65001 |
|||
|
|||
Date: 06/08/2022 15:12:35 |
|||
*/ |
|||
|
|||
SET NAMES utf8mb4; |
|||
SET FOREIGN_KEY_CHECKS = 0; |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for config_info |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `config_info`; |
|||
CREATE TABLE `config_info` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id', |
|||
`group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content', |
|||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5', |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', |
|||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user', |
|||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip', |
|||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段', |
|||
`c_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`c_use` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`effect` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`c_schema` text CHARACTER SET utf8 COLLATE utf8_bin NULL, |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_configinfo_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of config_info |
|||
-- ---------------------------- |
|||
INSERT INTO `config_info` VALUES (1, 'jeecg-dev.yaml', 'DEFAULT_GROUP', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'edb0e79d570edf341755caf3853f11e4', '2021-03-03 13:01:11', '2022-08-06 07:10:17', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''); |
|||
INSERT INTO `config_info` VALUES (2, 'jeecg.yaml', 'DEFAULT_GROUP', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2021-03-03 13:01:42', '2022-08-05 13:12:21', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''); |
|||
INSERT INTO `config_info` VALUES (3, 'jeecg-gateway-router.json', 'DEFAULT_GROUP', '[{\n \"id\": \"jeecg-system\",\n \"order\": 0,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/sys/**\",\n \"_genkey_1\": \"/jmreport/**\",\n \"_genkey_3\": \"/online/**\",\n \"_genkey_4\": \"/generic/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb://jeecg-system\"\n}, {\n \"id\": \"jeecg-demo\",\n \"order\": 1,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/mock/**\",\n \"_genkey_1\": \"/test/**\",\n \"_genkey_2\": \"/bigscreen/template1/**\",\n \"_genkey_3\": \"/bigscreen/template2/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb://jeecg-demo\"\n}, {\n \"id\": \"jeecg-system-websocket\",\n \"order\": 2,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/websocket/**\",\n \"_genkey_1\": \"/newsWebsocket/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb:ws://jeecg-system\"\n}, {\n \"id\": \"jeecg-demo-websocket\",\n \"order\": 3,\n \"predicates\": [{\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/vxeSocket/**\"\n }\n }],\n \"filters\": [],\n \"uri\": \"lb:ws://jeecg-demo\"\n}]', 'be6548051d99309d7fa5ac4398404201', '2021-03-03 13:02:14', '2022-02-23 11:49:01', NULL, '0:0:0:0:0:0:0:1', '', '', '', '', '', 'json', ''); |
|||
INSERT INTO `config_info` VALUES (20, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', 'jeecg:\n route:\n config:\n #type:database nacos yml\n data-type: database\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', '0fc619d2d5e304f18bc4ea8be99f68a4', '2022-08-04 16:36:11', '2022-08-06 07:11:34', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''); |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for config_info_aggr |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `config_info_aggr`; |
|||
CREATE TABLE `config_info_aggr` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id', |
|||
`group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id', |
|||
`datum_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'datum_id', |
|||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '内容', |
|||
`gmt_modified` datetime NOT NULL COMMENT '修改时间', |
|||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_configinfoaggr_datagrouptenantdatum`(`data_id`, `group_id`, `tenant_id`, `datum_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '增加租户字段' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of config_info_aggr |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for config_info_beta |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `config_info_beta`; |
|||
CREATE TABLE `config_info_beta` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id', |
|||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id', |
|||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name', |
|||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content', |
|||
`beta_ips` varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'betaIps', |
|||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5', |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', |
|||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user', |
|||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip', |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_configinfobeta_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_beta' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of config_info_beta |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for config_info_tag |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `config_info_tag`; |
|||
CREATE TABLE `config_info_tag` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id', |
|||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id', |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id', |
|||
`tag_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_id', |
|||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name', |
|||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content', |
|||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5', |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', |
|||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user', |
|||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_configinfotag_datagrouptenanttag`(`data_id`, `group_id`, `tenant_id`, `tag_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_tag' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of config_info_tag |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for config_tags_relation |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `config_tags_relation`; |
|||
CREATE TABLE `config_tags_relation` ( |
|||
`id` bigint(20) NOT NULL COMMENT 'id', |
|||
`tag_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_name', |
|||
`tag_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tag_type', |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id', |
|||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id', |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id', |
|||
`nid` bigint(20) NOT NULL AUTO_INCREMENT, |
|||
PRIMARY KEY (`nid`) USING BTREE, |
|||
UNIQUE INDEX `uk_configtagrelation_configidtag`(`id`, `tag_name`, `tag_type`) USING BTREE, |
|||
INDEX `idx_tenant_id`(`tenant_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_tag_relation' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of config_tags_relation |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for group_capacity |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `group_capacity`; |
|||
CREATE TABLE `group_capacity` ( |
|||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', |
|||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', |
|||
`quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值', |
|||
`usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量', |
|||
`max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', |
|||
`max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数,,0表示使用默认值', |
|||
`max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', |
|||
`max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量', |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_group_id`(`group_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '集群、各Group容量信息表' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of group_capacity |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for his_config_info |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `his_config_info`; |
|||
CREATE TABLE `his_config_info` ( |
|||
`id` bigint(20) UNSIGNED NOT NULL, |
|||
`nid` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
|||
`data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, |
|||
`group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, |
|||
`app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name', |
|||
`content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, |
|||
`md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00', |
|||
`src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL, |
|||
`src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`op_type` char(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段', |
|||
PRIMARY KEY (`nid`) USING BTREE, |
|||
INDEX `idx_gmt_create`(`gmt_create`) USING BTREE, |
|||
INDEX `idx_gmt_modified`(`gmt_modified`) USING BTREE, |
|||
INDEX `idx_did`(`data_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 91 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '多租户改造' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of his_config_info |
|||
-- ---------------------------- |
|||
INSERT INTO `his_config_info` VALUES (20, 70, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', '', 'jeecg:\n route:\n config:\n #mode: database、nacos、yml\n data-type: database\n #nacos: jeecg-gateway-router.json\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', '26fff601e10bbc8bc5ff1fa2b192087b', '2010-05-05 00:00:00', '2022-08-05 10:45:21', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 71, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao :\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg :\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path :\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: 127.0.0.1:9200\n check-enabled: false\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\n\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n # agent-app-secret: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '17b0553ae2ade6474301e3d4eca6f05e', '2010-05-05 00:00:00', '2022-08-05 10:54:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 72, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: 127.0.0.1:9200\n check-enabled: false\n desform:\n theme-color: \'#1890ff\'\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '70922f6374bf2e4ccf0de8c089445811', '2010-05-05 00:00:00', '2022-08-05 10:57:40', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 73, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n desform:\n theme-color: \'#1890ff\'\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '035fff10fc0e5a38abf3c357afff7c67', '2010-05-05 00:00:00', '2022-08-05 10:59:02', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 74, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '87ec968621f8ac532e2fc50f98dd4f57', '2010-05-05 00:00:00', '2022-08-05 11:00:08', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 75, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'edb0e79d570edf341755caf3853f11e4', '2010-05-05 00:00:00', '2022-08-05 11:01:10', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 76, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-05 11:02:49', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 77, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '32d655df70c77beb8e39c5d3d8c69c9c', '2010-05-05 00:00:00', '2022-08-05 11:03:31', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 78, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\nsignUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', 'd3b15d3bb35c4baed32f75eabb2bf864', '2010-05-05 00:00:00', '2022-08-05 11:04:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 79, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-05 13:02:54', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 80, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true', '92ced3a81dece861666606c44cd4f630', '2010-05-05 00:00:00', '2022-08-05 13:03:28', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 81, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp', '364814ff81fb2a38c869f7bb5aa92f45', '2010-05-05 00:00:00', '2022-08-05 13:03:55', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 82, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', '064d0471e33d707a5b70e0807f8f0d93', '2010-05-05 00:00:00', '2022-08-05 13:04:39', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (2, 83, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2010-05-05 00:00:00', '2022-08-05 13:05:34', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 84, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n dynamic:\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', 'a12eaf6e6c090b303590f1e83c22ac3f', '2010-05-05 00:00:00', '2022-08-05 13:07:33', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 85, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n dynamic:\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379', '5e33b9dc9022eee8a1652e473dadbc42', '2010-05-05 00:00:00', '2022-08-05 13:09:30', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (2, 86, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1', '4525d8351d9498a8e5f43373ee6367a1', '2010-05-05 00:00:00', '2022-08-05 13:09:55', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (2, 87, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n startup-delay: 1s\n overwrite-existing-jobs: true\n properties:\n org:\n quartz:\n scheduler:\n instanceName: MyScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n misfireThreshold: 12000\n clusterCheckinInterval: 15000\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 10\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', '2117a96ba08e8fd0f66825e87416af27', '2010-05-05 00:00:00', '2022-08-05 13:10:58', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (2, 88, 'jeecg.yaml', 'DEFAULT_GROUP', '', 'server:\n tomcat:\n max-swallow-size: -1\n error:\n include-exception: true\n include-stacktrace: ALWAYS\n include-message: ALWAYS\n compression:\n enabled: true\n min-response-size: 1024\n mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*\nmanagement:\n health:\n mail:\n enabled: false\n endpoints:\n web:\n exposure:\n include: \"*\"\n health:\n sensitive: true\n endpoint:\n health:\n show-details: ALWAYS\nspring:\n servlet:\n multipart:\n max-file-size: 10MB\n max-request-size: 10MB\n mail:\n host: smtp.163.com\n username: jeecgos@163.com\n password: ??\n properties:\n mail:\n smtp:\n auth: true\n starttls:\n enable: true\n required: true\n quartz:\n job-store-type: jdbc\n initialize-schema: embedded\n auto-startup: false\n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n time-zone: GMT+8\n aop:\n proxy-target-class: true\n activiti:\n check-process-definitions: false\n async-executor-activate: false\n job-executor-activate: false\n jpa:\n open-in-view: false\n freemarker:\n suffix: .ftl\n content-type: text/html\n charset: UTF-8\n cache: false\n prefer-file-system-access: false\n template-loader-path:\n - classpath:/templates\n mvc:\n static-path-pattern: /**\n pathmatch:\n matching-strategy: ant_path_matcher\n resource:\n static-locations: classpath:/static/,classpath:/public/\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\nmybatis-plus:\n mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: ASSIGN_ID\n table-underline: true\n configuration:\n call-setters-on-nulls: true', 'a1effef2c22a7d2846f84728aa29ecd4', '2010-05-05 00:00:00', '2022-08-05 13:12:21', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (1, 89, 'jeecg-dev.yaml', 'DEFAULT_GROUP', '', 'spring:\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n allow:\n web-stat-filter:\n enabled: true\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,wall,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n url: jdbc:mysql://jeecg-boot-mysql:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai\n username: root\n password: root\n driver-class-name: com.mysql.cj.jdbc.Driver\n redis:\n database: 0\n host: jeecg-boot-redis\n password:\n port: 6379\n rabbitmq:\n host: jeecg-boot-rabbitmq\n username: guest\n password: guest\n port: 5672\n publisher-confirms: true\n publisher-returns: true\n virtual-host: /\n listener:\n simple:\n acknowledge-mode: manual\n concurrency: 1\n max-concurrency: 1\n retry:\n enabled: true\nminidao:\n base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*\njeecg:\n signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a\n signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys\n uploadType: local\n domainUrl:\n pc: http://localhost:3100\n app: http://localhost:8051\n path:\n upload: /opt/upFiles\n webapp: /opt/webapp\n shiro:\n excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**\n desform:\n theme-color: \"#1890ff\"\n upload-type: system\n map:\n baidu: ??\n oss:\n endpoint: oss-cn-beijing.aliyuncs.com\n accessKey: ??\n secretKey: ??\n bucketName: jeecgdev\n staticDomain: ??\n elasticsearch:\n cluster-name: jeecg-ES\n cluster-nodes: jeecg-boot-es:9200\n check-enabled: false\n file-view-domain: 127.0.0.1:8012\n minio:\n minio_url: http://minio.jeecg.com\n minio_name: ??\n minio_pass: ??\n bucketName: otatest\n jmreport:\n mode: dev\n is_verify_token: false\n verify_methods: remove,delete,save,add,update\n wps:\n domain: https://wwo.wps.cn/office/\n appid: ??\n appsecret: ??\n xxljob:\n enabled: false\n adminAddresses: http://jeecg-boot-xxljob:9080/xxl-job-admin\n appname: ${spring.application.name}\n accessToken: \'\'\n logPath: logs/jeecg/job/jobhandler/\n logRetentionDays: 30\n redisson:\n address: jeecg-boot-redis:6379\n password:\n type: STANDALONE\n enabled: true\nlogging:\n level:\n org.jeecg.modules.system.mapper : info\ncas:\n prefixUrl: http://localhost:8888/cas\nknife4j:\n production: false\n basic:\n enable: false\n username: jeecg\n password: jeecg1314\njustauth:\n enabled: true\n type:\n GITHUB:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/github/callback\n WECHAT_ENTERPRISE:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/wechat_enterprise/callback\n agent-id: ??\n DINGTALK:\n client-id: ??\n client-secret: ??\n redirect-uri: http://sso.test.com:8080/jeecg-boot/thirdLogin/dingtalk/callback\n cache:\n type: default\n prefix: \'demo::\'\n timeout: 1h\nthird-app:\n enabled: false\n type:\n WECHAT_ENTERPRISE:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??\n DINGTALK:\n enabled: false\n client-id: ??\n client-secret: ??\n agent-id: ??', '53b1c1130dff673311ad863b4ce67c8e', '2010-05-05 00:00:00', '2022-08-06 07:10:17', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
INSERT INTO `his_config_info` VALUES (20, 90, 'jeecg-gateway-dev.yaml', 'DEFAULT_GROUP', '', 'jeecg:\n route:\n config:\n #mode:database nacos yml\n data-type: database\n group: DEFAULT_GROUP\n data-id: jeecg-gateway-router\nspring:\n redis:\n database: 0\n host: jeecg-boot-redis\n port: 6379\n password:', 'b08a4c456f508fdd0fc347305da39a9e', '2010-05-05 00:00:00', '2022-08-06 07:11:34', 'nacos', '0:0:0:0:0:0:0:1', 'U', ''); |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for permissions |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `permissions`; |
|||
CREATE TABLE `permissions` ( |
|||
`role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
`resource` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
`action` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
UNIQUE INDEX `uk_role_permission`(`role`, `resource`, `action`) USING BTREE |
|||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of permissions |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for roles |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `roles`; |
|||
CREATE TABLE `roles` ( |
|||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
`role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
UNIQUE INDEX `uk_username_role`(`username`, `role`) USING BTREE |
|||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of roles |
|||
-- ---------------------------- |
|||
INSERT INTO `roles` VALUES ('nacos', 'ROLE_ADMIN'); |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for tenant_capacity |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `tenant_capacity`; |
|||
CREATE TABLE `tenant_capacity` ( |
|||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID', |
|||
`quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值', |
|||
`usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量', |
|||
`max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', |
|||
`max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数', |
|||
`max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', |
|||
`max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量', |
|||
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间', |
|||
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_tenant_id`(`tenant_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '租户容量信息表' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of tenant_capacity |
|||
-- ---------------------------- |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for tenant_info |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `tenant_info`; |
|||
CREATE TABLE `tenant_info` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', |
|||
`kp` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'kp', |
|||
`tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id', |
|||
`tenant_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_name', |
|||
`tenant_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tenant_desc', |
|||
`create_source` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'create_source', |
|||
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间', |
|||
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', |
|||
PRIMARY KEY (`id`) USING BTREE, |
|||
UNIQUE INDEX `uk_tenant_info_kptenantid`(`kp`, `tenant_id`) USING BTREE, |
|||
INDEX `idx_tenant_id`(`tenant_id`) USING BTREE |
|||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'tenant_info' ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of tenant_info |
|||
-- ---------------------------- |
|||
INSERT INTO `tenant_info` VALUES (1, '1', 'ac14ab82-51f8-4f0c-aa5b-25fb8384bfb6', 'jeecg', 'jeecg 测试命名空间', 'nacos', 1653291038942, 1653291038942); |
|||
|
|||
-- ---------------------------- |
|||
-- Table structure for users |
|||
-- ---------------------------- |
|||
DROP TABLE IF EXISTS `users`; |
|||
CREATE TABLE `users` ( |
|||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
`password` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, |
|||
`enabled` tinyint(1) NOT NULL, |
|||
PRIMARY KEY (`username`) USING BTREE |
|||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC; |
|||
|
|||
-- ---------------------------- |
|||
-- Records of users |
|||
-- ---------------------------- |
|||
INSERT INTO `users` VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', 1); |
|||
|
|||
SET FOREIGN_KEY_CHECKS = 1; |
@ -0,0 +1,119 @@ |
|||
# |
|||
# XXL-JOB v2.2.0 |
|||
# Copyright (c) 2015-present, xuxueli. |
|||
|
|||
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_general_ci; |
|||
use `xxl_job`; |
|||
|
|||
SET NAMES utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_info` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID', |
|||
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON', |
|||
`job_desc` varchar(255) NOT NULL, |
|||
`add_time` datetime DEFAULT NULL, |
|||
`update_time` datetime DEFAULT NULL, |
|||
`author` varchar(64) DEFAULT NULL COMMENT '作者', |
|||
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件', |
|||
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略', |
|||
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler', |
|||
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数', |
|||
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略', |
|||
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒', |
|||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数', |
|||
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型', |
|||
`glue_source` mediumtext COMMENT 'GLUE源代码', |
|||
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注', |
|||
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间', |
|||
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔', |
|||
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行', |
|||
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间', |
|||
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间', |
|||
PRIMARY KEY (`id`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_log` ( |
|||
`id` bigint(20) NOT NULL AUTO_INCREMENT, |
|||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID', |
|||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID', |
|||
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址', |
|||
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler', |
|||
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数', |
|||
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2', |
|||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数', |
|||
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间', |
|||
`trigger_code` int(11) NOT NULL COMMENT '调度-结果', |
|||
`trigger_msg` text COMMENT '调度-日志', |
|||
`handle_time` datetime DEFAULT NULL COMMENT '执行-时间', |
|||
`handle_code` int(11) NOT NULL COMMENT '执行-状态', |
|||
`handle_msg` text COMMENT '执行-日志', |
|||
`alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败', |
|||
PRIMARY KEY (`id`), |
|||
KEY `I_trigger_time` (`trigger_time`), |
|||
KEY `I_handle_code` (`handle_code`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_log_report` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`trigger_day` datetime DEFAULT NULL COMMENT '调度-时间', |
|||
`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量', |
|||
`suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量', |
|||
`fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量', |
|||
PRIMARY KEY (`id`), |
|||
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_logglue` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID', |
|||
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型', |
|||
`glue_source` mediumtext COMMENT 'GLUE源代码', |
|||
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注', |
|||
`add_time` datetime DEFAULT NULL, |
|||
`update_time` datetime DEFAULT NULL, |
|||
PRIMARY KEY (`id`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_registry` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`registry_group` varchar(50) NOT NULL, |
|||
`registry_key` varchar(255) NOT NULL, |
|||
`registry_value` varchar(255) NOT NULL, |
|||
`update_time` datetime DEFAULT NULL, |
|||
PRIMARY KEY (`id`), |
|||
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_group` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName', |
|||
`title` varchar(12) NOT NULL COMMENT '执行器名称', |
|||
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入', |
|||
`address_list` varchar(512) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔', |
|||
PRIMARY KEY (`id`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_user` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`username` varchar(50) NOT NULL COMMENT '账号', |
|||
`password` varchar(50) NOT NULL COMMENT '密码', |
|||
`role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员', |
|||
`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割', |
|||
PRIMARY KEY (`id`), |
|||
UNIQUE KEY `i_username` (`username`) USING BTREE |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
CREATE TABLE `xxl_job_lock` ( |
|||
`lock_name` varchar(50) NOT NULL COMMENT '锁名称', |
|||
PRIMARY KEY (`lock_name`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; |
|||
|
|||
|
|||
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL); |
|||
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_cron`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '0 0 0 * * ? *', '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', ''); |
|||
INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL); |
|||
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock'); |
|||
|
|||
commit; |
|||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,32 @@ |
|||
|
|||
ALTER TABLE `sys_user` |
|||
MODIFY COLUMN `org_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '登录会话的机构编码' AFTER `phone`; |
|||
|
|||
ALTER TABLE `sys_role_index` |
|||
ADD COLUMN `component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '组件' AFTER `url`, |
|||
ADD COLUMN `is_route` tinyint(1) NULL DEFAULT 1 COMMENT '是否路由菜单: 0:不是 1:是(默认值1)' AFTER `component`; |
|||
|
|||
ALTER TABLE `jeecg_order_main` |
|||
ADD COLUMN `bpm_status` varchar(3) NULL COMMENT '流程状态' AFTER `update_time`; |
|||
|
|||
UPDATE `sys_dict_item` SET `dict_id` = '4f69be5f507accea8d5df5f11346181a', `item_text` = '文本', `item_value` = '1', `description` = '', `sort_order` = 1, `status` = 1, `create_by` = 'admin', `create_time` = '2023-02-28 10:50:36', `update_by` = 'admin', `update_time` = '2022-07-04 16:29:21' WHERE `id` = '222705e11ef0264d4214affff1fb4ff9'; |
|||
UPDATE `sys_dict_item` SET `dict_id` = '4f69be5f507accea8d5df5f11346181a', `item_text` = '富文本', `item_value` = '2', `description` = '', `sort_order` = 2, `status` = 1, `create_by` = 'admin', `create_time` = '2031-02-28 10:50:44', `update_by` = 'admin', `update_time` = '2022-07-04 16:29:30' WHERE `id` = '6a7a9e1403a7943aba69e54ebeff9762'; |
|||
delete from sys_dict_item where id in ('1199607547704647681', '8bccb963e1cd9e8d42482c54cc609ca2'); |
|||
update sys_sms_template set template_type = '2' where template_type='4'; |
|||
update sys_sms_template set template_type = '1' where template_type='3'; |
|||
|
|||
ALTER TABLE `sys_sms_template` |
|||
ADD COLUMN `use_status` varchar(1) NULL COMMENT '是否使用中 1是0否' AFTER `update_by`; |
|||
|
|||
ALTER TABLE `sys_sms` |
|||
MODIFY COLUMN `es_type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '发送方式:参考枚举MessageTypeEnum' AFTER `es_title`; |
|||
|
|||
|
|||
ALTER TABLE jimu_report_data_source |
|||
ADD COLUMN tenant_id varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '多租户标识' AFTER connect_times; |
|||
|
|||
ALTER TABLE jimu_dict |
|||
ADD COLUMN tenant_id varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '多租户标识' AFTER type; |
|||
|
|||
ALTER TABLE jimu_report |
|||
ADD COLUMN tenant_id varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '多租户标识' AFTER js_str; |
@ -0,0 +1,10 @@ |
|||
版本升级方法? |
|||
|
|||
JeecgBoot属于平台级产品,每次升级改动内容较多,目前做不到平滑升级。 |
|||
|
|||
这里给用户的升级建议是这样的: |
|||
1.代码升级 => 本地版本通过svn或者git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比代码进行提交; |
|||
2.数据库升级 => 针对数据库我们每次发布会提供增量升级SQL,可以通过增量SQL实现数据库的升级。 |
|||
3.兼容问题 => 每次版本发布会针对不兼容地方标注说明,需要手工修改不兼容的代码。 |
|||
|
|||
注意: 升级sql目前只提供mysql版本,执行完脚步后,新菜单需要手工进行角色授权,刷新首页才会出现。 |
@ -0,0 +1,42 @@ |
|||
version: '2' |
|||
services: |
|||
jeecg-boot-mysql: |
|||
build: |
|||
context: ./db |
|||
environment: |
|||
MYSQL_ROOT_PASSWORD: root |
|||
MYSQL_ROOT_HOST: '%' |
|||
TZ: Asia/Shanghai |
|||
restart: always |
|||
container_name: jeecg-boot-mysql |
|||
image: jeecg-boot-mysql |
|||
command: |
|||
--character-set-server=utf8mb4 |
|||
--collation-server=utf8mb4_general_ci |
|||
--explicit_defaults_for_timestamp=true |
|||
--lower_case_table_names=1 |
|||
--max_allowed_packet=128M |
|||
--default-authentication-plugin=caching_sha2_password |
|||
ports: |
|||
- 3306:3306 |
|||
|
|||
jeecg-boot-redis: |
|||
image: redis:5.0 |
|||
ports: |
|||
- 6379:6379 |
|||
restart: always |
|||
hostname: jeecg-boot-redis |
|||
container_name: jeecg-boot-redis |
|||
|
|||
jeecg-boot-system: |
|||
build: |
|||
context: ./jeecg-module-system/jeecg-system-start |
|||
restart: on-failure |
|||
depends_on: |
|||
- jeecg-boot-mysql |
|||
- jeecg-boot-redis |
|||
container_name: jeecg-boot-system |
|||
image: jeecg-boot-system |
|||
hostname: jeecg-boot-system |
|||
ports: |
|||
- 8080:8080 |
@ -0,0 +1,224 @@ |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<parent> |
|||
<artifactId>jeecg-boot-parent</artifactId> |
|||
<groupId>org.jeecgframework.boot</groupId> |
|||
<version>3.4.0</version> |
|||
</parent> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
|
|||
<artifactId>jeecg-boot-base-core</artifactId> |
|||
|
|||
<dependencies> |
|||
<!--jeecg-tools--> |
|||
<dependency> |
|||
<groupId>org.jeecgframework.boot</groupId> |
|||
<artifactId>jeecg-boot-common</artifactId> |
|||
</dependency> |
|||
<!--集成springmvc框架并实现自动配置 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
<!-- websocket --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-websocket</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-mail</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-aop</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-actuator</artifactId> |
|||
</dependency> |
|||
<!--springboot2.3+ 需引入validation对应的包--> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-validation</artifactId> |
|||
</dependency> |
|||
<!--springboot2.6+解决metrics端点不显示jvm信息的问题--> |
|||
<dependency> |
|||
<groupId>io.micrometer</groupId> |
|||
<artifactId>micrometer-registry-prometheus</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- commons --> |
|||
<dependency> |
|||
<groupId>commons-io</groupId> |
|||
<artifactId>commons-io</artifactId> |
|||
<version>${commons.version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>commons-lang</groupId> |
|||
<artifactId>commons-lang</artifactId> |
|||
<version>${commons.version}</version> |
|||
</dependency> |
|||
<!-- freemarker --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-freemarker</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- mybatis-plus --> |
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>mybatis-plus-boot-starter</artifactId> |
|||
<version>${mybatis-plus.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- druid --> |
|||
<dependency> |
|||
<groupId>com.alibaba</groupId> |
|||
<artifactId>druid-spring-boot-starter</artifactId> |
|||
<version>${druid.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 动态数据源 --> |
|||
<dependency> |
|||
<groupId>com.baomidou</groupId> |
|||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId> |
|||
<version>${dynamic-datasource-spring-boot-starter.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 数据库驱动 --> |
|||
<!--mysql--> |
|||
<dependency> |
|||
<groupId>mysql</groupId> |
|||
<artifactId>mysql-connector-java</artifactId> |
|||
<version>${mysql-connector-java.version}</version> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
<!-- sqlserver--> |
|||
<dependency> |
|||
<groupId>com.microsoft.sqlserver</groupId> |
|||
<artifactId>sqljdbc4</artifactId> |
|||
<version>${sqljdbc4.version}</version> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
<!-- oracle驱动 --> |
|||
<dependency> |
|||
<groupId>com.oracle</groupId> |
|||
<artifactId>ojdbc6</artifactId> |
|||
<version>${ojdbc6.version}</version> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
<!-- postgresql驱动 --> |
|||
<dependency> |
|||
<groupId>org.postgresql</groupId> |
|||
<artifactId>postgresql</artifactId> |
|||
<version>${postgresql.version}</version> |
|||
<scope>runtime</scope> |
|||
</dependency> |
|||
|
|||
<!-- Quartz定时任务 --> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-quartz</artifactId> |
|||
</dependency> |
|||
|
|||
<!--JWT--> |
|||
<dependency> |
|||
<groupId>com.auth0</groupId> |
|||
<artifactId>java-jwt</artifactId> |
|||
<version>${java-jwt.version}</version> |
|||
</dependency> |
|||
|
|||
<!--shiro--> |
|||
<dependency> |
|||
<groupId>org.apache.shiro</groupId> |
|||
<artifactId>shiro-spring-boot-starter</artifactId> |
|||
<version>${shiro.version}</version> |
|||
</dependency> |
|||
<!-- shiro-redis --> |
|||
<dependency> |
|||
<groupId>org.crazycake</groupId> |
|||
<artifactId>shiro-redis</artifactId> |
|||
<version>${shiro-redis.version}</version> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>org.apache.shiro</groupId> |
|||
<artifactId>shiro-core</artifactId> |
|||
</exclusion> |
|||
<!-- [issues/3596] 解决启动报错:Cannot resolve com.sun:tools:1.8.0 --> |
|||
<exclusion> |
|||
<groupId>com.puppycrawl.tools</groupId> |
|||
<artifactId>checkstyle</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
</dependency> |
|||
|
|||
<!-- knife4j --> |
|||
<dependency> |
|||
<groupId>com.github.xiaoymin</groupId> |
|||
<artifactId>knife4j-spring-boot-starter</artifactId> |
|||
<version>${knife4j-spring-boot-starter.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 代码生成器 --> |
|||
<!-- 如下载失败,请参考此文档 http://doc.jeecg.com/2043876 --> |
|||
<dependency> |
|||
<groupId>org.jeecgframework.boot</groupId> |
|||
<artifactId>codegenerate</artifactId> |
|||
<version>${codegenerate.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- AutoPoi Excel工具类--> |
|||
<dependency> |
|||
<groupId>org.jeecgframework</groupId> |
|||
<artifactId>autopoi-web</artifactId> |
|||
<version>${autopoi-web.version}</version> |
|||
<exclusions> |
|||
<exclusion> |
|||
<groupId>commons-codec</groupId> |
|||
<artifactId>commons-codec</artifactId> |
|||
</exclusion> |
|||
</exclusions> |
|||
</dependency> |
|||
|
|||
<!-- mini文件存储服务 --> |
|||
<dependency> |
|||
<groupId>io.minio</groupId> |
|||
<artifactId>minio</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.google.guava</groupId> |
|||
<artifactId>guava</artifactId> |
|||
<version>${guava.version}</version> |
|||
</dependency> |
|||
|
|||
<!-- 阿里云短信 --> |
|||
<dependency> |
|||
<groupId>com.aliyun</groupId> |
|||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId> |
|||
<version>${aliyun-java-sdk-dysmsapi.version}</version> |
|||
</dependency> |
|||
<!-- aliyun oss --> |
|||
<dependency> |
|||
<groupId>com.aliyun.oss</groupId> |
|||
<artifactId>aliyun-sdk-oss</artifactId> |
|||
<version>${aliyun.oss.version}</version> |
|||
</dependency> |
|||
<!-- 第三方登录 --> |
|||
<dependency> |
|||
<groupId>com.xkcoding.justauth</groupId> |
|||
<artifactId>justauth-spring-boot-starter</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.squareup.okhttp3</groupId> |
|||
<artifactId>okhttp</artifactId> |
|||
</dependency> |
|||
<!-- 解决okhttp引用了kotlin,应用启动有警告日志问题 --> |
|||
<dependency> |
|||
<groupId>com.fasterxml.jackson.module</groupId> |
|||
<artifactId>jackson-module-kotlin</artifactId> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
</project> |
@ -0,0 +1,130 @@ |
|||
package org.jeecg.common.api; |
|||
|
|||
import org.jeecg.common.system.vo.*; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* 通用api |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public interface CommonAPI { |
|||
|
|||
/** |
|||
* 1查询用户角色信息 |
|||
* @param username |
|||
* @return |
|||
*/ |
|||
Set<String> queryUserRoles(String username); |
|||
|
|||
|
|||
/** |
|||
* 2查询用户权限信息 |
|||
* @param username |
|||
* @return |
|||
*/ |
|||
Set<String> queryUserAuths(String username); |
|||
|
|||
/** |
|||
* 3根据 id 查询数据库中存储的 DynamicDataSourceModel |
|||
* |
|||
* @param dbSourceId |
|||
* @return |
|||
*/ |
|||
DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId); |
|||
|
|||
/** |
|||
* 4根据 code 查询数据库中存储的 DynamicDataSourceModel |
|||
* |
|||
* @param dbSourceCode |
|||
* @return |
|||
*/ |
|||
DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode); |
|||
|
|||
/** |
|||
* 5根据用户账号查询用户信息 |
|||
* @param username |
|||
* @return |
|||
*/ |
|||
public LoginUser getUserByName(String username); |
|||
|
|||
|
|||
/** |
|||
* 6字典表的 翻译 |
|||
* @param table |
|||
* @param text |
|||
* @param code |
|||
* @param key |
|||
* @return |
|||
*/ |
|||
String translateDictFromTable(String table, String text, String code, String key); |
|||
|
|||
/** |
|||
* 7普通字典的翻译 |
|||
* @param code |
|||
* @param key |
|||
* @return |
|||
*/ |
|||
String translateDict(String code, String key); |
|||
|
|||
/** |
|||
* 8查询数据权限 |
|||
* @param component 组件 |
|||
* @param username 用户名 |
|||
* @param requestPath 前段请求地址 |
|||
* @return |
|||
*/ |
|||
List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username); |
|||
|
|||
|
|||
/** |
|||
* 9查询用户信息 |
|||
* @param username |
|||
* @return |
|||
*/ |
|||
SysUserCacheInfo getCacheUser(String username); |
|||
|
|||
/** |
|||
* 10获取数据字典 |
|||
* @param code |
|||
* @return |
|||
*/ |
|||
public List<DictModel> queryDictItemsByCode(String code); |
|||
|
|||
/** |
|||
* 获取有效的数据字典项 |
|||
* @param code |
|||
* @return |
|||
*/ |
|||
public List<DictModel> queryEnableDictItemsByCode(String code); |
|||
|
|||
/** |
|||
* 13获取表数据字典 |
|||
* @param table |
|||
* @param text |
|||
* @param code |
|||
* @return |
|||
*/ |
|||
List<DictModel> queryTableDictItemsByCode(String table, String text, String code); |
|||
|
|||
/** |
|||
* 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割 |
|||
* @param dictCodes 例如:user_status,sex |
|||
* @param keys 例如:1,2,0 |
|||
* @return |
|||
*/ |
|||
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys); |
|||
|
|||
/** |
|||
* 15 字典表的 翻译,可批量 |
|||
* @param table |
|||
* @param text |
|||
* @param code |
|||
* @param keys 多个用逗号分割 |
|||
* @return |
|||
*/ |
|||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys); |
|||
|
|||
} |
@ -0,0 +1,31 @@ |
|||
package org.jeecg.common.api.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 文件下载 |
|||
* cloud api 用到的接口传输对象 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class FileDownDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 6749126258686446019L; |
|||
|
|||
private String filePath; |
|||
private String uploadpath; |
|||
private String uploadType; |
|||
private HttpServletResponse response; |
|||
|
|||
public FileDownDTO(){} |
|||
|
|||
public FileDownDTO(String filePath, String uploadpath, String uploadType,HttpServletResponse response){ |
|||
this.filePath = filePath; |
|||
this.uploadpath = uploadpath; |
|||
this.uploadType = uploadType; |
|||
this.response = response; |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
package org.jeecg.common.api.dto; |
|||
|
|||
import lombok.Data; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 文件上传 |
|||
* cloud api 用到的接口传输对象 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class FileUploadDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = -4111953058578954386L; |
|||
|
|||
private MultipartFile file; |
|||
|
|||
private String bizPath; |
|||
|
|||
private String uploadType; |
|||
|
|||
private String customBucket; |
|||
|
|||
public FileUploadDTO(){ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 简单上传 构造器1 |
|||
* @param file |
|||
* @param bizPath |
|||
* @param uploadType |
|||
*/ |
|||
public FileUploadDTO(MultipartFile file,String bizPath,String uploadType){ |
|||
this.file = file; |
|||
this.bizPath = bizPath; |
|||
this.uploadType = uploadType; |
|||
} |
|||
|
|||
/** |
|||
* 申明桶 文件上传 构造器2 |
|||
* @param file |
|||
* @param bizPath |
|||
* @param uploadType |
|||
* @param customBucket |
|||
*/ |
|||
public FileUploadDTO(MultipartFile file,String bizPath,String uploadType,String customBucket){ |
|||
this.file = file; |
|||
this.bizPath = bizPath; |
|||
this.uploadType = uploadType; |
|||
this.customBucket = customBucket; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,69 @@ |
|||
package org.jeecg.common.api.dto; |
|||
import lombok.Data; |
|||
import org.jeecg.common.system.vo.LoginUser; |
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 日志对象 |
|||
* cloud api 用到的接口传输对象 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class LogDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 8482720462943906924L; |
|||
|
|||
/**内容*/ |
|||
private String logContent; |
|||
|
|||
/**日志类型(0:操作日志;1:登录日志;2:定时任务) */ |
|||
private Integer logType; |
|||
|
|||
/**操作类型(1:添加;2:修改;3:删除;) */ |
|||
private Integer operateType; |
|||
|
|||
/**登录用户 */ |
|||
private LoginUser loginUser; |
|||
|
|||
private String id; |
|||
private String createBy; |
|||
private Date createTime; |
|||
private Long costTime; |
|||
private String ip; |
|||
|
|||
/**请求参数 */ |
|||
private String requestParam; |
|||
|
|||
/**请求类型*/ |
|||
private String requestType; |
|||
|
|||
/**请求路径*/ |
|||
private String requestUrl; |
|||
|
|||
/**请求方法 */ |
|||
private String method; |
|||
|
|||
/**操作人用户名称*/ |
|||
private String username; |
|||
|
|||
/**操作人用户账户*/ |
|||
private String userid; |
|||
|
|||
public LogDTO(){ |
|||
|
|||
} |
|||
|
|||
public LogDTO(String logContent, Integer logType, Integer operatetype){ |
|||
this.logContent = logContent; |
|||
this.logType = logType; |
|||
this.operateType = operatetype; |
|||
} |
|||
|
|||
public LogDTO(String logContent, Integer logType, Integer operatetype, LoginUser loginUser){ |
|||
this.logContent = logContent; |
|||
this.logType = logType; |
|||
this.operateType = operatetype; |
|||
this.loginUser = loginUser; |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
package org.jeecg.common.api.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* online 拦截器权限判断 |
|||
* cloud api 用到的接口传输对象 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class OnlineAuthDTO implements Serializable { |
|||
private static final long serialVersionUID = 1771827545416418203L; |
|||
|
|||
|
|||
/** |
|||
* 用户名 |
|||
*/ |
|||
private String username; |
|||
|
|||
/** |
|||
* 可能的请求地址 |
|||
*/ |
|||
private List<String> possibleUrl; |
|||
|
|||
/** |
|||
* online开发的菜单地址 |
|||
*/ |
|||
private String onlineFormUrl; |
|||
|
|||
public OnlineAuthDTO(){ |
|||
|
|||
} |
|||
|
|||
public OnlineAuthDTO(String username, List<String> possibleUrl, String onlineFormUrl){ |
|||
this.username = username; |
|||
this.possibleUrl = possibleUrl; |
|||
this.onlineFormUrl = onlineFormUrl; |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
package org.jeecg.common.api.dto.message; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 带业务参数的消息 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class BusMessageDTO extends MessageDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 9104793287983367669L; |
|||
/** |
|||
* 业务类型 |
|||
*/ |
|||
private String busType; |
|||
|
|||
/** |
|||
* 业务id |
|||
*/ |
|||
private String busId; |
|||
|
|||
public BusMessageDTO(){ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 构造 带业务参数的消息 |
|||
* @param fromUser |
|||
* @param toUser |
|||
* @param title |
|||
* @param msgContent |
|||
* @param msgCategory |
|||
* @param busType |
|||
* @param busId |
|||
*/ |
|||
public BusMessageDTO(String fromUser, String toUser, String title, String msgContent, String msgCategory, String busType, String busId){ |
|||
super(fromUser, toUser, title, msgContent, msgCategory); |
|||
this.busId = busId; |
|||
this.busType = busType; |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
package org.jeecg.common.api.dto.message; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 带业务参数的模板消息 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class BusTemplateMessageDTO extends TemplateMessageDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = -4277810906346929459L; |
|||
|
|||
/** |
|||
* 业务类型 |
|||
*/ |
|||
private String busType; |
|||
|
|||
/** |
|||
* 业务id |
|||
*/ |
|||
private String busId; |
|||
|
|||
public BusTemplateMessageDTO(){ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 构造 带业务参数的模板消息 |
|||
* @param fromUser |
|||
* @param toUser |
|||
* @param title |
|||
* @param templateParam |
|||
* @param templateCode |
|||
* @param busType |
|||
* @param busId |
|||
*/ |
|||
public BusTemplateMessageDTO(String fromUser, String toUser, String title, Map<String, String> templateParam, String templateCode, String busType, String busId){ |
|||
super(fromUser, toUser, title, templateParam, templateCode); |
|||
this.busId = busId; |
|||
this.busType = busType; |
|||
} |
|||
} |
@ -0,0 +1,90 @@ |
|||
package org.jeecg.common.api.dto.message; |
|||
|
|||
import lombok.Data; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 普通消息 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class MessageDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = -5690444483968058442L; |
|||
|
|||
/** |
|||
* 发送人(用户登录账户) |
|||
*/ |
|||
protected String fromUser; |
|||
|
|||
/** |
|||
* 发送给(用户登录账户) |
|||
*/ |
|||
protected String toUser; |
|||
|
|||
/** |
|||
* 发送给所有人 |
|||
*/ |
|||
protected Boolean toAll; |
|||
|
|||
/** |
|||
* 消息主题 |
|||
*/ |
|||
protected String title; |
|||
|
|||
/** |
|||
* 消息内容 |
|||
*/ |
|||
protected String content; |
|||
|
|||
/** |
|||
* 消息类型 1:消息 2:系统消息 |
|||
*/ |
|||
protected String category; |
|||
|
|||
|
|||
public MessageDTO(){ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 构造器1 系统消息 |
|||
*/ |
|||
public MessageDTO(String fromUser,String toUser,String title, String content){ |
|||
this.fromUser = fromUser; |
|||
this.toUser = toUser; |
|||
this.title = title; |
|||
this.content = content; |
|||
//默认 都是2系统消息
|
|||
this.category = CommonConstant.MSG_CATEGORY_2; |
|||
} |
|||
|
|||
/** |
|||
* 构造器2 支持设置category 1:消息 2:系统消息 |
|||
*/ |
|||
public MessageDTO(String fromUser,String toUser,String title, String content, String category){ |
|||
this.fromUser = fromUser; |
|||
this.toUser = toUser; |
|||
this.title = title; |
|||
this.content = content; |
|||
this.category = category; |
|||
} |
|||
|
|||
/** |
|||
* 模板消息对应的模板编码 |
|||
*/ |
|||
protected String templateCode; |
|||
/** |
|||
* 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum |
|||
*/ |
|||
protected String type; |
|||
|
|||
/** |
|||
* 解析模板内容 对应的数据 |
|||
*/ |
|||
protected Map<String, Object> data; |
|||
|
|||
} |
@ -0,0 +1,38 @@ |
|||
package org.jeecg.common.api.dto.message; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 消息模板dto |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class TemplateDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 5848247133907528650L; |
|||
|
|||
/** |
|||
* 模板编码 |
|||
*/ |
|||
protected String templateCode; |
|||
|
|||
/** |
|||
* 模板参数 |
|||
*/ |
|||
protected Map<String, String> templateParam; |
|||
|
|||
/** |
|||
* 构造器 通过设置模板参数和模板编码 作为参数获取消息内容 |
|||
*/ |
|||
public TemplateDTO(String templateCode, Map<String, String> templateParam){ |
|||
this.templateCode = templateCode; |
|||
this.templateParam = templateParam; |
|||
} |
|||
|
|||
public TemplateDTO(){ |
|||
|
|||
} |
|||
} |
@ -0,0 +1,49 @@ |
|||
package org.jeecg.common.api.dto.message; |
|||
|
|||
import lombok.Data; |
|||
import java.io.Serializable; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 模板消息 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class TemplateMessageDTO extends TemplateDTO implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 411137565170647585L; |
|||
|
|||
|
|||
/** |
|||
* 发送人(用户登录账户) |
|||
*/ |
|||
protected String fromUser; |
|||
|
|||
/** |
|||
* 发送给(用户登录账户) |
|||
*/ |
|||
protected String toUser; |
|||
|
|||
/** |
|||
* 消息主题 |
|||
*/ |
|||
protected String title; |
|||
|
|||
|
|||
public TemplateMessageDTO(){ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 构造器1 发模板消息用 |
|||
*/ |
|||
public TemplateMessageDTO(String fromUser, String toUser,String title, Map<String, String> templateParam, String templateCode){ |
|||
super(templateCode, templateParam); |
|||
this.fromUser = fromUser; |
|||
this.toUser = toUser; |
|||
this.title = title; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,177 @@ |
|||
package org.jeecg.common.api.vo; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 接口返回数据格式 |
|||
* @author scott |
|||
* @email jeecgos@163.com |
|||
* @date 2019年1月19日 |
|||
*/ |
|||
@Data |
|||
@ApiModel(value="接口返回对象", description="接口返回对象") |
|||
public class Result<T> implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 成功标志 |
|||
*/ |
|||
@ApiModelProperty(value = "成功标志") |
|||
private boolean success = true; |
|||
|
|||
/** |
|||
* 返回处理消息 |
|||
*/ |
|||
@ApiModelProperty(value = "返回处理消息") |
|||
private String message = ""; |
|||
|
|||
/** |
|||
* 返回代码 |
|||
*/ |
|||
@ApiModelProperty(value = "返回代码") |
|||
private Integer code = 0; |
|||
|
|||
/** |
|||
* 返回数据对象 data |
|||
*/ |
|||
@ApiModelProperty(value = "返回数据对象") |
|||
private T result; |
|||
|
|||
/** |
|||
* 时间戳 |
|||
*/ |
|||
@ApiModelProperty(value = "时间戳") |
|||
private long timestamp = System.currentTimeMillis(); |
|||
|
|||
public Result() { |
|||
} |
|||
|
|||
/** |
|||
* 兼容VUE3版token失效不跳转登录页面 |
|||
* @param code |
|||
* @param message |
|||
*/ |
|||
public Result(Integer code, String message) { |
|||
this.code = code; |
|||
this.message = message; |
|||
} |
|||
|
|||
public Result<T> success(String message) { |
|||
this.message = message; |
|||
this.code = CommonConstant.SC_OK_200; |
|||
this.success = true; |
|||
return this; |
|||
} |
|||
|
|||
public static<T> Result<T> ok() { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> ok(String msg) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
//Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D
|
|||
r.setResult((T) msg); |
|||
r.setMessage(msg); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> ok(T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK() { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
return r; |
|||
} |
|||
|
|||
/** |
|||
* 此方法是为了兼容升级所创建 |
|||
* |
|||
* @param msg |
|||
* @param <T> |
|||
* @return |
|||
*/ |
|||
public static<T> Result<T> OK(String msg) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage(msg); |
|||
//Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D
|
|||
r.setResult((T) msg); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK(T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> OK(String msg, T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(true); |
|||
r.setCode(CommonConstant.SC_OK_200); |
|||
r.setMessage(msg); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> error(String msg, T data) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setSuccess(false); |
|||
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); |
|||
r.setMessage(msg); |
|||
r.setResult(data); |
|||
return r; |
|||
} |
|||
|
|||
public static<T> Result<T> error(String msg) { |
|||
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); |
|||
} |
|||
|
|||
public static<T> Result<T> error(int code, String msg) { |
|||
Result<T> r = new Result<T>(); |
|||
r.setCode(code); |
|||
r.setMessage(msg); |
|||
r.setSuccess(false); |
|||
return r; |
|||
} |
|||
|
|||
public Result<T> error500(String message) { |
|||
this.message = message; |
|||
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500; |
|||
this.success = false; |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* 无权限访问返回结果 |
|||
*/ |
|||
public static<T> Result<T> noauth(String msg) { |
|||
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg); |
|||
} |
|||
|
|||
@JsonIgnore |
|||
private String onlTable; |
|||
|
|||
} |
@ -0,0 +1,256 @@ |
|||
package org.jeecg.common.aspect; |
|||
|
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.alibaba.fastjson.serializer.PropertyFilter; |
|||
import org.apache.shiro.SecurityUtils; |
|||
import org.aspectj.lang.JoinPoint; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.aspectj.lang.annotation.Around; |
|||
import org.aspectj.lang.annotation.Aspect; |
|||
import org.aspectj.lang.annotation.Pointcut; |
|||
import org.aspectj.lang.reflect.MethodSignature; |
|||
import org.jeecg.common.api.dto.LogDTO; |
|||
import org.jeecg.common.api.vo.Result; |
|||
import org.jeecg.common.aspect.annotation.AutoLog; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.constant.enums.ModuleType; |
|||
import org.jeecg.common.constant.enums.OperateTypeEnum; |
|||
import org.jeecg.modules.base.service.BaseCommonService; |
|||
import org.jeecg.common.system.vo.LoginUser; |
|||
import org.jeecg.common.util.IpUtils; |
|||
import org.jeecg.common.util.SpringContextUtils; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.validation.BindingResult; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
import javax.annotation.Resource; |
|||
import javax.servlet.ServletRequest; |
|||
import javax.servlet.ServletResponse; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.lang.reflect.Method; |
|||
import java.util.Date; |
|||
|
|||
|
|||
/** |
|||
* 系统日志,切面处理类 |
|||
* |
|||
* @Author scott |
|||
* @email jeecgos@163.com |
|||
* @Date 2018年1月14日 |
|||
*/ |
|||
@Aspect |
|||
@Component |
|||
public class AutoLogAspect { |
|||
|
|||
@Resource |
|||
private BaseCommonService baseCommonService; |
|||
|
|||
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.AutoLog)") |
|||
public void logPointCut() { |
|||
|
|||
} |
|||
|
|||
@Around("logPointCut()") |
|||
public Object around(ProceedingJoinPoint point) throws Throwable { |
|||
long beginTime = System.currentTimeMillis(); |
|||
//执行方法
|
|||
Object result = point.proceed(); |
|||
//执行时长(毫秒)
|
|||
long time = System.currentTimeMillis() - beginTime; |
|||
|
|||
//保存日志
|
|||
saveSysLog(point, time, result); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) { |
|||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
|
|||
LogDTO dto = new LogDTO(); |
|||
AutoLog syslog = method.getAnnotation(AutoLog.class); |
|||
if(syslog != null){ |
|||
//update-begin-author:taoyan date:
|
|||
String content = syslog.value(); |
|||
if(syslog.module()== ModuleType.ONLINE){ |
|||
content = getOnlineLogContent(obj, content); |
|||
} |
|||
//注解上的描述,操作日志内容
|
|||
dto.setLogType(syslog.logType()); |
|||
dto.setLogContent(content); |
|||
} |
|||
|
|||
//请求的方法名
|
|||
String className = joinPoint.getTarget().getClass().getName(); |
|||
String methodName = signature.getName(); |
|||
dto.setMethod(className + "." + methodName + "()"); |
|||
|
|||
|
|||
//设置操作类型
|
|||
if (CommonConstant.LOG_TYPE_2 == dto.getLogType()) { |
|||
dto.setOperateType(getOperateType(methodName, syslog.operateType())); |
|||
} |
|||
|
|||
//获取request
|
|||
HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); |
|||
//请求的参数
|
|||
dto.setRequestParam(getReqestParams(request,joinPoint)); |
|||
//设置IP地址
|
|||
dto.setIp(IpUtils.getIpAddr(request)); |
|||
//获取登录用户信息
|
|||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
|||
if(sysUser!=null){ |
|||
dto.setUserid(sysUser.getUsername()); |
|||
dto.setUsername(sysUser.getRealname()); |
|||
|
|||
} |
|||
//耗时
|
|||
dto.setCostTime(time); |
|||
dto.setCreateTime(new Date()); |
|||
//保存系统日志
|
|||
baseCommonService.addLog(dto); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取操作类型 |
|||
*/ |
|||
private int getOperateType(String methodName,int operateType) { |
|||
if (operateType > 0) { |
|||
return operateType; |
|||
} |
|||
//update-begin---author:wangshuai ---date:20220331 for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------
|
|||
return OperateTypeEnum.getTypeByMethodName(methodName); |
|||
//update-end---author:wangshuai ---date:20220331 for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------
|
|||
} |
|||
|
|||
/** |
|||
* @Description: 获取请求参数 |
|||
* @author: scott |
|||
* @date: 2020/4/16 0:10 |
|||
* @param request: request |
|||
* @param joinPoint: joinPoint |
|||
* @Return: java.lang.String |
|||
*/ |
|||
private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) { |
|||
String httpMethod = request.getMethod(); |
|||
String params = ""; |
|||
if (CommonConstant.HTTP_POST.equals(httpMethod) || CommonConstant.HTTP_PUT.equals(httpMethod) || CommonConstant.HTTP_PATCH.equals(httpMethod)) { |
|||
Object[] paramsArray = joinPoint.getArgs(); |
|||
// java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
|
|||
// https://my.oschina.net/mengzhang6/blog/2395893
|
|||
Object[] arguments = new Object[paramsArray.length]; |
|||
for (int i = 0; i < paramsArray.length; i++) { |
|||
if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) { |
|||
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
|
|||
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
|
|||
continue; |
|||
} |
|||
arguments[i] = paramsArray[i]; |
|||
} |
|||
//update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
|
|||
PropertyFilter profilter = new PropertyFilter() { |
|||
@Override |
|||
public boolean apply(Object o, String name, Object value) { |
|||
int length = 500; |
|||
if(value!=null && value.toString().length()>length){ |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
}; |
|||
params = JSONObject.toJSONString(arguments, profilter); |
|||
//update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
|
|||
} else { |
|||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
// 请求的方法参数值
|
|||
Object[] args = joinPoint.getArgs(); |
|||
// 请求的方法参数名称
|
|||
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); |
|||
String[] paramNames = u.getParameterNames(method); |
|||
if (args != null && paramNames != null) { |
|||
for (int i = 0; i < args.length; i++) { |
|||
params += " " + paramNames[i] + ": " + args[i]; |
|||
} |
|||
} |
|||
} |
|||
return params; |
|||
} |
|||
|
|||
/** |
|||
* online日志内容拼接 |
|||
* @param obj |
|||
* @param content |
|||
* @return |
|||
*/ |
|||
private String getOnlineLogContent(Object obj, String content){ |
|||
if (Result.class.isInstance(obj)){ |
|||
Result res = (Result)obj; |
|||
String msg = res.getMessage(); |
|||
String tableName = res.getOnlTable(); |
|||
if(oConvertUtils.isNotEmpty(tableName)){ |
|||
content+=",表名:"+tableName; |
|||
} |
|||
if(res.isSuccess()){ |
|||
content+= ","+(oConvertUtils.isEmpty(msg)?"操作成功":msg); |
|||
}else{ |
|||
content+= ","+(oConvertUtils.isEmpty(msg)?"操作失败":msg); |
|||
} |
|||
} |
|||
return content; |
|||
} |
|||
|
|||
|
|||
/* private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) { |
|||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
|
|||
SysLog sysLog = new SysLog(); |
|||
AutoLog syslog = method.getAnnotation(AutoLog.class); |
|||
if(syslog != null){ |
|||
//update-begin-author:taoyan date:
|
|||
String content = syslog.value(); |
|||
if(syslog.module()== ModuleType.ONLINE){ |
|||
content = getOnlineLogContent(obj, content); |
|||
} |
|||
//注解上的描述,操作日志内容
|
|||
sysLog.setLogContent(content); |
|||
sysLog.setLogType(syslog.logType()); |
|||
} |
|||
|
|||
//请求的方法名
|
|||
String className = joinPoint.getTarget().getClass().getName(); |
|||
String methodName = signature.getName(); |
|||
sysLog.setMethod(className + "." + methodName + "()"); |
|||
|
|||
|
|||
//设置操作类型
|
|||
if (sysLog.getLogType() == CommonConstant.LOG_TYPE_2) { |
|||
sysLog.setOperateType(getOperateType(methodName, syslog.operateType())); |
|||
} |
|||
|
|||
//获取request
|
|||
HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); |
|||
//请求的参数
|
|||
sysLog.setRequestParam(getReqestParams(request,joinPoint)); |
|||
|
|||
//设置IP地址
|
|||
sysLog.setIp(IPUtils.getIpAddr(request)); |
|||
|
|||
//获取登录用户信息
|
|||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); |
|||
if(sysUser!=null){ |
|||
sysLog.setUserid(sysUser.getUsername()); |
|||
sysLog.setUsername(sysUser.getRealname()); |
|||
|
|||
} |
|||
//耗时
|
|||
sysLog.setCostTime(time); |
|||
sysLog.setCreateTime(new Date()); |
|||
//保存系统日志
|
|||
sysLogService.save(sysLog); |
|||
}*/ |
|||
} |
@ -0,0 +1,429 @@ |
|||
package org.jeecg.common.aspect; |
|||
|
|||
import com.alibaba.fastjson.JSON; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.alibaba.fastjson.parser.Feature; |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.fasterxml.jackson.core.JsonProcessingException; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.aspectj.lang.annotation.Around; |
|||
import org.aspectj.lang.annotation.Aspect; |
|||
import org.aspectj.lang.annotation.Pointcut; |
|||
import org.jeecg.common.api.CommonAPI; |
|||
import org.jeecg.common.api.vo.Result; |
|||
import org.jeecg.common.aspect.annotation.Dict; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.system.vo.DictModel; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.*; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* @Description: 字典aop类 |
|||
* @Author: dangzhenghui |
|||
* @Date: 2019-3-17 21:50 |
|||
* @Version: 1.0 |
|||
*/ |
|||
@Aspect |
|||
@Component |
|||
@Slf4j |
|||
public class DictAspect { |
|||
@Lazy |
|||
@Autowired |
|||
private CommonAPI commonApi; |
|||
@Autowired |
|||
public RedisTemplate redisTemplate; |
|||
|
|||
@Autowired |
|||
private ObjectMapper objectMapper; |
|||
|
|||
private static final String JAVA_UTIL_DATE = "java.util.Date"; |
|||
|
|||
/** |
|||
* 定义切点Pointcut |
|||
*/ |
|||
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..)) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)") |
|||
public void excudeService() { |
|||
} |
|||
|
|||
@Around("excudeService()") |
|||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable { |
|||
long time1=System.currentTimeMillis(); |
|||
Object result = pjp.proceed(); |
|||
long time2=System.currentTimeMillis(); |
|||
log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms"); |
|||
long start=System.currentTimeMillis(); |
|||
result=this.parseDictText(result); |
|||
long end=System.currentTimeMillis(); |
|||
log.debug("注入字典到JSON数据 耗时"+(end-start)+"ms"); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 本方法针对返回对象为Result 的IPage的分页列表数据进行动态字典注入 |
|||
* 字典注入实现 通过对实体类添加注解@dict 来标识需要的字典内容,字典分为单字典code即可 ,table字典 code table text配合使用与原来jeecg的用法相同 |
|||
* 示例为SysUser 字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text,已字段名称加_dictText形式返回到前端 |
|||
* 例输入当前返回值的就会多出一个sex_dictText字段 |
|||
* { |
|||
* sex:1, |
|||
* sex_dictText:"男" |
|||
* } |
|||
* 前端直接取值sext_dictText在table里面无需再进行前端的字典转换了 |
|||
* customRender:function (text) { |
|||
* if(text==1){ |
|||
* return "男"; |
|||
* }else if(text==2){ |
|||
* return "女"; |
|||
* }else{ |
|||
* return text; |
|||
* } |
|||
* } |
|||
* 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用 |
|||
* @param result |
|||
*/ |
|||
private Object parseDictText(Object result) { |
|||
if (result instanceof Result) { |
|||
if (((Result) result).getResult() instanceof IPage) { |
|||
List<JSONObject> items = new ArrayList<>(); |
|||
|
|||
//step.1 筛选出加了 Dict 注解的字段列表
|
|||
List<Field> dictFieldList = new ArrayList<>(); |
|||
// 字典数据列表, key = 字典code,value=数据列表
|
|||
Map<String, List<String>> dataListMap = new HashMap<>(5); |
|||
//取出结果集
|
|||
List<Object> records=((IPage) ((Result) result).getResult()).getRecords(); |
|||
//update-begin--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回-----
|
|||
Boolean hasDict= checkHasDict(records); |
|||
if(!hasDict){ |
|||
return result; |
|||
} |
|||
|
|||
log.info(" __ 进入字典翻译切面 DictAspect —— " ); |
|||
//update-end--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回-----
|
|||
for (Object record : records) { |
|||
String json="{}"; |
|||
try { |
|||
//update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
|
|||
//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
|
|||
json = objectMapper.writeValueAsString(record); |
|||
//update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
|
|||
} catch (JsonProcessingException e) { |
|||
log.error("json解析失败"+e.getMessage(),e); |
|||
} |
|||
//update-begin--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----
|
|||
JSONObject item = JSONObject.parseObject(json, Feature.OrderedField); |
|||
//update-end--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----
|
|||
|
|||
//update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
|||
//for (Field field : record.getClass().getDeclaredFields()) {
|
|||
// 遍历所有字段,把字典Code取出来,放到 map 里
|
|||
for (Field field : oConvertUtils.getAllFields(record)) { |
|||
String value = item.getString(field.getName()); |
|||
if (oConvertUtils.isEmpty(value)) { |
|||
continue; |
|||
} |
|||
//update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
|||
if (field.getAnnotation(Dict.class) != null) { |
|||
if (!dictFieldList.contains(field)) { |
|||
dictFieldList.add(field); |
|||
} |
|||
String code = field.getAnnotation(Dict.class).dicCode(); |
|||
String text = field.getAnnotation(Dict.class).dicText(); |
|||
String table = field.getAnnotation(Dict.class).dictTable(); |
|||
|
|||
List<String> dataList; |
|||
String dictCode = code; |
|||
if (!StringUtils.isEmpty(table)) { |
|||
dictCode = String.format("%s,%s,%s", table, text, code); |
|||
} |
|||
dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>()); |
|||
this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(","))); |
|||
} |
|||
//date类型默认转换string格式化日期
|
|||
//update-begin--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
|
|||
//if (JAVA_UTIL_DATE.equals(field.getType().getName())&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
|
|||
//SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|||
// item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
|
|||
//}
|
|||
//update-end--Author:zyf -- Date:20220531 ----for:【issues/#3629】 DictAspect Jackson序列化报错-----
|
|||
} |
|||
items.add(item); |
|||
} |
|||
|
|||
//step.2 调用翻译方法,一次性翻译
|
|||
Map<String, List<DictModel>> translText = this.translateAllDict(dataListMap); |
|||
|
|||
//step.3 将翻译结果填充到返回结果里
|
|||
for (JSONObject record : items) { |
|||
for (Field field : dictFieldList) { |
|||
String code = field.getAnnotation(Dict.class).dicCode(); |
|||
String text = field.getAnnotation(Dict.class).dicText(); |
|||
String table = field.getAnnotation(Dict.class).dictTable(); |
|||
|
|||
String fieldDictCode = code; |
|||
if (!StringUtils.isEmpty(table)) { |
|||
fieldDictCode = String.format("%s,%s,%s", table, text, code); |
|||
} |
|||
|
|||
String value = record.getString(field.getName()); |
|||
if (oConvertUtils.isNotEmpty(value)) { |
|||
List<DictModel> dictModels = translText.get(fieldDictCode); |
|||
if(dictModels==null || dictModels.size()==0){ |
|||
continue; |
|||
} |
|||
|
|||
String textValue = this.translDictText(dictModels, value); |
|||
log.debug(" 字典Val : " + textValue); |
|||
log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue); |
|||
|
|||
// TODO-sun 测试输出,待删
|
|||
log.debug(" ---- dictCode: " + fieldDictCode); |
|||
log.debug(" ---- value: " + value); |
|||
log.debug(" ----- text: " + textValue); |
|||
log.debug(" ---- dictModels: " + JSON.toJSONString(dictModels)); |
|||
|
|||
record.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue); |
|||
} |
|||
} |
|||
} |
|||
|
|||
((IPage) ((Result) result).getResult()).setRecords(items); |
|||
} |
|||
|
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* list 去重添加 |
|||
*/ |
|||
private void listAddAllDeduplicate(List<String> dataList, List<String> addList) { |
|||
// 筛选出dataList中没有的数据
|
|||
List<String> filterList = addList.stream().filter(i -> !dataList.contains(i)).collect(Collectors.toList()); |
|||
dataList.addAll(filterList); |
|||
} |
|||
|
|||
/** |
|||
* 一次性把所有的字典都翻译了 |
|||
* 1. 所有的普通数据字典的所有数据只执行一次SQL |
|||
* 2. 表字典相同的所有数据只执行一次SQL |
|||
* @param dataListMap |
|||
* @return |
|||
*/ |
|||
private Map<String, List<DictModel>> translateAllDict(Map<String, List<String>> dataListMap) { |
|||
// 翻译后的字典文本,key=dictCode
|
|||
Map<String, List<DictModel>> translText = new HashMap<>(5); |
|||
// 需要翻译的数据(有些可以从redis缓存中获取,就不走数据库查询)
|
|||
List<String> needTranslData = new ArrayList<>(); |
|||
//step.1 先通过redis中获取缓存字典数据
|
|||
for (String dictCode : dataListMap.keySet()) { |
|||
List<String> dataList = dataListMap.get(dictCode); |
|||
if (dataList.size() == 0) { |
|||
continue; |
|||
} |
|||
// 表字典需要翻译的数据
|
|||
List<String> needTranslDataTable = new ArrayList<>(); |
|||
for (String s : dataList) { |
|||
String data = s.trim(); |
|||
if (data.length() == 0) { |
|||
continue; //跳过循环
|
|||
} |
|||
if (dictCode.contains(",")) { |
|||
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, data); |
|||
if (redisTemplate.hasKey(keyString)) { |
|||
try { |
|||
String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); |
|||
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); |
|||
list.add(new DictModel(data, text)); |
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage()); |
|||
} |
|||
} else if (!needTranslDataTable.contains(data)) { |
|||
// 去重添加
|
|||
needTranslDataTable.add(data); |
|||
} |
|||
} else { |
|||
String keyString = String.format("sys:cache:dict::%s:%s", dictCode, data); |
|||
if (redisTemplate.hasKey(keyString)) { |
|||
try { |
|||
String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); |
|||
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); |
|||
list.add(new DictModel(data, text)); |
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage()); |
|||
} |
|||
} else if (!needTranslData.contains(data)) { |
|||
// 去重添加
|
|||
needTranslData.add(data); |
|||
} |
|||
} |
|||
|
|||
} |
|||
//step.2 调用数据库翻译表字典
|
|||
if (needTranslDataTable.size() > 0) { |
|||
String[] arr = dictCode.split(","); |
|||
String table = arr[0], text = arr[1], code = arr[2]; |
|||
String values = String.join(",", needTranslDataTable); |
|||
log.info("translateDictFromTableByKeys.dictCode:" + dictCode); |
|||
log.info("translateDictFromTableByKeys.values:" + values); |
|||
List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values); |
|||
log.info("translateDictFromTableByKeys.result:" + texts); |
|||
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); |
|||
list.addAll(texts); |
|||
|
|||
// 做 redis 缓存
|
|||
for (DictModel dict : texts) { |
|||
String redisKey = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, dict.getValue()); |
|||
try { |
|||
// update-begin-author:taoyan date:20211012 for: 字典表翻译注解缓存未更新 issues/3061
|
|||
// 保留5分钟
|
|||
redisTemplate.opsForValue().set(redisKey, dict.getText(), 300, TimeUnit.SECONDS); |
|||
// update-end-author:taoyan date:20211012 for: 字典表翻译注解缓存未更新 issues/3061
|
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage(), e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
//step.3 调用数据库进行翻译普通字典
|
|||
if (needTranslData.size() > 0) { |
|||
List<String> dictCodeList = Arrays.asList(dataListMap.keySet().toArray(new String[]{})); |
|||
// 将不包含逗号的字典code筛选出来,因为带逗号的是表字典,而不是普通的数据字典
|
|||
List<String> filterDictCodes = dictCodeList.stream().filter(key -> !key.contains(",")).collect(Collectors.toList()); |
|||
String dictCodes = String.join(",", filterDictCodes); |
|||
String values = String.join(",", needTranslData); |
|||
log.info("translateManyDict.dictCodes:" + dictCodes); |
|||
log.info("translateManyDict.values:" + values); |
|||
Map<String, List<DictModel>> manyDict = commonApi.translateManyDict(dictCodes, values); |
|||
log.info("translateManyDict.result:" + manyDict); |
|||
for (String dictCode : manyDict.keySet()) { |
|||
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); |
|||
List<DictModel> newList = manyDict.get(dictCode); |
|||
list.addAll(newList); |
|||
|
|||
// 做 redis 缓存
|
|||
for (DictModel dict : newList) { |
|||
String redisKey = String.format("sys:cache:dict::%s:%s", dictCode, dict.getValue()); |
|||
try { |
|||
redisTemplate.opsForValue().set(redisKey, dict.getText()); |
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage(), e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return translText; |
|||
} |
|||
|
|||
/** |
|||
* 字典值替换文本 |
|||
* |
|||
* @param dictModels |
|||
* @param values |
|||
* @return |
|||
*/ |
|||
private String translDictText(List<DictModel> dictModels, String values) { |
|||
List<String> result = new ArrayList<>(); |
|||
|
|||
// 允许多个逗号分隔,允许传数组对象
|
|||
String[] splitVal = values.split(","); |
|||
for (String val : splitVal) { |
|||
String dictText = val; |
|||
for (DictModel dict : dictModels) { |
|||
if (val.equals(dict.getValue())) { |
|||
dictText = dict.getText(); |
|||
break; |
|||
} |
|||
} |
|||
result.add(dictText); |
|||
} |
|||
return String.join(",", result); |
|||
} |
|||
|
|||
/** |
|||
* 翻译字典文本 |
|||
* @param code |
|||
* @param text |
|||
* @param table |
|||
* @param key |
|||
* @return |
|||
*/ |
|||
@Deprecated |
|||
private String translateDictValue(String code, String text, String table, String key) { |
|||
if(oConvertUtils.isEmpty(key)) { |
|||
return null; |
|||
} |
|||
StringBuffer textValue=new StringBuffer(); |
|||
String[] keys = key.split(","); |
|||
for (String k : keys) { |
|||
String tmpValue = null; |
|||
log.debug(" 字典 key : "+ k); |
|||
if (k.trim().length() == 0) { |
|||
continue; //跳过循环
|
|||
} |
|||
//update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
|||
if (!StringUtils.isEmpty(table)){ |
|||
log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code); |
|||
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim()); |
|||
if (redisTemplate.hasKey(keyString)){ |
|||
try { |
|||
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); |
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage()); |
|||
} |
|||
}else { |
|||
tmpValue= commonApi.translateDictFromTable(table,text,code,k.trim()); |
|||
} |
|||
}else { |
|||
String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim()); |
|||
if (redisTemplate.hasKey(keyString)){ |
|||
try { |
|||
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); |
|||
} catch (Exception e) { |
|||
log.warn(e.getMessage()); |
|||
} |
|||
}else { |
|||
tmpValue = commonApi.translateDict(code, k.trim()); |
|||
} |
|||
} |
|||
//update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
|||
|
|||
if (tmpValue != null) { |
|||
if (!"".equals(textValue.toString())) { |
|||
textValue.append(","); |
|||
} |
|||
textValue.append(tmpValue); |
|||
} |
|||
|
|||
} |
|||
return textValue.toString(); |
|||
} |
|||
|
|||
/** |
|||
* 检测返回结果集中是否包含Dict注解 |
|||
* @param records |
|||
* @return |
|||
*/ |
|||
private Boolean checkHasDict(List<Object> records){ |
|||
if(oConvertUtils.isNotEmpty(records) && records.size()>0){ |
|||
for (Field field : oConvertUtils.getAllFields(records.get(0))) { |
|||
if (oConvertUtils.isNotEmpty(field.getAnnotation(Dict.class))) { |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,140 @@ |
|||
package org.jeecg.common.aspect; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.aspectj.lang.annotation.Around; |
|||
import org.aspectj.lang.annotation.Aspect; |
|||
import org.aspectj.lang.annotation.Pointcut; |
|||
import org.aspectj.lang.reflect.MethodSignature; |
|||
import org.jeecg.common.api.CommonAPI; |
|||
import org.jeecg.common.aspect.annotation.PermissionData; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.constant.SymbolConstant; |
|||
import org.jeecg.common.system.query.QueryRuleEnum; |
|||
import org.jeecg.common.system.util.JeecgDataAutorUtils; |
|||
import org.jeecg.common.system.util.JwtUtil; |
|||
import org.jeecg.common.system.vo.SysPermissionDataRuleModel; |
|||
import org.jeecg.common.system.vo.SysUserCacheInfo; |
|||
import org.jeecg.common.util.SpringContextUtils; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Lazy; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.lang.reflect.Method; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 数据权限切面处理类 |
|||
* 当被请求的方法有注解PermissionData时,会在往当前request中写入数据权限信息 |
|||
* @Date 2019年4月10日 |
|||
* @Version: 1.0 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Aspect |
|||
@Component |
|||
@Slf4j |
|||
public class PermissionDataAspect { |
|||
@Lazy |
|||
@Autowired |
|||
private CommonAPI commonApi; |
|||
|
|||
private static final String SPOT_DO = ".do"; |
|||
|
|||
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.PermissionData)") |
|||
public void pointCut() { |
|||
|
|||
} |
|||
|
|||
@Around("pointCut()") |
|||
public Object arround(ProceedingJoinPoint point) throws Throwable{ |
|||
HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); |
|||
MethodSignature signature = (MethodSignature) point.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
PermissionData pd = method.getAnnotation(PermissionData.class); |
|||
String component = pd.pageComponent(); |
|||
String requestMethod = request.getMethod(); |
|||
String requestPath = request.getRequestURI().substring(request.getContextPath().length()); |
|||
requestPath = filterUrl(requestPath); |
|||
//update-begin-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
|
|||
//先判断是否online报表请求
|
|||
// TODO 参数顺序调整有隐患
|
|||
if(requestPath.indexOf(UrlMatchEnum.CGREPORT_DATA.getMatchUrl())>=0){ |
|||
// 获取地址栏参数
|
|||
String urlParamString = request.getParameter(CommonConstant.ONL_REP_URL_PARAM_STR); |
|||
if(oConvertUtils.isNotEmpty(urlParamString)){ |
|||
requestPath+="?"+urlParamString; |
|||
} |
|||
} |
|||
//update-end-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
|
|||
log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod); |
|||
String username = JwtUtil.getUserNameByToken(request); |
|||
//查询数据权限信息
|
|||
//TODO 微服务情况下也得支持缓存机制
|
|||
List<SysPermissionDataRuleModel> dataRules = commonApi.queryPermissionDataRule(component, requestPath, username); |
|||
if(dataRules!=null && dataRules.size()>0) { |
|||
//临时存储
|
|||
JeecgDataAutorUtils.installDataSearchConditon(request, dataRules); |
|||
//TODO 微服务情况下也得支持缓存机制
|
|||
SysUserCacheInfo userinfo = commonApi.getCacheUser(username); |
|||
JeecgDataAutorUtils.installUserInfo(request, userinfo); |
|||
} |
|||
return point.proceed(); |
|||
} |
|||
|
|||
private String filterUrl(String requestPath){ |
|||
String url = ""; |
|||
if(oConvertUtils.isNotEmpty(requestPath)){ |
|||
url = requestPath.replace("\\", "/"); |
|||
url = url.replace("//", "/"); |
|||
if(url.indexOf(SymbolConstant.DOUBLE_SLASH)>=0){ |
|||
url = filterUrl(url); |
|||
} |
|||
/*if(url.startsWith("/")){ |
|||
url=url.substring(1); |
|||
}*/ |
|||
} |
|||
return url; |
|||
} |
|||
|
|||
/** |
|||
* 获取请求地址 |
|||
* @param request |
|||
* @return |
|||
*/ |
|||
@Deprecated |
|||
private String getJgAuthRequsetPath(HttpServletRequest request) { |
|||
String queryString = request.getQueryString(); |
|||
String requestPath = request.getRequestURI(); |
|||
if(oConvertUtils.isNotEmpty(queryString)){ |
|||
requestPath += "?" + queryString; |
|||
} |
|||
// 去掉其他参数(保留一个参数) 例如:loginController.do?login
|
|||
if (requestPath.indexOf(SymbolConstant.AND) > -1) { |
|||
requestPath = requestPath.substring(0, requestPath.indexOf("&")); |
|||
} |
|||
if(requestPath.indexOf(QueryRuleEnum.EQ.getValue())!=-1){ |
|||
if(requestPath.indexOf(SPOT_DO)!=-1){ |
|||
requestPath = requestPath.substring(0,requestPath.indexOf(".do")+3); |
|||
}else{ |
|||
requestPath = requestPath.substring(0,requestPath.indexOf("?")); |
|||
} |
|||
} |
|||
// 去掉项目路径
|
|||
requestPath = requestPath.substring(request.getContextPath().length() + 1); |
|||
return filterUrl(requestPath); |
|||
} |
|||
|
|||
@Deprecated |
|||
private boolean moHuContain(List<String> list,String key){ |
|||
for(String str : list){ |
|||
if(key.contains(str)){ |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,66 @@ |
|||
package org.jeecg.common.aspect; |
|||
|
|||
/** |
|||
* @Author scott |
|||
* @Date 2020/1/14 13:36 |
|||
* @Description: 请求URL与菜单路由URL转换规则(方便于采用菜单路由URL来配置数据权限规则) |
|||
*/ |
|||
public enum UrlMatchEnum { |
|||
/**求URL与菜单路由URL转换规则 /online/cgform/api/getData/ */ |
|||
CGFORM_DATA("/online/cgform/api/getData/", "/online/cgformList/"), |
|||
/**求URL与菜单路由URL转换规则 /online/cgform/api/exportXls/ */ |
|||
CGFORM_EXCEL_DATA("/online/cgform/api/exportXls/", "/online/cgformList/"), |
|||
/**求URL与菜单路由URL转换规则 /online/cgform/api/getTreeData/ */ |
|||
CGFORM_TREE_DATA("/online/cgform/api/getTreeData/", "/online/cgformList/"), |
|||
/**求URL与菜单路由URL转换规则 /online/cgreport/api/getColumnsAndData/ */ |
|||
CGREPORT_DATA("/online/cgreport/api/getColumnsAndData/", "/online/cgreport/"), |
|||
/**求URL与菜单路由URL转换规则 /online/cgreport/api/exportXls/ */ |
|||
CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/"), |
|||
/**求URL与菜单路由URL转换规则 /online/cgreport/api/exportManySheetXls/ */ |
|||
CGREPORT_EXCEL_DATA2("/online/cgreport/api/exportManySheetXls/", "/online/cgreport/"); |
|||
|
|||
UrlMatchEnum(String url, String matchUrl) { |
|||
this.url = url; |
|||
this.matchUrl = matchUrl; |
|||
} |
|||
|
|||
/** |
|||
* Request 请求 URL前缀 |
|||
*/ |
|||
private String url; |
|||
/** |
|||
* 菜单路由 URL前缀 (对应菜单路径) |
|||
*/ |
|||
private String matchUrl; |
|||
|
|||
/** |
|||
* 根据req url 获取到菜单配置路径(前端页面路由URL) |
|||
* |
|||
* @param url |
|||
* @return |
|||
*/ |
|||
public static String getMatchResultByUrl(String url) { |
|||
//获取到枚举
|
|||
UrlMatchEnum[] values = UrlMatchEnum.values(); |
|||
//加强for循环进行遍历操作
|
|||
for (UrlMatchEnum lr : values) { |
|||
//如果遍历获取的type和参数type一致
|
|||
if (url.indexOf(lr.url) != -1) { |
|||
//返回type对象的desc
|
|||
return url.replace(lr.url, lr.matchUrl); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public String getMatchUrl() { |
|||
return matchUrl; |
|||
} |
|||
// public static void main(String[] args) {
|
|||
// /**
|
|||
// * 比如request真实请求URL: /online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a
|
|||
// * 转换匹配路由URL后(对应配置的菜单路径):/online/cgformList/81fcf7d8922d45069b0d5ba983612d3a
|
|||
// */
|
|||
// System.out.println(UrlMatchEnum.getMatchResultByUrl("/online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a"));
|
|||
// }
|
|||
} |
@ -0,0 +1,23 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 通过此注解声明的接口,自动实现字典翻译 |
|||
* |
|||
* @Author scott |
|||
* @email jeecgos@163.com |
|||
* @Date 2022年01月05日 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface AutoDict { |
|||
|
|||
/** |
|||
* 暂时无用 |
|||
* @return |
|||
*/ |
|||
String value() default ""; |
|||
|
|||
} |
@ -0,0 +1,46 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.constant.enums.ModuleType; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 系统日志注解 |
|||
* |
|||
* @Author scott |
|||
* @email jeecgos@163.com |
|||
* @Date 2019年1月14日 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface AutoLog { |
|||
|
|||
/** |
|||
* 日志内容 |
|||
* |
|||
* @return |
|||
*/ |
|||
String value() default ""; |
|||
|
|||
/** |
|||
* 日志类型 |
|||
* |
|||
* @return 0:操作日志;1:登录日志;2:定时任务; |
|||
*/ |
|||
int logType() default CommonConstant.LOG_TYPE_2; |
|||
|
|||
/** |
|||
* 操作日志类型 |
|||
* |
|||
* @return (1查询,2添加,3修改,4删除) |
|||
*/ |
|||
int operateType() default 0; |
|||
|
|||
/** |
|||
* 模块类型 默认为common |
|||
* @return |
|||
*/ |
|||
ModuleType module() default ModuleType.COMMON; |
|||
} |
@ -0,0 +1,33 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
import org.jeecg.common.constant.enums.LowAppAopEnum; |
|||
|
|||
/** |
|||
* 自动注入low_app_id |
|||
* |
|||
* @Author scott |
|||
* @email jeecgos@163.com |
|||
* @Date 2022年01月05日 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface AutoLowApp { |
|||
|
|||
/** |
|||
* 切面类型(add、delete、db_import等其他操作) |
|||
* |
|||
* @return |
|||
*/ |
|||
LowAppAopEnum action(); |
|||
|
|||
/** |
|||
* 业务类型(cgform等) |
|||
* |
|||
* @return |
|||
*/ |
|||
String bizType(); |
|||
|
|||
} |
@ -0,0 +1,42 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
/** |
|||
* 字典注解 |
|||
* @author: dangzhenghui |
|||
* @date: 2019年03月17日-下午9:37:16 |
|||
*/ |
|||
@Target(ElementType.FIELD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
public @interface Dict { |
|||
/** |
|||
* 方法描述: 数据code |
|||
* 作 者: dangzhenghui |
|||
* 日 期: 2019年03月17日-下午9:37:16 |
|||
* |
|||
* @return 返回类型: String |
|||
*/ |
|||
String dicCode(); |
|||
|
|||
/** |
|||
* 方法描述: 数据Text |
|||
* 作 者: dangzhenghui |
|||
* 日 期: 2019年03月17日-下午9:37:16 |
|||
* |
|||
* @return 返回类型: String |
|||
*/ |
|||
String dicText() default ""; |
|||
|
|||
/** |
|||
* 方法描述: 数据字典表 |
|||
* 作 者: dangzhenghui |
|||
* 日 期: 2019年03月17日-下午9:37:16 |
|||
* |
|||
* @return 返回类型: String |
|||
*/ |
|||
String dictTable() default ""; |
|||
} |
@ -0,0 +1,20 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 动态table切换 |
|||
* |
|||
* @author :zyf |
|||
* @date:2020-04-25 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface DynamicTable { |
|||
/** |
|||
* 需要动态解析的表名 |
|||
* @return |
|||
*/ |
|||
String value(); |
|||
} |
@ -0,0 +1,19 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* online请求拦截专用注解 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.TYPE,ElementType.METHOD}) |
|||
@Documented |
|||
public @interface OnlineAuth { |
|||
|
|||
/** |
|||
* 请求关键字,在xxx/code之前的字符串 |
|||
* @return |
|||
*/ |
|||
String value(); |
|||
} |
@ -0,0 +1,29 @@ |
|||
package org.jeecg.common.aspect.annotation; |
|||
|
|||
import java.lang.annotation.Documented; |
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
/** |
|||
* 数据权限注解 |
|||
* @Author taoyan |
|||
* @Date 2019年4月11日 |
|||
*/ |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.TYPE,ElementType.METHOD}) |
|||
@Documented |
|||
public @interface PermissionData { |
|||
/** |
|||
* 暂时没用 |
|||
* @return |
|||
*/ |
|||
String value() default ""; |
|||
|
|||
|
|||
/** |
|||
* 配置菜单的组件路径,用于数据权限 |
|||
*/ |
|||
String pageComponent() default ""; |
|||
} |
@ -0,0 +1,409 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* @Description: 通用常量 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public interface CommonConstant { |
|||
|
|||
/** |
|||
* 正常状态 |
|||
*/ |
|||
Integer STATUS_NORMAL = 0; |
|||
|
|||
/** |
|||
* 禁用状态 |
|||
*/ |
|||
Integer STATUS_DISABLE = -1; |
|||
|
|||
/** |
|||
* 删除标志 |
|||
*/ |
|||
Integer DEL_FLAG_1 = 1; |
|||
|
|||
/** |
|||
* 未删除 |
|||
*/ |
|||
Integer DEL_FLAG_0 = 0; |
|||
|
|||
/** |
|||
* 系统日志类型: 登录 |
|||
*/ |
|||
int LOG_TYPE_1 = 1; |
|||
|
|||
/** |
|||
* 系统日志类型: 操作 |
|||
*/ |
|||
int LOG_TYPE_2 = 2; |
|||
|
|||
/** |
|||
* 操作日志类型: 查询 |
|||
*/ |
|||
int OPERATE_TYPE_1 = 1; |
|||
|
|||
/** |
|||
* 操作日志类型: 添加 |
|||
*/ |
|||
int OPERATE_TYPE_2 = 2; |
|||
|
|||
/** |
|||
* 操作日志类型: 更新 |
|||
*/ |
|||
int OPERATE_TYPE_3 = 3; |
|||
|
|||
/** |
|||
* 操作日志类型: 删除 |
|||
*/ |
|||
int OPERATE_TYPE_4 = 4; |
|||
|
|||
/** |
|||
* 操作日志类型: 倒入 |
|||
*/ |
|||
int OPERATE_TYPE_5 = 5; |
|||
|
|||
/** |
|||
* 操作日志类型: 导出 |
|||
*/ |
|||
int OPERATE_TYPE_6 = 6; |
|||
|
|||
|
|||
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */ |
|||
Integer SC_INTERNAL_SERVER_ERROR_500 = 500; |
|||
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */ |
|||
Integer SC_OK_200 = 200; |
|||
|
|||
/**访问权限认证未通过 510*/ |
|||
Integer SC_JEECG_NO_AUTHZ=510; |
|||
|
|||
/** 登录用户Shiro权限缓存KEY前缀 */ |
|||
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:"; |
|||
/** 登录用户Token令牌缓存KEY前缀 */ |
|||
String PREFIX_USER_TOKEN = "prefix_user_token_"; |
|||
// /** Token缓存时间:3600秒即一小时 */
|
|||
// int TOKEN_EXPIRE_TIME = 3600;
|
|||
|
|||
/** 登录二维码 */ |
|||
String LOGIN_QRCODE_PRE = "QRCODELOGIN:"; |
|||
String LOGIN_QRCODE = "LQ:"; |
|||
/** 登录二维码token */ |
|||
String LOGIN_QRCODE_TOKEN = "LQT:"; |
|||
|
|||
|
|||
/** |
|||
* 0:一级菜单 |
|||
*/ |
|||
Integer MENU_TYPE_0 = 0; |
|||
/** |
|||
* 1:子菜单 |
|||
*/ |
|||
Integer MENU_TYPE_1 = 1; |
|||
/** |
|||
* 2:按钮权限 |
|||
*/ |
|||
Integer MENU_TYPE_2 = 2; |
|||
|
|||
/**通告对象类型(USER:指定用户,ALL:全体用户)*/ |
|||
String MSG_TYPE_UESR = "USER"; |
|||
String MSG_TYPE_ALL = "ALL"; |
|||
|
|||
/**发布状态(0未发布,1已发布,2已撤销)*/ |
|||
String NO_SEND = "0"; |
|||
String HAS_SEND = "1"; |
|||
String HAS_CANCLE = "2"; |
|||
|
|||
/**阅读状态(0未读,1已读)*/ |
|||
String HAS_READ_FLAG = "1"; |
|||
String NO_READ_FLAG = "0"; |
|||
|
|||
/**优先级(L低,M中,H高)*/ |
|||
String PRIORITY_L = "L"; |
|||
String PRIORITY_M = "M"; |
|||
String PRIORITY_H = "H"; |
|||
|
|||
/** |
|||
* 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 |
|||
*/ |
|||
String SMS_TPL_TYPE_0 = "0"; |
|||
String SMS_TPL_TYPE_1 = "1"; |
|||
String SMS_TPL_TYPE_2 = "2"; |
|||
|
|||
/** |
|||
* 状态(0无效1有效) |
|||
*/ |
|||
String STATUS_0 = "0"; |
|||
String STATUS_1 = "1"; |
|||
|
|||
/** |
|||
* 同步工作流引擎1同步0不同步 |
|||
*/ |
|||
Integer ACT_SYNC_1 = 1; |
|||
Integer ACT_SYNC_0 = 0; |
|||
|
|||
/** |
|||
* 消息类型1:通知公告2:系统消息 |
|||
*/ |
|||
String MSG_CATEGORY_1 = "1"; |
|||
String MSG_CATEGORY_2 = "2"; |
|||
|
|||
/** |
|||
* 是否配置菜单的数据权限 1是0否 |
|||
*/ |
|||
Integer RULE_FLAG_0 = 0; |
|||
Integer RULE_FLAG_1 = 1; |
|||
|
|||
/** |
|||
* 是否用户已被冻结 1正常(解冻) 2冻结 |
|||
*/ |
|||
Integer USER_UNFREEZE = 1; |
|||
Integer USER_FREEZE = 2; |
|||
|
|||
/**字典翻译文本后缀*/ |
|||
String DICT_TEXT_SUFFIX = "_dictText"; |
|||
|
|||
/** |
|||
* 表单设计器主表类型 |
|||
*/ |
|||
Integer DESIGN_FORM_TYPE_MAIN = 1; |
|||
|
|||
/** |
|||
* 表单设计器子表表类型 |
|||
*/ |
|||
Integer DESIGN_FORM_TYPE_SUB = 2; |
|||
|
|||
/** |
|||
* 表单设计器URL授权通过 |
|||
*/ |
|||
Integer DESIGN_FORM_URL_STATUS_PASSED = 1; |
|||
|
|||
/** |
|||
* 表单设计器URL授权未通过 |
|||
*/ |
|||
Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2; |
|||
|
|||
/** |
|||
* 表单设计器新增 Flag |
|||
*/ |
|||
String DESIGN_FORM_URL_TYPE_ADD = "add"; |
|||
/** |
|||
* 表单设计器修改 Flag |
|||
*/ |
|||
String DESIGN_FORM_URL_TYPE_EDIT = "edit"; |
|||
/** |
|||
* 表单设计器详情 Flag |
|||
*/ |
|||
String DESIGN_FORM_URL_TYPE_DETAIL = "detail"; |
|||
/** |
|||
* 表单设计器复用数据 Flag |
|||
*/ |
|||
String DESIGN_FORM_URL_TYPE_REUSE = "reuse"; |
|||
/** |
|||
* 表单设计器编辑 Flag (已弃用) |
|||
*/ |
|||
String DESIGN_FORM_URL_TYPE_VIEW = "view"; |
|||
|
|||
/** |
|||
* online参数值设置(是:Y, 否:N) |
|||
*/ |
|||
String ONLINE_PARAM_VAL_IS_TURE = "Y"; |
|||
String ONLINE_PARAM_VAL_IS_FALSE = "N"; |
|||
|
|||
/** |
|||
* 文件上传类型(本地:local,Minio:minio,阿里云:alioss) |
|||
*/ |
|||
String UPLOAD_TYPE_LOCAL = "local"; |
|||
String UPLOAD_TYPE_MINIO = "minio"; |
|||
String UPLOAD_TYPE_OSS = "alioss"; |
|||
|
|||
/** |
|||
* 文档上传自定义桶名称 |
|||
*/ |
|||
String UPLOAD_CUSTOM_BUCKET = "eoafile"; |
|||
/** |
|||
* 文档上传自定义路径 |
|||
*/ |
|||
String UPLOAD_CUSTOM_PATH = "eoafile"; |
|||
/** |
|||
* 文件外链接有效天数 |
|||
*/ |
|||
Integer UPLOAD_EFFECTIVE_DAYS = 1; |
|||
|
|||
/** |
|||
* 员工身份 (1:普通员工 2:上级) |
|||
*/ |
|||
Integer USER_IDENTITY_1 = 1; |
|||
Integer USER_IDENTITY_2 = 2; |
|||
|
|||
/** sys_user 表 username 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username"; |
|||
/** sys_user 表 work_no 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no"; |
|||
/** sys_user 表 phone 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone"; |
|||
/** 达梦数据库升提示。违反表[SYS_USER]唯一性约束 */ |
|||
String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束"; |
|||
|
|||
/** sys_user 表 email 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email"; |
|||
/** sys_quartz_job 表 job_class_name 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name"; |
|||
/** sys_position 表 code 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_CODE = "uniq_code"; |
|||
/** sys_role 表 code 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code"; |
|||
/** sys_depart 表 code 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code"; |
|||
/** sys_category 表 code 唯一键索引 */ |
|||
String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code"; |
|||
/** |
|||
* 在线聊天 是否为默认分组 |
|||
*/ |
|||
String IM_DEFAULT_GROUP = "1"; |
|||
/** |
|||
* 在线聊天 图片文件保存路径 |
|||
*/ |
|||
String IM_UPLOAD_CUSTOM_PATH = "imfile"; |
|||
/** |
|||
* 在线聊天 用户状态 |
|||
*/ |
|||
String IM_STATUS_ONLINE = "online"; |
|||
|
|||
/** |
|||
* 在线聊天 SOCKET消息类型 |
|||
*/ |
|||
String IM_SOCKET_TYPE = "chatMessage"; |
|||
|
|||
/** |
|||
* 在线聊天 是否开启默认添加好友 1是 0否 |
|||
*/ |
|||
String IM_DEFAULT_ADD_FRIEND = "1"; |
|||
|
|||
/** |
|||
* 在线聊天 用户好友缓存前缀 |
|||
*/ |
|||
String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_"; |
|||
|
|||
/** |
|||
* 考勤补卡业务状态 (1:同意 2:不同意) |
|||
*/ |
|||
String SIGN_PATCH_BIZ_STATUS_1 = "1"; |
|||
String SIGN_PATCH_BIZ_STATUS_2 = "2"; |
|||
|
|||
/** |
|||
* 公文文档上传自定义路径 |
|||
*/ |
|||
String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc"; |
|||
/** |
|||
* 公文文档下载自定义路径 |
|||
*/ |
|||
String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown"; |
|||
|
|||
/** |
|||
* WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板)) |
|||
*/ |
|||
String WPS_TYPE_1="1"; |
|||
String WPS_TYPE_2="2"; |
|||
|
|||
|
|||
/**===============================================================================================*/ |
|||
/** |
|||
* ::非常重要:: |
|||
* 注意:这四个常量值如果修改,需要与 jeecg-boot-starter/jeecg-boot-common/org.jeecg.config.FeignConfig 类中的值保持一致。 |
|||
*/ |
|||
String X_ACCESS_TOKEN = "X-Access-Token"; |
|||
String X_SIGN = "X-Sign"; |
|||
String X_TIMESTAMP = "X-TIMESTAMP"; |
|||
/** 租户 请求头*/ |
|||
String TENANT_ID = "tenant-id"; |
|||
/**===============================================================================================*/ |
|||
|
|||
String TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!"; |
|||
String X_FORWARDED_SCHEME = "X-Forwarded-Scheme"; |
|||
|
|||
|
|||
/** |
|||
* 微服务读取配置文件属性 服务地址 |
|||
*/ |
|||
String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr"; |
|||
|
|||
/** |
|||
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用 |
|||
*/ |
|||
String THIRD_LOGIN_CODE = "third_login_code"; |
|||
|
|||
/** |
|||
* 第三方APP同步方向:本地 --> 第三方APP |
|||
*/ |
|||
String THIRD_SYNC_TO_APP = "SYNC_TO_APP"; |
|||
/** |
|||
* 第三方APP同步方向:第三方APP --> 本地 |
|||
*/ |
|||
String THIRD_SYNC_TO_LOCAL = "SYNC_TO_LOCAL"; |
|||
|
|||
/** 系统通告消息状态:0=未发布 */ |
|||
String ANNOUNCEMENT_SEND_STATUS_0 = "0"; |
|||
/** 系统通告消息状态:1=已发布 */ |
|||
String ANNOUNCEMENT_SEND_STATUS_1 = "1"; |
|||
/** 系统通告消息状态:2=已撤销 */ |
|||
String ANNOUNCEMENT_SEND_STATUS_2 = "2"; |
|||
|
|||
/**ONLINE 报表权限用 从request中获取地址栏后的参数*/ |
|||
String ONL_REP_URL_PARAM_STR="onlRepUrlParamStr"; |
|||
|
|||
/**POST请求*/ |
|||
String HTTP_POST = "POST"; |
|||
|
|||
/**PUT请求*/ |
|||
String HTTP_PUT = "PUT"; |
|||
|
|||
/**PATCH请求*/ |
|||
String HTTP_PATCH = "PATCH"; |
|||
|
|||
/**未知的*/ |
|||
String UNKNOWN = "unknown"; |
|||
|
|||
/**字符串http*/ |
|||
String STR_HTTP = "http"; |
|||
|
|||
/**String 类型的空值*/ |
|||
String STRING_NULL = "null"; |
|||
|
|||
/**前端vue3版本Header参数名*/ |
|||
String VERSION="X-Version"; |
|||
|
|||
/**存储在线程变量里的动态表名*/ |
|||
String DYNAMIC_TABLE_NAME="DYNAMIC_TABLE_NAME"; |
|||
/** |
|||
* http:// http协议
|
|||
*/ |
|||
String HTTP_PROTOCOL = "http://"; |
|||
|
|||
/** |
|||
* https:// https协议
|
|||
*/ |
|||
String HTTPS_PROTOCOL = "https://"; |
|||
|
|||
/** 部门表唯一key,id */ |
|||
String DEPART_KEY_ID = "id"; |
|||
/** 部门表唯一key,orgCode */ |
|||
String DEPART_KEY_ORG_CODE = "orgCode"; |
|||
|
|||
/** |
|||
* 发消息 会传递一些信息到map |
|||
*/ |
|||
String NOTICE_MSG_SUMMARY = "NOTICE_MSG_SUMMARY"; |
|||
|
|||
/** |
|||
* 发消息 会传递一个业务ID到map |
|||
*/ |
|||
String NOTICE_MSG_BUS_ID = "NOTICE_MSG_BUS_ID"; |
|||
|
|||
/** |
|||
* 邮箱消息中地址登录时地址后携带的token,需要替换成真实的token值 |
|||
*/ |
|||
String LOGIN_TOKEN = "{LOGIN_TOKEN}"; |
|||
|
|||
/** |
|||
* 模板消息中 跳转地址的对应的key |
|||
*/ |
|||
String MSG_HREF_URL = "url"; |
|||
} |
@ -0,0 +1,37 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* 系统通告 - 发布状态 |
|||
* @Author LeeShaoQing |
|||
* |
|||
*/ |
|||
public interface CommonSendStatus { |
|||
|
|||
/** |
|||
* 未发布 |
|||
*/ |
|||
public static final String UNPUBLISHED_STATUS_0 = "0"; |
|||
|
|||
/** |
|||
* 已发布 |
|||
*/ |
|||
public static final String PUBLISHED_STATUS_1 = "1"; |
|||
|
|||
/** |
|||
* 撤销 |
|||
*/ |
|||
public static final String REVOKE_STATUS_2 = "2"; |
|||
|
|||
/** |
|||
* app端推送会话标识后缀 |
|||
*/ |
|||
public static final String APP_SESSION_SUFFIX = "_app"; |
|||
|
|||
|
|||
/**流程催办——系统通知消息模板*/ |
|||
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban"; |
|||
/**标准模板—系统消息通知*/ |
|||
public static final String TZMB_SYS_TS_NOTE = "sys_ts_note"; |
|||
/**流程超时提醒——系统通知消息模板*/ |
|||
public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip"; |
|||
} |
@ -0,0 +1,166 @@ |
|||
package org.jeecg.common.constant; |
|||
/** |
|||
* 数据库上下文常量 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public interface DataBaseConstant { |
|||
//*********数据库类型****************************************
|
|||
|
|||
/**MYSQL数据库*/ |
|||
public static final String DB_TYPE_MYSQL = "MYSQL"; |
|||
|
|||
/** ORACLE*/ |
|||
public static final String DB_TYPE_ORACLE = "ORACLE"; |
|||
|
|||
/**达梦数据库*/ |
|||
public static final String DB_TYPE_DM = "DM"; |
|||
|
|||
/**postgreSQL达梦数据库*/ |
|||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL"; |
|||
|
|||
/**sqlserver数据库*/ |
|||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER"; |
|||
|
|||
/**mariadb 数据库*/ |
|||
public static final String DB_TYPE_MARIADB = "MARIADB"; |
|||
|
|||
/**DB2 数据库*/ |
|||
public static final String DB_TYPE_DB2 = "DB2"; |
|||
|
|||
/**HSQL 数据库*/ |
|||
public static final String DB_TYPE_HSQL = "HSQL"; |
|||
|
|||
// // 数据库类型,对应 database_type 字典
|
|||
// public static final String DB_TYPE_MYSQL_NUM = "1";
|
|||
// public static final String DB_TYPE_MYSQL7_NUM = "6";
|
|||
// public static final String DB_TYPE_ORACLE_NUM = "2";
|
|||
// public static final String DB_TYPE_SQLSERVER_NUM = "3";
|
|||
// public static final String DB_TYPE_POSTGRESQL_NUM = "4";
|
|||
// public static final String DB_TYPE_MARIADB_NUM = "5";
|
|||
|
|||
//*********系统上下文变量****************************************
|
|||
/** |
|||
* 数据-所属机构编码 |
|||
*/ |
|||
public static final String SYS_ORG_CODE = "sysOrgCode"; |
|||
/** |
|||
* 数据-所属机构编码 |
|||
*/ |
|||
public static final String SYS_ORG_CODE_TABLE = "sys_org_code"; |
|||
/** |
|||
* 数据-所属机构编码 |
|||
*/ |
|||
public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode"; |
|||
/** |
|||
* 数据-所属机构编码 |
|||
*/ |
|||
public static final String SYS_MULTI_ORG_CODE_TABLE = "sys_multi_org_code"; |
|||
/** |
|||
* 数据-系统用户编码(对应登录用户账号) |
|||
*/ |
|||
public static final String SYS_USER_CODE = "sysUserCode"; |
|||
/** |
|||
* 数据-系统用户编码(对应登录用户账号) |
|||
*/ |
|||
public static final String SYS_USER_CODE_TABLE = "sys_user_code"; |
|||
|
|||
/** |
|||
* 登录用户真实姓名 |
|||
*/ |
|||
public static final String SYS_USER_NAME = "sysUserName"; |
|||
/** |
|||
* 登录用户真实姓名 |
|||
*/ |
|||
public static final String SYS_USER_NAME_TABLE = "sys_user_name"; |
|||
/** |
|||
* 系统日期"yyyy-MM-dd" |
|||
*/ |
|||
public static final String SYS_DATE = "sysDate"; |
|||
/** |
|||
* 系统日期"yyyy-MM-dd" |
|||
*/ |
|||
public static final String SYS_DATE_TABLE = "sys_date"; |
|||
/** |
|||
* 系统时间"yyyy-MM-dd HH:mm" |
|||
*/ |
|||
public static final String SYS_TIME = "sysTime"; |
|||
/** |
|||
* 系统时间"yyyy-MM-dd HH:mm" |
|||
*/ |
|||
public static final String SYS_TIME_TABLE = "sys_time"; |
|||
/** |
|||
* 数据-所属机构编码 |
|||
*/ |
|||
public static final String SYS_BASE_PATH = "sys_base_path"; |
|||
//*********系统上下文变量****************************************
|
|||
|
|||
|
|||
//*********系统建表标准字段****************************************
|
|||
/** |
|||
* 创建者登录名称 |
|||
*/ |
|||
public static final String CREATE_BY_TABLE = "create_by"; |
|||
/** |
|||
* 创建者登录名称 |
|||
*/ |
|||
public static final String CREATE_BY = "createBy"; |
|||
/** |
|||
* 创建日期时间 |
|||
*/ |
|||
public static final String CREATE_TIME_TABLE = "create_time"; |
|||
/** |
|||
* 创建日期时间 |
|||
*/ |
|||
public static final String CREATE_TIME = "createTime"; |
|||
/** |
|||
* 更新用户登录名称 |
|||
*/ |
|||
public static final String UPDATE_BY_TABLE = "update_by"; |
|||
/** |
|||
* 更新用户登录名称 |
|||
*/ |
|||
public static final String UPDATE_BY = "updateBy"; |
|||
/** |
|||
* 更新日期时间 |
|||
*/ |
|||
public static final String UPDATE_TIME = "updateTime"; |
|||
/** |
|||
* 更新日期时间 |
|||
*/ |
|||
public static final String UPDATE_TIME_TABLE = "update_time"; |
|||
|
|||
/** |
|||
* 业务流程状态 |
|||
*/ |
|||
public static final String BPM_STATUS = "bpmStatus"; |
|||
/** |
|||
* 业务流程状态 |
|||
*/ |
|||
public static final String BPM_STATUS_TABLE = "bpm_status"; |
|||
//*********系统建表标准字段****************************************
|
|||
|
|||
|
|||
/** |
|||
* 租户ID 实体字段名 |
|||
*/ |
|||
String TENANT_ID = "tenantId"; |
|||
/** |
|||
* 租户ID 数据库字段名 |
|||
*/ |
|||
String TENANT_ID_TABLE = "tenant_id"; |
|||
|
|||
/** |
|||
* sql语句 where |
|||
*/ |
|||
String SQL_WHERE = "where"; |
|||
|
|||
/** |
|||
* sql语句 asc |
|||
*/ |
|||
String SQL_ASC = "asc"; |
|||
|
|||
/** |
|||
* sqlserver数据库,中间有空格 |
|||
*/ |
|||
String DB_TYPE_SQL_SERVER_BLANK = "sql server"; |
|||
} |
@ -0,0 +1,16 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* 动态切换表配置常量 |
|||
* |
|||
* @author: scott |
|||
* @date: 2022年04月25日 22:30 |
|||
*/ |
|||
public class DynamicTableConstant { |
|||
/** |
|||
* 角色首页配置表 |
|||
* vue2表名: sys_role_index |
|||
* vue3表名: sys_role_index_vue3 |
|||
*/ |
|||
public static final String SYS_ROLE_INDEX = "sys_role_index"; |
|||
} |
@ -0,0 +1,25 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* 规则值生成 编码常量类 |
|||
* @author: taoyan |
|||
* @date: 2020年04月02日 |
|||
*/ |
|||
public class FillRuleConstant { |
|||
|
|||
/** |
|||
* 公文发文编码 |
|||
*/ |
|||
public static final String DOC_SEND = "doc_send_code"; |
|||
|
|||
/** |
|||
* 部门编码 |
|||
*/ |
|||
public static final String DEPART = "org_num_role"; |
|||
|
|||
/** |
|||
* 分类字典编码 |
|||
*/ |
|||
public static final String CATEGORY = "category_code_rule"; |
|||
|
|||
} |
@ -0,0 +1,218 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
import com.alibaba.fastjson.JSONObject; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.core.io.Resource; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.util.ArrayList; |
|||
import java.util.Scanner; |
|||
import java.util.Set; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @Description: 省市区 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Component("pca") |
|||
public class ProvinceCityArea { |
|||
List<Area> areaList; |
|||
|
|||
public String getText(String code){ |
|||
this.initAreaList(); |
|||
if(this.areaList!=null || this.areaList.size()>0){ |
|||
List<String> ls = new ArrayList<String>(); |
|||
getAreaByCode(code,ls); |
|||
return String.join("/",ls); |
|||
} |
|||
return ""; |
|||
} |
|||
|
|||
public String getCode(String text){ |
|||
this.initAreaList(); |
|||
if(areaList!=null && areaList.size()>0){ |
|||
for(int i=areaList.size()-1;i>=0;i--){ |
|||
//update-begin-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
|||
String areaText = areaList.get(i).getText(); |
|||
String cityText = areaList.get(i).getAheadText(); |
|||
if(text.indexOf(areaText)>=0 && (cityText!=null && text.indexOf(cityText)>=0)){ |
|||
return areaList.get(i).getId(); |
|||
} |
|||
//update-end-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
// update-begin-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
|
|||
/** |
|||
* 获取省市区code,精准匹配 |
|||
* @param texts 文本数组,省,市,区 |
|||
* @return 返回 省市区的code |
|||
*/ |
|||
public String[] getCode(String[] texts) { |
|||
if (texts == null || texts.length == 0) { |
|||
return null; |
|||
} |
|||
this.initAreaList(); |
|||
if (areaList == null || areaList.size() == 0) { |
|||
return null; |
|||
} |
|||
String[] codes = new String[texts.length]; |
|||
String code = null; |
|||
for (int i = 0; i < texts.length; i++) { |
|||
String text = texts[i]; |
|||
Area area; |
|||
if (code == null) { |
|||
area = getAreaByText(text); |
|||
} else { |
|||
area = getAreaByPidAndText(code, text); |
|||
} |
|||
if (area != null) { |
|||
code = area.id; |
|||
codes[i] = code; |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
return codes; |
|||
} |
|||
|
|||
/** |
|||
* 根据text获取area |
|||
* @param text |
|||
* @return |
|||
*/ |
|||
public Area getAreaByText(String text) { |
|||
for (Area area : areaList) { |
|||
if (text.equals(area.getText())) { |
|||
return area; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 通过pid获取 area 对象 |
|||
* @param pCode 父级编码 |
|||
* @param text |
|||
* @return |
|||
*/ |
|||
public Area getAreaByPidAndText(String pCode, String text) { |
|||
this.initAreaList(); |
|||
if (this.areaList != null && this.areaList.size() > 0) { |
|||
for (Area area : this.areaList) { |
|||
if (area.getPid().equals(pCode) && area.getText().equals(text)) { |
|||
return area; |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
// update-end-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
|
|||
|
|||
public void getAreaByCode(String code,List<String> ls){ |
|||
for(Area area: areaList){ |
|||
if(area.getId().equals(code)){ |
|||
String pid = area.getPid(); |
|||
ls.add(0,area.getText()); |
|||
getAreaByCode(pid,ls); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void initAreaList(){ |
|||
//System.out.println("=====================");
|
|||
if(this.areaList==null || this.areaList.size()==0){ |
|||
this.areaList = new ArrayList<Area>(); |
|||
try { |
|||
String jsonData = oConvertUtils.readStatic("classpath:static/pca.json"); |
|||
JSONObject baseJson = JSONObject.parseObject(jsonData); |
|||
//第一层 省
|
|||
JSONObject provinceJson = baseJson.getJSONObject("86"); |
|||
for(String provinceKey: provinceJson.keySet()){ |
|||
//System.out.println("===="+provinceKey);
|
|||
Area province = new Area(provinceKey,provinceJson.getString(provinceKey),"86"); |
|||
this.areaList.add(province); |
|||
//第二层 市
|
|||
JSONObject cityJson = baseJson.getJSONObject(provinceKey); |
|||
for(String cityKey:cityJson.keySet()){ |
|||
//System.out.println("-----"+cityKey);
|
|||
Area city = new Area(cityKey,cityJson.getString(cityKey),provinceKey); |
|||
this.areaList.add(city); |
|||
//第三层 区
|
|||
JSONObject areaJson = baseJson.getJSONObject(cityKey); |
|||
if(areaJson!=null){ |
|||
for(String areaKey:areaJson.keySet()){ |
|||
//System.out.println("········"+areaKey);
|
|||
Area area = new Area(areaKey,areaJson.getString(areaKey),cityKey); |
|||
//update-begin-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
|||
area.setAheadText(cityJson.getString(cityKey)); |
|||
//update-end-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
|||
this.areaList.add(area); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
private String jsonRead(File file){ |
|||
Scanner scanner = null; |
|||
StringBuilder buffer = new StringBuilder(); |
|||
try { |
|||
scanner = new Scanner(file, "utf-8"); |
|||
while (scanner.hasNextLine()) { |
|||
buffer.append(scanner.nextLine()); |
|||
} |
|||
} catch (Exception e) { |
|||
|
|||
} finally { |
|||
if (scanner != null) { |
|||
scanner.close(); |
|||
} |
|||
} |
|||
return buffer.toString(); |
|||
} |
|||
|
|||
class Area{ |
|||
String id; |
|||
String text; |
|||
String pid; |
|||
// 用于存储上级文本数据,区的上级文本 是市的数据
|
|||
String aheadText; |
|||
|
|||
public Area(String id,String text,String pid){ |
|||
this.id = id; |
|||
this.text = text; |
|||
this.pid = pid; |
|||
} |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public String getText() { |
|||
return text; |
|||
} |
|||
|
|||
public String getPid() { |
|||
return pid; |
|||
} |
|||
|
|||
public String getAheadText() { |
|||
return aheadText; |
|||
} |
|||
public void setAheadText(String aheadText) { |
|||
this.aheadText = aheadText; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
/* |
|||
* |
|||
* * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com). |
|||
* * <p> |
|||
* * Licensed under the GNU Lesser General Public License 3.0 (the "License"); |
|||
* * you may not use this file except in compliance with the License. |
|||
* * You may obtain a copy of the License at |
|||
* * <p> |
|||
* * https://www.gnu.org/licenses/lgpl.html
|
|||
* * <p> |
|||
* * Unless required by applicable law or agreed to in writing, software |
|||
* * distributed under the License is distributed on an "AS IS" BASIS, |
|||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* * See the License for the specific language governing permissions and |
|||
* * limitations under the License. |
|||
* |
|||
*/ |
|||
|
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* @author scott |
|||
* @date 2019年05月18日 |
|||
* 服务名称 |
|||
*/ |
|||
public interface ServiceNameConstants { |
|||
|
|||
/** |
|||
* 微服务名:系统管理模块 |
|||
*/ |
|||
String SERVICE_SYSTEM = "jeecg-system"; |
|||
/** |
|||
* 微服务名:Demo模块 |
|||
*/ |
|||
String SERVICE_DEMO = "jeecg-demo"; |
|||
|
|||
/** |
|||
* gateway通过header传递根路径 basePath |
|||
*/ |
|||
String X_GATEWAY_BASE_PATH = "X_GATEWAY_BASE_PATH"; |
|||
|
|||
} |
@ -0,0 +1,119 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* @Description: 符号和特殊符号常用类 |
|||
* @author: wangshuai |
|||
* @date: 2022年03月30日 17:44 |
|||
*/ |
|||
public class SymbolConstant { |
|||
|
|||
/** |
|||
* 符号:点 |
|||
*/ |
|||
public static final String SPOT = "."; |
|||
|
|||
/** |
|||
* 符号:双斜杠 |
|||
*/ |
|||
public static final String DOUBLE_BACKSLASH = "\\"; |
|||
|
|||
/** |
|||
* 符号:冒号 |
|||
*/ |
|||
public static final String COLON = ":"; |
|||
|
|||
/** |
|||
* 符号:逗号 |
|||
*/ |
|||
public static final String COMMA = ","; |
|||
|
|||
/** |
|||
* 符号:左花括号 } |
|||
*/ |
|||
public static final String LEFT_CURLY_BRACKET = "{"; |
|||
|
|||
/** |
|||
* 符号:右花括号 } |
|||
*/ |
|||
public static final String RIGHT_CURLY_BRACKET = "}"; |
|||
|
|||
/** |
|||
* 符号:井号 # |
|||
*/ |
|||
public static final String WELL_NUMBER = "#"; |
|||
|
|||
/** |
|||
* 符号:单斜杠 |
|||
*/ |
|||
public static final String SINGLE_SLASH = "/"; |
|||
|
|||
/** |
|||
* 符号:双斜杠 |
|||
*/ |
|||
public static final String DOUBLE_SLASH = "//"; |
|||
|
|||
/** |
|||
* 符号:感叹号 |
|||
*/ |
|||
public static final String EXCLAMATORY_MARK = "!"; |
|||
|
|||
/** |
|||
* 符号:下划线 |
|||
*/ |
|||
public static final String UNDERLINE = "_"; |
|||
|
|||
/** |
|||
* 符号:单引号 |
|||
*/ |
|||
public static final String SINGLE_QUOTATION_MARK = "'"; |
|||
|
|||
/** |
|||
* 符号:星号 |
|||
*/ |
|||
public static final String ASTERISK = "*"; |
|||
|
|||
/** |
|||
* 符号:百分号 |
|||
*/ |
|||
public static final String PERCENT_SIGN = "%"; |
|||
|
|||
/** |
|||
* 符号:美元 $ |
|||
*/ |
|||
public static final String DOLLAR = "$"; |
|||
|
|||
/** |
|||
* 符号:和 & |
|||
*/ |
|||
public static final String AND = "&"; |
|||
|
|||
/** |
|||
* 符号:../ |
|||
*/ |
|||
public static final String SPOT_SINGLE_SLASH = "../"; |
|||
|
|||
/** |
|||
* 符号:..\\ |
|||
*/ |
|||
public static final String SPOT_DOUBLE_BACKSLASH = "..\\"; |
|||
|
|||
/** |
|||
* 系统变量前缀 #{ |
|||
*/ |
|||
public static final String SYS_VAR_PREFIX = "#{"; |
|||
|
|||
/** |
|||
* 符号 {{ |
|||
*/ |
|||
public static final String DOUBLE_LEFT_CURLY_BRACKET = "{{"; |
|||
|
|||
/** |
|||
* 符号:[ |
|||
*/ |
|||
public static final String SQUARE_BRACKETS_LEFT = "["; |
|||
/** |
|||
* 符号:] |
|||
*/ |
|||
public static final String SQUARE_BRACKETS_RIGHT = "]"; |
|||
|
|||
} |
@ -0,0 +1,33 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* VXESocket 常量 |
|||
* |
|||
* update: 【类名改了大小写】 date: 2022-04-18 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public class VxeSocketConst { |
|||
|
|||
/** |
|||
* 消息类型 |
|||
*/ |
|||
public static final String TYPE = "type"; |
|||
/** |
|||
* 消息数据 |
|||
*/ |
|||
public static final String DATA = "data"; |
|||
|
|||
/** |
|||
* 消息类型:心跳检测 |
|||
*/ |
|||
public static final String TYPE_HB = "heart_beat"; |
|||
/** |
|||
* 消息类型:通用数据传递 |
|||
*/ |
|||
public static final String TYPE_CSD = "common_send_date"; |
|||
/** |
|||
* 消息类型:更新vxe table数据 |
|||
*/ |
|||
public static final String TYPE_UVT = "update_vxe_table"; |
|||
|
|||
} |
@ -0,0 +1,61 @@ |
|||
package org.jeecg.common.constant; |
|||
|
|||
/** |
|||
* @Description: Websocket常量类 |
|||
* @author: taoyan |
|||
* @date: 2020年03月23日 |
|||
*/ |
|||
public class WebsocketConst { |
|||
|
|||
|
|||
/** |
|||
* 消息json key:cmd |
|||
*/ |
|||
public static final String MSG_CMD = "cmd"; |
|||
|
|||
/** |
|||
* 消息json key:msgId |
|||
*/ |
|||
public static final String MSG_ID = "msgId"; |
|||
|
|||
/** |
|||
* 消息json key:msgTxt |
|||
*/ |
|||
public static final String MSG_TXT = "msgTxt"; |
|||
|
|||
/** |
|||
* 消息json key:userId |
|||
*/ |
|||
public static final String MSG_USER_ID = "userId"; |
|||
|
|||
/** |
|||
* 消息类型 heartcheck |
|||
*/ |
|||
public static final String CMD_CHECK = "heartcheck"; |
|||
|
|||
/** |
|||
* 消息类型 user 用户消息 |
|||
*/ |
|||
public static final String CMD_USER = "user"; |
|||
|
|||
/** |
|||
* 消息类型 topic 系统通知 |
|||
*/ |
|||
public static final String CMD_TOPIC = "topic"; |
|||
|
|||
/** |
|||
* 消息类型 email |
|||
*/ |
|||
public static final String CMD_EMAIL = "email"; |
|||
|
|||
/** |
|||
* 消息类型 meetingsign 会议签到 |
|||
*/ |
|||
public static final String CMD_SIGN = "sign"; |
|||
|
|||
/** |
|||
* 消息类型 新闻发布/取消 |
|||
*/ |
|||
public static final String NEWS_PUBLISH = "publish"; |
|||
|
|||
} |
@ -0,0 +1,152 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* online表单枚举 代码生成器用到 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public enum CgformEnum { |
|||
|
|||
/** |
|||
* 单表 |
|||
*/ |
|||
ONE(1, "one", "/jeecg/code-template-online-zgx", "default.one", "经典风格"), |
|||
/** |
|||
* 多表 |
|||
*/ |
|||
MANY(2, "many", "/jeecg/code-template-online-zgx", "default.onetomany", "经典风格"), |
|||
/** |
|||
* 多表(jvxe风格) |
|||
* */ |
|||
JVXE_TABLE(2, "jvxe", "/jeecg/code-template-online-zgx", "jvxe.onetomany", "JVXE风格"), |
|||
|
|||
/** |
|||
* 多表 |
|||
*/ |
|||
ERP(2, "erp", "/jeecg/code-template-online-zgx", "erp.onetomany", "ERP风格"), |
|||
/** |
|||
* 多表(内嵌子表风格) |
|||
*/ |
|||
INNER_TABLE(2, "innerTable", "/jeecg/code-template-online-zgx", "inner-table.onetomany", "内嵌子表风格"), |
|||
/** |
|||
* 多表(tab风格) |
|||
* */ |
|||
TAB(2, "tab", "/jeecg/code-template-online-zgx", "tab.onetomany", "Tab风格"), |
|||
/** |
|||
* 树形列表 |
|||
*/ |
|||
TREE(3, "tree", "/jeecg/code-template-online-zgx", "default.tree", "树形列表"); |
|||
|
|||
/** |
|||
* 类型 1/单表 2/一对多 3/树 |
|||
*/ |
|||
int type; |
|||
/** |
|||
* 编码标识 |
|||
*/ |
|||
String code; |
|||
/** |
|||
* 代码生成器模板路径 |
|||
*/ |
|||
String templatePath; |
|||
/** |
|||
* 代码生成器模板路径 |
|||
*/ |
|||
String stylePath; |
|||
/** |
|||
* 模板风格名称 |
|||
*/ |
|||
String note; |
|||
|
|||
/** |
|||
* 构造器 |
|||
* |
|||
* @param type 类型 1/单表 2/一对多 3/树 |
|||
* @param code 模板编码 |
|||
* @param templatePath 模板路径 |
|||
* @param stylePath 模板子路径 |
|||
* @param note |
|||
*/ |
|||
CgformEnum(int type, String code, String templatePath, String stylePath, String note) { |
|||
this.type = type; |
|||
this.code = code; |
|||
this.templatePath = templatePath; |
|||
this.stylePath = stylePath; |
|||
this.note = note; |
|||
} |
|||
|
|||
/** |
|||
* 根据code获取模板路径 |
|||
* |
|||
* @param code |
|||
* @return |
|||
*/ |
|||
public static String getTemplatePathByConfig(String code) { |
|||
return getCgformEnumByConfig(code).templatePath; |
|||
} |
|||
|
|||
|
|||
public int getType() { |
|||
return type; |
|||
} |
|||
|
|||
public void setType(int type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
public String getTemplatePath() { |
|||
return templatePath; |
|||
} |
|||
|
|||
public void setTemplatePath(String templatePath) { |
|||
this.templatePath = templatePath; |
|||
} |
|||
|
|||
public String getStylePath() { |
|||
return stylePath; |
|||
} |
|||
|
|||
public void setStylePath(String stylePath) { |
|||
this.stylePath = stylePath; |
|||
} |
|||
|
|||
/** |
|||
* 根据code找枚举 |
|||
* |
|||
* @param code |
|||
* @return |
|||
*/ |
|||
public static CgformEnum getCgformEnumByConfig(String code) { |
|||
for (CgformEnum e : CgformEnum.values()) { |
|||
if (e.code.equals(code)) { |
|||
return e; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 根据类型找所有 |
|||
* |
|||
* @param type |
|||
* @return |
|||
*/ |
|||
public static List<Map<String, Object>> getJspModelList(int type) { |
|||
List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>(); |
|||
for (CgformEnum e : CgformEnum.values()) { |
|||
if (e.type == type) { |
|||
Map<String, Object> map = new HashMap<String, Object>(); |
|||
map.put("code", e.code); |
|||
map.put("note", e.note); |
|||
ls.add(map); |
|||
} |
|||
} |
|||
return ls; |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,25 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
/** |
|||
* LowApp 切面注解枚举 |
|||
* @date 2022-1-5 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public enum LowAppAopEnum { |
|||
|
|||
/** |
|||
* 新增方法 |
|||
*/ |
|||
ADD, |
|||
/** |
|||
* 删除方法(包含单个和批量删除) |
|||
*/ |
|||
DELETE, |
|||
/** 复制表单操作 */ |
|||
COPY, |
|||
|
|||
/** |
|||
* Online表单专用:数据库表转Online表单 |
|||
*/ |
|||
CGFORM_DB_IMPORT |
|||
} |
@ -0,0 +1,68 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
import org.jeecg.common.system.annotation.EnumDict; |
|||
import org.jeecg.common.system.vo.DictModel; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 消息类型 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@EnumDict("messageType") |
|||
public enum MessageTypeEnum { |
|||
|
|||
XT("system", "系统消息"), |
|||
YJ("email", "邮件消息"), |
|||
DD("dingtalk", "钉钉消息"), |
|||
QYWX("wechat_enterprise", "企业微信"); |
|||
|
|||
MessageTypeEnum(String type, String note){ |
|||
this.type = type; |
|||
this.note = note; |
|||
} |
|||
|
|||
/** |
|||
* 消息类型 |
|||
*/ |
|||
String type; |
|||
|
|||
/** |
|||
* 类型说明 |
|||
*/ |
|||
String note; |
|||
|
|||
public String getNote() { |
|||
return note; |
|||
} |
|||
|
|||
public void setNote(String note) { |
|||
this.note = note; |
|||
} |
|||
|
|||
public String getType() { |
|||
return type; |
|||
} |
|||
|
|||
public void setType(String type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取字典数据 |
|||
* @return |
|||
*/ |
|||
public static List<DictModel> getDictList(){ |
|||
List<DictModel> list = new ArrayList<>(); |
|||
DictModel dictModel = null; |
|||
for(MessageTypeEnum e: MessageTypeEnum.values()){ |
|||
dictModel = new DictModel(); |
|||
dictModel.setValue(e.getType()); |
|||
dictModel.setText(e.getNote()); |
|||
list.add(dictModel); |
|||
} |
|||
return list; |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
/** |
|||
* 日志按模块分类 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public enum ModuleType { |
|||
|
|||
/** |
|||
* 普通 |
|||
*/ |
|||
COMMON, |
|||
|
|||
/** |
|||
* online |
|||
*/ |
|||
ONLINE; |
|||
} |
@ -0,0 +1,95 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
import org.jeecg.common.constant.CommonConstant; |
|||
|
|||
/** |
|||
* @Description: 操作类型 |
|||
* @author: jeecg-boot |
|||
* @date: 2022/3/31 10:05 |
|||
*/ |
|||
public enum OperateTypeEnum { |
|||
|
|||
/** |
|||
* 列表 |
|||
*/ |
|||
LIST(CommonConstant.OPERATE_TYPE_1, "list"), |
|||
|
|||
/** |
|||
* 新增 |
|||
*/ |
|||
ADD(CommonConstant.OPERATE_TYPE_2, "add"), |
|||
|
|||
/** |
|||
* 编辑 |
|||
*/ |
|||
EDIT(CommonConstant.OPERATE_TYPE_3, "edit"), |
|||
|
|||
/** |
|||
* 删除 |
|||
*/ |
|||
DELETE(CommonConstant.OPERATE_TYPE_4, "delete"), |
|||
|
|||
/** |
|||
* 导入 |
|||
*/ |
|||
IMPORT(CommonConstant.OPERATE_TYPE_5, "import"), |
|||
|
|||
/** |
|||
* 导出 |
|||
*/ |
|||
EXPORT(CommonConstant.OPERATE_TYPE_6, "export"); |
|||
|
|||
/** |
|||
* 类型 1列表,2新增,3编辑,4删除,5导入,6导出 |
|||
*/ |
|||
int type; |
|||
|
|||
/** |
|||
* 编码(请求方式) |
|||
*/ |
|||
String code; |
|||
|
|||
|
|||
public int getType() { |
|||
return type; |
|||
} |
|||
|
|||
public void setType(int type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public void setCode(String code) { |
|||
this.code = code; |
|||
} |
|||
|
|||
/** |
|||
* 构造器 |
|||
* |
|||
* @param type 类型 |
|||
* @param code 编码(请求方式) |
|||
*/ |
|||
OperateTypeEnum(int type, String code) { |
|||
this.type = type; |
|||
this.code = code; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 根据请求名称匹配 |
|||
* |
|||
* @param methodName 请求名称 |
|||
* @return Integer 类型 |
|||
*/ |
|||
public static Integer getTypeByMethodName(String methodName) { |
|||
for (OperateTypeEnum e : OperateTypeEnum.values()) { |
|||
if (methodName.startsWith(e.getCode())) { |
|||
return e.getType(); |
|||
} |
|||
} |
|||
return CommonConstant.OPERATE_TYPE_1; |
|||
} |
|||
} |
@ -0,0 +1,93 @@ |
|||
package org.jeecg.common.constant.enums; |
|||
|
|||
import org.jeecg.common.util.oConvertUtils; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 首页自定义 |
|||
* 通过角色编码与首页组件路径配置 |
|||
* 枚举的顺序有权限高低权重作用(也就是配置多个角色,在前面的角色首页,会优先生效) |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public enum RoleIndexConfigEnum { |
|||
|
|||
/**首页自定义 admin*/ |
|||
ADMIN("admin", "dashboard/Analysis"), |
|||
//TEST("test", "dashboard/IndexChart"),
|
|||
/**首页自定义 hr*/ |
|||
HR("hr", "dashboard/IndexBdc"); |
|||
//DM("dm", "dashboard/IndexTask"),
|
|||
|
|||
/** |
|||
* 角色编码 |
|||
*/ |
|||
String roleCode; |
|||
/** |
|||
* 路由index |
|||
*/ |
|||
String componentUrl; |
|||
|
|||
/** |
|||
* 构造器 |
|||
* |
|||
* @param roleCode 角色编码 |
|||
* @param componentUrl 首页组件路径(规则跟菜单配置一样) |
|||
*/ |
|||
RoleIndexConfigEnum(String roleCode, String componentUrl) { |
|||
this.roleCode = roleCode; |
|||
this.componentUrl = componentUrl; |
|||
} |
|||
/** |
|||
* 根据code找枚举 |
|||
* @param roleCode 角色编码 |
|||
* @return |
|||
*/ |
|||
private static RoleIndexConfigEnum getEnumByCode(String roleCode) { |
|||
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { |
|||
if (e.roleCode.equals(roleCode)) { |
|||
return e; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
/** |
|||
* 根据code找index |
|||
* @param roleCode 角色编码 |
|||
* @return |
|||
*/ |
|||
private static String getIndexByCode(String roleCode) { |
|||
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { |
|||
if (e.roleCode.equals(roleCode)) { |
|||
return e.componentUrl; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public static String getIndexByRoles(List<String> roles) { |
|||
String[] rolesArray = roles.toArray(new String[roles.size()]); |
|||
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { |
|||
if (oConvertUtils.isIn(e.roleCode,rolesArray)){ |
|||
return e.componentUrl; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public String getRoleCode() { |
|||
return roleCode; |
|||
} |
|||
|
|||
public void setRoleCode(String roleCode) { |
|||
this.roleCode = roleCode; |
|||
} |
|||
|
|||
public String getComponentUrl() { |
|||
return componentUrl; |
|||
} |
|||
|
|||
public void setComponentUrl(String componentUrl) { |
|||
this.componentUrl = componentUrl; |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
package org.jeecg.common.desensitization.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 解密注解 |
|||
* |
|||
* 在方法上定义 将方法返回对象中的敏感字段 解密,需要注意的是,如果没有加密过,解密会出问题,返回原字符串 |
|||
*/ |
|||
@Documented |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.METHOD}) |
|||
public @interface SensitiveDecode { |
|||
|
|||
/** |
|||
* 指明需要脱敏的实体类class |
|||
* @return |
|||
*/ |
|||
Class entity() default Object.class; |
|||
} |
@ -0,0 +1,20 @@ |
|||
package org.jeecg.common.desensitization.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 加密注解 |
|||
* |
|||
* 在方法上声明 将方法返回对象中的敏感字段 加密/格式化 |
|||
*/ |
|||
@Documented |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target({ElementType.METHOD}) |
|||
public @interface SensitiveEncode { |
|||
|
|||
/** |
|||
* 指明需要脱敏的实体类class |
|||
* @return |
|||
*/ |
|||
Class entity() default Object.class; |
|||
} |
@ -0,0 +1,21 @@ |
|||
package org.jeecg.common.desensitization.annotation; |
|||
|
|||
|
|||
import org.jeecg.common.desensitization.enums.SensitiveEnum; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 在字段上定义 标识字段存储的信息是敏感的 |
|||
*/ |
|||
@Documented |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Target(ElementType.FIELD) |
|||
public @interface SensitiveField { |
|||
|
|||
/** |
|||
* 不同类型处理不同 |
|||
* @return |
|||
*/ |
|||
SensitiveEnum type() default SensitiveEnum.ENCODE; |
|||
} |
@ -0,0 +1,81 @@ |
|||
package org.jeecg.common.desensitization.aspect; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.aspectj.lang.annotation.Around; |
|||
import org.aspectj.lang.annotation.Aspect; |
|||
import org.aspectj.lang.annotation.Pointcut; |
|||
import org.aspectj.lang.reflect.MethodSignature; |
|||
import org.jeecg.common.desensitization.annotation.SensitiveDecode; |
|||
import org.jeecg.common.desensitization.annotation.SensitiveEncode; |
|||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.lang.reflect.Method; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 敏感数据切面处理类 |
|||
* @Author taoYan |
|||
* @Date 2022/4/20 17:45 |
|||
**/ |
|||
@Slf4j |
|||
@Aspect |
|||
@Component |
|||
public class SensitiveDataAspect { |
|||
|
|||
/** |
|||
* 定义切点Pointcut |
|||
*/ |
|||
@Pointcut("@annotation(org.jeecg.common.desensitization.annotation.SensitiveEncode) || @annotation(org.jeecg.common.desensitization.annotation.SensitiveDecode)") |
|||
public void sensitivePointCut() { |
|||
} |
|||
|
|||
@Around("sensitivePointCut()") |
|||
public Object around(ProceedingJoinPoint point) throws Throwable { |
|||
// 处理结果
|
|||
Object result = point.proceed(); |
|||
if(result == null){ |
|||
return result; |
|||
} |
|||
Class resultClass = result.getClass(); |
|||
log.debug(" resultClass = {}" , resultClass); |
|||
|
|||
if(resultClass.isPrimitive()){ |
|||
//是基本类型 直接返回 不需要处理
|
|||
return result; |
|||
} |
|||
// 获取方法注解信息:是哪个实体、是加密还是解密
|
|||
boolean isEncode = true; |
|||
Class entity = null; |
|||
MethodSignature methodSignature = (MethodSignature) point.getSignature(); |
|||
Method method = methodSignature.getMethod(); |
|||
SensitiveEncode encode = method.getAnnotation(SensitiveEncode.class); |
|||
if(encode==null){ |
|||
SensitiveDecode decode = method.getAnnotation(SensitiveDecode.class); |
|||
if(decode!=null){ |
|||
entity = decode.entity(); |
|||
isEncode = false; |
|||
} |
|||
}else{ |
|||
entity = encode.entity(); |
|||
} |
|||
|
|||
long startTime=System.currentTimeMillis(); |
|||
if(resultClass.equals(entity) || entity.equals(Object.class)){ |
|||
// 方法返回实体和注解的entity一样,如果注解没有申明entity属性则认为是(方法返回实体和注解的entity一样)
|
|||
SensitiveInfoUtil.handlerObject(result, isEncode); |
|||
} else if(result instanceof List){ |
|||
// 方法返回List<实体>
|
|||
SensitiveInfoUtil.handleList(result, entity, isEncode); |
|||
}else{ |
|||
// 方法返回一个对象
|
|||
SensitiveInfoUtil.handleNestedObject(result, entity, isEncode); |
|||
} |
|||
long endTime=System.currentTimeMillis(); |
|||
log.info((isEncode ? "加密操作," : "解密操作,") + "Aspect程序耗时:" + (endTime - startTime) + "ms"); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,55 @@ |
|||
package org.jeecg.common.desensitization.enums; |
|||
|
|||
/** |
|||
* 敏感字段信息类型 |
|||
*/ |
|||
public enum SensitiveEnum { |
|||
|
|||
|
|||
/** |
|||
* 加密 |
|||
*/ |
|||
ENCODE, |
|||
|
|||
/** |
|||
* 中文名 |
|||
*/ |
|||
CHINESE_NAME, |
|||
|
|||
/** |
|||
* 身份证号 |
|||
*/ |
|||
ID_CARD, |
|||
|
|||
/** |
|||
* 座机号 |
|||
*/ |
|||
FIXED_PHONE, |
|||
|
|||
/** |
|||
* 手机号 |
|||
*/ |
|||
MOBILE_PHONE, |
|||
|
|||
/** |
|||
* 地址 |
|||
*/ |
|||
ADDRESS, |
|||
|
|||
/** |
|||
* 电子邮件 |
|||
*/ |
|||
EMAIL, |
|||
|
|||
/** |
|||
* 银行卡 |
|||
*/ |
|||
BANK_CARD, |
|||
|
|||
/** |
|||
* 公司开户银行联号 |
|||
*/ |
|||
CNAPS_CODE; |
|||
|
|||
|
|||
} |
@ -0,0 +1,362 @@ |
|||
package org.jeecg.common.desensitization.util; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.jeecg.common.desensitization.annotation.SensitiveField; |
|||
import org.jeecg.common.desensitization.enums.SensitiveEnum; |
|||
import org.jeecg.common.util.encryption.AesEncryptUtil; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.lang.reflect.ParameterizedType; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 敏感信息处理工具类 |
|||
* @author taoYan |
|||
* @date 2022/4/20 18:01 |
|||
**/ |
|||
@Slf4j |
|||
public class SensitiveInfoUtil { |
|||
|
|||
/** |
|||
* 处理嵌套对象 |
|||
* @param obj 方法返回值 |
|||
* @param entity 实体class |
|||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作) |
|||
* @throws IllegalAccessException |
|||
*/ |
|||
public static void handleNestedObject(Object obj, Class entity, boolean isEncode) throws IllegalAccessException { |
|||
Field[] fields = obj.getClass().getDeclaredFields(); |
|||
for (Field field : fields) { |
|||
if(field.getType().isPrimitive()){ |
|||
continue; |
|||
} |
|||
if(field.getType().equals(entity)){ |
|||
// 对象里面是实体
|
|||
field.setAccessible(true); |
|||
Object nestedObject = field.get(obj); |
|||
handlerObject(nestedObject, isEncode); |
|||
break; |
|||
}else{ |
|||
// 对象里面是List<实体>
|
|||
if(field.getGenericType() instanceof ParameterizedType){ |
|||
ParameterizedType pt = (ParameterizedType)field.getGenericType(); |
|||
if(pt.getRawType().equals(List.class)){ |
|||
if(pt.getActualTypeArguments()[0].equals(entity)){ |
|||
field.setAccessible(true); |
|||
Object nestedObject = field.get(obj); |
|||
handleList(nestedObject, entity, isEncode); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 处理Object |
|||
* @param obj 方法返回值 |
|||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作) |
|||
* @return |
|||
* @throws IllegalAccessException |
|||
*/ |
|||
public static Object handlerObject(Object obj, boolean isEncode) throws IllegalAccessException { |
|||
log.debug(" obj --> "+ obj.toString()); |
|||
long startTime=System.currentTimeMillis(); |
|||
if (oConvertUtils.isEmpty(obj)) { |
|||
return obj; |
|||
} |
|||
// 判断是不是一个对象
|
|||
Field[] fields = obj.getClass().getDeclaredFields(); |
|||
for (Field field : fields) { |
|||
boolean isSensitiveField = field.isAnnotationPresent(SensitiveField.class); |
|||
if(isSensitiveField){ |
|||
// 必须有SensitiveField注解 才作处理
|
|||
if(field.getType().isAssignableFrom(String.class)){ |
|||
//必须是字符串类型 才作处理
|
|||
field.setAccessible(true); |
|||
String realValue = (String) field.get(obj); |
|||
if(realValue==null || "".equals(realValue)){ |
|||
continue; |
|||
} |
|||
SensitiveField sf = field.getAnnotation(SensitiveField.class); |
|||
if(isEncode==true){ |
|||
//加密
|
|||
String value = SensitiveInfoUtil.getEncodeData(realValue, sf.type()); |
|||
field.set(obj, value); |
|||
}else{ |
|||
//解密只处理 encode类型的
|
|||
if(sf.type().equals(SensitiveEnum.ENCODE)){ |
|||
String value = SensitiveInfoUtil.getDecodeData(realValue); |
|||
field.set(obj, value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//long endTime=System.currentTimeMillis();
|
|||
//log.info((isEncode ? "加密操作," : "解密操作,") + "当前程序耗时:" + (endTime - startTime) + "ms");
|
|||
return obj; |
|||
} |
|||
|
|||
/** |
|||
* 处理 List<实体> |
|||
* @param obj |
|||
* @param entity |
|||
* @param isEncode(true: 加密操作 / false:解密操作) |
|||
*/ |
|||
public static void handleList(Object obj, Class entity, boolean isEncode){ |
|||
List list = (List)obj; |
|||
if(list.size()>0){ |
|||
Object first = list.get(0); |
|||
if(first.getClass().equals(entity)){ |
|||
for(int i=0; i<list.size(); i++){ |
|||
Object temp = list.get(i); |
|||
try { |
|||
handlerObject(temp, isEncode); |
|||
} catch (IllegalAccessException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 处理数据 获取解密后的数据 |
|||
* @param data |
|||
* @return |
|||
*/ |
|||
public static String getDecodeData(String data){ |
|||
String result = null; |
|||
try { |
|||
result = AesEncryptUtil.desEncrypt(data); |
|||
} catch (Exception exception) { |
|||
log.warn("数据解密错误,原数据:"+data); |
|||
} |
|||
//解决debug模式下,加解密失效导致中文被解密变成空的问题
|
|||
if(oConvertUtils.isEmpty(result) && oConvertUtils.isNotEmpty(data)){ |
|||
result = data; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 处理数据 获取加密后的数据 或是格式化后的数据 |
|||
* @param data 字符串 |
|||
* @param sensitiveEnum 类型 |
|||
* @return 处理后的字符串 |
|||
*/ |
|||
public static String getEncodeData(String data, SensitiveEnum sensitiveEnum){ |
|||
String result; |
|||
switch (sensitiveEnum){ |
|||
case ENCODE: |
|||
try { |
|||
result = AesEncryptUtil.encrypt(data); |
|||
} catch (Exception exception) { |
|||
log.error("数据加密错误", exception.getMessage()); |
|||
result = data; |
|||
} |
|||
break; |
|||
case CHINESE_NAME: |
|||
result = chineseName(data); |
|||
break; |
|||
case ID_CARD: |
|||
result = idCardNum(data); |
|||
break; |
|||
case FIXED_PHONE: |
|||
result = fixedPhone(data); |
|||
break; |
|||
case MOBILE_PHONE: |
|||
result = mobilePhone(data); |
|||
break; |
|||
case ADDRESS: |
|||
result = address(data, 3); |
|||
break; |
|||
case EMAIL: |
|||
result = email(data); |
|||
break; |
|||
case BANK_CARD: |
|||
result = bankCard(data); |
|||
break; |
|||
case CNAPS_CODE: |
|||
result = cnapsCode(data); |
|||
break; |
|||
default: |
|||
result = data; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号 |
|||
* @param fullName 全名 |
|||
* @return <例子:李**> |
|||
*/ |
|||
private static String chineseName(String fullName) { |
|||
if (oConvertUtils.isEmpty(fullName)) { |
|||
return ""; |
|||
} |
|||
return formatRight(fullName, 1); |
|||
} |
|||
|
|||
/** |
|||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号 |
|||
* @param familyName 姓 |
|||
* @param firstName 名 |
|||
* @return <例子:李**> |
|||
*/ |
|||
private static String chineseName(String familyName, String firstName) { |
|||
if (oConvertUtils.isEmpty(familyName) || oConvertUtils.isEmpty(firstName)) { |
|||
return ""; |
|||
} |
|||
return chineseName(familyName + firstName); |
|||
} |
|||
|
|||
/** |
|||
* [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。 |
|||
* @param id 身份证号 |
|||
* @return <例子:*************5762> |
|||
*/ |
|||
private static String idCardNum(String id) { |
|||
if (oConvertUtils.isEmpty(id)) { |
|||
return ""; |
|||
} |
|||
return formatLeft(id, 4); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* [固定电话] 后四位,其他隐藏 |
|||
* @param num 固定电话 |
|||
* @return <例子:****1234> |
|||
*/ |
|||
private static String fixedPhone(String num) { |
|||
if (oConvertUtils.isEmpty(num)) { |
|||
return ""; |
|||
} |
|||
return formatLeft(num, 4); |
|||
} |
|||
|
|||
/** |
|||
* [手机号码] 前三位,后四位,其他隐藏 |
|||
* @param num 手机号码 |
|||
* @return <例子:138******1234> |
|||
*/ |
|||
private static String mobilePhone(String num) { |
|||
if (oConvertUtils.isEmpty(num)) { |
|||
return ""; |
|||
} |
|||
int len = num.length(); |
|||
if(len<11){ |
|||
return num; |
|||
} |
|||
return formatBetween(num, 3, 4); |
|||
} |
|||
|
|||
/** |
|||
* [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护 |
|||
* @param address 地址 |
|||
* @param sensitiveSize 敏感信息长度 |
|||
* @return <例子:北京市海淀区****> |
|||
*/ |
|||
private static String address(String address, int sensitiveSize) { |
|||
if (oConvertUtils.isEmpty(address)) { |
|||
return ""; |
|||
} |
|||
int len = address.length(); |
|||
if(len<sensitiveSize){ |
|||
return address; |
|||
} |
|||
return formatRight(address, sensitiveSize); |
|||
} |
|||
|
|||
/** |
|||
* [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示 |
|||
* @param email 电子邮箱 |
|||
* @return <例子:g**@163.com> |
|||
*/ |
|||
private static String email(String email) { |
|||
if (oConvertUtils.isEmpty(email)) { |
|||
return ""; |
|||
} |
|||
int index = email.indexOf("@"); |
|||
if (index <= 1){ |
|||
return email; |
|||
} |
|||
String begin = email.substring(0, 1); |
|||
String end = email.substring(index); |
|||
String stars = "**"; |
|||
return begin + stars + end; |
|||
} |
|||
|
|||
/** |
|||
* [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号 |
|||
* @param cardNum 银行卡号 |
|||
* @return <例子:6222600**********1234> |
|||
*/ |
|||
private static String bankCard(String cardNum) { |
|||
if (oConvertUtils.isEmpty(cardNum)) { |
|||
return ""; |
|||
} |
|||
return formatBetween(cardNum, 6, 4); |
|||
} |
|||
|
|||
/** |
|||
* [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号 |
|||
* @param code 公司开户银行联号 |
|||
* @return <例子:12********> |
|||
*/ |
|||
private static String cnapsCode(String code) { |
|||
if (oConvertUtils.isEmpty(code)) { |
|||
return ""; |
|||
} |
|||
return formatRight(code, 2); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 将右边的格式化成* |
|||
* @param str 字符串 |
|||
* @param reservedLength 保留长度 |
|||
* @return 格式化后的字符串 |
|||
*/ |
|||
private static String formatRight(String str, int reservedLength){ |
|||
String name = str.substring(0, reservedLength); |
|||
String stars = String.join("", Collections.nCopies(str.length()-reservedLength, "*")); |
|||
return name + stars; |
|||
} |
|||
|
|||
/** |
|||
* 将左边的格式化成* |
|||
* @param str 字符串 |
|||
* @param reservedLength 保留长度 |
|||
* @return 格式化后的字符串 |
|||
*/ |
|||
private static String formatLeft(String str, int reservedLength){ |
|||
int len = str.length(); |
|||
String show = str.substring(len-reservedLength); |
|||
String stars = String.join("", Collections.nCopies(len-reservedLength, "*")); |
|||
return stars + show; |
|||
} |
|||
|
|||
/** |
|||
* 将中间的格式化成* |
|||
* @param str 字符串 |
|||
* @param beginLen 开始保留长度 |
|||
* @param endLen 结尾保留长度 |
|||
* @return 格式化后的字符串 |
|||
*/ |
|||
private static String formatBetween(String str, int beginLen, int endLen){ |
|||
int len = str.length(); |
|||
String begin = str.substring(0, beginLen); |
|||
String end = str.substring(len-endLen); |
|||
String stars = String.join("", Collections.nCopies(len-beginLen-endLen, "*")); |
|||
return begin + stars + end; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,544 @@ |
|||
package org.jeecg.common.es; |
|||
|
|||
import com.alibaba.fastjson.JSONArray; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.jeecg.common.util.RestUtil; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.http.HttpHeaders; |
|||
import org.springframework.http.HttpMethod; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.*; |
|||
|
|||
/** |
|||
* 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等) |
|||
* |
|||
* @author sunjianlei |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class JeecgElasticsearchTemplate { |
|||
/** es服务地址 */ |
|||
private String baseUrl; |
|||
private final String FORMAT_JSON = "format=json"; |
|||
/** Elasticsearch 的版本号 */ |
|||
private String version = null; |
|||
|
|||
/**ElasticSearch 最大可返回条目数*/ |
|||
public static final int ES_MAX_SIZE = 10000; |
|||
|
|||
/**es7*/ |
|||
public static final String IE_SEVEN = "7"; |
|||
|
|||
/**url not found 404*/ |
|||
public static final String URL_NOT_FOUND = "404 Not Found"; |
|||
|
|||
public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl, @Value("${jeecg.elasticsearch.check-enabled}") boolean checkEnabled) { |
|||
log.debug("JeecgElasticsearchTemplate BaseURL:" + baseUrl); |
|||
if (StringUtils.isNotEmpty(baseUrl)) { |
|||
this.baseUrl = baseUrl; |
|||
// 验证配置的ES地址是否有效
|
|||
if (checkEnabled) { |
|||
try { |
|||
this.getElasticsearchVersion(); |
|||
log.info("ElasticSearch 服务连接成功"); |
|||
log.info("ElasticSearch version: " + this.version); |
|||
} catch (Exception e) { |
|||
this.version = ""; |
|||
log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取 Elasticsearch 的版本号信息,失败返回null |
|||
*/ |
|||
private void getElasticsearchVersion() { |
|||
if (this.version == null) { |
|||
String url = this.getBaseUrl().toString(); |
|||
JSONObject result = RestUtil.get(url); |
|||
if (result != null) { |
|||
JSONObject v = result.getJSONObject("version"); |
|||
this.version = v.getString("number"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public StringBuilder getBaseUrl(String indexName, String typeName) { |
|||
typeName = typeName.trim().toLowerCase(); |
|||
return this.getBaseUrl(indexName).append("/").append(typeName); |
|||
} |
|||
|
|||
public StringBuilder getBaseUrl(String indexName) { |
|||
indexName = indexName.trim().toLowerCase(); |
|||
return this.getBaseUrl().append("/").append(indexName); |
|||
} |
|||
|
|||
public StringBuilder getBaseUrl() { |
|||
return new StringBuilder("http://").append(this.baseUrl); |
|||
} |
|||
|
|||
/** |
|||
* cat 查询ElasticSearch系统数据,返回json |
|||
*/ |
|||
private <T> ResponseEntity<T> cat(String urlAfter, Class<T> responseType) { |
|||
String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString(); |
|||
return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType); |
|||
} |
|||
|
|||
/** |
|||
* 查询所有索引 |
|||
* <p> |
|||
* 查询地址:GET http://{baseUrl}/_cat/indices
|
|||
*/ |
|||
public JSONArray getIndices() { |
|||
return getIndices(null); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 查询单个索引 |
|||
* <p> |
|||
* 查询地址:GET http://{baseUrl}/_cat/indices/{indexName}
|
|||
*/ |
|||
public JSONArray getIndices(String indexName) { |
|||
StringBuilder urlAfter = new StringBuilder("/indices"); |
|||
if (!StringUtils.isEmpty(indexName)) { |
|||
urlAfter.append("/").append(indexName.trim().toLowerCase()); |
|||
} |
|||
return cat(urlAfter.toString(), JSONArray.class).getBody(); |
|||
} |
|||
|
|||
/** |
|||
* 索引是否存在 |
|||
*/ |
|||
public boolean indexExists(String indexName) { |
|||
try { |
|||
JSONArray array = getIndices(indexName); |
|||
return array != null; |
|||
} catch (org.springframework.web.client.HttpClientErrorException ex) { |
|||
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { |
|||
return false; |
|||
} else { |
|||
throw ex; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 根据ID获取索引数据,未查询到返回null |
|||
* <p> |
|||
* 查询地址:GET http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
|||
* |
|||
* @param indexName 索引名称 |
|||
* @param typeName type,一个任意字符串,用于分类 |
|||
* @param dataId 数据id |
|||
* @return |
|||
*/ |
|||
public JSONObject getDataById(String indexName, String typeName, String dataId) { |
|||
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString(); |
|||
log.info("url:" + url); |
|||
JSONObject result = RestUtil.get(url); |
|||
boolean found = result.getBoolean("found"); |
|||
if (found) { |
|||
return result.getJSONObject("_source"); |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 创建索引 |
|||
* <p> |
|||
* 查询地址:PUT http://{baseUrl}/{indexName}
|
|||
*/ |
|||
public boolean createIndex(String indexName) { |
|||
String url = this.getBaseUrl(indexName).toString(); |
|||
|
|||
/* 返回结果 (仅供参考) |
|||
"createIndex": { |
|||
"shards_acknowledged": true, |
|||
"acknowledged": true, |
|||
"index": "hello_world" |
|||
} |
|||
*/ |
|||
try { |
|||
return RestUtil.put(url).getBoolean("acknowledged"); |
|||
} catch (org.springframework.web.client.HttpClientErrorException ex) { |
|||
if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) { |
|||
log.warn("索引创建失败:" + indexName + " 已存在,无需再创建"); |
|||
} else { |
|||
ex.printStackTrace(); |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* 删除索引 |
|||
* <p> |
|||
* 查询地址:DELETE http://{baseUrl}/{indexName}
|
|||
*/ |
|||
public boolean removeIndex(String indexName) { |
|||
String url = this.getBaseUrl(indexName).toString(); |
|||
try { |
|||
return RestUtil.delete(url).getBoolean("acknowledged"); |
|||
} catch (org.springframework.web.client.HttpClientErrorException ex) { |
|||
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { |
|||
log.warn("索引删除失败:" + indexName + " 不存在,无需删除"); |
|||
} else { |
|||
ex.printStackTrace(); |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* 获取索引字段映射(可获取字段类型) |
|||
* <p> |
|||
* |
|||
* @param indexName 索引名称 |
|||
* @param typeName 分类名称 |
|||
* @return |
|||
*/ |
|||
public JSONObject getIndexMapping(String indexName, String typeName) { |
|||
String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString(); |
|||
// 针对 es 7.x 版本做兼容
|
|||
this.getElasticsearchVersion(); |
|||
if (oConvertUtils.isNotEmpty(this.version) && this.version.startsWith(IE_SEVEN)) { |
|||
url += "&include_type_name=true"; |
|||
} |
|||
log.info("getIndexMapping-url:" + url); |
|||
/* |
|||
* 参考返回JSON结构: |
|||
* |
|||
*{ |
|||
* // 索引名称
|
|||
* "[indexName]": { |
|||
* "mappings": { |
|||
* // 分类名称
|
|||
* "[typeName]": { |
|||
* "properties": { |
|||
* // 字段名
|
|||
* "input_number": { |
|||
* // 字段类型
|
|||
* "type": "long" |
|||
* }, |
|||
* "input_string": { |
|||
* "type": "text", |
|||
* "fields": { |
|||
* "keyword": { |
|||
* "type": "keyword", |
|||
* "ignore_above": 256 |
|||
* } |
|||
* } |
|||
* } |
|||
* } |
|||
* } |
|||
* } |
|||
* } |
|||
* } |
|||
*/ |
|||
try { |
|||
return RestUtil.get(url); |
|||
} catch (org.springframework.web.client.HttpClientErrorException e) { |
|||
String message = e.getMessage(); |
|||
if (message != null && message.contains(URL_NOT_FOUND)) { |
|||
return null; |
|||
} |
|||
throw e; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取索引字段映射,返回Java实体类 |
|||
* |
|||
* @param indexName |
|||
* @param typeName |
|||
* @return |
|||
*/ |
|||
public <T> Map<String, T> getIndexMappingFormat(String indexName, String typeName, Class<T> clazz) { |
|||
JSONObject mapping = this.getIndexMapping(indexName, typeName); |
|||
Map<String, T> map = new HashMap<>(5); |
|||
if (mapping == null) { |
|||
return map; |
|||
} |
|||
// 获取字段属性
|
|||
JSONObject properties = mapping.getJSONObject(indexName) |
|||
.getJSONObject("mappings") |
|||
.getJSONObject(typeName) |
|||
.getJSONObject("properties"); |
|||
// 封装成 java类型
|
|||
for (String key : properties.keySet()) { |
|||
T entity = properties.getJSONObject(key).toJavaObject(clazz); |
|||
map.put(key, entity); |
|||
} |
|||
return map; |
|||
} |
|||
|
|||
/** |
|||
* 保存数据,详见:saveOrUpdate |
|||
*/ |
|||
public boolean save(String indexName, String typeName, String dataId, JSONObject data) { |
|||
return this.saveOrUpdate(indexName, typeName, dataId, data); |
|||
} |
|||
|
|||
/** |
|||
* 更新数据,详见:saveOrUpdate |
|||
*/ |
|||
public boolean update(String indexName, String typeName, String dataId, JSONObject data) { |
|||
return this.saveOrUpdate(indexName, typeName, dataId, data); |
|||
} |
|||
|
|||
/** |
|||
* 保存或修改索引数据 |
|||
* <p> |
|||
* 查询地址:PUT http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
|||
* |
|||
* @param indexName 索引名称 |
|||
* @param typeName type,一个任意字符串,用于分类 |
|||
* @param dataId 数据id |
|||
* @param data 要存储的数据 |
|||
* @return |
|||
*/ |
|||
public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) { |
|||
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).append("?refresh=wait_for").toString(); |
|||
/* 返回结果(仅供参考) |
|||
"createIndexA2": { |
|||
"result": "created", |
|||
"_shards": { |
|||
"total": 2, |
|||
"successful": 1, |
|||
"failed": 0 |
|||
}, |
|||
"_seq_no": 0, |
|||
"_index": "test_index_1", |
|||
"_type": "test_type_1", |
|||
"_id": "a2", |
|||
"_version": 1, |
|||
"_primary_term": 1 |
|||
} |
|||
*/ |
|||
|
|||
try { |
|||
// 去掉 data 中为空的值
|
|||
Set<String> keys = data.keySet(); |
|||
List<String> emptyKeys = new ArrayList<>(keys.size()); |
|||
for (String key : keys) { |
|||
String value = data.getString(key); |
|||
//1、剔除空值
|
|||
if (oConvertUtils.isEmpty(value) || "[]".equals(value)) { |
|||
emptyKeys.add(key); |
|||
} |
|||
//2、剔除上传控件值(会导致ES同步失败,报异常failed to parse field [ge_pic] of type [text] )
|
|||
if (oConvertUtils.isNotEmpty(value) && value.indexOf("[{")!=-1) { |
|||
emptyKeys.add(key); |
|||
log.info("-------剔除上传控件字段------------key: "+ key); |
|||
} |
|||
} |
|||
for (String key : emptyKeys) { |
|||
data.remove(key); |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
try { |
|||
String result = RestUtil.put(url, data).getString("result"); |
|||
return "created".equals(result) || "updated".equals(result); |
|||
} catch (Exception e) { |
|||
log.error(e.getMessage() + "\n-- url: " + url + "\n-- data: " + data.toJSONString()); |
|||
//TODO 打印接口返回异常json
|
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 批量保存数据 |
|||
* |
|||
* @param indexName 索引名称 |
|||
* @param typeName type,一个任意字符串,用于分类 |
|||
* @param dataList 要存储的数据数组,每行数据必须包含id |
|||
* @return |
|||
*/ |
|||
public boolean saveBatch(String indexName, String typeName, JSONArray dataList) { |
|||
String url = this.getBaseUrl().append("/_bulk").append("?refresh=wait_for").toString(); |
|||
StringBuilder bodySb = new StringBuilder(); |
|||
for (int i = 0; i < dataList.size(); i++) { |
|||
JSONObject data = dataList.getJSONObject(i); |
|||
String id = data.getString("id"); |
|||
// 该行的操作
|
|||
// {"create": {"_id":"${id}", "_index": "${indexName}", "_type": "${typeName}"}}
|
|||
JSONObject action = new JSONObject(); |
|||
JSONObject actionInfo = new JSONObject(); |
|||
actionInfo.put("_id", id); |
|||
actionInfo.put("_index", indexName); |
|||
actionInfo.put("_type", typeName); |
|||
action.put("create", actionInfo); |
|||
bodySb.append(action.toJSONString()).append("\n"); |
|||
// 该行的数据
|
|||
data.remove("id"); |
|||
bodySb.append(data.toJSONString()).append("\n"); |
|||
} |
|||
System.out.println("+-+-+-: bodySb.toString(): " + bodySb.toString()); |
|||
HttpHeaders headers = RestUtil.getHeaderApplicationJson(); |
|||
RestUtil.request(url, HttpMethod.PUT, headers, null, bodySb, JSONObject.class); |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* 删除索引数据 |
|||
* <p> |
|||
* 请求地址:DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
|||
*/ |
|||
public boolean delete(String indexName, String typeName, String dataId) { |
|||
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString(); |
|||
/* 返回结果(仅供参考) |
|||
{ |
|||
"_index": "es_demo", |
|||
"_type": "docs", |
|||
"_id": "001", |
|||
"_version": 3, |
|||
"result": "deleted", |
|||
"_shards": { |
|||
"total": 1, |
|||
"successful": 1, |
|||
"failed": 0 |
|||
}, |
|||
"_seq_no": 28, |
|||
"_primary_term": 18 |
|||
} |
|||
*/ |
|||
try { |
|||
return "deleted".equals(RestUtil.delete(url).getString("result")); |
|||
} catch (org.springframework.web.client.HttpClientErrorException ex) { |
|||
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { |
|||
return false; |
|||
} else { |
|||
throw ex; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* = = = 以下关于查询和查询条件的方法 = = =*/ |
|||
|
|||
/** |
|||
* 查询数据 |
|||
* <p> |
|||
* 请求地址:POST http://{baseUrl}/{indexName}/{typeName}/_search
|
|||
*/ |
|||
public JSONObject search(String indexName, String typeName, JSONObject queryObject) { |
|||
String url = this.getBaseUrl(indexName, typeName).append("/_search").toString(); |
|||
|
|||
log.info("url:" + url + " ,search: " + queryObject.toJSONString()); |
|||
JSONObject res = RestUtil.post(url, queryObject); |
|||
log.info("url:" + url + " ,return res: \n" + res.toJSONString()); |
|||
return res; |
|||
} |
|||
|
|||
/** |
|||
* @param source (源滤波器)指定返回的字段,传null返回所有字段 |
|||
* @param query |
|||
* @param from 从第几条数据开始 |
|||
* @param size 返回条目数 |
|||
* @return { "query": query } |
|||
*/ |
|||
public JSONObject buildQuery(List<String> source, JSONObject query, int from, int size) { |
|||
JSONObject json = new JSONObject(); |
|||
if (source != null) { |
|||
json.put("_source", source); |
|||
} |
|||
json.put("query", query); |
|||
json.put("from", from); |
|||
json.put("size", size); |
|||
return json; |
|||
} |
|||
|
|||
/** |
|||
* @return { "bool" : { "must": must, "must_not": mustNot, "should": should } } |
|||
*/ |
|||
public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) { |
|||
JSONObject bool = new JSONObject(); |
|||
if (must != null) { |
|||
bool.put("must", must); |
|||
} |
|||
if (mustNot != null) { |
|||
bool.put("must_not", mustNot); |
|||
} |
|||
if (should != null) { |
|||
bool.put("should", should); |
|||
} |
|||
JSONObject json = new JSONObject(); |
|||
json.put("bool", bool); |
|||
return json; |
|||
} |
|||
|
|||
/** |
|||
* @param field 要查询的字段 |
|||
* @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊* |
|||
* @return |
|||
*/ |
|||
public JSONObject buildQueryString(String field, String... args) { |
|||
if (field == null) { |
|||
return null; |
|||
} |
|||
StringBuilder sb = new StringBuilder(field).append(":("); |
|||
if (args != null) { |
|||
for (String arg : args) { |
|||
sb.append(arg).append(" "); |
|||
} |
|||
} |
|||
sb.append(")"); |
|||
return this.buildQueryString(sb.toString()); |
|||
} |
|||
|
|||
/** |
|||
* @return { "query_string": { "query": query } } |
|||
*/ |
|||
public JSONObject buildQueryString(String query) { |
|||
JSONObject queryString = new JSONObject(); |
|||
queryString.put("query", query); |
|||
JSONObject json = new JSONObject(); |
|||
json.put("query_string", queryString); |
|||
return json; |
|||
} |
|||
|
|||
/** |
|||
* @param field 查询字段 |
|||
* @param min 最小值 |
|||
* @param max 最大值 |
|||
* @param containMin 范围内是否包含最小值 |
|||
* @param containMax 范围内是否包含最大值 |
|||
* @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} } |
|||
*/ |
|||
public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) { |
|||
JSONObject inner = new JSONObject(); |
|||
if (min != null) { |
|||
if (containMin) { |
|||
inner.put("gte", min); |
|||
} else { |
|||
inner.put("gt", min); |
|||
} |
|||
} |
|||
if (max != null) { |
|||
if (containMax) { |
|||
inner.put("lte", max); |
|||
} else { |
|||
inner.put("lt", max); |
|||
} |
|||
} |
|||
JSONObject range = new JSONObject(); |
|||
range.put(field, inner); |
|||
JSONObject json = new JSONObject(); |
|||
json.put("range", range); |
|||
return json; |
|||
} |
|||
|
|||
} |
|||
|
@ -0,0 +1,98 @@ |
|||
package org.jeecg.common.es; |
|||
|
|||
/** |
|||
* 用于创建 ElasticSearch 的 queryString |
|||
* |
|||
* @author sunjianlei |
|||
*/ |
|||
public class QueryStringBuilder { |
|||
|
|||
StringBuilder builder; |
|||
|
|||
public QueryStringBuilder(String field, String str, boolean not, boolean addQuot) { |
|||
builder = this.createBuilder(field, str, not, addQuot); |
|||
} |
|||
|
|||
public QueryStringBuilder(String field, String str, boolean not) { |
|||
builder = this.createBuilder(field, str, not, true); |
|||
} |
|||
|
|||
/** |
|||
* 创建 StringBuilder |
|||
* |
|||
* @param field |
|||
* @param str |
|||
* @param not 是否是不匹配 |
|||
* @param addQuot 是否添加双引号 |
|||
* @return |
|||
*/ |
|||
public StringBuilder createBuilder(String field, String str, boolean not, boolean addQuot) { |
|||
StringBuilder sb = new StringBuilder(field).append(":("); |
|||
if (not) { |
|||
sb.append(" NOT "); |
|||
} |
|||
this.addQuotEffect(sb, str, addQuot); |
|||
return sb; |
|||
} |
|||
|
|||
public QueryStringBuilder and(String str) { |
|||
return this.and(str, true); |
|||
} |
|||
|
|||
public QueryStringBuilder and(String str, boolean addQuot) { |
|||
builder.append(" AND "); |
|||
this.addQuot(str, addQuot); |
|||
return this; |
|||
} |
|||
|
|||
public QueryStringBuilder or(String str) { |
|||
return this.or(str, true); |
|||
} |
|||
|
|||
public QueryStringBuilder or(String str, boolean addQuot) { |
|||
builder.append(" OR "); |
|||
this.addQuot(str, addQuot); |
|||
return this; |
|||
} |
|||
|
|||
public QueryStringBuilder not(String str) { |
|||
return this.not(str, true); |
|||
} |
|||
|
|||
public QueryStringBuilder not(String str, boolean addQuot) { |
|||
builder.append(" NOT "); |
|||
this.addQuot(str, addQuot); |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* 添加双引号(模糊查询,不能加双引号) |
|||
*/ |
|||
private QueryStringBuilder addQuot(String str, boolean addQuot) { |
|||
return this.addQuotEffect(this.builder, str, addQuot); |
|||
} |
|||
|
|||
/** |
|||
* 是否在两边加上双引号 |
|||
* @param builder |
|||
* @param str |
|||
* @param addQuot |
|||
* @return |
|||
*/ |
|||
private QueryStringBuilder addQuotEffect(StringBuilder builder, String str, boolean addQuot) { |
|||
if (addQuot) { |
|||
builder.append('"'); |
|||
} |
|||
builder.append(str); |
|||
if (addQuot) { |
|||
builder.append('"'); |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return builder.append(")").toString(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,23 @@ |
|||
package org.jeecg.common.exception; |
|||
|
|||
/** |
|||
* @Description: jeecg-boot自定义401异常 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public class JeecgBoot401Exception extends RuntimeException { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
public JeecgBoot401Exception(String message){ |
|||
super(message); |
|||
} |
|||
|
|||
public JeecgBoot401Exception(Throwable cause) |
|||
{ |
|||
super(cause); |
|||
} |
|||
|
|||
public JeecgBoot401Exception(String message, Throwable cause) |
|||
{ |
|||
super(message,cause); |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
package org.jeecg.common.exception; |
|||
|
|||
/** |
|||
* @Description: jeecg-boot自定义异常 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public class JeecgBootException extends RuntimeException { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
public JeecgBootException(String message){ |
|||
super(message); |
|||
} |
|||
|
|||
public JeecgBootException(Throwable cause) |
|||
{ |
|||
super(cause); |
|||
} |
|||
|
|||
public JeecgBootException(String message,Throwable cause) |
|||
{ |
|||
super(message,cause); |
|||
} |
|||
} |
@ -0,0 +1,136 @@ |
|||
package org.jeecg.common.exception; |
|||
|
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import org.apache.shiro.authz.AuthorizationException; |
|||
import org.apache.shiro.authz.UnauthorizedException; |
|||
import org.jeecg.common.api.vo.Result; |
|||
import org.jeecg.common.enums.SentinelErrorInfoEnum; |
|||
import org.springframework.dao.DataIntegrityViolationException; |
|||
import org.springframework.dao.DuplicateKeyException; |
|||
import org.springframework.data.redis.connection.PoolException; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.web.HttpRequestMethodNotSupportedException; |
|||
import org.springframework.web.bind.annotation.ExceptionHandler; |
|||
import org.springframework.web.bind.annotation.ResponseStatus; |
|||
import org.springframework.web.bind.annotation.RestControllerAdvice; |
|||
import org.springframework.web.multipart.MaxUploadSizeExceededException; |
|||
import org.springframework.web.servlet.NoHandlerFoundException; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
/** |
|||
* 异常处理器 |
|||
* |
|||
* @Author scott |
|||
* @Date 2019 |
|||
*/ |
|||
@RestControllerAdvice |
|||
@Slf4j |
|||
public class JeecgBootExceptionHandler { |
|||
|
|||
/** |
|||
* 处理自定义异常 |
|||
*/ |
|||
@ExceptionHandler(JeecgBootException.class) |
|||
public Result<?> handleJeecgBootException(JeecgBootException e){ |
|||
log.error(e.getMessage(), e); |
|||
return Result.error(e.getMessage()); |
|||
} |
|||
|
|||
/** |
|||
* 处理自定义微服务异常 |
|||
*/ |
|||
@ExceptionHandler(JeecgCloudException.class) |
|||
public Result<?> handleJeecgCloudException(JeecgCloudException e){ |
|||
log.error(e.getMessage(), e); |
|||
return Result.error(e.getMessage()); |
|||
} |
|||
|
|||
/** |
|||
* 处理自定义异常 |
|||
*/ |
|||
@ExceptionHandler(JeecgBoot401Exception.class) |
|||
@ResponseStatus(HttpStatus.UNAUTHORIZED) |
|||
public Result<?> handleJeecgBoot401Exception(JeecgBoot401Exception e){ |
|||
log.error(e.getMessage(), e); |
|||
return new Result(401,e.getMessage()); |
|||
} |
|||
|
|||
@ExceptionHandler(NoHandlerFoundException.class) |
|||
public Result<?> handlerNoFoundException(Exception e) { |
|||
log.error(e.getMessage(), e); |
|||
return Result.error(404, "路径不存在,请检查路径是否正确"); |
|||
} |
|||
|
|||
@ExceptionHandler(DuplicateKeyException.class) |
|||
public Result<?> handleDuplicateKeyException(DuplicateKeyException e){ |
|||
log.error(e.getMessage(), e); |
|||
return Result.error("数据库中已存在该记录"); |
|||
} |
|||
|
|||
@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class}) |
|||
public Result<?> handleAuthorizationException(AuthorizationException e){ |
|||
log.error(e.getMessage(), e); |
|||
return Result.noauth("没有权限,请联系管理员授权"); |
|||
} |
|||
|
|||
@ExceptionHandler(Exception.class) |
|||
public Result<?> handleException(Exception e){ |
|||
log.error(e.getMessage(), e); |
|||
//update-begin---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
|||
Throwable throwable = e.getCause(); |
|||
SentinelErrorInfoEnum errorInfoEnum = SentinelErrorInfoEnum.getErrorByException(throwable); |
|||
if (ObjectUtil.isNotEmpty(errorInfoEnum)) { |
|||
return Result.error(errorInfoEnum.getError()); |
|||
} |
|||
//update-end---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常
|
|||
return Result.error("操作失败,"+e.getMessage()); |
|||
} |
|||
|
|||
/** |
|||
* @Author 政辉 |
|||
* @param e |
|||
* @return |
|||
*/ |
|||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class) |
|||
public Result<?> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){ |
|||
StringBuffer sb = new StringBuffer(); |
|||
sb.append("不支持"); |
|||
sb.append(e.getMethod()); |
|||
sb.append("请求方法,"); |
|||
sb.append("支持以下"); |
|||
String [] methods = e.getSupportedMethods(); |
|||
if(methods!=null){ |
|||
for(String str:methods){ |
|||
sb.append(str); |
|||
sb.append("、"); |
|||
} |
|||
} |
|||
log.error(sb.toString(), e); |
|||
//return Result.error("没有权限,请联系管理员授权");
|
|||
return Result.error(405,sb.toString()); |
|||
} |
|||
|
|||
/** |
|||
* spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException |
|||
*/ |
|||
@ExceptionHandler(MaxUploadSizeExceededException.class) |
|||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) { |
|||
log.error(e.getMessage(), e); |
|||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! "); |
|||
} |
|||
|
|||
@ExceptionHandler(DataIntegrityViolationException.class) |
|||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) { |
|||
log.error(e.getMessage(), e); |
|||
//【issues/3624】数据库执行异常handleDataIntegrityViolationException提示有误 #3624
|
|||
return Result.error("执行数据库异常,违反了完整性例如:违反惟一约束、违反非空限制、字段内容超出长度等"); |
|||
} |
|||
|
|||
@ExceptionHandler(PoolException.class) |
|||
public Result<?> handlePoolException(PoolException e) { |
|||
log.error(e.getMessage(), e); |
|||
return Result.error("Redis 连接异常!"); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
package org.jeecg.common.handler; |
|||
|
|||
import com.alibaba.fastjson.JSONObject; |
|||
|
|||
/** |
|||
* 填值规则接口 |
|||
* |
|||
* @author Yan_东 |
|||
* 如需使用填值规则功能,规则实现类必须实现此接口 |
|||
*/ |
|||
public interface IFillRuleHandler { |
|||
|
|||
/** |
|||
* 填值规则 |
|||
* @param params 页面配置固定参数 |
|||
* @param formData 动态表单参数 |
|||
* @return |
|||
*/ |
|||
public Object execute(JSONObject params, JSONObject formData); |
|||
|
|||
} |
|||
|
@ -0,0 +1,19 @@ |
|||
package org.jeecg.common.system.annotation; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 将枚举类转化成字典数据 |
|||
* @Author taoYan |
|||
* @Date 2022/7/8 10:34 |
|||
**/ |
|||
@Target(ElementType.TYPE) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Documented |
|||
public @interface EnumDict { |
|||
|
|||
/** |
|||
* 作为字典数据的唯一编码 |
|||
*/ |
|||
String value() default ""; |
|||
} |
@ -0,0 +1,203 @@ |
|||
package org.jeecg.common.system.base.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.baomidou.mybatisplus.extension.service.IService; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.beanutils.PropertyUtils; |
|||
import org.apache.shiro.SecurityUtils; |
|||
import org.jeecg.common.api.vo.Result; |
|||
import org.jeecg.common.system.query.QueryGenerator; |
|||
import org.jeecg.common.system.vo.LoginUser; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.jeecgframework.poi.excel.ExcelImportUtil; |
|||
import org.jeecgframework.poi.excel.def.NormalExcelConstants; |
|||
import org.jeecgframework.poi.excel.entity.ExportParams; |
|||
import org.jeecgframework.poi.excel.entity.ImportParams; |
|||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType; |
|||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
import org.springframework.web.multipart.MultipartHttpServletRequest; |
|||
import org.springframework.web.servlet.ModelAndView; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* @Description: Controller基类 |
|||
* @Author: dangzhenghui@163.com |
|||
* @Date: 2019-4-21 8:13 |
|||
* @Version: 1.0 |
|||
*/ |
|||
@Slf4j |
|||
public class JeecgController<T, S extends IService<T>> { |
|||
/**issues/2933 JeecgController注入service时改用protected修饰,能避免重复引用service*/ |
|||
@Autowired |
|||
protected S service; |
|||
|
|||
@Value("${jeecg.path.upload}") |
|||
private String upLoadPath; |
|||
/** |
|||
* 导出excel |
|||
* |
|||
* @param request |
|||
*/ |
|||
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title) { |
|||
// Step.1 组装查询条件
|
|||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); |
|||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
|||
|
|||
// 过滤选中数据
|
|||
String selections = request.getParameter("selections"); |
|||
if (oConvertUtils.isNotEmpty(selections)) { |
|||
List<String> selectionList = Arrays.asList(selections.split(",")); |
|||
queryWrapper.in("id",selectionList); |
|||
} |
|||
// Step.2 获取导出数据
|
|||
List<T> exportList = service.list(queryWrapper); |
|||
|
|||
// Step.3 AutoPoi 导出Excel
|
|||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); |
|||
//此处设置的filename无效 ,前端会重更新设置一下
|
|||
mv.addObject(NormalExcelConstants.FILE_NAME, title); |
|||
mv.addObject(NormalExcelConstants.CLASS, clazz); |
|||
//update-begin--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置--------------------
|
|||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title); |
|||
exportParams.setImageBasePath(upLoadPath); |
|||
//update-end--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置----------------------
|
|||
mv.addObject(NormalExcelConstants.PARAMS,exportParams); |
|||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList); |
|||
return mv; |
|||
} |
|||
/** |
|||
* 根据每页sheet数量导出多sheet |
|||
* |
|||
* @param request |
|||
* @param object 实体类 |
|||
* @param clazz 实体类class |
|||
* @param title 标题 |
|||
* @param exportFields 导出字段自定义 |
|||
* @param pageNum 每个sheet的数据条数 |
|||
* @param request |
|||
*/ |
|||
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) { |
|||
// Step.1 组装查询条件
|
|||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); |
|||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
|||
// Step.2 计算分页sheet数据
|
|||
double total = service.count(); |
|||
int count = (int)Math.ceil(total/pageNum); |
|||
//update-begin-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
|||
// Step.3 过滤选中数据
|
|||
String selections = request.getParameter("selections"); |
|||
if (oConvertUtils.isNotEmpty(selections)) { |
|||
List<String> selectionList = Arrays.asList(selections.split(",")); |
|||
queryWrapper.in("id",selectionList); |
|||
} |
|||
//update-end-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
|||
// Step.4 多sheet处理
|
|||
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>(); |
|||
for (int i = 1; i <=count ; i++) { |
|||
Page<T> page = new Page<T>(i, pageNum); |
|||
IPage<T> pageList = service.page(page, queryWrapper); |
|||
List<T> exportList = pageList.getRecords(); |
|||
Map<String, Object> map = new HashMap<>(5); |
|||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath); |
|||
exportParams.setType(ExcelType.XSSF); |
|||
//map.put("title",exportParams);
|
|||
//表格Title
|
|||
map.put(NormalExcelConstants.PARAMS,exportParams); |
|||
//表格对应实体
|
|||
map.put(NormalExcelConstants.CLASS,clazz); |
|||
//数据集合
|
|||
map.put(NormalExcelConstants.DATA_LIST, exportList); |
|||
listMap.add(map); |
|||
} |
|||
// Step.4 AutoPoi 导出Excel
|
|||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); |
|||
//此处设置的filename无效 ,前端会重更新设置一下
|
|||
mv.addObject(NormalExcelConstants.FILE_NAME, title); |
|||
mv.addObject(NormalExcelConstants.MAP_LIST, listMap); |
|||
return mv; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 根据权限导出excel,传入导出字段参数 |
|||
* |
|||
* @param request |
|||
*/ |
|||
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields) { |
|||
ModelAndView mv = this.exportXls(request,object,clazz,title); |
|||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS,exportFields); |
|||
return mv; |
|||
} |
|||
|
|||
/** |
|||
* 获取对象ID |
|||
* |
|||
* @return |
|||
*/ |
|||
private String getId(T item) { |
|||
try { |
|||
return PropertyUtils.getProperty(item, "id").toString(); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 通过excel导入数据 |
|||
* |
|||
* @param request |
|||
* @param response |
|||
* @return |
|||
*/ |
|||
protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) { |
|||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; |
|||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); |
|||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { |
|||
// 获取上传文件对象
|
|||
MultipartFile file = entity.getValue(); |
|||
ImportParams params = new ImportParams(); |
|||
params.setTitleRows(2); |
|||
params.setHeadRows(1); |
|||
params.setNeedSave(true); |
|||
try { |
|||
List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params); |
|||
//update-begin-author:taoyan date:20190528 for:批量插入数据
|
|||
long start = System.currentTimeMillis(); |
|||
service.saveBatch(list); |
|||
//400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒
|
|||
//1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
|
|||
log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒"); |
|||
//update-end-author:taoyan date:20190528 for:批量插入数据
|
|||
return Result.ok("文件导入成功!数据行数:" + list.size()); |
|||
} catch (Exception e) { |
|||
//update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示
|
|||
String msg = e.getMessage(); |
|||
log.error(msg, e); |
|||
if(msg!=null && msg.indexOf("Duplicate entry")>=0){ |
|||
return Result.error("文件导入失败:有重复数据!"); |
|||
}else{ |
|||
return Result.error("文件导入失败:" + e.getMessage()); |
|||
} |
|||
//update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
|
|||
} finally { |
|||
try { |
|||
file.getInputStream().close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
return Result.error("文件导入失败!"); |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
package org.jeecg.common.system.base.entity; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
import org.jeecgframework.poi.excel.annotation.Excel; |
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.IdType; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
|
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
/** |
|||
* @Description: Entity基类 |
|||
* @Author: dangzhenghui@163.com |
|||
* @Date: 2019-4-28 |
|||
* @Version: 1.1 |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Accessors(chain = true) |
|||
public class JeecgEntity implements Serializable { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* ID |
|||
*/ |
|||
@TableId(type = IdType.ASSIGN_ID) |
|||
@ApiModelProperty(value = "ID") |
|||
private java.lang.String id; |
|||
|
|||
/** |
|||
* 创建人 |
|||
*/ |
|||
@ApiModelProperty(value = "创建人") |
|||
@Excel(name = "创建人", width = 15) |
|||
private java.lang.String createBy; |
|||
|
|||
/** |
|||
* 创建时间 |
|||
*/ |
|||
@ApiModelProperty(value = "创建时间") |
|||
@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
private java.util.Date createTime; |
|||
|
|||
/** |
|||
* 更新人 |
|||
*/ |
|||
@ApiModelProperty(value = "更新人") |
|||
@Excel(name = "更新人", width = 15) |
|||
private java.lang.String updateBy; |
|||
|
|||
/** |
|||
* 更新时间 |
|||
*/ |
|||
@ApiModelProperty(value = "更新时间") |
|||
@Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
private java.util.Date updateTime; |
|||
|
|||
} |
@ -0,0 +1,12 @@ |
|||
package org.jeecg.common.system.base.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
|
|||
/** |
|||
* @Description: Service基类 |
|||
* @Author: dangzhenghui@163.com |
|||
* @Date: 2019-4-21 8:13 |
|||
* @Version: 1.0 |
|||
*/ |
|||
public interface JeecgService<T> extends IService<T> { |
|||
} |
@ -0,0 +1,19 @@ |
|||
package org.jeecg.common.system.base.service.impl; |
|||
|
|||
import org.jeecg.common.system.base.entity.JeecgEntity; |
|||
import org.jeecg.common.system.base.service.JeecgService; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
/** |
|||
* @Description: ServiceImpl基类 |
|||
* @Author: dangzhenghui@163.com |
|||
* @Date: 2019-4-21 8:13 |
|||
* @Version: 1.0 |
|||
*/ |
|||
@Slf4j |
|||
public class JeecgServiceImpl<M extends BaseMapper<T>, T extends JeecgEntity> extends ServiceImpl<M, T> implements JeecgService<T> { |
|||
|
|||
} |
@ -0,0 +1,45 @@ |
|||
package org.jeecg.common.system.query; |
|||
|
|||
import org.jeecg.common.util.oConvertUtils; |
|||
|
|||
/** |
|||
* 查询链接规则 |
|||
* |
|||
* @Author Sunjianlei |
|||
*/ |
|||
public enum MatchTypeEnum { |
|||
|
|||
/**查询链接规则 AND*/ |
|||
AND("AND"), |
|||
/**查询链接规则 OR*/ |
|||
OR("OR"); |
|||
|
|||
private String value; |
|||
|
|||
MatchTypeEnum(String value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
public String getValue() { |
|||
return value; |
|||
} |
|||
|
|||
public static MatchTypeEnum getByValue(Object value) { |
|||
if (oConvertUtils.isEmpty(value)) { |
|||
return null; |
|||
} |
|||
return getByValue(value.toString()); |
|||
} |
|||
|
|||
public static MatchTypeEnum getByValue(String value) { |
|||
if (oConvertUtils.isEmpty(value)) { |
|||
return null; |
|||
} |
|||
for (MatchTypeEnum val : values()) { |
|||
if (val.getValue().toLowerCase().equals(value.toLowerCase())) { |
|||
return val; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
package org.jeecg.common.system.query; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* @Description: QueryCondition |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public class QueryCondition implements Serializable { |
|||
|
|||
private static final long serialVersionUID = 4740166316629191651L; |
|||
|
|||
private String field; |
|||
/** 组件的类型(例如:input、select、radio) */ |
|||
private String type; |
|||
/** |
|||
* 对应的数据库字段的类型 |
|||
* 支持:int、bigDecimal、short、long、float、double、boolean |
|||
*/ |
|||
private String dbType; |
|||
private String rule; |
|||
private String val; |
|||
|
|||
public String getField() { |
|||
return field; |
|||
} |
|||
|
|||
public void setField(String field) { |
|||
this.field = field; |
|||
} |
|||
|
|||
public String getType() { |
|||
return type; |
|||
} |
|||
|
|||
public void setType(String type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
public String getDbType() { |
|||
return dbType; |
|||
} |
|||
|
|||
public void setDbType(String dbType) { |
|||
this.dbType = dbType; |
|||
} |
|||
|
|||
public String getRule() { |
|||
return rule; |
|||
} |
|||
|
|||
public void setRule(String rule) { |
|||
this.rule = rule; |
|||
} |
|||
|
|||
public String getVal() { |
|||
return val; |
|||
} |
|||
|
|||
public void setVal(String val) { |
|||
this.val = val; |
|||
} |
|||
|
|||
@Override |
|||
public String toString(){ |
|||
StringBuffer sb =new StringBuffer(); |
|||
if(field == null || "".equals(field)){ |
|||
return ""; |
|||
} |
|||
sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.dbType).append(" ").append(this.val); |
|||
return sb.toString(); |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,86 @@ |
|||
package org.jeecg.common.system.query; |
|||
|
|||
import org.jeecg.common.util.oConvertUtils; |
|||
|
|||
/** |
|||
* Query 规则 常量 |
|||
* @Author Scott |
|||
* @Date 2019年02月14日 |
|||
*/ |
|||
public enum QueryRuleEnum { |
|||
|
|||
/**查询规则 大于*/ |
|||
GT(">","gt","大于"), |
|||
/**查询规则 大于等于*/ |
|||
GE(">=","ge","大于等于"), |
|||
/**查询规则 小于*/ |
|||
LT("<","lt","小于"), |
|||
/**查询规则 小于等于*/ |
|||
LE("<=","le","小于等于"), |
|||
/**查询规则 等于*/ |
|||
EQ("=","eq","等于"), |
|||
/**查询规则 不等于*/ |
|||
NE("!=","ne","不等于"), |
|||
/**查询规则 包含*/ |
|||
IN("IN","in","包含"), |
|||
/**查询规则 全模糊*/ |
|||
LIKE("LIKE","like","全模糊"), |
|||
/**查询规则 左模糊*/ |
|||
LEFT_LIKE("LEFT_LIKE","left_like","左模糊"), |
|||
/**查询规则 右模糊*/ |
|||
RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"), |
|||
/**查询规则 带加号等于*/ |
|||
EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"), |
|||
/**查询规则 多词模糊匹配*/ |
|||
LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"), |
|||
/**查询规则 自定义SQL片段*/ |
|||
SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段"); |
|||
|
|||
private String value; |
|||
|
|||
private String condition; |
|||
|
|||
private String msg; |
|||
|
|||
QueryRuleEnum(String value, String condition, String msg){ |
|||
this.value = value; |
|||
this.condition = condition; |
|||
this.msg = msg; |
|||
} |
|||
|
|||
public String getValue() { |
|||
return value; |
|||
} |
|||
|
|||
public void setValue(String value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
public String getMsg() { |
|||
return msg; |
|||
} |
|||
|
|||
public void setMsg(String msg) { |
|||
this.msg = msg; |
|||
} |
|||
|
|||
public String getCondition() { |
|||
return condition; |
|||
} |
|||
|
|||
public void setCondition(String condition) { |
|||
this.condition = condition; |
|||
} |
|||
|
|||
public static QueryRuleEnum getByValue(String value){ |
|||
if(oConvertUtils.isEmpty(value)) { |
|||
return null; |
|||
} |
|||
for(QueryRuleEnum val :values()){ |
|||
if (val.getValue().equals(value) || val.getCondition().equals(value)){ |
|||
return val; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,106 @@ |
|||
package org.jeecg.common.system.util; |
|||
|
|||
import org.jeecg.common.system.vo.SysPermissionDataRuleModel; |
|||
import org.jeecg.common.system.vo.SysUserCacheInfo; |
|||
import org.jeecg.common.util.SpringContextUtils; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @ClassName: JeecgDataAutorUtils |
|||
* @Description: 数据权限查询规则容器工具类 |
|||
* @Author: 张代浩 |
|||
* @Date: 2012-12-15 下午11:27:39 |
|||
* |
|||
*/ |
|||
public class JeecgDataAutorUtils { |
|||
|
|||
public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES"; |
|||
|
|||
public static final String MENU_DATA_AUTHOR_RULE_SQL = "MENU_DATA_AUTHOR_RULE_SQL"; |
|||
|
|||
public static final String SYS_USER_INFO = "SYS_USER_INFO"; |
|||
|
|||
/** |
|||
* 往链接请求里面,传入数据查询条件 |
|||
* |
|||
* @param request |
|||
* @param dataRules |
|||
*/ |
|||
public static synchronized void installDataSearchConditon(HttpServletRequest request, List<SysPermissionDataRuleModel> dataRules) { |
|||
@SuppressWarnings("unchecked") |
|||
// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
|
|||
List<SysPermissionDataRuleModel> list = (List<SysPermissionDataRuleModel>)loadDataSearchConditon(); |
|||
if (list==null) { |
|||
// 2.如果不存在,则new一个list
|
|||
list = new ArrayList<SysPermissionDataRuleModel>(); |
|||
} |
|||
for (SysPermissionDataRuleModel tsDataRule : dataRules) { |
|||
list.add(tsDataRule); |
|||
} |
|||
// 3.往list里面增量存指
|
|||
request.setAttribute(MENU_DATA_AUTHOR_RULES, list); |
|||
} |
|||
|
|||
/** |
|||
* 获取请求对应的数据权限规则 |
|||
* |
|||
* @return |
|||
*/ |
|||
@SuppressWarnings("unchecked") |
|||
public static synchronized List<SysPermissionDataRuleModel> loadDataSearchConditon() { |
|||
return (List<SysPermissionDataRuleModel>) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 获取请求对应的数据权限SQL |
|||
* |
|||
* @return |
|||
*/ |
|||
public static synchronized String loadDataSearchConditonSqlString() { |
|||
return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL); |
|||
} |
|||
|
|||
/** |
|||
* 往链接请求里面,传入数据查询条件 |
|||
* |
|||
* @param request |
|||
* @param sql |
|||
*/ |
|||
public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) { |
|||
String ruleSql = (String) loadDataSearchConditonSqlString(); |
|||
if (!StringUtils.hasText(ruleSql)) { |
|||
request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL,sql); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 将用户信息存到request |
|||
* @param request |
|||
* @param userinfo |
|||
*/ |
|||
public static synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) { |
|||
request.setAttribute(SYS_USER_INFO, userinfo); |
|||
} |
|||
|
|||
/** |
|||
* 将用户信息存到request |
|||
* @param userinfo |
|||
*/ |
|||
public static synchronized void installUserInfo(SysUserCacheInfo userinfo) { |
|||
SpringContextUtils.getHttpServletRequest().setAttribute(SYS_USER_INFO, userinfo); |
|||
} |
|||
|
|||
/** |
|||
* 从request获取用户信息 |
|||
* @return |
|||
*/ |
|||
public static synchronized SysUserCacheInfo loadUserInfo() { |
|||
return (SysUserCacheInfo) SpringContextUtils.getHttpServletRequest().getAttribute(SYS_USER_INFO); |
|||
|
|||
} |
|||
} |
@ -0,0 +1,252 @@ |
|||
package org.jeecg.common.system.util; |
|||
|
|||
import com.auth0.jwt.JWT; |
|||
import com.auth0.jwt.JWTVerifier; |
|||
import com.auth0.jwt.algorithms.Algorithm; |
|||
import com.auth0.jwt.exceptions.JWTDecodeException; |
|||
import com.auth0.jwt.interfaces.DecodedJWT; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.google.common.base.Joiner; |
|||
|
|||
import java.io.IOException; |
|||
import java.io.OutputStream; |
|||
import java.util.Date; |
|||
import javax.servlet.ServletResponse; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import javax.servlet.http.HttpSession; |
|||
|
|||
import org.apache.shiro.SecurityUtils; |
|||
import org.jeecg.common.api.vo.Result; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.constant.DataBaseConstant; |
|||
import org.jeecg.common.constant.SymbolConstant; |
|||
import org.jeecg.common.exception.JeecgBootException; |
|||
import org.jeecg.common.system.vo.LoginUser; |
|||
import org.jeecg.common.system.vo.SysUserCacheInfo; |
|||
import org.jeecg.common.util.DateUtils; |
|||
import org.jeecg.common.util.SpringContextUtils; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
|
|||
/** |
|||
* @Author Scott |
|||
* @Date 2018-07-12 14:23 |
|||
* @Desc JWT工具类 |
|||
**/ |
|||
public class JwtUtil { |
|||
|
|||
/**Token有效期为1小时(Token在reids中缓存时间为两倍)*/ |
|||
public static final long EXPIRE_TIME = 60 * 60 * 1000; |
|||
static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET; |
|||
|
|||
/** |
|||
* |
|||
* @param response |
|||
* @param code |
|||
* @param errorMsg |
|||
*/ |
|||
public static void responseError(ServletResponse response, Integer code, String errorMsg) { |
|||
HttpServletResponse httpServletResponse = (HttpServletResponse) response; |
|||
// issues/I4YH95浏览器显示乱码问题
|
|||
httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8"); |
|||
Result jsonResult = new Result(code, errorMsg); |
|||
OutputStream os = null; |
|||
try { |
|||
os = httpServletResponse.getOutputStream(); |
|||
httpServletResponse.setCharacterEncoding("UTF-8"); |
|||
httpServletResponse.setStatus(code); |
|||
os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8")); |
|||
os.flush(); |
|||
os.close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 校验token是否正确 |
|||
* |
|||
* @param token 密钥 |
|||
* @param secret 用户的密码 |
|||
* @return 是否正确 |
|||
*/ |
|||
public static boolean verify(String token, String username, String secret) { |
|||
try { |
|||
// 根据密码生成JWT效验器
|
|||
Algorithm algorithm = Algorithm.HMAC256(secret); |
|||
JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build(); |
|||
// 效验TOKEN
|
|||
DecodedJWT jwt = verifier.verify(token); |
|||
return true; |
|||
} catch (Exception exception) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获得token中的信息无需secret解密也能获得 |
|||
* |
|||
* @return token中包含的用户名 |
|||
*/ |
|||
public static String getUsername(String token) { |
|||
try { |
|||
DecodedJWT jwt = JWT.decode(token); |
|||
return jwt.getClaim("username").asString(); |
|||
} catch (JWTDecodeException e) { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 生成签名,5min后过期 |
|||
* |
|||
* @param username 用户名 |
|||
* @param secret 用户的密码 |
|||
* @return 加密的token |
|||
*/ |
|||
public static String sign(String username, String secret) { |
|||
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); |
|||
Algorithm algorithm = Algorithm.HMAC256(secret); |
|||
// 附带username信息
|
|||
return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 根据request中的token获取用户账号 |
|||
* |
|||
* @param request |
|||
* @return |
|||
* @throws JeecgBootException |
|||
*/ |
|||
public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException { |
|||
String accessToken = request.getHeader("X-Access-Token"); |
|||
String username = getUsername(accessToken); |
|||
if (oConvertUtils.isEmpty(username)) { |
|||
throw new JeecgBootException("未获取到用户"); |
|||
} |
|||
return username; |
|||
} |
|||
|
|||
/** |
|||
* 从session中获取变量 |
|||
* @param key |
|||
* @return |
|||
*/ |
|||
public static String getSessionData(String key) { |
|||
//${myVar}%
|
|||
//得到${} 后面的值
|
|||
String moshi = ""; |
|||
String wellNumber = WELL_NUMBER; |
|||
|
|||
if(key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET)!=-1){ |
|||
moshi = key.substring(key.indexOf("}")+1); |
|||
} |
|||
String returnValue = null; |
|||
if (key.contains(wellNumber)) { |
|||
key = key.substring(2,key.indexOf("}")); |
|||
} |
|||
if (oConvertUtils.isNotEmpty(key)) { |
|||
HttpSession session = SpringContextUtils.getHttpServletRequest().getSession(); |
|||
returnValue = (String) session.getAttribute(key); |
|||
} |
|||
//结果加上${} 后面的值
|
|||
if(returnValue!=null){returnValue = returnValue + moshi;} |
|||
return returnValue; |
|||
} |
|||
|
|||
/** |
|||
* 从当前用户中获取变量 |
|||
* @param key |
|||
* @param user |
|||
* @return |
|||
*/ |
|||
public static String getUserSystemData(String key,SysUserCacheInfo user) { |
|||
if(user==null) { |
|||
user = JeecgDataAutorUtils.loadUserInfo(); |
|||
} |
|||
//#{sys_user_code}%
|
|||
|
|||
// 获取登录用户信息
|
|||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
|||
|
|||
String moshi = ""; |
|||
String wellNumber = WELL_NUMBER; |
|||
if(key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET)!=-1){ |
|||
moshi = key.substring(key.indexOf("}")+1); |
|||
} |
|||
String returnValue = null; |
|||
//针对特殊标示处理#{sysOrgCode},判断替换
|
|||
if (key.contains(wellNumber)) { |
|||
key = key.substring(2,key.indexOf("}")); |
|||
} else { |
|||
key = key; |
|||
} |
|||
//替换为系统登录用户帐号
|
|||
if (key.equals(DataBaseConstant.SYS_USER_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_CODE_TABLE)) { |
|||
if(user==null) { |
|||
returnValue = sysUser.getUsername(); |
|||
}else { |
|||
returnValue = user.getSysUserCode(); |
|||
} |
|||
} |
|||
//替换为系统登录用户真实名字
|
|||
else if (key.equals(DataBaseConstant.SYS_USER_NAME)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_NAME_TABLE)) { |
|||
if(user==null) { |
|||
returnValue = sysUser.getRealname(); |
|||
}else { |
|||
returnValue = user.getSysUserName(); |
|||
} |
|||
} |
|||
|
|||
//替换为系统用户登录所使用的机构编码
|
|||
else if (key.equals(DataBaseConstant.SYS_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) { |
|||
if(user==null) { |
|||
returnValue = sysUser.getOrgCode(); |
|||
}else { |
|||
returnValue = user.getSysOrgCode(); |
|||
} |
|||
} |
|||
//替换为系统用户所拥有的所有机构编码
|
|||
else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) { |
|||
if(user==null){ |
|||
//TODO 暂时使用用户登录部门,存在逻辑缺陷,不是用户所拥有的部门
|
|||
returnValue = sysUser.getOrgCode(); |
|||
}else{ |
|||
if(user.isOneDepart()) { |
|||
returnValue = user.getSysMultiOrgCode().get(0); |
|||
}else { |
|||
returnValue = Joiner.on(",").join(user.getSysMultiOrgCode()); |
|||
} |
|||
} |
|||
} |
|||
//替换为当前系统时间(年月日)
|
|||
else if (key.equals(DataBaseConstant.SYS_DATE)|| key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) { |
|||
returnValue = DateUtils.formatDate(); |
|||
} |
|||
//替换为当前系统时间(年月日时分秒)
|
|||
else if (key.equals(DataBaseConstant.SYS_TIME)|| key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) { |
|||
returnValue = DateUtils.now(); |
|||
} |
|||
//流程状态默认值(默认未发起)
|
|||
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) { |
|||
returnValue = "1"; |
|||
} |
|||
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
|
|||
else if (key.equals(DataBaseConstant.TENANT_ID) || key.toLowerCase().equals(DataBaseConstant.TENANT_ID_TABLE)){ |
|||
returnValue = sysUser.getRelTenantIds(); |
|||
boolean flag = returnValue != null && returnValue.indexOf(SymbolConstant.COMMA) > 0; |
|||
if(oConvertUtils.isEmpty(returnValue) || flag){ |
|||
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID); |
|||
} |
|||
} |
|||
//update-end-author:taoyan date:20210330 for:多租户ID作为系统变量
|
|||
if(returnValue!=null){returnValue = returnValue + moshi;} |
|||
return returnValue; |
|||
} |
|||
|
|||
// public static void main(String[] args) {
|
|||
// String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0";
|
|||
// System.out.println(JwtUtil.getUsername(token));
|
|||
// }
|
|||
} |
@ -0,0 +1,111 @@ |
|||
package org.jeecg.common.system.util; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.jeecg.common.system.annotation.EnumDict; |
|||
import org.jeecg.common.system.vo.DictModel; |
|||
import org.jeecg.common.util.oConvertUtils; |
|||
import org.springframework.core.io.Resource; |
|||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; |
|||
import org.springframework.core.io.support.ResourcePatternResolver; |
|||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; |
|||
import org.springframework.core.type.classreading.MetadataReader; |
|||
import org.springframework.core.type.classreading.MetadataReaderFactory; |
|||
import org.springframework.util.ClassUtils; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 资源加载工具类 |
|||
* @Author taoYan |
|||
* @Date 2022/7/8 10:40 |
|||
**/ |
|||
@Slf4j |
|||
public class ResourceUtil { |
|||
|
|||
|
|||
/** |
|||
* 枚举字典数据 |
|||
*/ |
|||
private final static Map<String, List<DictModel>> enumDictData = new HashMap<>(5); |
|||
|
|||
/** |
|||
* 所有java类 |
|||
*/ |
|||
private final static String CLASS_PATTERN="/**/*.class"; |
|||
|
|||
/** |
|||
* 包路径 org.jeecg |
|||
*/ |
|||
private final static String BASE_PACKAGE = "org.jeecg"; |
|||
|
|||
/** |
|||
* 枚举类中获取字典数据的方法名 |
|||
*/ |
|||
private final static String METHOD_NAME = "getDictList"; |
|||
|
|||
/** |
|||
* 获取枚举类对应的字典数据 SysDictServiceImpl#queryAllDictItems() |
|||
* @return |
|||
*/ |
|||
public static Map<String, List<DictModel>> getEnumDictData(){ |
|||
if(enumDictData.keySet().size()>0){ |
|||
return enumDictData; |
|||
} |
|||
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); |
|||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + CLASS_PATTERN; |
|||
try { |
|||
Resource[] resources = resourcePatternResolver.getResources(pattern); |
|||
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver); |
|||
for (Resource resource : resources) { |
|||
MetadataReader reader = readerFactory.getMetadataReader(resource); |
|||
String classname = reader.getClassMetadata().getClassName(); |
|||
Class<?> clazz = Class.forName(classname); |
|||
EnumDict enumDict = clazz.getAnnotation(EnumDict.class); |
|||
if (enumDict != null) { |
|||
EnumDict annotation = clazz.getAnnotation(EnumDict.class); |
|||
String key = annotation.value(); |
|||
if(oConvertUtils.isNotEmpty(key)){ |
|||
List<DictModel> list = (List<DictModel>) clazz.getDeclaredMethod(METHOD_NAME).invoke(null); |
|||
enumDictData.put(key, list); |
|||
} |
|||
} |
|||
} |
|||
}catch (Exception e){ |
|||
log.error("获取枚举类字典数据异常", e.getMessage()); |
|||
// e.printStackTrace();
|
|||
} |
|||
return enumDictData; |
|||
} |
|||
|
|||
/** |
|||
* 用于后端字典翻译 SysDictServiceImpl#queryManyDictByKeys(java.util.List, java.util.List) |
|||
* @param dictCodeList |
|||
* @param keys |
|||
* @return |
|||
*/ |
|||
public static Map<String, List<DictModel>> queryManyDictByKeys(List<String> dictCodeList, List<String> keys){ |
|||
if(enumDictData.keySet().size()==0){ |
|||
getEnumDictData(); |
|||
} |
|||
Map<String, List<DictModel>> map = new HashMap<>(); |
|||
for (String code : enumDictData.keySet()) { |
|||
if(dictCodeList.indexOf(code)>=0){ |
|||
List<DictModel> dictItemList = enumDictData.get(code); |
|||
for(DictModel dm: dictItemList){ |
|||
String value = dm.getValue(); |
|||
if(keys.indexOf(value)>=0){ |
|||
List<DictModel> list = new ArrayList<>(); |
|||
list.add(new DictModel(value, dm.getText())); |
|||
map.put(code,list); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return map; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,40 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* @Description: 文档管理 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Accessors(chain = true) |
|||
@JsonIgnoreProperties(ignoreUnknown = true) |
|||
public class ComboModel implements Serializable { |
|||
private String id; |
|||
private String title; |
|||
/**文档管理 表单table默认选中*/ |
|||
private boolean checked; |
|||
/**文档管理 表单table 用户账号*/ |
|||
private String username; |
|||
/**文档管理 表单table 用户邮箱*/ |
|||
private String email; |
|||
/**文档管理 表单table 角色编码*/ |
|||
private String roleCode; |
|||
|
|||
public ComboModel(){ |
|||
|
|||
}; |
|||
|
|||
public ComboModel(String id,String title,boolean checked,String username){ |
|||
this.id = id; |
|||
this.title = title; |
|||
this.checked = false; |
|||
this.username = username; |
|||
}; |
|||
} |
@ -0,0 +1,53 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
/** |
|||
* @Description: 字典类 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Accessors(chain = true) |
|||
@JsonIgnoreProperties(ignoreUnknown = true) |
|||
public class DictModel implements Serializable{ |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
public DictModel() { |
|||
} |
|||
|
|||
public DictModel(String value, String text) { |
|||
this.value = value; |
|||
this.text = text; |
|||
} |
|||
|
|||
/** |
|||
* 字典value |
|||
*/ |
|||
private String value; |
|||
/** |
|||
* 字典文本 |
|||
*/ |
|||
private String text; |
|||
|
|||
/** |
|||
* 特殊用途: JgEditableTable |
|||
* @return |
|||
*/ |
|||
public String getTitle() { |
|||
return this.text; |
|||
} |
|||
/** |
|||
* 特殊用途: vue3 Select组件 |
|||
*/ |
|||
public String getLabel() { |
|||
return this.text; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,19 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
/** |
|||
* 查询多个字典时用到 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class DictModelMany extends DictModel { |
|||
|
|||
/** |
|||
* 字典code,根据多个字段code查询时才用到,用于区分不同的字典选项 |
|||
*/ |
|||
private String dictCode; |
|||
|
|||
} |
@ -0,0 +1,35 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* 字典查询参数实体 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class DictQuery { |
|||
/** |
|||
* 表名 |
|||
*/ |
|||
private String table; |
|||
/** |
|||
* 存储列 |
|||
*/ |
|||
private String code; |
|||
|
|||
/** |
|||
* 显示列 |
|||
*/ |
|||
private String text; |
|||
|
|||
/** |
|||
* 关键字查询 |
|||
*/ |
|||
private String keyword; |
|||
|
|||
/** |
|||
* 存储列的值 用于回显查询 |
|||
*/ |
|||
private String codeValue; |
|||
|
|||
} |
@ -0,0 +1,58 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import lombok.Data; |
|||
import org.springframework.beans.BeanUtils; |
|||
|
|||
/** |
|||
* @Description: 数据源 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class DynamicDataSourceModel { |
|||
|
|||
public DynamicDataSourceModel() { |
|||
|
|||
} |
|||
|
|||
public DynamicDataSourceModel(Object dbSource) { |
|||
if (dbSource != null) { |
|||
BeanUtils.copyProperties(dbSource, this); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* id |
|||
*/ |
|||
private java.lang.String id; |
|||
/** |
|||
* 数据源编码 |
|||
*/ |
|||
private java.lang.String code; |
|||
/** |
|||
* 数据库类型 |
|||
*/ |
|||
private java.lang.String dbType; |
|||
/** |
|||
* 驱动类 |
|||
*/ |
|||
private java.lang.String dbDriver; |
|||
/** |
|||
* 数据源地址 |
|||
*/ |
|||
private java.lang.String dbUrl; |
|||
|
|||
// /**
|
|||
// * 数据库名称
|
|||
// */
|
|||
// private java.lang.String dbName;
|
|||
|
|||
/** |
|||
* 用户名 |
|||
*/ |
|||
private java.lang.String dbUsername; |
|||
/** |
|||
* 密码 |
|||
*/ |
|||
private java.lang.String dbPassword; |
|||
|
|||
} |
@ -0,0 +1,130 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import java.util.Date; |
|||
|
|||
import org.jeecg.common.desensitization.annotation.SensitiveField; |
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
/** |
|||
* <p> |
|||
* 在线用户信息 |
|||
* </p> |
|||
* |
|||
* @Author scott |
|||
* @since 2018-12-20 |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Accessors(chain = true) |
|||
public class LoginUser { |
|||
|
|||
/** |
|||
* 登录人id |
|||
*/ |
|||
@SensitiveField |
|||
private String id; |
|||
|
|||
/** |
|||
* 登录人账号 |
|||
*/ |
|||
@SensitiveField |
|||
private String username; |
|||
|
|||
/** |
|||
* 登录人名字 |
|||
*/ |
|||
@SensitiveField |
|||
private String realname; |
|||
|
|||
/** |
|||
* 登录人密码 |
|||
*/ |
|||
@SensitiveField |
|||
private String password; |
|||
|
|||
/** |
|||
* 当前登录部门code |
|||
*/ |
|||
private String orgCode; |
|||
/** |
|||
* 头像 |
|||
*/ |
|||
@SensitiveField |
|||
private String avatar; |
|||
|
|||
/** |
|||
* 生日 |
|||
*/ |
|||
@SensitiveField |
|||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd") |
|||
private Date birthday; |
|||
|
|||
/** |
|||
* 性别(1:男 2:女) |
|||
*/ |
|||
private Integer sex; |
|||
|
|||
/** |
|||
* 电子邮件 |
|||
*/ |
|||
@SensitiveField |
|||
private String email; |
|||
|
|||
/** |
|||
* 电话 |
|||
*/ |
|||
@SensitiveField |
|||
private String phone; |
|||
|
|||
/** |
|||
* 状态(1:正常 2:冻结 ) |
|||
*/ |
|||
private Integer status; |
|||
|
|||
private Integer delFlag; |
|||
/** |
|||
* 同步工作流引擎1同步0不同步 |
|||
*/ |
|||
private Integer activitiSync; |
|||
|
|||
/** |
|||
* 创建时间 |
|||
*/ |
|||
private Date createTime; |
|||
|
|||
/** |
|||
* 身份(1 普通员工 2 上级) |
|||
*/ |
|||
private Integer userIdentity; |
|||
|
|||
/** |
|||
* 管理部门ids |
|||
*/ |
|||
private String departIds; |
|||
|
|||
/** |
|||
* 职务,关联职务表 |
|||
*/ |
|||
@SensitiveField |
|||
private String post; |
|||
|
|||
/** |
|||
* 座机号 |
|||
*/ |
|||
@SensitiveField |
|||
private String telephone; |
|||
|
|||
/**多租户id配置,编辑用户的时候设置*/ |
|||
private String relTenantIds; |
|||
|
|||
/**设备id uniapp推送用*/ |
|||
private String clientId; |
|||
|
|||
} |
@ -0,0 +1,32 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 下拉树 model |
|||
* |
|||
* @author jeecg-boot |
|||
*/ |
|||
@Data |
|||
public class SelectTreeModel implements Serializable { |
|||
|
|||
private String key; |
|||
private String title; |
|||
private String value; |
|||
/** |
|||
* 父Id |
|||
*/ |
|||
private String parentId; |
|||
/** |
|||
* 是否是叶节点 |
|||
*/ |
|||
private boolean isLeaf; |
|||
/** |
|||
* 子节点 |
|||
*/ |
|||
private List<SelectTreeModel> children; |
|||
|
|||
} |
@ -0,0 +1,52 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import org.jeecgframework.poi.excel.annotation.Excel; |
|||
|
|||
/** |
|||
* @Author qinfeng |
|||
* @Date 2020/2/19 12:01 |
|||
* @Description: |
|||
* @Version 1.0 |
|||
*/ |
|||
public class SysCategoryModel { |
|||
/**主键*/ |
|||
private java.lang.String id; |
|||
/**父级节点*/ |
|||
private java.lang.String pid; |
|||
/**类型名称*/ |
|||
private java.lang.String name; |
|||
/**类型编码*/ |
|||
private java.lang.String code; |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getPid() { |
|||
return pid; |
|||
} |
|||
|
|||
public void setPid(String pid) { |
|||
this.pid = pid; |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public void setName(String name) { |
|||
this.name = name; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public void setCode(String code) { |
|||
this.code = code; |
|||
} |
|||
} |
@ -0,0 +1,148 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
/** |
|||
* 部门机构model |
|||
* @author: lvdandan |
|||
*/ |
|||
public class SysDepartModel { |
|||
/**ID*/ |
|||
private String id; |
|||
/**父机构ID*/ |
|||
private String parentId; |
|||
/**机构/部门名称*/ |
|||
private String departName; |
|||
/**英文名*/ |
|||
private String departNameEn; |
|||
/**缩写*/ |
|||
private String departNameAbbr; |
|||
/**排序*/ |
|||
private Integer departOrder; |
|||
/**描述*/ |
|||
private String description; |
|||
/**机构类别 1组织机构,2岗位*/ |
|||
private String orgCategory; |
|||
/**机构类型*/ |
|||
private String orgType; |
|||
/**机构编码*/ |
|||
private String orgCode; |
|||
/**手机号*/ |
|||
private String mobile; |
|||
/**传真*/ |
|||
private String fax; |
|||
/**地址*/ |
|||
private String address; |
|||
/**备注*/ |
|||
private String memo; |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getParentId() { |
|||
return parentId; |
|||
} |
|||
|
|||
public void setParentId(String parentId) { |
|||
this.parentId = parentId; |
|||
} |
|||
|
|||
public String getDepartName() { |
|||
return departName; |
|||
} |
|||
|
|||
public void setDepartName(String departName) { |
|||
this.departName = departName; |
|||
} |
|||
|
|||
public String getDepartNameEn() { |
|||
return departNameEn; |
|||
} |
|||
|
|||
public void setDepartNameEn(String departNameEn) { |
|||
this.departNameEn = departNameEn; |
|||
} |
|||
|
|||
public String getDepartNameAbbr() { |
|||
return departNameAbbr; |
|||
} |
|||
|
|||
public void setDepartNameAbbr(String departNameAbbr) { |
|||
this.departNameAbbr = departNameAbbr; |
|||
} |
|||
|
|||
public Integer getDepartOrder() { |
|||
return departOrder; |
|||
} |
|||
|
|||
public void setDepartOrder(Integer departOrder) { |
|||
this.departOrder = departOrder; |
|||
} |
|||
|
|||
public String getDescription() { |
|||
return description; |
|||
} |
|||
|
|||
public void setDescription(String description) { |
|||
this.description = description; |
|||
} |
|||
|
|||
public String getOrgCategory() { |
|||
return orgCategory; |
|||
} |
|||
|
|||
public void setOrgCategory(String orgCategory) { |
|||
this.orgCategory = orgCategory; |
|||
} |
|||
|
|||
public String getOrgType() { |
|||
return orgType; |
|||
} |
|||
|
|||
public void setOrgType(String orgType) { |
|||
this.orgType = orgType; |
|||
} |
|||
|
|||
public String getOrgCode() { |
|||
return orgCode; |
|||
} |
|||
|
|||
public void setOrgCode(String orgCode) { |
|||
this.orgCode = orgCode; |
|||
} |
|||
|
|||
public String getMobile() { |
|||
return mobile; |
|||
} |
|||
|
|||
public void setMobile(String mobile) { |
|||
this.mobile = mobile; |
|||
} |
|||
|
|||
public String getFax() { |
|||
return fax; |
|||
} |
|||
|
|||
public void setFax(String fax) { |
|||
this.fax = fax; |
|||
} |
|||
|
|||
public String getAddress() { |
|||
return address; |
|||
} |
|||
|
|||
public void setAddress(String address) { |
|||
this.address = address; |
|||
} |
|||
|
|||
public String getMemo() { |
|||
return memo; |
|||
} |
|||
|
|||
public void setMemo(String memo) { |
|||
this.memo = memo; |
|||
} |
|||
} |
@ -0,0 +1,151 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.IdType; |
|||
import com.baomidou.mybatisplus.annotation.TableId; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.experimental.Accessors; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* <p> |
|||
* 菜单权限规则表 |
|||
* </p> |
|||
* |
|||
* @Author huangzhilin |
|||
* @since 2019-03-29 |
|||
*/ |
|||
public class SysPermissionDataRuleModel { |
|||
|
|||
/** |
|||
* id |
|||
*/ |
|||
private String id; |
|||
|
|||
/** |
|||
* 对应的菜单id |
|||
*/ |
|||
private String permissionId; |
|||
|
|||
/** |
|||
* 规则名称 |
|||
*/ |
|||
private String ruleName; |
|||
|
|||
/** |
|||
* 字段 |
|||
*/ |
|||
private String ruleColumn; |
|||
|
|||
/** |
|||
* 条件 |
|||
*/ |
|||
private String ruleConditions; |
|||
|
|||
/** |
|||
* 规则值 |
|||
*/ |
|||
private String ruleValue; |
|||
|
|||
/** |
|||
* 创建时间 |
|||
*/ |
|||
private Date createTime; |
|||
|
|||
/** |
|||
* 创建人 |
|||
*/ |
|||
private String createBy; |
|||
|
|||
/** |
|||
* 修改时间 |
|||
*/ |
|||
private Date updateTime; |
|||
|
|||
/** |
|||
* 修改人 |
|||
*/ |
|||
private String updateBy; |
|||
|
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getPermissionId() { |
|||
return permissionId; |
|||
} |
|||
|
|||
public void setPermissionId(String permissionId) { |
|||
this.permissionId = permissionId; |
|||
} |
|||
|
|||
public String getRuleName() { |
|||
return ruleName; |
|||
} |
|||
|
|||
public void setRuleName(String ruleName) { |
|||
this.ruleName = ruleName; |
|||
} |
|||
|
|||
public String getRuleColumn() { |
|||
return ruleColumn; |
|||
} |
|||
|
|||
public void setRuleColumn(String ruleColumn) { |
|||
this.ruleColumn = ruleColumn; |
|||
} |
|||
|
|||
public String getRuleConditions() { |
|||
return ruleConditions; |
|||
} |
|||
|
|||
public void setRuleConditions(String ruleConditions) { |
|||
this.ruleConditions = ruleConditions; |
|||
} |
|||
|
|||
public String getRuleValue() { |
|||
return ruleValue; |
|||
} |
|||
|
|||
public void setRuleValue(String ruleValue) { |
|||
this.ruleValue = ruleValue; |
|||
} |
|||
|
|||
public Date getCreateTime() { |
|||
return createTime; |
|||
} |
|||
|
|||
public void setCreateTime(Date createTime) { |
|||
this.createTime = createTime; |
|||
} |
|||
|
|||
public String getCreateBy() { |
|||
return createBy; |
|||
} |
|||
|
|||
public void setCreateBy(String createBy) { |
|||
this.createBy = createBy; |
|||
} |
|||
|
|||
public Date getUpdateTime() { |
|||
return updateTime; |
|||
} |
|||
|
|||
public void setUpdateTime(Date updateTime) { |
|||
this.updateTime = updateTime; |
|||
} |
|||
|
|||
public String getUpdateBy() { |
|||
return updateBy; |
|||
} |
|||
|
|||
public void setUpdateBy(String updateBy) { |
|||
this.updateBy = updateBy; |
|||
} |
|||
} |
@ -0,0 +1,71 @@ |
|||
package org.jeecg.common.system.vo; |
|||
|
|||
import java.util.List; |
|||
|
|||
import org.jeecg.common.util.DateUtils; |
|||
|
|||
/** |
|||
* @Description: 用户缓存信息 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
public class SysUserCacheInfo { |
|||
|
|||
private String sysUserCode; |
|||
|
|||
private String sysUserName; |
|||
|
|||
private String sysOrgCode; |
|||
|
|||
private List<String> sysMultiOrgCode; |
|||
|
|||
private boolean oneDepart; |
|||
|
|||
public boolean isOneDepart() { |
|||
return oneDepart; |
|||
} |
|||
|
|||
public void setOneDepart(boolean oneDepart) { |
|||
this.oneDepart = oneDepart; |
|||
} |
|||
|
|||
public String getSysDate() { |
|||
return DateUtils.formatDate(); |
|||
} |
|||
|
|||
public String getSysTime() { |
|||
return DateUtils.now(); |
|||
} |
|||
|
|||
public String getSysUserCode() { |
|||
return sysUserCode; |
|||
} |
|||
|
|||
public void setSysUserCode(String sysUserCode) { |
|||
this.sysUserCode = sysUserCode; |
|||
} |
|||
|
|||
public String getSysUserName() { |
|||
return sysUserName; |
|||
} |
|||
|
|||
public void setSysUserName(String sysUserName) { |
|||
this.sysUserName = sysUserName; |
|||
} |
|||
|
|||
public String getSysOrgCode() { |
|||
return sysOrgCode; |
|||
} |
|||
|
|||
public void setSysOrgCode(String sysOrgCode) { |
|||
this.sysOrgCode = sysOrgCode; |
|||
} |
|||
|
|||
public List<String> getSysMultiOrgCode() { |
|||
return sysMultiOrgCode; |
|||
} |
|||
|
|||
public void setSysMultiOrgCode(List<String> sysMultiOrgCode) { |
|||
this.sysMultiOrgCode = sysMultiOrgCode; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,13 @@ |
|||
package org.jeecg.common.util; |
|||
|
|||
/** |
|||
* |
|||
* @Author 张代浩 |
|||
* |
|||
*/ |
|||
public enum BrowserType { |
|||
/** |
|||
* 浏览类型 IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko |
|||
*/ |
|||
IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko |
|||
} |
@ -0,0 +1,212 @@ |
|||
package org.jeecg.common.util; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
|
|||
/** |
|||
* |
|||
* @Author 张代浩 |
|||
* |
|||
*/ |
|||
public class BrowserUtils { |
|||
|
|||
/** |
|||
* 判断是否是IE |
|||
* @param request |
|||
* @return |
|||
*/ |
|||
public static boolean isIe(HttpServletRequest request) { |
|||
return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request |
|||
.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true |
|||
: false; |
|||
} |
|||
|
|||
/** |
|||
* 获取IE版本 |
|||
* |
|||
* @param request |
|||
* @return |
|||
*/ |
|||
public static Double getIeVersion(HttpServletRequest request) { |
|||
Double version = 0.0; |
|||
if (getBrowserType(request, IE11)) { |
|||
version = 11.0; |
|||
} else if (getBrowserType(request, IE10)) { |
|||
version = 10.0; |
|||
} else if (getBrowserType(request, IE9)) { |
|||
version = 9.0; |
|||
} else if (getBrowserType(request, IE8)) { |
|||
version = 8.0; |
|||
} else if (getBrowserType(request, IE7)) { |
|||
version = 7.0; |
|||
} else if (getBrowserType(request, IE6)) { |
|||
version = 6.0; |
|||
} |
|||
return version; |
|||
} |
|||
|
|||
/** |
|||
* 获取浏览器类型 |
|||
* |
|||
* @param request |
|||
* @return |
|||
*/ |
|||
public static BrowserType getBrowserType(HttpServletRequest request) { |
|||
BrowserType browserType = null; |
|||
if (getBrowserType(request, IE11)) { |
|||
browserType = BrowserType.IE11; |
|||
} |
|||
if (getBrowserType(request, IE10)) { |
|||
browserType = BrowserType.IE10; |
|||
} |
|||
if (getBrowserType(request, IE9)) { |
|||
browserType = BrowserType.IE9; |
|||
} |
|||
if (getBrowserType(request, IE8)) { |
|||
browserType = BrowserType.IE8; |
|||
} |
|||
if (getBrowserType(request, IE7)) { |
|||
browserType = BrowserType.IE7; |
|||
} |
|||
if (getBrowserType(request, IE6)) { |
|||
browserType = BrowserType.IE6; |
|||
} |
|||
if (getBrowserType(request, FIREFOX)) { |
|||
browserType = BrowserType.Firefox; |
|||
} |
|||
if (getBrowserType(request, SAFARI)) { |
|||
browserType = BrowserType.Safari; |
|||
} |
|||
if (getBrowserType(request, CHROME)) { |
|||
browserType = BrowserType.Chrome; |
|||
} |
|||
if (getBrowserType(request, OPERA)) { |
|||
browserType = BrowserType.Opera; |
|||
} |
|||
if (getBrowserType(request, CAMINO)) { |
|||
browserType = BrowserType.Camino; |
|||
} |
|||
return browserType; |
|||
} |
|||
|
|||
private static boolean getBrowserType(HttpServletRequest request, |
|||
String brosertype) { |
|||
return request.getHeader("USER-AGENT").toLowerCase() |
|||
.indexOf(brosertype) > 0 ? true : false; |
|||
} |
|||
|
|||
private final static String IE11 = "rv:11.0"; |
|||
private final static String IE10 = "MSIE 10.0"; |
|||
private final static String IE9 = "MSIE 9.0"; |
|||
private final static String IE8 = "MSIE 8.0"; |
|||
private final static String IE7 = "MSIE 7.0"; |
|||
private final static String IE6 = "MSIE 6.0"; |
|||
private final static String MAXTHON = "Maxthon"; |
|||
private final static String QQ = "QQBrowser"; |
|||
private final static String GREEN = "GreenBrowser"; |
|||
private final static String SE360 = "360SE"; |
|||
private final static String FIREFOX = "Firefox"; |
|||
private final static String OPERA = "Opera"; |
|||
private final static String CHROME = "Chrome"; |
|||
private final static String SAFARI = "Safari"; |
|||
private final static String OTHER = "其它"; |
|||
private final static String CAMINO = "Camino"; |
|||
|
|||
public static String checkBrowse(HttpServletRequest request) { |
|||
String userAgent = request.getHeader("USER-AGENT"); |
|||
if (regex(OPERA, userAgent)) { |
|||
return OPERA; |
|||
} |
|||
if (regex(CHROME, userAgent)) { |
|||
return CHROME; |
|||
} |
|||
if (regex(FIREFOX, userAgent)) { |
|||
return FIREFOX; |
|||
} |
|||
if (regex(SAFARI, userAgent)) { |
|||
return SAFARI; |
|||
} |
|||
if (regex(SE360, userAgent)) { |
|||
return SE360; |
|||
} |
|||
if (regex(GREEN, userAgent)) { |
|||
return GREEN; |
|||
} |
|||
if (regex(QQ, userAgent)) { |
|||
return QQ; |
|||
} |
|||
if (regex(MAXTHON, userAgent)) { |
|||
return MAXTHON; |
|||
} |
|||
if (regex(IE11, userAgent)) { |
|||
return IE11; |
|||
} |
|||
if (regex(IE10, userAgent)) { |
|||
return IE10; |
|||
} |
|||
if (regex(IE9, userAgent)) { |
|||
return IE9; |
|||
} |
|||
if (regex(IE8, userAgent)) { |
|||
return IE8; |
|||
} |
|||
if (regex(IE7, userAgent)) { |
|||
return IE7; |
|||
} |
|||
if (regex(IE6, userAgent)) { |
|||
return IE6; |
|||
} |
|||
return OTHER; |
|||
} |
|||
|
|||
public static boolean regex(String regex, String str) { |
|||
Pattern p = Pattern.compile(regex, Pattern.MULTILINE); |
|||
Matcher m = p.matcher(str); |
|||
return m.find(); |
|||
} |
|||
|
|||
|
|||
private static Map<String, String> langMap = new HashMap<String, String>(); |
|||
private final static String ZH = "zh"; |
|||
private final static String ZH_CN = "zh-cn"; |
|||
|
|||
private final static String EN = "en"; |
|||
private final static String EN_US = "en"; |
|||
|
|||
|
|||
static |
|||
{ |
|||
langMap.put(ZH, ZH_CN); |
|||
langMap.put(EN, EN_US); |
|||
} |
|||
|
|||
public static String getBrowserLanguage(HttpServletRequest request) { |
|||
|
|||
String browserLang = request.getLocale().getLanguage(); |
|||
String browserLangCode = (String)langMap.get(browserLang); |
|||
|
|||
if(browserLangCode == null) |
|||
{ |
|||
browserLangCode = EN_US; |
|||
} |
|||
return browserLangCode; |
|||
} |
|||
|
|||
/** 判断请求是否来自电脑端 */ |
|||
public static boolean isDesktop(HttpServletRequest request) { |
|||
return !isMobile(request); |
|||
} |
|||
|
|||
/** 判断请求是否来自移动端 */ |
|||
public static boolean isMobile(HttpServletRequest request) { |
|||
String ua = request.getHeader("User-Agent").toLowerCase(); |
|||
String type = "(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)"; |
|||
Pattern pattern = Pattern.compile(type); |
|||
return pattern.matcher(ua).find(); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,346 @@ |
|||
package org.jeecg.common.util; |
|||
|
|||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; |
|||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; |
|||
import com.baomidou.mybatisplus.annotation.DbType; |
|||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.jeecg.common.constant.CommonConstant; |
|||
import org.jeecg.common.constant.DataBaseConstant; |
|||
import org.jeecg.common.constant.ServiceNameConstants; |
|||
import org.jeecg.common.constant.SymbolConstant; |
|||
import org.jeecg.common.util.filter.FileTypeFilter; |
|||
import org.jeecg.common.util.oss.OssBootUtil; |
|||
import org.jeecgframework.poi.util.PoiPublicUtil; |
|||
import org.springframework.jdbc.datasource.DriverManagerDataSource; |
|||
import org.springframework.util.FileCopyUtils; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.sql.DataSource; |
|||
import java.io.ByteArrayInputStream; |
|||
import java.io.File; |
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.sql.Connection; |
|||
import java.sql.DatabaseMetaData; |
|||
import java.sql.SQLException; |
|||
import java.util.Map; |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
|
|||
/** |
|||
* @Description: 通用工具 |
|||
* @author: jeecg-boot |
|||
*/ |
|||
@Slf4j |
|||
public class CommonUtils { |
|||
|
|||
/** |
|||
* 中文正则 |
|||
*/ |
|||
private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]"); |
|||
|
|||
/** |
|||
* 文件名 正则字符串 |
|||
* 文件名支持的字符串:字母数字中文.-_()() 除此之外的字符将被删除 |
|||
*/ |
|||
private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]"; |
|||
|
|||
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){ |
|||
String dbPath = null; |
|||
String fileName = "image" + Math.round(Math.random() * 100000000000L); |
|||
fileName += "." + PoiPublicUtil.getFileExtendName(data); |
|||
try { |
|||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){ |
|||
File file = new File(basePath + File.separator + bizPath + File.separator ); |
|||
if (!file.exists()) { |
|||
file.mkdirs();// 创建文件根目录
|
|||
} |
|||
String savePath = file.getPath() + File.separator + fileName; |
|||
File savefile = new File(savePath); |
|||
FileCopyUtils.copy(data, savefile); |
|||
dbPath = bizPath + File.separator + fileName; |
|||
}else { |
|||
InputStream in = new ByteArrayInputStream(data); |
|||
String relativePath = bizPath+"/"+fileName; |
|||
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ |
|||
dbPath = MinioUtil.upload(in,relativePath); |
|||
}else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){ |
|||
dbPath = OssBootUtil.upload(in,relativePath); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
return dbPath; |
|||
} |
|||
|
|||
/** |
|||
* 判断文件名是否带盘符,重新处理 |
|||
* @param fileName |
|||
* @return |
|||
*/ |
|||
public static String getFileName(String fileName){ |
|||
//判断是否带有盘符信息
|
|||
// Check for Unix-style path
|
|||
int unixSep = fileName.lastIndexOf('/'); |
|||
// Check for Windows-style path
|
|||
int winSep = fileName.lastIndexOf('\\'); |
|||
// Cut off at latest possible point
|
|||
int pos = (winSep > unixSep ? winSep : unixSep); |
|||
if (pos != -1) { |
|||
// Any sort of path separator found...
|
|||
fileName = fileName.substring(pos + 1); |
|||
} |
|||
//替换上传文件名字的特殊字符
|
|||
fileName = fileName.replace("=","").replace(",","").replace("&","") |
|||
.replace("#", "").replace("“", "").replace("”", ""); |
|||
//替换上传文件名字中的空格
|
|||
fileName=fileName.replaceAll("\\s",""); |
|||
//update-beign-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
|||
fileName = fileName.replaceAll(FILE_NAME_REGEX, ""); |
|||
//update-end-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常
|
|||
return fileName; |
|||
} |
|||
|
|||
/** |
|||
* java 判断字符串里是否包含中文字符 |
|||
* @param str |
|||
* @return |
|||
*/ |
|||
public static boolean ifContainChinese(String str) { |
|||
if(str.getBytes().length == str.length()){ |
|||
return false; |
|||
}else{ |
|||
Matcher m = ZHONGWEN_PATTERN.matcher(str); |
|||
if (m.find()) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 统一全局上传 |
|||
* @Return: java.lang.String |
|||
*/ |
|||
public static String upload(MultipartFile file, String bizPath, String uploadType) { |
|||
String url = ""; |
|||
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ |
|||
url = MinioUtil.upload(file,bizPath); |
|||
}else{ |
|||
url = OssBootUtil.upload(file,bizPath); |
|||
} |
|||
return url; |
|||
} |
|||
/** |
|||
* 本地文件上传 |
|||
* @param mf 文件 |
|||
* @param bizPath 自定义路径 |
|||
* @return |
|||
*/ |
|||
public static String uploadLocal(MultipartFile mf,String bizPath,String uploadpath){ |
|||
try { |
|||
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
|||
FileTypeFilter.fileTypeFilter(mf); |
|||
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
|||
String fileName = null; |
|||
File file = new File(uploadpath + File.separator + bizPath + File.separator ); |
|||
if (!file.exists()) { |
|||
// 创建文件根目录
|
|||
file.mkdirs(); |
|||
} |
|||
// 获取文件名
|
|||
String orgName = mf.getOriginalFilename(); |
|||
orgName = CommonUtils.getFileName(orgName); |
|||
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){ |
|||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); |
|||
}else{ |
|||
fileName = orgName+ "_" + System.currentTimeMillis(); |
|||
} |
|||
String savePath = file.getPath() + File.separator + fileName; |
|||
File savefile = new File(savePath); |
|||
FileCopyUtils.copy(mf.getBytes(), savefile); |
|||
String dbpath = null; |
|||
if(oConvertUtils.isNotEmpty(bizPath)){ |
|||
dbpath = bizPath + File.separator + fileName; |
|||
}else{ |
|||
dbpath = fileName; |
|||
} |
|||
if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) { |
|||
dbpath = dbpath.replace("\\", "/"); |
|||
} |
|||
return dbpath; |
|||
} catch (IOException e) { |
|||
log.error(e.getMessage(), e); |
|||
}catch (Exception e) { |
|||
log.error(e.getMessage(), e); |
|||
} |
|||
return ""; |
|||
} |
|||
|
|||
/** |
|||
* 统一全局上传 带桶 |
|||
* @Return: java.lang.String |
|||
*/ |
|||
public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) { |
|||
String url = ""; |
|||
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ |
|||
url = MinioUtil.upload(file,bizPath,customBucket); |
|||
}else{ |
|||
url = OssBootUtil.upload(file,bizPath,customBucket); |
|||
} |
|||
return url; |
|||
} |
|||
|
|||
/** 当前系统数据库类型 */ |
|||
private static String DB_TYPE = ""; |
|||
private static DbType dbTypeEnum = null; |
|||
|
|||
/** |
|||
* 全局获取平台数据库类型(作废了) |
|||
* @return |
|||
*/ |
|||
@Deprecated |
|||
public static String getDatabaseType() { |
|||
if(oConvertUtils.isNotEmpty(DB_TYPE)){ |
|||
return DB_TYPE; |
|||
} |
|||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class); |
|||
try { |
|||
return getDatabaseTypeByDataSource(dataSource); |
|||
} catch (SQLException e) { |
|||
//e.printStackTrace();
|
|||
log.warn(e.getMessage(),e); |
|||
return ""; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 全局获取平台数据库类型(对应mybaisPlus枚举) |
|||
* @return |
|||
*/ |
|||
public static DbType getDatabaseTypeEnum() { |
|||
if (oConvertUtils.isNotEmpty(dbTypeEnum)) { |
|||
return dbTypeEnum; |
|||
} |
|||
try { |
|||
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class); |
|||
dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL()); |
|||
return dbTypeEnum; |
|||
} catch (SQLException e) { |
|||
log.warn(e.getMessage(), e); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 根据数据源key获取DataSourceProperty |
|||
* @param sourceKey |
|||
* @return |
|||
*/ |
|||
public static DataSourceProperty getDataSourceProperty(String sourceKey){ |
|||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class); |
|||
Map<String, DataSourceProperty> map = prop.getDatasource(); |
|||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey); |
|||
return db; |
|||
} |
|||
|
|||
/** |
|||
* 根据sourceKey 获取数据源连接 |
|||
* @param sourceKey |
|||
* @return |
|||
* @throws SQLException |
|||
*/ |
|||
public static Connection getDataSourceConnect(String sourceKey) throws SQLException { |
|||
if (oConvertUtils.isEmpty(sourceKey)) { |
|||
sourceKey = "master"; |
|||
} |
|||
DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class); |
|||
Map<String, DataSourceProperty> map = prop.getDatasource(); |
|||
DataSourceProperty db = (DataSourceProperty)map.get(sourceKey); |
|||
if(db==null){ |
|||
return null; |
|||
} |
|||
DriverManagerDataSource ds = new DriverManagerDataSource (); |
|||
ds.setDriverClassName(db.getDriverClassName()); |
|||
ds.setUrl(db.getUrl()); |
|||
ds.setUsername(db.getUsername()); |
|||
ds.setPassword(db.getPassword()); |
|||
return ds.getConnection(); |
|||
} |
|||
|
|||
/** |
|||
* 获取数据库类型 |
|||
* @param dataSource |
|||
* @return |
|||
* @throws SQLException |
|||
*/ |
|||
private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{ |
|||
if("".equals(DB_TYPE)) { |
|||
Connection connection = dataSource.getConnection(); |
|||
try { |
|||
DatabaseMetaData md = connection.getMetaData(); |
|||
String dbType = md.getDatabaseProductName().toUpperCase(); |
|||
String sqlserver= "SQL SERVER"; |
|||
if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL)>=0) { |
|||
DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL; |
|||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE)>=0 ||dbType.indexOf(DataBaseConstant.DB_TYPE_DM)>=0) { |
|||
DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE; |
|||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER)>=0||dbType.indexOf(sqlserver)>=0) { |
|||
DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER; |
|||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0) { |
|||
DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL; |
|||
}else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB)>=0) { |
|||
DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB; |
|||
}else { |
|||
log.error("数据库类型:[" + dbType + "]不识别!"); |
|||
//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
|
|||
} |
|||
} catch (Exception e) { |
|||
log.error(e.getMessage(), e); |
|||
}finally { |
|||
connection.close(); |
|||
} |
|||
} |
|||
return DB_TYPE; |
|||
|
|||
} |
|||
/** |
|||
* 获取服务器地址 |
|||
* |
|||
* @param request |
|||
* @return |
|||
*/ |
|||
public static String getBaseUrl(HttpServletRequest request) { |
|||
//1.【兼容】兼容微服务下的 base path-------
|
|||
String xGatewayBasePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH); |
|||
if(oConvertUtils.isNotEmpty(xGatewayBasePath)){ |
|||
log.info("x_gateway_base_path = "+ xGatewayBasePath); |
|||
return xGatewayBasePath; |
|||
} |
|||
//2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题
|
|||
// https://blog.csdn.net/weixin_34376986/article/details/89767950
|
|||
String scheme = request.getHeader(CommonConstant.X_FORWARDED_SCHEME); |
|||
if(oConvertUtils.isEmpty(scheme)){ |
|||
scheme = request.getScheme(); |
|||
} |
|||
|
|||
//3.常规操作
|
|||
String serverName = request.getServerName(); |
|||
int serverPort = request.getServerPort(); |
|||
String contextPath = request.getContextPath(); |
|||
|
|||
//返回 host domain
|
|||
String baseDomainPath = null; |
|||
int length = 80; |
|||
if(length == serverPort){ |
|||
baseDomainPath = scheme + "://" + serverName + contextPath ; |
|||
}else{ |
|||
baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ; |
|||
} |
|||
log.info("-----Common getBaseUrl----- : " + baseDomainPath); |
|||
return baseDomainPath; |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue