forked from Qi/Oroqen-CMD
初始化
This commit is contained in:
commit
8173b4e31e
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
## ide
|
||||
**/.idea
|
||||
*.iml
|
||||
rebel.xml
|
||||
|
||||
## backend
|
||||
**/target
|
||||
**/logs
|
||||
|
||||
## front
|
||||
**/*.lock
|
||||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
derby.log
|
213
LICENSE
Normal file
213
LICENSE
Normal file
@ -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.JeecgBoot开源版本无任何限制,在遵循本开源协议条款下,允许商用使用,不会造成侵权行为。
|
||||
2.允许基于本平台软件开展业务系统开发。
|
||||
3.在任何情况下,您不得使用本软件开发可能被认为与本软件竞争的软件。
|
||||
|
||||
最终解释权归:http://www.jeecg.com
|
165
README.md
Normal file
165
README.md
Normal file
@ -0,0 +1,165 @@
|
||||
|
||||
JeecgBoot 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.8.1(发布日期:2025-06-30)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
||||
|
||||
项目介绍
|
||||
-----------------------------------
|
||||
|
||||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3>
|
||||
|
||||
JeecgBoot 是一款基于代码生成器的`低代码开发平台`!前后端分离架构 SpringBoot2.x和3.x,SpringCloud,Ant Design Vue3,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot 引领新的低代码开发模式(OnlineCoding-> 代码生成器-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性!
|
||||
|
||||
|
||||
#### 项目说明
|
||||
|
||||
| 项目名 | 说明 |
|
||||
|--------------------|------------------------|
|
||||
| `jeecg-boot` | 后端源码JAVA(SpringBoot微服务架构) |
|
||||
| `jeecgboot-vue3` | 前端源码VUE3(vue3+vite5+ts最新技术栈) |
|
||||
|
||||
|
||||
|
||||
技术文档
|
||||
-----------------------------------
|
||||
|
||||
- 官方网站: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
- 新手指南: [快速入门](http://www.jeecg.com/doc/quickstart)
|
||||
- QQ交流群 : 964611995、⑩716488839(满)、⑨808791225(满)、其他(满)
|
||||
- 在线演示 : [在线演示](http://boot3.jeecg.com) | [APP演示](http://jeecg.com/appIndex)
|
||||
> 演示系统的登录账号密码,请点击 [获取账号密码](http://jeecg.com/doc/demo) 获取
|
||||
|
||||
|
||||
|
||||
启动项目
|
||||
-----------------------------------
|
||||
|
||||
- [IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup)
|
||||
- [Docker一键启动前后端](https://help.jeecg.com/java/docker/quick)
|
||||
|
||||
|
||||
微服务启动
|
||||
-----------------------------------
|
||||
- [单体快速切换微服务](https://help.jeecg.com/java/springcloud/switchcloud/monomer)
|
||||
- [Docker启动微服务后台](https://help.jeecg.com/java/docker/springcloud)
|
||||
|
||||
|
||||
|
||||
技术架构:
|
||||
-----------------------------------
|
||||
|
||||
#### 后端
|
||||
|
||||
- IDE建议: IDEA (必须安装lombok插件 )
|
||||
- 语言:Java 8+ (支持17)
|
||||
- 依赖管理:Maven
|
||||
- 基础框架:Spring Boot 2.7.18
|
||||
- 微服务框架: Spring Cloud Alibaba 2021.0.1.0
|
||||
- 持久层框架:MybatisPlus 3.5.3.2
|
||||
- 报表工具: JimuReport 1.9.4
|
||||
- 安全框架:Apache Shiro 1.12.0,Jwt 3.11.0
|
||||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywalking
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.24
|
||||
- 日志打印:logback
|
||||
- 缓存:Redis
|
||||
- 其他:autopoi, fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
|
||||
- 默认数据库脚本:MySQL5.7+
|
||||
- [其他数据库,需要自己转](https://my.oschina.net/jeecg/blog/4905722)
|
||||
|
||||
|
||||
#### 前端
|
||||
|
||||
- 前端IDE建议:WebStorm、Vscode
|
||||
- 采用 Vue3.0+TypeScript+Vite+Ant-Design-Vue等新技术方案,包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能
|
||||
- 最新技术栈:Vue3.0 + TypeScript + Vite5 + ant-design-vue4 + pinia + echarts + unocss + vxe-table + qiankun + es6
|
||||
- 依赖管理:node、npm、pnpm
|
||||
|
||||
|
||||
|
||||
#### 支持库
|
||||
|
||||
| 数据库 | 支持 |
|
||||
| --- | --- |
|
||||
| MySQL | √ |
|
||||
| Oracle11g | √ |
|
||||
| Sqlserver2017 | √ |
|
||||
| PostgreSQL | √ |
|
||||
| MariaDB | √ |
|
||||
| 达梦 | √ |
|
||||
| 人大金仓 | √ |
|
||||
| TiDB | √ |
|
||||
|
||||
|
||||
|
||||
|
||||
## 微服务解决方案
|
||||
|
||||
|
||||
- 1、服务注册和发现 Nacos √
|
||||
- 2、统一配置中心 Nacos √
|
||||
- 3、路由网关 gateway(三种加载方式) √
|
||||
- 4、分布式 http feign √
|
||||
- 5、熔断降级限流 Sentinel √
|
||||
- 6、分布式文件 Minio、阿里OSS √
|
||||
- 7、统一权限控制 JWT + Shiro √
|
||||
- 8、服务监控 SpringBootAdmin√
|
||||
- 9、链路跟踪 Skywalking [参考文档](https://help.jeecg.com/java/springcloud/super/skywarking)
|
||||
- 10、消息中间件 RabbitMQ √
|
||||
- 11、分布式任务 xxl-job √
|
||||
- 12、分布式事务 Seata
|
||||
- 13、轻量分布式日志 Loki+grafana套件
|
||||
- 14、支持 docker-compose、k8s、jenkins
|
||||
- 15、CAS 单点登录 √
|
||||
- 16、路由限流 √
|
||||
|
||||
|
||||
|
||||
后台目录结构
|
||||
-----------------------------------
|
||||
```
|
||||
项目结构
|
||||
├─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 -- 微服务测试示例(分库分表)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### 微服务架构图
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
13
db/Dockerfile
Normal file
13
db/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
FROM registry.cn-hangzhou.aliyuncs.com/jeecgdocker/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
|
8850
db/jeecgboot-mysql-5.7.sql
Normal file
8850
db/jeecgboot-mysql-5.7.sql
Normal file
File diff suppressed because one or more lines are too long
323
db/tables_nacos.sql
Normal file
323
db/tables_nacos.sql
Normal file
File diff suppressed because one or more lines are too long
360
db/tables_xxl_job.sql
Normal file
360
db/tables_xxl_job.sql
Normal file
@ -0,0 +1,360 @@
|
||||
#
|
||||
# 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`;
|
||||
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : mysql5.7
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50738 (5.7.38)
|
||||
Source Host : 127.0.0.1:3306
|
||||
Source Schema : xxl_job
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50738 (5.7.38)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 10/02/2025 13:49:31
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_group
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_group`;
|
||||
CREATE TABLE `xxl_job_group` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行器AppName',
|
||||
`title` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '执行器名称',
|
||||
`address_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '执行器地址类型:0=自动注册、1=手动录入',
|
||||
`address_list` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行器地址列表,多地址逗号分隔',
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_group
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_group` VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2025-02-10 13:49:04');
|
||||
INSERT INTO `xxl_job_group` VALUES (2, 'jeecg-demo', '测试Demo模块', 0, NULL, '2025-02-10 13:49:04');
|
||||
INSERT INTO `xxl_job_group` VALUES (3, 'jeecg-system', '系统System模块', 0, NULL, '2025-02-10 13:49:04');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_info`;
|
||||
CREATE TABLE `xxl_job_info` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
|
||||
`job_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`add_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
`author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '作者',
|
||||
`alarm_email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '报警邮件',
|
||||
`schedule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
|
||||
`schedule_conf` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
|
||||
`misfire_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
|
||||
`executor_route_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器路由策略',
|
||||
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_block_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL 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) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE备注',
|
||||
`glue_updatetime` datetime NULL DEFAULT NULL COMMENT 'GLUE更新时间',
|
||||
`child_jobid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL 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`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_info
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_info` VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2024-08-21 22:30:30', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '', 1, 1729353600000, 1739203200000);
|
||||
INSERT INTO `xxl_job_info` VALUES (2, 3, '测试jeecg xxljob', '2024-08-21 22:41:10', '2024-08-21 22:41:30', 'JEECG', '', 'CRON', '* * * * * ?', 'DO_NOTHING', 'FIRST', 'demoJob', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2024-08-21 22:41:10', '', 1, 1739166572000, 1739166573000);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_lock
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_lock`;
|
||||
CREATE TABLE `xxl_job_lock` (
|
||||
`lock_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '锁名称',
|
||||
PRIMARY KEY (`lock_name`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_lock
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_lock` VALUES ('schedule_lock');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_log`;
|
||||
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) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
|
||||
`executor_handler` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务handler',
|
||||
`executor_param` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务参数',
|
||||
`executor_sharding_param` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
|
||||
`executor_fail_retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '失败重试次数',
|
||||
`trigger_time` datetime NULL DEFAULT NULL COMMENT '调度-时间',
|
||||
`trigger_code` int(11) NOT NULL COMMENT '调度-结果',
|
||||
`trigger_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '调度-日志',
|
||||
`handle_time` datetime NULL DEFAULT NULL COMMENT '执行-时间',
|
||||
`handle_code` int(11) NOT NULL COMMENT '执行-状态',
|
||||
`handle_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行-日志',
|
||||
`alarm_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `I_trigger_time`(`trigger_time`) USING BTREE,
|
||||
INDEX `I_handle_code`(`handle_code`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 6761 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_log
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_log` VALUES (6618, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6619, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6620, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6621, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6622, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6623, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6624, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6625, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6626, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6627, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6628, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6629, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6630, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6631, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6632, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6633, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6634, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6635, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6636, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6637, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6638, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6639, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6640, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6641, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:32', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6642, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:33', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6643, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:34', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6644, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:35', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6645, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:36', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6646, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:37', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6647, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:38', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6648, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:39', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6649, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:40', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6650, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:41', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6651, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:42', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6652, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:43', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6653, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:44', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6654, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:45', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6655, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:46', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6656, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:47', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6657, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:48', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6658, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:49', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6659, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:50', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6660, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:51', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6661, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:52', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6662, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:53', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6663, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:54', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6664, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:55', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6665, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:56', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6666, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:57', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6667, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:58', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6668, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:47:59', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6669, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:00', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6670, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:01', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6671, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:02', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6672, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:03', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6673, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:04', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6674, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:05', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6675, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:06', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6676, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:07', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6677, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:08', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6678, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6679, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6680, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6681, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6682, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6683, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6684, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6685, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6686, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6687, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6688, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6689, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6690, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6691, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6692, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6693, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6694, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6695, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6696, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6697, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6698, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6699, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6700, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6701, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:32', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6702, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:33', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6703, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:34', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6704, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:35', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6705, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:36', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6706, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:37', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6707, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:38', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6708, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:39', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6709, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:40', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6710, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:41', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6711, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:42', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6712, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:43', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6713, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:44', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6714, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:45', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6715, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:46', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6716, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:47', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6717, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:48', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6718, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:49', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6719, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:50', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6720, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:51', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6721, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:52', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6722, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:53', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6723, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:54', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6724, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:55', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6725, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:56', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6726, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:57', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6727, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:58', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6728, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:48:59', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6729, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:00', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6730, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:01', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6731, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:02', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6732, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:03', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6733, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:04', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6734, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:05', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6735, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:06', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6736, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:07', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6737, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:08', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6738, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:09', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6739, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:10', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6740, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:11', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6741, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:12', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6742, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:13', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6743, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:14', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6744, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:15', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6745, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:16', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6746, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:17', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6747, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:18', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6748, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:19', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6749, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:20', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6750, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:21', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6751, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:22', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6752, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:23', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6753, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:24', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 2);
|
||||
INSERT INTO `xxl_job_log` VALUES (6754, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:25', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6755, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:26', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6756, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:27', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6757, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:28', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6758, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:29', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6759, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:30', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
INSERT INTO `xxl_job_log` VALUES (6760, 3, 2, NULL, 'demoJob', '', NULL, 0, '2025-02-10 13:49:31', 500, '任务触发类型:Cron触发<br>调度机器:192.168.1.11<br>执行器-注册方式:自动注册<br>执行器-地址列表:null<br>路由策略:第一个<br>阻塞处理策略:单机串行<br>任务超时时间:0<br>失败重试次数:0<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发调度<<<<<<<<<<< </span><br>调度失败:执行器地址为空<br><br>', NULL, 0, NULL, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_log_report
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_log_report`;
|
||||
CREATE TABLE `xxl_job_log_report` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`trigger_day` datetime NULL 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 '执行失败-日志数量',
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `i_trigger_day`(`trigger_day`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_log_report
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_log_report` VALUES (1, '2024-08-21 00:00:00', 70, 0, 5, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (2, '2024-08-20 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (3, '2024-08-19 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (4, '2024-09-10 00:00:00', 0, 0, 56, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (5, '2024-09-09 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (6, '2024-09-08 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (7, '2024-10-19 00:00:00', 0, 0, 6391, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (8, '2024-10-18 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (9, '2024-10-17 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (10, '2025-02-10 00:00:00', 0, 0, 116, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (11, '2025-02-09 00:00:00', 0, 0, 0, NULL);
|
||||
INSERT INTO `xxl_job_log_report` VALUES (12, '2025-02-08 00:00:00', 0, 0, 0, NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_logglue
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_logglue`;
|
||||
CREATE TABLE `xxl_job_logglue` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`job_id` int(11) NOT NULL COMMENT '任务,主键ID',
|
||||
`glue_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'GLUE类型',
|
||||
`glue_source` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'GLUE源代码',
|
||||
`glue_remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'GLUE备注',
|
||||
`add_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_logglue
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_registry
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_registry`;
|
||||
CREATE TABLE `xxl_job_registry` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`registry_group` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`registry_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`registry_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `i_g_k_v`(`registry_group`, `registry_key`, `registry_value`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_registry
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for xxl_job_user
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `xxl_job_user`;
|
||||
CREATE TABLE `xxl_job_user` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号',
|
||||
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
|
||||
`role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
|
||||
`permission` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `i_username`(`username`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of xxl_job_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `xxl_job_user` VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
15
db/版本升级说明.md
Normal file
15
db/版本升级说明.md
Normal file
@ -0,0 +1,15 @@
|
||||
# 版本升级方法
|
||||
|
||||
> JeecgBoot属于平台级产品,每次升级改动较大,目前做不到平滑升级。
|
||||
|
||||
### 增量升级方案
|
||||
#### 1.代码合并
|
||||
本地通过svn或git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比合并代码;
|
||||
|
||||
#### 2.数据库升级
|
||||
- 从3.6.2+版本增加flyway自动升级数据库机制,支持 mysql5.7、mysql8;
|
||||
- 其他库请手工执行SQL, 目录: `jeecg-module-system\jeecg-system-start\src\main\resources\flyway\sql\mysql`
|
||||
> 注意: 升级sql只提供mysql版本;如果有权限升级, 还需要手工角色授权,退出重新登录才好使。
|
||||
|
||||
#### 3.兼容问题
|
||||
每次发版,会针对不兼容地方重点说明。
|
52
docker-compose.yml
Normal file
52
docker-compose.yml
Normal file
@ -0,0 +1,52 @@
|
||||
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
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
jeecg-boot-redis:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/jeecgdocker/redis:5.0
|
||||
ports:
|
||||
- 6379:6379
|
||||
restart: always
|
||||
hostname: jeecg-boot-redis
|
||||
container_name: jeecg-boot-redis
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
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
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
323
jeecg-boot-base-core/pom.xml
Normal file
323
jeecg-boot-base-core/pom.xml
Normal file
@ -0,0 +1,323 @@
|
||||
<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>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>aliyun</id>
|
||||
<name>aliyun Repository</name>
|
||||
<url>https://maven.aliyun.com/repository/public</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jeecg</id>
|
||||
<name>jeecg Repository</name>
|
||||
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jeecg-snapshots</id>
|
||||
<name>jeecg-snapshots Repository</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<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>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</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-io.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>
|
||||
<!-- minidao -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>minidao-spring-boot-starter</artifactId>
|
||||
</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>
|
||||
<!--人大金仓驱动 版本号V008R006C005B0013 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework</groupId>
|
||||
<artifactId>kingbase8</artifactId>
|
||||
<version>9.0.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!--达梦数据库驱动 版本号1-3-26-2023.07.26-197096-20046-ENT -->
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>Dm8JdbcDriver18</artifactId>
|
||||
<version>${dm8.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmDialect-for-hibernate5.0</artifactId>
|
||||
<version>${dm8.version}</version>
|
||||
</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>
|
||||
<exclusion>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- knife4j -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成器 -->
|
||||
<!-- 如下载失败,请参考此文档 https://help.jeecg.com/java/setup/maven.html -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>codegenerate</artifactId>
|
||||
<version>${codegenerate.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<groupId>mysql</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</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>
|
||||
<exclusion>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<groupId>xerces</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>2.12.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- mini文件存储服务 -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</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>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
<!--加载hutool-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
</dependency>
|
||||
<!-- chatgpt -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,147 @@
|
||||
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);
|
||||
|
||||
/**
|
||||
* 1查询用户角色信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserRolesById(String userId);
|
||||
|
||||
|
||||
/**
|
||||
* 2查询用户权限信息
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserAuths(String userId);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 5根据用户账号查询用户Id
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public String getUserIdByName(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 tableFilterSql
|
||||
* @param text
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictItemsByCode(String tableFilterSql, 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);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 15 字典表的 翻译,可批量
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param keys 多个用逗号分割
|
||||
* @param dataSource 数据源
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package org.jeecg.common.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/26 14:44
|
||||
**/
|
||||
@Data
|
||||
public class DataLogDTO {
|
||||
|
||||
private String tableName;
|
||||
|
||||
private String dataId;
|
||||
|
||||
private String content;
|
||||
|
||||
private String type;
|
||||
|
||||
private String createName;
|
||||
|
||||
public DataLogDTO(){
|
||||
|
||||
}
|
||||
|
||||
public DataLogDTO(String tableName, String dataId, String content, String type) {
|
||||
this.tableName = tableName;
|
||||
this.dataId = dataId;
|
||||
this.content = content;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public DataLogDTO(String tableName, String dataId, String type) {
|
||||
this.tableName = tableName;
|
||||
this.dataId = dataId;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
@ -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,80 @@
|
||||
package org.jeecg.common.api.dto;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private Integer tenantId;
|
||||
|
||||
/**
|
||||
* 客户终端类型 pc:电脑端 app:手机端 h5:移动网页端
|
||||
*/
|
||||
private String clientType;
|
||||
|
||||
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,49 @@
|
||||
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;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
/**
|
||||
* online工单的地址
|
||||
*/
|
||||
private String onlineWorkOrderUrl;
|
||||
//update-end---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
|
||||
public OnlineAuthDTO(){
|
||||
|
||||
}
|
||||
|
||||
public OnlineAuthDTO(String username, List<String> possibleUrl, String onlineFormUrl){
|
||||
this.username = username;
|
||||
this.possibleUrl = possibleUrl;
|
||||
this.onlineFormUrl = onlineFormUrl;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package org.jeecg.common.api.dto.message;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 带业务参数的消息
|
||||
*
|
||||
* @author: taoyan
|
||||
* @date: 2022/8/17
|
||||
*/
|
||||
@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,128 @@
|
||||
package org.jeecg.common.api.dto.message;
|
||||
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 普通消息
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum
|
||||
* XT("system", "系统消息")
|
||||
* YJ("email", "邮件消息")
|
||||
* DD("dingtalk", "钉钉消息")
|
||||
* QYWX("wechat_enterprise", "企业微信")
|
||||
*/
|
||||
protected String type;
|
||||
|
||||
|
||||
//---【推送模板相关参数】-------------------------------------------------------------
|
||||
/**
|
||||
* 是否发送Markdown格式的消息
|
||||
*/
|
||||
protected boolean isMarkdown;
|
||||
/**
|
||||
* 模板消息对应的模板编码
|
||||
*/
|
||||
protected String templateCode;
|
||||
/**
|
||||
* 解析模板内容 对应的数据
|
||||
*/
|
||||
protected Map<String, Object> data;
|
||||
//---【推送模板相关参数】-------------------------------------------------------------
|
||||
|
||||
//---【邮件相关参数】-------------------------------------------------------------
|
||||
/**
|
||||
* 邮件抄送人
|
||||
*/
|
||||
private String copyToUser;
|
||||
|
||||
/**
|
||||
* 邮件推送地址
|
||||
*/
|
||||
protected Set<String> toEmailList;
|
||||
|
||||
/**
|
||||
* 邮件抄送地址
|
||||
*/
|
||||
protected Set<String> ccEmailList;
|
||||
|
||||
/**
|
||||
* 是否为定时任务推送email
|
||||
*/
|
||||
private Boolean isTimeJob = false;
|
||||
|
||||
//---【邮件相关参数】-------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isMarkdown() {
|
||||
return this.isMarkdown;
|
||||
}
|
||||
|
||||
public void setIsMarkdown(boolean isMarkdown) {
|
||||
this.isMarkdown = isMarkdown;
|
||||
}
|
||||
}
|
@ -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.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 接口返回数据格式
|
||||
* @author scott
|
||||
* @email jeecgos@163.com
|
||||
* @date 2019年1月19日
|
||||
*/
|
||||
@Data
|
||||
@Schema(description="接口返回对象")
|
||||
public class Result<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 成功标志
|
||||
*/
|
||||
@Schema(description = "成功标志")
|
||||
private boolean success = true;
|
||||
|
||||
/**
|
||||
* 返回处理消息
|
||||
*/
|
||||
@Schema(description = "返回处理消息")
|
||||
private String message = "";
|
||||
|
||||
/**
|
||||
* 返回代码
|
||||
*/
|
||||
@Schema(description = "返回代码")
|
||||
private Integer code = 0;
|
||||
|
||||
/**
|
||||
* 返回数据对象 data
|
||||
*/
|
||||
@Schema(description = "返回数据对象")
|
||||
private T result;
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
@Schema(description = "时间戳")
|
||||
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,259 @@
|
||||
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;
|
||||
}
|
||||
if(value instanceof MultipartFile){
|
||||
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,457 @@
|
||||
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("(@within(org.springframework.web.bind.annotation.RestController) || " +
|
||||
"@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " +
|
||||
"&& execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..))")
|
||||
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 (true) {
|
||||
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.debug(" __ 进入字典翻译切面 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();
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
String dataSource = field.getAnnotation(Dict.class).ds();
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
List<String> dataList;
|
||||
String dictCode = code;
|
||||
if (!StringUtils.isEmpty(table)) {
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
dictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
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();
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 自定义的字典表数据源
|
||||
String dataSource = field.getAnnotation(Dict.class).ds();
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
String fieldDictCode = code;
|
||||
if (!StringUtils.isEmpty(table)) {
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
fieldDictCode = String.format("%s,%s,%s,%s", table, text, code, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
|
||||
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);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 自定义的数据源
|
||||
String dataSource = null;
|
||||
if (arr.length > 3) {
|
||||
dataSource = arr[3];
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
log.debug("translateDictFromTableByKeys.dictCode:" + dictCode);
|
||||
log.debug("translateDictFromTableByKeys.values:" + values);
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
|
||||
if(null == dataSource){
|
||||
dataSource = "";
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
|
||||
|
||||
List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values, dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
log.debug("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.debug("translateManyDict.dictCodes:" + dictCodes);
|
||||
log.debug("translateManyDict.values:" + values);
|
||||
Map<String, List<DictModel>> manyDict = commonApi.translateManyDict(dictCodes, values);
|
||||
log.debug("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.debug("--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,139 @@
|
||||
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报表请求
|
||||
if(requestPath.indexOf(UrlMatchEnum.CGREPORT_DATA.getMatchUrl())>=0 || requestPath.indexOf(UrlMatchEnum.CGREPORT_ONLY_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.debug("拦截请求 >> {} ; 请求类型 >> {} . ", 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,68 @@
|
||||
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/getData/ 【vue3报表数据请求地址】 */
|
||||
CGREPORT_ONLY_DATA("/online/cgreport/api/getData/", "/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,54 @@
|
||||
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 "";
|
||||
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 方法描述: 数据字典表所在数据源名称
|
||||
* 作 者: chenrui
|
||||
* 日 期: 2023年12月20日-下午4:58
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String ds() default "";
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
@ -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,632 @@
|
||||
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 LOG_TYPE_3 = 3;
|
||||
|
||||
/**
|
||||
* 系统日志类型: 异常
|
||||
*/
|
||||
int LOG_TYPE_4 = 4;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 查询
|
||||
*/
|
||||
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 404 Not Found} (HTTP/1.0 - RFC 1945) */
|
||||
Integer SC_INTERNAL_NOT_FOUND_404 = 404;
|
||||
/** {@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已读)*/
|
||||
Integer HAS_READ_FLAG = 1;
|
||||
Integer 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";
|
||||
Integer STATUS_0_INT = 0;
|
||||
Integer STATUS_1_INT = 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冻结 3离职
|
||||
*/
|
||||
Integer USER_UNFREEZE = 1;
|
||||
Integer USER_FREEZE = 2;
|
||||
Integer USER_QUIT = 3;
|
||||
|
||||
/**字典翻译文本后缀*/
|
||||
String DICT_TEXT_SUFFIX = "_dictText";
|
||||
/**字典翻译颜色后缀*/
|
||||
String DICT_COLOR_SUFFIX = "_dictColor";
|
||||
|
||||
/**
|
||||
* 表单设计器主表类型
|
||||
*/
|
||||
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 = "biz/user_imgs";
|
||||
/**
|
||||
* 在线聊天 用户状态
|
||||
*/
|
||||
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_";
|
||||
/**
|
||||
* 缓存用户id与用户名关系
|
||||
*/
|
||||
String SYS_USER_ID_MAPPING_CACHE = "sys:cache:user:id_mapping";
|
||||
|
||||
/**
|
||||
* 考勤补卡业务状态 (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";
|
||||
/** 租户请求头 更名为:X-Tenant-Id */
|
||||
String TENANT_ID = "X-Tenant-Id";
|
||||
/** 简流接口请求头,用于排除不支持的控件字段 */
|
||||
String X_MiniFlowExclusionFieldMode = "X-Miniflowexclusionfieldmode";
|
||||
/**===============================================================================================*/
|
||||
|
||||
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 VERSION_V3 = "v3";
|
||||
|
||||
/**存储在线程变量里的动态表名*/
|
||||
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";
|
||||
|
||||
/**
|
||||
* 发消息 消息业务类型
|
||||
*/
|
||||
String NOTICE_MSG_BUS_TYPE = "NOTICE_MSG_BUS_TYPE";
|
||||
|
||||
/**
|
||||
* 邮箱消息中地址登录时地址后携带的token,需要替换成真实的token值
|
||||
*/
|
||||
String LOGIN_TOKEN = "{LOGIN_TOKEN}";
|
||||
|
||||
/**
|
||||
* 模板消息中 跳转地址的对应的key
|
||||
*/
|
||||
String MSG_HREF_URL = "url";
|
||||
|
||||
/**
|
||||
* sys_data_log表的类型 用于区别评论区域的日志数据
|
||||
*/
|
||||
String DATA_LOG_TYPE_COMMENT = "comment";
|
||||
|
||||
/**
|
||||
* sys_data_log表的类型 老的数据比较 类型都设置为json
|
||||
*/
|
||||
String DATA_LOG_TYPE_JSON = "json";
|
||||
|
||||
/** 消息模板:markdown */
|
||||
String MSG_TEMPLATE_TYPE_MD = "5";
|
||||
/**========【消息推送相关】==========================================================================*/
|
||||
|
||||
/**
|
||||
* 短信验证码redis-key的前缀
|
||||
*/
|
||||
String PHONE_REDIS_KEY_PRE = "phone_msg";
|
||||
|
||||
/**
|
||||
* 是文件夹
|
||||
*/
|
||||
String IT_IS_FOLDER = "1";
|
||||
|
||||
/**
|
||||
* 文件拥有者
|
||||
*/
|
||||
String FILE_OWNER = "owner";
|
||||
|
||||
/**
|
||||
* 文件管理员
|
||||
*/
|
||||
String FILE_ADMIN = "admin";
|
||||
|
||||
/**
|
||||
* 只允许编辑
|
||||
*/
|
||||
String FILE_EDITABLE = "editable";
|
||||
|
||||
/**
|
||||
* 文件 只读
|
||||
*/
|
||||
String FILE_READONLY = "readonly";
|
||||
|
||||
/**
|
||||
* 登录失败,用于记录失败次数的key
|
||||
*/
|
||||
String LOGIN_FAIL = "LOGIN_FAIL_";
|
||||
|
||||
/**
|
||||
* 入职事件
|
||||
*/
|
||||
Integer BPM_USER_EVENT_ADD = 1;
|
||||
|
||||
/**
|
||||
* 离职事件
|
||||
*/
|
||||
Integer BPM_USER_EVENT_LEVEL = 2;
|
||||
|
||||
/**
|
||||
* 用户租户状态(正常/已通过审核的)
|
||||
*/
|
||||
String USER_TENANT_NORMAL = "1";
|
||||
|
||||
/**
|
||||
* 用户租户状态(离职)
|
||||
*/
|
||||
String USER_TENANT_QUIT = "2";
|
||||
|
||||
/**
|
||||
* 用户租户状态(审核中)
|
||||
*/
|
||||
String USER_TENANT_UNDER_REVIEW = "3";
|
||||
|
||||
/**
|
||||
* 用户租户状态(拒绝)
|
||||
*/
|
||||
String USER_TENANT_REFUSE = "4";
|
||||
|
||||
/**
|
||||
* 用户租户状态(邀请)
|
||||
*/
|
||||
String USER_TENANT_INVITE = "5";
|
||||
|
||||
/**
|
||||
* 不是叶子节点
|
||||
*/
|
||||
Integer NOT_LEAF = 0;
|
||||
|
||||
/**
|
||||
* 是叶子节点
|
||||
*/
|
||||
Integer IS_LEAF = 1;
|
||||
|
||||
/**
|
||||
* 钉钉
|
||||
*/
|
||||
String DINGTALK = "DINGTALK";
|
||||
|
||||
/**
|
||||
* 企业微信
|
||||
*/
|
||||
String WECHAT_ENTERPRISE = "WECHAT_ENTERPRISE";
|
||||
|
||||
/**
|
||||
* 系统默认租户id 0
|
||||
*/
|
||||
Integer TENANT_ID_DEFAULT_VALUE = 0;
|
||||
|
||||
/**
|
||||
* 【low-app用】 应用级别的复制
|
||||
*/
|
||||
String COPY_LEVEL_APP = "app";
|
||||
|
||||
/**
|
||||
* 【low-app用】 菜单级别的复制
|
||||
*/
|
||||
String COPY_LEVEL_MENU = "menu";
|
||||
|
||||
|
||||
/**
|
||||
* 【low-app用】 应用备份
|
||||
*/
|
||||
String COPY_LEVEL_BAK = "backup";
|
||||
|
||||
/**
|
||||
* 【low-app用】 从备份还原
|
||||
*/
|
||||
String COPY_LEVEL_COVER = "cover";
|
||||
|
||||
/** 【QQYUN-6034】关联字段变更历史值,缓存半个小时 */
|
||||
String CACHE_REL_FIELD_OLD_VAL = "sys:cache:desform:relFieldOldVal:";
|
||||
|
||||
/**
|
||||
* 排序类型:升序
|
||||
*/
|
||||
String ORDER_TYPE_ASC = "ASC";
|
||||
/**
|
||||
* 排序类型:降序
|
||||
*/
|
||||
String ORDER_TYPE_DESC = "DESC";
|
||||
|
||||
|
||||
//update-begin---author:scott ---date:2023-09-10 for:积木报表常量----
|
||||
/**
|
||||
* 报表允许设计开发的角色
|
||||
*/
|
||||
public static String[] allowDevRoles = new String[]{"lowdeveloper", "admin"};
|
||||
/**
|
||||
* 【对应积木报表的常量】
|
||||
* 数据隔离模式: 按照创建人隔离
|
||||
*/
|
||||
public static final String SAAS_MODE_CREATED = "created";
|
||||
/**
|
||||
* 【对应积木报表的常量】
|
||||
* 数据隔离模式: 按照租户隔离
|
||||
*/
|
||||
public static final String SAAS_MODE_TENANT = "tenant";
|
||||
//update-end---author:scott ---date::2023-09-10 for:积木报表常量----
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-04-07---for:修改手机号常量---
|
||||
/**
|
||||
* 修改手机号短信验证码redis-key的前缀
|
||||
*/
|
||||
String CHANGE_PHONE_REDIS_KEY_PRE = "sys:cache:phone:change_phone_msg:";
|
||||
|
||||
/**
|
||||
* 手机号短信验证码redis-key的前缀
|
||||
*/
|
||||
String LOG_OFF_PHONE_REDIS_KEY_PRE = "sys:cache:phone:qqy_log_off_user_msg:";
|
||||
|
||||
/**
|
||||
* 缓存用户最后一次收到消息通知的时间 KEY
|
||||
*/
|
||||
String CACHE_KEY_USER_LAST_ANNOUNT_TIME_1HOUR = "sys:cache:userinfo:user_last_annount_time::%s";
|
||||
|
||||
/**
|
||||
* 验证原手机号
|
||||
*/
|
||||
String VERIFY_ORIGINAL_PHONE = "verifyOriginalPhone";
|
||||
|
||||
/**
|
||||
* 修改手机号
|
||||
*/
|
||||
String UPDATE_PHONE = "updatePhone";
|
||||
//update-end---author:wangshuai---date:2024-04-07---for:修改手机号常量---
|
||||
|
||||
/**
|
||||
* 修改手机号验证码请求次数超出
|
||||
*/
|
||||
Integer PHONE_SMS_FAIL_CODE = 40002;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
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";
|
||||
|
||||
|
||||
/**-----【流程相关通知模板code】------------------------------------------------------------*/
|
||||
/**流程催办——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
|
||||
/**流程抄送——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CC = "bpm_cc";
|
||||
/**流程催办——邮件通知消息模板*/
|
||||
public static final String TZMB_BPM_CUIBAN_EMAIL = "bpm_cuiban_email";
|
||||
/**标准模板—系统消息通知*/
|
||||
public static final String TZMB_SYS_TS_NOTE = "sys_ts_note";
|
||||
/**流程超时提醒——系统通知消息模板*/
|
||||
public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip";
|
||||
/**-----【流程相关通知模板code】-----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 系统通知拓展参数(比如:用于流程抄送和催办通知,这里额外传递流程跳转页面所需要的路由参数)
|
||||
*/
|
||||
public static final String MSG_ABSTRACT_JSON = "msg_abstract";
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
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";
|
||||
|
||||
/**人大金仓数据库*/
|
||||
public static final String DB_TYPE_KINGBASEES = "KINGBASEES";
|
||||
|
||||
/**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";
|
||||
/**
|
||||
* 数据-所属机构ID
|
||||
*/
|
||||
public static final String SYS_ORG_ID = "sysOrgId";
|
||||
/**
|
||||
* 数据-所属机构ID
|
||||
*/
|
||||
public static final String SYS_ORG_ID_TABLE = "sys_org_id";
|
||||
/**
|
||||
* 数据-所属角色code(多个逗号分割)
|
||||
*/
|
||||
public static final String SYS_ROLE_CODE = "sysRoleCode";
|
||||
/**
|
||||
* 数据-所属角色code(多个逗号分割)
|
||||
*/
|
||||
public static final String SYS_ROLE_CODE_TABLE = "sys_role_code";
|
||||
/**
|
||||
* 数据-系统用户编码(对应登录用户账号)
|
||||
*/
|
||||
public static final String SYS_USER_CODE = "sysUserCode";
|
||||
/**
|
||||
* 数据-系统用户编码(对应登录用户账号)
|
||||
*/
|
||||
public static final String SYS_USER_CODE_TABLE = "sys_user_code";
|
||||
/**
|
||||
* 登录用户ID
|
||||
*/
|
||||
public static final String SYS_USER_ID = "sysUserId";
|
||||
/**
|
||||
* 登录用户ID
|
||||
*/
|
||||
public static final String SYS_USER_ID_TABLE = "sys_user_id";
|
||||
/**
|
||||
* 登录用户真实姓名
|
||||
*/
|
||||
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";
|
||||
//*********系统建表标准字段****************************************
|
||||
|
||||
/**
|
||||
* 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,223 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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){
|
||||
if(StringUtils.isNotBlank(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){
|
||||
if(StringUtils.isNotBlank(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,59 @@
|
||||
/*
|
||||
*
|
||||
* * 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";
|
||||
/**
|
||||
* 微服务名:joa模块
|
||||
*/
|
||||
String SERVICE_JOA = "jeecg-joa";
|
||||
|
||||
// /**
|
||||
// * 微服务名:online在线模块
|
||||
// */
|
||||
// String SERVICE_ONLINE = "jeecg-online";
|
||||
// /**
|
||||
// * 微服务名:OA模块
|
||||
// */
|
||||
// String SERVICE_EOA = "jeecg-eoa";
|
||||
// /**
|
||||
// * 微服务名:表单设计模块
|
||||
// */
|
||||
// String SERVICE_FORM = "jeecg-desform";
|
||||
|
||||
/**
|
||||
* gateway通过header传递根路径 basePath
|
||||
*/
|
||||
String X_GATEWAY_BASE_PATH = "X_GATEWAY_BASE_PATH";
|
||||
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
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 = "]";
|
||||
|
||||
/**
|
||||
* 拼接字符串符号 分号 ;
|
||||
*/
|
||||
public static final String SEMICOLON = ";";
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* @Description: TenantConstant
|
||||
* @author: scott
|
||||
* @date: 2022年08月29日 15:29
|
||||
*/
|
||||
public interface TenantConstant {
|
||||
/*------【低代码应用参数】----------------------------------------------*/
|
||||
/**
|
||||
* header的lowAppId标识
|
||||
*/
|
||||
String X_LOW_APP_ID = "X-Low-App-ID";
|
||||
/**
|
||||
* 应用ID——实体字段
|
||||
*/
|
||||
String FIELD_LOW_APP_ID = "lowAppId";
|
||||
/**
|
||||
* 应用ID——表字段
|
||||
*/
|
||||
String DB_FIELD_LOW_APP_ID = "low_app_id";
|
||||
/*------【低代码应用参数】---------------------------------------------*/
|
||||
|
||||
/*--------【租户参数】-----------------------------------------------*/
|
||||
/**
|
||||
* 租户ID(实体字段名 和 url参数名)
|
||||
*/
|
||||
String TENANT_ID = "tenantId";
|
||||
/**
|
||||
* 租户ID 数据库字段名
|
||||
*/
|
||||
String TENANT_ID_TABLE = "tenant_id";
|
||||
/*-------【租户参数】-----------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 超级管理员
|
||||
*/
|
||||
String SUPER_ADMIN = "superAdmin";
|
||||
|
||||
/**
|
||||
* 组织账户管理员
|
||||
*/
|
||||
String ACCOUNT_ADMIN = "accountAdmin";
|
||||
|
||||
/**
|
||||
* 组织应用管理员
|
||||
*/
|
||||
String APP_ADMIN = "appAdmin";
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* VXESocket 常量
|
||||
* @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,66 @@
|
||||
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";
|
||||
|
||||
/**
|
||||
* 消息json key:chat
|
||||
*/
|
||||
public static final String MSG_CHAT = "chat";
|
||||
|
||||
/**
|
||||
* 消息类型 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,167 @@
|
||||
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", "default.one", "经典风格", new String[]{"vue3","vue","vue3Native"}),
|
||||
|
||||
/**
|
||||
* 多表
|
||||
*/
|
||||
MANY(2, "many", "/jeecg/code-template-online", "default.onetomany", "经典风格" ,new String[]{"vue"}),
|
||||
/**
|
||||
* 多表(jvxe风格)
|
||||
* */
|
||||
JVXE_TABLE(2, "jvxe", "/jeecg/code-template-online", "jvxe.onetomany", "默认风格" ,new String[]{"vue3","vue","vue3Native"}),
|
||||
|
||||
/**
|
||||
* 多表 (erp风格)
|
||||
*/
|
||||
ERP(2, "erp", "/jeecg/code-template-online", "erp.onetomany", "ERP风格" ,new String[]{"vue3","vue","vue3Native"}),
|
||||
/**
|
||||
* 多表(内嵌子表风格)
|
||||
*/
|
||||
INNER_TABLE(2, "innerTable", "/jeecg/code-template-online", "inner-table.onetomany", "内嵌子表风格" ,new String[]{"vue3","vue"}),
|
||||
/**
|
||||
* 多表(tab风格)
|
||||
* */
|
||||
TAB(2, "tab", "/jeecg/code-template-online", "tab.onetomany", "Tab风格" ,new String[]{"vue3","vue"}),
|
||||
/**
|
||||
* 树形列表
|
||||
*/
|
||||
TREE(3, "tree", "/jeecg/code-template-online", "default.tree", "树形列表" ,new String[]{"vue3","vue","vue3Native"});
|
||||
|
||||
/**
|
||||
* 类型 1/单表 2/一对多 3/树
|
||||
*/
|
||||
int type;
|
||||
/**
|
||||
* 编码标识
|
||||
*/
|
||||
String code;
|
||||
/**
|
||||
* 代码生成器模板路径
|
||||
*/
|
||||
String templatePath;
|
||||
/**
|
||||
* 代码生成器模板路径
|
||||
*/
|
||||
String stylePath;
|
||||
/**
|
||||
* 模板风格名称
|
||||
*/
|
||||
String note;
|
||||
/**
|
||||
* 支持代码风格 vue3:vue3包装代码 vue3Native:vue3原生代码 vue:vue2代码
|
||||
*/
|
||||
String[] vueStyle;
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*
|
||||
* @param type 类型 1/单表 2/一对多 3/树
|
||||
* @param code 模板编码
|
||||
* @param templatePath 模板路径
|
||||
* @param stylePath 模板子路径
|
||||
* @param note
|
||||
* @param vueStyle 支持代码风格
|
||||
*/
|
||||
CgformEnum(int type, String code, String templatePath, String stylePath, String note, String[] vueStyle) {
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
this.templatePath = templatePath;
|
||||
this.stylePath = stylePath;
|
||||
this.note = note;
|
||||
this.vueStyle = vueStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据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;
|
||||
}
|
||||
|
||||
public String[] getVueStyle() {
|
||||
return vueStyle;
|
||||
}
|
||||
|
||||
public void setVueStyle(String[] vueStyle) {
|
||||
this.vueStyle = vueStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据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,23 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
/**
|
||||
* 客户终端类型
|
||||
*/
|
||||
public enum ClientTerminalTypeEnum {
|
||||
|
||||
PC("pc", "电脑终端"),
|
||||
H5("h5", "移动网页端"),
|
||||
APP("app", "手机app端");
|
||||
|
||||
private String key;
|
||||
private String text;
|
||||
|
||||
ClientTerminalTypeEnum(String value, String text) {
|
||||
this.key = value;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
/**
|
||||
* 日期预设范围枚举
|
||||
*/
|
||||
public enum DateRangeEnum {
|
||||
// 今天
|
||||
TODAY,
|
||||
// 昨天
|
||||
YESTERDAY,
|
||||
// 明天
|
||||
TOMORROW,
|
||||
// 本周
|
||||
THIS_WEEK,
|
||||
// 上周
|
||||
LAST_WEEK,
|
||||
// 下周
|
||||
NEXT_WEEK,
|
||||
// 过去七天
|
||||
LAST_7_DAYS,
|
||||
// 本月
|
||||
THIS_MONTH,
|
||||
// 上月
|
||||
LAST_MONTH,
|
||||
// 下月
|
||||
NEXT_MONTH,
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @Description: 短信枚举类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum DySmsEnum {
|
||||
|
||||
/**登录短信模板编码*/
|
||||
LOGIN_TEMPLATE_CODE("SMS_175435174","敲敲云","code"),
|
||||
/**忘记密码短信模板编码*/
|
||||
FORGET_PASSWORD_TEMPLATE_CODE("SMS_175435174","敲敲云","code"),
|
||||
/**修改密码短信模板编码*/
|
||||
CHANGE_PASSWORD_TEMPLATE_CODE("SMS_465391221","敲敲云","code"),
|
||||
/**注册账号短信模板编码*/
|
||||
REGISTER_TEMPLATE_CODE("SMS_175430166","敲敲云","code");
|
||||
|
||||
/**
|
||||
* 短信模板编码
|
||||
*/
|
||||
private String templateCode;
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
private String signName;
|
||||
/**
|
||||
* 短信模板必需的数据名称,多个key以逗号分隔,此处配置作为校验
|
||||
*/
|
||||
private String keys;
|
||||
|
||||
private DySmsEnum(String templateCode,String signName,String keys) {
|
||||
this.templateCode = templateCode;
|
||||
this.signName = signName;
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public String getTemplateCode() {
|
||||
return templateCode;
|
||||
}
|
||||
|
||||
public void setTemplateCode(String templateCode) {
|
||||
this.templateCode = templateCode;
|
||||
}
|
||||
|
||||
public String getSignName() {
|
||||
return signName;
|
||||
}
|
||||
|
||||
public void setSignName(String signName) {
|
||||
this.signName = signName;
|
||||
}
|
||||
|
||||
public String getKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public void setKeys(String keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
public static DySmsEnum toEnum(String templateCode) {
|
||||
if(StringUtils.isEmpty(templateCode)){
|
||||
return null;
|
||||
}
|
||||
for(DySmsEnum item : DySmsEnum.values()) {
|
||||
if(item.getTemplateCode().equals(templateCode)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* 邮件html模板配置地址美剧
|
||||
*
|
||||
* @author: liusq
|
||||
* @Date: 2023-10-13
|
||||
*/
|
||||
public enum EmailTemplateEnum {
|
||||
/**
|
||||
* 流程催办
|
||||
*/
|
||||
BPM_CUIBAN_EMAIL("bpm_cuiban_email", "/templates/email/bpm_cuiban_email.ftl"),
|
||||
/**
|
||||
* 流程新任务
|
||||
*/
|
||||
BPM_NEW_TASK_EMAIL("bpm_new_task_email", "/templates/email/bpm_new_task_email.ftl"),
|
||||
/**
|
||||
* 表单新增记录
|
||||
*/
|
||||
DESFORM_NEW_DATA_EMAIL("desform_new_data_email", "/templates/email/desform_new_data_email.ftl");
|
||||
|
||||
/**
|
||||
* 模板名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 模板地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
EmailTemplateEnum(String name, String url) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public static EmailTemplateEnum getByName(String name) {
|
||||
if (oConvertUtils.isEmpty(name)) {
|
||||
return null;
|
||||
}
|
||||
for (EmailTemplateEnum val : values()) {
|
||||
if (val.getName().equals(name)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
public enum FileTypeEnum {
|
||||
// 文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频 voice:语音)
|
||||
// FOLDER
|
||||
xls(".xls","excel","excel"),
|
||||
xlsx(".xlsx","excel","excel"),
|
||||
doc(".doc","doc","word"),
|
||||
docx(".docx","doc","word"),
|
||||
ppt(".ppt","pp","ppt"),
|
||||
pptx(".pptx","pp","ppt"),
|
||||
gif(".gif","image","图片"),
|
||||
jpg(".jpg","image","图片"),
|
||||
jpeg(".jpeg","image","图片"),
|
||||
png(".png","image","图片"),
|
||||
txt(".txt","text","文本"),
|
||||
avi(".avi","video","视频"),
|
||||
mov(".mov","video","视频"),
|
||||
rmvb(".rmvb","video","视频"),
|
||||
rm(".rm","video","视频"),
|
||||
flv(".flv","video","视频"),
|
||||
mp4(".mp4","video","视频"),
|
||||
zip(".zip","zip","压缩包"),
|
||||
pdf(".pdf","pdf","pdf"),
|
||||
mp3(".mp3","mp3","语音");
|
||||
|
||||
private String type;
|
||||
private String value;
|
||||
private String text;
|
||||
private FileTypeEnum(String type,String value,String text){
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.text = text;
|
||||
}
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static FileTypeEnum getByType(String type){
|
||||
if (oConvertUtils.isEmpty(type)) {
|
||||
return null;
|
||||
}
|
||||
for (FileTypeEnum val : values()) {
|
||||
if (val.getType().equals(type)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据type获取枚举
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static MessageTypeEnum valueOfType(String type) {
|
||||
for (MessageTypeEnum e : MessageTypeEnum.values()) {
|
||||
if (e.getType().equals(type)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -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,97 @@
|
||||
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"),
|
||||
|
||||
// 注:此值仅为防止报错,无任何实际意义
|
||||
ROLE_INDEX_CONFIG_ENUM("RoleIndexConfigEnumDefault", "dashboard/Analysis");
|
||||
|
||||
/**
|
||||
* 角色编码
|
||||
*/
|
||||
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,82 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* 系统公告自定义跳转方式
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public enum SysAnnmentTypeEnum {
|
||||
/**
|
||||
* 邮件跳转组件
|
||||
*/
|
||||
EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"),
|
||||
/**
|
||||
* 流程跳转到我的任务
|
||||
*/
|
||||
BPM("bpm", "url", "/bpm/task/MyTaskList"),
|
||||
|
||||
/**
|
||||
* 流程抄送任务
|
||||
*/
|
||||
BPM_VIEW("bpm_cc", "url", "/bpm/task/MyTaskList"),
|
||||
/**
|
||||
* 邀请用户跳转到个人设置
|
||||
*/
|
||||
TENANT_INVITE("tenant_invite", "url", "/system/usersetting");
|
||||
|
||||
/**
|
||||
* 业务类型(email:邮件 bpm:流程)
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 打开方式 组件:component 路由:url
|
||||
*/
|
||||
private String openType;
|
||||
/**
|
||||
* 组件/路由 地址
|
||||
*/
|
||||
private String openPage;
|
||||
|
||||
SysAnnmentTypeEnum(String type, String openType, String openPage) {
|
||||
this.type = type;
|
||||
this.openType = openType;
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getOpenType() {
|
||||
return openType;
|
||||
}
|
||||
|
||||
public void setOpenType(String openType) {
|
||||
this.openType = openType;
|
||||
}
|
||||
|
||||
public String getOpenPage() {
|
||||
return openPage;
|
||||
}
|
||||
|
||||
public void setOpenPage(String openPage) {
|
||||
this.openPage = openPage;
|
||||
}
|
||||
|
||||
public static SysAnnmentTypeEnum getByType(String type) {
|
||||
if (oConvertUtils.isEmpty(type)) {
|
||||
return null;
|
||||
}
|
||||
for (SysAnnmentTypeEnum val : values()) {
|
||||
if (val.getType().equals(type)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 消息跳转【vue3】
|
||||
* @Author taoYan
|
||||
* @Date 2022/8/19 20:41
|
||||
**/
|
||||
@EnumDict("messageHref")
|
||||
public enum Vue3MessageHrefEnum {
|
||||
|
||||
/**
|
||||
* 流程催办
|
||||
*/
|
||||
BPM("bpm", "/task/myHandleTaskInfo"),
|
||||
|
||||
/**
|
||||
* 系统消息通知
|
||||
*/
|
||||
BPM_SYSTEM_MSG("bpm_msg_node", ""),
|
||||
|
||||
/**
|
||||
* 流程抄送任务
|
||||
*/
|
||||
BPM_VIEW("bpm_cc", "/task/myHandleTaskInfo"),
|
||||
|
||||
/**
|
||||
* 节点通知
|
||||
*/
|
||||
BPM_TASK("bpm_task", "/task/myHandleTaskInfo"),
|
||||
|
||||
/**
|
||||
* 邮件消息
|
||||
*/
|
||||
EMAIL("email", "/eoa/email");
|
||||
|
||||
String busType;
|
||||
|
||||
String path;
|
||||
|
||||
Vue3MessageHrefEnum(String busType, String path) {
|
||||
this.busType = busType;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getBusType() {
|
||||
return busType;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
* @return
|
||||
*/
|
||||
public static List<DictModel> getDictList(){
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
DictModel dictModel = null;
|
||||
for(Vue3MessageHrefEnum e: Vue3MessageHrefEnum.values()){
|
||||
dictModel = new DictModel();
|
||||
dictModel.setValue(e.getBusType());
|
||||
dictModel.setText(e.getPath());
|
||||
list.add(dictModel);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package org.jeecg.common.desensitization;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.BeanProperty;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.desensitization.annotation.Sensitive;
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.jeecg.common.util.encryption.AesEncryptUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author eightmonth@qq.com
|
||||
* @date 2024/6/19 10:43
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {
|
||||
|
||||
private SensitiveEnum type;
|
||||
|
||||
@Override
|
||||
public void serialize(String data, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
switch (type){
|
||||
case ENCODE:
|
||||
try {
|
||||
jsonGenerator.writeString(AesEncryptUtil.encrypt(data));
|
||||
} catch (Exception exception) {
|
||||
log.error("数据加密错误", exception.getMessage());
|
||||
jsonGenerator.writeString(data);
|
||||
}
|
||||
break;
|
||||
case CHINESE_NAME:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.chineseName(data));
|
||||
break;
|
||||
case ID_CARD:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.idCardNum(data));
|
||||
break;
|
||||
case FIXED_PHONE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.fixedPhone(data));
|
||||
break;
|
||||
case MOBILE_PHONE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.mobilePhone(data));
|
||||
break;
|
||||
case ADDRESS:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.address(data, 3));
|
||||
break;
|
||||
case EMAIL:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.email(data));
|
||||
break;
|
||||
case BANK_CARD:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.bankCard(data));
|
||||
break;
|
||||
case CNAPS_CODE:
|
||||
jsonGenerator.writeString(SensitiveInfoUtil.cnapsCode(data));
|
||||
break;
|
||||
default:
|
||||
jsonGenerator.writeString(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
|
||||
if (beanProperty != null) {
|
||||
if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
|
||||
Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
|
||||
if (sensitive == null) {
|
||||
sensitive = beanProperty.getContextAnnotation(Sensitive.class);
|
||||
}
|
||||
if (sensitive != null) {
|
||||
return new SensitiveSerialize(sensitive.type());
|
||||
}
|
||||
}
|
||||
return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
|
||||
}
|
||||
return serializerProvider.findNullValueSerializer(null);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jeecg.common.desensitization.annotation;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.jeecg.common.desensitization.SensitiveSerialize;
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 在字段上定义 标识字段存储的信息是敏感的
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@JacksonAnnotationsInside
|
||||
@JsonSerialize(using = SensitiveSerialize.class)
|
||||
public @interface Sensitive {
|
||||
|
||||
/**
|
||||
* 不同类型处理不同
|
||||
* @return
|
||||
*/
|
||||
SensitiveEnum type() default SensitiveEnum.ENCODE;
|
||||
}
|
@ -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,363 @@
|
||||
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 {
|
||||
if (oConvertUtils.isEmpty(obj)) {
|
||||
return obj;
|
||||
}
|
||||
long startTime=System.currentTimeMillis();
|
||||
log.debug(" obj --> "+ obj.toString());
|
||||
|
||||
// 判断是不是一个对象
|
||||
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.debug("数据解密错误,原数据:"+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 <例子:李**>
|
||||
*/
|
||||
public static String chineseName(String fullName) {
|
||||
if (oConvertUtils.isEmpty(fullName)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(fullName, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号
|
||||
* @param familyName 姓
|
||||
* @param firstName 名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
public 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>
|
||||
*/
|
||||
public static String idCardNum(String id) {
|
||||
if (oConvertUtils.isEmpty(id)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(id, 4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* [固定电话] 后四位,其他隐藏
|
||||
* @param num 固定电话
|
||||
* @return <例子:****1234>
|
||||
*/
|
||||
public static String fixedPhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(num, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [手机号码] 前三位,后四位,其他隐藏
|
||||
* @param num 手机号码
|
||||
* @return <例子:138******1234>
|
||||
*/
|
||||
public 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 <例子:北京市海淀区****>
|
||||
*/
|
||||
public 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>
|
||||
*/
|
||||
public 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>
|
||||
*/
|
||||
public static String bankCard(String cardNum) {
|
||||
if (oConvertUtils.isEmpty(cardNum)) {
|
||||
return "";
|
||||
}
|
||||
return formatBetween(cardNum, 6, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号
|
||||
* @param code 公司开户银行联号
|
||||
* @return <例子:12********>
|
||||
*/
|
||||
public static String cnapsCode(String code) {
|
||||
if (oConvertUtils.isEmpty(code)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(code, 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将右边的格式化成*
|
||||
* @param str 字符串
|
||||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public 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 格式化后的字符串
|
||||
*/
|
||||
public 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 格式化后的字符串
|
||||
*/
|
||||
public 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,546 @@
|
||||
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.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
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
|
||||
@ConditionalOnProperty(prefix = "jeecg.elasticsearch", name = "cluster-nodes")
|
||||
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,21 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
/**
|
||||
* jeecgboot断言异常
|
||||
* for [QQYUN-10990]AIRAG
|
||||
* @author chenrui
|
||||
* @date 2025/2/14 14:31
|
||||
*/
|
||||
public class JeecgBootAssertException extends JeecgBootException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
public JeecgBootAssertException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootAssertException(String message, int errCode) {
|
||||
super(message, errCode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
/**
|
||||
* @Description: 业务提醒异常(用于操作业务提醒)
|
||||
* @date: 2024-04-26
|
||||
* @author: scott
|
||||
*/
|
||||
public class JeecgBootBizTipException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 返回给前端的错误code
|
||||
*/
|
||||
private int errCode = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
|
||||
|
||||
public JeecgBootBizTipException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootBizTipException(String message, int errCode){
|
||||
super(message);
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public int getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public JeecgBootBizTipException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgBootBizTipException(String message, Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
/**
|
||||
* @Description: jeecg-boot自定义异常
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class JeecgBootException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 返回给前端的错误code
|
||||
*/
|
||||
private int errCode = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
|
||||
|
||||
public JeecgBootException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgBootException(String message, int errCode){
|
||||
super(message);
|
||||
this.errCode = errCode;
|
||||
}
|
||||
|
||||
public int getErrCode() {
|
||||
return errCode;
|
||||
}
|
||||
|
||||
public JeecgBootException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgBootException(String message,Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,304 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import io.undertow.server.RequestTooBigException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.jeecg.common.api.dto.LogDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.enums.ClientTerminalTypeEnum;
|
||||
import org.jeecg.common.enums.SentinelErrorInfoEnum;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.BrowserUtils;
|
||||
import org.jeecg.common.util.IpUtils;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.springframework.beans.BeansException;
|
||||
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.util.CollectionUtils;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
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.multipart.MultipartException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
*
|
||||
* @Author scott
|
||||
* @Date 2019
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class JeecgBootExceptionHandler {
|
||||
|
||||
@Resource
|
||||
BaseCommonService baseCommonService;
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Result<?> handleValidationExceptions(MethodArgumentNotValidException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error("校验失败!" + e.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(",")));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBootException.class)
|
||||
public Result<?> handleJeecgBootException(JeecgBootException e){
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error(e.getErrCode(), e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBootBizTipException.class)
|
||||
public Result<?> handleJeecgBootBizTipException(JeecgBootBizTipException e){
|
||||
log.error(e.getMessage());
|
||||
return Result.error(e.getErrCode(), e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义微服务异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgCloudException.class)
|
||||
public Result<?> handleJeecgCloudException(JeecgCloudException e){
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(JeecgBoot401Exception.class)
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
public Result<?> handleJeecgBoot401Exception(JeecgBoot401Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return new Result(401,e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public Result<?> handlerNoFoundException(Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error(404, "路径不存在,请检查路径是否正确");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public Result<?> handleDuplicateKeyException(DuplicateKeyException e){
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(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限流自定义异常
|
||||
addSysLog(e);
|
||||
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("没有权限,请联系管理员授权");
|
||||
addSysLog(e);
|
||||
return Result.error(405,sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
|
||||
*/
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理文件过大异常.
|
||||
* jdk17中的MultipartException异常类已经被拆分成了MultipartException和MaxUploadSizeExceededException
|
||||
* for [QQYUN-11716]上传大图片失败没有精确提示
|
||||
* @param e
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2025/4/8 16:13
|
||||
*/
|
||||
@ExceptionHandler(MultipartException.class)
|
||||
public Result<?> handleMaxUploadSizeExceededException(MultipartException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof IllegalStateException && cause.getCause() instanceof RequestTooBigException) {
|
||||
log.error("文件大小超出限制: {}", cause.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error("文件大小超出限制, 请压缩或降低文件质量!");
|
||||
} else {
|
||||
return handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
//【issues/3624】数据库执行异常handleDataIntegrityViolationException提示有误 #3624
|
||||
return Result.error("执行数据库异常,违反了完整性例如:违反惟一约束、违反非空限制、字段内容超出长度等");
|
||||
}
|
||||
|
||||
@ExceptionHandler(PoolException.class)
|
||||
public Result<?> handlePoolException(PoolException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error("Redis 连接异常!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SQL注入风险,全局异常处理
|
||||
*
|
||||
* @param exception
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler(JeecgSqlInjectionException.class)
|
||||
public Result<?> handleSQLException(Exception exception) {
|
||||
String msg = exception.getMessage().toLowerCase();
|
||||
final String extractvalue = "extractvalue";
|
||||
final String updatexml = "updatexml";
|
||||
boolean hasSensitiveInformation = msg.indexOf(extractvalue) >= 0 || msg.indexOf(updatexml) >= 0;
|
||||
if (msg != null && hasSensitiveInformation) {
|
||||
log.error("校验失败,存在SQL注入风险!{}", msg);
|
||||
return Result.error("校验失败,存在SQL注入风险!");
|
||||
}
|
||||
addSysLog(exception);
|
||||
return Result.error("校验失败,存在SQL注入风险!" + msg);
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240423 for:[QQYUN-8732]把错误的日志都抓取了 方便后续处理,单独弄个日志类型------------
|
||||
/**
|
||||
* 添加异常新系统日志
|
||||
* @param e 异常
|
||||
* @author chenrui
|
||||
* @date 2024/4/22 17:16
|
||||
*/
|
||||
private void addSysLog(Throwable e) {
|
||||
LogDTO log = new LogDTO();
|
||||
log.setLogType(CommonConstant.LOG_TYPE_4);
|
||||
log.setLogContent(e.getClass().getName()+":"+e.getMessage());
|
||||
log.setRequestParam(ExceptionUtils.getStackTrace(e));
|
||||
//获取request
|
||||
HttpServletRequest request = null;
|
||||
try {
|
||||
request = SpringContextUtils.getHttpServletRequest();
|
||||
} catch (NullPointerException | BeansException ignored) {
|
||||
}
|
||||
if (null != request) {
|
||||
//update-begin---author:chenrui ---date:20250408 for:[QQYUN-11716]上传大图片失败没有精确提示------------
|
||||
//请求的参数
|
||||
if (!isTooBigException(e)) {
|
||||
// 文件上传过大异常时不能获取参数,否则会报错
|
||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||
if(!CollectionUtils.isEmpty(parameterMap)) {
|
||||
log.setMethod(oConvertUtils.mapToString(request.getParameterMap()));
|
||||
}
|
||||
}
|
||||
//update-end---author:chenrui ---date:20250408 for:[QQYUN-11716]上传大图片失败没有精确提示------------
|
||||
// 请求地址
|
||||
log.setRequestUrl(request.getRequestURI());
|
||||
//设置IP地址
|
||||
log.setIp(IpUtils.getIpAddr(request));
|
||||
//设置客户端
|
||||
if(BrowserUtils.isDesktop(request)){
|
||||
log.setClientType(ClientTerminalTypeEnum.PC.getKey());
|
||||
}else{
|
||||
log.setClientType(ClientTerminalTypeEnum.APP.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//获取登录用户信息
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
if(sysUser!=null){
|
||||
log.setUserid(sysUser.getUsername());
|
||||
log.setUsername(sysUser.getRealname());
|
||||
|
||||
}
|
||||
|
||||
baseCommonService.addLog(log);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240423 for:[QQYUN-8732]把错误的日志都抓取了 方便后续处理,单独弄个日志类型------------
|
||||
|
||||
/**
|
||||
* 是否文件过大异常
|
||||
* for [QQYUN-11716]上传大图片失败没有精确提示
|
||||
* @param e
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2025/4/8 20:21
|
||||
*/
|
||||
private static boolean isTooBigException(Throwable e) {
|
||||
boolean isTooBigException = false;
|
||||
if(e instanceof MultipartException){
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof IllegalStateException && cause.getCause() instanceof RequestTooBigException){
|
||||
isTooBigException = true;
|
||||
}
|
||||
}
|
||||
if(e instanceof MaxUploadSizeExceededException){
|
||||
isTooBigException = true;
|
||||
}
|
||||
return isTooBigException;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
/**
|
||||
* @Description: jeecg-boot自定义SQL注入异常
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class JeecgSqlInjectionException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JeecgSqlInjectionException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
public JeecgSqlInjectionException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public JeecgSqlInjectionException(String message, Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
@ -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.jeecg.config.JeecgBaseConfig;
|
||||
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.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
@Resource
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* 导出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(jeecgBaseConfig.getPath().getUpload());
|
||||
//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,jeecgBaseConfig.getPath().getUpload());
|
||||
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.v3.oas.annotations.media.Schema;
|
||||
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)
|
||||
@Schema(description = "ID")
|
||||
private java.lang.String id;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
@Excel(name = "创建人", width = 15)
|
||||
private java.lang.String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@Schema(description = "更新人")
|
||||
@Excel(name = "更新人", width = 15)
|
||||
private java.lang.String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
@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,19 @@
|
||||
package org.jeecg.common.system.enhance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户增强
|
||||
*/
|
||||
public interface UserFilterEnhance {
|
||||
|
||||
/**
|
||||
* 获取用户id
|
||||
* @param loginUserId 当前登录的用户id
|
||||
*
|
||||
* @return List<String> 返回多个用户id
|
||||
*/
|
||||
default List<String> getUserIds(String loginUserId) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -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,81 @@
|
||||
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 QueryCondition(String field, String type, String dbType, String rule, String val) {
|
||||
this.field = field;
|
||||
this.type = type;
|
||||
this.dbType = dbType;
|
||||
this.rule = rule;
|
||||
this.val = 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
Load Diff
@ -0,0 +1,116 @@
|
||||
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","全模糊"),
|
||||
/**查询规则 不模糊包含*/
|
||||
NOT_LIKE("NOT_LIKE","not_like","不模糊包含"),
|
||||
/**查询规则 左模糊*/
|
||||
LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
|
||||
/**查询规则 右模糊*/
|
||||
RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
|
||||
/**查询规则 带加号等于*/
|
||||
EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"),
|
||||
/**查询规则 多词模糊匹配(and)*/
|
||||
LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"),
|
||||
/**查询规则 多词模糊匹配(or)*/
|
||||
LIKE_WITH_OR("LIKEWITHOR","like_with_or","多词模糊匹配(or)"),
|
||||
/**查询规则 自定义SQL片段*/
|
||||
SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段"),
|
||||
|
||||
/** 查询工作表 */
|
||||
LINKAGE("LINKAGE","linkage","查询工作表"),
|
||||
|
||||
// ------- 当前表单设计器内专用 -------
|
||||
/**查询规则 不以…结尾*/
|
||||
NOT_LEFT_LIKE("NOT_LEFT_LIKE","not_left_like","不以…结尾"),
|
||||
/**查询规则 不以…开头*/
|
||||
NOT_RIGHT_LIKE("NOT_RIGHT_LIKE","not_right_like","不以…开头"),
|
||||
/** 值为空 */
|
||||
EMPTY("EMPTY","empty","值为空"),
|
||||
/** 值不为空 */
|
||||
NOT_EMPTY("NOT_EMPTY","not_empty","值不为空"),
|
||||
/**查询规则 不包含*/
|
||||
NOT_IN("NOT_IN","not_in","不包含"),
|
||||
/**查询规则 多词精确匹配*/
|
||||
ELE_MATCH("ELE_MATCH","elemMatch","多词匹配"),
|
||||
/**查询规则 多词精确不匹配*/
|
||||
ELE_NOT_MATCH("ELE_NOT_MATCH","elemNotMatch","多词精确不匹配"),
|
||||
/**查询规则 范围查询*/
|
||||
RANGE("RANGE","range","范围查询"),
|
||||
/**查询规则 不在范围内查询*/
|
||||
NOT_RANGE("NOT_RANGE","not_range","不在范围查询"),
|
||||
/** 自定义mongodb查询语句 */
|
||||
CUSTOM_MONGODB("CUSTOM_MONGODB","custom_mongodb","自定义mongodb查询语句");
|
||||
// ------- 当前表单设计器内专用 -------
|
||||
|
||||
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().equalsIgnoreCase(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,333 @@
|
||||
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 java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.constant.TenantConstant;
|
||||
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工具类
|
||||
**/
|
||||
@Slf4j
|
||||
public class JwtUtil {
|
||||
|
||||
/**Token有效期为7天(Token在reids中缓存时间为两倍)*/
|
||||
public static final long EXPIRE_TIME = (7 * 12) * 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);
|
||||
jsonResult.setSuccess(false);
|
||||
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) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验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 e) {
|
||||
log.error(e.getMessage(), e);
|
||||
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) {
|
||||
log.warn(e.getMessage(), 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) {
|
||||
//1.优先获取 SysUserCacheInfo
|
||||
if(user==null) {
|
||||
try {
|
||||
user = JeecgDataAutorUtils.loadUserInfo();
|
||||
} catch (Exception e) {
|
||||
log.warn("获取用户信息异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
//2.通过shiro获取登录用户信息
|
||||
LoginUser sysUser = null;
|
||||
try {
|
||||
sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
} catch (Exception e) {
|
||||
log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage());
|
||||
}
|
||||
|
||||
//#{sys_user_code}%
|
||||
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;
|
||||
}
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
// 是否存在字符串标志
|
||||
boolean multiStr;
|
||||
if(oConvertUtils.isNotEmpty(key) && key.trim().matches("^\\[\\w+]$")){
|
||||
key = key.substring(1,key.length()-1);
|
||||
multiStr = true;
|
||||
} else {
|
||||
multiStr = false;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
//替换为当前系统时间(年月日)
|
||||
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";
|
||||
}
|
||||
|
||||
//后台任务获取用户信息异常,导致程序中断
|
||||
if(sysUser==null && user==null){
|
||||
return null;
|
||||
}
|
||||
|
||||
//替换为系统登录用户帐号
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// 替换为系统登录用户ID
|
||||
else if (key.equals(DataBaseConstant.SYS_USER_ID) || key.equalsIgnoreCase(DataBaseConstant.SYS_USER_ID_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getId();
|
||||
}else {
|
||||
returnValue = user.getSysUserId();
|
||||
}
|
||||
}
|
||||
|
||||
//替换为系统登录用户真实名字
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// 替换为系统用户登录所使用的机构ID
|
||||
else if (key.equals(DataBaseConstant.SYS_ORG_ID) || key.equalsIgnoreCase(DataBaseConstant.SYS_ORG_ID_TABLE)) {
|
||||
if (user == null) {
|
||||
returnValue = sysUser.getOrgId();
|
||||
} else {
|
||||
returnValue = user.getSysOrgId();
|
||||
}
|
||||
}
|
||||
|
||||
//替换为系统用户所拥有的所有机构编码
|
||||
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();
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
returnValue = multiStr ? "'" + returnValue + "'" : returnValue;
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
}else{
|
||||
if(user.isOneDepart()) {
|
||||
returnValue = user.getSysMultiOrgCode().get(0);
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
returnValue = multiStr ? "'" + returnValue + "'" : returnValue;
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
}else {
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
returnValue = user.getSysMultiOrgCode().stream()
|
||||
.filter(Objects::nonNull)
|
||||
//update-begin---author:chenrui ---date:20250224 for:[issues/7288]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
.map(orgCode -> {
|
||||
if (multiStr) {
|
||||
return "'" + orgCode + "'";
|
||||
} else {
|
||||
return orgCode;
|
||||
}
|
||||
})
|
||||
//update-end---author:chenrui ---date:20250224 for:[issues/7288]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
.collect(Collectors.joining(", "));
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10785]数据权限,查看自己拥有部门的权限中存在问题 #7288------------
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 替换为当前登录用户的角色code(多个逗号分割)
|
||||
else if (key.equals(DataBaseConstant.SYS_ROLE_CODE) || key.equalsIgnoreCase(DataBaseConstant.SYS_ROLE_CODE_TABLE)) {
|
||||
if (user == null) {
|
||||
returnValue = sysUser.getRoleCode();
|
||||
} else {
|
||||
returnValue = user.getSysRoleCode();
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||
else if (key.equals(TenantConstant.TENANT_ID) || key.toLowerCase().equals(TenantConstant.TENANT_ID_TABLE)){
|
||||
try {
|
||||
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID);
|
||||
} catch (Exception e) {
|
||||
log.warn("获取系统租户异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
//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,136 @@
|
||||
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.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
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";
|
||||
|
||||
/**
|
||||
* 所有枚举java类
|
||||
*/
|
||||
|
||||
private final static String CLASS_ENUM_PATTERN="/**/*Enum.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_ENUM_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实现类
|
||||
*
|
||||
* @param classPath
|
||||
*/
|
||||
public static Object getImplementationClass(String classPath){
|
||||
try {
|
||||
Class<?> aClass = Class.forName(classPath);
|
||||
return SpringContextUtils.getBean(aClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.error("类没有找到",e);
|
||||
return null;
|
||||
} catch (NoSuchBeanDefinitionException e){
|
||||
log.error(classPath + "没有实现",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,243 @@
|
||||
package org.jeecg.common.system.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 查询过滤器,SQL拼接写法拆成独立工具类
|
||||
* @author:qinfeng
|
||||
* @date 20230904
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlConcatUtil {
|
||||
|
||||
/**
|
||||
* 获取单个查询条件的值
|
||||
* @param rule
|
||||
* @param field
|
||||
* @param value
|
||||
* @param isString
|
||||
* @return
|
||||
*/
|
||||
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
|
||||
return getSingleSqlByRule(rule, field, value, isString, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 报表获取查询条件 支持多数据源
|
||||
* @param field
|
||||
* @param alias
|
||||
* @param value
|
||||
* @param isString
|
||||
* @param dataBaseType
|
||||
* @return
|
||||
*/
|
||||
public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString, String dataBaseType) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
field = alias+oConvertUtils.camelToUnderline(field);
|
||||
QueryRuleEnum rule = QueryGenerator.convert2Rule(value);
|
||||
return getSingleSqlByRule(rule, field, value, isString, dataBaseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个查询条件的值
|
||||
* @param rule
|
||||
* @param field
|
||||
* @param value
|
||||
* @param isString
|
||||
* @param dataBaseType
|
||||
* @return
|
||||
*/
|
||||
private static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString, String dataBaseType) {
|
||||
String res = "";
|
||||
switch (rule) {
|
||||
case GT:
|
||||
res =field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case GE:
|
||||
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case LT:
|
||||
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case LE:
|
||||
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case EQ:
|
||||
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case EQ_WITH_ADD:
|
||||
res = field+" = "+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case NE:
|
||||
res = field+" <> "+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
case IN:
|
||||
res = field + " in "+getInConditionValue(value, isString);
|
||||
break;
|
||||
case LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.LIKE);
|
||||
break;
|
||||
case LEFT_LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.LEFT_LIKE);
|
||||
break;
|
||||
case RIGHT_LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.RIGHT_LIKE);
|
||||
break;
|
||||
default:
|
||||
res = field+" = "+getFieldConditionValue(value, isString, dataBaseType);
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询条件的值
|
||||
* @param value
|
||||
* @param isString
|
||||
* @param dataBaseType
|
||||
* @return
|
||||
*/
|
||||
private static String getFieldConditionValue(Object value,boolean isString, String dataBaseType) {
|
||||
String str = value.toString().trim();
|
||||
if(str.startsWith(SymbolConstant.EXCLAMATORY_MARK)) {
|
||||
str = str.substring(1);
|
||||
}else if(str.startsWith(QueryRuleEnum.GE.getValue())) {
|
||||
str = str.substring(2);
|
||||
}else if(str.startsWith(QueryRuleEnum.LE.getValue())) {
|
||||
str = str.substring(2);
|
||||
}else if(str.startsWith(QueryRuleEnum.GT.getValue())) {
|
||||
str = str.substring(1);
|
||||
}else if(str.startsWith(QueryRuleEnum.LT.getValue())) {
|
||||
str = str.substring(1);
|
||||
}else if(str.indexOf(QueryGenerator.QUERY_COMMA_ESCAPE)>0) {
|
||||
str = str.replaceAll("\\+\\+", SymbolConstant.COMMA);
|
||||
}
|
||||
if(dataBaseType==null){
|
||||
dataBaseType = getDbType();
|
||||
}
|
||||
if(isString) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType)){
|
||||
return " N'"+str+"' ";
|
||||
}else{
|
||||
return " '"+str+"' ";
|
||||
}
|
||||
}else {
|
||||
// 如果不是字符串 有一种特殊情况 popup调用都走这个逻辑 参数传递的可能是“‘admin’”这种格式的
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){
|
||||
return " N"+str;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getInConditionValue(Object value,boolean isString) {
|
||||
//update-begin-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错
|
||||
String[] temp = value.toString().split(",");
|
||||
if(temp.length==0){
|
||||
return "('')";
|
||||
}
|
||||
if(isString) {
|
||||
List<String> res = new ArrayList<>();
|
||||
for (String string : temp) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
res.add("N'"+string+"'");
|
||||
}else{
|
||||
res.add("'"+string+"'");
|
||||
}
|
||||
}
|
||||
return "("+String.join("," ,res)+")";
|
||||
}else {
|
||||
return "("+value.toString()+")";
|
||||
}
|
||||
//update-end-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错
|
||||
}
|
||||
|
||||
/**
|
||||
* 先根据值判断 走左模糊还是右模糊
|
||||
* 最后如果值不带任何标识(*或者%),则再根据ruleEnum判断
|
||||
* @param value
|
||||
* @param ruleEnum
|
||||
* @return
|
||||
*/
|
||||
private static String getLikeConditionValue(Object value, QueryRuleEnum ruleEnum) {
|
||||
String str = value.toString().trim();
|
||||
if(str.startsWith(SymbolConstant.ASTERISK) && str.endsWith(SymbolConstant.ASTERISK)) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
return "N'%"+str.substring(1,str.length()-1)+"%'";
|
||||
}else{
|
||||
return "'%"+str.substring(1,str.length()-1)+"%'";
|
||||
}
|
||||
}else if(str.startsWith(SymbolConstant.ASTERISK)) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
return "N'%"+str.substring(1)+"'";
|
||||
}else{
|
||||
return "'%"+str.substring(1)+"'";
|
||||
}
|
||||
}else if(str.endsWith(SymbolConstant.ASTERISK)) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
return "N'"+str.substring(0,str.length()-1)+"%'";
|
||||
}else{
|
||||
return "'"+str.substring(0,str.length()-1)+"%'";
|
||||
}
|
||||
}else {
|
||||
if(str.indexOf(SymbolConstant.PERCENT_SIGN)>=0) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
if(str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){
|
||||
return "N"+str;
|
||||
}else{
|
||||
return "N"+"'"+str+"'";
|
||||
}
|
||||
}else{
|
||||
if(str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){
|
||||
return str;
|
||||
}else{
|
||||
return "'"+str+"'";
|
||||
}
|
||||
}
|
||||
}else {
|
||||
|
||||
//update-begin-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题
|
||||
// 走到这里说明 value不带有任何模糊查询的标识(*或者%)
|
||||
if (ruleEnum == QueryRuleEnum.LEFT_LIKE) {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'%" + str + "'";
|
||||
} else {
|
||||
return "'%" + str + "'";
|
||||
}
|
||||
} else if (ruleEnum == QueryRuleEnum.RIGHT_LIKE) {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'" + str + "%'";
|
||||
} else {
|
||||
return "'" + str + "%'";
|
||||
}
|
||||
} else {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'%" + str + "%'";
|
||||
} else {
|
||||
return "'%" + str + "%'";
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统数据库类型
|
||||
*/
|
||||
private static String getDbType() {
|
||||
return CommonUtils.getDatabaseType();
|
||||
}
|
||||
|
||||
}
|
@ -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,71 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
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;
|
||||
}
|
||||
|
||||
public DictModel(String value, String text, String color) {
|
||||
this.value = value;
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典value
|
||||
*/
|
||||
private String value;
|
||||
/**
|
||||
* 字典文本
|
||||
*/
|
||||
private String text;
|
||||
/**
|
||||
* 字典颜色
|
||||
*/
|
||||
private String color;
|
||||
|
||||
/**
|
||||
* 特殊用途: JgEditableTable
|
||||
* @return
|
||||
*/
|
||||
public String getTitle() {
|
||||
return this.text;
|
||||
}
|
||||
/**
|
||||
* 特殊用途: vue3 Select组件
|
||||
*/
|
||||
public String getLabel() {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用于表单设计器 关联记录表数据存储
|
||||
* QQYUN-5595【表单设计器】他表字段 导入没有翻译
|
||||
*/
|
||||
private JSONObject jsonObject;
|
||||
|
||||
}
|
@ -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,141 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <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
|
||||
*/
|
||||
@SensitiveField
|
||||
private String orgCode;
|
||||
/**
|
||||
* 当前登录部门id
|
||||
*/
|
||||
@SensitiveField
|
||||
private String orgId;
|
||||
/**
|
||||
* 当前登录角色code(多个逗号分割)
|
||||
*/
|
||||
@SensitiveField
|
||||
private String roleCode;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
@SensitiveField
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
@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
|
||||
*/
|
||||
@SensitiveField
|
||||
private String departIds;
|
||||
|
||||
/**
|
||||
* 职务,关联职务表
|
||||
*/
|
||||
@SensitiveField
|
||||
private String post;
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
@SensitiveField
|
||||
private String telephone;
|
||||
|
||||
/** 多租户ids临时用,不持久化数据库(数据库字段不存在) */
|
||||
@SensitiveField
|
||||
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,80 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 系统文件实体类
|
||||
* @author: wangshuai
|
||||
* @date: 2022年08月11日 9:48
|
||||
*/
|
||||
public class SysFilesModel {
|
||||
/**主键id*/
|
||||
private String id;
|
||||
/**文件名称*/
|
||||
private String fileName;
|
||||
/**文件地址*/
|
||||
private String url;
|
||||
/**文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)*/
|
||||
private String fileType;
|
||||
/**文件上传类型(temp/本地上传(临时文件) manage/知识库)*/
|
||||
private String storeType;
|
||||
/**文件大小(kb)*/
|
||||
private Double fileSize;
|
||||
/**租户id*/
|
||||
private String tenantId;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getFileType() {
|
||||
return fileType;
|
||||
}
|
||||
|
||||
public void setFileType(String fileType) {
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
public String getStoreType() {
|
||||
return storeType;
|
||||
}
|
||||
|
||||
public void setStoreType(String storeType) {
|
||||
this.storeType = storeType;
|
||||
}
|
||||
|
||||
public Double getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
public void setFileSize(Double fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(String tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
}
|
@ -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,106 @@
|
||||
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 sysUserId;
|
||||
|
||||
private String sysUserCode;
|
||||
|
||||
private String sysUserName;
|
||||
|
||||
private String sysOrgCode;
|
||||
|
||||
/**
|
||||
* 当前用户部门ID
|
||||
*/
|
||||
private String sysOrgId;
|
||||
|
||||
private List<String> sysMultiOrgCode;
|
||||
|
||||
private boolean oneDepart;
|
||||
|
||||
/**
|
||||
* 当前用户角色code(多个逗号分割)
|
||||
*/
|
||||
private String sysRoleCode;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getSysUserId() {
|
||||
return sysUserId;
|
||||
}
|
||||
|
||||
public void setSysUserId(String sysUserId) {
|
||||
this.sysUserId = sysUserId;
|
||||
}
|
||||
|
||||
public String getSysOrgId() {
|
||||
return sysOrgId;
|
||||
}
|
||||
|
||||
public void setSysOrgId(String sysOrgId) {
|
||||
this.sysOrgId = sysOrgId;
|
||||
}
|
||||
|
||||
public String getSysRoleCode() {
|
||||
return sysRoleCode;
|
||||
}
|
||||
|
||||
public void setSysRoleCode(String sysRoleCode) {
|
||||
this.sysRoleCode = sysRoleCode;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 在线用户信息
|
||||
* </p>
|
||||
*
|
||||
* @Author scott
|
||||
* @since 2023-08-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class UserAccountInfo {
|
||||
|
||||
/**
|
||||
* 登录人id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 登录人账号
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 登录人名字
|
||||
*/
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* 电子邮件
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
@SensitiveField
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
private Integer activitiSync;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@SensitiveField
|
||||
private String phone;
|
||||
}
|
@ -0,0 +1,239 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
|
||||
import org.jeecg.common.exception.JeecgBootAssertException;
|
||||
|
||||
/**
|
||||
* 断言检查工具
|
||||
* for for [QQYUN-10990]AIRAG
|
||||
* @author chenrui
|
||||
* @date 2017-06-22 10:05:56
|
||||
*/
|
||||
public class AssertUtils {
|
||||
|
||||
/**
|
||||
* 确保对象为空,如果不为空抛出异常
|
||||
*
|
||||
* @param msg
|
||||
* @param obj
|
||||
* @throws JeecgBootAssertException
|
||||
* @author chenrui
|
||||
* @date 2017-06-22 10:05:56
|
||||
*/
|
||||
public static void assertEmpty(String msg, Object obj) {
|
||||
if (oConvertUtils.isObjectNotEmpty(obj)) {
|
||||
throw new JeecgBootAssertException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 确保对象不为空,如果为空抛出异常
|
||||
*
|
||||
* @param msg
|
||||
* @param obj
|
||||
* @throws JeecgBootAssertException
|
||||
* @author chenrui
|
||||
* @date 2017-06-22 10:05:56
|
||||
*/
|
||||
public static void assertNotEmpty(String msg, Object obj) {
|
||||
if (oConvertUtils.isObjectEmpty(obj)) {
|
||||
throw new JeecgBootAssertException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证对象是否相同
|
||||
*
|
||||
* @param message
|
||||
* @param expected
|
||||
* @param actual
|
||||
* @author chenrui
|
||||
* @date 2018/9/12 15:45
|
||||
*/
|
||||
public static void assertEquals(String message, Object expected,
|
||||
Object actual) {
|
||||
if (oConvertUtils.isEqual(expected, actual)) {
|
||||
return;
|
||||
}
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证不相同
|
||||
*
|
||||
* @param message
|
||||
* @param expected
|
||||
* @param actual
|
||||
* @author chenrui
|
||||
* @date 2018/9/12 15:45
|
||||
*/
|
||||
public static void assertNotEquals(String message, Object expected,
|
||||
Object actual) {
|
||||
if (oConvertUtils.isEqual(expected, actual)) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否相等
|
||||
*
|
||||
* @param message
|
||||
* @param expected
|
||||
* @param actual
|
||||
* @author chenrui
|
||||
* @date 2018/9/12 15:45
|
||||
*/
|
||||
public static void assertSame(String message, Object expected,
|
||||
Object actual) {
|
||||
if (expected == actual) {
|
||||
return;
|
||||
}
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证不相等
|
||||
*
|
||||
* @param message
|
||||
* @param unexpected
|
||||
* @param actual
|
||||
* @author chenrui
|
||||
* @date 2018/9/12 15:45
|
||||
*/
|
||||
public static void assertNotSame(String message, Object unexpected,
|
||||
Object actual) {
|
||||
if (unexpected == actual) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否为真
|
||||
*
|
||||
* @param message
|
||||
* @param condition
|
||||
*/
|
||||
public static void assertTrue(String message, boolean condition) {
|
||||
if (!condition) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 condition是否为false
|
||||
*
|
||||
* @param message
|
||||
* @param condition
|
||||
*/
|
||||
public static void assertFalse(String message, boolean condition) {
|
||||
assertTrue(message, !condition);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证是否存在
|
||||
*
|
||||
* @param message
|
||||
* @param obj
|
||||
* @param objs
|
||||
* @param <T>
|
||||
* @throws JeecgBootAssertException
|
||||
* @author chenrui
|
||||
* @date 2018/1/31 22:14
|
||||
*/
|
||||
public static <T> void assertIn(String message, T obj, T... objs) {
|
||||
assertNotEmpty(message, obj);
|
||||
assertNotEmpty(message, objs);
|
||||
if (!oConvertUtils.isIn(obj, objs)) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否不存在
|
||||
*
|
||||
* @param message
|
||||
* @param obj
|
||||
* @param objs
|
||||
* @param <T>
|
||||
* @throws JeecgBootAssertException
|
||||
* @author chenrui
|
||||
* @date 2018/1/31 22:14
|
||||
*/
|
||||
|
||||
public static <T> void assertNotIn(String message, T obj, T... objs) {
|
||||
assertNotEmpty(message, obj);
|
||||
assertNotEmpty(message, objs);
|
||||
if (oConvertUtils.isIn(obj, objs)) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 确保src大于des
|
||||
*
|
||||
* @param message
|
||||
* @param src
|
||||
* @param des
|
||||
* @author chenrui
|
||||
* @date 2018/9/19 15:30
|
||||
*/
|
||||
public static void assertGt(String message, Number src, Number des) {
|
||||
if (oConvertUtils.isGt(src, des)) {
|
||||
return;
|
||||
}
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保src大于等于des
|
||||
*
|
||||
* @param message
|
||||
* @param src
|
||||
* @param des
|
||||
* @author chenrui
|
||||
* @date 2018/9/19 15:30
|
||||
*/
|
||||
public static void assertGe(String message, Number src, Number des) {
|
||||
if (oConvertUtils.isGe(src, des)) {
|
||||
return;
|
||||
}
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 确保src小于des
|
||||
*
|
||||
* @param message
|
||||
* @param src
|
||||
* @param des
|
||||
* @author chenrui
|
||||
* @date 2018/9/19 15:30
|
||||
*/
|
||||
public static void assertLt(String message, Number src, Number des) {
|
||||
if (oConvertUtils.isGe(src, des)) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保src小于等于des
|
||||
*
|
||||
* @param message
|
||||
* @param src
|
||||
* @param des
|
||||
* @author chenrui
|
||||
* @date 2018/9/19 15:30
|
||||
*/
|
||||
public static void assertLe(String message, Number src, Number des) {
|
||||
if (oConvertUtils.isGt(src, des)) {
|
||||
throw new JeecgBootAssertException(message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user