diff --git a/.gogs/ISSUE_TEMPLATE.md b/.gogs/ISSUE_TEMPLATE.md
index 3362cf8e6..e4221897f 100644
--- a/.gogs/ISSUE_TEMPLATE.md
+++ b/.gogs/ISSUE_TEMPLATE.md
@@ -1,13 +1,11 @@
-### 环境信息 (*)
+### 环境信息 (必填)
- pigx版本:
- 是否修改包名:
+### 描述(无法理解工单,将直接关闭)
-### 问题描述(*)
-
-
-### 详细回显步骤
+日志、截图、回显步骤
diff --git a/README.md b/README.md
index 47bdea4a0..6d77216a8 100644
--- a/README.md
+++ b/README.md
@@ -3,19 +3,9 @@
pigX并非一个开源软件,作者保留全部的权利。
擅自窃用,即属严重侵权行为,与盗窃无异。产生的一切任何后果责任由侵权者自负。
-### 🌹权益
-
-1. 个人使用
-2. 允许用于学习、毕设等。
-
### 🚫禁止
-1. 将本项目的部分或全部代码和资源进行任何形式的再发行(尤其上传GitHub、Gitee )
-2. 利用本项目的部分或全部代码和资源进行`任何商业行为`
-
-### 免责声明
-
-PigX 未对任何组织、团队,书面授权商业使用。如若出现任何商业后果、纠纷和本人无关,特此声明
+将本项目的部分或全部代码和资源进行任何形式的再发行(上传GitHub、Gitee )
## 贡献代码
diff --git a/db/2pigxx.sql b/db/2pigxx.sql
index cb57a502d..2b5523b0a 100644
--- a/db/2pigxx.sql
+++ b/db/2pigxx.sql
@@ -11,8 +11,8 @@ CREATE TABLE `sys_dept` (
`dept_id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
- `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`del_flag` char(1) DEFAULT '0',
`parent_id` int(11) DEFAULT NULL,
`tenant_id` int(11) DEFAULT NULL,
@@ -71,6 +71,7 @@ INSERT INTO `sys_dept_relation` VALUES (7, 12);
INSERT INTO `sys_dept_relation` VALUES (8, 8);
COMMIT;
+
-- ----------------------------
-- Table structure for sys_dict
-- ----------------------------
@@ -79,15 +80,15 @@ CREATE TABLE `sys_dict` (
`id` int(64) NOT NULL AUTO_INCREMENT COMMENT '编号',
`type` varchar(100) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remarks` varchar(255) DEFAULT NULL,
`system` char(1) DEFAULT '0',
`del_flag` char(1) DEFAULT '0',
`tenant_id` int(11) NOT NULL DEFAULT '0' COMMENT '所属租户',
PRIMARY KEY (`id`) USING BTREE,
KEY `sys_dict_del_flag` (`del_flag`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COMMENT='字典表';
+) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COMMENT='字典表';
-- ----------------------------
-- Records of sys_dict
@@ -104,25 +105,13 @@ INSERT INTO `sys_dict` VALUES (8, 'gender', '性别', '2019-03-27 13:44:06', '20
INSERT INTO `sys_dict` VALUES (9, 'subscribe', '订阅状态', '2019-03-27 13:48:33', '2019-03-27 13:48:33', '公众号订阅状态', '1', '0', 1);
INSERT INTO `sys_dict` VALUES (10, 'response_type', '回复', '2019-03-28 21:29:21', '2019-03-28 21:29:21', '微信消息是否已回复', '1', '0', 1);
INSERT INTO `sys_dict` VALUES (11, 'param_type', '参数配置', '2019-04-29 18:20:47', '2019-04-29 18:20:47', '检索、原文、报表、安全、文档、消息、其他', '1', '0', 1);
-INSERT INTO `sys_dict` VALUES (12, 'tenant_status_type', '租户状态', '2019-05-15 16:31:08', '2019-05-15 16:31:08', '租户状态', '1', '0', 1);
+INSERT INTO `sys_dict` VALUES (12, 'status_type', '租户状态', '2019-05-15 16:31:08', '2019-05-15 16:31:08', '租户状态', '1', '0', 1);
INSERT INTO `sys_dict` VALUES (13, 'dict_type', '字典类型', '2019-05-16 14:16:20', '2019-05-16 14:20:16', '系统类不能修改', '1', '0', 1);
-INSERT INTO `sys_dict` VALUES (14, 'channel_status', '支付渠道状态', '2019-05-30 16:14:43', '2019-05-30 16:14:43', '支付渠道状态(0-正常,1-冻结)', '0', '0', 1);
-INSERT INTO `sys_dict` VALUES (15, 'channel_id', '渠道编码ID', '2019-05-30 18:59:12', '2019-05-30 18:59:12', '不同的支付方式', '0', '0', 1);
-INSERT INTO `sys_dict` VALUES (16, 'order_status', '订单状态', '2019-06-27 08:17:40', '2019-06-27 08:17:40', '支付订单状态', '0', '0', 1);
-INSERT INTO `sys_dict` VALUES (17, 'grant_types', '授权类型', '2019-08-13 07:34:10', '2019-08-13 07:34:10', NULL, '0', '0', 1);
-INSERT INTO `sys_dict` VALUES (18, 'log_type', '日志类型', '2019-03-19 11:06:44', '2019-03-19 11:06:44', '异常、正常', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (19, 'social_type', '社交登录', '2019-03-19 11:09:44', '2019-03-19 11:09:44', '微信、QQ', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (20, 'leave_status', '请假状态', '2019-03-19 11:09:44', '2019-03-19 11:09:44', '未提交、审批中、完成、驳回', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (21, 'job_type', '定时任务类型', '2019-03-19 11:22:21', '2019-03-19 11:22:21', 'quartz', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (22, 'job_status', '定时任务状态', '2019-03-19 11:24:57', '2019-03-19 11:24:57', '发布状态、运行状态', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (23, 'job_execute_status', '定时任务执行状态', '2019-03-19 11:26:15', '2019-03-19 11:26:15', '正常、异常', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (24, 'misfire_policy', '定时任务错失执行策略', '2019-03-19 11:27:19', '2019-03-19 11:27:19', '周期', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (25, 'gender', '性别', '2019-03-27 13:44:06', '2019-03-27 13:44:06', '微信用户性别', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (26, 'subscribe', '订阅状态', '2019-03-27 13:48:33', '2019-03-27 13:48:33', '公众号订阅状态', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (27, 'response_type', '回复', '2019-03-28 21:29:21', '2019-03-28 21:29:21', '微信消息是否已回复', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (28, 'param_type', '参数配置', '2019-04-29 18:20:47', '2019-04-29 18:20:47', '检索、原文、报表、安全、文档、消息、其他', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (29, 'tenant_status_type', '租户状态', '2019-05-15 16:31:08', '2019-05-15 16:31:08', '租户状态', '1', '0', 2);
-INSERT INTO `sys_dict` VALUES (30, 'dict_type', '字典类型', '2019-05-16 14:16:20', '2019-05-16 14:20:16', '系统类不能修改', '1', '0', 2);
+INSERT INTO `sys_dict` VALUES (14, 'channel_status', '支付渠道状态', '2019-05-30 16:14:43', '2019-05-30 16:14:43', '支付渠道状态(0-正常,1-冻结)', '1', '0', 1);
+INSERT INTO `sys_dict` VALUES (15, 'channel_id', '渠道编码ID', '2019-05-30 18:59:12', '2019-05-30 18:59:12', '不同的支付方式', '1', '0', 1);
+INSERT INTO `sys_dict` VALUES (16, 'order_status', '订单状态', '2019-06-27 08:17:40', '2019-06-27 08:17:40', '支付订单状态', '1', '0', 1);
+INSERT INTO `sys_dict` VALUES (17, 'grant_types', '授权类型', '2019-08-13 07:34:10', '2019-08-13 07:34:10', NULL, '1', '0', 1);
+INSERT INTO `sys_dict` VALUES (18, 'style_type', '前端风格', '2020-02-07 03:49:28', '2020-02-07 03:50:40', '0-Avue 1-element', '1', '0', 1);
COMMIT;
-- ----------------------------
@@ -137,8 +126,8 @@ CREATE TABLE `sys_dict_item` (
`type` varchar(100) DEFAULT NULL,
`description` varchar(100) DEFAULT NULL,
`sort` int(10) NOT NULL DEFAULT '0' COMMENT '排序(升序)',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remarks` varchar(255) DEFAULT NULL,
`del_flag` char(1) DEFAULT '0',
`tenant_id` int(11) NOT NULL DEFAULT '0' COMMENT '所属租户',
@@ -146,7 +135,7 @@ CREATE TABLE `sys_dict_item` (
KEY `sys_dict_value` (`value`) USING BTREE,
KEY `sys_dict_label` (`label`) USING BTREE,
KEY `sys_dict_del_flag` (`del_flag`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COMMENT='字典项';
+) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8mb4 COMMENT='字典项';
-- ----------------------------
-- Records of sys_dict_item
@@ -207,46 +196,8 @@ INSERT INTO `sys_dict_item` VALUES (52, 17, 'authorization_code', '授权码模
INSERT INTO `sys_dict_item` VALUES (53, 17, 'client_credentials', '客户端模式', 'grant_types', 'oauth2 客户端模式', 2, '2019-08-13 07:36:30', '2019-08-13 07:36:30', NULL, '0', 1);
INSERT INTO `sys_dict_item` VALUES (54, 17, 'refresh_token', '刷新模式', 'grant_types', 'oauth2 刷新token', 3, '2019-08-13 07:36:54', '2019-08-13 07:36:54', NULL, '0', 1);
INSERT INTO `sys_dict_item` VALUES (55, 17, 'implicit', '简化模式', 'grant_types', 'oauth2 简化模式', 4, '2019-08-13 07:39:32', '2019-08-13 07:39:32', NULL, '0', 1);
-INSERT INTO `sys_dict_item` VALUES (56, 18, '9', '异常', 'log_type', '日志异常', 1, '2019-03-19 11:08:59', '2019-03-25 12:49:13', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (57, 18, '0', '正常', 'log_type', '日志正常', 0, '2019-03-19 11:09:17', '2019-03-25 12:49:18', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (58, 19, 'WX', '微信', 'social_type', '微信登录', 0, '2019-03-19 11:10:02', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (59, 19, 'QQ', 'QQ', 'social_type', 'QQ登录', 1, '2019-03-19 11:10:14', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (60, 19, 'GITEE', '码云', 'social_type', '码云', 2, '2019-06-28 09:59:12', '2019-06-28 09:59:12', '码云', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (61, 19, 'OSC', '开源中国', 'social_type', '开源中国登录', 0, '2019-06-28 10:04:32', '2019-06-28 10:04:32', 'http://gitee.huaxiadaowei.com/#/authredirect', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (62, 20, '0', '未提交', 'leave_status', '未提交', 0, '2019-03-19 11:18:34', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (63, 20, '1', '审批中', 'leave_status', '审批中', 1, '2019-03-19 11:18:45', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (64, 20, '2', '完成', 'leave_status', '完成', 2, '2019-03-19 11:19:02', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (65, 20, '9', '驳回', 'leave_status', '驳回', 9, '2019-03-19 11:19:20', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (66, 21, '1', 'java类', 'job_type', 'java类', 1, '2019-03-19 11:22:37', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (67, 21, '2', 'spring bean', 'job_type', 'spring bean容器实例', 2, '2019-03-19 11:23:05', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (68, 21, '9', '其他', 'job_type', '其他类型', 9, '2019-03-19 11:23:31', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (69, 21, '3', 'Rest 调用', 'job_type', 'Rest 调用', 3, '2019-03-19 11:23:57', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (70, 21, '4', 'jar', 'job_type', 'jar类型', 4, '2019-03-19 11:24:20', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (71, 22, '1', '未发布', 'job_status', '未发布', 1, '2019-03-19 11:25:18', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (72, 22, '2', '运行中', 'job_status', '运行中', 2, '2019-03-19 11:25:31', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (73, 22, '3', '暂停', 'job_status', '暂停', 3, '2019-03-19 11:25:42', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (74, 23, '0', '正常', 'job_execute_status', '正常', 0, '2019-03-19 11:26:27', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (75, 23, '1', '异常', 'job_execute_status', '异常', 1, '2019-03-19 11:26:41', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (76, 24, '1', '错失周期立即执行', 'misfire_policy', '错失周期立即执行', 1, '2019-03-19 11:27:45', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (77, 24, '2', '错失周期执行一次', 'misfire_policy', '错失周期执行一次', 2, '2019-03-19 11:27:57', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (78, 24, '3', '下周期执行', 'misfire_policy', '下周期执行', 3, '2019-03-19 11:28:08', '2019-03-25 12:49:36', NULL, '0', 2);
-INSERT INTO `sys_dict_item` VALUES (79, 25, '1', '男', 'gender', '微信-男', 0, '2019-03-27 13:45:13', '2019-03-27 13:45:13', '微信-男', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (80, 25, '2', '女', 'gender', '女-微信', 1, '2019-03-27 13:45:34', '2019-03-27 13:45:34', '女-微信', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (81, 25, '0', '未知', 'gender', 'x性别未知', 3, '2019-03-27 13:45:57', '2019-03-27 13:45:57', 'x性别未知', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (82, 26, '0', '未关注', 'subscribe', '公众号-未关注', 0, '2019-03-27 13:49:07', '2019-03-27 13:49:07', '公众号-未关注', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (83, 26, '1', '已关注', 'subscribe', '公众号-已关注', 1, '2019-03-27 13:49:26', '2019-03-27 13:49:26', '公众号-已关注', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (84, 27, '0', '未回复', 'response_type', '微信消息-未回复', 0, '2019-03-28 21:29:47', '2019-03-28 21:29:47', '微信消息-未回复', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (85, 27, '1', '已回复', 'response_type', '微信消息-已回复', 1, '2019-03-28 21:30:08', '2019-03-28 21:30:08', '微信消息-已回复', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (86, 28, '1', '检索', 'param_type', '检索', 0, '2019-04-29 18:22:17', '2019-04-29 18:22:17', '检索', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (87, 28, '2', '原文', 'param_type', '原文', 0, '2019-04-29 18:22:27', '2019-04-29 18:22:27', '原文', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (88, 28, '3', '报表', 'param_type', '报表', 0, '2019-04-29 18:22:36', '2019-04-29 18:22:36', '报表', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (89, 28, '4', '安全', 'param_type', '安全', 0, '2019-04-29 18:22:46', '2019-04-29 18:22:46', '安全', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (90, 28, '5', '文档', 'param_type', '文档', 0, '2019-04-29 18:22:56', '2019-04-29 18:22:56', '文档', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (91, 28, '6', '消息', 'param_type', '消息', 0, '2019-04-29 18:23:05', '2019-04-29 18:23:05', '消息', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (92, 28, '9', '其他', 'param_type', '其他', 0, '2019-04-29 18:23:16', '2019-04-29 18:23:16', '其他', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (93, 28, '0', '默认', 'param_type', '默认', 0, '2019-04-29 18:23:30', '2019-04-29 18:23:30', '默认', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (94, 30, '1', '系统类', 'dict_type', '系统类字典', 0, '2019-05-16 14:20:40', '2019-05-16 14:20:40', '不能修改删除', '0', 2);
-INSERT INTO `sys_dict_item` VALUES (95, 30, '0', '业务类', 'dict_type', '业务类字典', 0, '2019-05-16 14:20:59', '2019-05-16 14:20:59', '可以修改', '0', 2);
+INSERT INTO `sys_dict_item` VALUES (56, 18, '0', 'Avue', 'style_type', 'Avue风格', 0, '2020-02-07 03:52:52', '2020-02-07 03:52:52', '', '0', 1);
+INSERT INTO `sys_dict_item` VALUES (57, 18, '1', 'element', 'style_type', 'element-ui', 1, '2020-02-07 03:53:12', '2020-02-07 03:53:12', '', '0', 1);
COMMIT;
-- ----------------------------
@@ -311,9 +262,10 @@ CREATE TABLE `sys_menu` (
`sort` int(11) DEFAULT '1' COMMENT '排序值',
`keep_alive` char(1) DEFAULT '0',
`type` char(1) DEFAULT '0',
- `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0',
+ `tenant_id` int(11) unsigned DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10013 DEFAULT CHARSET=utf8mb4 COMMENT='菜单权限表';
@@ -321,129 +273,125 @@ CREATE TABLE `sys_menu` (
-- Records of sys_menu
-- ----------------------------
BEGIN;
-INSERT INTO `sys_menu` VALUES (1000, '权限管理', NULL, '/user', -1, 'icon-quanxianguanli', 0, '0', '0', '2018-09-28 08:29:53', '2018-09-28 08:53:01', '0');
-INSERT INTO `sys_menu` VALUES (1100, '用户管理', NULL, '/admin/user/index', 1000, 'icon-yonghuguanli', 1, '1', '0', '2017-11-02 22:24:37', '2019-06-24 14:36:36', '0');
-INSERT INTO `sys_menu` VALUES (1101, '用户新增', 'sys_user_add', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:52:09', '2018-09-28 09:06:34', '0');
-INSERT INTO `sys_menu` VALUES (1102, '用户修改', 'sys_user_edit', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:52:48', '2018-09-28 09:06:37', '0');
-INSERT INTO `sys_menu` VALUES (1103, '用户删除', 'sys_user_del', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:54:01', '2018-09-28 09:06:42', '0');
-INSERT INTO `sys_menu` VALUES (1200, '菜单管理', NULL, '/admin/menu/index', 1000, 'icon-caidanguanli', 2, '0', '0', '2017-11-08 09:57:27', '2019-06-24 14:42:07', '0');
-INSERT INTO `sys_menu` VALUES (1201, '菜单新增', 'sys_menu_add', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:15:53', '2018-09-28 09:07:16', '0');
-INSERT INTO `sys_menu` VALUES (1202, '菜单修改', 'sys_menu_edit', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:16:23', '2018-09-28 09:07:18', '0');
-INSERT INTO `sys_menu` VALUES (1203, '菜单删除', 'sys_menu_del', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:16:43', '2018-09-28 09:07:22', '0');
-INSERT INTO `sys_menu` VALUES (1300, '角色管理', NULL, '/admin/role/index', 1000, 'icon-jiaoseguanli', 3, '0', '0', '2017-11-08 10:13:37', '2018-09-28 09:00:48', '0');
-INSERT INTO `sys_menu` VALUES (1301, '角色新增', 'sys_role_add', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:18', '2018-09-28 09:07:46', '0');
-INSERT INTO `sys_menu` VALUES (1302, '角色修改', 'sys_role_edit', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:41', '2018-09-28 09:07:49', '0');
-INSERT INTO `sys_menu` VALUES (1303, '角色删除', 'sys_role_del', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:59', '2018-09-28 09:07:53', '0');
-INSERT INTO `sys_menu` VALUES (1304, '分配权限', 'sys_role_perm', NULL, 1300, NULL, NULL, '0', '1', '2018-04-20 07:22:55', '2018-09-28 09:13:23', '0');
-INSERT INTO `sys_menu` VALUES (1400, '部门管理', NULL, '/admin/dept/index', 1000, 'icon-web-icon-', 4, '0', '0', '2018-01-20 13:17:19', '2018-12-09 16:35:12', '0');
-INSERT INTO `sys_menu` VALUES (1401, '部门新增', 'sys_dept_add', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:56:16', '2018-09-28 09:08:13', '0');
-INSERT INTO `sys_menu` VALUES (1402, '部门修改', 'sys_dept_edit', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:56:59', '2018-09-28 09:08:16', '0');
-INSERT INTO `sys_menu` VALUES (1403, '部门删除', 'sys_dept_del', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:57:28', '2018-09-28 09:08:18', '0');
-INSERT INTO `sys_menu` VALUES (1500, '租户管理', '', '/admin/tenant/index', 1000, 'icon-erji-zuhushouye', 5, '0', '0', '2018-01-20 13:17:19', '2019-05-17 15:36:11', '0');
-INSERT INTO `sys_menu` VALUES (1501, '租户新增', 'admin_systenant_add', NULL, 1500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-05-17 15:36:34', '0');
-INSERT INTO `sys_menu` VALUES (1502, '租户修改', 'admin_systenant_edit', NULL, 1500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2019-05-17 15:36:53', '0');
-INSERT INTO `sys_menu` VALUES (1503, '租户删除', 'admin_systenant_del', NULL, 1500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2019-05-17 15:37:00', '0');
-INSERT INTO `sys_menu` VALUES (2000, '系统管理', NULL, '/admin', -1, 'icon-xitongguanli', 1, '0', '0', '2017-11-07 20:56:00', '2018-09-28 08:53:18', '0');
-INSERT INTO `sys_menu` VALUES (2100, '日志管理', NULL, '/admin/log/index', 2000, 'icon-rizhiguanli', 5, '0', '0', '2017-11-20 14:06:22', '2018-09-28 09:01:52', '0');
-INSERT INTO `sys_menu` VALUES (2101, '日志删除', 'sys_log_del', NULL, 2100, NULL, NULL, '0', '1', '2017-11-20 20:37:37', '2018-09-28 09:08:44', '0');
-INSERT INTO `sys_menu` VALUES (2200, '字典管理', NULL, '/admin/dict/index', 2000, 'icon-navicon-zdgl', 6, '0', '0', '2017-11-29 11:30:52', '2018-09-28 09:01:47', '0');
-INSERT INTO `sys_menu` VALUES (2201, '字典删除', 'sys_dict_del', NULL, 2200, NULL, NULL, '0', '1', '2017-11-29 11:30:11', '2018-09-28 09:09:10', '0');
-INSERT INTO `sys_menu` VALUES (2202, '字典新增', 'sys_dict_add', NULL, 2200, NULL, NULL, '0', '1', '2018-05-11 22:34:55', '2018-09-28 09:09:12', '0');
-INSERT INTO `sys_menu` VALUES (2203, '字典修改', 'sys_dict_edit', NULL, 2200, NULL, NULL, '0', '1', '2018-05-11 22:36:03', '2018-09-28 09:09:16', '0');
-INSERT INTO `sys_menu` VALUES (2210, '参数管理', NULL, '/admin/param/index', 2000, 'icon-canshu', 7, '1', '0', '2019-04-29 22:16:50', '2019-06-24 14:52:00', '0');
-INSERT INTO `sys_menu` VALUES (2211, '参数新增', 'admin_syspublicparam_add', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:17:36', NULL, '0');
-INSERT INTO `sys_menu` VALUES (2212, '参数删除', 'admin_syspublicparam_del', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:17:55', NULL, '0');
-INSERT INTO `sys_menu` VALUES (2213, '参数编辑', 'admin_syspublicparam_edit', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:18:14', '2019-04-29 22:19:25', '0');
-INSERT INTO `sys_menu` VALUES (2300, '代码生成', '', '/gen/index', 10006, 'icon-weibiaoti46', 1, '0', '0', '2018-01-20 13:17:19', '2019-08-12 10:28:44', '0');
-INSERT INTO `sys_menu` VALUES (2400, '终端管理', '', '/admin/client/index', 2000, 'icon-shouji', 9, '0', '0', '2018-01-20 13:17:19', '2018-09-28 09:01:43', '0');
-INSERT INTO `sys_menu` VALUES (2401, '客户端新增', 'sys_client_add', NULL, 2400, '1', NULL, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:10:25', '0');
-INSERT INTO `sys_menu` VALUES (2402, '客户端修改', 'sys_client_edit', NULL, 2400, NULL, NULL, '0', '1', '2018-05-15 21:37:06', '2018-09-28 09:10:27', '0');
-INSERT INTO `sys_menu` VALUES (2403, '客户端删除', 'sys_client_del', NULL, 2400, NULL, NULL, '0', '1', '2018-05-15 21:39:16', '2018-09-28 09:10:30', '0');
-INSERT INTO `sys_menu` VALUES (2500, '密钥管理', '', '/admin/social/index', 2000, 'icon-miyue', 10, '0', '0', '2018-01-20 13:17:19', '2018-09-28 09:01:41', '0');
-INSERT INTO `sys_menu` VALUES (2501, '密钥新增', 'sys_social_details_add', NULL, 2500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:52:18', '0');
-INSERT INTO `sys_menu` VALUES (2502, '密钥修改', 'sys_social_details_edit', NULL, 2500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:51:36', '0');
-INSERT INTO `sys_menu` VALUES (2503, '密钥删除', 'sys_social_details_del', NULL, 2500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:51:30', '0');
-INSERT INTO `sys_menu` VALUES (2600, '令牌管理', NULL, '/admin/token/index', 2000, 'icon-denglvlingpai', 11, '0', '0', '2018-09-04 05:58:41', '2018-09-28 09:01:38', '0');
-INSERT INTO `sys_menu` VALUES (2601, '令牌删除', 'sys_token_del', NULL, 2600, NULL, 1, '0', '1', '2018-09-04 05:59:50', '2018-09-28 09:11:24', '0');
-INSERT INTO `sys_menu` VALUES (2700, '动态路由', NULL, '/admin/route/index', 2000, 'icon-luyou', 12, '0', '0', '2018-09-04 05:58:41', '2019-06-24 15:14:28', '0');
-INSERT INTO `sys_menu` VALUES (2800, 'Quartz管理', '', '/daemon/job-manage/index', 2000, 'icon-guanwangfangwen', 8, '0', '0', '2018-01-20 13:17:19', '2019-03-25 13:52:14', '0');
-INSERT INTO `sys_menu` VALUES (2810, '任务新增', 'job_sys_job_add', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:23', '0');
-INSERT INTO `sys_menu` VALUES (2820, '任务修改', 'job_sys_job_edit', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:26', '0');
-INSERT INTO `sys_menu` VALUES (2830, '任务删除', 'job_sys_job_del', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:30', '0');
-INSERT INTO `sys_menu` VALUES (2840, '任务暂停', 'job_sys_job_shutdown_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:18', '0');
-INSERT INTO `sys_menu` VALUES (2850, '任务开始', 'job_sys_job_start_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:35', '0');
-INSERT INTO `sys_menu` VALUES (2860, '任务刷新', 'job_sys_job_refresh_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-03-25 11:50:39', '0');
-INSERT INTO `sys_menu` VALUES (2870, '执行任务', 'job_sys_job_run_job', NULL, 2800, '1', 0, '0', '1', '2019-08-08 15:35:18', '2019-08-08 15:50:35', '0');
-INSERT INTO `sys_menu` VALUES (3000, '系统监控', NULL, '/daemon', -1, 'icon-msnui-supervise', 2, '0', '0', '2018-07-27 01:13:21', '2018-09-28 08:53:24', '0');
-INSERT INTO `sys_menu` VALUES (3100, '服务监控', NULL, 'http://127.0.0.1:5001', 3000, 'icon-server', 0, '0', '0', '2018-06-26 10:50:32', '2019-05-01 23:54:05', '0');
-INSERT INTO `sys_menu` VALUES (3110, '缓存监控', NULL, '/monitor/redis/index', 3000, 'icon-qingchuhuancun', 1, '1', '0', '2019-05-08 23:51:27', '2019-06-24 15:17:45', '0');
-INSERT INTO `sys_menu` VALUES (3200, '接口文档', NULL, 'http://127.0.0.1:9999/swagger-ui.html', 3000, 'icon-wendang', 1, '0', '0', '2018-06-26 10:50:32', '2019-05-01 23:57:11', '0');
-INSERT INTO `sys_menu` VALUES (3300, '事务监控', NULL, '/tx/index', 3000, 'icon-gtsquanjushiwufuwuGTS', 5, '0', '0', '2018-08-19 11:02:39', '2019-06-24 15:18:04', '0');
-INSERT INTO `sys_menu` VALUES (3400, '在线事务', NULL, '/tx/model', 3000, 'icon-online', 6, '0', '0', '2018-08-19 11:32:04', '2019-06-24 15:18:13', '0');
-INSERT INTO `sys_menu` VALUES (3500, '文档扩展', NULL, 'http://127.0.0.1:9999/doc.html', 3000, 'icon-wendang', 2, '0', '0', '2018-06-26 10:50:32', '2019-05-01 23:57:42', '0');
-INSERT INTO `sys_menu` VALUES (3600, '任务轨迹', '', '/daemon/status-trace-log/index', 3000, 'icon-guiji', 8, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:18:41', '0');
-INSERT INTO `sys_menu` VALUES (3601, '删除轨迹', 'daemon_status_trace_log_del', NULL, 3600, '1', 2, '0', '1', '2018-05-15 21:35:18', '2019-03-30 09:31:06', '0');
-INSERT INTO `sys_menu` VALUES (3620, 'Quartz日志', '', '/daemon/job-log/index', 3000, 'icon-gtsquanjushiwufuwuGTS', 8, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:18:54', '0');
-INSERT INTO `sys_menu` VALUES (3630, '任务日志', '', '/daemon/execution-log/index', 3000, 'icon-wendang', 7, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:19:07', '0');
-INSERT INTO `sys_menu` VALUES (3631, '删除日志', 'daemon_execution_log_del', NULL, 3900, '1', 2, '0', '1', '2018-05-15 21:35:18', '2019-03-30 09:30:45', '0');
-INSERT INTO `sys_menu` VALUES (3700, '注册配置', NULL, '', 3000, 'icon-line', 10, '0', '0', '2018-01-25 11:08:52', '2019-06-24 15:35:10', '1');
-INSERT INTO `sys_menu` VALUES (4000, '协同管理', NULL, '/activti', -1, 'icon-kuaisugongzuoliu_o', 3, '0', '0', '2018-09-26 01:38:13', '2018-09-28 08:58:24', '0');
-INSERT INTO `sys_menu` VALUES (4100, '模型管理', NULL, '/activiti/index', 4000, 'icon-weibiaoti13', 1, '0', '0', '2018-09-26 01:39:07', '2019-06-24 15:20:00', '0');
-INSERT INTO `sys_menu` VALUES (4101, '模型管理', 'act_model_manage', NULL, 4100, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:07', '0');
-INSERT INTO `sys_menu` VALUES (4200, '流程管理', '/activiti/process', '/activiti/process', 4000, 'icon-liucheng', 2, '0', '0', '2018-09-26 06:41:05', '2019-06-24 08:31:07', '0');
-INSERT INTO `sys_menu` VALUES (4201, '流程管理', 'act_process_manage', NULL, 4200, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:07', '0');
-INSERT INTO `sys_menu` VALUES (4300, '请假管理', '/activiti/leave', '/activiti/leave', 4000, 'icon-qingjia', 3, '0', '0', '2018-01-20 13:17:19', '2019-06-24 08:31:11', '0');
-INSERT INTO `sys_menu` VALUES (4301, '请假新增', 'act_leavebill_add', NULL, 4300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:07', '0');
-INSERT INTO `sys_menu` VALUES (4302, '请假修改', 'act_leavebill_edit', NULL, 4300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:09', '0');
-INSERT INTO `sys_menu` VALUES (4303, '请假删除', 'act_leavebill_del', NULL, 4300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:14', '0');
-INSERT INTO `sys_menu` VALUES (4400, '待办任务', '/activiti/task', '/activiti/task', 4000, 'icon-renwu', 4, '0', '0', '2018-09-27 09:52:31', '2019-06-24 08:31:18', '0');
-INSERT INTO `sys_menu` VALUES (4401, '流程管理', 'act_task_manage', NULL, 4400, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-09-28 09:12:07', '0');
-INSERT INTO `sys_menu` VALUES (5000, '支付管理', NULL, '/pay', -1, 'icon-pay6zhifu', 4, '1', '0', '2019-05-30 15:28:03', '2019-06-20 16:13:23', '0');
-INSERT INTO `sys_menu` VALUES (5100, '渠道管理', NULL, '/pay/paychannel/index', 5000, 'icon-zhifuqudaoguanli', 1, '1', '0', '2019-05-30 15:32:17', '2019-05-30 19:43:27', '0');
-INSERT INTO `sys_menu` VALUES (5110, '增加渠道', 'pay_paychannel_add', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:46:14', NULL, '0');
-INSERT INTO `sys_menu` VALUES (5120, '编辑渠道', 'pay_paychannel_edit', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:46:35', NULL, '0');
-INSERT INTO `sys_menu` VALUES (5130, '删除渠道', 'pay_paychannel_del', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:47:08', NULL, '0');
-INSERT INTO `sys_menu` VALUES (5200, '收银台', NULL, '/pay/cd/index', 5000, 'icon-shouyintai', 0, '1', '0', '2019-05-30 19:44:00', '2019-05-30 19:45:05', '0');
-INSERT INTO `sys_menu` VALUES (5300, '商品订单', '', '/pay/goods/index', 5000, 'icon-dingdan', 2, '0', '0', '2018-01-20 13:17:19', '2019-06-16 18:02:21', '0');
-INSERT INTO `sys_menu` VALUES (5310, '商品订单新增', 'generator_paygoodsorder_add', NULL, 5300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5320, '商品订单修改', 'generator_paygoodsorder_edit', NULL, 5300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5330, '商品订单删除', 'generator_paygoodsorder_del', NULL, 5300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5400, '支付订单', '', '/pay/orders/index', 5000, 'icon-zhifu', 3, '0', '0', '2018-01-20 13:17:19', '2019-06-16 18:02:06', '0');
-INSERT INTO `sys_menu` VALUES (5410, '支付订单新增', 'generator_paytradeorder_add', NULL, 5400, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5420, '支付订单修改', 'generator_paytradeorder_edit', NULL, 5400, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5430, '支付订单删除', 'generator_paytradeorder_del', NULL, 5400, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5500, '回调记录', '', '/pay/notify/index', 5000, 'icon-huitiao', 4, '0', '0', '2018-01-20 13:17:19', '2019-06-16 18:01:49', '0');
-INSERT INTO `sys_menu` VALUES (5510, '记录新增', 'generator_paynotifyrecord_add', NULL, 5500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5520, '记录修改', 'generator_paynotifyrecord_edit', NULL, 5500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (5530, '记录删除', 'generator_paynotifyrecord_del', NULL, 5500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6000, '微信管理', NULL, '/mp', -1, 'icon-gongzhonghao', 4, '0', '0', '2018-09-26 01:38:13', '2018-09-28 08:58:24', '0');
-INSERT INTO `sys_menu` VALUES (6100, '账号管理', '', '/mp/wxaccount/index', 6000, 'icon-weixincaidan', 8, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:24:36', '0');
-INSERT INTO `sys_menu` VALUES (6101, '公众号新增', 'mp_wxaccount_add', '', 6100, '1', 0, '0', '1', '2018-05-15 21:35:18', '2019-06-24 15:24:33', '0');
-INSERT INTO `sys_menu` VALUES (6102, '公众号修改', 'mp_wxaccount_edit', NULL, 6100, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6103, '公众号删除', 'mp_wxaccount_del', NULL, 6100, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6200, '粉丝管理', '', '/mp/wxaccountfans/index', 6000, 'icon-fensiguanli', 8, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:24:46', '0');
-INSERT INTO `sys_menu` VALUES (6201, '粉丝新增', 'mp_wxaccountfans_add', NULL, 6200, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6202, '粉丝修改', 'mp_wxaccountfans_edit', NULL, 6200, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6203, '粉丝删除', 'mp_wxaccountfans_del', NULL, 6200, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6300, '消息管理', '', '/mp/wxfansmsg/index', 6000, 'icon-xiaoxiguanli', 8, '0', '0', '2018-01-20 13:17:19', '2019-06-24 15:24:57', '0');
-INSERT INTO `sys_menu` VALUES (6301, '消息新增', 'mp_wxfansmsg_add', NULL, 6300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6302, '消息修改', 'mp_wxfansmsg_edit', NULL, 6300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6303, '消息删除', 'mp_wxfansmsg_del', NULL, 6300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6304, '消息回复', 'mp_wxfansmsgres_add', NULL, 6300, '1', 3, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (6305, '回复删除', 'mp_wxfansmsgres_del', NULL, 6300, NULL, 1, '0', '1', '2019-03-28 22:53:49', NULL, '0');
-INSERT INTO `sys_menu` VALUES (6400, '菜单设置', NULL, '/mp/wxmenu/index', 6000, 'icon-anniu_weixincaidanlianjie', 6, '1', '0', '2019-03-29 15:20:12', '2019-06-24 15:25:07', '0');
-INSERT INTO `sys_menu` VALUES (6401, '保存', 'mp_wxmenu_add', NULL, 6400, NULL, 1, '0', '1', '2019-03-29 15:43:22', '2019-03-29 15:43:30', '0');
-INSERT INTO `sys_menu` VALUES (6402, '发布', 'mp_wxmenu_push', NULL, 6400, NULL, 1, '0', '1', '2019-03-29 15:43:54', NULL, '0');
-INSERT INTO `sys_menu` VALUES (6500, '运营数据', NULL, '/mp/wxstatistics/index', 6000, 'icon-zhexiantu', 7, '1', '0', '2019-04-14 00:15:35', '2019-06-24 15:25:15', '0');
-INSERT INTO `sys_menu` VALUES (10000, '文件管理', NULL, '/admin/file/index', 2000, 'icon-wenjianguanli', 6, '1', '0', '2019-06-25 12:44:46', NULL, '0');
-INSERT INTO `sys_menu` VALUES (10001, '删除文件', 'sys_file_del', NULL, 10000, NULL, 1, '0', '1', '2019-06-25 13:41:41', NULL, '0');
-INSERT INTO `sys_menu` VALUES (10002, '表单管理', '', '/gen/form', 10006, 'icon-record', 3, '0', '0', '2018-01-20 13:17:19', '2019-08-12 09:36:09', '0');
-INSERT INTO `sys_menu` VALUES (10003, '表单新增', 'gen_form_add', NULL, 10002, '1', 0, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (10004, '表单修改', 'gen_form_edit', NULL, 10002, '1', 1, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (10005, '表单删除', 'gen_form_del', NULL, 10002, '1', 2, '0', '1', '2018-05-15 21:35:18', '2018-07-29 13:38:59', '0');
-INSERT INTO `sys_menu` VALUES (10006, '开发平台', NULL, '/gen', -1, 'icon-shejiyukaifa-', 9, '1', '0', '2019-08-12 09:35:16', '2019-08-12 10:28:35', '0');
-INSERT INTO `sys_menu` VALUES (10007, '数据源管理', NULL, '/gen/datasource', 10006, 'icon-mysql', 0, '1', '0', '2019-08-12 09:42:11', '2019-08-12 10:33:30', '0');
-INSERT INTO `sys_menu` VALUES (10008, '表单设计', NULL, '/gen/design', 10006, 'icon-biaodanbiaoqian', 2, '1', '0', '2019-08-16 10:08:56', NULL, '0');
+INSERT INTO `sys_menu` VALUES (1000, '权限管理', NULL, '/user', -1, 'icon-quanxianguanli', 0, '0', '0', '2018-09-28 08:29:53', '2020-03-24 08:56:32', '0', 1);
+INSERT INTO `sys_menu` VALUES (1100, '用户管理', NULL, '/admin/user/index', 1000, 'icon-yonghuguanli', 1, '1', '0', '2017-11-02 22:24:37', '2020-03-24 08:56:33', '0', 1);
+INSERT INTO `sys_menu` VALUES (1101, '用户新增', 'sys_user_add', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:52:09', '2020-03-24 08:56:34', '0', 1);
+INSERT INTO `sys_menu` VALUES (1102, '用户修改', 'sys_user_edit', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:52:48', '2020-03-24 08:56:35', '0', 1);
+INSERT INTO `sys_menu` VALUES (1103, '用户删除', 'sys_user_del', NULL, 1100, NULL, NULL, '0', '1', '2017-11-08 09:54:01', '2020-03-24 08:56:37', '0', 1);
+INSERT INTO `sys_menu` VALUES (1200, '菜单管理', NULL, '/admin/menu/index', 1000, 'icon-caidanguanli', 2, '0', '0', '2017-11-08 09:57:27', '2020-03-24 08:56:38', '0', 1);
+INSERT INTO `sys_menu` VALUES (1201, '菜单新增', 'sys_menu_add', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:15:53', '2020-03-24 08:56:39', '0', 1);
+INSERT INTO `sys_menu` VALUES (1202, '菜单修改', 'sys_menu_edit', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:16:23', '2020-03-24 08:56:40', '0', 1);
+INSERT INTO `sys_menu` VALUES (1203, '菜单删除', 'sys_menu_del', NULL, 1200, NULL, NULL, '0', '1', '2017-11-08 10:16:43', '2020-03-24 08:56:41', '0', 1);
+INSERT INTO `sys_menu` VALUES (1300, '角色管理', NULL, '/admin/role/index', 1000, 'icon-jiaoseguanli', 3, '0', '0', '2017-11-08 10:13:37', '2020-03-24 08:56:42', '0', 1);
+INSERT INTO `sys_menu` VALUES (1301, '角色新增', 'sys_role_add', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:18', '2020-03-24 08:56:43', '0', 1);
+INSERT INTO `sys_menu` VALUES (1302, '角色修改', 'sys_role_edit', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:41', '2020-03-24 08:56:43', '0', 1);
+INSERT INTO `sys_menu` VALUES (1303, '角色删除', 'sys_role_del', NULL, 1300, NULL, NULL, '0', '1', '2017-11-08 10:14:59', '2020-03-24 08:56:45', '0', 1);
+INSERT INTO `sys_menu` VALUES (1304, '分配权限', 'sys_role_perm', NULL, 1300, NULL, NULL, '0', '1', '2018-04-20 07:22:55', '2020-03-24 08:56:46', '0', 1);
+INSERT INTO `sys_menu` VALUES (1400, '部门管理', NULL, '/admin/dept/index', 1000, 'icon-web-icon-', 4, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:56:47', '0', 1);
+INSERT INTO `sys_menu` VALUES (1401, '部门新增', 'sys_dept_add', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:56:16', '2020-03-24 08:56:48', '0', 1);
+INSERT INTO `sys_menu` VALUES (1402, '部门修改', 'sys_dept_edit', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:56:59', '2020-03-24 08:56:48', '0', 1);
+INSERT INTO `sys_menu` VALUES (1403, '部门删除', 'sys_dept_del', NULL, 1400, NULL, NULL, '0', '1', '2018-01-20 14:57:28', '2020-03-24 08:56:51', '0', 1);
+INSERT INTO `sys_menu` VALUES (1500, '租户管理', '', '/admin/tenant/index', 1000, 'icon-erji-zuhushouye', 5, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:56:49', '0', 1);
+INSERT INTO `sys_menu` VALUES (1501, '租户新增', 'admin_systenant_add', NULL, 1500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:56:52', '0', 1);
+INSERT INTO `sys_menu` VALUES (1502, '租户修改', 'admin_systenant_edit', NULL, 1500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:56:53', '0', 1);
+INSERT INTO `sys_menu` VALUES (1503, '租户删除', 'admin_systenant_del', NULL, 1500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:56:54', '0', 1);
+INSERT INTO `sys_menu` VALUES (2000, '系统管理', NULL, '/admin', -1, 'icon-xitongguanli', 1, '0', '0', '2017-11-07 20:56:00', '2020-03-24 08:56:55', '0', 1);
+INSERT INTO `sys_menu` VALUES (2100, '日志管理', NULL, '/admin/log/index', 2000, 'icon-rizhiguanli', 5, '0', '0', '2017-11-20 14:06:22', '2020-03-24 08:56:56', '0', 1);
+INSERT INTO `sys_menu` VALUES (2101, '日志删除', 'sys_log_del', NULL, 2100, NULL, NULL, '0', '1', '2017-11-20 20:37:37', '2020-03-24 08:56:58', '0', 1);
+INSERT INTO `sys_menu` VALUES (2200, '字典管理', NULL, '/admin/dict/index', 2000, 'icon-navicon-zdgl', 6, '0', '0', '2017-11-29 11:30:52', '2020-03-24 08:56:58', '0', 1);
+INSERT INTO `sys_menu` VALUES (2201, '字典删除', 'sys_dict_del', NULL, 2200, NULL, NULL, '0', '1', '2017-11-29 11:30:11', '2020-03-24 08:56:59', '0', 1);
+INSERT INTO `sys_menu` VALUES (2202, '字典新增', 'sys_dict_add', NULL, 2200, NULL, NULL, '0', '1', '2018-05-11 22:34:55', '2020-03-24 08:57:01', '0', 1);
+INSERT INTO `sys_menu` VALUES (2203, '字典修改', 'sys_dict_edit', NULL, 2200, NULL, NULL, '0', '1', '2018-05-11 22:36:03', '2020-03-24 08:57:09', '0', 1);
+INSERT INTO `sys_menu` VALUES (2210, '参数管理', NULL, '/admin/param/index', 2000, 'icon-canshu', 7, '1', '0', '2019-04-29 22:16:50', '2020-03-24 08:57:10', '0', 1);
+INSERT INTO `sys_menu` VALUES (2211, '参数新增', 'admin_syspublicparam_add', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:17:36', '2020-03-24 08:57:11', '0', 1);
+INSERT INTO `sys_menu` VALUES (2212, '参数删除', 'admin_syspublicparam_del', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:17:55', '2020-03-24 08:57:12', '0', 1);
+INSERT INTO `sys_menu` VALUES (2213, '参数编辑', 'admin_syspublicparam_edit', NULL, 2210, NULL, 1, '0', '1', '2019-04-29 22:18:14', '2020-03-24 08:57:13', '0', 1);
+INSERT INTO `sys_menu` VALUES (2300, '代码生成', '', '/gen/index', 10006, 'icon-weibiaoti46', 1, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:14', '0', 1);
+INSERT INTO `sys_menu` VALUES (2400, '终端管理', '', '/admin/client/index', 2000, 'icon-shouji', 9, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:15', '0', 1);
+INSERT INTO `sys_menu` VALUES (2401, '客户端新增', 'sys_client_add', NULL, 2400, '1', NULL, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:16', '0', 1);
+INSERT INTO `sys_menu` VALUES (2402, '客户端修改', 'sys_client_edit', NULL, 2400, NULL, NULL, '0', '1', '2018-05-15 21:37:06', '2020-03-24 08:57:16', '0', 1);
+INSERT INTO `sys_menu` VALUES (2403, '客户端删除', 'sys_client_del', NULL, 2400, NULL, NULL, '0', '1', '2018-05-15 21:39:16', '2020-03-24 08:57:17', '0', 1);
+INSERT INTO `sys_menu` VALUES (2500, '密钥管理', '', '/admin/social/index', 2000, 'icon-miyue', 10, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:18', '0', 1);
+INSERT INTO `sys_menu` VALUES (2501, '密钥新增', 'sys_social_details_add', NULL, 2500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:19', '0', 1);
+INSERT INTO `sys_menu` VALUES (2502, '密钥修改', 'sys_social_details_edit', NULL, 2500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:19', '0', 1);
+INSERT INTO `sys_menu` VALUES (2503, '密钥删除', 'sys_social_details_del', NULL, 2500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:23', '0', 1);
+INSERT INTO `sys_menu` VALUES (2600, '令牌管理', NULL, '/admin/token/index', 2000, 'icon-denglvlingpai', 11, '0', '0', '2018-09-04 05:58:41', '2020-03-24 08:57:24', '0', 1);
+INSERT INTO `sys_menu` VALUES (2601, '令牌删除', 'sys_token_del', NULL, 2600, NULL, 1, '0', '1', '2018-09-04 05:59:50', '2020-03-24 08:57:24', '0', 1);
+INSERT INTO `sys_menu` VALUES (2700, '动态路由', NULL, '/admin/route/index', 2000, 'icon-luyou', 12, '0', '0', '2018-09-04 05:58:41', '2020-03-24 08:57:25', '0', 1);
+INSERT INTO `sys_menu` VALUES (2800, 'Quartz管理', '', '/daemon/job-manage/index', 2000, 'icon-guanwangfangwen', 8, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:26', '0', 1);
+INSERT INTO `sys_menu` VALUES (2810, '任务新增', 'job_sys_job_add', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:26', '0', 1);
+INSERT INTO `sys_menu` VALUES (2820, '任务修改', 'job_sys_job_edit', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:27', '0', 1);
+INSERT INTO `sys_menu` VALUES (2830, '任务删除', 'job_sys_job_del', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:28', '0', 1);
+INSERT INTO `sys_menu` VALUES (2840, '任务暂停', 'job_sys_job_shutdown_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:28', '0', 1);
+INSERT INTO `sys_menu` VALUES (2850, '任务开始', 'job_sys_job_start_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:29', '0', 1);
+INSERT INTO `sys_menu` VALUES (2860, '任务刷新', 'job_sys_job_refresh_job', NULL, 2800, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:30', '0', 1);
+INSERT INTO `sys_menu` VALUES (2870, '执行任务', 'job_sys_job_run_job', NULL, 2800, '1', 0, '0', '1', '2019-08-08 15:35:18', '2020-03-24 08:57:31', '0', 1);
+INSERT INTO `sys_menu` VALUES (3000, '系统监控', NULL, '/daemon', -1, 'icon-msnui-supervise', 2, '0', '0', '2018-07-27 01:13:21', '2020-03-24 08:57:31', '0', 1);
+INSERT INTO `sys_menu` VALUES (3100, '服务监控', NULL, 'http://127.0.0.1:5001', 3000, 'icon-server', 0, '0', '0', '2018-06-26 10:50:32', '2020-03-24 08:57:32', '0', 1);
+INSERT INTO `sys_menu` VALUES (3110, '缓存监控', NULL, '/monitor/redis/index', 3000, 'icon-qingchuhuancun', 1, '1', '0', '2019-05-08 23:51:27', '2020-03-24 08:57:33', '0', 1);
+INSERT INTO `sys_menu` VALUES (3200, '接口文档', NULL, 'http://127.0.0.1:9999/swagger-ui.html', 3000, 'icon-wendang', 1, '0', '0', '2018-06-26 10:50:32', '2020-03-24 08:57:34', '0', 1);
+INSERT INTO `sys_menu` VALUES (3300, '事务监控', NULL, '/tx/index', 3000, 'icon-gtsquanjushiwufuwuGTS', 5, '0', '0', '2018-08-19 11:02:39', '2020-03-24 08:57:34', '0', 1);
+INSERT INTO `sys_menu` VALUES (3400, '在线事务', NULL, '/tx/model', 3000, 'icon-online', 6, '0', '0', '2018-08-19 11:32:04', '2020-03-24 08:57:35', '0', 1);
+INSERT INTO `sys_menu` VALUES (3500, '文档扩展', NULL, 'http://127.0.0.1:9999/doc.html', 3000, 'icon-wendang', 2, '0', '0', '2018-06-26 10:50:32', '2020-03-24 08:57:36', '0', 1);
+INSERT INTO `sys_menu` VALUES (3600, 'Quartz日志', '', '/daemon/job-log/index', 3000, 'icon-gtsquanjushiwufuwuGTS', 8, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:37', '0', 1);
+INSERT INTO `sys_menu` VALUES (3700, '注册配置', NULL, '', 3000, 'icon-line', 10, '0', '0', '2018-01-25 11:08:52', '2020-03-24 08:57:37', '1', 1);
+INSERT INTO `sys_menu` VALUES (4000, '协同管理', NULL, '/activti', -1, 'icon-kuaisugongzuoliu_o', 3, '0', '0', '2018-09-26 01:38:13', '2020-03-24 08:57:39', '0', 1);
+INSERT INTO `sys_menu` VALUES (4100, '模型管理', NULL, '/activiti/index', 4000, 'icon-weibiaoti13', 1, '0', '0', '2018-09-26 01:39:07', '2020-03-24 08:57:40', '0', 1);
+INSERT INTO `sys_menu` VALUES (4101, '模型管理', 'act_model_manage', NULL, 4100, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:41', '0', 1);
+INSERT INTO `sys_menu` VALUES (4200, '流程管理', '/activiti/process', '/activiti/process', 4000, 'icon-liucheng', 2, '0', '0', '2018-09-26 06:41:05', '2020-03-24 08:57:42', '0', 1);
+INSERT INTO `sys_menu` VALUES (4201, '流程管理', 'act_process_manage', NULL, 4200, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:42', '0', 1);
+INSERT INTO `sys_menu` VALUES (4300, '请假管理', '/activiti/leave', '/activiti/leave', 4000, 'icon-qingjia', 3, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:57:43', '0', 1);
+INSERT INTO `sys_menu` VALUES (4301, '请假新增', 'act_leavebill_add', NULL, 4300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:44', '0', 1);
+INSERT INTO `sys_menu` VALUES (4302, '请假修改', 'act_leavebill_edit', NULL, 4300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:45', '0', 1);
+INSERT INTO `sys_menu` VALUES (4303, '请假删除', 'act_leavebill_del', NULL, 4300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:46', '0', 1);
+INSERT INTO `sys_menu` VALUES (4400, '待办任务', '/activiti/task', '/activiti/task', 4000, 'icon-renwu', 4, '0', '0', '2018-09-27 09:52:31', '2020-03-24 08:57:48', '0', 1);
+INSERT INTO `sys_menu` VALUES (4401, '流程管理', 'act_task_manage', NULL, 4400, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:57:50', '0', 1);
+INSERT INTO `sys_menu` VALUES (5000, '支付管理', NULL, '/pay', -1, 'icon-pay6zhifu', 4, '1', '0', '2019-05-30 15:28:03', '2020-03-24 08:57:51', '0', 1);
+INSERT INTO `sys_menu` VALUES (5100, '渠道管理', NULL, '/pay/paychannel/index', 5000, 'icon-zhifuqudaoguanli', 1, '1', '0', '2019-05-30 15:32:17', '2020-03-24 08:57:52', '0', 1);
+INSERT INTO `sys_menu` VALUES (5110, '增加渠道', 'pay_paychannel_add', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:46:14', '2020-03-24 08:58:07', '0', 1);
+INSERT INTO `sys_menu` VALUES (5120, '编辑渠道', 'pay_paychannel_edit', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:46:35', '2020-03-24 08:58:08', '0', 1);
+INSERT INTO `sys_menu` VALUES (5130, '删除渠道', 'pay_paychannel_del', NULL, 5100, NULL, 1, '0', '1', '2019-05-30 15:47:08', '2020-03-24 08:58:09', '0', 1);
+INSERT INTO `sys_menu` VALUES (5200, '收银台', NULL, '/pay/cd/index', 5000, 'icon-shouyintai', 0, '1', '0', '2019-05-30 19:44:00', '2020-03-24 08:58:09', '0', 1);
+INSERT INTO `sys_menu` VALUES (5300, '商品订单', '', '/pay/goods/index', 5000, 'icon-dingdan', 2, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:10', '0', 1);
+INSERT INTO `sys_menu` VALUES (5310, '商品订单新增', 'generator_paygoodsorder_add', NULL, 5300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:11', '0', 1);
+INSERT INTO `sys_menu` VALUES (5320, '商品订单修改', 'generator_paygoodsorder_edit', NULL, 5300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:13', '0', 1);
+INSERT INTO `sys_menu` VALUES (5330, '商品订单删除', 'generator_paygoodsorder_del', NULL, 5300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:14', '0', 1);
+INSERT INTO `sys_menu` VALUES (5400, '支付订单', '', '/pay/orders/index', 5000, 'icon-zhifu', 3, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:14', '0', 1);
+INSERT INTO `sys_menu` VALUES (5410, '支付订单新增', 'generator_paytradeorder_add', NULL, 5400, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:15', '0', 1);
+INSERT INTO `sys_menu` VALUES (5420, '支付订单修改', 'generator_paytradeorder_edit', NULL, 5400, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:16', '0', 1);
+INSERT INTO `sys_menu` VALUES (5430, '支付订单删除', 'generator_paytradeorder_del', NULL, 5400, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:18', '0', 1);
+INSERT INTO `sys_menu` VALUES (5500, '回调记录', '', '/pay/notify/index', 5000, 'icon-huitiao', 4, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:19', '0', 1);
+INSERT INTO `sys_menu` VALUES (5510, '记录新增', 'generator_paynotifyrecord_add', NULL, 5500, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:19', '0', 1);
+INSERT INTO `sys_menu` VALUES (5520, '记录修改', 'generator_paynotifyrecord_edit', NULL, 5500, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:20', '0', 1);
+INSERT INTO `sys_menu` VALUES (5530, '记录删除', 'generator_paynotifyrecord_del', NULL, 5500, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:21', '0', 1);
+INSERT INTO `sys_menu` VALUES (6000, '微信管理', NULL, '/mp', -1, 'icon-gongzhonghao', 4, '0', '0', '2018-09-26 01:38:13', '2020-03-24 08:58:21', '0', 1);
+INSERT INTO `sys_menu` VALUES (6100, '账号管理', '', '/mp/wxaccount/index', 6000, 'icon-weixincaidan', 8, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:22', '0', 1);
+INSERT INTO `sys_menu` VALUES (6101, '公众号新增', 'mp_wxaccount_add', '', 6100, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:23', '0', 1);
+INSERT INTO `sys_menu` VALUES (6102, '公众号修改', 'mp_wxaccount_edit', NULL, 6100, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:23', '0', 1);
+INSERT INTO `sys_menu` VALUES (6103, '公众号删除', 'mp_wxaccount_del', NULL, 6100, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:25', '0', 1);
+INSERT INTO `sys_menu` VALUES (6200, '粉丝管理', '', '/mp/wxaccountfans/index', 6000, 'icon-fensiguanli', 8, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:26', '0', 1);
+INSERT INTO `sys_menu` VALUES (6201, '粉丝新增', 'mp_wxaccountfans_add', NULL, 6200, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:27', '0', 1);
+INSERT INTO `sys_menu` VALUES (6202, '粉丝修改', 'mp_wxaccountfans_edit', NULL, 6200, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:30', '0', 1);
+INSERT INTO `sys_menu` VALUES (6203, '粉丝删除', 'mp_wxaccountfans_del', NULL, 6200, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:31', '0', 1);
+INSERT INTO `sys_menu` VALUES (6300, '消息管理', '', '/mp/wxfansmsg/index', 6000, 'icon-xiaoxiguanli', 8, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:31', '0', 1);
+INSERT INTO `sys_menu` VALUES (6301, '消息新增', 'mp_wxfansmsg_add', NULL, 6300, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:32', '0', 1);
+INSERT INTO `sys_menu` VALUES (6302, '消息修改', 'mp_wxfansmsg_edit', NULL, 6300, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:33', '0', 1);
+INSERT INTO `sys_menu` VALUES (6303, '消息删除', 'mp_wxfansmsg_del', NULL, 6300, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:33', '0', 1);
+INSERT INTO `sys_menu` VALUES (6304, '消息回复', 'mp_wxfansmsgres_add', NULL, 6300, '1', 3, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:37', '0', 1);
+INSERT INTO `sys_menu` VALUES (6305, '回复删除', 'mp_wxfansmsgres_del', NULL, 6300, NULL, 1, '0', '1', '2019-03-28 22:53:49', '2020-03-24 08:58:35', '0', 1);
+INSERT INTO `sys_menu` VALUES (6400, '菜单设置', NULL, '/mp/wxmenu/index', 6000, 'icon-anniu_weixincaidanlianjie', 6, '1', '0', '2019-03-29 15:20:12', '2020-03-24 08:58:38', '0', 1);
+INSERT INTO `sys_menu` VALUES (6401, '保存', 'mp_wxmenu_add', NULL, 6400, NULL, 1, '0', '1', '2019-03-29 15:43:22', '2020-03-24 08:58:38', '0', 1);
+INSERT INTO `sys_menu` VALUES (6402, '发布', 'mp_wxmenu_push', NULL, 6400, NULL, 1, '0', '1', '2019-03-29 15:43:54', '2020-03-24 08:58:39', '0', 1);
+INSERT INTO `sys_menu` VALUES (6500, '运营数据', NULL, '/mp/wxstatistics/index', 6000, 'icon-zhexiantu', 7, '1', '0', '2019-04-14 00:15:35', '2020-03-24 08:58:40', '0', 1);
+INSERT INTO `sys_menu` VALUES (10000, '文件管理', NULL, '/admin/file/index', 2000, 'icon-wenjianguanli', 6, '1', '0', '2019-06-25 12:44:46', '2020-03-24 08:58:41', '0', 1);
+INSERT INTO `sys_menu` VALUES (10001, '删除文件', 'sys_file_del', NULL, 10000, NULL, 1, '0', '1', '2019-06-25 13:41:41', '2020-03-24 08:58:42', '0', 1);
+INSERT INTO `sys_menu` VALUES (10002, '表单管理', '', '/gen/form', 10006, 'icon-record', 3, '0', '0', '2018-01-20 13:17:19', '2020-03-24 08:58:44', '0', 1);
+INSERT INTO `sys_menu` VALUES (10003, '表单新增', 'gen_form_add', NULL, 10002, '1', 0, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:45', '0', 1);
+INSERT INTO `sys_menu` VALUES (10004, '表单修改', 'gen_form_edit', NULL, 10002, '1', 1, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:46', '0', 1);
+INSERT INTO `sys_menu` VALUES (10005, '表单删除', 'gen_form_del', NULL, 10002, '1', 2, '0', '1', '2018-05-15 21:35:18', '2020-03-24 08:58:47', '0', 1);
+INSERT INTO `sys_menu` VALUES (10006, '开发平台', NULL, '/gen', -1, 'icon-shejiyukaifa-', 9, '1', '0', '2019-08-12 09:35:16', '2020-03-24 08:58:48', '0', 1);
+INSERT INTO `sys_menu` VALUES (10007, '数据源管理', NULL, '/gen/datasource', 10006, 'icon-mysql', 0, '1', '0', '2019-08-12 09:42:11', '2020-03-24 08:58:49', '0', 1);
+INSERT INTO `sys_menu` VALUES (10008, '表单设计', NULL, '/gen/design', 10006, 'icon-biaodanbiaoqian', 2, '1', '0', '2019-08-16 10:08:56', '2020-03-24 08:58:53', '0', 1);
COMMIT;
-- ----------------------------
@@ -451,6 +399,7 @@ COMMIT;
-- ----------------------------
DROP TABLE IF EXISTS `sys_oauth_client_details`;
CREATE TABLE `sys_oauth_client_details` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`client_id` varchar(32) NOT NULL,
`resource_ids` varchar(256) DEFAULT NULL,
`client_secret` varchar(256) DEFAULT NULL,
@@ -462,21 +411,21 @@ CREATE TABLE `sys_oauth_client_details` (
`refresh_token_validity` int(11) DEFAULT NULL,
`additional_information` varchar(4096) DEFAULT NULL,
`autoapprove` varchar(256) DEFAULT NULL,
+ `del_flag` char(1) DEFAULT '0',
`tenant_id` int(11) NOT NULL DEFAULT '0' COMMENT '所属租户',
- PRIMARY KEY (`client_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='终端信息表';
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COMMENT='终端信息表';
-- ----------------------------
-- Records of sys_oauth_client_details
-- ----------------------------
BEGIN;
-INSERT INTO `sys_oauth_client_details` VALUES ('app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,client_credentials,implicit', NULL, NULL, 43200, 2592001, NULL, 'true', 1);
-INSERT INTO `sys_oauth_client_details` VALUES ('daemon', NULL, 'daemon', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', 1);
-INSERT INTO `sys_oauth_client_details` VALUES ('gen', NULL, 'gen', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', 1);
-INSERT INTO `sys_oauth_client_details` VALUES ('mp', NULL, 'mp', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', 1);
-INSERT INTO `sys_oauth_client_details` VALUES ('pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,client_credentials', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, NULL, NULL, NULL, 'false', 1);
-INSERT INTO `sys_oauth_client_details` VALUES ('qwe', NULL, 'qwe', 'qwe', 'implicit', NULL, NULL, NULL, NULL, NULL, 'false', 0);
-INSERT INTO `sys_oauth_client_details` VALUES ('test', NULL, 'test', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,client_credentials,implicit', NULL, NULL, 43200, 2592001, NULL, 'true', '0', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (2, 'daemon', NULL, 'daemon', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (3, 'gen', NULL, 'gen', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (4, 'mp', NULL, 'mp', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,client_credentials', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, NULL, NULL, NULL, 'false', '0', 1);
+INSERT INTO `sys_oauth_client_details` VALUES (6, 'test', NULL, 'test', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
COMMIT;
-- ----------------------------
@@ -490,8 +439,8 @@ CREATE TABLE `sys_public_param` (
`public_value` varchar(128) DEFAULT NULL,
`status` char(1) DEFAULT '0',
`validate_code` varchar(64) DEFAULT NULL,
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`public_type` char(1) DEFAULT '0',
`system` char(1) DEFAULT '0',
`del_flag` char(1) DEFAULT '0',
@@ -510,8 +459,8 @@ CREATE TABLE `sys_role` (
`role_desc` varchar(255) DEFAULT NULL,
`ds_type` char(1) DEFAULT '2',
`ds_scope` varchar(255) DEFAULT NULL,
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`del_flag` char(1) DEFAULT '0',
`tenant_id` int(11) DEFAULT NULL,
PRIMARY KEY (`role_id`) USING BTREE,
@@ -522,7 +471,7 @@ CREATE TABLE `sys_role` (
-- Records of sys_role
-- ----------------------------
BEGIN;
-INSERT INTO `sys_role` VALUES (1, '管理员', 'ROLE_ADMIN', '管理员', '3', '2', '2017-10-29 15:45:51', '2018-12-26 14:09:11', '0', 1);
+INSERT INTO `sys_role` VALUES (1, '管理员', 'ROLE_ADMIN', '管理员', '0', '2', '2017-10-29 15:45:51', '2018-12-26 14:09:11', '0', 1);
COMMIT;
-- ----------------------------
@@ -600,9 +549,6 @@ INSERT INTO `sys_role_menu` VALUES (1, 3300);
INSERT INTO `sys_role_menu` VALUES (1, 3400);
INSERT INTO `sys_role_menu` VALUES (1, 3500);
INSERT INTO `sys_role_menu` VALUES (1, 3600);
-INSERT INTO `sys_role_menu` VALUES (1, 3601);
-INSERT INTO `sys_role_menu` VALUES (1, 3620);
-INSERT INTO `sys_role_menu` VALUES (1, 3630);
INSERT INTO `sys_role_menu` VALUES (1, 4000);
INSERT INTO `sys_role_menu` VALUES (1, 4100);
INSERT INTO `sys_role_menu` VALUES (1, 4101);
@@ -738,8 +684,8 @@ CREATE TABLE `sys_tenant` (
`end_time` timestamp NULL DEFAULT NULL COMMENT '结束时间',
`status` char(1) DEFAULT '0',
`del_flag` char(1) DEFAULT '0',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='租户表';
@@ -747,7 +693,7 @@ CREATE TABLE `sys_tenant` (
-- Records of sys_tenant
-- ----------------------------
BEGIN;
-INSERT INTO `sys_tenant` VALUES (1, '北京分公司', '1', '2019-05-15 00:00:00', '2020-05-15 00:00:00', '0', '0', '2019-05-15 15:44:57', '2019-05-18 14:47:30');
+INSERT INTO `sys_tenant` VALUES (1, '北京分公司', '1', '2019-05-15 00:00:00', '2029-05-15 00:00:00', '0', '0', '2019-05-15 15:44:57', '2019-05-18 14:47:30');
COMMIT;
-- ----------------------------
@@ -762,8 +708,8 @@ CREATE TABLE `sys_user` (
`phone` varchar(20) DEFAULT NULL,
`avatar` varchar(255) DEFAULT NULL,
`dept_id` int(11) DEFAULT NULL COMMENT '部门ID',
- `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`lock_flag` char(1) DEFAULT '0',
`del_flag` char(1) DEFAULT '0',
`wx_openid` varchar(32) DEFAULT NULL COMMENT '微信登录openId',
diff --git a/db/4pigxx_job.sql b/db/4pigxx_job.sql
index 6f01f4aab..4fb89347c 100644
--- a/db/4pigxx_job.sql
+++ b/db/4pigxx_job.sql
@@ -7,45 +7,6 @@ USE pigxx_job;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
--- ----------------------------
--- Table structure for job_execution_log
--- ----------------------------
-DROP TABLE IF EXISTS `job_execution_log`;
-CREATE TABLE `job_execution_log` (
- `id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
- `job_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `task_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `hostname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `sharding_item` int(11) NOT NULL,
- `execution_source` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `failure_cause` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `is_success` int(11) NOT NULL,
- `start_time` timestamp NULL DEFAULT NULL,
- `complete_time` timestamp NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='任务日志表';
-
--- ----------------------------
--- Table structure for job_status_trace_log
--- ----------------------------
-DROP TABLE IF EXISTS `job_status_trace_log`;
-CREATE TABLE `job_status_trace_log` (
- `id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
- `job_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `original_task_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `task_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `slave_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `source` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `execution_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `sharding_item` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `state` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `message` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
- `creation_time` timestamp NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE,
- KEY `TASK_ID_STATE_INDEX` (`task_id`,`state`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='任务轨迹表';
-
-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
@@ -267,9 +228,9 @@ CREATE TABLE `sys_job` (
`job_status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(1、未发布;2、运行中;3、暂停;4、删除;)',
`job_execute_status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '状态(0正常 1异常)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建者',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`start_time` timestamp NULL DEFAULT NULL COMMENT '初次执行时间',
`previous_time` timestamp NULL DEFAULT NULL COMMENT '上次执行时间',
`next_time` timestamp NULL DEFAULT NULL COMMENT '下次执行时间',
@@ -298,7 +259,7 @@ CREATE TABLE `sys_job_log` (
`job_log_status` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
`execute_time` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '执行时间',
`exception_info` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '异常信息',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`tenant_id` int(11) NOT NULL DEFAULT '1' COMMENT '租户id',
PRIMARY KEY (`job_log_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='定时任务执行日志表';
@@ -315,13 +276,13 @@ CREATE TABLE `xxl_job_group` (
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
`address_list` varchar(512) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of xxl_job_group
-- ----------------------------
BEGIN;
-INSERT INTO `xxl_job_group` VALUES (1, 'xxl-job-executor-sample', '示例执行器', 1, 0, NULL);
+INSERT INTO `xxl_job_group` VALUES (1, 'xxl-job-executor', '示例执行器', 1, 0, NULL);
COMMIT;
-- ----------------------------
@@ -352,13 +313,13 @@ CREATE TABLE `xxl_job_info` (
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of xxl_job_info
-- ----------------------------
BEGIN;
-INSERT INTO `xxl_job_info` VALUES (1, 1, '0 0 0 * * ? *', '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '', 0, 0, 0);
+INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_cron`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`, `trigger_status`, `trigger_last_time`, `trigger_next_time`) VALUES (1, 1, '0 0 0 * * ? *', '测试任务1', '2018-11-03 22:21:31', '2020-04-15 13:58:35', 'lengleng', '', 'ROUND', 'demoJobHandler', '', 'DISCARD_LATER', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '', 0, 0, 0);
COMMIT;
-- ----------------------------
@@ -368,7 +329,7 @@ DROP TABLE IF EXISTS `xxl_job_lock`;
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) NOT NULL COMMENT '锁名称',
PRIMARY KEY (`lock_name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of xxl_job_lock
@@ -400,7 +361,7 @@ CREATE TABLE `xxl_job_log` (
PRIMARY KEY (`id`),
KEY `I_trigger_time` (`trigger_time`),
KEY `I_handle_code` (`handle_code`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for xxl_job_log_report
@@ -414,16 +375,7 @@ CREATE TABLE `xxl_job_log_report` (
`fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
PRIMARY KEY (`id`),
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-
--- ----------------------------
--- Records of xxl_job_log_report
--- ----------------------------
-BEGIN;
-INSERT INTO `xxl_job_log_report` VALUES (1, '2019-12-09 00:00:00', 0, 0, 0);
-INSERT INTO `xxl_job_log_report` VALUES (2, '2019-12-08 00:00:00', 0, 0, 0);
-INSERT INTO `xxl_job_log_report` VALUES (3, '2019-12-07 00:00:00', 0, 0, 0);
-COMMIT;
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for xxl_job_logglue
@@ -438,7 +390,7 @@ CREATE TABLE `xxl_job_logglue` (
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for xxl_job_registry
@@ -452,7 +404,7 @@ CREATE TABLE `xxl_job_registry` (
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for xxl_job_user
@@ -466,7 +418,7 @@ CREATE TABLE `xxl_job_user` (
`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
PRIMARY KEY (`id`),
UNIQUE KEY `i_username` (`username`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of xxl_job_user
diff --git a/db/6pigxx_config.sql b/db/6pigxx_config.sql
index 3778e0cbd..4441ba0ef 100644
--- a/db/6pigxx_config.sql
+++ b/db/6pigxx_config.sql
@@ -9,41 +9,41 @@ SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `config_info`;
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(255) DEFAULT NULL,
- `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
- `md5` varchar(32) DEFAULT NULL,
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
- `src_user` mediumtext,
- `src_ip` varchar(20) DEFAULT NULL,
- `app_name` varchar(128) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- `c_desc` varchar(256) DEFAULT NULL,
- `c_use` varchar(64) DEFAULT NULL,
- `effect` varchar(64) DEFAULT NULL,
- `type` varchar(64) DEFAULT NULL,
- `c_schema` mediumtext,
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4 COMMENT='config_info';
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ `c_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL,
+ `c_use` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `effect` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `type` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `c_schema` text COLLATE utf8_bin,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
-- ----------------------------
-- Records of config_info
-- ----------------------------
BEGIN;
-INSERT INTO `config_info` VALUES (1, 'application-dev.yml', 'DEFAULT_GROUP', 'jasypt:\n encryptor:\n password: pigx\n \nspring:\n redis:\n host: pigx-redis\n servlet:\n multipart:\n max-file-size: 100MB\n max-request-size: 100MB\n cloud:\n sentinel:\n transport:\n dashboard: pigx-sentinel:5020\n \nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\nribbon:\n ReadTimeout: 10000\n ConnectTimeout: 10000\n\n\nmybatis-plus:\n tenant-enable: ture\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: auto\n field-strategy: NOT_EMPTY\n type-handlers-package: com.pig4cloud.pigx.common.data.handler\n\nswagger:\n title: PigX Swagger API\n license: Powered By PigX\n licenseUrl: https://pig4cloud.com/\n terms-of-service-url: https://pig4cloud.com/\n contact:\n email: wangiegie@gmail.com\n url: https://pig4cloud.com/about.html\n authorization:\n name: pigX OAuth\n auth-regex: ^.*$\n authorization-scope-list:\n - scope: server\n description: server all\n token-url-list:\n - http://${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}/auth/oauth/token\n\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /actuator/**\n - /v2/api-docs\n resource:\n loadBalanced: true\n token-info-uri: http://pigx-auth/oauth/check_token', '8f6a2d54269c4e0769da90ecaa1d3698', '2019-04-18 02:10:20', '2019-12-31 12:54:53', NULL, '172.17.0.157', '', '', '通用配置文件', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/', 'a6674e6747c1a0bb6c6d78e13706f8f0', '2019-04-18 02:11:32', '2019-08-27 18:24:04', NULL, '127.0.0.1', '', '', '认证中心配置文件', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_datasource_conf', 'b7d132a3ecdfac4252c994adbb65b23a', '2019-04-18 02:12:10', '2019-08-27 18:24:18', NULL, '127.0.0.1', '', '', '代码生成', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n## 定时任务\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n elasticjob:\n # 分布式任务协调依赖zookeeper\n zookeeper:\n server-lists: ${ZOOKEEPER-HOST:pigx-zookeeper}:${ZOOKEEPER-PORT:2181}\n namespace: pigx-daemon\n # 普通任务\n simples:\n spring-simple-job:\n job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxSimpleJob\n cron: 0 0 0/1 * * ?\n sharding-total-count: 3\n sharding-item-parameters: 0=service1,1=service2,2=service3\n eventTraceRdbDataSource: \'dataSource\'\n listener:\n listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxElasticJobListener\n spring-simple-job2:\n job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxSimpleJob2\n cron: 0 0 0/1 * * ?\n sharding-total-count: 3\n sharding-item-parameters: 0=service1,1=service2,2=service3\n eventTraceRdbDataSource: \'dataSource\'\n listener:\n listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxElasticJobListener\n # 简单任务\n dataflows:\n spring-dataflow-job:\n job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxDataflowJob\n cron: 0 0 0/1 * * ?\n sharding-total-count: 3\n sharding-item-parameters: 0=service1,1=service2,2=service3\n streaming-process: true\n eventTraceRdbDataSource: \'dataSource\'\n listener:\n distributed-listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxDistributeElasticJobListener\n started-timeout-milliseconds: 5000\n completed-timeout-milliseconds: 10000\n\nxxl:\n job:\n admin:\n addresses: http://${XXL-HOST:pigx-xxl}:${XXL-HOST:9080}/xxl-job-admin\n executor:\n port: 9988\n appName: test-xxl', '9ce58242d57b57f737dcb59a41ee6e55', '2019-04-18 02:12:57', '2019-10-04 11:22:56', NULL, '127.0.0.1', '', '', '定时任务-elastic-job配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (1, 'application-dev.yml', 'DEFAULT_GROUP', 'jasypt:\n encryptor:\n password: pigx\n \nspring:\n redis:\n host: pigx-redis\n servlet:\n multipart:\n max-file-size: 100MB\n max-request-size: 100MB\n cloud:\n sentinel:\n eager: true\n filter:\n url-patterns: /** \n transport:\n dashboard: pigx-sentinel:5020\n \nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\nribbon:\n ReadTimeout: 10000\n ConnectTimeout: 10000\n\n#开启灰度\ngray:\n rule:\n enabled: true\n\nmybatis-plus:\n tenant-enable: ture\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: auto\n field-strategy: NOT_EMPTY\n type-handlers-package: com.pig4cloud.pigx.common.data.handler\n\nswagger:\n title: PigX Swagger API\n license: Powered By PigX\n licenseUrl: https://pig4cloud.com/\n terms-of-service-url: https://pig4cloud.com/\n contact:\n email: wangiegie@gmail.com\n url: https://pig4cloud.com/about.html\n authorization:\n name: pigX OAuth\n auth-regex: ^.*$\n authorization-scope-list:\n - scope: server\n description: server all\n token-url-list:\n - http://${GATEWAY_HOST:pigx-gateway}:${GATEWAY_PORT:9999}/auth/oauth/token\n\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /actuator/**\n - /v2/api-docs\n resource:\n loadBalanced: true\n token-info-uri: http://pigx-auth/oauth/check_token', '954b56ac77f2691529aad5c497591b28', '2019-04-18 02:10:20', '2020-02-24 13:58:21', NULL, '172.17.0.125', '', '', '通用配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/', 'a6674e6747c1a0bb6c6d78e13706f8f0', '2019-04-18 02:11:32', '2019-08-27 18:24:04', NULL, '127.0.0.1', '', '', '认证中心配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\npigx:\n tenant:\n column: tenant_id\n tables:\n - gen_datasource_conf', 'b7d132a3ecdfac4252c994adbb65b23a', '2019-04-18 02:12:10', '2019-08-27 18:24:18', NULL, '127.0.0.1', '', '', '代码生成', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n## 定时任务\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\nxxl:\n job:\n admin:\n addresses: http://${XXL_HOST:pigx-xxl}:${XXL_HOST:9080}/xxl-job-admin', 'af2d24afd75cbd73c3bbc8297ca65bc9', '2019-04-18 02:12:57', '2020-04-15 21:56:37', NULL, '127.0.0.1', '', '', '定时任务-elastic-job配置', 'null', 'null', 'yaml', 'null');
INSERT INTO `config_info` VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', 'security:\n encode:\n key: \'pigxpigxpigxpigx\'\n\nignore:\n clients:\n - test\n swagger-providers:\n - pigx-auth\n - pigx-tx-manager\n\nribbon:\n rule:\n gray-enabled: true', '24403a5b205b1e9d320078e309584bbc', '2019-04-18 02:13:52', '2019-10-20 17:07:42', NULL, '127.0.0.1', '', '', '网关配置文件', 'null', 'null', 'yaml', 'null');
INSERT INTO `config_info` VALUES (6, 'pigx-monitor-dev.yml', 'DEFAULT_GROUP', 'spring:\n # 安全配置\n security:\n user:\n name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx\n password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx\n boot:\n admin:\n ui:\n title: \'pigx 服务状态监控\'\n brand: \'pigx 服务状态监控\'\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n endpoint:\n health:\n show-details: ALWAYS #显示详细信息', '7925a0c734460526262319b6a189e39d', '2019-04-18 02:14:17', '2019-12-31 19:04:00', NULL, '172.17.0.157', '', '', '监控配置文件', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n scope: server\n ignore-urls:\n - /druid/**\n - /actuator/**\n - /v2/api-docs\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 文件系统 (提供测试环境,不要乱传)\nminio:\n url: http://minio.pig4cloud.com\n access-key: lengleng\n secret-key: lengleng\n\n# Logger Config\nlogging:\n level:\n com.pig4cloud.pigx.admin.mapper: debug\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_user\n - sys_role\n - sys_dept\n - sys_log\n - sys_social_details\n - sys_dict\n - sys_dict_item\n - sys_public_param\n - sys_log\n - sys_file', 'fab3a6b4cb292954d9841b22a41e3dab', '2019-04-18 02:32:44', '2019-11-01 12:22:38', NULL, '127.0.0.1', '', '', 'admin 服务配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n scope: server\n ignore-urls:\n - /druid/**\n - /actuator/**\n - /v2/api-docs\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 文件系统 (提供测试环境,不要乱传)\nminio:\n url: http://minio.pig4cloud.com\n access-key: lengleng\n secret-key: lengleng\n\n# Logger Config\nlogging:\n level:\n com.pig4cloud.pigx.admin.mapper: debug\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_user\n - sys_role\n - sys_menu\n - sys_dept\n - sys_log\n - sys_social_details\n - sys_dict\n - sys_dict_item\n - sys_public_param\n - sys_log\n - sys_file\n - sys_oauth_client_details', 'fab3a6b4cb292954d9841b22a41e3dab', '2019-04-18 02:32:44', '2019-11-01 12:22:38', NULL, '127.0.0.1', '', '', 'admin 服务配置', 'null', 'null', 'yaml', 'null');
INSERT INTO `config_info` VALUES (8, 'pigx-tx-manager-dev.yml', 'DEFAULT_GROUP', '# 页面配置\nspring:\n mvc:\n static-path-pattern: /**\n resources:\n static-locations: classpath:/static/\n\n\n# LCN 配置\ntm:\n transaction:\n netty:\n delaytime: 5 # 客户端链接最大通讯时间 (秒)\n hearttime: 15 # 客户端心跳时间 (秒)\n redis:\n savemaxtime: 30 # redis 保存时间 (秒)\n socket:\n port: 9998 # 通讯端口\n maxconnection: 1000 #最大链接数\n compensate:\n auto: false #是否自动补偿\n notifyUrl: http://ip:port/path #补偿结果通知(配消息总线里面)\n tryTime: 30 # z再次重试时间间隔\n maxWaitTime: 5000 # 请求超时的最大时间 (毫秒)', '885f5c125f2df7a08692929ccce154be', '2019-04-18 02:54:03', '2019-04-18 02:54:03', NULL, '127.0.0.1', '', '', '分布式事务协调模块', NULL, NULL, 'yaml', NULL);
-INSERT INTO `config_info` VALUES (9, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n quartz:\n #相关属性配置\n properties:\n org:\n quartz:\n scheduler:\n instanceName: clusteredScheduler\n instanceId: AUTO\n jobStore:\n class: org.quartz.impl.jdbcjobstore.JobStoreTX\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n clusterCheckinInterval: 10000\n useProperties: false\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 50\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n #数据库方式\n job-store-type: jdbc\n #初始化表结构\n #jdbc:\n #initialize-schema: never\n\n', '276cf549fb8b084e35dc07d1eb309932', '2019-04-18 03:08:34', '2019-08-27 18:25:41', NULL, '127.0.0.1', '', '', 'quartz 配置文件', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (10, 'pigx-pay-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_pay}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n pay:\n test: lengleng\n aliPayConfig:\n expire-time: 30\n return-url: http://pig4cloud.com\n notify-url: https://admin.pig4cloud.com/pay/notify/ali/callbak\n wxPayConfig:\n notify-url: https://admin.pig4cloud.com/pay/notify/wx/callbak\n xsequence: #发号器相关配置\n db:\n retry-times: 3\n table-name: pay_sequence\n tenant:\n column: tenant_id\n tables:\n - pay_channel\n - pay_trade_order\n - pay_goods_order\n - pay_notify_record', 'bf185a74bb9af224bfe7f8f52ae3c9cb', '2019-05-28 11:46:27', '2019-08-27 18:26:01', NULL, '127.0.0.1', '', '', '支付模块配置', 'null', 'null', 'yaml', 'null');
-INSERT INTO `config_info` VALUES (11, 'pigx-oa-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - \'/actuator/**\'\n - \'/v2/api-docs\'\n - \'/editor-app/**\'\n - \'/modeler.html\'\n - \'/ws/**\'\nspring:\n autoconfigure:\n exclude: org.activiti.spring.boot.SecurityAutoConfiguration\n activiti:\n check-process-definitions: false\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - oa_leave_bill', 'bb2ee29e458875b0334e9f204f958272', '2019-10-16 16:38:52', '2019-10-16 16:38:52', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
-INSERT INTO `config_info` VALUES (12, 'pigx-mp-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n client-secret: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - wx_mp_menu\n - wx_account\n - wx_account_fans\n - wx_fans_msg_res', 'bf4f6943566ce47a98551923bc4c4f80', '2019-10-21 08:58:24', '2019-10-21 08:58:24', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
+INSERT INTO `config_info` VALUES (9, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n quartz:\n #相关属性配置\n properties:\n org:\n quartz:\n scheduler:\n instanceName: clusteredScheduler\n instanceId: AUTO\n jobStore:\n class: org.quartz.impl.jdbcjobstore.JobStoreTX\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n clusterCheckinInterval: 10000\n useProperties: false\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 50\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n #数据库方式\n job-store-type: jdbc\n #初始化表结构\n #jdbc:\n #initialize-schema: never\n\n', '276cf549fb8b084e35dc07d1eb309932', '2019-04-18 03:08:34', '2019-08-27 18:25:41', NULL, '127.0.0.1', '', '', 'quartz 配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (10, 'pigx-pay-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_pay}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n pay:\n test: lengleng\n aliPayConfig:\n expire-time: 30\n return-url: http://pig4cloud.com\n notify-url: https://admin.pig4cloud.com/pay/notify/ali/callbak\n wxPayConfig:\n notify-url: https://admin.pig4cloud.com/pay/notify/wx/callbak\n xsequence: #发号器相关配置\n db:\n retry-times: 3\n table-name: pay_sequence\n tenant:\n column: tenant_id\n tables:\n - pay_channel\n - pay_trade_order\n - pay_goods_order\n - pay_notify_record', 'bf185a74bb9af224bfe7f8f52ae3c9cb', '2019-05-28 11:46:27', '2019-08-27 18:26:01', NULL, '127.0.0.1', '', '', '支付模块配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (11, 'pigx-oa-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - \'/actuator/**\'\n - \'/v2/api-docs\'\n - \'/editor-app/**\'\n - \'/modeler.html\'\n - \'/ws/**\'\nspring:\n autoconfigure:\n exclude: org.activiti.spring.boot.SecurityAutoConfiguration\n activiti:\n check-process-definitions: false\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - oa_leave_bill', 'bb2ee29e458875b0334e9f204f958272', '2019-10-16 16:38:52', '2019-10-16 16:38:52', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
+INSERT INTO `config_info` VALUES (12, 'pigx-mp-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n client-secret: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - wx_mp_menu\n - wx_account\n - wx_account_fans\n - wx_fans_msg_res', 'bf4f6943566ce47a98551923bc4c4f80', '2019-10-21 08:58:24', '2019-10-21 08:58:24', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
COMMIT;
-- ----------------------------
@@ -52,16 +52,16 @@ COMMIT;
DROP TABLE IF EXISTS `config_info_aggr`;
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(128) DEFAULT NULL,
- `datum_id` varchar(255) DEFAULT NULL,
- `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '内容',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `datum_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
- `app_name` varchar(128) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='增加租户字段';
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
-- ----------------------------
-- Table structure for config_info_beta
@@ -69,20 +69,20 @@ CREATE TABLE `config_info_aggr` (
DROP TABLE IF EXISTS `config_info_beta`;
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(128) DEFAULT NULL,
- `app_name` varchar(128) DEFAULT NULL,
- `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
- `beta_ips` varchar(1024) DEFAULT NULL,
- `md5` varchar(32) DEFAULT NULL,
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `beta_ips` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT 'betaIps',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
- `src_user` mediumtext,
- `src_ip` varchar(20) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info_beta';
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
-- ----------------------------
-- Table structure for config_info_tag
@@ -90,20 +90,20 @@ CREATE TABLE `config_info_beta` (
DROP TABLE IF EXISTS `config_info_tag`;
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(128) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- `tag_id` varchar(128) DEFAULT NULL,
- `app_name` varchar(128) DEFAULT NULL,
- `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
- `md5` varchar(32) DEFAULT NULL,
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
+ `tag_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
- `src_user` mediumtext,
- `src_ip` varchar(20) DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info_tag';
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
-- ----------------------------
-- Table structure for config_tags_relation
@@ -111,16 +111,16 @@ CREATE TABLE `config_info_tag` (
DROP TABLE IF EXISTS `config_tags_relation`;
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
- `tag_name` varchar(128) DEFAULT NULL,
- `tag_type` varchar(64) DEFAULT NULL,
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(128) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
+ `tag_name` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
+ `tag_type` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'tag_type',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (`nid`) USING BTREE,
- UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`) USING BTREE,
- KEY `idx_tenant_id` (`tenant_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_tag_relation';
+ PRIMARY KEY (`nid`),
+ UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
-- ----------------------------
-- Table structure for group_capacity
@@ -128,7 +128,7 @@ CREATE TABLE `config_tags_relation` (
DROP TABLE IF EXISTS `group_capacity`;
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
- `group_id` varchar(128) DEFAULT NULL,
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
@@ -137,9 +137,9 @@ CREATE TABLE `group_capacity` (
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_group_id` (`group_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='集群、各Group容量信息表';
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_group_id` (`group_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
-- ----------------------------
-- Table structure for his_config_info
@@ -148,39 +148,58 @@ DROP TABLE IF EXISTS `his_config_info`;
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `data_id` varchar(255) DEFAULT NULL,
- `group_id` varchar(128) DEFAULT NULL,
- `app_name` varchar(128) DEFAULT NULL,
- `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
- `md5` varchar(32) DEFAULT NULL,
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL,
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL,
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
- `src_user` mediumtext,
- `src_ip` varchar(20) DEFAULT NULL,
- `op_type` char(10) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- PRIMARY KEY (`nid`) USING BTREE,
- KEY `idx_gmt_create` (`gmt_create`) USING BTREE,
- KEY `idx_gmt_modified` (`gmt_modified`) USING BTREE,
- KEY `idx_did` (`data_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='多租户改造';
+ `src_user` text COLLATE utf8_bin,
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+ `op_type` char(10) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`nid`),
+ KEY `idx_gmt_create` (`gmt_create`),
+ KEY `idx_gmt_modified` (`gmt_modified`),
+ KEY `idx_did` (`data_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
+
+-- ----------------------------
+-- Table structure for permissions
+-- ----------------------------
+DROP TABLE IF EXISTS `permissions`;
+CREATE TABLE `permissions` (
+ `role` varchar(50) NOT NULL,
+ `resource` varchar(512) NOT NULL,
+ `action` varchar(8) NOT NULL,
+ UNIQUE KEY `uk_role_permission` (`role`,`resource`,`action`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Table structure for roles
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
- `username` varchar(50) DEFAULT NULL,
- `role` varchar(50) DEFAULT NULL
+ `username` varchar(50) NOT NULL,
+ `role` varchar(50) NOT NULL,
+ UNIQUE KEY `uk_username_role` (`username`,`role`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+-- ----------------------------
+-- Records of roles
+-- ----------------------------
+BEGIN;
+INSERT INTO `roles` VALUES ('nacos', 'ROLE_ADMIN');
+COMMIT;
+
-- ----------------------------
-- Table structure for tenant_capacity
-- ----------------------------
DROP TABLE IF EXISTS `tenant_capacity`;
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
- `tenant_id` varchar(128) DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
@@ -189,9 +208,9 @@ CREATE TABLE `tenant_capacity` (
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_tenant_id` (`tenant_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户容量信息表';
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
-- ----------------------------
-- Table structure for tenant_info
@@ -199,24 +218,17 @@ CREATE TABLE `tenant_capacity` (
DROP TABLE IF EXISTS `tenant_info`;
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
- `kp` varchar(128) DEFAULT NULL,
- `tenant_id` varchar(128) DEFAULT NULL,
- `tenant_name` varchar(128) DEFAULT NULL,
- `tenant_desc` varchar(256) DEFAULT NULL,
- `create_source` varchar(32) DEFAULT NULL,
+ `kp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'kp',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
+ `tenant_name` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_name',
+ `tenant_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT 'tenant_desc',
+ `create_source` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`) USING BTREE,
- KEY `idx_tenant_id` (`tenant_id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='tenant_info';
-
--- ----------------------------
--- Records of tenant_info
--- ----------------------------
-BEGIN;
-INSERT INTO `tenant_info` VALUES (1, '1', '3bd14074-1dc5-4afc-ad04-506230b73923', 'SENTINEL_GROUP', 'sentinel 相关', 'nacos', 1570872049054, 1570872049054);
-COMMIT;
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
-- ----------------------------
-- Table structure for users
@@ -224,16 +236,16 @@ COMMIT;
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(50) NOT NULL,
- `password` varchar(500) DEFAULT NULL,
+ `password` varchar(500) NOT NULL,
`enabled` tinyint(1) NOT NULL,
- PRIMARY KEY (`username`) USING BTREE
+ PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of users
-- ----------------------------
BEGIN;
-INSERT INTO `users` VALUES ('nacos', '$2a$10$1fXDf9q5CKAA.Fe4rjTzzONGDI4cXFvMfPx9Yribr9OQC2.JDe/wK', 1);
+INSERT INTO `users` VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', 1);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
diff --git a/db/7pigxx_pay.sql b/db/7pigxx_pay.sql
index f68aad5d5..2eb5769fd 100644
--- a/db/7pigxx_pay.sql
+++ b/db/7pigxx_pay.sql
@@ -17,8 +17,8 @@ CREATE TABLE `pay_channel` (
`param` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`remark` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
`app_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
@@ -45,8 +45,8 @@ CREATE TABLE `pay_goods_order` (
`status` tinyint(6) NOT NULL DEFAULT '0' COMMENT '订单状态,订单生成(0),支付成功(1),处理完成(2),处理失败(-1)',
`pay_order_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`goods_order_id`) USING BTREE,
UNIQUE KEY `IDX_PayOrderId` (`pay_order_id`) USING BTREE
@@ -64,8 +64,8 @@ CREATE TABLE `pay_notify_record` (
`order_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`http_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='通知记录日志表';
@@ -102,8 +102,8 @@ CREATE TABLE `pay_refund_order` (
`expire_time` datetime DEFAULT NULL COMMENT '订单失效时间',
`refund_succ_time` datetime DEFAULT NULL COMMENT '订单退款成功时间',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`refund_order_id`) USING BTREE,
UNIQUE KEY `IDX_MchId_MchOrderNo` (`mch_id`,`mch_refund_no`) USING BTREE
@@ -149,8 +149,8 @@ CREATE TABLE `pay_trade_order` (
`last_notify_time` bigint(20) DEFAULT NULL COMMENT '最后一次通知时间',
`expire_time` bigint(20) DEFAULT NULL COMMENT '订单失效时间',
`pay_succ_time` bigint(20) DEFAULT NULL COMMENT '订单支付成功时间',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`order_id`) USING BTREE
diff --git a/db/8pigxx_codegen.sql b/db/8pigxx_codegen.sql
index a80c54298..47da6fc18 100644
--- a/db/8pigxx_codegen.sql
+++ b/db/8pigxx_codegen.sql
@@ -20,17 +20,6 @@ CREATE TABLE `gen_datasource_conf` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='数据源表';
--- ----------------------------
--- Records of gen_datasource_conf
--- ----------------------------
-BEGIN;
-INSERT INTO `gen_datasource_conf` VALUES (1, 'pigxx', 'jdbc:mysql://pigx-mysql:3306/pigxx?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true', 'root', 'Cx+ocw0iFCpae4Qo4IoFmQ==', '2019-03-31 16:40:43', '2019-06-13 03:07:24', '0', 1);
-INSERT INTO `gen_datasource_conf` VALUES (2, 'pigxx_ac', 'jdbc:mysql://pigx-mysql:3306/pigxx_ac?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8', 'root', 'Cx+ocw0iFCpae4Qo4IoFmQ==', '2019-03-31 17:53:25', '2019-06-13 03:07:25', '0', 1);
-INSERT INTO `gen_datasource_conf` VALUES (3, 'pigxx_job', 'jdbc:mysql://pigx-mysql:3306/pigxx_job?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8', 'root', 'Cx+ocw0iFCpae4Qo4IoFmQ==', '2019-03-31 17:53:25', '2019-06-13 03:07:26', '0', 1);
-INSERT INTO `gen_datasource_conf` VALUES (4, 'pigxx_mp', 'jdbc:mysql://pigx-mysql:3306/pigxx_mp?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8', 'root', 'Cx+ocw0iFCpae4Qo4IoFmQ==', '2019-03-31 17:53:25', '2019-06-13 03:07:28', '0', 1);
-INSERT INTO `gen_datasource_conf` VALUES (5, 'pigxx_pay', 'jdbc:mysql://pigx-mysql:3306/pigxx_pay?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8', 'root', 'Cx+ocw0iFCpae4Qo4IoFmQ==', '2019-03-31 17:53:25', '2019-06-13 03:07:30', '0', 1);
-INSERT INTO `gen_datasource_conf` VALUES (6, 'pigxx_codegen', 'jdbc:mysql://pigx-mysql:3306/pigxx_codegen?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true', 'root', 'hyxlg2iaqpDLOe9qEcv2xQ==', '2019-08-12 15:47:39', '2019-08-12 15:47:39', '0', 1);
-COMMIT;
-- ----------------------------
-- Table structure for gen_form_conf
@@ -40,8 +29,8 @@ CREATE TABLE `gen_form_conf` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`form_info` json NOT NULL COMMENT '表单信息',
- `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0',
`tenant_id` int(11) DEFAULT NULL COMMENT '所属租户',
PRIMARY KEY (`id`) USING BTREE,
diff --git a/db/Dockerfile b/db/Dockerfile
index d37855415..b286c6427 100644
--- a/db/Dockerfile
+++ b/db/Dockerfile
@@ -1,21 +1,23 @@
-FROM mysql:8.0.18
+FROM mysql:8.0.19
MAINTAINER lengleng(wangiegie@gmail.com)
-RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+ENV TZ=Asia/Shanghai
-COPY ./db/1schema.sql /docker-entrypoint-initdb.d
+RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
-COPY ./db/2pigxx.sql /docker-entrypoint-initdb.d
+COPY ./1schema.sql /docker-entrypoint-initdb.d
-COPY ./db/3pigxx_ac.sql /docker-entrypoint-initdb.d
+COPY ./2pigxx.sql /docker-entrypoint-initdb.d
-COPY ./db/4pigxx_job.sql /docker-entrypoint-initdb.d
+COPY ./3pigxx_ac.sql /docker-entrypoint-initdb.d
-COPY ./db/5pigxx_mp.sql /docker-entrypoint-initdb.d
+COPY ./4pigxx_job.sql /docker-entrypoint-initdb.d
-COPY ./db/6pigxx_config.sql /docker-entrypoint-initdb.d
+COPY ./5pigxx_mp.sql /docker-entrypoint-initdb.d
-COPY ./db/7pigxx_pay.sql /docker-entrypoint-initdb.d
+COPY ./6pigxx_config.sql /docker-entrypoint-initdb.d
-COPY ./db/8pigxx_codegen.sql /docker-entrypoint-initdb.d
\ No newline at end of file
+COPY ./7pigxx_pay.sql /docker-entrypoint-initdb.d
+
+COPY ./8pigxx_codegen.sql /docker-entrypoint-initdb.d
\ No newline at end of file
diff --git a/db/增量3.7_3.8.sql b/db/增量3.7_3.8.sql
new file mode 100644
index 000000000..f1aa5545a
--- /dev/null
+++ b/db/增量3.7_3.8.sql
@@ -0,0 +1,288 @@
+USE pigxx_config;
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for config_info
+-- ----------------------------
+DROP TABLE IF EXISTS `config_info`;
+CREATE TABLE `config_info` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ `c_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL,
+ `c_use` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `effect` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `type` varchar(64) COLLATE utf8_bin DEFAULT NULL,
+ `c_schema` text COLLATE utf8_bin,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
+
+-- ----------------------------
+-- Records of config_info
+-- ----------------------------
+BEGIN;
+INSERT INTO `config_info` VALUES (1, 'application-dev.yml', 'DEFAULT_GROUP', 'jasypt:\n encryptor:\n password: pigx\n \nspring:\n redis:\n host: pigx-redis\n servlet:\n multipart:\n max-file-size: 100MB\n max-request-size: 100MB\n cloud:\n sentinel:\n eager: true\n filter:\n url-patterns: /** \n transport:\n dashboard: pigx-sentinel:5020\n \nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\nribbon:\n ReadTimeout: 10000\n ConnectTimeout: 10000\n\n#开启灰度\ngray:\n rule:\n enabled: true\n\nmybatis-plus:\n tenant-enable: ture\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n banner: false\n db-config:\n id-type: auto\n field-strategy: NOT_EMPTY\n type-handlers-package: com.pig4cloud.pigx.common.data.handler\n\nswagger:\n title: PigX Swagger API\n license: Powered By PigX\n licenseUrl: https://pig4cloud.com/\n terms-of-service-url: https://pig4cloud.com/\n contact:\n email: wangiegie@gmail.com\n url: https://pig4cloud.com/about.html\n authorization:\n name: pigX OAuth\n auth-regex: ^.*$\n authorization-scope-list:\n - scope: server\n description: server all\n token-url-list:\n - http://${GATEWAY_HOST:pigx-gateway}:${GATEWAY_PORT:9999}/auth/oauth/token\n\nsecurity:\n oauth2:\n client:\n ignore-urls:\n - /actuator/**\n - /v2/api-docs\n resource:\n loadBalanced: true\n token-info-uri: http://pigx-auth/oauth/check_token', '954b56ac77f2691529aad5c497591b28', '2019-04-18 02:10:20', '2020-02-24 13:58:21', NULL, '172.17.0.125', '', '', '通用配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (2, 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/', 'a6674e6747c1a0bb6c6d78e13706f8f0', '2019-04-18 02:11:32', '2019-08-27 18:24:04', NULL, '127.0.0.1', '', '', '认证中心配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_codegen}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\npigx:\n tenant:\n column: tenant_id\n tables:\n - gen_datasource_conf', 'b7d132a3ecdfac4252c994adbb65b23a', '2019-04-18 02:12:10', '2019-08-27 18:24:18', NULL, '127.0.0.1', '', '', '代码生成', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n## 定时任务\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\nxxl:\n job:\n admin:\n addresses: http://${XXL_HOST:pigx-xxl}:${XXL_HOST:9080}/xxl-job-admin', 'af2d24afd75cbd73c3bbc8297ca65bc9', '2019-04-18 02:12:57', '2020-04-15 21:56:37', NULL, '127.0.0.1', '', '', '定时任务-elastic-job配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', 'security:\n encode:\n key: \'pigxpigxpigxpigx\'\n\nignore:\n clients:\n - test\n swagger-providers:\n - pigx-auth\n - pigx-tx-manager\n\nribbon:\n rule:\n gray-enabled: true', '24403a5b205b1e9d320078e309584bbc', '2019-04-18 02:13:52', '2019-10-20 17:07:42', NULL, '127.0.0.1', '', '', '网关配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (6, 'pigx-monitor-dev.yml', 'DEFAULT_GROUP', 'spring:\n # 安全配置\n security:\n user:\n name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx\n password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx\n boot:\n admin:\n ui:\n title: \'pigx 服务状态监控\'\n brand: \'pigx 服务状态监控\'\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n endpoint:\n health:\n show-details: ALWAYS #显示详细信息', '7925a0c734460526262319b6a189e39d', '2019-04-18 02:14:17', '2019-12-31 19:04:00', NULL, '172.17.0.157', '', '', '监控配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n scope: server\n ignore-urls:\n - /druid/**\n - /actuator/**\n - /v2/api-docs\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 文件系统 (提供测试环境,不要乱传)\nminio:\n url: http://minio.pig4cloud.com\n access-key: lengleng\n secret-key: lengleng\n\n# Logger Config\nlogging:\n level:\n com.pig4cloud.pigx.admin.mapper: debug\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_user\n - sys_role\n - sys_menu\n - sys_dept\n - sys_log\n - sys_social_details\n - sys_dict\n - sys_dict_item\n - sys_public_param\n - sys_log\n - sys_file\n - sys_oauth_client_details', 'fab3a6b4cb292954d9841b22a41e3dab', '2019-04-18 02:32:44', '2019-11-01 12:22:38', NULL, '127.0.0.1', '', '', 'admin 服务配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (8, 'pigx-tx-manager-dev.yml', 'DEFAULT_GROUP', '# 页面配置\nspring:\n mvc:\n static-path-pattern: /**\n resources:\n static-locations: classpath:/static/\n\n\n# LCN 配置\ntm:\n transaction:\n netty:\n delaytime: 5 # 客户端链接最大通讯时间 (秒)\n hearttime: 15 # 客户端心跳时间 (秒)\n redis:\n savemaxtime: 30 # redis 保存时间 (秒)\n socket:\n port: 9998 # 通讯端口\n maxconnection: 1000 #最大链接数\n compensate:\n auto: false #是否自动补偿\n notifyUrl: http://ip:port/path #补偿结果通知(配消息总线里面)\n tryTime: 30 # z再次重试时间间隔\n maxWaitTime: 5000 # 请求超时的最大时间 (毫秒)', '885f5c125f2df7a08692929ccce154be', '2019-04-18 02:54:03', '2019-04-18 02:54:03', NULL, '127.0.0.1', '', '', '分布式事务协调模块', NULL, NULL, 'yaml', NULL);
+INSERT INTO `config_info` VALUES (9, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n quartz:\n #相关属性配置\n properties:\n org:\n quartz:\n scheduler:\n instanceName: clusteredScheduler\n instanceId: AUTO\n jobStore:\n class: org.quartz.impl.jdbcjobstore.JobStoreTX\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n clusterCheckinInterval: 10000\n useProperties: false\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 50\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n #数据库方式\n job-store-type: jdbc\n #初始化表结构\n #jdbc:\n #initialize-schema: never\n\n', '276cf549fb8b084e35dc07d1eb309932', '2019-04-18 03:08:34', '2019-08-27 18:25:41', NULL, '127.0.0.1', '', '', 'quartz 配置文件', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (10, 'pigx-pay-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_pay}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n pay:\n test: lengleng\n aliPayConfig:\n expire-time: 30\n return-url: http://pig4cloud.com\n notify-url: https://admin.pig4cloud.com/pay/notify/ali/callbak\n wxPayConfig:\n notify-url: https://admin.pig4cloud.com/pay/notify/wx/callbak\n xsequence: #发号器相关配置\n db:\n retry-times: 3\n table-name: pay_sequence\n tenant:\n column: tenant_id\n tables:\n - pay_channel\n - pay_trade_order\n - pay_goods_order\n - pay_notify_record', 'bf185a74bb9af224bfe7f8f52ae3c9cb', '2019-05-28 11:46:27', '2019-08-27 18:26:01', NULL, '127.0.0.1', '', '', '支付模块配置', 'null', 'null', 'yaml', 'null');
+INSERT INTO `config_info` VALUES (11, 'pigx-oa-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - \'/actuator/**\'\n - \'/v2/api-docs\'\n - \'/editor-app/**\'\n - \'/modeler.html\'\n - \'/ws/**\'\nspring:\n autoconfigure:\n exclude: org.activiti.spring.boot.SecurityAutoConfiguration\n activiti:\n check-process-definitions: false\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - oa_leave_bill', 'bb2ee29e458875b0334e9f204f958272', '2019-10-16 16:38:52', '2019-10-16 16:38:52', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
+INSERT INTO `config_info` VALUES (12, 'pigx-mp-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n client-secret: ENC(vW+Nup9LaTfIFwgufUBsYg==)\n scope: server\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - wx_mp_menu\n - wx_account\n - wx_account_fans\n - wx_fans_msg_res', 'bf4f6943566ce47a98551923bc4c4f80', '2019-10-21 08:58:24', '2019-10-21 08:58:24', NULL, '127.0.0.1', '', '', NULL, NULL, NULL, 'yaml', NULL);
+COMMIT;
+
+-- ----------------------------
+-- Table structure for config_info_aggr
+-- ----------------------------
+DROP TABLE IF EXISTS `config_info_aggr`;
+CREATE TABLE `config_info_aggr` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `datum_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT '内容',
+ `gmt_modified` datetime NOT NULL COMMENT '修改时间',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
+
+-- ----------------------------
+-- Table structure for config_info_beta
+-- ----------------------------
+DROP TABLE IF EXISTS `config_info_beta`;
+CREATE TABLE `config_info_beta` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `beta_ips` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT 'betaIps',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
+
+-- ----------------------------
+-- Table structure for config_info_tag
+-- ----------------------------
+DROP TABLE IF EXISTS `config_info_tag`;
+CREATE TABLE `config_info_tag` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
+ `tag_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+ `src_user` text COLLATE utf8_bin COMMENT 'source user',
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
+
+-- ----------------------------
+-- Table structure for config_tags_relation
+-- ----------------------------
+DROP TABLE IF EXISTS `config_tags_relation`;
+CREATE TABLE `config_tags_relation` (
+ `id` bigint(20) NOT NULL COMMENT 'id',
+ `tag_name` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
+ `tag_type` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'tag_type',
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
+ `nid` bigint(20) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`nid`),
+ UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
+
+-- ----------------------------
+-- Table structure for group_capacity
+-- ----------------------------
+DROP TABLE IF EXISTS `group_capacity`;
+CREATE TABLE `group_capacity` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
+ `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
+ `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
+ `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
+ `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
+ `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
+ `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_group_id` (`group_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
+
+-- ----------------------------
+-- Table structure for his_config_info
+-- ----------------------------
+DROP TABLE IF EXISTS `his_config_info`;
+CREATE TABLE `his_config_info` (
+ `id` bigint(64) unsigned NOT NULL,
+ `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `data_id` varchar(255) COLLATE utf8_bin NOT NULL,
+ `group_id` varchar(128) COLLATE utf8_bin NOT NULL,
+ `app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
+ `content` longtext COLLATE utf8_bin NOT NULL,
+ `md5` varchar(32) COLLATE utf8_bin DEFAULT NULL,
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
+ `src_user` text COLLATE utf8_bin,
+ `src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL,
+ `op_type` char(10) COLLATE utf8_bin DEFAULT NULL,
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
+ PRIMARY KEY (`nid`),
+ KEY `idx_gmt_create` (`gmt_create`),
+ KEY `idx_gmt_modified` (`gmt_modified`),
+ KEY `idx_did` (`data_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
+
+-- ----------------------------
+-- Table structure for permissions
+-- ----------------------------
+DROP TABLE IF EXISTS `permissions`;
+CREATE TABLE `permissions` (
+ `role` varchar(50) NOT NULL,
+ `resource` varchar(512) NOT NULL,
+ `action` varchar(8) NOT NULL,
+ UNIQUE KEY `uk_role_permission` (`role`,`resource`,`action`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+-- ----------------------------
+-- Table structure for roles
+-- ----------------------------
+DROP TABLE IF EXISTS `roles`;
+CREATE TABLE `roles` (
+ `username` varchar(50) NOT NULL,
+ `role` varchar(50) NOT NULL,
+ UNIQUE KEY `uk_username_role` (`username`,`role`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+-- ----------------------------
+-- Records of roles
+-- ----------------------------
+BEGIN;
+INSERT INTO `roles` VALUES ('nacos', 'ROLE_ADMIN');
+COMMIT;
+
+-- ----------------------------
+-- Table structure for tenant_capacity
+-- ----------------------------
+DROP TABLE IF EXISTS `tenant_capacity`;
+CREATE TABLE `tenant_capacity` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `tenant_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
+ `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
+ `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
+ `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
+ `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
+ `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
+ `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
+ `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+ `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
+
+-- ----------------------------
+-- Table structure for tenant_info
+-- ----------------------------
+DROP TABLE IF EXISTS `tenant_info`;
+CREATE TABLE `tenant_info` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `kp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'kp',
+ `tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
+ `tenant_name` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_name',
+ `tenant_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT 'tenant_desc',
+ `create_source` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'create_source',
+ `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
+ `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
+ KEY `idx_tenant_id` (`tenant_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
+
+-- ----------------------------
+-- Table structure for users
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `username` varchar(50) NOT NULL,
+ `password` varchar(500) NOT NULL,
+ `enabled` tinyint(1) NOT NULL,
+ PRIMARY KEY (`username`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+-- ----------------------------
+-- Records of users
+-- ----------------------------
+BEGIN;
+INSERT INTO `users` VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', 1);
+COMMIT;
+
+ALTER TABLE `pigxx`.`sys_menu` ADD COLUMN `tenant_id` int(11) UNSIGNED NULL DEFAULT 1 COMMENT '租户ID' AFTER `del_flag`;
+
+DROP TABLE IF EXISTS `pigxx`.`sys_oauth_client_details`;
+CREATE TABLE `pigxx`.`sys_oauth_client_details` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+ `client_id` varchar(32) NOT NULL,
+ `resource_ids` varchar(256) DEFAULT NULL,
+ `client_secret` varchar(256) DEFAULT NULL,
+ `scope` varchar(256) DEFAULT NULL,
+ `authorized_grant_types` varchar(256) DEFAULT NULL,
+ `web_server_redirect_uri` varchar(256) DEFAULT NULL,
+ `authorities` varchar(256) DEFAULT NULL,
+ `access_token_validity` int(11) DEFAULT NULL,
+ `refresh_token_validity` int(11) DEFAULT NULL,
+ `additional_information` varchar(4096) DEFAULT NULL,
+ `autoapprove` varchar(256) DEFAULT NULL,
+ `del_flag` char(1) DEFAULT '0',
+ `tenant_id` int(11) NOT NULL DEFAULT '0' COMMENT '所属租户',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COMMENT='终端信息表';
+
+-- ----------------------------
+-- Records of sys_oauth_client_details
+-- ----------------------------
+BEGIN;
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (1, 'app', NULL, 'app', 'server', 'password,refresh_token,authorization_code,client_credentials,implicit', NULL, NULL, 43200, 2592001, NULL, 'true', '0', 1);
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (2, 'daemon', NULL, 'daemon', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (3, 'gen', NULL, 'gen', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (4, 'mp', NULL, 'mp', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (5, 'pig', NULL, 'pig', 'server', 'password,refresh_token,authorization_code,client_credentials', 'http://localhost:4040/sso1/login,http://localhost:4041/sso1/login,http://localhost:8080/renren-admin/sys/oauth2-sso,http://localhost:8090/sys/oauth2-sso', NULL, NULL, NULL, NULL, 'false', '0', 1);
+INSERT INTO `pigxx`.`sys_oauth_client_details` VALUES (6, 'test', NULL, 'test', 'server', 'password,refresh_token', NULL, NULL, NULL, NULL, NULL, 'true', '0', 1);
+COMMIT;
+
+UPDATE `pigxx_job`.`xxl_job_group` SET `app_name` = 'xxl-job-executor', `title` = '示例执行器', `order` = 1, `address_type` = 0, `address_list` = NULL WHERE `id` = 1;
+
+DROP TABLE `pigxx_job`.`job_execution_log`;
+
+DROP TABLE `pigxx_job`.`job_status_trace_log`;
diff --git a/docker-compose.yml b/docker-compose.yml
index ddd165323..8d150d272 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,4 @@
-# 使用说明 V3.6.0
+# 使用说明 V3.8.0
# 1. 使用docker-compose 宿主机不需要配置host来发现
# 2. 无需修改源码,根目录 docker-compose up 即可
# 3. 静静等待服务启动
@@ -7,8 +7,7 @@ version: '2'
services:
pigx-mysql:
build:
- context: ./
- dockerfile: ./db/Dockerfile
+ context: ./db
environment:
MYSQL_ROOT_PASSWORD: root
restart: always
@@ -20,28 +19,24 @@ services:
- ./pigx-mysql:/var/lib/mysql
command: --lower_case_table_names=1
- pigx-zookeeper:
- image: zookeeper:3.4.13
- restart: always
-
pigx-xxl:
- image: pig4cloud/xxl-job-admin:2.1.1
+ container_name: pigx-xxl
+ image: xuxueli/xxl-job-admin:2.2.0
restart: always
environment:
- PARAMS: "--spring.datasource.url=jdbc:mysql://pigx-mysql:3306/pigxx_job?Unicode=true&characterEncoding=UTF-8 --spring.datasource.username=root --spring.datasource.password=root"
+ PARAMS: "--server.port=9080 --spring.datasource.url=jdbc:mysql://pigx-mysql:3306/pigxx_job?Unicode=true&characterEncoding=UTF-8 --spring.datasource.username=root --spring.datasource.password=root"
ports:
- - 9080:8080
+ - 9080:9080
pigx-redis:
+ container_name: pigx-redis
image: redis:5.0.7
restart: always
- # 加密
- #command: redis-server --requirepass lengleng@123
- container_name: pigx-redis
ports:
- 6379:6379
pigx-minio:
+ container_name: pigx-minio
image: minio/minio
command: server /data
ports:
@@ -56,8 +51,7 @@ services:
pigx-register:
build:
- context: ./
- dockerfile: ./pigx-register/Dockerfile
+ context: ./pigx-register
restart: always
container_name: pigx-register
image: pigx-register
@@ -66,8 +60,7 @@ services:
pigx-gateway:
build:
- context: ./
- dockerfile: ./pigx-gateway/Dockerfile
+ context: ./pigx-gateway
restart: always
container_name: pigx-gateway
image: pigx-gateway
@@ -76,24 +69,21 @@ services:
pigx-auth:
build:
- context: ./
- dockerfile: ./pigx-auth/Dockerfile
+ context: ./pigx-auth
restart: always
container_name: pigx-auth
image: pigx-auth
pigx-upms:
build:
- context: ./
- dockerfile: ./pigx-upms/pigx-upms-biz/Dockerfile
+ context: ./pigx-upms/pigx-upms-biz
restart: always
container_name: pigx-upms
image: pigx-upms
pigx-monitor:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-monitor/Dockerfile
+ context: ./pigx-visual/pigx-monitor
restart: always
image: pigx-monitor
container_name: pigx-monitor
@@ -102,56 +92,49 @@ services:
pigx-daemon-quartz:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-daemon-quartz/Dockerfile
+ context: ./pigx-visual/pigx-daemon-quartz
restart: always
image: pigx-daemon-quartz
container_name: pigx-daemon-quartz
pigx-daemon-elastic-job:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-daemon-elastic-job/Dockerfile
+ context: ./pigx-visual/pigx-daemon-elastic-job
restart: always
image: pigx-daemon-elastic-job
container_name: pigx-daemon-elastic-job
pigx-codegen:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-codegen/Dockerfile
+ context: ./pigx-visual/pigx-codegen
restart: always
image: pigx-codegen
container_name: pigx-codegen
pigx-mp-platform:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-mp-platform/Dockerfile
+ context: ./pigx-visual/pigx-mp-platform
restart: always
image: pigx-mp-platform
container_name: pigx-mp-platform
pigx-pay-platform:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-pay-platform/Dockerfile
+ context: ./pigx-visual/pigx-pay-platform
restart: always
image: pigx-pay-platform
container_name: pigx-pay-platform
pigx-oa-platform:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-oa-platform/Dockerfile
+ context: ./pigx-visual/pigx-oa-platform
restart: always
image: pigx-oa-platform
container_name: pigx-oa-platform
pigx-tx-manager:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-tx-manager/Dockerfile
+ context: ./pigx-visual/pigx-tx-manager
restart: always
image: pigx-tx-manager
container_name: pigx-tx-manager
@@ -161,8 +144,7 @@ services:
pigx-sentinel:
build:
- context: ./
- dockerfile: ./pigx-visual/pigx-sentinel-dashboard/Dockerfile
+ context: ./pigx-visual/pigx-sentinel-dashboard
restart: always
image: pigx-sentinel
container_name: pigx-sentinel
diff --git a/pigx-auth/Dockerfile b/pigx-auth/Dockerfile
index 0d3b938e0..f22275d15 100644
--- a/pigx-auth/Dockerfile
+++ b/pigx-auth/Dockerfile
@@ -1,8 +1,10 @@
-FROM java:8-jre
+FROM pig4cloud/java:8-jre
MAINTAINER wangiegie@gmail.com
-RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+ENV TZ=Asia/Shanghai
+
+RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /pigx-auth
@@ -10,6 +12,6 @@ WORKDIR /pigx-auth
EXPOSE 3000
-ADD ./pigx-auth/target/pigx-auth.jar ./
+ADD ./target/pigx-auth.jar ./
CMD sleep 120;java -Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom -jar pigx-auth.jar
diff --git a/pigx-auth/pom.xml b/pigx-auth/pom.xml
index 3c2fa96c8..a96061028 100644
--- a/pigx-auth/pom.xml
+++ b/pigx-auth/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-auth
@@ -48,11 +48,21 @@
com.pig4cloud
pigx-upms-api
+
+
+ com.pig4cloud
+ pigx-common-log
+
com.pig4cloud
pigx-common-security
+
+
+ com.pig4cloud
+ pigx-common-feign
+
mysql
@@ -68,6 +78,11 @@
com.pig4cloud
pigx-common-sentinel
+
+
+ com.pig4cloud
+ pigx-common-gray
+
org.springframework.boot
@@ -102,7 +117,7 @@
spring-boot-maven-plugin
- com.spotify
+ io.fabric8
docker-maven-plugin
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/PigxAuthApplication.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/PigxAuthApplication.java
index bd492f999..2e41ffa7c 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/PigxAuthApplication.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/PigxAuthApplication.java
@@ -20,13 +20,13 @@
package com.pig4cloud.pigx.auth;
-import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients;
+import com.pig4cloud.pigx.common.feign.annotation.EnablePigxFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
/**
* @author lengleng
- * @date 2018年06月21日
+ * @date 2020-02-08
* 认证授权中心
*/
@SpringCloudApplication
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
index 2827b3603..cf771def3 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
@@ -23,8 +23,6 @@ import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.security.component.PigxWebResponseExceptionTranslator;
-import com.pig4cloud.pigx.common.security.service.PigxClientDetailsService;
-import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
@@ -32,19 +30,19 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
-import javax.sql.DataSource;
-
/**
* @author lengleng
* @date 2018/6/22
@@ -54,19 +52,16 @@ import javax.sql.DataSource;
@AllArgsConstructor
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
- private final DataSource dataSource;
- private final TokenEnhancer pigxTokenEnhancer;
- private final PigxUserDetailsService pigxUserDetailsService;
+ private final ClientDetailsService pigxClientDetailsServiceImpl;
private final AuthenticationManager authenticationManagerBean;
private final RedisConnectionFactory redisConnectionFactory;
+ private final UserDetailsService pigxUserDetailsService;
+ private final TokenEnhancer pigxTokenEnhancer;
@Override
@SneakyThrows
public void configure(ClientDetailsServiceConfigurer clients) {
- PigxClientDetailsService clientDetailsService = new PigxClientDetailsService(dataSource);
- clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
- clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
- clients.withClientDetails(clientDetailsService);
+ clients.withClientDetails(pigxClientDetailsServiceImpl);
}
@Override
@@ -103,3 +98,4 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
return tokenStore;
}
}
+
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java
index bf218dd7e..f104bf9dc 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSecurityConfigurer.java
@@ -27,6 +27,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
@@ -54,6 +55,14 @@ public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
.loginProcessingUrl("/token/form")
.failureHandler(authenticationFailureHandler())
.and()
+ .logout()
+ .logoutSuccessHandler((request, response, authentication) -> {
+ String referer = request.getHeader(HttpHeaders.REFERER);
+ response.sendRedirect(referer);
+ })
+ .deleteCookies("JSESSIONID")
+ .invalidateHttpSession(true)
+ .and()
.authorizeRequests()
.antMatchers(
"/token/**",
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java
index 4b087f0e2..148f5103d 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/endpoint/PigxTokenEndpoint.java
@@ -124,7 +124,19 @@ public class PigxTokenEndpoint {
}
String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();
- OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
+ return delToken(tokenValue);
+ }
+
+ /**
+ * 令牌管理调用
+ *
+ * @param token token
+ * @return
+ */
+ @Inner
+ @DeleteMapping("/{token}")
+ public R delToken(@PathVariable("token") String token) {
+ OAuth2AccessToken accessToken = tokenStore.readAccessToken(token);
if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
return R.ok(Boolean.TRUE, "退出失败,token 无效");
}
@@ -140,21 +152,7 @@ public class PigxTokenEndpoint {
// 清空 refresh token
OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
tokenStore.removeRefreshToken(refreshToken);
- return R.ok(Boolean.TRUE);
- }
-
- /**
- * 令牌管理调用
- *
- * @param token token
- * @return
- */
- @Inner
- @DeleteMapping("/{token}")
- public R delToken(@PathVariable("token") String token) {
- OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
- tokenStore.removeAccessToken(oAuth2AccessToken);
- return new R<>();
+ return R.ok();
}
@@ -176,7 +174,7 @@ public class PigxTokenEndpoint {
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
Page result = new Page(MapUtil.getInt(params, PaginationConstants.CURRENT), MapUtil.getInt(params, PaginationConstants.SIZE));
result.setRecords(redisTemplate.opsForValue().multiGet(pages));
- result.setTotal((long) redisTemplate.keys(key).size());
+ result.setTotal(redisTemplate.keys(key).size());
return R.ok(result);
}
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEvenHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java
similarity index 52%
rename from pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEvenHandler.java
rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java
index 286e2ae3a..290d72d6c 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEvenHandler.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java
@@ -17,8 +17,19 @@
package com.pig4cloud.pigx.auth.handler;
-import com.pig4cloud.pigx.common.security.handler.AbstractAuthenticationFailureEvenHandler;
+import cn.hutool.core.util.StrUtil;
+import com.pig4cloud.pigx.admin.api.entity.SysLog;
+import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
+import com.pig4cloud.pigx.common.core.constant.CommonConstants;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.core.util.WebUtils;
+import com.pig4cloud.pigx.common.log.util.SysLogUtils;
+import com.pig4cloud.pigx.common.security.handler.AuthenticationFailureHandler;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
@@ -32,10 +43,12 @@ import javax.servlet.http.HttpServletResponse;
*/
@Slf4j
@Component
-public class PigxAuthenticationFailureEvenHandler extends AbstractAuthenticationFailureEvenHandler {
+@AllArgsConstructor
+public class PigxAuthenticationFailureEventHandler implements AuthenticationFailureHandler {
+ private final RemoteLogService logService;
/**
- * 处理登录失败方法
+ * 异步处理,登录失败方法
*
*
* @param authenticationException 登录的authentication 对象
@@ -43,8 +56,23 @@ public class PigxAuthenticationFailureEvenHandler extends AbstractAuthentication
* @param request 请求
* @param response 响应
*/
+ @Async
@Override
+ @SneakyThrows
public void handle(AuthenticationException authenticationException, Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
- log.info("用户:{} 登录失败,异常:{}", authentication.getPrincipal(), authenticationException.getLocalizedMessage());
+ String username = authentication.getName();
+ SysLog sysLog = SysLogUtils.getSysLog(request, username);
+ sysLog.setTitle(username + "用户登录");
+ sysLog.setType(CommonConstants.STATUS_LOCK);
+ sysLog.setParams(username);
+ sysLog.setException(authenticationException.getLocalizedMessage());
+ String header = request.getHeader(HttpHeaders.AUTHORIZATION);
+ if (StrUtil.isNotBlank(header)) {
+ sysLog.setServiceId(WebUtils.getClientId(header));
+ }
+
+ logService.saveLog(sysLog, SecurityConstants.FROM_IN);
+
+ log.info("用户:{} 登录失败,异常:{}", username, authenticationException.getLocalizedMessage());
}
}
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java
index 0dd045565..c8daca597 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java
@@ -17,8 +17,17 @@
package com.pig4cloud.pigx.auth.handler;
-import com.pig4cloud.pigx.common.security.handler.AbstractAuthenticationSuccessEventHandler;
+import cn.hutool.core.util.StrUtil;
+import com.pig4cloud.pigx.admin.api.entity.SysLog;
+import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.core.util.WebUtils;
+import com.pig4cloud.pigx.common.log.util.SysLogUtils;
+import com.pig4cloud.pigx.common.security.handler.AuthenticationSuccessHandler;
+import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
@@ -31,7 +40,9 @@ import javax.servlet.http.HttpServletResponse;
*/
@Slf4j
@Component
-public class PigxAuthenticationSuccessEventHandler extends AbstractAuthenticationSuccessEventHandler {
+@AllArgsConstructor
+public class PigxAuthenticationSuccessEventHandler implements AuthenticationSuccessHandler {
+ private final RemoteLogService logService;
/**
* 处理登录成功方法
@@ -42,8 +53,19 @@ public class PigxAuthenticationSuccessEventHandler extends AbstractAuthenticatio
* @param request 请求
* @param response 返回
*/
+ @Async
@Override
public void handle(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
- log.info("用户:{} 登录成功", authentication.getPrincipal());
+ String username = authentication.getName();
+ SysLog sysLog = SysLogUtils.getSysLog(request, username);
+ sysLog.setTitle(username + "用户登录");
+ sysLog.setParams(username);
+ String header = request.getHeader(HttpHeaders.AUTHORIZATION);
+ if (StrUtil.isNotBlank(header)) {
+ sysLog.setServiceId(WebUtils.getClientId(header));
+ }
+
+ logService.saveLog(sysLog, SecurityConstants.FROM_IN);
+ log.info("用户:{} 登录成功", username);
}
}
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxClientDetailsServiceImpl.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxClientDetailsServiceImpl.java
new file mode 100644
index 000000000..bbb8e0d51
--- /dev/null
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxClientDetailsServiceImpl.java
@@ -0,0 +1,41 @@
+package com.pig4cloud.pigx.auth.service;
+
+import com.pig4cloud.pigx.common.core.constant.CacheConstants;
+import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
+import org.springframework.security.oauth2.provider.ClientDetails;
+import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
+import org.springframework.stereotype.Service;
+
+import javax.sql.DataSource;
+
+/**
+ * @author lengleng
+ * @date 2020/03/25
+ *
+ * 扩展 JdbcClientDetailsService 支持多租户
+ */
+@Service
+public class PigxClientDetailsServiceImpl extends JdbcClientDetailsService {
+ public PigxClientDetailsServiceImpl(DataSource dataSource) {
+ super(dataSource);
+ }
+
+
+ /**
+ * 重写原生方法支持redis缓存
+ *
+ * @param clientId
+ * @return ClientDetails
+ * @throws InvalidClientException
+ */
+ @Override
+ @Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
+ public ClientDetails loadClientByClientId(String clientId) {
+ super.setSelectClientDetailsSql(String.format(SecurityConstants.DEFAULT_SELECT_STATEMENT
+ , TenantContextHolder.getTenantId()));
+ return super.loadClientByClientId(clientId);
+ }
+}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxUserDetailsServiceImpl.java
similarity index 89%
rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java
rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxUserDetailsServiceImpl.java
index 819269f59..f8abe6dbe 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUserDetailsServiceImpl.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxUserDetailsServiceImpl.java
@@ -15,7 +15,7 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.common.security.service;
+package com.pig4cloud.pigx.auth.service;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
@@ -26,6 +26,8 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
+import com.pig4cloud.pigx.common.security.service.PigxUser;
+import com.pig4cloud.pigx.common.security.service.PigxUserDetailsService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -35,6 +37,7 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collection;
@@ -47,6 +50,7 @@ import java.util.Set;
* @author lengleng
*/
@Slf4j
+@Service
@AllArgsConstructor
public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
private final RemoteUserService remoteUserService;
@@ -113,7 +117,9 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
boolean enabled = StrUtil.equals(user.getLockFlag(), CommonConstants.STATUS_NORMAL);
// 构造security用户
- return new PigxUser(user.getUserId(), user.getDeptId(), user.getTenantId(), user.getUsername(), SecurityConstants.BCRYPT + user.getPassword(), enabled,
- true, true, !CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
+ return new PigxUser(user.getUserId(), user.getDeptId(), user.getPhone(), user.getAvatar(), user.getTenantId()
+ , user.getUsername(), SecurityConstants.BCRYPT + user.getPassword()
+ , enabled, true, true
+ , !CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
}
}
diff --git a/pigx-auth/src/main/resources/bootstrap.yml b/pigx-auth/src/main/resources/bootstrap.yml
index abba77d6f..f2c880673 100644
--- a/pigx-auth/src/main/resources/bootstrap.yml
+++ b/pigx-auth/src/main/resources/bootstrap.yml
@@ -7,10 +7,11 @@ spring:
cloud:
nacos:
discovery:
- server-addr: ${NACOS-HOST:pigx-register}:${NACOS-PORT:8848}
+ server-addr: ${NACOS_HOST:pigx-register}:${NACOS_PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
- shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ shared-configs:
+ - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
profiles:
active: @profiles.active@
\ No newline at end of file
diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml
index a912c9bbb..a9642b357 100644
--- a/pigx-common/pigx-common-bom/pom.xml
+++ b/pigx-common/pigx-common-bom/pom.xml
@@ -6,7 +6,7 @@
pigx-cloud-dependencies-parent
com.pig4cloud
- Hoxton.SR1
+ Hoxton.SR3
@@ -17,12 +17,16 @@
pigx 公共版本控制
- 3.6.0
- 3.3.0
+ 3.9.0-SNAPSHOT
+ 3.3.1
+ 3.0.0
1.1.21
- 8.0.18
+ 8.0.19
1.5.22
3.6.0
+ 1.2.0
+ 1.2.67
+ 3.0.52.ALL
@@ -42,6 +46,11 @@
pigx-common-gateway
${pigx.version}
+
+ com.pig4cloud
+ pigx-common-gray
+ ${pigx.version}
+
com.pig4cloud
pigx-common-datasource
@@ -72,6 +81,11 @@
pigx-common-sentinel
${pigx.version}
+
+ com.pig4cloud
+ pigx-common-feign
+ ${pigx.version}
+
com.pig4cloud
pigx-common-sequence
@@ -116,6 +130,12 @@
mysql-connector-java
${mysql.connector.version}
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
io.swagger
@@ -138,6 +158,21 @@
weixin-java-common
${mp.weixin.version}
+
+ com.github.javen205
+ IJPay
+ ${ijpay.version}
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+ ${aliyun.version}
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ ${dynamic-ds.version}
+
@@ -147,7 +182,7 @@
com.pig4cloud.plugin
spring-cloud-maven-plugin
- 1.0.0
+ 1.1.1
package
@@ -159,4 +194,17 @@
+
+
+
+ aliyun-plugin
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+ false
+
+
+
diff --git a/pigx-common/pigx-common-core/pom.xml b/pigx-common/pigx-common-core/pom.xml
index e5127da49..e3aed8b2d 100644
--- a/pigx-common/pigx-common-core/pom.xml
+++ b/pigx-common/pigx-common-core/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-core
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/config/JacksonConfig.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/config/JacksonConfig.java
index 323109bc1..e5a788457 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/config/JacksonConfig.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/config/JacksonConfig.java
@@ -10,7 +10,6 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import java.time.ZoneId;
import java.util.Locale;
import java.util.TimeZone;
@@ -30,7 +29,7 @@ public class JacksonConfig {
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
builder.locale(Locale.CHINA);
- builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
+ builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
builder.modules(new PigxJavaTimeModule());
};
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstants.java
index d1847c199..8c6c24b35 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstants.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CommonConstants.java
@@ -53,11 +53,6 @@ public interface CommonConstants {
*/
String STATUS_LOCK = "9";
- /**
- * 菜单
- */
- String MENU = "0";
-
/**
* 菜单树根节点
*/
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java
index d47f356f9..4c72a9eb2 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java
@@ -134,15 +134,10 @@ public interface SecurityConstants {
String BASE_FIND_STATEMENT = "select " + CLIENT_FIELDS
+ " from sys_oauth_client_details";
- /**
- * 默认的查询语句
- */
- String DEFAULT_FIND_STATEMENT = BASE_FIND_STATEMENT + " order by client_id";
-
/**
* 按条件client_id 查询
*/
- String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ?";
+ String DEFAULT_SELECT_STATEMENT = BASE_FIND_STATEMENT + " where client_id = ? and del_flag = 0 and tenant_id = %s";
/**
* 资源服务器默认bean名称
@@ -157,22 +152,36 @@ public interface SecurityConstants {
/**
* 用户ID字段
*/
- String DETAILS_USER_ID = "user_id";
+ String DETAILS_USER_ID = "id";
/**
- * 用户名字段
+ * 用户名
*/
String DETAILS_USERNAME = "username";
+ /**
+ * 用户基本信息
+ */
+ String DETAILS_USER = "user_info";
+
+ /**
+ * 用户名phone
+ */
+ String DETAILS_PHONE = "phone";
+
+ /**
+ * 头像
+ */
+ String DETAILS_AVATAR = "avatar";
/**
* 用户部门字段
*/
- String DETAILS_DEPT_ID = "dept_id";
+ String DETAILS_DEPT_ID = "deptId";
/**
* 租户ID 字段
*/
- String DETAILS_TENANT_ID = "tenant_id";
+ String DETAILS_TENANT_ID = "tenantId";
/**
* 协议字段
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/MenuTypeEnum.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/MenuTypeEnum.java
new file mode 100644
index 000000000..84dce2c54
--- /dev/null
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/MenuTypeEnum.java
@@ -0,0 +1,39 @@
+package com.pig4cloud.pigx.common.core.constant.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author lengleng
+ * @date 2020-02-17
+ *
+ * 菜单类型
+ */
+@Getter
+@AllArgsConstructor
+public enum MenuTypeEnum {
+
+ /**
+ * 左侧菜单
+ */
+ LEFT_MENU("0", "left"),
+
+ /**
+ * 顶部菜单
+ */
+ TOP_MENU("2", "top"),
+
+ /**
+ * 按钮
+ */
+ BUTTON("1", "button");
+
+ /**
+ * 类型
+ */
+ private String type;
+ /**
+ * 描述
+ */
+ private String description;
+}
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/StyleTypeEnum.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/StyleTypeEnum.java
new file mode 100644
index 000000000..0e776f828
--- /dev/null
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/enums/StyleTypeEnum.java
@@ -0,0 +1,33 @@
+package com.pig4cloud.pigx.common.core.constant.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author lengleng
+ * @date 2020-01-19
+ *
+ * 前端类型类型
+ */
+@Getter
+@AllArgsConstructor
+public enum StyleTypeEnum {
+ /**
+ * 前端类型-avue 风格
+ */
+ AVUE("0", "avue 风格"),
+
+ /**
+ * 前端类型-element 风格
+ */
+ ELEMENT("1", "element 风格");
+
+ /**
+ * 类型
+ */
+ private String style;
+ /**
+ * 描述
+ */
+ private String description;
+}
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/exception/ValidateCodeException.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/exception/ValidateCodeException.java
index ea5767f43..896878ea8 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/exception/ValidateCodeException.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/exception/ValidateCodeException.java
@@ -23,7 +23,7 @@ package com.pig4cloud.pigx.common.core.exception;
* @author lengleng
* @date 2018年06月22日16:22:15
*/
-public class ValidateCodeException extends Exception {
+public class ValidateCodeException extends RuntimeException {
private static final long serialVersionUID = -7285211528095468156L;
public ValidateCodeException() {
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/R.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/R.java
index 09b511c19..82fe04b54 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/R.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/R.java
@@ -33,6 +33,7 @@ import java.io.Serializable;
* @param
* @author lengleng
*/
+@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
index bcffaa807..6e2bf43a0 100644
--- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
+++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/util/WebUtils.java
@@ -26,11 +26,10 @@ import com.pig4cloud.pigx.common.core.exception.CheckedException;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
@@ -51,8 +50,8 @@ import java.nio.charset.StandardCharsets;
@Slf4j
@UtilityClass
public class WebUtils extends org.springframework.web.util.WebUtils {
- private final String BASIC_ = "Basic ";
- private final String UNKNOWN = "unknown";
+ private final String BASIC_ = "Basic ";
+ private final String UNKNOWN = "unknown";
/**
* 判断是否ajax请求
@@ -122,7 +121,12 @@ public class WebUtils extends org.springframework.web.util.WebUtils {
* @return {HttpServletRequest}
*/
public HttpServletRequest getRequest() {
- return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ try {
+ RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
+ return ((ServletRequestAttributes) requestAttributes).getRequest();
+ } catch (IllegalStateException e) {
+ return null;
+ }
}
/**
@@ -206,8 +210,7 @@ public class WebUtils extends org.springframework.web.util.WebUtils {
* @return
*/
@SneakyThrows
- public String[] getClientId(ServerHttpRequest request) {
- String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
+ public String getClientId(String header) {
if (header == null || !header.startsWith(BASIC_)) {
throw new CheckedException("请求头中client信息为空");
@@ -228,7 +231,7 @@ public class WebUtils extends org.springframework.web.util.WebUtils {
if (delim == -1) {
throw new CheckedException("Invalid basic authentication token");
}
- return new String[]{token.substring(0, delim), token.substring(delim + 1)};
+ return token.substring(0, delim);
}
}
diff --git a/pigx-common/pigx-common-data/pom.xml b/pigx-common/pigx-common-data/pom.xml
index 6159ce3ce..aac977ab0 100644
--- a/pigx-common/pigx-common-data/pom.xml
+++ b/pigx-common/pigx-common-data/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-data
@@ -49,6 +49,11 @@
com.pig4cloud
pigx-common-security
+
+
+ com.pig4cloud
+ pigx-upms-api
+
org.springframework.boot
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/cache/RedisTemplateConfig.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/cache/RedisTemplateConfig.java
index d2bf27e95..d89791f6a 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/cache/RedisTemplateConfig.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/cache/RedisTemplateConfig.java
@@ -78,7 +78,7 @@ public class RedisTemplateConfig {
// https://github.com/lettuce-io/lettuce-core/wiki/ReadFrom-Settings
LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
- .readFrom(ReadFrom.SLAVE_PREFERRED)
+ .readFrom(ReadFrom.REPLICA_PREFERRED)
.clientOptions(clusterClientOptions).build();
return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeMapper.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeMapper.java
new file mode 100644
index 000000000..8d3b41ec1
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeMapper.java
@@ -0,0 +1,38 @@
+package com.pig4cloud.pigx.common.data.datascope;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author lengleng
+ * @date 2020/4/26
+ */
+public interface DataScopeMapper extends BaseMapper {
+
+ /**
+ * 根据 entity 条件,查询全部记录
+ *
+ * @param queryWrapper 实体对象封装操作类(可以为 null)
+ * @param scope 数据权限范围
+ * @return List
+ */
+ List selectListByScope(@Param(Constants.WRAPPER) Wrapper queryWrapper, DataScope scope);
+
+
+ /**
+ * 根据 entity 条件,查询全部记录(并翻页)
+ *
+ * @param page 分页查询条件(可以为 RowBounds.DEFAULT)
+ * @param queryWrapper 实体对象封装操作类(可以为 null)
+ * @param scope 数据权限范围
+ * @return Page
+ */
+ > E selectPageByScope(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper, DataScope scope);
+
+
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeSqlInjector.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeSqlInjector.java
new file mode 100644
index 000000000..5c65ed32c
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/DataScopeSqlInjector.java
@@ -0,0 +1,21 @@
+package com.pig4cloud.pigx.common.data.datascope;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+
+import java.util.List;
+
+/**
+ * @author lengleng
+ * @date 2020/4/26
+ */
+public class DataScopeSqlInjector extends DefaultSqlInjector {
+
+ @Override
+ public List getMethodList(Class> mapperClass) {
+ List methodList = super.getMethodList(mapperClass);
+ methodList.add(new SelectListByScope());
+ methodList.add(new SelectPageByScope());
+ return methodList;
+ }
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectListByScope.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectListByScope.java
new file mode 100644
index 000000000..e349e4d2d
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectListByScope.java
@@ -0,0 +1,22 @@
+package com.pig4cloud.pigx.common.data.datascope;
+
+import com.baomidou.mybatisplus.core.enums.SqlMethod;
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+
+/**
+ * @author lengleng
+ * @date 2020/4/26
+ */
+public class SelectListByScope extends AbstractMethod {
+ @Override
+ public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
+ SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
+ String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
+ sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+ SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
+ return this.addSelectMappedStatementForTable(mapperClass, "selectListByScope", sqlSource, tableInfo);
+ }
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectPageByScope.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectPageByScope.java
new file mode 100644
index 000000000..b8017dd91
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/datascope/SelectPageByScope.java
@@ -0,0 +1,24 @@
+package com.pig4cloud.pigx.common.data.datascope;
+
+import com.baomidou.mybatisplus.core.enums.SqlMethod;
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+
+/**
+ * @author lengleng
+ * @date 2020/4/26
+ */
+public class SelectPageByScope extends AbstractMethod {
+
+ @Override
+ public MappedStatement injectMappedStatement(Class> mapperClass, Class> modelClass, TableInfo tableInfo) {
+ SqlMethod sqlMethod = SqlMethod.SELECT_PAGE;
+ String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true),
+ tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+ SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
+ return this.addSelectMappedStatementForTable(mapperClass, "selectPageByScope", sqlSource, tableInfo);
+ }
+
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
similarity index 91%
rename from pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java
rename to pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
index 0d64acaa9..bb94b7c4d 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfig.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
@@ -22,9 +22,9 @@ import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import com.pig4cloud.pigx.common.data.datascope.DataScopeHandle;
import com.pig4cloud.pigx.common.data.datascope.DataScopeInterceptor;
+import com.pig4cloud.pigx.common.data.datascope.DataScopeSqlInjector;
import com.pig4cloud.pigx.common.data.datascope.PigxDefaultDatascopeHandle;
import com.pig4cloud.pigx.common.data.tenant.PigxTenantHandler;
-import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -39,13 +39,12 @@ import java.util.List;
/**
* @author lengleng
- * @date 2017/10/29
+ * @date 2020-02-08
*/
@Configuration
@ConditionalOnBean(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
-@MapperScan("com.pig4cloud.pigx.**.mapper")
-public class MybatisPlusConfig {
+public class MybatisPlusConfiguration {
/**
* 创建租户维护处理器对象
@@ -95,7 +94,14 @@ public class MybatisPlusConfig {
*/
@Bean
@ConditionalOnMissingBean
+ @ConditionalOnBean(DataScopeHandle.class)
public DataScopeInterceptor dataScopeInterceptor() {
return new DataScopeInterceptor(dataScopeHandle());
}
+
+ @Bean
+ @ConditionalOnBean(DataScopeHandle.class)
+ public DataScopeSqlInjector dataScopeSqlInjector() {
+ return new DataScopeSqlInjector();
+ }
}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/resolver/SqlFilterArgumentResolver.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/resolver/SqlFilterArgumentResolver.java
index 6826743f2..44acbbb7a 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/resolver/SqlFilterArgumentResolver.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/resolver/SqlFilterArgumentResolver.java
@@ -17,7 +17,6 @@
package com.pig4cloud.pigx.common.data.resolver;
-import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -33,6 +32,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -88,13 +88,28 @@ public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver
List orderItemList = new ArrayList<>();
Optional.ofNullable(ascs).ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
- .filter(s1 -> !ArrayUtil.containsIgnoreCase(KEYWORDS, s1))
+ .filter(sqlInjectPredicate())
.map(OrderItem::asc).collect(Collectors.toList())));
Optional.ofNullable(descs).ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
- .filter(s1 -> !ArrayUtil.containsIgnoreCase(KEYWORDS, s1))
+ .filter(sqlInjectPredicate())
.map(OrderItem::desc).collect(Collectors.toList())));
page.addOrder(orderItemList);
return page;
}
+
+ /**
+ * 判断用户输入里面有没有关键字
+ * @return Predicate
+ */
+ private Predicate sqlInjectPredicate() {
+ return sql -> {
+ for (String keyword : KEYWORDS) {
+ if (StrUtil.containsIgnoreCase(sql, keyword)){
+ return false;
+ }
+ }
+ return true;
+ };
+ }
}
diff --git a/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories
index 8bc3f62f8..fd3942d5c 100644
--- a/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories
+++ b/pigx-common/pigx-common-data/src/main/resources/META-INF/spring.factories
@@ -5,5 +5,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.pig4cloud.pigx.common.data.tenant.PigxTenantConfigProperties,\
com.pig4cloud.pigx.common.data.tenant.TenantContextHolderFilter,\
com.pig4cloud.pigx.common.data.tenant.PigxFeignTenantConfiguration,\
- com.pig4cloud.pigx.common.data.mybatis.MybatisPlusConfig,\
+ com.pig4cloud.pigx.common.data.mybatis.MybatisPlusConfiguration,\
com.pig4cloud.pigx.common.data.resolver.WebMvcConfig
\ No newline at end of file
diff --git a/pigx-common/pigx-common-datasource/pom.xml b/pigx-common/pigx-common-datasource/pom.xml
index 0725599d5..dab7d0e92 100644
--- a/pigx-common/pigx-common-datasource/pom.xml
+++ b/pigx-common/pigx-common-datasource/pom.xml
@@ -5,7 +5,7 @@
pigx-common
com.pig4cloud
- 3.6.0
+ 3.9.0-SNAPSHOT
4.0.0
@@ -17,72 +17,16 @@
pigx 动态切换数据源
-
- org.springframework.boot
- spring-boot-starter-jdbc
-
-
- javax.servlet
- javax.servlet-api
-
-
- org.springframework
- spring-webmvc
-
-
-
- com.pig4cloud
- pigx-common-core
-
-
-
-
- com.pig4cloud
- pigx-common-data
-
com.baomidou
- mybatis-plus-boot-starter
-
-
- mysql
- mysql-connector-java
+ dynamic-datasource-spring-boot-starter
com.alibaba
druid-spring-boot-starter
-
-
-
- com.pig4cloud
- pigx-common-swagger
-
-
-
- com.pig4cloud
- pigx-common-security
-
-
- com.pig4cloud
- pigx-common-log
-
-
-
- velocity
- org.apache.velocity
- ${velocity.version}
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-undertow
+ provided
\ No newline at end of file
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java
deleted file mode 100644
index 011876df7..000000000
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.pig4cloud.pigx.common.datasource;
-
-import com.pig4cloud.pigx.common.datasource.config.DruidDataSourceProperties;
-import lombok.AllArgsConstructor;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-
-/**
- * @author Lucky
- * @date 2019-05-18
- *
- * 自动配置类
- */
-@AllArgsConstructor
-@EnableConfigurationProperties({DruidDataSourceProperties.class})
-public class DataSourceAutoConfiguration {
-}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DynamicDataSourceAutoConfiguration.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DynamicDataSourceAutoConfiguration.java
new file mode 100644
index 000000000..0e7dbd146
--- /dev/null
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DynamicDataSourceAutoConfiguration.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.datasource;
+
+import com.baomidou.dynamic.datasource.processor.DsProcessor;
+import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
+import com.pig4cloud.pigx.common.datasource.config.DruidDataSourceProperties;
+import com.pig4cloud.pigx.common.datasource.config.JdbcDynamicDataSourceProvider;
+import com.pig4cloud.pigx.common.datasource.config.LastParamDsProcessor;
+import lombok.AllArgsConstructor;
+import org.jasypt.encryption.StringEncryptor;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lengleng
+ * @date 2020-02-06
+ *
+ * 动态数据源切换配置
+ */
+@Configuration
+@AllArgsConstructor
+@AutoConfigureAfter(DataSourceAutoConfiguration.class)
+@EnableConfigurationProperties(DruidDataSourceProperties.class)
+public class DynamicDataSourceAutoConfiguration {
+ private final StringEncryptor stringEncryptor;
+ private final DruidDataSourceProperties properties;
+
+ @Bean
+ public DynamicDataSourceProvider dynamicDataSourceProvider() {
+ return new JdbcDynamicDataSourceProvider(stringEncryptor, properties);
+ }
+
+ @Bean
+ public DsProcessor dsProcessor() {
+ return new LastParamDsProcessor();
+ }
+}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java
index 99ebdbd6d..c04d6a105 100644
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java
@@ -1,6 +1,8 @@
package com.pig4cloud.pigx.common.datasource.annotation;
-import com.pig4cloud.pigx.common.datasource.config.DynamicDataSourceConfig;
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import com.pig4cloud.pigx.common.datasource.DynamicDataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@@ -15,6 +17,7 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
-@Import({DynamicDataSourceConfig.class})
+@EnableAutoConfiguration(exclude = {DruidDataSourceAutoConfigure.class})
+@Import(DynamicDataSourceAutoConfiguration.class)
public @interface EnableDynamicDataSource {
}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java
index efb00821c..5c9164b7f 100644
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java
@@ -14,8 +14,29 @@ import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("spring.datasource.druid")
public class DruidDataSourceProperties {
+
+ /**
+ * 数据源用户名
+ */
private String username;
+
+ /**
+ * 数据源密码
+ */
private String password;
+
+ /**
+ * jdbcurl
+ */
private String url;
+
+ /**
+ * 数据源驱动
+ */
private String driverClassName;
+
+ /**
+ * 查询数据源的SQL
+ */
+ private String queryDsSql = "select * from gen_datasource_conf where del_flag = 0";
}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java
deleted file mode 100644
index 557b5d236..000000000
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.pig4cloud.pigx.common.datasource.config;
-
-import com.pig4cloud.pigx.common.datasource.support.DynamicDataSourceContextHolder;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-
-/**
- * @author lengleng
- * @date 2019-03-31
- *
- * 动态数据源类
- */
-@Slf4j
-public class DynamicDataSource extends AbstractRoutingDataSource {
-
- /**
- * 指定路由Key
- *
- * @return
- */
- @Override
- protected Object determineCurrentLookupKey() {
- return DynamicDataSourceContextHolder.getDataSourceType();
- }
-}
\ No newline at end of file
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java
deleted file mode 100644
index 56a0b870b..000000000
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.pig4cloud.pigx.common.datasource.config;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import com.mysql.cj.jdbc.Driver;
-import com.pig4cloud.pigx.common.datasource.support.DataSourceConstants;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.jasypt.encryption.StringEncryptor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.transaction.ChainedTransactionManager;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-import org.springframework.jdbc.datasource.DriverManagerDataSource;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.TransactionManagementConfigurer;
-
-import javax.annotation.PostConstruct;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * @author lengleng
- * @date 2019-03-31
- *
- * 动态数据源切换配置
- */
-@Slf4j
-@Configuration
-@AllArgsConstructor
-public class DynamicDataSourceConfig implements TransactionManagementConfigurer {
- private final Map dataSourceMap = new HashMap<>(8);
- private final DruidDataSourceProperties dataSourceProperties;
- private final StringEncryptor stringEncryptor;
-
- @Bean("dynamicDataSource")
- public DynamicDataSource dataSource() {
- DynamicDataSource ds = new DynamicDataSource();
- DruidDataSource cads = new DruidDataSource();
- cads.setUrl(dataSourceProperties.getUrl());
- cads.setDriverClassName(dataSourceProperties.getDriverClassName());
- cads.setUsername(dataSourceProperties.getUsername());
- cads.setPassword(dataSourceProperties.getPassword());
- ds.setDefaultTargetDataSource(cads);
- dataSourceMap.put(0, cads);
- ds.setTargetDataSources(dataSourceMap);
- return ds;
- }
-
- /**
- * 组装默认配置的数据源,查询数据库配置
- */
- @PostConstruct
- public void init() {
- DriverManagerDataSource dds = new DriverManagerDataSource();
- dds.setUrl(dataSourceProperties.getUrl());
- dds.setDriverClassName(dataSourceProperties.getDriverClassName());
- dds.setUsername(dataSourceProperties.getUsername());
- dds.setPassword(dataSourceProperties.getPassword());
-
- List> dbList = new JdbcTemplate(dds).queryForList(DataSourceConstants.QUERY_DS_SQL);
- log.info("开始 -> 初始化动态数据源");
- Optional.of(dbList).ifPresent(list -> list.forEach(db -> {
- log.info("数据源:{}", db.get(DataSourceConstants.DS_NAME));
- DruidDataSource ds = new DruidDataSource();
- ds.setUrl(String.valueOf(db.get(DataSourceConstants.DS_JDBC_URL)));
- ds.setDriverClassName(Driver.class.getName());
- ds.setUsername((String) db.get(DataSourceConstants.DS_USER_NAME));
-
- String decPwd = stringEncryptor.decrypt((String) db.get(DataSourceConstants.DS_USER_PWD));
- ds.setPassword(decPwd);
- dataSourceMap.put(db.get(DataSourceConstants.DS_ROUTE_KEY), ds);
- }));
-
- log.info("完毕 -> 初始化动态数据源,共计 {} 条", dataSourceMap.size());
- }
-
- /**
- * 重新加载数据源配置
- */
- public Boolean reload() {
- init();
- DynamicDataSource dataSource = dataSource();
- dataSource.setTargetDataSources(dataSourceMap);
- dataSource.afterPropertiesSet();
- return Boolean.FALSE;
- }
-
-
- @Bean
- public PlatformTransactionManager txManager() {
- DataSourceTransactionManager transactionManager
- = new DataSourceTransactionManager(dataSource());
- return new ChainedTransactionManager(transactionManager);
- }
-
- @Override
- public PlatformTransactionManager annotationDrivenTransactionManager() {
- return txManager();
- }
-
-}
\ No newline at end of file
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java
deleted file mode 100644
index d10d0fac5..000000000
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.pig4cloud.pigx.common.datasource.config;
-
-import com.pig4cloud.pigx.common.datasource.support.DynamicDataSourceContextHolder;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.lang.Nullable;
-import org.springframework.stereotype.Component;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * @author lengleng
- * @date 2019-05-18
- *
- * 动态数据源拦截器
- */
-@Slf4j
-@Component
-@AllArgsConstructor
-public class DynamicDatasourceInterceptor implements HandlerInterceptor {
-
- /**
- * TODO 根据上下文判断路由哪个数据库
- *
- * @param request
- * @param response
- * @param handler
- * @return
- */
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
- DynamicDataSourceContextHolder.setDataSourceType(1);
- return true;
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
- @Nullable Exception ex) {
- DynamicDataSourceContextHolder.clearDataSourceType();
- }
-
-}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/JdbcDynamicDataSourceProvider.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/JdbcDynamicDataSourceProvider.java
new file mode 100644
index 000000000..3881d21ef
--- /dev/null
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/JdbcDynamicDataSourceProvider.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.datasource.config;
+
+import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
+import com.pig4cloud.pigx.common.datasource.support.DataSourceConstants;
+import org.jasypt.encryption.StringEncryptor;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author lengleng
+ * @date 2020/2/6
+ *
+ * 从数据源中获取 配置信息
+ */
+public class JdbcDynamicDataSourceProvider extends AbstractJdbcDataSourceProvider {
+ private final DruidDataSourceProperties properties;
+ private final StringEncryptor stringEncryptor;
+
+ public JdbcDynamicDataSourceProvider(StringEncryptor stringEncryptor, DruidDataSourceProperties properties) {
+ super(properties.getDriverClassName(), properties.getUrl(), properties.getUsername(), properties.getPassword());
+ this.stringEncryptor = stringEncryptor;
+ this.properties = properties;
+ }
+
+ /**
+ * 执行语句获得数据源参数
+ *
+ * @param statement 语句
+ * @return 数据源参数
+ * @throws SQLException sql异常
+ */
+ @Override
+ protected Map executeStmt(Statement statement) throws SQLException {
+ ResultSet rs = statement.executeQuery(properties.getQueryDsSql());
+
+ Map map = new HashMap<>(8);
+ while (rs.next()) {
+ String name = rs.getString(DataSourceConstants.DS_NAME);
+ String username = rs.getString(DataSourceConstants.DS_USER_NAME);
+ String password = rs.getString(DataSourceConstants.DS_USER_PWD);
+ String url = rs.getString(DataSourceConstants.DS_JDBC_URL);
+ DataSourceProperty property = new DataSourceProperty();
+ property.setUsername(username);
+ property.setPassword(stringEncryptor.decrypt(password));
+ property.setUrl(url);
+ map.put(name, property);
+ }
+
+ // 添加默认主数据源
+ DataSourceProperty property = new DataSourceProperty();
+ property.setUsername(properties.getUsername());
+ property.setPassword(properties.getPassword());
+ property.setUrl(properties.getUrl());
+ map.put(DataSourceConstants.DS_MASTER, property);
+ return map;
+ }
+}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/LastParamDsProcessor.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/LastParamDsProcessor.java
new file mode 100644
index 000000000..10953abc9
--- /dev/null
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/LastParamDsProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.datasource.config;
+
+import com.baomidou.dynamic.datasource.processor.DsProcessor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * @author lengleng
+ * @date 2020/2/6
+ *
+ * 参数数据源解析 @DS("#last)
+ */
+public class LastParamDsProcessor extends DsProcessor {
+
+ private static final String LAST_PREFIX = "#last";
+
+
+ /**
+ * 抽象匹配条件 匹配才会走当前执行器否则走下一级执行器
+ *
+ * @param key DS注解里的内容
+ * @return 是否匹配
+ */
+ @Override
+ public boolean matches(String key) {
+ return key.startsWith(LAST_PREFIX);
+ }
+
+ /**
+ * 抽象最终决定数据源
+ *
+ * @param invocation 方法执行信息
+ * @param key DS注解里的内容
+ * @return 数据源名称
+ */
+ @Override
+ public String doDetermineDatasource(MethodInvocation invocation, String key) {
+ Object[] arguments = invocation.getArguments();
+ return String.valueOf(arguments[arguments.length - 1]);
+ }
+}
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java
index af57b82fc..07a34ea62 100644
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java
+++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java
@@ -7,21 +7,17 @@ package com.pig4cloud.pigx.common.datasource.support;
* 数据源相关常量
*/
public interface DataSourceConstants {
- /**
- * 查询数据源的SQL
- */
- String QUERY_DS_SQL = "select * from gen_datasource_conf where del_flag = 0";
-
- /**
- * 动态路由KEY
- */
- String DS_ROUTE_KEY = "id";
/**
* 数据源名称
*/
String DS_NAME = "name";
+ /**
+ * 默认数据源(master)
+ */
+ String DS_MASTER = "master";
+
/**
* jdbcurl
*/
diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java
deleted file mode 100644
index d082585d4..000000000
--- a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.pig4cloud.pigx.common.datasource.support;
-
-import lombok.experimental.UtilityClass;
-
-/**
- * @author lengleng
- * @date 2019-05-18
- *
- * 根据当前线程来选择具体的数据源
- */
-@UtilityClass
-public class DynamicDataSourceContextHolder {
- private final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>();
-
- /**
- * 提供给AOP去设置当前的线程的数据源的信息
- *
- * @param dataSourceType
- */
- public void setDataSourceType(Integer dataSourceType) {
- CONTEXT_HOLDER.set(dataSourceType);
- }
-
- /**
- * 提供给AbstractRoutingDataSource的实现类,通过key选择数据源
- *
- * @return
- */
- public Integer getDataSourceType() {
- return CONTEXT_HOLDER.get();
- }
-
- /**
- * 使用默认的数据源
- *
- */
- public void clearDataSourceType() {
- CONTEXT_HOLDER.remove();
- }
-}
\ No newline at end of file
diff --git a/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 15efe41d9..000000000
--- a/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,2 +0,0 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.pig4cloud.pigx.common.datasource.DataSourceAutoConfiguration
\ No newline at end of file
diff --git a/pigx-common/pigx-common-feign/pom.xml b/pigx-common/pigx-common-feign/pom.xml
new file mode 100755
index 000000000..11790ace1
--- /dev/null
+++ b/pigx-common/pigx-common-feign/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ com.pig4cloud
+ pigx-common
+ 3.9.0-SNAPSHOT
+
+
+ 4.0.0
+ jar
+ pigx-common-feign
+ feign 通用组件
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
diff --git a/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/PigxFeignAutoConfiguration.java b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/PigxFeignAutoConfiguration.java
new file mode 100644
index 000000000..db0f54436
--- /dev/null
+++ b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/PigxFeignAutoConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.feign;
+
+import com.pig4cloud.pigx.common.feign.endpoint.FeignClientEndpoint;
+import feign.Feign;
+import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.PigxFeignClientsRegistrar;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author lengleng
+ * @date 2020/2/8
+ *
+ * feign 自动化配置
+ */
+@Configuration
+@ConditionalOnClass(Feign.class)
+@Import(PigxFeignClientsRegistrar.class)
+@AutoConfigureAfter(EnableFeignClients.class)
+public class PigxFeignAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ @ConditionalOnAvailableEndpoint
+ public FeignClientEndpoint feignClientEndpoint(ApplicationContext context) {
+ return new FeignClientEndpoint(context);
+ }
+
+}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/annotation/EnablePigxFeignClients.java b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/annotation/EnablePigxFeignClients.java
similarity index 91%
rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/annotation/EnablePigxFeignClients.java
rename to pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/annotation/EnablePigxFeignClients.java
index f6fc388a3..9075c216b 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/annotation/EnablePigxFeignClients.java
+++ b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/annotation/EnablePigxFeignClients.java
@@ -15,20 +15,23 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.common.security.annotation;
+package com.pig4cloud.pigx.common.feign.annotation;
import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.cloud.openfeign.PigxFeignClientsRegistrar;
+import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author lengleng
- * @date 2018/9/5
+ * @date 2020-02-08
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EnableFeignClients
+@Import(PigxFeignClientsRegistrar.class)
public @interface EnablePigxFeignClients {
/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
diff --git a/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/endpoint/FeignClientEndpoint.java b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/endpoint/FeignClientEndpoint.java
new file mode 100644
index 000000000..60d6f0986
--- /dev/null
+++ b/pigx-common/pigx-common-feign/src/main/java/com/pig4cloud/pigx/common/feign/endpoint/FeignClientEndpoint.java
@@ -0,0 +1,114 @@
+package com.pig4cloud.pigx.common.feign.endpoint;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.SmartInitializingSingleton;
+import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
+import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Feign client 端点
+ *
+ * @author L.cm
+ */
+@Endpoint(id = "feign")
+public class FeignClientEndpoint implements SmartInitializingSingleton {
+ private final ApplicationContext context;
+ private final List clientList;
+
+ public FeignClientEndpoint(ApplicationContext context) {
+ this.context = context;
+ this.clientList = new ArrayList<>();
+ }
+
+ @ReadOperation
+ public List invoke() {
+ return clientList;
+ }
+
+ @Override
+ public void afterSingletonsInstantiated() {
+ clientList.addAll(getClientList(context));
+ }
+
+ private static List getClientList(ApplicationContext context) {
+ Map feignClientMap = context.getBeansWithAnnotation(FeignClient.class);
+ // 1. 解析注解
+ List feignClientInfoList = new ArrayList<>();
+ Set> feignClientEntrySet = feignClientMap.entrySet();
+ for (Map.Entry feignClientEntry : feignClientEntrySet) {
+ String beanName = feignClientEntry.getKey();
+ Object feignClientBean = feignClientEntry.getValue();
+ if (feignClientBean == null) {
+ continue;
+ }
+ // 解析注解
+ Class> feignClientClass = feignClientBean.getClass();
+ FeignClient feignClientAnn = AnnotationUtils.findAnnotation(feignClientClass, FeignClient.class);
+ if (feignClientAnn == null) {
+ continue;
+ }
+ FeignClientInfo feignClientInfo = new FeignClientInfo();
+ feignClientInfo.setBeanName(beanName);
+ String serviceId = feignClientAnn.value();
+ String contextId = feignClientAnn.contextId();
+ String url = feignClientAnn.url();
+ String path = feignClientAnn.path();
+ feignClientInfo.setServiceId(serviceId);
+ feignClientInfo.setContextId(contextId);
+ feignClientInfo.setUrl(url);
+ feignClientInfo.setPath(path);
+ // 组装客户端信息
+ List clientInfoList = new ArrayList<>();
+ Class>[] interfaces = feignClientClass.getInterfaces();
+ for (Class> clientInterface : interfaces) {
+ Method[] methods = clientInterface.getDeclaredMethods();
+ for (Method method : methods) {
+ if (method.isDefault()) {
+ continue;
+ }
+ RequestMapping requestMapping = AnnotatedElementUtils.getMergedAnnotation(method, RequestMapping.class);
+ if (requestMapping == null) {
+ continue;
+ }
+ clientInfoList.add(new ClientInfo(requestMapping.method(), requestMapping.value()));
+ }
+ }
+ feignClientInfo.setClientList(clientInfoList);
+ feignClientInfoList.add(feignClientInfo);
+ }
+ return feignClientInfoList;
+ }
+
+ @Getter
+ @Setter
+ public static class FeignClientInfo {
+ private String beanName;
+ private String serviceId;
+ private String contextId;
+ private String url;
+ private String path;
+ private List clientList;
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public static class ClientInfo {
+ private final RequestMethod[] methods;
+ private final String[] mappings;
+ }
+
+}
\ No newline at end of file
diff --git a/pigx-common/pigx-common-feign/src/main/java/org/springframework/cloud/openfeign/PigxFeignClientsRegistrar.java b/pigx-common/pigx-common-feign/src/main/java/org/springframework/cloud/openfeign/PigxFeignClientsRegistrar.java
new file mode 100644
index 000000000..5585de580
--- /dev/null
+++ b/pigx-common/pigx-common-feign/src/main/java/org/springframework/cloud/openfeign/PigxFeignClientsRegistrar.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package org.springframework.cloud.openfeign;
+
+import com.pig4cloud.pigx.common.feign.PigxFeignAutoConfiguration;
+import lombok.Getter;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.support.SpringFactoriesLoader;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.lang.Nullable;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author L.cm
+ * @date 2020/2/8
+ *
+ * feign 自动配置功能 from mica
+ */
+public class PigxFeignClientsRegistrar implements ImportBeanDefinitionRegistrar, BeanClassLoaderAware, EnvironmentAware {
+ @Getter
+ private ClassLoader beanClassLoader;
+ @Getter
+ private Environment environment;
+
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
+ registerFeignClients(registry);
+ }
+
+ @Override
+ public void setBeanClassLoader(ClassLoader classLoader) {
+ this.beanClassLoader = classLoader;
+ }
+
+ private void registerFeignClients(BeanDefinitionRegistry registry) {
+ List feignClients = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
+ // 如果 spring.factories 里为空
+ if (feignClients.isEmpty()) {
+ return;
+ }
+ for (String className : feignClients) {
+ try {
+ Class> clazz = beanClassLoader.loadClass(className);
+ AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(clazz, FeignClient.class);
+ if (attributes == null) {
+ continue;
+ }
+ // 如果已经存在该 bean,支持原生的 Feign
+ if (registry.containsBeanDefinition(className)) {
+ continue;
+ }
+ registerClientConfiguration(registry, getClientName(attributes), attributes.get("configuration"));
+
+ validate(attributes);
+ BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);
+ definition.addPropertyValue("url", getUrl(attributes));
+ definition.addPropertyValue("path", getPath(attributes));
+ String name = getName(attributes);
+ definition.addPropertyValue("name", name);
+
+ // 兼容最新版本的 spring-cloud-openfeign,尚未发布
+ StringBuilder aliasBuilder = new StringBuilder(18);
+ if (attributes.containsKey("contextId")) {
+ String contextId = getContextId(attributes);
+ aliasBuilder.append(contextId);
+ definition.addPropertyValue("contextId", contextId);
+ } else {
+ aliasBuilder.append(name);
+ }
+
+ definition.addPropertyValue("type", className);
+ definition.addPropertyValue("decode404", attributes.get("decode404"));
+ definition.addPropertyValue("fallback", attributes.get("fallback"));
+ definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
+ definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
+
+ AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
+
+ // alias
+ String alias = aliasBuilder.append("FeignClient").toString();
+
+ // has a default, won't be null
+ boolean primary = (Boolean) attributes.get("primary");
+
+ beanDefinition.setPrimary(primary);
+
+ String qualifier = getQualifier(attributes);
+ if (StringUtils.hasText(qualifier)) {
+ alias = qualifier;
+ }
+
+ BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className, new String[]{alias});
+ BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
+
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Return the class used by {@link SpringFactoriesLoader} to load configuration
+ * candidates.
+ *
+ * @return the factory class
+ */
+ private Class> getSpringFactoriesLoaderFactoryClass() {
+ return PigxFeignAutoConfiguration.class;
+ }
+
+ private void validate(Map attributes) {
+ AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes);
+ // This blows up if an aliased property is overspecified
+ FeignClientsRegistrar.validateFallback(annotation.getClass("fallback"));
+ FeignClientsRegistrar.validateFallbackFactory(annotation.getClass("fallbackFactory"));
+ }
+
+ private String getName(Map attributes) {
+ String name = (String) attributes.get("serviceId");
+ if (!StringUtils.hasText(name)) {
+ name = (String) attributes.get("name");
+ }
+ if (!StringUtils.hasText(name)) {
+ name = (String) attributes.get("value");
+ }
+ name = resolve(name);
+ return FeignClientsRegistrar.getName(name);
+ }
+
+ private String getContextId(Map attributes) {
+ String contextId = (String) attributes.get("contextId");
+ if (!StringUtils.hasText(contextId)) {
+ return getName(attributes);
+ }
+
+ contextId = resolve(contextId);
+ return FeignClientsRegistrar.getName(contextId);
+ }
+
+ private String resolve(String value) {
+ if (StringUtils.hasText(value)) {
+ return this.environment.resolvePlaceholders(value);
+ }
+ return value;
+ }
+
+ private String getUrl(Map attributes) {
+ String url = resolve((String) attributes.get("url"));
+ return FeignClientsRegistrar.getUrl(url);
+ }
+
+ private String getPath(Map attributes) {
+ String path = resolve((String) attributes.get("path"));
+ return FeignClientsRegistrar.getPath(path);
+ }
+
+ @Nullable
+ private String getQualifier(@Nullable Map client) {
+ if (client == null) {
+ return null;
+ }
+ String qualifier = (String) client.get("qualifier");
+ if (StringUtils.hasText(qualifier)) {
+ return qualifier;
+ }
+ return null;
+ }
+
+ @Nullable
+ private String getClientName(@Nullable Map client) {
+ if (client == null) {
+ return null;
+ }
+ String value = (String) client.get("contextId");
+ if (!StringUtils.hasText(value)) {
+ value = (String) client.get("value");
+ }
+ if (!StringUtils.hasText(value)) {
+ value = (String) client.get("name");
+ }
+ if (!StringUtils.hasText(value)) {
+ value = (String) client.get("serviceId");
+ }
+ if (StringUtils.hasText(value)) {
+ return value;
+ }
+
+ throw new IllegalStateException("Either 'name' or 'value' must be provided in @" + FeignClient.class.getSimpleName());
+ }
+
+ private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object configuration) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FeignClientSpecification.class);
+ builder.addConstructorArgValue(name);
+ builder.addConstructorArgValue(configuration);
+ registry.registerBeanDefinition(name + "." + FeignClientSpecification.class.getSimpleName(), builder.getBeanDefinition());
+ }
+
+ @Override
+ public void setEnvironment(Environment environment) {
+ this.environment = environment;
+ }
+
+}
\ No newline at end of file
diff --git a/pigx-common/pigx-common-feign/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-feign/src/main/resources/META-INF/spring.factories
new file mode 100755
index 000000000..d078c185f
--- /dev/null
+++ b/pigx-common/pigx-common-feign/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.pig4cloud.pigx.common.feign.PigxFeignAutoConfiguration
diff --git a/pigx-common/pigx-common-gateway/pom.xml b/pigx-common/pigx-common-gateway/pom.xml
index 182eede61..1f2554b51 100644
--- a/pigx-common/pigx-common-gateway/pom.xml
+++ b/pigx-common/pigx-common-gateway/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-gateway
@@ -47,8 +47,12 @@
com.alibaba.cloud
- spring-cloud-alibaba-nacos-discovery
+ spring-cloud-starter-alibaba-nacos-discovery
compile
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/GrayLoadBalancerClientConfiguration.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/GrayLoadBalancerClientConfiguration.java
new file mode 100755
index 000000000..e7fd0051e
--- /dev/null
+++ b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/GrayLoadBalancerClientConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.gateway.configuration;
+
+import com.pig4cloud.pigx.common.gateway.filter.GrayReactiveLoadBalancerClientFilter;
+import com.pig4cloud.pigx.common.gateway.rule.GrayLoadBalancer;
+import com.pig4cloud.pigx.common.gateway.rule.VersionGrayLoadBalancer;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration;
+import org.springframework.cloud.gateway.config.LoadBalancerProperties;
+import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Mica ribbon rule auto configuration.
+ *
+ * @author L.cm
+ * @link https://github.com/lets-mica/mica
+ */
+@Configuration
+@EnableConfigurationProperties(LoadBalancerProperties.class)
+@ConditionalOnProperty(value = "gray.rule.enabled", havingValue = "true")
+@AutoConfigureBefore(GatewayReactiveLoadBalancerClientAutoConfiguration.class)
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+public class GrayLoadBalancerClientConfiguration {
+
+ @Bean
+ public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(GrayLoadBalancer grayLoadBalancer,
+ LoadBalancerProperties properties) {
+ return new GrayReactiveLoadBalancerClientFilter(properties, grayLoadBalancer);
+ }
+
+ @Bean
+ public GrayLoadBalancer grayLoadBalancer(DiscoveryClient discoveryClient) {
+ return new VersionGrayLoadBalancer(discoveryClient);
+ }
+}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/PigxRibbonRuleAutoConfiguration.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/PigxRibbonRuleAutoConfiguration.java
deleted file mode 100755
index 0c3aa42f2..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/configuration/PigxRibbonRuleAutoConfiguration.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.configuration;
-
-import com.alibaba.cloud.nacos.ribbon.NacosServer;
-import com.pig4cloud.pigx.common.gateway.filter.GrayLoadBalancerClientFilter;
-import com.pig4cloud.pigx.common.gateway.rule.AbstractDiscoveryEnabledRule;
-import com.pig4cloud.pigx.common.gateway.rule.MetadataAwareRule;
-import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.gateway.config.LoadBalancerProperties;
-import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
-import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
-import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
-import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Scope;
-
-/**
- * Mica ribbon rule auto configuration.
- *
- * @author L.cm
- * @link https://github.com/lets-mica/mica
- */
-@Configuration
-@RequiredArgsConstructor
-@ConditionalOnClass(NacosServer.class)
-@AutoConfigureBefore(RibbonClientConfiguration.class)
-@EnableConfigurationProperties(PigxRibbonRuleProperties.class)
-@ConditionalOnProperty(value = "ribbon.rule.enabled", matchIfMissing = true)
-public class PigxRibbonRuleAutoConfiguration {
-
- @Bean
- @ConditionalOnMissingBean
- @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public AbstractDiscoveryEnabledRule metadataAwareRule() {
- return new MetadataAwareRule();
- }
-
- @Bean
- @ConditionalOnMissingBean(LoadBalancerClient.class)
- public LoadBalancerClient loadBalancerClient(SpringClientFactory springClientFactory) {
- return new RibbonLoadBalancerClient(springClientFactory);
- }
-
- @Bean
- @ConditionalOnMissingBean(LoadBalancerClientFilter.class)
- public LoadBalancerClientFilter loadBalancerClientFilter(RibbonLoadBalancerClient client
- , LoadBalancerProperties properties) {
- return new GrayLoadBalancerClientFilter(client, properties);
- }
-
-}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayLoadBalancerClientFilter.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayLoadBalancerClientFilter.java
deleted file mode 100644
index 256e16a82..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayLoadBalancerClientFilter.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.filter;
-
-import org.springframework.cloud.client.ServiceInstance;
-import org.springframework.cloud.gateway.config.LoadBalancerProperties;
-import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
-import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
-import org.springframework.http.HttpHeaders;
-import org.springframework.web.server.ServerWebExchange;
-
-import java.net.URI;
-
-import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
-
-/**
- * @author Spencer Gibb
- * @author Tim Ysewyn
- */
-public class GrayLoadBalancerClientFilter extends LoadBalancerClientFilter {
- private final RibbonLoadBalancerClient loadBalancer;
-
- public GrayLoadBalancerClientFilter(RibbonLoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
- super(loadBalancer, properties);
- this.loadBalancer = loadBalancer;
- }
-
- @Override
- protected ServiceInstance choose(ServerWebExchange exchange) {
- HttpHeaders headers = exchange.getRequest().getHeaders();
- return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost(), headers);
- }
-
-}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayReactiveLoadBalancerClientFilter.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayReactiveLoadBalancerClientFilter.java
new file mode 100644
index 000000000..248f2e5ea
--- /dev/null
+++ b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/filter/GrayReactiveLoadBalancerClientFilter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.gateway.filter;
+
+import com.pig4cloud.pigx.common.gateway.rule.GrayLoadBalancer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools;
+import org.springframework.cloud.client.loadbalancer.reactive.DefaultResponse;
+import org.springframework.cloud.client.loadbalancer.reactive.Response;
+import org.springframework.cloud.gateway.config.LoadBalancerProperties;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
+import org.springframework.cloud.gateway.support.DelegatingServiceInstance;
+import org.springframework.cloud.gateway.support.NotFoundException;
+import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.net.URI;
+
+/**
+ * @author lengleng
+ * @date 2020/1/11
+ */
+@Slf4j
+public class GrayReactiveLoadBalancerClientFilter extends ReactiveLoadBalancerClientFilter {
+ private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150;
+ private LoadBalancerProperties properties;
+
+ private GrayLoadBalancer grayLoadBalancer;
+
+ public GrayReactiveLoadBalancerClientFilter(LoadBalancerProperties properties, GrayLoadBalancer grayLoadBalancer) {
+ super(null, properties);
+ this.properties = properties;
+ this.grayLoadBalancer = grayLoadBalancer;
+ }
+
+ @Override
+ public int getOrder() {
+ return LOAD_BALANCER_CLIENT_FILTER_ORDER;
+ }
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
+ String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
+ if (url == null
+ || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
+ return chain.filter(exchange);
+ }
+ // preserve the original url
+ ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
+
+ if (log.isTraceEnabled()) {
+ log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName()
+ + " url before: " + url);
+ }
+
+ return choose(exchange).doOnNext(response -> {
+
+ if (!response.hasServer()) {
+ throw NotFoundException.create(properties.isUse404(),
+ "Unable to find instance for " + url.getHost());
+ }
+
+ URI uri = exchange.getRequest().getURI();
+
+ // if the `lb:` mechanism was used, use `` as the default,
+ // if the loadbalancer doesn't provide one.
+ String overrideScheme = null;
+ if (schemePrefix != null) {
+ overrideScheme = url.getScheme();
+ }
+
+ DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(
+ response.getServer(), overrideScheme);
+
+ URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
+
+ if (log.isTraceEnabled()) {
+ log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
+ }
+ exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
+ }).then(chain.filter(exchange));
+ }
+
+ private Mono> choose(ServerWebExchange exchange) {
+ URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
+ ServiceInstance serviceInstance = grayLoadBalancer.choose(uri.getHost(),exchange.getRequest());
+ return Mono.just(new DefaultResponse(serviceInstance));
+ }
+}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/AbstractDiscoveryEnabledPredicate.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/AbstractDiscoveryEnabledPredicate.java
deleted file mode 100755
index ace152074..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/AbstractDiscoveryEnabledPredicate.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.predicate;
-
-import com.alibaba.cloud.nacos.ribbon.NacosServer;
-import com.netflix.loadbalancer.AbstractServerPredicate;
-import com.netflix.loadbalancer.PredicateKey;
-import org.springframework.http.HttpHeaders;
-import org.springframework.lang.Nullable;
-
-/**
- * 过滤服务
- *
- * @author L.cm
- */
-public abstract class AbstractDiscoveryEnabledPredicate extends AbstractServerPredicate {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean apply(@Nullable PredicateKey input) {
- return input != null
- && input.getServer() instanceof NacosServer
- && apply((NacosServer) input.getServer(), (HttpHeaders) input.getLoadBalancerKey());
- }
-
- /**
- * Returns whether the specific {@link NacosServer} matches this predicate.
- *
- * @param server the discovered server
- * @param headers 请求头
- * @return whether the server matches the predicate
- */
- abstract boolean apply(NacosServer server, HttpHeaders headers);
-}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/GrayMetadataAwarePredicate.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/GrayMetadataAwarePredicate.java
deleted file mode 100755
index 4f3be07a0..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/predicate/GrayMetadataAwarePredicate.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.predicate;
-
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.cloud.nacos.ribbon.NacosServer;
-import com.pig4cloud.pigx.common.core.constant.CommonConstants;
-import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
-import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpHeaders;
-
-import java.util.Map;
-
-/**
- * 基于 Metadata version 的服务筛选
- *
- * @author L.cm
- * @author lengleng
- */
-@Slf4j
-public class GrayMetadataAwarePredicate extends AbstractDiscoveryEnabledPredicate {
-
- @Override
- protected boolean apply(NacosServer server, HttpHeaders headers) {
- PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
-
- if (!ribbonProperties.isGrayEnabled()) {
- log.debug("gray closed,GrayMetadataAwarePredicate return true");
- return true;
- }
-
- final Map metadata = server.getMetadata();
- String version = metadata.get(CommonConstants.VERSION);
- // 判断Nacos服务是否有版本标签
- if (StrUtil.isBlank(version)) {
- log.debug("nacos server tag is blank ,GrayMetadataAwarePredicate return true");
- return true;
- }
-
- // 判断请求中是否有版本
- String target = headers.getFirst(CommonConstants.VERSION);
- if (StrUtil.isBlank(target)) {
- log.debug("request headers version is blank,GrayMetadataAwarePredicate return true");
- return true;
- }
-
- log.debug("请求版本:{} ,当前服务版本:{}", target, version);
- return target.equals(version);
- }
-
-}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/AbstractDiscoveryEnabledRule.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/AbstractDiscoveryEnabledRule.java
deleted file mode 100755
index 2d0a762f7..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/AbstractDiscoveryEnabledRule.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.rule;
-
-import com.google.common.base.Optional;
-import com.netflix.loadbalancer.*;
-import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
-import org.springframework.util.Assert;
-
-import java.util.List;
-
-/**
- * ribbon 路由规则
- *
- * @author L.cm
- */
-public abstract class AbstractDiscoveryEnabledRule extends PredicateBasedRule {
- private final CompositePredicate predicate;
-
- public AbstractDiscoveryEnabledRule(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate) {
- Assert.notNull(discoveryEnabledPredicate, "Parameter 'discoveryEnabledPredicate' can't be null");
- this.predicate = createCompositePredicate(discoveryEnabledPredicate, new AvailabilityPredicate(this, null));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public AbstractServerPredicate getPredicate() {
- return predicate;
- }
-
- @Override
- public Server choose(Object key) {
- ILoadBalancer lb = getLoadBalancer();
-
- List allServers = lb.getAllServers();
- // 过滤服务列表
- List serverList = filterServers(allServers);
-
- Optional server = getPredicate().chooseRoundRobinAfterFiltering(serverList, key);
- if (server.isPresent()) {
- return server.get();
- } else {
- return null;
- }
- }
-
- /**
- * 过滤服务
- *
- * @param serverList 服务列表
- * @return 服务列表
- */
- public abstract List filterServers(List serverList);
-
- private CompositePredicate createCompositePredicate(AbstractDiscoveryEnabledPredicate discoveryEnabledPredicate, AvailabilityPredicate availabilityPredicate) {
- return CompositePredicate.withPredicates(discoveryEnabledPredicate, availabilityPredicate)
- .build();
- }
-}
diff --git a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxDataflowJob.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/GrayLoadBalancer.java
similarity index 65%
rename from pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxDataflowJob.java
rename to pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/GrayLoadBalancer.java
index f43388f81..ad2efe0eb 100644
--- a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxDataflowJob.java
+++ b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/GrayLoadBalancer.java
@@ -15,26 +15,25 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.daemon.elastic.job;
+package com.pig4cloud.pigx.common.gateway.rule;
-import com.dangdang.ddframe.job.api.ShardingContext;
-import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
-
-import java.util.List;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.http.server.reactive.ServerHttpRequest;
/**
* @author lengleng
- * @date 2018/2/8
+ * @date 2020/1/12
+ *
+ * 灰度路由
*/
-public class PigxDataflowJob implements DataflowJob {
+public interface GrayLoadBalancer {
- @Override
- public List fetchData(ShardingContext shardingContext) {
- return null;
- }
-
- @Override
- public void processData(ShardingContext shardingContext, List list) {
-
- }
+ /**
+ * 根据serviceId 筛选可用服务
+ *
+ * @param serviceId 服务ID
+ * @param request 当前请求
+ * @return
+ */
+ ServiceInstance choose(String serviceId, ServerHttpRequest request);
}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/MetadataAwareRule.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/MetadataAwareRule.java
deleted file mode 100755
index 92eea034e..000000000
--- a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/MetadataAwareRule.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.gateway.rule;
-
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.system.HostInfo;
-import cn.hutool.system.SystemUtil;
-import com.netflix.loadbalancer.Server;
-import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
-import com.pig4cloud.pigx.common.gateway.predicate.AbstractDiscoveryEnabledPredicate;
-import com.pig4cloud.pigx.common.gateway.predicate.GrayMetadataAwarePredicate;
-import com.pig4cloud.pigx.common.gateway.support.PigxRibbonRuleProperties;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.util.PatternMatchUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * ribbon 路由规则器
- *
- * @author dream.lu
- */
-@Slf4j
-public class MetadataAwareRule extends AbstractDiscoveryEnabledRule {
-
- public MetadataAwareRule() {
- this(new GrayMetadataAwarePredicate());
- }
-
- public MetadataAwareRule(AbstractDiscoveryEnabledPredicate predicate) {
- super(predicate);
- }
-
- @Override
- public List filterServers(List serverList) {
- PigxRibbonRuleProperties ribbonProperties = SpringContextHolder.getBean(PigxRibbonRuleProperties.class);
- List priorIpPattern = ribbonProperties.getPriorIpPattern();
-
- if (ribbonProperties.isGrayEnabled()) {
- return serverList;
- }
-
- // 1. 查找是否有本机 ip
- HostInfo hostInfo = SystemUtil.getHostInfo();
- String hostIp = hostInfo.getAddress();
-
- // 优先的 ip 规则
- boolean hasPriorIpPattern = !priorIpPattern.isEmpty();
- String[] priorIpPatterns = priorIpPattern.toArray(new String[0]);
-
- List priorServerList = new ArrayList<>();
- for (Server server : serverList) {
- String host = server.getHost();
- // 2. 优先本地 ip 的服务
- if (!hasPriorIpPattern && ObjectUtil.equal(hostIp, host)) {
- log.debug("{} 不存在优先配置,本地路由条件", hostIp);
- return Collections.singletonList(server);
- }
- // 3. 优先的 ip 服务
- if (hasPriorIpPattern && PatternMatchUtils.simpleMatch(priorIpPatterns, host)) {
- log.debug("{} 存在优先配置,ribbon 强制路由", priorIpPatterns);
- priorServerList.add(server);
- }
- }
-
- // 4. 如果优先的有数据直接返回
- if (!priorServerList.isEmpty()) {
- return priorServerList;
- }
-
- return Collections.unmodifiableList(serverList);
- }
-
-}
diff --git a/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/VersionGrayLoadBalancer.java b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/VersionGrayLoadBalancer.java
new file mode 100644
index 000000000..07c69a1e9
--- /dev/null
+++ b/pigx-common/pigx-common-gateway/src/main/java/com/pig4cloud/pigx/common/gateway/rule/VersionGrayLoadBalancer.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.gateway.rule;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.pig4cloud.pigx.common.core.constant.CommonConstants;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.gateway.support.NotFoundException;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author lengleng
+ * @date 2020/1/12
+ *
+ * 基于客户端版本号灰度路由
+ */
+@Slf4j
+@AllArgsConstructor
+public class VersionGrayLoadBalancer implements GrayLoadBalancer {
+ private DiscoveryClient discoveryClient;
+
+
+ /**
+ * 根据serviceId 筛选可用服务
+ *
+ * @param serviceId 服务ID
+ * @param request 当前请求
+ * @return
+ */
+ @Override
+ public ServiceInstance choose(String serviceId, ServerHttpRequest request) {
+ List instances = discoveryClient.getInstances(serviceId);
+
+ //注册中心无实例 抛出异常
+ if (CollUtil.isEmpty(instances)) {
+ log.warn("No instance available for {}", serviceId);
+ throw new NotFoundException("No instance available for " + serviceId);
+ }
+
+ // 获取请求version,无则随机返回可用实例
+ String reqVersion = request.getHeaders().getFirst(CommonConstants.VERSION);
+ if (StrUtil.isBlank(reqVersion)) {
+ return instances.get(RandomUtil.randomInt(instances.size()));
+ }
+
+ // 遍历可以实例元数据,若匹配则返回此实例
+ for (ServiceInstance instance : instances) {
+ Map metadata = instance.getMetadata();
+ String targetVersion = MapUtil.getStr(metadata, CommonConstants.VERSION);
+ if (reqVersion.equalsIgnoreCase(targetVersion)) {
+ log.debug("gray requst match success :{} {}", reqVersion, instance);
+ return instance;
+ }
+ }
+ return instances.get(RandomUtil.randomInt(instances.size()));
+ }
+}
diff --git a/pigx-common/pigx-common-gray/pom.xml b/pigx-common/pigx-common-gray/pom.xml
new file mode 100644
index 000000000..c52592d72
--- /dev/null
+++ b/pigx-common/pigx-common-gray/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+
+ 4.0.0
+
+ com.pig4cloud
+ pigx-common
+ 3.9.0-SNAPSHOT
+
+
+ pigx-common-gray
+ jar
+
+ pigx 灰度路由
+
+
+
+ com.pig4cloud
+ pigx-common-core
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+ io.github.openfeign
+ feign-core
+
+
+
diff --git a/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/GrayRibbonLoadBalancerConfiguration.java b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/GrayRibbonLoadBalancerConfiguration.java
new file mode 100644
index 000000000..5d686f858
--- /dev/null
+++ b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/GrayRibbonLoadBalancerConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.gray;
+
+import com.pig4cloud.pigx.common.gray.feign.GrayFeignRequestInterceptor;
+import com.pig4cloud.pigx.common.gray.rule.GrayRibbonLoadBalancerRule;
+import feign.RequestInterceptor;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+/**
+ * @author lengleng
+ * @date 2020/1/12
+ */
+@Configuration
+@ConditionalOnProperty(value = "gray.rule.enabled", havingValue = "true")
+public class GrayRibbonLoadBalancerConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public GrayRibbonLoadBalancerRule ribbonLoadBalancerRule() {
+ return new GrayRibbonLoadBalancerRule();
+ }
+
+ @Bean
+ public RequestInterceptor grayFeignRequestInterceptor() {
+ return new GrayFeignRequestInterceptor();
+ }
+}
diff --git a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxSimpleJob2.java b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/feign/GrayFeignRequestInterceptor.java
similarity index 52%
rename from pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxSimpleJob2.java
rename to pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/feign/GrayFeignRequestInterceptor.java
index 11d44804c..1d261750f 100644
--- a/pigx-visual/pigx-daemon-elastic-job/src/main/java/com/pig4cloud/pigx/daemon/elastic/job/PigxSimpleJob2.java
+++ b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/feign/GrayFeignRequestInterceptor.java
@@ -15,26 +15,36 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.daemon.elastic.job;
+package com.pig4cloud.pigx.common.gray.feign;
-import com.dangdang.ddframe.job.api.ShardingContext;
-import com.dangdang.ddframe.job.api.simple.SimpleJob;
+import cn.hutool.core.util.StrUtil;
+import com.pig4cloud.pigx.common.core.constant.CommonConstants;
+import com.pig4cloud.pigx.common.core.util.WebUtils;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
/**
* @author lengleng
- * @date 2018/2/7
- * 测试Job
+ * @date 2020/1/12
+ *
+ * feign 请求VERSION 传递
*/
@Slf4j
-public class PigxSimpleJob2 implements SimpleJob {
+public class GrayFeignRequestInterceptor implements RequestInterceptor {
/**
- * 业务执行逻辑
+ * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
*
- * @param shardingContext 分片信息
+ * @param template
*/
@Override
- public void execute(ShardingContext shardingContext) {
- log.info("第二个执行了:{}", shardingContext);
+ public void apply(RequestTemplate template) {
+ String reqVersion = WebUtils.getRequest() != null
+ ? WebUtils.getRequest().getHeader(CommonConstants.VERSION) : null;
+
+ if (StrUtil.isNotBlank(reqVersion)) {
+ log.debug("feign gray add header version :{}", reqVersion);
+ template.header(CommonConstants.VERSION, reqVersion);
+ }
}
}
diff --git a/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/rule/GrayRibbonLoadBalancerRule.java b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/rule/GrayRibbonLoadBalancerRule.java
new file mode 100644
index 000000000..a4c553515
--- /dev/null
+++ b/pigx-common/pigx-common-gray/src/main/java/com/pig4cloud/pigx/common/gray/rule/GrayRibbonLoadBalancerRule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.gray.rule;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.cloud.nacos.ribbon.NacosServer;
+import com.netflix.client.config.IClientConfig;
+import com.netflix.loadbalancer.AbstractLoadBalancerRule;
+import com.netflix.loadbalancer.ILoadBalancer;
+import com.netflix.loadbalancer.Server;
+import com.pig4cloud.pigx.common.core.constant.CommonConstants;
+import com.pig4cloud.pigx.common.core.util.WebUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author lengleng
+ * @date 2020/1/12
+ */
+@Slf4j
+public class GrayRibbonLoadBalancerRule extends AbstractLoadBalancerRule {
+ @Override
+ public void initWithNiwsConfig(IClientConfig iClientConfig) {
+ }
+
+ @Override
+ public Server choose(Object key) {
+ return choose(getLoadBalancer(), key);
+ }
+
+
+ public Server choose(ILoadBalancer lb, Object key) {
+ List reachableServers = lb.getReachableServers();
+
+ //注册中心无可用实例 抛出异常
+ if (CollUtil.isEmpty(reachableServers)) {
+ log.warn("No instance available for {}", key);
+ return null;
+ }
+
+ // 获取请求version,无则随机返回可用实例
+ String reqVersion = WebUtils.getRequest() != null
+ ? WebUtils.getRequest().getHeader(CommonConstants.VERSION) : null;
+ if (StrUtil.isBlank(reqVersion)) {
+ return reachableServers.get(RandomUtil.randomInt(reachableServers.size()));
+ }
+
+ // 遍历可以实例元数据,若匹配则返回此实例
+ for (Server server : reachableServers) {
+ NacosServer nacosServer = (NacosServer) server;
+ Map metadata = nacosServer.getMetadata();
+ String targetVersion = MapUtil.getStr(metadata, CommonConstants.VERSION);
+ if (reqVersion.equalsIgnoreCase(targetVersion)) {
+ log.debug("gray requst match success :{} {}", reqVersion, nacosServer);
+ return nacosServer;
+ }
+ }
+ return reachableServers.get(RandomUtil.randomInt(reachableServers.size()));
+ }
+
+}
diff --git a/pigx-common/pigx-common-gray/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-gray/src/main/resources/META-INF/spring.factories
new file mode 100644
index 000000000..0dc0c1d27
--- /dev/null
+++ b/pigx-common/pigx-common-gray/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.pig4cloud.pigx.common.gray.GrayRibbonLoadBalancerConfiguration
\ No newline at end of file
diff --git a/pigx-common/pigx-common-job/pom.xml b/pigx-common/pigx-common-job/pom.xml
index 2db6a36fd..b4866bf33 100644
--- a/pigx-common/pigx-common-job/pom.xml
+++ b/pigx-common/pigx-common-job/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-job
@@ -33,24 +33,6 @@
pigx 定时任务
-
-
- com.dangdang
- elastic-job-lite-core
- ${elastic-job-lite.version}
-
-
- com.zaxxer
- HikariCP-java7
-
-
-
-
-
- com.dangdang
- elastic-job-lite-spring
- ${elastic-job-lite.version}
-
com.xuxueli
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/ElasticJobAutoConfiguration.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/ElasticJobAutoConfiguration.java
deleted file mode 100755
index 97afd9bb7..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/ElasticJobAutoConfiguration.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job;
-
-import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
-import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
-import com.pig4cloud.pigx.common.job.jobinit.DataflowJobInitialization;
-import com.pig4cloud.pigx.common.job.jobinit.ScriptJobInitialization;
-import com.pig4cloud.pigx.common.job.jobinit.SimpleJobInitialization;
-import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 任务初配置入口类
- */
-@Configuration
-@EnableAutoConfiguration
-@EnableConfigurationProperties(ElasticJobProperties.class)
-public class ElasticJobAutoConfiguration {
-
- /**
- * 默认注册中心
- */
- public static final String DEFAULT_REGISTRY_CENTER_NAME = "elasticJobRegistryCenter";
-
- @Autowired
- private ElasticJobProperties elasticJobProperties;
-
- @Bean(name = DEFAULT_REGISTRY_CENTER_NAME, initMethod = "init")
- @ConditionalOnMissingBean
- public ZookeeperRegistryCenter elasticJobRegistryCenter() {
- ElasticJobProperties.ZkConfiguration regCenterProperties = elasticJobProperties.getZookeeper();
- ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration(regCenterProperties.getServerLists(), regCenterProperties.getNamespace());
- zookeeperConfiguration.setBaseSleepTimeMilliseconds(regCenterProperties.getBaseSleepTimeMilliseconds());
- zookeeperConfiguration.setConnectionTimeoutMilliseconds(regCenterProperties.getConnectionTimeoutMilliseconds());
- zookeeperConfiguration.setMaxSleepTimeMilliseconds(regCenterProperties.getMaxSleepTimeMilliseconds());
- zookeeperConfiguration.setSessionTimeoutMilliseconds(regCenterProperties.getSessionTimeoutMilliseconds());
- zookeeperConfiguration.setMaxRetries(regCenterProperties.getMaxRetries());
- zookeeperConfiguration.setDigest(regCenterProperties.getDigest());
- return new ZookeeperRegistryCenter(zookeeperConfiguration);
- }
-
- @Bean(initMethod = "init")
- @ConditionalOnMissingBean
- @ConditionalOnBean(ZookeeperRegistryCenter.class)
- public SimpleJobInitialization simpleJobInitialization() {
- return new SimpleJobInitialization(elasticJobProperties.getSimples());
- }
-
- @Bean(initMethod = "init")
- @ConditionalOnMissingBean
- @ConditionalOnBean(ZookeeperRegistryCenter.class)
- public DataflowJobInitialization dataflowJobInitialization() {
- return new DataflowJobInitialization(elasticJobProperties.getDataflows());
- }
-
- @Bean(initMethod = "init")
- @ConditionalOnMissingBean
- @ConditionalOnBean(ZookeeperRegistryCenter.class)
- public ScriptJobInitialization scriptJobInitialization() {
- return new ScriptJobInitialization(elasticJobProperties.getScripts());
- }
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/XxlJobAutoConfiguration.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/XxlJobAutoConfiguration.java
index 7e81e44bd..8f6361b95 100644
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/XxlJobAutoConfiguration.java
+++ b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/XxlJobAutoConfiguration.java
@@ -35,11 +35,12 @@ import org.springframework.context.annotation.Configuration;
@ComponentScan("com.pig4cloud.pigx.common.job.properties")
public class XxlJobAutoConfiguration {
- @Bean(initMethod = "start", destroyMethod = "destroy")
+ @Bean
public XxlJobSpringExecutor xxlJobSpringExecutor(XxlJobProperties xxlJobProperties) {
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdmin().getAddresses());
- xxlJobSpringExecutor.setAppName(xxlJobProperties.getExecutor().getAppName());
+ xxlJobSpringExecutor.setAppname(xxlJobProperties.getExecutor().getAppname());
+ xxlJobSpringExecutor.setAddress(xxlJobProperties.getExecutor().getAddress());
xxlJobSpringExecutor.setIp(xxlJobProperties.getExecutor().getIp());
xxlJobSpringExecutor.setPort(xxlJobProperties.getExecutor().getPort());
xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getExecutor().getAccessToken());
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java
deleted file mode 100755
index b9b81b5d8..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/AbstractJobInitialization.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job.jobinit;
-
-import com.dangdang.ddframe.job.api.ElasticJob;
-import com.dangdang.ddframe.job.api.JobType;
-import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
-import com.dangdang.ddframe.job.api.simple.SimpleJob;
-import com.dangdang.ddframe.job.config.JobCoreConfiguration;
-import com.dangdang.ddframe.job.config.JobTypeConfiguration;
-import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
-import com.dangdang.ddframe.job.executor.handler.JobProperties.JobPropertiesEnum;
-import com.dangdang.ddframe.job.lite.api.listener.AbstractDistributeOnceElasticJobListener;
-import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
-import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
-import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
-import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
-import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
-import lombok.SneakyThrows;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.util.CollectionUtils;
-
-import javax.sql.DataSource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import static com.pig4cloud.pigx.common.job.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 任务初始化基类
- */
-public abstract class AbstractJobInitialization implements ApplicationContextAware {
-
- protected ApplicationContext applicationContext;
-
- @Override
- @SneakyThrows
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
-
- /**
- * 初始化任务
- *
- * @param jobName 任务名称
- * @param jobType 任务类型
- * @param configuration 配置
- */
- protected void initJob(String jobName, JobType jobType, ElasticJobProperties.JobConfiguration configuration) {
- //向spring容器中注册作业任务
- ElasticJob elasticJob = registerElasticJob(jobName, configuration.getJobClass(), jobType);
- //获取注册中心
- ZookeeperRegistryCenter regCenter = getZookeeperRegistryCenter(configuration.getRegistryCenterRef());
- //构建核心配置
- JobCoreConfiguration jobCoreConfiguration = getJobCoreConfiguration(jobName, configuration);
- //获取作业类型配置
- JobTypeConfiguration jobTypeConfiguration = getJobTypeConfiguration(jobName, jobCoreConfiguration);
- //获取Lite作业配置
- LiteJobConfiguration liteJobConfiguration = getLiteJobConfiguration(jobTypeConfiguration, configuration);
- //获取作业事件追踪的数据源配置
- JobEventRdbConfiguration jobEventRdbConfiguration = getJobEventRdbConfiguration(configuration.getEventTraceRdbDataSource());
- //获取作业监听器
- ElasticJobListener[] elasticJobListeners = creatElasticJobListeners(configuration.getListener());
- elasticJobListeners = null == elasticJobListeners ? new ElasticJobListener[0] : elasticJobListeners;
- //注册作业
- if (null == jobEventRdbConfiguration) {
- new SpringJobScheduler(elasticJob, regCenter, liteJobConfiguration, elasticJobListeners).init();
- } else {
- new SpringJobScheduler(elasticJob, regCenter, liteJobConfiguration, jobEventRdbConfiguration, elasticJobListeners).init();
- }
- }
-
- /**
- * 获取作业类型配置
- *
- * @param jobName 任务名称
- * @param jobCoreConfiguration 任务核心配置
- * @return JobTypeConfiguration
- */
- public abstract JobTypeConfiguration getJobTypeConfiguration(String jobName, JobCoreConfiguration jobCoreConfiguration);
-
- /**
- * 获取作业任务实例
- *
- * @param jobName 任务名称
- * @param jobType 任务类型
- * @param strClass 任务类全路径
- * @return ElasticJob
- */
- private ElasticJob registerElasticJob(String jobName, String strClass, JobType jobType) {
- switch (jobType) {
- case SIMPLE:
- return registerBean(jobName, strClass, SimpleJob.class);
- case DATAFLOW:
- return registerBean(jobName, strClass, DataflowJob.class);
- default:
- return null;
- }
- }
-
- /**
- * 获取注册中心
- *
- * @param registryCenterRef 注册中心引用
- * @return ZookeeperRegistryCenter
- */
- private ZookeeperRegistryCenter getZookeeperRegistryCenter(String registryCenterRef) {
- if (StringUtils.isBlank(registryCenterRef)) {
- registryCenterRef = DEFAULT_REGISTRY_CENTER_NAME;
- }
- if (!applicationContext.containsBean(registryCenterRef)) {
- throw new RuntimeException("not exist ZookeeperRegistryCenter [" + registryCenterRef + "] !");
- }
- return applicationContext.getBean(registryCenterRef, ZookeeperRegistryCenter.class);
- }
-
- /**
- * 获取作业事件追踪的数据源配置
- *
- * @param eventTraceRdbDataSource 作业事件追踪的数据源Bean引用
- * @return JobEventRdbConfiguration
- */
- private JobEventRdbConfiguration getJobEventRdbConfiguration(String eventTraceRdbDataSource) {
- if (StringUtils.isBlank(eventTraceRdbDataSource)) {
- return null;
- }
- if (!applicationContext.containsBean(eventTraceRdbDataSource)) {
- throw new RuntimeException("not exist datasource [" + eventTraceRdbDataSource + "] !");
- }
- DataSource dataSource = (DataSource) applicationContext.getBean(eventTraceRdbDataSource);
- return new JobEventRdbConfiguration(dataSource);
- }
-
-
- /**
- * 构建Lite作业
- *
- * @param jobTypeConfiguration 任务类型
- * @param jobConfiguration 任务配置
- * @return LiteJobConfiguration
- */
- private LiteJobConfiguration getLiteJobConfiguration(JobTypeConfiguration jobTypeConfiguration, ElasticJobProperties.JobConfiguration jobConfiguration) {
- //构建Lite作业
- return LiteJobConfiguration.newBuilder(Objects.requireNonNull(jobTypeConfiguration))
- .monitorExecution(jobConfiguration.isMonitorExecution())
- .monitorPort(jobConfiguration.getMonitorPort())
- .maxTimeDiffSeconds(jobConfiguration.getMaxTimeDiffSeconds())
- .jobShardingStrategyClass(jobConfiguration.getJobShardingStrategyClass())
- .reconcileIntervalMinutes(jobConfiguration.getReconcileIntervalMinutes())
- .disabled(jobConfiguration.isDisabled())
- .overwrite(jobConfiguration.isOverwrite()).build();
- }
-
- /**
- * 构建任务核心配置
- *
- * @param jobName 任务执行名称
- * @param jobConfiguration 任务配置
- * @return JobCoreConfiguration
- */
- protected JobCoreConfiguration getJobCoreConfiguration(String jobName, ElasticJobProperties.JobConfiguration jobConfiguration) {
- JobCoreConfiguration.Builder builder = JobCoreConfiguration.newBuilder(jobName, jobConfiguration.getCron(), jobConfiguration.getShardingTotalCount())
- .shardingItemParameters(jobConfiguration.getShardingItemParameters())
- .jobParameter(jobConfiguration.getJobParameter())
- .failover(jobConfiguration.isFailover())
- .misfire(jobConfiguration.isMisfire())
- .description(jobConfiguration.getDescription());
- if (StringUtils.isNotBlank(jobConfiguration.getJobExceptionHandler())) {
- builder.jobProperties(JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), jobConfiguration.getJobExceptionHandler());
- }
- if (StringUtils.isNotBlank(jobConfiguration.getExecutorServiceHandler())) {
- builder.jobProperties(JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), jobConfiguration.getExecutorServiceHandler());
- }
- return builder.build();
- }
-
- /**
- * 获取监听器
- *
- * @param listener 监听器配置
- * @return ElasticJobListener[]
- */
- private ElasticJobListener[] creatElasticJobListeners(ElasticJobProperties.JobConfiguration.Listener listener) {
-
- if (null == listener) {
- return null;
- }
-
- List elasticJobListeners = new ArrayList<>(2);
-
- //注册每台作业节点均执行的监听
- ElasticJobListener elasticJobListener = registerBean(listener.getListenerClass(), listener.getListenerClass(), ElasticJobListener.class);
- if (null != elasticJobListener) {
- elasticJobListeners.add(elasticJobListener);
- }
-
- //注册分布式监听者
- AbstractDistributeOnceElasticJobListener distributedListener = registerBean(listener.getDistributedListenerClass(), listener.getDistributedListenerClass(),
- AbstractDistributeOnceElasticJobListener.class, listener.getStartedTimeoutMilliseconds(), listener.getCompletedTimeoutMilliseconds());
- if (null != distributedListener) {
- elasticJobListeners.add(distributedListener);
- }
-
- if (CollectionUtils.isEmpty(elasticJobListeners)) {
- return null;
- }
-
- //集合转数组
- ElasticJobListener[] elasticJobListenerArray = new ElasticJobListener[elasticJobListeners.size()];
- for (int i = 0; i < elasticJobListeners.size(); i++) {
- elasticJobListenerArray[i] = elasticJobListeners.get(i);
- }
- return elasticJobListenerArray;
- }
-
- /**
- * 向spring容器中注册bean
- *
- * @param beanName bean名字
- * @param strClass 类全路径
- * @param tClass 类类型
- * @param constructorArgValue 构造函数参数
- * @param 泛型
- * @return T
- */
- protected T registerBean(String beanName, String strClass, Class tClass, Object... constructorArgValue) {
-
- //判断是否配置了监听者
- if (StringUtils.isBlank(strClass)) {
- return null;
- }
-
- if (StringUtils.isBlank(beanName)) {
- beanName = strClass;
- }
-
- //判断监听者是否已经在spring容器中存在
- if (applicationContext.containsBean(beanName)) {
- return applicationContext.getBean(beanName, tClass);
- }
-
- //不存在则创建并注册到Spring容器中
- BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(strClass);
- beanDefinitionBuilder.setScope(BeanDefinition.SCOPE_PROTOTYPE);
- //设置参数
- for (Object argValue : constructorArgValue) {
- beanDefinitionBuilder.addConstructorArgValue(argValue);
- }
- getDefaultListableBeanFactory().registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
- return applicationContext.getBean(beanName, tClass);
- }
-
- /**
- * 获取beanFactory
- *
- * @return DefaultListableBeanFactory
- */
- private DefaultListableBeanFactory getDefaultListableBeanFactory() {
- return (DefaultListableBeanFactory) ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
- }
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/DataflowJobInitialization.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/DataflowJobInitialization.java
deleted file mode 100755
index 66af592bb..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/DataflowJobInitialization.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job.jobinit;
-
-import com.dangdang.ddframe.job.config.JobCoreConfiguration;
-import com.dangdang.ddframe.job.config.JobTypeConfiguration;
-import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
-import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
-
-import java.util.Map;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 流式任务初始
- */
-public class DataflowJobInitialization extends AbstractJobInitialization {
-
- private Map dataflowConfigurationMap;
-
- public DataflowJobInitialization(final Map dataflowConfigurationMap) {
- this.dataflowConfigurationMap = dataflowConfigurationMap;
- }
-
- public void init() {
- for (String jobName : dataflowConfigurationMap.keySet()) {
- ElasticJobProperties.DataflowConfiguration configuration = dataflowConfigurationMap.get(jobName);
- initJob(jobName, configuration.getJobType(), configuration);
- }
- }
-
- @Override
- public JobTypeConfiguration getJobTypeConfiguration(String jobName, JobCoreConfiguration jobCoreConfiguration) {
- ElasticJobProperties.DataflowConfiguration configuration = dataflowConfigurationMap.get(jobName);
- return new DataflowJobConfiguration(jobCoreConfiguration, configuration.getJobClass(), configuration.isStreamingProcess());
- }
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/ScriptJobInitialization.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/ScriptJobInitialization.java
deleted file mode 100755
index c7cbd5890..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/ScriptJobInitialization.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job.jobinit;
-
-import com.dangdang.ddframe.job.config.JobCoreConfiguration;
-import com.dangdang.ddframe.job.config.JobTypeConfiguration;
-import com.dangdang.ddframe.job.config.script.ScriptJobConfiguration;
-import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
-
-import java.util.Map;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 脚本任务初始
- */
-public class ScriptJobInitialization extends AbstractJobInitialization {
-
- private Map scriptConfigurationMap;
-
- public ScriptJobInitialization(final Map scriptConfigurationMap) {
- this.scriptConfigurationMap = scriptConfigurationMap;
- }
-
- public void init() {
- for (String jobName : scriptConfigurationMap.keySet()) {
- ElasticJobProperties.ScriptConfiguration configuration = scriptConfigurationMap.get(jobName);
- initJob(jobName, configuration.getJobType(), configuration);
- }
- }
-
- @Override
- public JobTypeConfiguration getJobTypeConfiguration(String jobName, JobCoreConfiguration jobCoreConfiguration) {
- ElasticJobProperties.ScriptConfiguration configuration = scriptConfigurationMap.get(jobName);
- return new ScriptJobConfiguration(jobCoreConfiguration, configuration.getScriptCommandLine());
- }
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/SimpleJobInitialization.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/SimpleJobInitialization.java
deleted file mode 100755
index fbbead7cb..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/jobinit/SimpleJobInitialization.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job.jobinit;
-
-import com.dangdang.ddframe.job.config.JobCoreConfiguration;
-import com.dangdang.ddframe.job.config.JobTypeConfiguration;
-import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
-import com.pig4cloud.pigx.common.job.properties.ElasticJobProperties;
-
-import java.util.Map;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 简单任务初始
- */
-public class SimpleJobInitialization extends AbstractJobInitialization {
-
- private Map simpleConfigurationMap;
-
- public SimpleJobInitialization(final Map simpleConfigurationMap) {
- this.simpleConfigurationMap = simpleConfigurationMap;
- }
-
- public void init() {
- for (String jobName : simpleConfigurationMap.keySet()) {
- ElasticJobProperties.SimpleConfiguration configuration = simpleConfigurationMap.get(jobName);
- initJob(jobName, configuration.getJobType(), configuration);
- }
- }
-
- @Override
- public JobTypeConfiguration getJobTypeConfiguration(String jobName, JobCoreConfiguration jobCoreConfiguration) {
- ElasticJobProperties.SimpleConfiguration configuration = simpleConfigurationMap.get(jobName);
- return new SimpleJobConfiguration(jobCoreConfiguration, configuration.getJobClass());
- }
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/ElasticJobProperties.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/ElasticJobProperties.java
deleted file mode 100755
index 7dbbab4d7..000000000
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/ElasticJobProperties.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.job.properties;
-
-import com.dangdang.ddframe.job.api.JobType;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import static com.pig4cloud.pigx.common.job.ElasticJobAutoConfiguration.DEFAULT_REGISTRY_CENTER_NAME;
-
-
-/**
- * @author lengleng
- * @date 2018/7/24
- * 任务配置类
- */
-@Getter
-@Setter
-@ConfigurationProperties(prefix = "spring.elasticjob")
-public class ElasticJobProperties {
-
- /**
- * 注册中心
- */
- private ZkConfiguration zookeeper;
-
- /**
- * 简单作业配置
- */
- private Map simples = new LinkedHashMap<>();
-
- /**
- * 流式作业配置
- */
- private Map dataflows = new LinkedHashMap<>();
-
- /**
- * 脚本作业配置
- */
- private Map scripts = new LinkedHashMap<>();
-
- @Getter
- @Setter
- public static class ZkConfiguration {
-
- /**
- * 连接Zookeeper服务器的列表
- * 包括IP地址和端口号
- * 多个地址用逗号分隔
- * 如: host1:2181,host2:2181
- */
- private String serverLists;
-
- /**
- * Zookeeper的命名空间
- */
- private String namespace;
-
- /**
- * 等待重试的间隔时间的初始值
- * 单位:毫秒
- */
- private int baseSleepTimeMilliseconds = 1000;
-
- /**
- * 等待重试的间隔时间的最大值
- * 单位:毫秒
- */
- private int maxSleepTimeMilliseconds = 3000;
-
- /**
- * 最大重试次数
- */
- private int maxRetries = 3;
-
- /**
- * 连接超时时间
- * 单位:毫秒
- */
- private int connectionTimeoutMilliseconds = 15000;
-
- /**
- * 会话超时时间
- * 单位:毫秒
- */
- private int sessionTimeoutMilliseconds = 60000;
-
- /**
- * 连接Zookeeper的权限令牌
- * 缺省为不需要权限验
- */
- private String digest;
-
- }
-
- @Getter
- @Setter
- public static class SimpleConfiguration extends JobConfiguration {
- /**
- * 作业类型
- */
- private final JobType jobType = JobType.SIMPLE;
- }
-
- @Getter
- @Setter
- public static class DataflowConfiguration extends JobConfiguration {
- /**
- * 作业类型
- */
- private final JobType jobType = JobType.DATAFLOW;
- /**
- * 是否流式处理数据
- * 如果流式处理数据, 则fetchData不返回空结果将持续执行作业
- * 如果非流式处理数据, 则处理数据完成后作业结束
- */
- private boolean streamingProcess = false;
- }
-
- @Getter
- @Setter
- public static class ScriptConfiguration extends JobConfiguration {
- /**
- * 作业类型
- */
- private final JobType jobType = JobType.SCRIPT;
- /**
- * 脚本型作业执行命令行
- */
- private String scriptCommandLine;
- }
-
- @Getter
- @Setter
- public static class JobConfiguration {
-
- /**
- * 作业实现类,需实现ElasticJob接口
- */
- private String jobClass;
- /**
- * 注册中心Bean的引用,需引用reg:zookeeper的声明
- */
- private String registryCenterRef = DEFAULT_REGISTRY_CENTER_NAME;
- /**
- * cron表达式,用于控制作业触发时间
- */
- private String cron;
- /**
- * 作业分片总数
- */
- private int shardingTotalCount = 1;
- /**
- * 分片序列号和参数用等号分隔,多个键值对用逗号分隔
- * 分片序列号从0开始,不可大于或等于作业分片总数
- * 如:0=a,1=b,2=c
- */
- private String shardingItemParameters = "0=A";
- /**
- * 作业实例主键,同IP可运行实例主键不同, 但名称相同的多个作业实例
- */
- private String jobInstanceId;
- /**
- * 作业自定义参数
- * 作业自定义参数,可通过传递该参数为作业调度的业务方法传参,用于实现带参数的作业
- * 例:每次获取的数据量、作业实例从数据库读取的主键等
- */
- private String jobParameter;
- /**
- * 监控作业运行时状态
- * 每次作业执行时间和间隔时间均非常短的情况,建议不监控作业运行时状态以提升效率。
- * 因为是瞬时状态,所以无必要监控。请用户自行增加数据堆积监控。并且不能保证数据重复选取,应在作业中实现幂等性。
- * 每次作业执行时间和间隔时间均较长的情况,建议监控作业运行时状态,可保证数据不会重复选取。
- */
- private boolean monitorExecution = true;
- /**
- * 作业监控端口
- * 建议配置作业监控端口, 方便开发者dump作业信息。
- * 使用方法: echo “dump” | nc 127.0.0.1 9888
- */
- private int monitorPort = -1;
- /**
- * 最大允许的本机与注册中心的时间误差秒数
- * 如果时间误差超过配置秒数则作业启动时将抛异常
- * 配置为-1表示不校验时间误差
- */
- private int maxTimeDiffSeconds = -1;
- /**
- * 是否开启失效转移
- */
- private boolean failover = false;
- /**
- * 是否开启错过任务重新执行
- */
- private boolean misfire = true;
- /**
- * 作业分片策略实现类全路径
- * 默认使用平均分配策略
- * 详情参见:作业分片策略http://elasticjob.io/docs/elastic-job-lite/02-guide/job-sharding-strategy
- */
- private String jobShardingStrategyClass;
- /**
- * 作业描述信息
- */
- private String description;
- /**
- * 作业是否禁止启动
- * 可用于部署作业时,先禁止启动,部署结束后统一启动
- */
- private boolean disabled = false;
- /**
- * 本地配置是否可覆盖注册中心配置
- * 如果可覆盖,每次启动作业都以本地配置为准
- */
- private boolean overwrite = true;
- /**
- * 扩展异常处理类
- */
- private String jobExceptionHandler;
- /**
- * 扩展作业处理线程池类
- */
- private String executorServiceHandler;
- /**
- * 修复作业服务器不一致状态服务调度间隔时间,配置为小于1的任意值表示不执行修复
- * 单位:分钟
- */
- private int reconcileIntervalMinutes = 10;
- /**
- * 作业事件追踪的数据源Bean引用
- */
- private String eventTraceRdbDataSource;
-
- /**
- * 监听器
- */
- private Listener listener;
-
- @Getter
- @Setter
- public static class Listener {
- /**
- * 每台作业节点均执行的监听
- * 若作业处理作业服务器的文件,处理完成后删除文件,可考虑使用每个节点均执行清理任务。
- * 此类型任务实现简单,且无需考虑全局分布式任务是否完成,请尽量使用此类型监听器。
- *
- * 注意:类必须继承com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener
- */
- String listenerClass;
-
- /**
- * 分布式场景中仅单一节点执行的监听
- * 若作业处理数据库数据,处理完成后只需一个节点完成数据清理任务即可。
- * 此类型任务处理复杂,需同步分布式环境下作业的状态同步,提供了超时设置来避免作业不同步导致的死锁,请谨慎使用。
- *
- * 注意:类必须继承com.dangdang.ddframe.job.lite.api.listener.AbstractDistributeOnceElasticJobListener
- */
- String distributedListenerClass;
-
- /**
- * 最后一个作业执行前的执行方法的超时时间
- * 单位:毫秒
- */
- Long startedTimeoutMilliseconds = Long.MAX_VALUE;
-
- /**
- * 最后一个作业执行后的执行方法的超时时间
- * 单位:毫秒
- */
- Long completedTimeoutMilliseconds = Long.MAX_VALUE;
- }
- }
-
-}
diff --git a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/XxlExecutorProperties.java b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/XxlExecutorProperties.java
index 09f56cec7..405998b14 100644
--- a/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/XxlExecutorProperties.java
+++ b/pigx-common/pigx-common-job/src/main/java/com/pig4cloud/pigx/common/job/properties/XxlExecutorProperties.java
@@ -28,7 +28,14 @@ public class XxlExecutorProperties {
/**
* 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
*/
- private String appName = "xxl-job-executor";
+ private String appname = "xxl-job-executor";
+
+ /**
+ * 服务注册地址,优先使用该配置作为注册地址
+ * 为空时使用内嵌服务 ”IP:PORT“ 作为注册地址
+ * 从而更灵活的支持容器类型执行器动态IP和动态映射端口问题
+ */
+ private String address;
/**
* 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP
diff --git a/pigx-common/pigx-common-log/pom.xml b/pigx-common/pigx-common-log/pom.xml
index b73fb8640..0e1cb55a3 100644
--- a/pigx-common/pigx-common-log/pom.xml
+++ b/pigx-common/pigx-common-log/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-log
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
index f1d603642..d3d0ee4ad 100644
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
@@ -56,6 +56,19 @@ public class SysLogUtils {
return sysLog;
}
+ public SysLog getSysLog(HttpServletRequest request, String username) {
+ SysLog sysLog = new SysLog();
+ sysLog.setCreateBy(username);
+ sysLog.setType(CommonConstants.STATUS_NORMAL);
+ sysLog.setRemoteAddr(ServletUtil.getClientIP(request));
+ sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
+ sysLog.setMethod(request.getMethod());
+ sysLog.setUserAgent(request.getHeader("user-agent"));
+ sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
+ sysLog.setServiceId(getClientId());
+ return sysLog;
+ }
+
/**
* 获取客户端
*
diff --git a/pigx-common/pigx-common-minio/pom.xml b/pigx-common/pigx-common-minio/pom.xml
index 7f14d1a01..6112d949d 100755
--- a/pigx-common/pigx-common-minio/pom.xml
+++ b/pigx-common/pigx-common-minio/pom.xml
@@ -6,7 +6,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-minio
diff --git a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/MinioProperties.java b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/MinioProperties.java
index 93c91d323..dc9029c92 100755
--- a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/MinioProperties.java
+++ b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/MinioProperties.java
@@ -19,7 +19,6 @@ package com.pig4cloud.pigx.common.minio;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
/**
* minio 配置信息
@@ -27,7 +26,6 @@ import org.springframework.context.annotation.Configuration;
* @author lengleng
*/
@Data
-@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
/**
diff --git a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/service/MinioTemplate.java b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/service/MinioTemplate.java
index 474e9cc08..2653a433e 100755
--- a/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/service/MinioTemplate.java
+++ b/pigx-common/pigx-common-minio/src/main/java/com/pig4cloud/pigx/common/minio/service/MinioTemplate.java
@@ -97,8 +97,8 @@ public class MinioTemplate implements InitializingBean {
Iterable> objectsIterator = client
.listObjects(bucketName, prefix, recursive);
- while (objectsIterator.iterator().hasNext()) {
- objectList.add(new MinioItem(objectsIterator.iterator().next().get()));
+ for (Result- itemResult : objectsIterator) {
+ objectList.add(new MinioItem(itemResult.get()));
}
return objectList;
}
diff --git a/pigx-common/pigx-common-security/pom.xml b/pigx-common/pigx-common-security/pom.xml
index 2521e7fab..721b09b15 100644
--- a/pigx-common/pigx-common-security/pom.xml
+++ b/pigx-common/pigx-common-security/pom.xml
@@ -23,7 +23,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-security
@@ -43,10 +43,15 @@
org.springframework.cloud
spring-cloud-starter-oauth2
-
+
- com.pig4cloud
- pigx-upms-api
+ io.github.openfeign
+ feign-core
+
+
+
+ org.aspectj
+ aspectjrt
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/GlobalExceptionHandlerResolver.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/GlobalExceptionHandlerResolver.java
index 185fff514..dbb8fe397 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/GlobalExceptionHandlerResolver.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/GlobalExceptionHandlerResolver.java
@@ -75,11 +75,25 @@ public class GlobalExceptionHandlerResolver {
* @param exception
* @return R
*/
- @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
+ @ExceptionHandler({MethodArgumentNotValidException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public R handleBodyValidException(MethodArgumentNotValidException exception) {
List fieldErrors = exception.getBindingResult().getFieldErrors();
- log.error("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
+ log.warn("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
+ return R.failed(fieldErrors.get(0).getDefaultMessage());
+ }
+
+ /**
+ * validation Exception (以form-data形式传参)
+ *
+ * @param exception
+ * @return R
+ */
+ @ExceptionHandler({BindException.class})
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public R bindExceptionHandler(BindException exception) {
+ List fieldErrors = exception.getBindingResult().getFieldErrors();
+ log.warn("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
return R.failed(fieldErrors.get(0).getDefaultMessage());
}
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PermitAllUrlProperties.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PermitAllUrlProperties.java
index fd9c2d89c..bbd37ff33 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PermitAllUrlProperties.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PermitAllUrlProperties.java
@@ -18,7 +18,6 @@
package com.pig4cloud.pigx.common.security.component;
import cn.hutool.core.util.ReUtil;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.pig4cloud.pigx.common.security.annotation.Inner;
import lombok.Getter;
import lombok.Setter;
@@ -71,13 +70,13 @@ public class PermitAllUrlProperties implements InitializingBean {
Inner method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Inner.class);
Optional.ofNullable(method)
.ifPresent(inner -> info.getPatternsCondition().getPatterns()
- .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, StringPool.ASTERISK))));
+ .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"))));
// 获取类上边的注解, 替代path variable 为 *
Inner controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Inner.class);
Optional.ofNullable(controller)
.ifPresent(inner -> info.getPatternsCondition().getPatterns()
- .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, StringPool.ASTERISK))));
+ .forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"))));
});
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxResourceServerAutoConfiguration.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxResourceServerAutoConfiguration.java
index 0bb548e75..5bc39d1be 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxResourceServerAutoConfiguration.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxResourceServerAutoConfiguration.java
@@ -21,12 +21,15 @@ import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
+import java.util.Collections;
/**
* @author lengleng
@@ -39,6 +42,10 @@ public class PigxResourceServerAutoConfiguration {
@LoadBalanced
public RestTemplate lbRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
+ restTemplate.setInterceptors(Collections.singletonList((request, body, execution) -> {
+ request.getHeaders().set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
+ return execution.execute(request, body);
+ }));
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public void handleError(ClientHttpResponse response) throws IOException {
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java
index 5a568ba98..31990661c 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxSecurityInnerAspect.java
@@ -27,7 +27,6 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.access.AccessDeniedException;
-import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@@ -39,7 +38,6 @@ import javax.servlet.http.HttpServletRequest;
*/
@Slf4j
@Aspect
-@Component
@AllArgsConstructor
public class PigxSecurityInnerAspect {
private final HttpServletRequest request;
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxTokenEnhancer.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxTokenEnhancer.java
index a6f50acf1..c23931c4b 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxTokenEnhancer.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxTokenEnhancer.java
@@ -51,10 +51,7 @@ public class PigxTokenEnhancer implements TokenEnhancer {
final Map additionalInfo = new HashMap<>(8);
PigxUser pigxUser = (PigxUser) authentication.getUserAuthentication().getPrincipal();
- additionalInfo.put(SecurityConstants.DETAILS_USER_ID, pigxUser.getId());
- additionalInfo.put(SecurityConstants.DETAILS_USERNAME, pigxUser.getUsername());
- additionalInfo.put(SecurityConstants.DETAILS_DEPT_ID, pigxUser.getDeptId());
- additionalInfo.put(SecurityConstants.DETAILS_TENANT_ID, pigxUser.getTenantId());
+ additionalInfo.put(SecurityConstants.DETAILS_USER, pigxUser);
additionalInfo.put(SecurityConstants.DETAILS_LICENSE, SecurityConstants.PIGX_LICENSE);
additionalInfo.put(SecurityConstants.ACTIVE, Boolean.TRUE);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxUserAuthenticationConverter.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxUserAuthenticationConverter.java
index 626624b7d..96f0de22e 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxUserAuthenticationConverter.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/PigxUserAuthenticationConverter.java
@@ -17,6 +17,7 @@
package com.pig4cloud.pigx.common.security.component;
+import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
@@ -34,7 +35,10 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
-import java.util.*;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Optional;
/**
* @author lengleng
@@ -65,19 +69,22 @@ public class PigxUserAuthenticationConverter implements UserAuthenticationConver
/**
* Inverse of {@link #convertUserAuthentication(Authentication)}. Extracts an Authentication from a map.
*
- * @param map a map of user information
+ * @param responseMap a map of user information
* @return an Authentication representing the user or null if there is none
*/
@Override
- public Authentication extractAuthentication(Map map) {
- if (map.containsKey(USERNAME)) {
+ public Authentication extractAuthentication(Map responseMap) {
+ if (responseMap.containsKey(USERNAME)) {
+ Collection extends GrantedAuthority> authorities = getAuthorities(responseMap);
+ Map map = MapUtil.get(responseMap, SecurityConstants.DETAILS_USER, Map.class);
validateTenantId(map);
- Collection extends GrantedAuthority> authorities = getAuthorities(map);
- String username = (String) map.get(USERNAME);
- Integer id = (Integer) map.get(SecurityConstants.DETAILS_USER_ID);
- Integer deptId = (Integer) map.get(SecurityConstants.DETAILS_DEPT_ID);
- Integer tenantId = (Integer) map.get(SecurityConstants.DETAILS_TENANT_ID);
- PigxUser user = new PigxUser(id, deptId, tenantId, username, N_A, true
+ String username = MapUtil.getStr(map, SecurityConstants.DETAILS_USERNAME);
+ Integer id = MapUtil.getInt(map, SecurityConstants.DETAILS_USER_ID);
+ Integer deptId = MapUtil.getInt(map, SecurityConstants.DETAILS_DEPT_ID);
+ Integer tenantId = MapUtil.getInt(map, SecurityConstants.DETAILS_TENANT_ID);
+ String phone = MapUtil.getStr(map, SecurityConstants.DETAILS_PHONE);
+ String avatar = MapUtil.getStr(map, SecurityConstants.DETAILS_AVATAR);
+ PigxUser user = new PigxUser(id, deptId, phone, avatar, tenantId, username, N_A, true
, true, true, true, authorities);
return new UsernamePasswordAuthenticationToken(user, N_A, authorities);
}
@@ -96,13 +103,13 @@ public class PigxUserAuthenticationConverter implements UserAuthenticationConver
throw new IllegalArgumentException("Authorities must be either a String or a Collection");
}
- private void validateTenantId(Map map){
- String headerValue = getCurrentTenantId();
- Integer userValue = (Integer) map.get(SecurityConstants.DETAILS_TENANT_ID);
- if(StrUtil.isNotBlank(headerValue) && !userValue.toString().equals(headerValue)){
- log.warn("请求头中的租户ID({})和用户的租户ID({})不一致",headerValue,userValue);
+ private void validateTenantId(Map map) {
+ String headerValue = getCurrentTenantId();
+ Integer userValue = MapUtil.getInt(map, SecurityConstants.DETAILS_TENANT_ID);
+ if (StrUtil.isNotBlank(headerValue) && !userValue.toString().equals(headerValue)) {
+ log.warn("请求头中的租户ID({})和用户的租户ID({})不一致", headerValue, userValue);
// TODO: 不要提示租户ID不对,可能被穷举
- throw new PigxAuth2Exception(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badTenantId","Bad tenant ID"));
+ throw new PigxAuth2Exception(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badTenantId", "Bad tenant ID"));
}
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java
index 142560ca7..b05ec5651 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/component/ResourceAuthExceptionEntryPoint.java
@@ -26,6 +26,7 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
@@ -54,7 +55,9 @@ public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint
R result = new R<>();
result.setCode(CommonConstants.FAIL);
if (authException != null) {
- result.setMsg(authException.getMessage());
+ String msg = SpringSecurityMessageSource.getAccessor().getMessage(
+ "AbstractUserDetailsAuthenticationProvider.credentialsExpired", authException.getMessage());
+ result.setMsg(msg);
result.setData(authException.getMessage());
}
response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationFailureHandler.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationFailureHandler.java
new file mode 100644
index 000000000..9b07e5f33
--- /dev/null
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationFailureHandler.java
@@ -0,0 +1,25 @@
+package com.pig4cloud.pigx.common.security.handler;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author lengleng
+ * @date 2020/03/25
+ * token 发放失败处理
+ */
+public interface AuthenticationFailureHandler {
+
+ /**
+ * 业务处理
+ *
+ * @param authenticationException 错误信息
+ * @param authentication 认证信息
+ * @param request 请求信息
+ * @param response 响应信息
+ */
+ void handle(AuthenticationException authenticationException, Authentication authentication, HttpServletRequest request, HttpServletResponse response);
+}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationSuccessHandler.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationSuccessHandler.java
new file mode 100644
index 000000000..594f96a6b
--- /dev/null
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AuthenticationSuccessHandler.java
@@ -0,0 +1,23 @@
+package com.pig4cloud.pigx.common.security.handler;
+
+import org.springframework.security.core.Authentication;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author lengleng
+ * @date 2020/03/25
+ * token 发放成功处理
+ */
+public interface AuthenticationSuccessHandler {
+
+ /**
+ * 业务处理
+ *
+ * @param authentication 认证信息
+ * @param request 请求信息
+ * @param response 响应信息
+ */
+ void handle(Authentication authentication, HttpServletRequest request, HttpServletResponse response);
+}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationFailureEvenHandler.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java
similarity index 71%
rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationFailureEvenHandler.java
rename to pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java
index c29cc1c59..f77093500 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationFailureEvenHandler.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java
@@ -15,8 +15,10 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.common.security.handler;
+package com.pig4cloud.pigx.common.security.listener;
+import com.pig4cloud.pigx.common.security.handler.AuthenticationFailureHandler;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.core.Authentication;
@@ -29,10 +31,12 @@ import javax.servlet.http.HttpServletResponse;
/**
* @author lengleng
- * @date 2018/10/8
- * 认证失败事件处理器
+ * @date 2020/03/25
+ * 认证失败事件监听器
*/
-public abstract class AbstractAuthenticationFailureEvenHandler implements ApplicationListener {
+public class AuthenticationFailureEventListener implements ApplicationListener {
+ @Autowired(required = false)
+ private AuthenticationFailureHandler failureHandler;
/**
* Handle an application event.
@@ -49,18 +53,9 @@ public abstract class AbstractAuthenticationFailureEvenHandler implements Applic
AuthenticationException authenticationException = event.getException();
Authentication authentication = (Authentication) event.getSource();
- handle(authenticationException, authentication, request, response);
+ // 调用自定义业务实现
+ if (failureHandler != null) {
+ failureHandler.handle(authenticationException, authentication, request, response);
+ }
}
-
- /**
- * 处理登录失败方法
- *
- *
- * @param authenticationException 登录的authentication 对象
- * @param authentication 登录的authenticationException 对象
- * @param request 请求
- * @param response 响应
- */
- public abstract void handle(AuthenticationException authenticationException, Authentication authentication
- , HttpServletRequest request, HttpServletResponse response);
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationSuccessEventHandler.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java
similarity index 63%
rename from pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationSuccessEventHandler.java
rename to pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java
index fb69571f2..be478ddc6 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/handler/AbstractAuthenticationSuccessEventHandler.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java
@@ -15,9 +15,11 @@
* Author: lengleng (wangiegie@gmail.com)
*/
-package com.pig4cloud.pigx.common.security.handler;
+package com.pig4cloud.pigx.common.security.listener;
import cn.hutool.core.collection.CollUtil;
+import com.pig4cloud.pigx.common.security.handler.AuthenticationSuccessHandler;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
@@ -29,10 +31,13 @@ import javax.servlet.http.HttpServletResponse;
/**
* @author lengleng
- * @date 2018/10/8
- * 认证成功事件处理器
+ * @date 2020/03/25
+ * 认证成功事件监听器
*/
-public abstract class AbstractAuthenticationSuccessEventHandler implements ApplicationListener {
+public class AuthenticationSuccessEventListener implements ApplicationListener {
+ @Autowired(required = false)
+ private AuthenticationSuccessHandler successHandler;
+
/**
* Handle an application event.
*
@@ -40,25 +45,15 @@ public abstract class AbstractAuthenticationSuccessEventHandler implements Appli
*/
@Override
public void onApplicationEvent(AuthenticationSuccessEvent event) {
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
- RequestContextHolder.getRequestAttributes();
- HttpServletRequest request = requestAttributes.getRequest();
- HttpServletResponse response = requestAttributes.getResponse();
-
Authentication authentication = (Authentication) event.getSource();
- if (CollUtil.isNotEmpty(authentication.getAuthorities())) {
- handle(authentication, request, response);
+ if (CollUtil.isNotEmpty(authentication.getAuthorities()) && successHandler != null) {
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
+ RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = requestAttributes.getRequest();
+ HttpServletResponse response = requestAttributes.getResponse();
+
+ successHandler.handle(authentication, request, response);
}
}
- /**
- * 处理登录成功方法
- *
- * 获取到登录的authentication 对象
- *
- * @param authentication 登录对象
- * @param request 请求
- * @param response 响应
- */
- public abstract void handle(Authentication authentication, HttpServletRequest request, HttpServletResponse response);
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java
deleted file mode 100644
index 01e664f50..000000000
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxClientDetailsService.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.security.service;
-
-import com.pig4cloud.pigx.common.core.constant.CacheConstants;
-import org.springframework.cache.annotation.Cacheable;
-import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
-import org.springframework.security.oauth2.provider.ClientDetails;
-import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
-
-import javax.sql.DataSource;
-
-/**
- * @author lengleng
- * @date 2018/10/22
- *
- * see JdbcClientDetailsService
- */
-public class PigxClientDetailsService extends JdbcClientDetailsService {
-
- public PigxClientDetailsService(DataSource dataSource) {
- super(dataSource);
- }
-
- /**
- * 重写原生方法支持redis缓存
- *
- * @param clientId
- * @return
- * @throws InvalidClientException
- */
- @Override
- @Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
- public ClientDetails loadClientByClientId(String clientId) {
- return super.loadClientByClientId(clientId);
- }
-}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUser.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUser.java
index cae1f7f50..74590d23e 100644
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUser.java
+++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/service/PigxUser.java
@@ -20,16 +20,20 @@ package com.pig4cloud.pigx.common.security.service;
import lombok.Getter;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
/**
* @author lengleng
- * @date 2018/8/20
+ * @date 2020/4/16
* 扩展用户信息
*/
public class PigxUser extends User {
+
+ private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+
/**
* 用户ID
*/
@@ -41,12 +45,25 @@ public class PigxUser extends User {
@Getter
private Integer deptId;
+ /**
+ * 手机号
+ */
+ @Getter
+ private String phone;
+
+ /**
+ * 头像
+ */
+ @Getter
+ private String avatar;
+
/**
* 租户ID
*/
@Getter
private Integer tenantId;
+
/**
* Construct the User with the details required by
* {@link DaoAuthenticationProvider}.
@@ -68,10 +85,12 @@ public class PigxUser extends User {
* @throws IllegalArgumentException if a null value was passed either as
* a parameter or as an element in the GrantedAuthority collection
*/
- public PigxUser(Integer id, Integer deptId, Integer tenantId, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection extends GrantedAuthority> authorities) {
+ public PigxUser(Integer id, Integer deptId, String phone, String avatar, Integer tenantId, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.id = id;
this.deptId = deptId;
+ this.phone = phone;
+ this.avatar = avatar;
this.tenantId = tenantId;
}
}
diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java
deleted file mode 100644
index b0063b674..000000000
--- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/util/ConcurrentDateFormat.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
- */
-
-package com.pig4cloud.pigx.common.security.util;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Queue;
-import java.util.TimeZone;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/**
- * 参考tomcat8中的并发DateFormat
- *
- * {@link SimpleDateFormat}的线程安全包装器。
- * 不使用ThreadLocal,创建足够的SimpleDateFormat对象来满足并发性要求。
- *
- * @author L.cm
- */
-public class ConcurrentDateFormat {
- private final String format;
- private final Locale locale;
- private final TimeZone timezone;
- private final Queue queue = new ConcurrentLinkedQueue<>();
-
- private ConcurrentDateFormat(String format, Locale locale, TimeZone timezone) {
- this.format = format;
- this.locale = locale;
- this.timezone = timezone;
- SimpleDateFormat initial = createInstance();
- queue.add(initial);
- }
-
- public static ConcurrentDateFormat of(String format) {
- return new ConcurrentDateFormat(format, Locale.getDefault(), TimeZone.getDefault());
- }
-
- public static ConcurrentDateFormat of(String format, TimeZone timezone) {
- return new ConcurrentDateFormat(format, Locale.getDefault(), timezone);
- }
-
- public static ConcurrentDateFormat of(String format, Locale locale, TimeZone timezone) {
- return new ConcurrentDateFormat(format, locale, timezone);
- }
-
- public String format(Date date) {
- SimpleDateFormat sdf = queue.poll();
- if (sdf == null) {
- sdf = createInstance();
- }
- String result = sdf.format(date);
- queue.add(sdf);
- return result;
- }
-
- public Date parse(String source) throws ParseException {
- SimpleDateFormat sdf = queue.poll();
- if (sdf == null) {
- sdf = createInstance();
- }
- Date result = sdf.parse(source);
- queue.add(sdf);
- return result;
- }
-
- private SimpleDateFormat createInstance() {
- SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
- sdf.setTimeZone(timezone);
- return sdf;
- }
-}
diff --git a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
index 7908386a5..367df029e 100644
--- a/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
+++ b/pigx-common/pigx-common-security/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.pig4cloud.pigx.common.security.component.GlobalExceptionHandlerResolver,\
com.pig4cloud.pigx.common.security.component.PigxTokenEnhancer,\
- com.pig4cloud.pigx.common.security.service.PigxUserDetailsServiceImpl
+ com.pig4cloud.pigx.common.security.component.PigxSecurityInnerAspect,\
+ com.pig4cloud.pigx.common.security.listener.AuthenticationFailureEventListener,\
+ com.pig4cloud.pigx.common.security.listener.AuthenticationSuccessEventListener
+
diff --git a/pigx-common/pigx-common-sentinel/pom.xml b/pigx-common/pigx-common-sentinel/pom.xml
index 349b437e4..7664cb323 100755
--- a/pigx-common/pigx-common-sentinel/pom.xml
+++ b/pigx-common/pigx-common-sentinel/pom.xml
@@ -5,7 +5,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
4.0.0
diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java
similarity index 64%
rename from pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java
rename to pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java
index 29a4919e9..9679af060 100755
--- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfigure.java
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/SentinelAutoConfiguration.java
@@ -17,25 +17,32 @@
package com.pig4cloud.pigx.common.sentinel;
-import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
+import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
+import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import com.pig4cloud.pigx.common.sentinel.handle.PigxUrlBlockHandler;
import com.pig4cloud.pigx.common.sentinel.parser.PigxHeaderRequestOriginParser;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import javax.annotation.PostConstruct;
-
/**
* @author lengleng
+ * @date 2020-02-12
*
* sentinel 配置
*/
@Configuration
-public class SentinelAutoConfigure {
+public class SentinelAutoConfiguration {
- @PostConstruct
- public void initWebCallbackManager() {
- WebCallbackManager.setUrlBlockHandler(new PigxUrlBlockHandler());
- WebCallbackManager.setRequestOriginParser(new PigxHeaderRequestOriginParser());
+ @Bean
+ @ConditionalOnMissingBean
+ public BlockExceptionHandler blockExceptionHandler() {
+ return new PigxUrlBlockHandler();
}
+ @Bean
+ @ConditionalOnMissingBean
+ public RequestOriginParser requestOriginParser(){
+ return new PigxHeaderRequestOriginParser();
+ }
}
diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java
index 0cdd8115c..691e2c618 100644
--- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/handle/PigxUrlBlockHandler.java
@@ -19,7 +19,7 @@ package com.pig4cloud.pigx.common.sentinel.handle;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
-import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
+import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.extern.slf4j.Slf4j;
@@ -27,7 +27,6 @@ import org.springframework.http.HttpStatus;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
/**
* @author lengleng
@@ -36,10 +35,10 @@ import java.io.IOException;
* 降级 限流策略
*/
@Slf4j
-public class PigxUrlBlockHandler implements UrlBlockHandler {
- @Override
- public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException e) throws IOException {
+public class PigxUrlBlockHandler implements BlockExceptionHandler {
+ @Override
+ public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
log.error("sentinel 降级 资源名称{}", e.getRule().getResource(), e);
response.setContentType(ContentType.JSON.toString());
diff --git a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
index efcc91c60..2b4308f56 100644
--- a/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
+++ b/pigx-common/pigx-common-sentinel/src/main/java/com/pig4cloud/pigx/common/sentinel/parser/PigxHeaderRequestOriginParser.java
@@ -17,7 +17,7 @@
package com.pig4cloud.pigx.common.sentinel.parser;
-import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
+import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import javax.servlet.http.HttpServletRequest;
diff --git a/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories
index c396f293f..550a79f02 100755
--- a/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories
+++ b/pigx-common/pigx-common-sentinel/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.pig4cloud.pigx.common.sentinel.SentinelAutoConfigure
+ com.pig4cloud.pigx.common.sentinel.SentinelAutoConfiguration
diff --git a/pigx-common/pigx-common-sequence/pom.xml b/pigx-common/pigx-common-sequence/pom.xml
index f33ab5f03..e80d4d79e 100755
--- a/pigx-common/pigx-common-sequence/pom.xml
+++ b/pigx-common/pigx-common-sequence/pom.xml
@@ -6,7 +6,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-sequence
diff --git a/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/pigx/common/sequence/range/BizName.java b/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/pigx/common/sequence/range/BizName.java
index 93ef9ec9b..04d0ba57a 100644
--- a/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/pigx/common/sequence/range/BizName.java
+++ b/pigx-common/pigx-common-sequence/src/main/java/com/pig4cloud/pigx/common/sequence/range/BizName.java
@@ -9,6 +9,8 @@ package com.pig4cloud.pigx.common.sequence.range;
public interface BizName {
/**
* 生成名称
+ *
+ * @return 返回文本序号
*/
String create();
diff --git a/pigx-common/pigx-common-swagger/pom.xml b/pigx-common/pigx-common-swagger/pom.xml
index 0b122d958..e11f695a3 100644
--- a/pigx-common/pigx-common-swagger/pom.xml
+++ b/pigx-common/pigx-common-swagger/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-swagger
diff --git a/pigx-common/pigx-common-swagger/src/main/java/com/pig4cloud/pigx/common/swagger/config/SwaggerAutoConfiguration.java b/pigx-common/pigx-common-swagger/src/main/java/com/pig4cloud/pigx/common/swagger/config/SwaggerAutoConfiguration.java
index e715ffdde..a07a1c2c3 100644
--- a/pigx-common/pigx-common-swagger/src/main/java/com/pig4cloud/pigx/common/swagger/config/SwaggerAutoConfiguration.java
+++ b/pigx-common/pigx-common-swagger/src/main/java/com/pig4cloud/pigx/common/swagger/config/SwaggerAutoConfiguration.java
@@ -25,8 +25,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
@@ -49,9 +51,9 @@ import java.util.List;
public class SwaggerAutoConfiguration {
/**
- * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点
+ * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点
*/
- private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error","/actuator/**");
+ private static final List DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**");
private static final String BASE_PATH = "/**";
@Bean
@@ -77,16 +79,26 @@ public class SwaggerAutoConfiguration {
List> excludePath = new ArrayList<>();
swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path)));
+ // 版本请求头处理
+ ParameterBuilder versionPar = new ParameterBuilder();
+ List pars = new ArrayList<>();
+ versionPar.name("VERSION").description("灰度路由版本信息")
+ .modelRef(new ModelRef("string")).parameterType("header")
+ .required(false).build();
+ pars.add(versionPar.build());
+
//noinspection Guava
return new Docket(DocumentationType.SWAGGER_2)
- .host(swaggerProperties.getHost())
- .apiInfo(apiInfo(swaggerProperties)).select()
- .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
- .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)), Predicates.or(basePath)))
- .build()
- .securitySchemes(Collections.singletonList(securitySchema()))
- .securityContexts(Collections.singletonList(securityContext()))
- .pathMapping("/");
+ .host(swaggerProperties.getHost())
+ .apiInfo(apiInfo(swaggerProperties))
+ .globalOperationParameters(pars)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
+ .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)), Predicates.or(basePath)))
+ .build()
+ .securitySchemes(Collections.singletonList(securitySchema()))
+ .securityContexts(Collections.singletonList(securityContext()))
+ .pathMapping("/");
}
/**
@@ -96,9 +108,9 @@ public class SwaggerAutoConfiguration {
*/
private SecurityContext securityContext() {
return SecurityContext.builder()
- .securityReferences(defaultAuth())
- .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex()))
- .build();
+ .securityReferences(defaultAuth())
+ .forPaths(PathSelectors.regex(swaggerProperties().getAuthorization().getAuthRegex()))
+ .build();
}
/**
@@ -111,9 +123,9 @@ public class SwaggerAutoConfiguration {
swaggerProperties().getAuthorization().getAuthorizationScopeList().forEach(authorizationScope -> authorizationScopeList.add(new AuthorizationScope(authorizationScope.getScope(), authorizationScope.getDescription())));
AuthorizationScope[] authorizationScopes = new AuthorizationScope[authorizationScopeList.size()];
return Collections.singletonList(SecurityReference.builder()
- .reference(swaggerProperties().getAuthorization().getName())
- .scopes(authorizationScopeList.toArray(authorizationScopes))
- .build());
+ .reference(swaggerProperties().getAuthorization().getName())
+ .scopes(authorizationScopeList.toArray(authorizationScopes))
+ .build());
}
@@ -127,14 +139,14 @@ public class SwaggerAutoConfiguration {
private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {
return new ApiInfoBuilder()
- .title(swaggerProperties.getTitle())
- .description(swaggerProperties.getDescription())
- .license(swaggerProperties.getLicense())
- .licenseUrl(swaggerProperties.getLicenseUrl())
- .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
- .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
- .version(swaggerProperties.getVersion())
- .build();
+ .title(swaggerProperties.getTitle())
+ .description(swaggerProperties.getDescription())
+ .license(swaggerProperties.getLicense())
+ .licenseUrl(swaggerProperties.getLicenseUrl())
+ .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
+ .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail()))
+ .version(swaggerProperties.getVersion())
+ .build();
}
}
diff --git a/pigx-common/pigx-common-transaction/pom.xml b/pigx-common/pigx-common-transaction/pom.xml
index 3d70feadc..6b9f5149b 100644
--- a/pigx-common/pigx-common-transaction/pom.xml
+++ b/pigx-common/pigx-common-transaction/pom.xml
@@ -5,7 +5,7 @@
com.pig4cloud
pigx-common
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common-transaction
diff --git a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java
index 51d1d4b43..8d40d51dd 100755
--- a/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java
+++ b/pigx-common/pigx-common-transaction/src/main/java/com/pig4cloud/pigx/common/transaction/tx/springcloud/interceptor/TxManagerInterceptor.java
@@ -18,9 +18,10 @@
package com.pig4cloud.pigx.common.transaction.tx.springcloud.interceptor;
import com.codingapi.tx.aop.service.AspectBeforeService;
+import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@@ -34,17 +35,23 @@ import javax.servlet.http.HttpServletRequest;
* @since 4.1.0
*/
+@Slf4j
@Component
+@AllArgsConstructor
public class TxManagerInterceptor {
-
- @Autowired
- private AspectBeforeService aspectBeforeService;
+ private final AspectBeforeService aspectBeforeService;
@SneakyThrows
public Object around(ProceedingJoinPoint point) {
- RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
- HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
- String groupId = request.getHeader("tx-group");
+ RequestAttributes requestAttributes;
+ String groupId = null;
+ try {
+ requestAttributes = RequestContextHolder.currentRequestAttributes();
+ HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
+ groupId = request.getHeader("tx-group");
+ } catch (IllegalStateException e) {
+ log.info("非web 环境调用 不包含请求上下文");
+ }
return aspectBeforeService.around(groupId, point);
}
}
diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml
index 46a7edf89..6e0dbca2b 100644
--- a/pigx-common/pom.xml
+++ b/pigx-common/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-common
@@ -37,7 +37,9 @@
pigx-common-core
pigx-common-data
pigx-common-datasource
+ pigx-common-feign
pigx-common-gateway
+ pigx-common-gray
pigx-common-job
pigx-common-log
pigx-common-minio
diff --git a/pigx-gateway/Dockerfile b/pigx-gateway/Dockerfile
index 8333b52c2..1725e6062 100644
--- a/pigx-gateway/Dockerfile
+++ b/pigx-gateway/Dockerfile
@@ -1,8 +1,10 @@
-FROM java:8-jre
+FROM pig4cloud/java:8-jre
MAINTAINER wangiegie@gmail.com
-RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+ENV TZ=Asia/Shanghai
+
+RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /pigx-gateway
@@ -10,6 +12,6 @@ WORKDIR /pigx-gateway
EXPOSE 9999
-ADD ./pigx-gateway/target/pigx-gateway.jar ./
+ADD ./target/pigx-gateway.jar ./
CMD sleep 120;java -Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom -jar pigx-gateway.jar
diff --git a/pigx-gateway/pom.xml b/pigx-gateway/pom.xml
index c97f8f620..5d7ce558d 100644
--- a/pigx-gateway/pom.xml
+++ b/pigx-gateway/pom.xml
@@ -24,7 +24,7 @@
com.pig4cloud
pigx
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-gateway
@@ -103,7 +103,7 @@
spring-boot-maven-plugin
- com.spotify
+ io.fabric8
docker-maven-plugin
diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java
index 033c382fd..4b5f8d3bb 100644
--- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java
+++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/PasswordDecoderFilter.java
@@ -25,76 +25,143 @@ import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
+import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
+import org.springframework.cloud.gateway.support.BodyInserterContext;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
-import org.springframework.web.util.UriComponentsBuilder;
+import org.springframework.web.reactive.function.BodyInserter;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.server.HandlerStrategies;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-import java.net.URI;
import java.nio.charset.StandardCharsets;
+import java.util.List;
import java.util.Map;
+import java.util.function.Function;
/**
* @author lengleng
- * @date 2018/7/15
+ * @date 2020/1/8
* 密码解密工具类
+ *
+ * 参考 ModifyRequestBodyGatewayFilterFactory 实现
*/
@Slf4j
@Component
public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
+ private final List> messageReaders = HandlerStrategies.withDefaults().messageReaders();
+
private static final String PASSWORD = "password";
private static final String KEY_ALGORITHM = "AES";
@Value("${security.encode.key:1234567812345678}")
private String encodeKey;
- @SneakyThrows
- private static String decryptAES(String data, String pass) {
- AES aes = new AES(Mode.CBC,Padding.NoPadding,
- new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM),
- new IvParameterSpec(pass.getBytes()));
- byte[] result = aes.decrypt(Base64.decode(data.getBytes(StandardCharsets.UTF_8)));
- return new String(result, StandardCharsets.UTF_8);
- }
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
-
// 不是登录请求,直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
return chain.filter(exchange);
}
- URI uri = exchange.getRequest().getURI();
- String queryParam = uri.getRawQuery();
- Map paramMap = HttpUtil.decodeParamMap(queryParam, CharsetUtil.UTF_8);
-
- String password = paramMap.get(PASSWORD);
- if (StrUtil.isNotBlank(password)) {
- try {
- password = decryptAES(password, encodeKey);
- } catch (Exception e) {
- log.error("密码解密失败:{}", password);
- return Mono.error(e);
- }
- paramMap.put(PASSWORD, password.trim());
+ // 刷新token,直接向下执行
+ String grantType = request.getQueryParams().getFirst("grant_type");
+ if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
+ return chain.filter(exchange);
}
- URI newUri = UriComponentsBuilder.fromUri(uri)
- .replaceQuery(HttpUtil.toParams(paramMap))
- .build(true)
- .toUri();
+ Class inClass = String.class;
+ Class outClass = String.class;
+ ServerRequest serverRequest = ServerRequest.create(exchange,
+ messageReaders);
- ServerHttpRequest newRequest = exchange.getRequest().mutate().uri(newUri).build();
- return chain.filter(exchange.mutate().request(newRequest).build());
+ // 解密生成新的报文
+ Mono> modifiedBody = serverRequest.bodyToMono(inClass)
+ .flatMap(decryptAES());
+
+ BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass);
+ HttpHeaders headers = new HttpHeaders();
+ headers.putAll(exchange.getRequest().getHeaders());
+ headers.remove(HttpHeaders.CONTENT_LENGTH);
+
+ headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+ CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(
+ exchange, headers);
+ return bodyInserter.insert(outputMessage, new BodyInserterContext())
+ .then(Mono.defer(() -> {
+ ServerHttpRequest decorator = decorate(exchange, headers,
+ outputMessage);
+ return chain
+ .filter(exchange.mutate().request(decorator).build());
+ }));
+ };
+ }
+
+ /**
+ * 原文解密
+ *
+ * @return
+ */
+ private Function decryptAES() {
+ return s -> {
+ // 构建前端对应解密AES 因子
+ AES aes = new AES(Mode.CBC, Padding.NoPadding,
+ new SecretKeySpec(encodeKey.getBytes(), KEY_ALGORITHM),
+ new IvParameterSpec(encodeKey.getBytes()));
+
+ // 获取请求密码并解密
+ Map inParamsMap = HttpUtil.decodeParamMap((String) s, CharsetUtil.CHARSET_UTF_8);
+ byte[] result = aes.decrypt(Base64.decode(inParamsMap.get(PASSWORD)
+ .getBytes(StandardCharsets.UTF_8)));
+ String password = new String(result, StandardCharsets.UTF_8);
+
+ // 返回修改后报文字符
+ inParamsMap.put(PASSWORD, password.trim());
+ return Mono.just(HttpUtil.toParams(inParamsMap));
+ };
+ }
+
+ /**
+ * 报文转换
+ *
+ * @return
+ */
+ private ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers,
+ CachedBodyOutputMessage outputMessage) {
+ return new ServerHttpRequestDecorator(exchange.getRequest()) {
+ @Override
+ public HttpHeaders getHeaders() {
+ long contentLength = headers.getContentLength();
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.putAll(super.getHeaders());
+ if (contentLength > 0) {
+ httpHeaders.setContentLength(contentLength);
+ } else {
+ httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
+ }
+ return httpHeaders;
+ }
+
+ @Override
+ public Flux getBody() {
+ return outputMessage.getBody();
+ }
};
}
}
diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java
index bdbabf41f..020b63618 100644
--- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java
+++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/filter/ValidateCodeGatewayFilter.java
@@ -34,6 +34,7 @@ import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -74,8 +75,9 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
// 终端设置不校验, 直接向下执行
try {
- String[] clientInfos = WebUtils.getClientId(request);
- if (filterIgnorePropertiesConfig.getClients().contains(clientInfos[0])) {
+ String header = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
+ String clientId = WebUtils.getClientId(header);
+ if (filterIgnorePropertiesConfig.getClients().contains(clientId)) {
return chain.filter(exchange);
}
diff --git a/pigx-gateway/src/main/resources/bootstrap.yml b/pigx-gateway/src/main/resources/bootstrap.yml
index 7f9f41e22..83045b213 100644
--- a/pigx-gateway/src/main/resources/bootstrap.yml
+++ b/pigx-gateway/src/main/resources/bootstrap.yml
@@ -7,10 +7,11 @@ spring:
cloud:
nacos:
discovery:
- server-addr: ${NACOS-HOST:pigx-register}:${NACOS-PORT:8848}
+ server-addr: ${NACOS_HOST:pigx-register}:${NACOS_PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
- shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ shared-configs:
+ - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
profiles:
- active: @profiles.active@
+ active: @profiles.active@
\ No newline at end of file
diff --git a/pigx-gateway/src/main/resources/logback-spring.xml b/pigx-gateway/src/main/resources/logback-spring.xml
new file mode 100644
index 000000000..998f18b5c
--- /dev/null
+++ b/pigx-gateway/src/main/resources/logback-spring.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${CONSOLE_LOG_PATTERN}
+
+
+
+
+
+ ${log.path}/debug.log
+
+ ${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz
+ 50MB
+ 30
+
+
+ %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n
+
+
+
+
+
+ ${log.path}/error.log
+
+ ${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz
+ 50MB
+ 30
+
+
+ %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n
+
+
+ ERROR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pigx-register/Dockerfile b/pigx-register/Dockerfile
index 00e73b26e..29f74fb74 100644
--- a/pigx-register/Dockerfile
+++ b/pigx-register/Dockerfile
@@ -1,8 +1,10 @@
-FROM java:8-jre
+FROM pig4cloud/java:8-jre
MAINTAINER wangiegie@gmail.com
-RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+ENV TZ=Asia/Shanghai
+
+RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /pigx-register
@@ -10,7 +12,7 @@ WORKDIR /pigx-register
EXPOSE 8848
-ADD ./pigx-register/target/pigx-register.jar ./
+ADD ./target/pigx-register.jar ./
CMD sleep 60;java -Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom -jar pigx-register.jar
diff --git a/pigx-register/pom.xml b/pigx-register/pom.xml
index 11ca0bcfb..7d9ddeb77 100755
--- a/pigx-register/pom.xml
+++ b/pigx-register/pom.xml
@@ -18,7 +18,7 @@
com.pig4cloud
pigx
- 3.6.0
+ 3.9.0-SNAPSHOT
pigx-register
@@ -30,14 +30,25 @@
com.pig4cloud.nacos
nacos-config
- 1.1.4
+ 1.2.1
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ 7.0.59
com.pig4cloud.nacos
nacos-naming
- 1.1.4
+ 1.2.1
-
+
+
+ com.pig4cloud.nacos
+ nacos-istio
+ 1.2.1
+
+
org.springframework.boot
spring-boot-starter-security
@@ -59,10 +70,6 @@
0.10.5
runtime
-
- org.springframework.cloud
- spring-cloud-starter
-
@@ -71,7 +78,7 @@
spring-boot-maven-plugin
- com.spotify
+ io.fabric8
docker-maven-plugin
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/PigxNacosApplication.java b/pigx-register/src/main/java/com/alibaba/nacos/PigxNacosApplication.java
index 2fe304942..51f509698 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/PigxNacosApplication.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/PigxNacosApplication.java
@@ -32,9 +32,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
public class PigxNacosApplication {
public static void main(String[] args) {
- System.setProperty(ConfigConstants.TOMCAT_DIR, "logs");
- System.setProperty(ConfigConstants.TOMCAT_ACCESS_LOG, "false");
System.setProperty(ConfigConstants.STANDALONE_MODE, "true");
+ System.setProperty(ConfigConstants.AUTH_ENABLED, "false");
SpringApplication.run(PigxNacosApplication.class, args);
}
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConfigConstants.java b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConfigConstants.java
index 0b39fb331..4572491d4 100644
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConfigConstants.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConfigConstants.java
@@ -30,12 +30,7 @@ public interface ConfigConstants {
String STANDALONE_MODE = "nacos.standalone";
/**
- * tomcat 目录
+ * 是否开启认证
*/
- String TOMCAT_DIR = "server.tomcat.basedir";
-
- /**
- * tomcat 日志配置
- */
- String TOMCAT_ACCESS_LOG = "server.tomcat.accesslog.enabled";
+ String AUTH_ENABLED = "nacos.core.auth.enabled";
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java
new file mode 100755
index 000000000..0a47b45b6
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/config/ConsoleConfig.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.config;
+
+
+import com.alibaba.nacos.core.code.ControllerMethodsCache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Component;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @author yshen
+ * @author nkorange
+ * @since 1.2.0
+ */
+@Component
+@EnableScheduling
+@PropertySource("/application.properties")
+public class ConsoleConfig {
+
+ @Autowired
+ private ControllerMethodsCache methodsCache;
+
+ @PostConstruct
+ public void init() {
+ methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers");
+ methodsCache.initClassMethod("com.alibaba.nacos.console.controller");
+ methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller");
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = new CorsConfiguration();
+ config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.setMaxAge(18000L);
+ config.addAllowedMethod("*");
+ source.registerCorsConfiguration("/**", config);
+ return new CorsFilter(source);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/AuthController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/AuthController.java
deleted file mode 100755
index 03f4d2328..000000000
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/AuthController.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * 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.
- */
-package com.alibaba.nacos.console.controller;
-
-import com.alibaba.nacos.config.server.model.RestResult;
-import com.alibaba.nacos.console.config.WebSecurityConfig;
-import com.alibaba.nacos.console.security.CustomUserDetailsServiceImpl;
-import com.alibaba.nacos.console.utils.JwtTokenUtils;
-import com.alibaba.nacos.console.utils.PasswordEncoderUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * auth
- *
- * @author wfnuser
- */
-@RestController("auth")
-@RequestMapping("/v1/auth")
-public class AuthController {
-
- @Autowired
- private JwtTokenUtils jwtTokenUtils;
- @Autowired
- private AuthenticationManager authenticationManager;
- @Autowired
- private CustomUserDetailsServiceImpl userDetailsService;
-
- /**
- * Whether the Nacos is in broken states or not, and cannot recover except by being restarted
- *
- * @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
- * Nacos is in broken states.
- */
-
- @PostMapping("login")
- public RestResult login(@RequestParam String username, @RequestParam String password, HttpServletResponse response) {
-
- // 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken
- UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
- RestResult rr = new RestResult();
-
- try {
- //通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 Authentication 对象
- Authentication authentication = authenticationManager.authenticate(authenticationToken);
- //将 Authentication 绑定到 SecurityContext
- SecurityContextHolder.getContext().setAuthentication(authentication);
- //生成Token
- String token = jwtTokenUtils.createToken(authentication);
- //将Token写入到Http头部
- response.addHeader(WebSecurityConfig.AUTHORIZATION_HEADER, "Bearer " + token);
- rr.setCode(200);
- rr.setData("Bearer " + token);
- return rr;
- } catch (BadCredentialsException authentication) {
- rr.setCode(401);
- rr.setMessage("Login failed");
- return rr;
- }
- }
-
- @PutMapping("password")
- public RestResult updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
- @RequestParam(value = "newPassword") String newPassword) {
-
- RestResult rr = new RestResult();
- Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- String username = ((UserDetails) principal).getUsername();
- UserDetails userDetails = userDetailsService.loadUserByUsername(username);
- String password = userDetails.getPassword();
-
- // TODO: throw out more fine grained exceptions
- try {
- if (PasswordEncoderUtil.matches(oldPassword, password)) {
- userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
- rr.setCode(200);
- rr.setMessage("Update password success");
- } else {
- rr.setCode(401);
- rr.setMessage("Old password is invalid");
- }
- } catch (Exception e) {
- rr.setCode(500);
- rr.setMessage("Update userpassword failed");
- }
- return rr;
- }
-}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
index f3595bdcb..05006ce55 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/HealthController.java
@@ -51,7 +51,7 @@ public class HealthController {
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
- @GetMapping("liveness")
+ @GetMapping("/liveness")
public ResponseEntity liveness() {
return ResponseEntity.ok().body("OK");
}
@@ -62,7 +62,7 @@ public class HealthController {
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready.
*/
- @GetMapping("readiness")
+ @GetMapping("/readiness")
public ResponseEntity readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request);
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
index 12720d87e..0e24b58a3 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java
@@ -20,6 +20,9 @@ import com.alibaba.nacos.config.server.model.TenantInfo;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.console.model.Namespace;
import com.alibaba.nacos.console.model.NamespaceAllInfo;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import com.alibaba.nacos.core.auth.ActionTypes;
+import com.alibaba.nacos.core.auth.Secured;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -29,6 +32,7 @@ import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import java.util.regex.Pattern;
/**
* namespace service
@@ -42,6 +46,10 @@ public class NamespaceController {
@Autowired
private PersistService persistService;
+ private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
+
+ private static final int NAMESPACE_ID_MAX_LENGTH = 128;
+
/**
* Get namespace list
*
@@ -101,16 +109,46 @@ public class NamespaceController {
* @return whether create ok
*/
@PostMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam("customNamespaceId") String namespaceId,
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp
- String namespaceId = UUID.randomUUID().toString();
+ if(StringUtils.isBlank(namespaceId)){
+ namespaceId = UUID.randomUUID().toString();
+ } else {
+ namespaceId = namespaceId.trim();
+ if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) {
+ return false;
+ }
+ if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
+ return false;
+ }
+ if(persistService.tenantInfoCountByTenantId(namespaceId) > 0){
+ return false;
+ }
+ }
persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos",
System.currentTimeMillis());
return true;
}
+ /**
+ * @author klw(213539@qq.com)
+ * @Description: check namespaceId exist
+ * @Date 2019/12/10 21:41
+ * @param: namespaceId
+ * @return java.lang.Boolean
+ */
+ @GetMapping(params = "checkNamespaceIdExist=true")
+ public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId){
+ if(StringUtils.isBlank(namespaceId)){
+ return false;
+ }
+ return (persistService.tenantInfoCountByTenantId(namespaceId) > 0);
+ }
+
/**
* edit namespace
*
@@ -120,6 +158,7 @@ public class NamespaceController {
* @return whether edit ok
*/
@PutMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean editNamespace(@RequestParam("namespace") String namespace,
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
@@ -137,6 +176,7 @@ public class NamespaceController {
* @return whether del ok
*/
@DeleteMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
persistService.removeTenantInfoAtomic("1", namespaceId);
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java
new file mode 100755
index 000000000..71339d4c5
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/PermissionController.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.controller;
+
+
+import com.alibaba.nacos.config.server.model.RestResult;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
+import com.alibaba.nacos.core.auth.ActionTypes;
+import com.alibaba.nacos.core.auth.Secured;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * Permission operation controller
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+@RestController
+@RequestMapping("/v1/auth/permissions")
+public class PermissionController {
+
+ @Autowired
+ private NacosRoleServiceImpl nacosRoleService;
+
+ /**
+ * Query permissions of a role
+ *
+ * @param role the role
+ * @param pageNo page index
+ * @param pageSize page size
+ * @return permission of a role
+ */
+ @GetMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.READ)
+ public Object getPermissions(@RequestParam int pageNo, @RequestParam int pageSize,
+ @RequestParam(name = "role", defaultValue = StringUtils.EMPTY) String role) {
+ return nacosRoleService.getPermissionsFromDatabase(role, pageNo, pageSize);
+ }
+
+ /**
+ * Add a permission to a role
+ *
+ * @param role the role
+ * @param resource the related resource
+ * @param action the related action
+ * @return ok if succeed
+ */
+ @PostMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
+ public Object addPermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
+ nacosRoleService.addPermission(role, resource, action);
+ return new RestResult<>(200, "add permission ok!");
+ }
+
+ /**
+ * Delete a permission from a role
+ *
+ * @param role the role
+ * @param resource the related resource
+ * @param action the related action
+ * @return ok if succeed
+ */
+ @DeleteMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
+ public Object deletePermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
+ nacosRoleService.deletePermission(role, resource, action);
+ return new RestResult<>(200, "delete permission ok!");
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/RoleController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/RoleController.java
new file mode 100755
index 000000000..69d720f5c
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/RoleController.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.controller;
+
+
+import com.alibaba.nacos.config.server.model.RestResult;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
+import com.alibaba.nacos.core.auth.ActionTypes;
+import com.alibaba.nacos.core.auth.Secured;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * Role operation controller
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+@RestController
+@RequestMapping("/v1/auth/roles")
+public class RoleController {
+
+ @Autowired
+ private NacosRoleServiceImpl roleService;
+
+ /**
+ * Get roles list
+ *
+ * @param pageNo number index of page
+ * @param pageSize page size
+ * @param username optional, username of user
+ * @return role list
+ */
+ @GetMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ)
+ public Object getRoles(@RequestParam int pageNo, @RequestParam int pageSize,
+ @RequestParam(name = "username", defaultValue = "") String username) {
+ return roleService.getRolesFromDatabase(username, pageNo, pageSize);
+ }
+
+ /**
+ * Add a role to a user
+ *
+ * This method is used for 2 functions:
+ * 1. create a role and bind it to GLOBAL_ADMIN.
+ * 2. bind a role to an user.
+ *
+ * @param role
+ * @param username
+ * @return
+ */
+ @PostMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
+ public Object addRole(@RequestParam String role, @RequestParam String username) {
+ roleService.addRole(role, username);
+ return new RestResult<>(200, "add role ok!");
+ }
+
+ /**
+ * Delete a role. If no username is specified, all users under this role are deleted
+ *
+ * @param role role
+ * @param username username
+ * @return ok if succeed
+ */
+ @DeleteMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
+ public Object deleteRole(@RequestParam String role,
+ @RequestParam(name = "username", defaultValue = StringUtils.EMPTY) String username) {
+ if (StringUtils.isBlank(username)) {
+ roleService.deleteRole(role);
+ } else {
+ roleService.deleteRole(role, username);
+ }
+ return new RestResult<>(200, "delete role of user " + username + " ok!");
+ }
+
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
index 3fd7c8029..80e04d5ed 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/ServerStateController.java
@@ -16,7 +16,7 @@
package com.alibaba.nacos.console.controller;
-import com.alibaba.nacos.common.util.VersionUtils;
+import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.core.utils.SystemUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@@ -34,7 +34,7 @@ import java.util.Map;
@RequestMapping("/v1/console/server")
public class ServerStateController {
- @GetMapping("state")
+ @GetMapping("/state")
public ResponseEntity serverState() {
Map serverState = new HashMap<>(3);
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/controller/UserController.java b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/UserController.java
new file mode 100755
index 000000000..2daef8690
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/controller/UserController.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.config.server.auth.RoleInfo;
+import com.alibaba.nacos.config.server.model.RestResult;
+import com.alibaba.nacos.config.server.model.User;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import com.alibaba.nacos.console.security.nacos.NacosAuthManager;
+import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
+import com.alibaba.nacos.console.security.nacos.users.NacosUser;
+import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
+import com.alibaba.nacos.console.utils.JwtTokenUtils;
+import com.alibaba.nacos.console.utils.PasswordEncoderUtil;
+import com.alibaba.nacos.core.auth.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * User related methods entry
+ *
+ * @author wfnuser
+ * @author nkorange
+ */
+@RestController("user")
+@RequestMapping({"/v1/auth", "/v1/auth/users"})
+public class UserController {
+
+ @Autowired
+ private JwtTokenUtils jwtTokenUtils;
+
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ @Autowired
+ private NacosUserDetailsServiceImpl userDetailsService;
+
+ @Autowired
+ private NacosRoleServiceImpl roleService;
+
+ @Autowired
+ private AuthConfigs authConfigs;
+
+ @Autowired
+ private NacosAuthManager authManager;
+
+ /**
+ * Create a new user
+ *
+ * @param username username
+ * @param password password
+ * @return ok if create succeed
+ * @throws IllegalArgumentException if user already exist
+ * @since 1.2.0
+ */
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
+ @PostMapping
+ public Object createUser(@RequestParam String username, @RequestParam String password) {
+
+ User user = userDetailsService.getUserFromDatabase(username);
+ if (user != null) {
+ throw new IllegalArgumentException("user '" + username + "' already exist!");
+ }
+ userDetailsService.createUser(username, PasswordEncoderUtil.encode(password));
+ return new RestResult<>(200, "create user ok!");
+ }
+
+ /**
+ * Delete an existed user
+ *
+ * @param username username of user
+ * @return ok if deleted succeed, keep silent if user not exist
+ * @since 1.2.0
+ */
+ @DeleteMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
+ public Object deleteUser(@RequestParam String username) {
+ List roleInfoList = roleService.getRoles(username);
+ if (roleInfoList != null) {
+ for (RoleInfo roleInfo : roleInfoList) {
+ if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
+ throw new IllegalArgumentException("cannot delete admin: " + username);
+ }
+ }
+ }
+ userDetailsService.deleteUser(username);
+ return new RestResult<>(200, "delete user ok!");
+ }
+
+ /**
+ * Update an user
+ *
+ * @param username username of user
+ * @param newPassword new password of user
+ * @return ok if update succeed
+ * @throws IllegalArgumentException if user not exist or oldPassword is incorrect
+ * @since 1.2.0
+ */
+ @PutMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
+ public Object updateUser(@RequestParam String username, @RequestParam String newPassword) {
+
+ User user = userDetailsService.getUserFromDatabase(username);
+ if (user == null) {
+ throw new IllegalArgumentException("user " + username + " not exist!");
+ }
+
+ userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
+
+ return new RestResult<>(200, "update user ok!");
+ }
+
+ /**
+ * Get paged users
+ *
+ * @param pageNo number index of page
+ * @param pageSize size of page
+ * @return A collection of users, empty set if no user is found
+ * @since 1.2.0
+ */
+ @GetMapping
+ @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.READ)
+ public Object getUsers(@RequestParam int pageNo, @RequestParam int pageSize) {
+ return userDetailsService.getUsersFromDatabase(pageNo, pageSize);
+ }
+
+ /**
+ * Login to Nacos
+ *
+ * This methods uses username and password to require a new token.
+ *
+ * @param username username of user
+ * @param password password
+ * @param response http response
+ * @param request http request
+ * @return new token of the user
+ * @throws AccessException if user info is incorrect
+ */
+ @PostMapping("/login")
+ public Object login(@RequestParam String username, @RequestParam String password,
+ HttpServletResponse response, HttpServletRequest request) throws AccessException {
+
+
+ if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
+ NacosUser user = (NacosUser) authManager.login(request);
+
+ response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER,
+ NacosAuthConfig.TOKEN_PREFIX + user.getToken());
+
+ JSONObject result = new JSONObject();
+ result.put(Constants.ACCESS_TOKEN, user.getToken());
+ result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
+ result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
+ return result;
+ }
+
+ // 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
+
+ RestResult rr = new RestResult();
+ try {
+ //通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 Authentication 对象
+ Authentication authentication = authenticationManager.authenticate(authenticationToken);
+ //将 Authentication 绑定到 SecurityContext
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ //生成Token
+ String token = jwtTokenUtils.createToken(authentication);
+ //将Token写入到Http头部
+ response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token);
+ rr.setCode(200);
+ rr.setData("Bearer " + token);
+ return rr;
+ } catch (BadCredentialsException authentication) {
+ rr.setCode(401);
+ rr.setMessage("Login failed");
+ return rr;
+ }
+ }
+
+ @PutMapping("/password")
+ @Deprecated
+ public RestResult updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
+ @RequestParam(value = "newPassword") String newPassword) {
+
+ RestResult rr = new RestResult();
+ Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ String username = ((UserDetails) principal).getUsername();
+ User user = userDetailsService.getUserFromDatabase(username);
+ String password = user.getPassword();
+
+ // TODO: throw out more fine grained exceptions
+ try {
+ if (PasswordEncoderUtil.matches(oldPassword, password)) {
+ userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
+ rr.setCode(200);
+ rr.setMessage("Update password success");
+ } else {
+ rr.setCode(401);
+ rr.setMessage("Old password is invalid");
+ }
+ } catch (Exception e) {
+ rr.setCode(500);
+ rr.setMessage("Update userpassword failed");
+ }
+ return rr;
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java b/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
new file mode 100755
index 000000000..9d9d285a3
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.exception;
+
+import com.alibaba.nacos.core.auth.AccessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+/**
+ * Exception handler for console module
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+@ControllerAdvice
+public class ConsoleExceptionHandler {
+
+ private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
+
+ @ExceptionHandler(AccessException.class)
+ private ResponseEntity handleAccessException(AccessException e) {
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
+ }
+
+ @ExceptionHandler(IllegalArgumentException.class)
+ private ResponseEntity handleIllegalArgumentException(IllegalArgumentException e) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.toString());
+ }
+
+ @ExceptionHandler(Exception.class)
+ private ResponseEntity handleException(Exception e) {
+ logger.error("CONSOLE", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.toString());
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java b/pigx-register/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java
index b760d6d89..e4ba2c547 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/filter/JwtAuthenticationTokenFilter.java
@@ -15,11 +15,12 @@
*/
package com.alibaba.nacos.console.filter;
-import com.alibaba.nacos.console.config.WebSecurityConfig;
-import com.alibaba.nacos.console.utils.JwtTokenUtils;
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.console.security.nacos.JwtTokenManager;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
@@ -37,29 +38,23 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final String TOKEN_PREFIX = "Bearer ";
- private JwtTokenUtils tokenProvider;
+ private JwtTokenManager tokenManager;
- public JwtAuthenticationTokenFilter(JwtTokenUtils tokenProvider) {
- this.tokenProvider = tokenProvider;
+ public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) {
+ this.tokenManager = tokenManager;
}
@Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+
String jwt = resolveToken(request);
- if (jwt != null && !"".equals(jwt.trim()) && SecurityContextHolder.getContext().getAuthentication() == null) {
- if (this.tokenProvider.validateToken(jwt)) {
- /**
- * get auth info
- */
- Authentication authentication = this.tokenProvider.getAuthentication(jwt);
- /**
- * save user info to securityContext
- */
- SecurityContextHolder.getContext().setAuthentication(authentication);
- }
+ if (StringUtils.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
+ this.tokenManager.validateToken(jwt);
+ Authentication authentication = this.tokenManager.getAuthentication(jwt);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
}
-
chain.doFilter(request, response);
}
@@ -67,12 +62,12 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
* Get token from header
*/
private String resolveToken(HttpServletRequest request) {
- String bearerToken = request.getHeader(WebSecurityConfig.AUTHORIZATION_HEADER);
- if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
- return bearerToken.substring(7, bearerToken.length());
+ String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
+ if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
+ return bearerToken.substring(7);
}
- String jwt = request.getParameter(WebSecurityConfig.AUTHORIZATION_TOKEN);
- if (StringUtils.hasText(jwt)) {
+ String jwt = request.getParameter(Constants.ACCESS_TOKEN);
+ if (StringUtils.isNotBlank(jwt)) {
return jwt;
}
return null;
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetailsServiceImpl.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetailsServiceImpl.java
deleted file mode 100755
index e814c09eb..000000000
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetailsServiceImpl.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- * 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.
- */
-package com.alibaba.nacos.console.security;
-
-
-import com.alibaba.nacos.config.server.model.User;
-import com.alibaba.nacos.config.server.service.PersistService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-/**
- * Custem user service
- *
- * @author wfnuser
- */
-@Service
-public class CustomUserDetailsServiceImpl implements UserDetailsService {
-
- @Autowired
- private transient PersistService persistService;
-
- @Override
- public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
- User user = persistService.findUserByUsername(userName);
- if (user == null) {
- throw new UsernameNotFoundException(userName);
- }
- return new CustomUserDetails(user);
- }
-
- public void updateUserPassword(String username, String password) throws Exception {
- persistService.updateUserPassword(username, password);
- }
-}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomAuthenticationProvider.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java
similarity index 90%
rename from pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomAuthenticationProvider.java
rename to pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java
index 893cc313d..c54db33f7 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomAuthenticationProvider.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/CustomAuthenticationProvider.java
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.nacos.console.security;
+package com.alibaba.nacos.console.security.nacos;
+import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -32,7 +33,7 @@ import org.springframework.stereotype.Component;
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
- private CustomUserDetailsServiceImpl userDetailsService;
+ private NacosUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/JwtAuthenticationEntryPoint.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java
similarity index 82%
rename from pigx-register/src/main/java/com/alibaba/nacos/console/security/JwtAuthenticationEntryPoint.java
rename to pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java
index 9fe911c85..dad99758c 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/security/JwtAuthenticationEntryPoint.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtAuthenticationEntryPoint.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.nacos.console.security;
+package com.alibaba.nacos.console.security.nacos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,10 +37,10 @@ public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override
- public void commence(HttpServletRequest httpServletRequest,
- HttpServletResponse httpServletResponse,
+ public void commence(HttpServletRequest request,
+ HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
- logger.error("Responding with unauthorized error. Message - {}", e.getMessage());
- httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
+ logger.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI());
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java
new file mode 100755
index 000000000..0ef8fce1f
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/JwtTokenManager.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.security.nacos;
+
+import com.alibaba.nacos.core.auth.AuthConfigs;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * JWT token manager
+ *
+ * @author wfnuser
+ * @author nkorange
+ */
+@Component
+public class JwtTokenManager {
+
+ private static final String AUTHORITIES_KEY = "auth";
+
+ @Autowired
+ private AuthConfigs authConfigs;
+
+ /**
+ * Create token
+ *
+ * @param authentication auth info
+ * @return token
+ */
+ public String createToken(Authentication authentication) {
+ return createToken(authentication.getName());
+ }
+
+ public String createToken(String userName) {
+
+ long now = (new Date()).getTime();
+
+ Date validity;
+ validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L);
+
+ Claims claims = Jwts.claims().setSubject(userName);
+
+ return Jwts.builder()
+ .setClaims(claims)
+ .setExpiration(validity)
+ .signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey())
+ .compact();
+ }
+
+ /**
+ * Get auth Info
+ *
+ * @param token token
+ * @return auth info
+ */
+ public Authentication getAuthentication(String token) {
+ /**
+ * parse the payload of token
+ */
+ Claims claims = Jwts.parser()
+ .setSigningKey(authConfigs.getSecretKey())
+ .parseClaimsJws(token)
+ .getBody();
+
+ List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
+
+ User principal = new User(claims.getSubject(), "", authorities);
+ return new UsernamePasswordAuthenticationToken(principal, "", authorities);
+ }
+
+ /**
+ * validate token
+ *
+ * @param token token
+ * @return whether valid
+ */
+ public void validateToken(String token) {
+ Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/config/WebSecurityConfig.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java
similarity index 53%
rename from pigx-register/src/main/java/com/alibaba/nacos/console/config/WebSecurityConfig.java
rename to pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java
index 1ef0eaff2..78fe636b5 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/config/WebSecurityConfig.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthConfig.java
@@ -13,13 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.nacos.console.config;
+package com.alibaba.nacos.console.security.nacos;
+
import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter;
-import com.alibaba.nacos.console.security.CustomUserDetailsServiceImpl;
-import com.alibaba.nacos.console.security.JwtAuthenticationEntryPoint;
-import com.alibaba.nacos.console.utils.JwtTokenUtils;
+import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
+import com.alibaba.nacos.core.auth.AuthConfigs;
+import com.alibaba.nacos.core.auth.AuthSystemTypes;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@@ -34,6 +37,7 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.cors.CorsUtils;
/**
* Spring security config
@@ -42,61 +46,96 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
public static final String AUTHORIZATION_HEADER = "Authorization";
- public static final String AUTHORIZATION_TOKEN = "access_token";
-
public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ",";
- @Autowired
- private CustomUserDetailsServiceImpl userDetailsService;
+ public static final String LOGIN_ENTRY_POINT = "/v1/auth/login";
- @Autowired
- private JwtAuthenticationEntryPoint unauthorizedHandler;
+ public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/v1/auth/**";
- @Autowired
- private JwtTokenUtils tokenProvider;
+ public static final String TOKEN_PREFIX = "Bearer ";
+
+ public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/";
@Autowired
private Environment env;
+ @Autowired
+ private JwtTokenManager tokenProvider;
+
+ @Autowired
+ private AuthConfigs authConfigs;
+
+ @Autowired
+ private NacosUserDetailsServiceImpl userDetailsService;
+
+ @Value("${nacos.security.ignore.urls}")
+ private String ignoreURLs;
+
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
+ @Override
+ public void configure(WebSecurity web) {
+
+ if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
+ ignoreURLs = "/**";
+ }
+//
+ if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
+ ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
+ }
+
+ if (StringUtils.isNotBlank(ignoreURLs)) {
+ for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
+ web.ignoring().antMatchers(ignoreURL.trim());
+ }
+ }
+
+ }
+
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
- @Override
- public void configure(WebSecurity web) {
- String ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
- for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
- web.ignoring().antMatchers(ignoreURL.trim());
- }
- }
-
@Override
protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .anyRequest().authenticated().and()
- // custom token authorize exception handler
- .exceptionHandling()
- .authenticationEntryPoint(unauthorizedHandler).and()
- // since we use jwt, session is not necessary
- .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
- // since we use jwt, csrf is not necessary
- .csrf().disable();
- http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
- // disable cache
- http.headers().cacheControl();
+ if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
+ http
+
+ .csrf().disable()
+ .cors() // We don't need CSRF for JWT based authentication
+
+ .and()
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+
+ .and()
+ .authorizeRequests()
+ .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
+ .antMatchers(LOGIN_ENTRY_POINT).permitAll()
+
+ .and()
+ .authorizeRequests()
+ .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
+
+ .and()
+ .exceptionHandling()
+ .authenticationEntryPoint(new JwtAuthenticationEntryPoint());
+
+ // disable cache
+ http.headers().cacheControl();
+
+ http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
+ }
}
@Bean
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java
new file mode 100755
index 000000000..bd6d12293
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.security.nacos;
+
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.config.server.auth.RoleInfo;
+import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
+import com.alibaba.nacos.console.security.nacos.users.NacosUser;
+import com.alibaba.nacos.core.auth.AccessException;
+import com.alibaba.nacos.core.auth.AuthManager;
+import com.alibaba.nacos.core.auth.Permission;
+import com.alibaba.nacos.core.auth.User;
+import com.alibaba.nacos.core.utils.Loggers;
+import io.jsonwebtoken.ExpiredJwtException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * Builtin access control entry of Nacos
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+@Component
+public class NacosAuthManager implements AuthManager {
+
+ private static final String TOKEN_PREFIX = "Bearer ";
+
+ @Autowired
+ private JwtTokenManager tokenManager;
+
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ @Autowired
+ private NacosRoleServiceImpl roleService;
+
+ @Override
+ public User login(Object request) throws AccessException {
+ HttpServletRequest req = (HttpServletRequest) request;
+ String token = resolveToken(req);
+ if (StringUtils.isBlank(token)) {
+ throw new AccessException("user not found!");
+ }
+
+ try {
+ tokenManager.validateToken(token);
+ } catch (ExpiredJwtException e) {
+ throw new AccessException("token expired!");
+ } catch (Exception e) {
+ throw new AccessException("token invalid!");
+ }
+
+ Authentication authentication = tokenManager.getAuthentication(token);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ String username = authentication.getName();
+ NacosUser user = new NacosUser();
+ user.setUserName(username);
+ user.setToken(token);
+ List roleInfoList = roleService.getRoles(username);
+ if (roleInfoList != null) {
+ for (RoleInfo roleInfo : roleInfoList) {
+ if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
+ user.setGlobalAdmin(true);
+ break;
+ }
+ }
+ }
+
+ return user;
+ }
+
+ @Override
+ public void auth(Permission permission, User user) throws AccessException {
+ if (Loggers.AUTH.isDebugEnabled()) {
+ Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
+ }
+
+ if (!roleService.hasPermission(user.getUserName(), permission)) {
+ throw new AccessException("authorization failed!");
+ }
+ }
+
+ /**
+ * Get token from header
+ */
+ private String resolveToken(HttpServletRequest request) throws AccessException {
+ String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
+ if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
+ return bearerToken.substring(7);
+ }
+ bearerToken = request.getParameter(Constants.ACCESS_TOKEN);
+ if (StringUtils.isBlank(bearerToken)) {
+ String userName = request.getParameter("username");
+ String password = request.getParameter("password");
+ bearerToken = resolveTokenFromUser(userName, password);
+ }
+
+ return bearerToken;
+ }
+
+ private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException {
+
+ try {
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, rawPassword);
+ authenticationManager.authenticate(authenticationToken);
+ } catch (AuthenticationException e) {
+ throw new AccessException("unknown user!");
+ }
+
+ return tokenManager.createToken(userName);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java
new file mode 100755
index 000000000..0799c1f31
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.security.nacos.roles;
+
+
+import com.alibaba.nacos.config.server.auth.PermissionInfo;
+import com.alibaba.nacos.config.server.auth.PermissionPersistService;
+import com.alibaba.nacos.config.server.auth.RoleInfo;
+import com.alibaba.nacos.config.server.auth.RolePersistService;
+import com.alibaba.nacos.config.server.model.Page;
+import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
+import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
+import com.alibaba.nacos.core.auth.AuthConfigs;
+import com.alibaba.nacos.core.auth.Permission;
+import com.alibaba.nacos.core.utils.Loggers;
+import io.jsonwebtoken.lang.Collections;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.mina.util.ConcurrentHashSet;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+/**
+ * Nacos builtin role service.
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+@Service
+public class NacosRoleServiceImpl {
+
+ public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
+
+ @Autowired
+ private AuthConfigs authConfigs;
+
+ @Autowired
+ private RolePersistService rolePersistService;
+
+ @Autowired
+ private NacosUserDetailsServiceImpl userDetailsService;
+
+ @Autowired
+ private PermissionPersistService permissionPersistService;
+
+ private Set roleSet = new ConcurrentHashSet<>();
+
+ private Map> roleInfoMap = new ConcurrentHashMap<>();
+
+ private Map> permissionInfoMap = new ConcurrentHashMap<>();
+
+ @Scheduled(initialDelay = 5000, fixedDelay = 15000)
+ private void reload() {
+ try {
+ Page roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE);
+ if (roleInfoPage == null) {
+ return;
+ }
+ Set tmpRoleSet = new HashSet<>(16);
+ Map> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
+ for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
+ if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
+ tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
+ }
+ tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
+ tmpRoleSet.add(roleInfo.getRole());
+ }
+
+ Map> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
+ for (String role : tmpRoleSet) {
+ Page permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE);
+ tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
+ }
+
+ roleSet = tmpRoleSet;
+ roleInfoMap = tmpRoleInfoMap;
+ permissionInfoMap = tmpPermissionInfoMap;
+ } catch (Exception e) {
+ Loggers.AUTH.warn("[LOAD-ROLES] load failed", e);
+ }
+ }
+
+ /**
+ * Determine if the user has permission of the resource.
+ *
+ * Note if the user has many roles, this method returns true if any one role of the user has the
+ * desired permission.
+ *
+ * @param username user info
+ * @param permission permission to auth
+ * @return true if granted, false otherwise
+ */
+ public boolean hasPermission(String username, Permission permission) {
+
+ List roleInfoList = getRoles(username);
+ if (Collections.isEmpty(roleInfoList)) {
+ return false;
+ }
+
+ // Global admin pass:
+ for (RoleInfo roleInfo : roleInfoList) {
+ if (GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) {
+ return true;
+ }
+ }
+
+ // Old global admin can pass resource 'console/':
+ if (permission.getResource().startsWith(NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX)) {
+ return false;
+ }
+
+ // For other roles, use a pattern match to decide if pass or not.
+ for (RoleInfo roleInfo : roleInfoList) {
+ List permissionInfoList = getPermissions(roleInfo.getRole());
+ if (Collections.isEmpty(permissionInfoList)) {
+ continue;
+ }
+ for (PermissionInfo permissionInfo : permissionInfoList) {
+ String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
+ String permissionAction = permissionInfo.getAction();
+ if (permissionAction.contains(permission.getAction()) &&
+ Pattern.matches(permissionResource, permission.getResource())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public List getRoles(String username) {
+ List roleInfoList = roleInfoMap.get(username);
+ if (!authConfigs.isCachingEnabled()) {
+ Page roleInfoPage = getRolesFromDatabase(username, 1, Integer.MAX_VALUE);
+ if (roleInfoPage != null) {
+ roleInfoList = roleInfoPage.getPageItems();
+ }
+ }
+ return roleInfoList;
+ }
+
+ public Page getRolesFromDatabase(String userName, int pageNo, int pageSize) {
+ Page roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize);
+ if (roles == null) {
+ return new Page<>();
+ }
+ return roles;
+ }
+
+ public List getPermissions(String role) {
+ List permissionInfoList = permissionInfoMap.get(role);
+ if (!authConfigs.isCachingEnabled()) {
+ Page permissionInfoPage = getPermissionsFromDatabase(role, 1, Integer.MAX_VALUE);
+ if (permissionInfoPage != null) {
+ permissionInfoList = permissionInfoPage.getPageItems();
+ }
+ }
+ return permissionInfoList;
+ }
+
+ public Page getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) {
+ return permissionPersistService.getPermissions(role, pageNo, pageSize);
+ }
+
+ public void addRole(String role, String username) {
+ if (userDetailsService.getUser(username) == null) {
+ throw new IllegalArgumentException("user '" + username + "' not found!");
+ }
+ if (GLOBAL_ADMIN_ROLE.equals(role)) {
+ throw new IllegalArgumentException("role '" + GLOBAL_ADMIN_ROLE + "' is not permitted to create!");
+ }
+ rolePersistService.addRole(role, username);
+ roleSet.add(role);
+ }
+
+ public void deleteRole(String role, String userName) {
+ rolePersistService.deleteRole(role, userName);
+ }
+
+ public void deleteRole(String role) {
+ rolePersistService.deleteRole(role);
+ roleSet.remove(role);
+ }
+
+ public Page getPermissionsFromDatabase(String role, int pageNo, int pageSize) {
+ Page pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize);
+ if (pageInfo == null) {
+ return new Page<>();
+ }
+ return pageInfo;
+ }
+
+ public void addPermission(String role, String resource, String action) {
+ if (!roleSet.contains(role)) {
+ throw new IllegalArgumentException("role " + role + " not found!");
+ }
+ permissionPersistService.addPermission(role, resource, action);
+ }
+
+ public void deletePermission(String role, String resource, String action) {
+ permissionPersistService.deletePermission(role, resource, action);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java
new file mode 100755
index 000000000..f2f519c58
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+
+package com.alibaba.nacos.console.security.nacos.users;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.core.auth.User;
+
+/**
+ * @author nkorange
+ * @since 1.2.0
+ */
+public class NacosUser extends User {
+
+ private String token;
+
+ private boolean globalAdmin = false;
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public boolean isGlobalAdmin() {
+ return globalAdmin;
+ }
+
+ public void setGlobalAdmin(boolean globalAdmin) {
+ this.globalAdmin = globalAdmin;
+ }
+
+ @Override
+ public String toString() {
+ return JSON.toJSONString(this);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetails.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java
similarity index 91%
rename from pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetails.java
rename to pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java
index 6e34e4a51..3390a2ce2 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/security/CustomUserDetails.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetails.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.nacos.console.security;
+package com.alibaba.nacos.console.security.nacos.users;
import com.alibaba.nacos.config.server.model.User;
import org.springframework.security.core.GrantedAuthority;
@@ -27,11 +27,11 @@ import java.util.Collection;
*
* @author wfnuser
*/
-public class CustomUserDetails implements UserDetails {
+public class NacosUserDetails implements UserDetails {
private User user;
- public CustomUserDetails(User user) {
+ public NacosUserDetails(User user) {
this.user = user;
}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java
new file mode 100755
index 000000000..7c9b66ceb
--- /dev/null
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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.
+ */
+package com.alibaba.nacos.console.security.nacos.users;
+
+
+import com.alibaba.nacos.config.server.auth.UserPersistService;
+import com.alibaba.nacos.config.server.model.Page;
+import com.alibaba.nacos.config.server.model.User;
+import com.alibaba.nacos.core.auth.AuthConfigs;
+import com.alibaba.nacos.core.utils.Loggers;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Custem user service
+ *
+ * @author wfnuser
+ * @author nkorange
+ */
+@Service
+public class NacosUserDetailsServiceImpl implements UserDetailsService {
+
+ private Map userMap = new ConcurrentHashMap<>();
+
+ @Autowired
+ private UserPersistService userPersistService;
+
+ @Autowired
+ private AuthConfigs authConfigs;
+
+ @Scheduled(initialDelay = 5000, fixedDelay = 15000)
+ private void reload() {
+ try {
+ Page users = getUsersFromDatabase(1, Integer.MAX_VALUE);
+ if (users == null) {
+ return;
+ }
+
+ Map map = new ConcurrentHashMap<>(16);
+ for (User user : users.getPageItems()) {
+ map.put(user.getUsername(), user);
+ }
+ userMap = map;
+ } catch (Exception e) {
+ Loggers.AUTH.warn("[LOAD-USERS] load failed", e);
+ }
+ }
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+
+ User user = userMap.get(username);
+ if (!authConfigs.isCachingEnabled()) {
+ user = userPersistService.findUserByUsername(username);
+ }
+
+ if (user == null) {
+ throw new UsernameNotFoundException(username);
+ }
+ return new NacosUserDetails(user);
+ }
+
+ public void updateUserPassword(String username, String password) {
+ userPersistService.updateUserPassword(username, password);
+ }
+
+ public Page getUsersFromDatabase(int pageNo, int pageSize) {
+ return userPersistService.getUsers(pageNo, pageSize);
+ }
+
+ public User getUser(String username) {
+ User user = userMap.get(username);
+ if (!authConfigs.isCachingEnabled()) {
+ user = getUserFromDatabase(username);
+ }
+ return user;
+ }
+
+ public User getUserFromDatabase(String username) {
+ return userPersistService.findUserByUsername(username);
+ }
+
+ public void createUser(String username, String password) {
+ userPersistService.createUser(username, password);
+ }
+
+ public void deleteUser(String username) {
+ userPersistService.deleteUser(username);
+ }
+}
diff --git a/pigx-register/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java b/pigx-register/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java
index 1057d4620..55b32401e 100755
--- a/pigx-register/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java
+++ b/pigx-register/src/main/java/com/alibaba/nacos/console/utils/JwtTokenUtils.java
@@ -16,8 +16,10 @@
package com.alibaba.nacos.console.utils;
import io.jsonwebtoken.*;
+import io.jsonwebtoken.security.Keys;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@@ -26,6 +28,7 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
+import javax.crypto.SecretKey;
import java.util.Date;
import java.util.List;
@@ -42,10 +45,26 @@ public class JwtTokenUtils {
private static final String AUTHORITIES_KEY = "auth";
+ /**
+ * minimum SHA_256 secretKey string length
+ */
+ private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8;
+
+ /**
+ * default SHA_256 secretKey flag
+ */
+ private static final String DEFAULT_SECRET_FLAG = "default";
+
+ /**
+ * custom SHA_256 secretKey from config property
+ */
+ @Value("${nacos.security.token.secret-key:default}")
+ private String customSecretKeyStr;
+
/**
* secret key
*/
- private String secretKey;
+ private SecretKey secretKey;
/**
* Token validity time(ms)
@@ -54,7 +73,24 @@ public class JwtTokenUtils {
@PostConstruct
public void init() {
- this.secretKey = "SecretKey012345678901234567890123456789012345678901234567890123456789";
+ //use default secretKey for SHA-256
+ if (customSecretKeyStr == null || DEFAULT_SECRET_FLAG.equals(customSecretKeyStr)) {
+ this.secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
+ } else {
+ //use custom secretKey
+ int size = customSecretKeyStr.length();
+ int left = SHA_256_SECRET_CHAR_SIZE - size;
+ if (left > 0) {
+ //character for padding
+ StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr);
+ for (int i = 0 ;i < left ; i ++){
+ stringBuilder.append(i%10);
+ }
+ this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes());
+ }else {
+ this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes());
+ }
+ }
this.tokenValidityInMilliseconds = 1000 * 60 * 30L;
}
@@ -82,7 +118,7 @@ public class JwtTokenUtils {
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, "")
.setExpiration(validity)
- .signWith(SignatureAlgorithm.HS256, secretKey)
+ .signWith(secretKey, SignatureAlgorithm.HS256)
.compact();
}
diff --git a/pigx-register/src/main/resources/application.yml b/pigx-register/src/main/resources/application.yml
new file mode 100755
index 000000000..62fa263c1
--- /dev/null
+++ b/pigx-register/src/main/resources/application.yml
@@ -0,0 +1,30 @@
+server:
+ port: 8848
+ tomcat:
+ basedir: logs
+
+db:
+ num: 1
+ user: ${MYSQL-USER:root}
+ password: ${MYSQL-PWD:root}
+ url:
+ 0: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
+
+
+nacos:
+ core:
+ auth:
+ system.type: nacos
+ default.token.secret.key: SecretKey012345678901234567890123456789012345678901234567890123456789
+ security:
+ ignore:
+ urls: /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
+
+spring:
+ datasource:
+ platform: mysql
+ security:
+ enabled: true
+
+useAddressServer: true
+
diff --git a/pigx-register/src/main/resources/bootstrap.yml b/pigx-register/src/main/resources/bootstrap.yml
deleted file mode 100755
index 0eec1b8f0..000000000
--- a/pigx-register/src/main/resources/bootstrap.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-nacos:
- cmdb:
- dumpTaskInterval: 3600
- eventTaskInterval: 10
- labelTaskInterval: 300
- loadDataAtStart: false
- security: # 删除此配置无需登录验证
- ignore:
- urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health/**,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**,/v1/console/server/**
-
-db:
- num: 1
- user: ${MYSQL-USER:root}
- password: ${MYSQL-PWD:root}
- url:
- 0: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
-
-spring:
- datasource:
- platform: mysql
- security:
- enabled: true
-
-server:
- tomcat:
- basedir: logs
-
diff --git a/pigx-register/src/main/resources/static/console-fe/.eslintrc b/pigx-register/src/main/resources/static/console-fe/.eslintrc
index bbb6e5c04..3c1a725af 100755
--- a/pigx-register/src/main/resources/static/console-fe/.eslintrc
+++ b/pigx-register/src/main/resources/static/console-fe/.eslintrc
@@ -30,6 +30,7 @@
"generator-star-spacing": "off",
"wrap-iife": "off",
"arrow-parens": "off",
- "indent": "off"
+ "indent": "off",
+ "comma-dangle": "off"
}
}
diff --git a/pigx-register/src/main/resources/static/console-fe/package.json b/pigx-register/src/main/resources/static/console-fe/package.json
index 778ddac62..861f8d5b4 100755
--- a/pigx-register/src/main/resources/static/console-fe/package.json
+++ b/pigx-register/src/main/resources/static/console-fe/package.json
@@ -27,55 +27,56 @@
},
"devDependencies": {
"@alifd/next-theme-loader": "^1.3.1",
- "@babel/cli": "^7.2.3",
- "@babel/core": "^7.2.2",
- "@babel/plugin-proposal-decorators": "^7.2.3",
- "@babel/preset-env": "^7.2.3",
- "@babel/runtime": "^7.2.0",
+ "@babel/cli": "^7.7.7",
+ "@babel/core": "^7.7.7",
+ "@babel/plugin-proposal-decorators": "^7.7.4",
+ "@babel/preset-env": "^7.7.7",
+ "@babel/runtime": "^7.7.7",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
- "babel-plugin-import": "^1.12.0",
- "babel-preset-react-app": "^6.1.0",
- "clean-webpack-plugin": "^0.1.19",
- "copy-webpack-plugin": "^4.6.0",
- "cross-env": "^5.2.0",
- "css-loader": "^2.0.2",
- "eslint": "^5.11.0",
- "eslint-config-ali": "^4.1.0",
- "eslint-config-prettier": "^3.3.0",
- "eslint-loader": "^2.1.1",
+ "babel-plugin-import": "^1.13.0",
+ "babel-preset-react-app": "^9.1.0",
+ "clean-webpack-plugin": "^3.0.0",
+ "copy-webpack-plugin": "^5.1.1 ",
+ "cross-env": "^6.0.3",
+ "css-loader": "^3.4.0",
+ "eslint": "^6.8.0",
+ "eslint-config-ali": "^9.0.2",
+ "eslint-config-prettier": "^6.8.0",
+ "eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-prettier": "^3.0.0",
- "eslint-plugin-react": "^7.11.1",
- "file-loader": "^2.0.0",
+ "eslint-plugin-react": "^7.17.0",
+ "eslint-plugin-react-hooks": "^2.3.0",
+ "file-loader": "^5.0.2",
"html-webpack-plugin": "^3.2.0",
- "husky": "^1.1.4",
- "lint-staged": "^8.0.4",
- "mini-css-extract-plugin": "^0.5.0",
- "node-sass": "^4.11.0",
- "optimize-css-assets-webpack-plugin": "^5.0.1",
- "prettier": "1.15.2",
- "sass-loader": "^7.1.0",
- "style-loader": "^0.23.1",
- "uglifyjs-webpack-plugin": "^2.1.0",
- "url-loader": "^1.1.2",
- "webpack": "^4.28.2",
- "webpack-cli": "^3.1.2",
- "webpack-dev-server": "^3.1.13"
+ "husky": "^3.1.0",
+ "lint-staged": "^9.5.0",
+ "mini-css-extract-plugin": "^0.9.0",
+ "node-sass": "^4.13.0",
+ "optimize-css-assets-webpack-plugin": "^5.0.3",
+ "prettier": "1.19.1",
+ "sass-loader": "^8.0.0",
+ "style-loader": "^1.1.2",
+ "uglifyjs-webpack-plugin": "^2.2.0",
+ "url-loader": "^3.0.0",
+ "webpack": "^4.41.4",
+ "webpack-cli": "^3.3.10",
+ "webpack-dev-server": "^3.10.1"
},
"dependencies": {
- "@alifd/next": "^1.15.12",
+ "@alifd/next": "^1.17.4",
"axios": "^0.18.0",
"jquery": "^3.3.1",
"moment": "^2.23.0",
"prop-types": "^15.6.2",
- "react": "^16.7.0",
- "react-dom": "^16.7.0",
- "react-redux": "^5.1.1",
- "react-router": "^4.3.1",
- "react-router-dom": "^4.3.1",
+ "react": "^16.12.0",
+ "react-dom": "^16.12.0",
+ "react-redux": "^7.1.3",
+ "react-router": "^5.1.2",
+ "react-router-dom": "^5.1.2",
"react-router-redux": "^4.0.8",
- "redux": "^4.0.1",
+ "redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"yamljs": "^0.3.0"
}
diff --git a/pigx-register/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js b/pigx-register/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js
index 88c6c9b9b..bdbb89758 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/components/NewNameSpace/NewNameSpace.js
@@ -109,14 +109,17 @@ class NewNameSpace extends React.Component {
this.setState({
disabled: true,
});
+ let { customNamespaceId } = values;
+ if (!customNamespaceId) {
+ customNamespaceId = '';
+ }
request({
- type: 'post',
- url: 'v1/console/namespaces',
+ type: 'get',
+ url: 'v1/console/namespaces?checkNamespaceIdExist=true',
contentType: 'application/x-www-form-urlencoded',
beforeSend: () => this.openLoading(),
data: {
- namespaceName: values.namespaceShowName,
- namespaceDesc: values.namespaceDesc,
+ customNamespaceId,
},
success: res => {
this.disabled = false;
@@ -124,13 +127,38 @@ class NewNameSpace extends React.Component {
disabled: false,
});
if (res === true) {
- this.closeDialog();
- this.props.getNameSpaces();
- this.refreshNameSpace(); // 刷新全局namespace
- } else {
Dialog.alert({
title: locale.notice,
- content: res.message,
+ content: locale.namespaceIdAlreadyExist,
+ });
+ } else {
+ request({
+ type: 'post',
+ url: 'v1/console/namespaces',
+ contentType: 'application/x-www-form-urlencoded',
+ beforeSend: () => this.openLoading(),
+ data: {
+ customNamespaceId,
+ namespaceName: values.namespaceShowName,
+ namespaceDesc: values.namespaceDesc,
+ },
+ success: res => {
+ this.disabled = false;
+ this.setState({
+ disabled: false,
+ });
+ if (res === true) {
+ this.closeDialog();
+ this.props.getNameSpaces();
+ this.refreshNameSpace(); // 刷新全局namespace
+ } else {
+ Dialog.alert({
+ title: locale.notice,
+ content: locale.newnamespceFailedMessage,
+ });
+ }
+ },
+ complete: () => this.closeLoading(),
});
}
},
@@ -164,6 +192,32 @@ class NewNameSpace extends React.Component {
}
}
+ validateNamespzecId(rule, value, callback) {
+ if (!value || value.trim() === '') {
+ callback();
+ } else {
+ const { locale = {} } = this.props;
+ if (value.length > 128) {
+ callback(locale.namespaceIdTooLong);
+ }
+ const chartReg = /^[\w-]+/g;
+ const matchResult = value.match(chartReg);
+ if (matchResult) {
+ if (matchResult.length > 1) {
+ callback(locale.input);
+ } else {
+ if (value.length !== matchResult[0].length) {
+ callback(locale.input);
+ return;
+ }
+ callback();
+ }
+ } else {
+ callback(locale.input);
+ }
+ }
+ }
+
render() {
const { locale = {} } = this.props;
const footer = (
@@ -193,6 +247,14 @@ class NewNameSpace extends React.Component {
style={{ width: '100%', position: 'relative' }}
visible={this.state.loading}
>
+
+
+
{
- this.setRegionWidth();
- }
+ () => this.setRegionWidth()
);
}
diff --git a/pigx-register/src/main/resources/static/console-fe/src/constants.js b/pigx-register/src/main/resources/static/console-fe/src/constants.js
index 5b67ffe4d..cea183963 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/constants.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/constants.js
@@ -23,3 +23,15 @@ export const GET_STATE = 'GET_STATE';
export const GET_SUBSCRIBERS = 'GET_SUBSCRIBERS';
export const REMOVE_SUBSCRIBERS = 'REMOVE_SUBSCRIBERS';
+
+export const UPDATE_USER = 'UPDATE_USER';
+export const SIGN_IN = 'SIGN_IN';
+export const USER_LIST = 'USER_LIST';
+
+export const ROLE_LIST = 'ROLE_LIST';
+
+export const PERMISSIONS_LIST = 'PERMISSIONS_LIST';
+
+export const GET_NAMESPACES = 'GET_NAMESPACES';
+
+export const GET_CONFIGURATION = 'GET_CONFIGURATION';
diff --git a/pigx-register/src/main/resources/static/console-fe/src/globalLib.js b/pigx-register/src/main/resources/static/console-fe/src/globalLib.js
index 1eb23c06a..050463208 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/globalLib.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/globalLib.js
@@ -12,9 +12,16 @@
*/
import projectConfig from './config';
-import moment from 'moment';
import $ from 'jquery';
-import i18DocObj from './i18ndoc';
+import { Message } from '@alifd/next';
+
+function goLogin() {
+ const url = window.location.href;
+ localStorage.removeItem('token');
+ const base_url = url.split('#')[0];
+ console.log('base_url', base_url);
+ window.location = `${base_url}#/login`;
+}
const global = window;
@@ -205,120 +212,6 @@ const nacosUtils = (function(_global) {
};
})(global);
-const aliwareIntl = (function(_global) {
- /**
- * 国际化构造方法
- * @param {Object} options 配置信息
- */
- function AliwareI18n(options) {
- // let currentLocal = options.currentLocal || navigator.language || navigator.userLanguage;
-
- const nowData = options.locals;
- this.nowData = nowData;
- this.setMomentLocale(this.currentLanguageCode);
- }
-
- let aliwareLocal = aliwareGetCookieByKeyName('aliyun_lang') || 'zh';
- let aliwareLocalSite = aliwareGetCookieByKeyName('aliyun_country') || 'cn';
- aliwareLocal = aliwareLocal.toLowerCase();
- aliwareLocalSite = aliwareLocalSite.toLowerCase();
- // 当前语言
- AliwareI18n.prototype.currentLocal = aliwareLocal;
- // 当前地区
- AliwareI18n.prototype.currentSite = aliwareLocalSite;
- // 当前语言-地区
- AliwareI18n.prototype.currentLanguageCode =
- aliwareGetCookieByKeyName('docsite_language') || `${aliwareLocal}-${aliwareLocalSite}`;
- /**
- * 通过key获取对应国际化文案
- * @param {String} key 国际化key
- */
- AliwareI18n.prototype.get = function(key) {
- return this.nowData[key];
- };
- /**
- * 修改国际化文案数据
- * @param {String} local 语言信息
- */
- AliwareI18n.prototype.changeLanguage = function(local) {
- this.nowData = i18DocObj[local] || {};
- };
- /**
- * 数字国际化
- * @param {Number} num 数字
- */
- AliwareI18n.prototype.intlNumberFormat = function(num) {
- if (typeof Intl !== 'object' || typeof Intl.NumberFormat !== 'function') {
- return num;
- }
- try {
- return new Intl.NumberFormat(this.currentLanguageCode).format(num || 0);
- } catch (error) {
- return num;
- }
- };
- /**
- * 时间戳格式化
- * @param {Number} num 时间戳
- * @param {Object} initOption 配置信息
- */
- AliwareI18n.prototype.intlTimeFormat = function(num = Date.now(), initOption = {}) {
- try {
- const date = Object.prototype.toString.call(num) === '[object Date]' ? num : new Date(num);
- const options = Object.assign(
- {},
- {
- // weekday: "short",
- hour12: false,
- year: 'numeric',
- month: 'short',
- day: 'numeric',
- hour: 'numeric',
- minute: 'numeric',
- second: 'numeric',
- },
- initOption
- );
- return date.toLocaleDateString(this.currentLanguageCode, options);
- } catch (error) {
- return typeof moment === 'function' ? moment(num).format() : '--';
- }
- };
- /**
- * 获取当前时间格式
- * @param {String} language 语言信息: zh/en
- */
- AliwareI18n.prototype.getIntlTimeFormat = function(_language) {
- const language = _language || aliwareLocal;
- const langObj = {
- zh: 'YYYY年M月D日 HH:mm:ss',
- en: 'MMM D, YYYY, h:mm:ss A',
- default: 'YYYY-MM-DD HH:mm:ss',
- };
- return langObj[language] ? langObj[language] : langObj.default;
- };
- /**
- * 设置moment的locale
- * @param {String} languageCode 语言信息: zh-ch/en-us
- */
- AliwareI18n.prototype.setMomentLocale = function(languageCode) {
- if (Object.prototype.toString.call(moment) === '[object Function]') {
- moment.locale(languageCode || this.currentLanguageCode);
- return true;
- }
- return false;
- };
-
- return new AliwareI18n({
- currentLocal: `${aliwareLocal}`,
- locals:
- i18DocObj[AliwareI18n.prototype.currentLanguageCode] ||
- i18DocObj['en-us'] ||
- i18DocObj['zh-cn'] ||
- {},
- });
-})(global);
-
/**
* 获取url中的参数
*/
@@ -561,7 +454,7 @@ const request = (function(_global) {
} catch (e) {}
// 设置自动loading效果
if (serviceObj.autoLoading) {
- nacosUtils.openLoading();
+ // nacosUtils.openLoading();
const prevComplete = config.complete;
config.complete = function() {
nacosUtils.closeLoading();
@@ -597,11 +490,22 @@ const request = (function(_global) {
// 处理后置中间件
config = handleMiddleWare.apply(this, [config, ...args, middlewareBackList]);
+ let token = {};
+ try {
+ token = JSON.parse(localStorage.token);
+ } catch (e) {
+ console.log('Token Erro', localStorage.token, e);
+ goLogin();
+ }
+ const { accessToken = '' } = token;
+ const [url, paramsStr = ''] = config.url.split('?');
+ const params = paramsStr.split('&');
+ params.push(`accessToken=${accessToken}`);
return $.ajax(
Object.assign({}, config, {
type: config.type,
- url: config.url,
+ url: [url, params.join('&')].join('?'),
data: config.data || '',
dataType: config.dataType || 'json',
beforeSend(xhr) {
@@ -615,17 +519,17 @@ const request = (function(_global) {
success => {},
error => {
// 处理403 forbidden
- if (error && (error.status === 403 || error.status === 401)) {
- // 跳转至login页
- // TODO: 用 react-router 重写,改造成本比较高,这里先hack
- const url = window.location.href;
- // TODO: 后端返回细致的错误码,如果原始密码不对 不应该直接跳到登陆页
- if (url.includes('password')) {
- return;
- }
- const base_url = url.split('#')[0];
- window.location = `${base_url}#/login`;
+ const { status, responseJSON = {} } = error || {};
+ if (responseJSON.message) {
+ Message.error(responseJSON.message);
}
+ if (
+ [401, 403].includes(status) &&
+ ['unknown user!', 'token invalid', 'token expired!'].includes(responseJSON.message)
+ ) {
+ goLogin();
+ }
+ return error;
}
);
}
@@ -645,10 +549,9 @@ export {
nacosEvent,
nacosUtils,
aliwareGetCookieByKeyName,
- aliwareIntl,
+ removeParams,
getParams,
setParam,
setParams,
- removeParams,
request,
};
diff --git a/pigx-register/src/main/resources/static/console-fe/src/i18ndoc.js b/pigx-register/src/main/resources/static/console-fe/src/i18ndoc.js
deleted file mode 100755
index 4f6d4b373..000000000
--- a/pigx-register/src/main/resources/static/console-fe/src/i18ndoc.js
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * Copyright 1999-2018 Alibaba Group Holding Ltd.
- * 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.
- */
-module.exports = {
- 'zh-cn': {
- 'com.alibaba.nacos.layout.noenv.nacosversion': '0.8.0',
- 'com.alibaba.nacos.page.configurationManagementVirtual': '配置管理',
- 'com.alibaba.nacos.page.serviceManagementVirtual': '服务管理',
- 'nacos.component.ExportDialog.tags2': '标签:',
- historyRollback: '历史版本',
- 'com.alibaba.nacos.component.MiddleWareEnv.Spas_dedicated': 'Spas专用',
- 'com.alibaba.nacos.page.pushTrajectory.track': '条轨迹。',
- 'com.alibaba.nacos.component.NameSpaceList.Prompt': '提示',
- 'nacos.page.namespace.namespace_ID': '命名空间ID:',
- 'com.alibaba.nacos.page.historyrollback.query': '查询',
- 'com.alibaba.nacos.page.configdetail.configuration_details': '配置详情',
- 'com.alibaba.nacos.component.AddGroup.a_new_group': '新建Group',
- 'com.alibaba.nacos.component.DiffEditorDialog.contents': '内容比较',
- namespace: '命名空间',
- 'com.alibaba.nacos.page.historyRollback.queryresult': '查询结果:共查询到',
- 'com.alibaba.nacos.page.pushTrajectory.determine': '查询',
- 'com.alibaba.nacos.component.NameSpaceList.online_customer_support': '在线客服支持:',
- 'com.alibaba.nacos.page.historyRollback.dataid': '请输入Data ID',
- 'nacos.page.configurationManagement.Please_enter_tag': '请输入标签',
- 'nacos.page.namespace.namespace_number': '命名空间ID',
- 'nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_message':
- '公告:Node.js版上线。支持定制消息。',
- 'com.alibaba.nacos.page.configRollback.retracted': '收起',
- 'com.alibaba.nacos.component.NewDatePicker.to_cancel_the': '确定',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_units': '日常单元',
- 'nacos.page.configdetail.Open0': '开',
- 'com.alibaba.nacos.page.configeditor.vdchart': '请勿输入非法字符',
- 'com.alibaba.nacos.component.EditorNameSpace.prompt': '提示',
- 'com.alibaba.nacos.component.DiffEditorDialog.confirm_that_the': '确认发布',
- 'com.alibaba.nacos.component.NewDatePicker.': '最近',
- 'com.alibaba.nacos.pubshow': '子账号没有权限,请联系主账号负责人RAM上授权',
- 'com.alibaba.nacos.page.configeditor.Home_application:': 'Group不能为空',
- 'nacos.page.configdetail.Tags': '标签:',
- 'com.alibaba.nacos.page.configurationManagement.configuration_management': '配置列表',
- 'nacos.page.configurationManagement.Tags': '标签:',
- 'com.alibaba.nacos.page.newconfig.new_listing': '新建配置',
- 'com.alibaba.nacos.page.configsync.target': '目标地域:',
- 'nacos.component.ExportDialog.configuration_number6': '配置数量:',
- 'nacos.component.validateDialog.title': '账号安全验证',
- 'nacos.page.configurationManagement.,_wherein': ',其中',
- 'com.alibaba.nacos.component.MiddleWareEnv.switch_environment': '切换环境',
- 'com.alibaba.nacos.page.configsync.return': '返回',
- newconfig: '新建配置',
- 'com.alibaba.nacos.page.configeditor.': '返回',
- 'com.alibaba.nacos.page.configsync.sync': '同步',
- 'com.alibaba.nacos.component.NewDatePicker.24_hours': '24小时',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_name': '环境名称',
- 'nacos.component.validateDialog.Click_to_get_verification_code': '点击获取验证码',
- 'com.alibaba.nacos.page.consistencyEfficacy.environment_marked': '环境标示',
- 'com.alibaba.nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_message':
- '公告:Node.js版上线,支持定制消息。',
- 'nacos.page.configurationManagement.process_is_successful,_the_cloned': '处理成功,克隆了',
- 'com.alibaba.nacos.page.configurationManagement.the_sample_code': '示例代码',
- 'nacos.component.CloneDialog.|_the_selected_entry4': '| 选中的条目',
- confirm: '确定',
- 'com.alibaba.nacos.page.configRollback.delete': '删除',
- 'com.alibaba.nacos.page.configsync.belongs_to_the_environment': '所属地域:',
- 'com.alibaba.nacos.component.ShowCodeing.loading': '加载中...',
- 'nacos.page.configurationManagement.import_failed': '导入失败',
- 'com.alibaba.nacos.page.configurationManagement.clickfordetail': '点击了解SDK详细示例',
- 'nacos.page.configurationManagement.configuration_management8': '配置管理',
- 'com.alibaba.nacos.page.consistencyEfficacy.operation': '操作',
- 'com.alibaba.nacos.page.environmentalManagement.view_environment_IP': '查看环境IP',
- 'com.alibaba.nacos.page.configeditor.configuration_formatpre': '默认不要勾选。',
- 'nacos.page.configurationManagement.Delete_failed': '删除失败',
- 'com.alibaba.nacos.page.environmentalManagement.environment_ip': '环境IP',
- 'com.alibaba.nacos.page.newconfig.Data_ID_length': '收起',
- 'nacos.page.configdetail.Data_encryption0': '数据加密',
- 'nacos.component.CloneDialog.get_the_namespace_failed': '获取命名空间失败',
- 'nacos.component.ImportDialog.Upload_File3': '上传文件',
- 'com.alibaba.nacos.page.configdetail.home': '归属应用:',
- 'com.alibaba.nacos.page.environmentalManagement.view': '查看',
- 'nacos.page.configurationManagement.configuration_item?': '条配置项?',
- 'com.alibaba.nacos.page.environmentalManagement.environment_name': '环境名称',
- 'nacos.page.namespace.AccessKey_recommended0': 'AccessKey(推荐):',
- 'nacos.component.validateDialog.remark': '提示: 验证码会通过短信发送到您绑定的手机号。',
- 'com.alibaba.nacos.page.consistencyEfficacy.reset': '重置',
- 'com.alibaba.nacos.page.newconfig.group_placeholder': '请输入Group名称',
- 'com.alibaba.nacos.page.configdetail.belongs_to_the_environment': '地域:',
- 'com.alibaba.nacos.page.listeningToQuery.failure': '失败',
- 'hanxie.show': '测试',
- 'com.alibaba.nacos.page.newconfig.esc_exit': '发布',
- pubnodata: '没有数据',
- 'nacos.page.configurationManagement.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_t':
- 'ACM专用AccessKey(即将废弃,不建议使用):',
- 'com.alibaba.nacos.page.newconfig.configuration_format': '配置内容:',
- configurationManagement: '配置列表',
- 'nacos.component.ShowCodeing.,_6000);_System.out.println(content);_//_初始化的时候,给配置添加监听,配置变更会回调通知_C':
- '", 6000);\t\t\tSystem.out.println(content);\t\t\t// 初始化的时候,给配置添加监听,配置变更会回调通知\t\t\tConfigService.addListener("',
- 'com.alibaba.nacos.component.NewDatePicker.custom': '时间范围不能超过45天',
- 'com.alibaba.nacos.page.historyDetail.recipient_from': '收起',
- 'com.alibaba.nacos.page.configdetail.recipient_from': '收起',
- 'nacos.component.validateDialog.Please_fill_out_the_verification_code': '输入验证码:',
- 'nacos.page.newconfig.Note_You_are_to_be_a_custom_packet_the_new_configuration,_make_sure_that_the_client_use_the_Pandora_version_higher_than_3._4._0,_otherwise_it_may_read_less_than_the_configuration.0':
- '注:您正在往一个自定义分组新增配置,请确保客户端使用的Pandora版本高于3.4.0,否则可能读取不到该配置。',
- 'com.alibaba.nacos.page.listeningToQuery.please_input_group': '请输入Group',
- 'com.alibaba.nacos.component.NewDatePicker.7_day': '7天',
- 'nacos.component.ShowCodeing.-Dproject.name=acmtest_-Dspas.identity=CUserswater.lyl.spas_keyacmt':
- '-Dproject.name=acmtest -Dspas.identity=C:Userswater.lyl.spas_keyacmtest\t\t\t * 在本地的acmtest文件中填写accessKey/secretKey,格式如下\t\t\t * accessKey=',
- 'nacos.component.DeleteDialog.deletetitle': '删除配置',
- 'com.alibaba.nacos.page.pushTrajectory.Push_the_trajectory': '推送轨迹',
- 'com.alibaba.nacos.page.configeditor.release': '发布Beta',
- 'com.alibaba.nacos.page.configeditor.Esc_exit': '按F1显示全屏',
- 'com.alibaba.nacos.page.configsync.home': '归属应用:',
- minute: '分钟',
- 'com.alibaba.nacos.layout.noenv.app_configuration_management_ACM': 'NACOS',
- 'com.alibaba.nacos.page.configRollback.home': '归属应用:',
- 'nacos.page.configurationManagement.no_longer_display4': '不再显示:',
- 'nacos.page.configurationManagement.open_Bulletin_Board7': '打开公告栏',
- 'nacos.page.configurationManagement.SecretKey_recommended4': 'SecretKey(推荐):',
- 'com.alibaba.nacos.page.pushTrajectory.configget': '配置推送 or 主动获取',
- 'com.alibaba.nacos.page.configRollback.action_type': '操作类型:',
- 'nacos.component.CloneDialog.target_space': '目标空间:',
- 'com.alibaba.nacos.component.DiffEditorDialog.original_value': '原始值',
- 'com.alibaba.nacos.page.configurationManagement.environment': '地域:',
- 'nacos.page.configdetail.Description': '描述:',
- 'com.alibaba.nacos.page.pushTrajectory.Data_Id_can_not_be_empty': 'Data ID不能为空',
- 'com.alibaba.nacos.page.listAllEnvironmental.Into_the': '进入',
- 'com.alibaba.nacos.page.listeningToQuery._Push_state': '推送状态',
- 'nacos.component.CloneDialog.configuration_cloning(': '配置克隆(',
- 'com.alibaba.nacos.page.configurationManagement.new_listing': '新建配置',
- 'nacos.component.ExportDialog.source_space5': '源空间:',
- 'nacos.component.ShowCodeing.*///_ConfigService.init();_//_主动获取配置_String_content_=_ConfigService.getConfig(':
- '*///\t\t\tConfigService.init();\t\t\t\t\t\t// 主动获取配置\t\t\tString content = ConfigService.getConfig("',
- cancel: '取消',
- 'com.alibaba.nacos.component.MiddleWareEnv.online': '线上',
- 'com.alibaba.nacos.page.historyRollback.rollback': '回滚',
- 'com.alibaba.nacos.page.historyRollback.last_update_time': '最后更新时间',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter': '请输入查询IP',
- 'com.alibaba.nacos.page.historyDetail.configure_content': '配置内容:',
- 'com.alibaba.nacos.page.consistencyEfficacy.environment_name': '环境名',
- 'nacos.component.ShowCodeing.-Dproject.name=acmtest_-Dspas.identity=CUserswater.lyl.spas_keyacmtest_*_在本地的acmtest文件中填写accessKey/secretKey,格式如下_*_accessKey=':
- '-Dproject.name=acmtest -Dspas.identity=C:Userswater.lyl.spas_keyacmtest\t\t\t * 在本地的acmtest文件中填写accessKey/secretKey,格式如下\t\t\t * accessKey=',
- 'nacos.page.configurationManagement.configuration_export9': '配置导出',
- 'nacos.page.namespace.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_scenario,_it_is_recommended_to_Unified_the_use_of_Ali_cloud_AK/SK.5':
- '注:ACM专用AK/SK主要用于一些兼容性场景。建议统一采用阿里云AK/SK。',
- 'com.alibaba.nacos.page.namespace.add': '新建命名空间',
- 'com.alibaba.nacos.page.configsync.sync_configuration_main': '同步配置',
- 'nacos.page.configeditor.Tags': '标签:',
- dateinfo1: '结束时间必须大于开始时间',
- 'com.alibaba.nacos.service.fill_the_code': '请填写验证码',
- 'nacos.page.newconfig.Description': '描述:',
- 'nacos.component.ImportDialog.target_space5': '目标空间:',
- configsync: '同步配置',
- 'nacos.component.CloneDialog.skip': '跳过',
- 'com.alibaba.nacos.page.configurationManagement.click_to_learn_Group': '点击了解Group',
- 'com.alibaba.nacos.page.newconfig.the_more_advanced': 'Group不能为空',
- 'nacos.page.namespace.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for_use4':
- 'ACM专用SecretKey(即将废弃,不建议使用):',
- 'com.alibaba.nacos.page.namespace.public': 'public(保留空间)',
- 'com.alibaba.nacos.page.configsync.error': '错误',
- 'nacos.page.namespace.AccessKey_recommended1': 'AccessKey(开发环境推荐):',
- 'com.alibaba.nacos.page.pushTrajectory.configuration': '配置',
- 'com.alibaba.nacos.page.configeditor.toedit': '编辑配置',
- 'com.alibaba.nacos.component.NewDatePicker.12_hours': '12小时',
- 'com.alibaba.nacos.page.configsync.for_more_advanced_options': '更多高级选项',
- 'nacos.page.configurationManagement.AccessKey_recommended3': 'AccessKey(开发环境推荐):',
- 'nacos.page.configurationManagement.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_c':
- '注:ACM 专用AK/SK主要用于一些兼容性场景,推荐您统一采用阿里云AK/SK。',
- 'com.alibaba.nacos.page.newconfig.the_home_application': '目标地域:',
- 'com.alibaba.nacos.page.configeditor.official': '正式',
- 'nacos.component.validateDialog.phoneNumber': '手机号码:',
- 'nacos.page.namespace.SecretKey_recommended2': 'SecretKey(推荐):',
- 'com.alibaba.nacos.page.namespace.delete': '删除',
- 'com.alibaba.nacos.component.NewDatePicker.60_-_': '60分钟',
- 'com.alibaba.nacos.page.configsync.retracted': '收起',
- 'nacos.page.configdetail.off1': '关',
- 'com.alibaba.nacos.page.historyDetail.delete': '删除',
- 'nacos.page.configurationManagement.items_for': '项为',
- 'nacos.component.CloneDialog.the_same_configuration': '相同配置:',
- 'com.alibaba.nacos.component.NewNameSpace.name': '命名空间名:',
- 'com.alibaba.nacos.component.MiddleWareEnv.line': '线上/',
- 'nacos.page.configurationManagement.batch_management': '批量管理',
- 'com.alibaba.nacos.page.configeditor.configure_contents_of': '配置格式:',
- 'com.alibaba.nacos.component.NewNameSpace.loading': '加载中...',
- 'com.alibaba.nacos.component.MiddleWareEnv.maletest': '阳中测试',
- 'nacos.page.configurationManagement.clone': '克隆',
- 'nacos.page.configurationManagement.a_ACM_front-end_monitoring_questionnaire,_the_time_limit_to_':
- '答 ACM 前端监控调查问卷,限时领取阿里云代金券\t 详情猛戳:',
- 'nacos.page.configurationManagement.HOME_Application': '归属应用:',
- 'com.alibaba.nacos.page.newconfig.publish_failed': '发布失败。请检查参数是否正确。',
- 'com.alibaba.nacos.page.historyDetail.belongs_to_the_environment': '所属地域:',
- 'com.alibaba.nacos.page.configRollback.configuration_rollback': '配置回滚',
- 'com.alibaba.nacos.page.configurationManagement.edit': '编辑',
- 'nacos.component.ImportDialog.skip1': '跳过',
- 'com.alibaba.nacos.page.pushTrajectory.Group_Id_cannot_be_empty': 'Group不能为空',
- 'nacos.page.configurationManagement.successful_entry': '成功的条目:',
- 'com.alibaba.nacos.component.NewNameSpace.cancel': '取消',
- 'nacos.page.newconfig.Open0': '开',
- 'com.alibaba.nacos.page.configRollback.environment': '地域:',
- 'com.alibaba.nacos.page.pushTrajectory.The_new_configuration_value_persistent':
- '新配置值持久化',
- 'nacos.component.CloneDialog.tags': '标签:',
- 'com.alibaba.nacos.page.pushTrajectory.interval:': '时间区间:',
- 'nacos.component.DeleteDialog.determine': '确定',
- 'nacos.component.validateDialog.verification_code_error': '验证码错误',
- 'com.alibaba.nacos.page.configdetail.return': '返回',
- 'com.alibaba.nacos.page.listAllEnvironmental.operation': '操作',
- 'com.alibaba.nacos.page.newconfig.stop_fails': '停止Beta发布失败。',
- 'com.alibaba.nacos.component.EditorNameSpace.confirm_modify': '编辑命名空间',
- 'com.alibaba.nacos.component.EditorNameSpace.namespace': '命名空间不能为空',
- 'nacos.page.namespace.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_s':
- '注:ACM 专用AK/SK主要用于一些兼容性场景,推荐您统一采用阿里云AK/SK。',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_stable': '日常稳定',
- 'com.alibaba.nacos.page.pushTrajectory.used': '新配置生效',
- 'com.alibaba.nacos.page.configRollback.determine': '确定要',
- 'nacos.component.NameSpaceList.Quick_to_learn0': '学习路径',
- 'nacos.page.namespace.click_on_the_obtain_of1': '点击获取 》',
- 'com.alibaba.nacos.page.newconfig': 'Data ID 不能为空',
- 'nacos.page.configurationManagement.export_check_failed': '导出检查失败',
- 'nacos.component.ImportDialog.file_upload_directly_after_importing_the_configuration,_please_be_sure_to_exercise_caution7':
- '文件上传后将直接导入配置,请务必谨慎操作',
- 'com.alibaba.nacos.page.namespace.prompt': '提示',
- 'nacos.page.namespace.sure_you_want_to_delete_the_following_namespaces?':
- '确定要删除以下命名空间吗?',
- 'nacos.component.validateDialog.confirm': '确定',
- 'nacos.page.configurationManagement.please_input_the_application_name': '请输入应用名',
- 'nacos.page.configurationManagement.please_select_the_required_delete_the_configuration_item':
- '请选择需要删除的配置项',
- 'com.alibaba.nacos.component.MiddleWareEnv.international': '国际化',
- 'com.alibaba.nacos.component.NewDatePicker.to': '查询范围:',
- 'com.alibaba.nacos.page.configeditor.recipient_from': 'Data ID不能为空',
- 'nacos.page.configurationManagement.whether_to_delete_the_selected': '是否删除已选择的',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_environment_packet': '日常环境分组',
- 'com.alibaba.nacos.page.configeditor.toedittitle': '编辑配置',
- 'nacos.page.configeditor.Description': '描述:',
- day: '天',
- 'com.alibaba.nacos.page.listAllEnvironmental.view_environment_IP': '查看环境IP',
- 'com.alibaba.nacos.page.configurationManagement.delete': '删除',
- 'cspupcloud.page.historyRollback.Retained_for_30_days': '保留30天',
- 'com.alibaba.nacos.page.configeditor.beta_release:': '目标地域:',
- 'nacos.page.pushTrajectory.Please_enter_the_user_IP0': '请输入用户IP',
- 'com.alibaba.nacos.component.NewNameSpace.confirm': '确定',
- 'nacos.component.DeleteDialog.deleted_successfully_configured': '删除配置成功',
- 'nacos.component.ShowCodeing.,_new_PropertiesListener()_{_@Override_public_void_innerReceive(Pro':
- '", new PropertiesListener() {\t\t\t\t\t\t\t\t@Override\t\t\t\tpublic void innerReceive(Properties properties) {\t\t\t\t\t// TODO Auto-generated method stub\t\t\t\t\tacmProperties = properties;\t\t\t\t\tSystem.out.println(properties);\t\t\t\t}\t\t\t});\t\t\t\t\t\t**/\t\t\t\t\t} catch (ConfigException e) {\t\t\te.printStackTrace();\t\t}\t\t// 测试让主线程不退出,因为订阅配置是守护线程,主线程退出守护线程就会退出。 正式代码中无需下面代码\t\twhile (true) {\t\t\ttry {\t\t\t\tThread.sleep(1000);\t\t\t} catch (InterruptedException e) {\t\t\t\te.printStackTrace();\t\t\t}\t\t}\t}\t // 通过get接口把配置值暴露出去使用 public static String getConfig() { return config; } \t// 通过get接口把配置值暴露出去使用\tpublic static Object getPorpertiesValue(String key) {\t\tif (acmProperties != null) {\t\t\treturn acmProperties.get(key);\t\t}\t\treturn null;\t}}',
- 'com.alibaba.nacos.page.namespace.operation': '操作',
- 'com.alibaba.nacos.page.configurationManagement.push_track': '推送轨迹',
- 'nacos.page.namespace.region_ID': '地域ID:',
- 'com.alibaba.nacos.component.NewNameSpace.norepeat': '命名空间名称不能重复',
- 'com.alibaba.nacos.page.configRollback.inserted': '插入',
- 'com.alibaba.nacos.page.configurationManagement.version': '历史版本',
- 'com.alibaba.nacos.page.configRollback.rollback': '回滚',
- 'nacos.page.namespace.delete_failed': '删除失败',
- 'com.alibaba.nacos.component.SuccessDialog.determine': '确定',
- 'nacos.page.configurationManagement.HOME_Application0': '归属应用:',
- to: '至',
- 'com.alibaba.nacos.page.environmentalManagement.operation': '操作',
- 'nacos.page.namespace.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_the_use_of3':
- 'ACM专用AccessKey(即将废弃,不建议使用):',
- 'com.alibaba.nacos.page.configurationManagement.configuration_query': '配置查询',
- 'nacos.component.validateDialog.fill_the_code': '请填写验证码',
- 'nacos.page.configurationManagement.Please_enter_the_name_of_the_app1': '请输入应用名',
- 'com.alibaba.nacos.page.newconfig.collapse': '更多高级选项',
- 'com.alibaba.nacos.page.namespace.edit': '编辑',
- 'nacos.page.namespace._Details_of6': '详情 》',
- 'com.alibaba.nacos.component.ShowCodeing.Sample_code': '示例代码',
- 'nacos.component.ImportDialog.Import_configuration4': '导入配置 ( ',
- 'nacos.page.configurationManagement.please_choose_the_required_export_configuration_items10':
- '请选择需要导出的配置项',
- 'com.alibaba.nacos.page.configdetail.beta_release': 'Beta发布:',
- 'com.alibaba.nacos.page.configurationManagement.fuzzyd': '模糊查询请输入Data ID',
- 'com.alibaba.nacos.page.newconfig.group_is_not_empty': 'Group ID长度不能超过127字符',
- 'com.alibaba.nacos.component.EditorNameSpace.private': '公共空间',
- 'com.alibaba.nacos.page.environmentalManagement.all_available_environment': '所有可用环境',
- dateinfo2: '时间范围不能超过45天',
- 'nacos.page.namespace.Namespace_details': '命名空间详情',
- 'nacos.component.ImportDialog.the_same_configuration6': '相同配置:',
- 'nacos.page.newconfig.Tags': '标签:',
- 'nacos.page.configurationManagement.Configuration_cloning0': '配置克隆',
- 'com.alibaba.nacos.component.NewDatePicker.4_hours': '4小时',
- 'com.alibaba.nacos.page.configeditor.group_is_not_empty': '更多高级选项',
- 'nacos.page.configurationManagement.SecretKey_recommended5': 'SecretKey(开发环境推荐):',
- 'com.alibaba.nacos.page.configurationManagement.click_to_learn_DataId': '点击了解Data ID',
- 'nacos.page.configurationManagement.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for':
- 'ACM专用SecretKey(即将废弃,不建议使用):',
- 'com.alibaba.nacos.page.configsync.sync_configuration': '同步配置成功',
- 'com.alibaba.nacos.component.MiddleWareEnv.new_diamond': '新版Diamond',
- 'com.alibaba.nacos.page.newconfig.release': '返回',
- 'com.alibaba.nacos.page.configeditor.wrong': '错误',
- 'com.alibaba.nacos.page.pushTrajectory.user_IP': '用户IP',
- 'nacos.page.configeditor.Data_encryption0': '数据加密',
- 'com.alibaba.nacos.page.historyDetail.update': '更新',
- historyDetail: '历史详情',
- 'nacos.page.configurationManagement.select_need_to_clone_the_configuration_items1':
- '请选择需要克隆的配置项',
- 'nacos.page.configurationManagement._Details_of8': '详情 》',
- 'nacos.page.configurationManagement.Batch_processing0': '批量处理',
- 'com.alibaba.nacos.page.pushTrajectory.query_dimension': '查询维度:',
- 'nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_messag':
- '公告:Node.JS版上线。支持定制消息。',
- 'nacos.component.ShowCodeing.package_com.alibaba.middleware.acm;import_java.util.Properties;impo':
- 'package com.alibaba.middleware.acm;import java.util.Properties;import com.alibaba.edas.acm.ConfigService;import com.alibaba.edas.acm.exception.ConfigException;import com.alibaba.edas.acm.listener.ConfigChangeListener;import com.alibaba.edas.acm.listener.PropertiesListener;// 示例代码,仅用于示例测试public class ACMTest { // 属性/开关 private static String config = "DefaultValue";\t private static Properties acmProperties = new Properties(); \tpublic static void main(String[] args) {\t\ttry {\t\t\t\t\t\t// 本地调试模式。本机测试无法连接ACM服务集群,因此设置debug模式(该模式下获取值为null,不会进入回调函数)。\t\t\t// ConfigService.setDebug(true);\t\t\t\t\t\t// 初始化配置服务,控制台通过示例代码自动获取下面参数\t\t\tConfigService.init("',
- 'com.alibaba.nacos.component.NewDatePicker.3_day': '3天',
- custom: '自定义',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_test_center': '日常测试中心',
- 'com.alibaba.nacos.page.configRollback.for_more_advanced': '更多高级选项',
- 'nacos.component.CloneDialog.Terminate_the_clone0': '终止克隆',
- 'com.alibaba.nacos.page.configurationManagement.operation': '操作',
- 'com.alibaba.nacos.layout.noenv.Click_to_learn_the_namespace': '点击了解命名空间',
- 'com.alibaba.nacos.page.configeditor.look': '查看推送轨迹',
- 'com.alibaba.nacos.component.NewNameSpace.newnamespce': '新建命名空间',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter_a_query_Ip': '请输入查询IP',
- 'nacos.page.configurationManagement.export': '导出',
- 'com.alibaba.nacos.page.newconfig.new_listing_main': '新建配置',
- 'nacos.component.CloneDialog.select_namespace': '请选择命名空间',
- 'nacos.page.newconfig.Note_You_are_to_be_a_custom_packet_the_new_configuration,_make_sure_that_t':
- '注:您正在往一个自定义分组新增配置,请确保客户端使用的Pandora版本高于3.4.0,否则可能读取不到该配置。',
- 'com.alibaba.nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_c':
- '公告:Node.js版上线。支持定制消息。',
- 'com.alibaba.nacos.page.configRollback.rollback_successful': '回滚成功',
- 'com.alibaba.nacos.page.pushTrajectory.getconifg': '配置推送 or 主动获取',
- 'com.alibaba.nacos.component.MiddleWareEnv.ungrouped': '未分组',
- 'nacos.page.configurationManagement.unprocessed_entry': '未处理的条目:',
- 'nacos.page.configurationManagement.ecs_ram_role':
- '自动下发 AccessKey 和 SecretKey (生产环境推荐):',
- 'com.alibaba.nacos.component.DiffEditorDialog.of_the_current_area': '当前值',
- 'com.alibaba.nacos.component.AddGroup.group_name': 'Group名:',
- 'nacos.page.configurationManagement.Important_reminder0': '重要提醒',
- 'com.alibaba.nacos.page.pushTrajectory.the_query_results:_a_total_query_to':
- '查询结果:共查询到',
- configRollback: '配置回滚',
- 'com.alibaba.nacos.page.pushTrajectory.please_input_Group': '请输入Group',
- 'nacos.component.validateDialog.cancel': '取消',
- 'nacos.page.namespace.namespace_name': '命名空间名称:',
- 'com.alibaba.nacos.page.namespace.namespace_names': '命名空间名称',
- 'nacos.page.newconfig.off1': '关',
- 'com.alibaba.nacos.page.pushTrajectory.getconfig': '获取配置',
- 'nacos.page.namespace.SecretKey_recommended3': 'SecretKey(开发环境推荐):',
- 'com.alibaba.nacos.page.pushTrajectory.configok': '新配置生效',
- 'nacos.component.ImportDialog.To_terminate_the_import0': '终止导入',
- 'nacos.page.configurationManagement.view_details1': '查看详情',
- 'com.alibaba.nacos.page.historyRollback.article_meet': '条满足要求的配置。',
- 'nacos.page.newconfig.data_encryption3': '数据加密:',
- 'com.alibaba.nacos.page.pushTrajectory.user_Ip': '用户IP:',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter_the_dataID': '请输入Data ID',
- 'nacos.page.namespace.remove_the_namespace': '删除命名空间',
- 'com.alibaba.nacos.page.configurationManagement.listener_query': '监听查询',
- 'com.alibaba.nacos.page.consistencyEfficacy.edit': '编辑',
- 'com.alibaba.nacos.component.EditorNameSpace.load': '命名空间名:',
- 'com.alibaba.nacos.component.MiddleWareEnv.performance': '性能',
- 'nacos.page.namespace._Remove_the_namespace_success': '删除命名空间成功',
- 'nacos.page.configurationManagement.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_scenario,_it_is_recommended_to_Unified_the_use_of_Ali_cloud_AK/SK.7':
- '注:ACM 专用AK/SK主要用于一些兼容性场景,推荐您统一采用阿里云AK/SK。',
- 'com.alibaba.nacos.page.historyRollback.to_configure': '历史版本(保留30天)',
- 'com.alibaba.nacos.page.pushTrajectory.interval': '时间区间:',
- 'com.alibaba.nacos.page.consistencyEfficacy.details': '详情',
- 'com.alibaba.nacos.component.EditorNameSpace.edit_namespace': '加载中...',
- 'com.alibaba.nacos.page.newconfig.do_not_ente': '请勿输入非法字符',
- 'com.alibaba.nacos.component.MiddleWareEnv.from-test': '自测',
- 'nacos.page.configurationManagement.Please_enter_application_name1': '请输入应用名',
- 'nacos.component.ImportDialog.You_can_only_upload._zip_file_format0': '只能上传.zip格式的文件',
- 'com.alibaba.nacos.page.configeditor.stop_beta': '停止Beta',
- 'com.alibaba.nacos.component.SuccessDialog.failure': '失败',
- 'nacos.page.configurationManagement.bulk_delete': '批量删除',
- 'com.alibaba.nacos.page.historyRollback.details': '详情',
- 'com.alibaba.nacos.page.configeditor.more_advanced_options': '收起',
- 'com.alibaba.nacos.page.configdetail.configuration': '配置内容:',
- 'nacos.component.CloneDialog.configuration_number': '配置数量:',
- 'com.alibaba.nacos.component.EditorNameSpace.public_space': '确认修改',
- chaxunfanwei: '查询范围',
- 'com.alibaba.nacos.page.newconfig.full_screen': '按Esc退出全屏',
- 'com.alibaba.nacos.page.configeditor.the_target_environment:': '归属应用:',
- hour: '小时',
- 'com.alibaba.nacos.page.namespace.configuration': '配置数',
- 'nacos.page.configurationManagement.Cloning_check_fails': '克隆检查失败',
- 'com.alibaba.nacos.component.NewNameSpace.namespacenotnull': '命名空间不能为空',
- 'com.alibaba.nacos.page.configeditor.beta_release_notes(default_not_checked)': 'Beta发布:',
- 'nacos.page.newconfig.to_the_authorization_of2': '去授权 》',
- 'com.alibaba.nacos.page.configeditor.return': '发布',
- 'com.alibaba.nacos.page.configurationManagement.more': '更多',
- 'com.alibaba.nacos.component.EnvConfigTopBar.context_switching': '环境切换',
- 'com.alibaba.nacos.component.SuccessDialog.Configuration_management': '配置管理',
- 'nacos.component.ImportDialog.cover2': '覆盖',
- 'com.alibaba.nacos.page.configurationManagement.last_modified_time': '最后修改时间',
- 'com.alibaba.nacos.page.newconfig.dataId_is_not_empty': 'Data ID 长度不能超过255字符',
- 'com.alibaba.nacos.page.configeditor.configcontent': '配置内容',
- 'com.alibaba.nacos.component.NewNameSpace.input': '请勿输入非法字符',
- 'com.alibaba.nacos.page.configRollback.updated': '更新',
- 'com.alibaba.nacos.page.pushTrajectory.user_Ip:': '用户IP:',
- 'nacos.component.DeleteDialog.delete_the_configuration_failed': '删除配置失败',
- 'com.alibaba.nacos.component.SuccessDialog.success': '成功',
- 'nacos.page.configurationManagement._The_process_is_successful,_delete_the': '处理成功,删除了',
- 'com.alibaba.nacos.component.NewNameSpace.prompt': '提示',
- 'com.alibaba.nacos.page.configRollback.please_confirm_rollback': '回滚配置',
- 'com.alibaba.nacos.page.pushTrajectory.the_query_results': '查询结果:共查询到',
- 'com.alibaba.nacos.page.historyRollback.group': '请输入Group',
- 'nacos.component.ExportDialog.export_configuration4': '导出配置(',
- 'com.alibaba.nacos.page.consistencyEfficacy.configuration_consistency_check': '配置一致性校验',
- 'com.alibaba.nacos.page.newconfig.stop_beta': '停止Beta发布',
- 'com.alibaba.nacos.page.historyDetail.home': '归属应用:',
- 'nacos.component.ExportDialog.export3': '导出',
- 'com.alibaba.nacos.page.pushTrajectory.cluster_synchronization': '集群间同步通知',
- 'nacos.page.namespace.ecs_ram_role': '自动下发 AccessKey 和 SecretKey (生产环境推荐):',
- 'nacos.component.CloneDialog.HOME_Application': '归属应用:',
- 'nacos.page.namespace.Namespace': '命名空间',
- 'com.alibaba.nacos.component.EditorNameSpace.please_do': '请勿输入非法字符',
- 'com.alibaba.nacos.page.listeningToQuery.configuration': '配置',
- 'com.alibaba.nacos.component.MiddleWareEnv.cloud_unit': '云单元',
- 'nacos.page.configurationManagement.Clone_failed': '克隆失败',
- 'nacos.page.newconfig.The_opening_of_the_data_encryption-related_services0':
- '开通数据加密相关服务',
- 'com.alibaba.nacos.component.NewDatePicker.recently': '取消',
- 'com.alibaba.nacos.component.editorNameSpace': '私有空间',
- 'com.alibaba.nacos.page.configeditor.configuration_format:':
- '默认不要勾选。点击了解Beta发布详情。',
- pushTrajectory: '推送轨迹',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily': '日常',
- 'nacos.component.ExportDialog.HOME_Application1': '归属应用:',
- 'nacos.page.newconfig._to_go_to_the_opening_of1': '\t 去开通 》',
- 'com.alibaba.nacos.component.NewDatePicker.determine': '至',
- 'nacos.page.configurationManagement.advanced_query9': '高级查询',
- 'nacos.page.configurationManagement.configuration': '项配置',
- 'nacos.page.configurationManagement.AccessKey_recommended2': 'AccessKey(推荐):',
- configeditor: '配置编辑',
- 'com.alibaba.nacos.page.listAllEnvironmental.all_available_environment': '所有可用环境',
- 'com.alibaba.nacos.page.newconfig.configuration_contentmax':
- '配置内容最大长度不能超过10240字符',
- 'com.alibaba.nacos.page.configdetail.error': '错误',
- 'com.alibaba.nacos.component.NameSpaceList.immediate_use': '立即使用',
- 'com.alibaba.nacos.page.newconfig.Group_ID_cannot_be_longer': '归属应用:',
- listeningToQuery: '监听查询',
- Configdetail: '配置详情',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_marked': '环境标示',
- 'com.alibaba.nacos.page.configsync.configuration': '配置内容:',
- configdetail: '配置详情',
- 'com.alibaba.nacos.page.historyDetail.insert': '插入',
- 'com.alibaba.nacos.page.configdetail.official': '正式',
- 'nacos.page.configurationManagement.questionnaire2': '问卷调查',
- 'com.alibaba.nacos.component.AddGroup.prompt': '提示',
- 'com.alibaba.nacos.layout.noenv.app_configuration_management_acm': 'NACOS',
- 'nacos.page.configurationManagement.process_is_successful,_import_the': '处理成功,导入了',
- 'nacos.component.DeleteDialog.Configuration_management': '配置管理',
- 'com.alibaba.nacos.page.consistencyEfficacy.configuration_content_md5': '配置内容MD5',
- 'com.alibaba.nacos.page.configRollback.return': '返回',
- 'com.alibaba.nacos.page.configurationManagement.details': '详情',
- 'nacos.page.namespace.details': '详情',
- 'com.alibaba.nacos.page.listeningToQuery.query_results:_query': '查询结果:共查询到',
- 'com.alibaba.nacos.page.form.Data_Id_can_not_be_empty': 'Data ID不能为空',
- 'com.alibaba.nacos.page.listeningToQuery.group_can_not_be_empty': 'Group不能为空',
- 'com.alibaba.nacos.page.configurationManagement.fuzzyg': '模糊查询请输入Group',
- 'nacos.component.NameSpaceList.Forum': '论坛',
- 'nacos.component.ShowCodeing.,_new_ConfigChangeListener()_{_public_void_receiveConfigInfo(String':
- '", new ConfigChangeListener() {\t\t\t\tpublic void receiveConfigInfo(String configInfo) {\t\t\t\t\t// 当配置更新后,通过该回调函数将最新值吐给用户。\t\t\t\t\t// 注意回调函数中不要做阻塞操作,否则阻塞通知线程。\t\t\t\t\tconfig = configInfo;\t\t\t\t\tSystem.out.println(configInfo);\t\t\t\t}\t\t\t});\t\t\t\t\t\t/**\t\t\t * 如果配置值的內容为properties格式(key=value), 可使用下面监听器。以便一个配置管理多个配置项\t\t\t */\t\t\t\t\t\t/**\t\t\tConfigService.addListener("',
- 'com.alibaba.nacos.page.consistencyEfficacy.advanced_query': '高级查询',
- 'com.alibaba.nacos.page.listeningToQuery.please_enter_the_dataid': '请输入Data ID',
- 'nacos.component.ShowCodeing.,_6000);_System.out.println(content);_//_初始化的时候,给配置添加监听,配置变更会回调通知_ConfigService.addListener(':
- '", 6000);\t\t\tSystem.out.println(content);\t\t\t// 初始化的时候,给配置添加监听,配置变更会回调通知\t\t\tConfigService.addListener("',
- 'nacos.component.CloneDialog.|_the_selected_entry': '| 选中的条目',
- 'nacos.page.newconfig.Data_encryption0': '数据加密',
- 'com.alibaba.nacos.page.environmentalManagement.environment_marked': '环境标示',
- 'com.alibaba.nacos.page.listeningToQuery.listener_query': '监听查询',
- 'nacos.component.ExportDialog.|_The_selected_entry0': '| 选中的条目',
- 'com.alibaba.nacos.page.consistencyEfficacy.query_results': '查询结果',
- 'nacos.page.namespace.deleted_successfully': '删除成功',
- 'nacos.component.CloneDialog.cover': '覆盖',
- 'com.alibaba.nacos.page.environmentalManagement.Into_the': '进入',
- 'com.alibaba.nacos.page.configdetail.more_advanced_options': '更多高级选项',
- 'com.alibaba.nacos.page.listeningToQuery.query_dimension': '查询维度:',
- 'com.alibaba.nacos.page.configRollback.configuration': '配置内容:',
- 'com.alibaba.nacos.page.historyDetail.more_advanced_options': '更多高级选项',
- 'com.alibaba.nacos.page.consistencyEfficacy.query': '查询',
- 'com.alibaba.nacos.page.listeningToQuery.please_input_ip': '请输入IP',
- 'com.alibaba.nacos.component.NewDatePicker.end_time_must_be_greater_than_the_start_time_of_the_t':
- '结束时间必须大于开始时间',
- 'com.alibaba.nacos.page.listAllEnvironmental.view': '查看',
- 'nacos.component.ShowCodeing.*///_ConfigService.init();_//_主动获取配置_String_content_=_ConfigService':
- '*///\t\t\tConfigService.init();\t\t\t\t\t\t// 主动获取配置\t\t\tString content = ConfigService.getConfig("',
- 'com.alibaba.nacos.page.newconfig.configure_contents_of': '按F1显示全屏',
- 'com.alibaba.nacos.page.listeningToQuery.success': '成功',
- 'com.alibaba.nacos.component.NewDatePicker.30_minutes': '30分钟',
- 'com.alibaba.nacos.page.historyDetail.history_details': '历史详情',
- 'com.alibaba.nacos.page.listeningToQuery.query': '查询',
- 'com.alibaba.nacos.page.newconfig.the_target_environment': '配置格式:',
- 'com.alibaba.nacos.layout.noenv.does_not_exist': '您访问的页面不存在',
- 'nacos.component.ImportDialog.file_upload_directly_after_importing_the_configuration,_please_be_':
- '文件上传后将直接导入配置,请务必谨慎操作',
- 'nacos.page.configurationManagement.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_the_use_of5':
- 'ACM专用AccessKey(即将废弃,不建议使用):',
- 'nacos.page.configurationManagement.import': '导入',
- 'com.alibaba.nacos.page.configurationManagement.suredelete': '确定要删除以下配置吗?',
- 'com.alibaba.nacos.page.configeditor.release_beta': '按Esc退出全屏',
- 'nacos.page.configurationManagement.no_announcement6': '暂无公告',
- 'com.alibaba.nacos.component.NewDatePicker.query_range:': '自定义',
- 'com.alibaba.nacos.page.configRollback.belongs_to': '所属地域:',
- 'com.alibaba.nacos.page.pushTrajectory.query_dimension:': '查询维度:',
- 'com.alibaba.nacos.component.MiddleWareEnv.payTM_daily': 'payTM日常',
- 'nacos.page.configurationManagement.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for_use6':
- 'ACM专用SecretKey(即将废弃,不建议使用):',
- 'com.alibaba.nacos.page.configurationManagement.query': '查询',
- 'com.alibaba.nacos.component.MiddleWareEnv.offline': '线下',
- 'com.alibaba.nacos.page.listeningToQuery.article_meet_the_requirements_of_the_configuration.':
- '条满足要求的配置。',
- 'com.alibaba.nacos.page.configurationManagement.Remove_configuration': '删除配置',
- recent: '最近',
- 'com.alibaba.nacos.page.configeditor.F1/fn F1(MAC)full_screen': '配置内容',
- 'nacos.page.configurationManagement.off_the_Bulletin_Board5': '关闭公告栏',
- 'com.alibaba.nacos.page.historyDetail.action_type': '操作类型:',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_IP': '环境IP',
- 'nacos.component.CloneDialog.source_space': '源空间:',
- 'nacos.page.configurationManagement.click_on_the_obtain_of3': '点击获取 》',
- 'com.alibaba.nacos.page.configurationManagement.article_meet_the_requirements':
- '条满足要求的配置。',
- 'com.alibaba.nacos.page.historyRollback.operation': '操作',
- 'nacos.component.ShowCodeing.);_/**_*_生产环境通过jvm参数传参,以便使用多个环境,_-Dacm.endpoint=':
- '");\t\t\t\t\t\t/**\t\t\t * 生产环境通过JVM参数传参,以便使用多个环境, -Dacm.endpoint=',
- 'com.alibaba.nacos.page.historyDetail.return': '返回',
- 'nacos.page.configurationManagement.failed_entry': '失败的条目:',
- 'nacos.component.CloneDialog.start_cloning': '开始克隆',
- 'com.alibaba.nacos.page.configRollback.the_following_configuration': '以下配置吗?',
- 'com.alibaba.nacos.page.configurationManagement.query_results': '查询结果:共查询到',
- 'nacos.page.configurationManagement.a_ACM_front-end_monitoring_questionnaire,_the_time_limit_to_receive_Ali_cloud_voucher_details_shoved_stamp_the3':
- '答 ACM 前端监控调查问卷,限时领取阿里云代金券\t 详情猛戳:',
- 'com.alibaba.nacos.component.MiddleWareEnv.online_center': '线上中心',
- 'com.alibaba.nacos.page.serviceManagement.service_list': '服务列表',
- 'com.alibaba.nacos.page.serviceManagement.service_name': '服务名称',
- 'com.alibaba.nacos.page.serviceManagement.please_enter_the_service_name': '请输入服务名称',
- 'com.alibaba.nacos.page.serviceManagement.table.column.service_name': '服务名',
- 'com.alibaba.nacos.page.serviceManagement.table.column.cluster_count': '集群数目',
- 'com.alibaba.nacos.page.serviceManagement.table.column.ip_count': '实例数',
- 'com.alibaba.nacos.page.serviceManagement.table.column.healthy_instance_count': '健康实例数',
- 'com.alibaba.nacos.page.serviceManagement.table.column.operation': '操作',
- 'com.alibaba.nacos.page.serviceManagement.detail': '详情',
- 'com.alibaba.nacos.page.serviceManagement.delete': '删除',
- 'com.alibaba.nacos.page.serviceManagement.prompt': '提示',
- 'com.alibaba.nacos.page.serviceManagement.prompt_delete': '确定要删除当前服务吗?',
- 'com.alibaba.nacos.page.serviceManagement.create': '创建服务',
- 'com.alibaba.nacos.page.serviceManagement.query': '查询',
- serviceManagement: '服务列表',
- 'com.alibaba.nacos.page.serviceDetail.service_details': '服务详情',
- 'com.alibaba.nacos.page.serviceDetail.edit_service': '编辑服务',
- 'com.alibaba.nacos.page.serviceDetail.back': '返回',
- 'com.alibaba.nacos.page.serviceDetail.service_name': '服务名',
- 'com.alibaba.nacos.page.serviceDetail.protect_threshold': '保护阈值',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern': '健康检查模式',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.service': '服务端',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.client': '客户端',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.none': '禁止',
- 'com.alibaba.nacos.page.serviceDetail.metadata': '元数据',
- 'com.alibaba.nacos.page.serviceDetail.create_service': '创建服务',
- 'com.alibaba.nacos.page.serviceDetail.update_service': '更新服务',
- 'com.alibaba.nacos.page.serviceDetail.cluster': '集群',
- 'com.alibaba.nacos.page.serviceDetail.edit_cluster': '集群配置',
- 'com.alibaba.nacos.page.serviceDetail.port': '端口',
- 'com.alibaba.nacos.page.serviceDetail.weight': '权重',
- 'com.alibaba.nacos.page.serviceDetail.healthy': '健康状态',
- 'com.alibaba.nacos.page.serviceDetail.operation': '操作',
- 'com.alibaba.nacos.page.serviceDetail.editor': '编辑',
- 'com.alibaba.nacos.page.serviceDetail.offline': '下线',
- 'com.alibaba.nacos.page.serviceDetail.online': '上线',
- 'com.alibaba.nacos.page.serviceDetail.check_type': '检查类型',
- 'com.alibaba.nacos.page.serviceDetail.check_port': '检查端口',
- 'com.alibaba.nacos.page.serviceDetail.use_ip_port_check': '使用IP端口检查',
- 'com.alibaba.nacos.page.serviceDetail.check_path': '检查路径',
- 'com.alibaba.nacos.page.serviceDetail.check_headers': '检查头',
- 'com.alibaba.nacos.page.serviceDetail.update_cluster': '更新集群',
- 'com.alibaba.nacos.page.serviceDetail.update_instance': '编辑实例',
- 'com.alibaba.nacos.page.serviceDetail.whether_online': '是否上线',
- serviceDetail: '服务详情',
- 'nacos.page.ConfigEditor.submit_failed': '不能为空, 提交失败',
- },
- 'en-us': {
- 'com.alibaba.nacos.layout.noenv.nacosversion': '0.8.0',
- 'com.alibaba.nacos.page.configurationManagementVirtual': 'ConfigManagement',
- 'com.alibaba.nacos.page.serviceManagementVirtual': 'ServiceManagement',
- 'nacos.component.CloneDialog.the_same_configuration': 'Conflict:',
- to: 'to',
- 'nacos.page.newconfig.data_encryption3': 'Data Encryption:',
- 'nacos.page.configurationManagement.batch_management': 'Batch Operation',
- 'com.alibaba.nacos.page.configsync.return': 'Back',
- 'com.alibaba.nacos.page.pushTrajectory.getconfig': 'Get Configuration',
- cancel: 'Cancel',
- 'nacos.component.CloneDialog.Terminate_the_clone0': 'Terminate',
- 'com.alibaba.nacos.component.NewNameSpace.newnamespce': 'Create Namespace',
- 'com.alibaba.nacos.page.pushTrajectory.Data_Id_can_not_be_empty': 'Data ID cannot be empty',
- 'com.alibaba.nacos.component.MiddleWareEnv.maletest': 'male. test',
- 'com.alibaba.nacos.page.configeditor.group_is_not_empty': 'Advanced Options',
- 'com.alibaba.nacos.component.editorNameSpace': 'Dedicated Space',
- 'nacos.component.CloneDialog.target_space': 'Target:',
- 'nacos.page.newconfig.off1': 'Off',
- 'com.alibaba.nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_c':
- 'Announcement: Node.js version now available, supporting customized messages.',
- 'com.alibaba.nacos.page.pushTrajectory.user_Ip': 'User IP:',
- 'nacos.page.configurationManagement.a_ACM_front-end_monitoring_questionnaire,_the_time_limit_to_':
- 'a ACM front-end monitoring questionnaire, the time limit to receive Ali cloud voucher details shoved stamp: the',
- 'nacos.page.configurationManagement.Important_reminder0': 'Important reminder',
- 'com.alibaba.nacos.page.pushTrajectory.the_query_results:_a_total_query_to': 'Results: Found',
- 'com.alibaba.nacos.page.configdetail.belongs_to_the_environment': 'Region:',
- 'com.alibaba.nacos.page.configurationManagement.operation': 'Actions',
- 'com.alibaba.nacos.layout.noenv.app_configuration_management_ACM': 'NACOS',
- 'nacos.page.namespace.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_scenario,_it_is_recommended_to_Unified_the_use_of_Ali_cloud_AK/SK.5':
- "Note: ACM's dedicated AK/SK is mainly used for improved compatibilities. We recommend that you always use Alibaba Cloud AK/SK.",
- 'com.alibaba.nacos.component.ShowCodeing.Sample_code': 'Sample Code',
- 'nacos.page.newconfig.Open0': 'Open',
- custom: 'Customize',
- 'com.alibaba.nacos.page.pushTrajectory.Group_Id_cannot_be_empty': 'Group name cannot be empty',
- 'com.alibaba.nacos.page.environmentalManagement.operation': 'operation',
- 'com.alibaba.nacos.page.configRollback.environment': 'Region:',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter_a_query_Ip': 'Enter IP',
- confirm: 'OK',
- 'nacos.page.configurationManagement.successful_entry': 'Successful Entry:',
- 'com.alibaba.nacos.page.configurationManagement.configuration_query': 'Configuration Search',
- 'nacos.page.configurationManagement._Details_of8': ' Details of',
- 'com.alibaba.nacos.page.namespace.add': 'Create Namespace',
- 'nacos.component.ImportDialog.the_same_configuration6': 'Conflict:',
- 'com.alibaba.nacos.page.pushTrajectory.Push_the_trajectory': 'Push Tracks',
- configsync: 'Synchronize Configuration',
- 'nacos.page.namespace.Namespace_details': 'Namespace details',
- dateinfo1: 'The end time must be greater than the start time',
- 'com.alibaba.nacos.page.newconfig.group_is_not_empty':
- 'Group ID cannot exceed 127 characters in length',
- 'com.alibaba.nacos.page.configurationManagement.click_to_learn_DataId':
- 'Learn more about Data ID',
- 'com.alibaba.nacos.page.configdetail.configuration_details': 'Configuration Details',
- 'com.alibaba.nacos.page.namespace.edit': 'Edit',
- 'nacos.page.newconfig.Tags': 'Tags:',
- 'nacos.page.configurationManagement.please_choose_the_required_export_configuration_items10':
- 'Please select configuration items to export.',
- 'nacos.page.namespace.namespace_name': 'Name:',
- 'com.alibaba.nacos.component.MiddleWareEnv.ungrouped': 'Ungrouped',
- 'nacos.component.ImportDialog.target_space5': 'Target:',
- 'com.alibaba.nacos.page.pushTrajectory.configok': 'New Configuration Published',
- 'com.alibaba.nacos.page.newconfig.esc_exit': 'Publish',
- 'nacos.page.namespace.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_the_use_of3':
- 'ACM dedicated AccessKey will the waste, does not recommend the use of:',
- 'nacos.page.configurationManagement.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_t':
- 'ACM dedicated AccessKey will the waste, does not recommend the use of:',
- 'com.alibaba.nacos.page.newconfig.the_more_advanced': 'Group cannot be empty',
- 'nacos.page.configurationManagement.SecretKey_recommended5':
- 'SecretKey (Recommended for development environment):',
- 'nacos.page.configurationManagement.Configuration_cloning0': 'Clone',
- 'com.alibaba.nacos.page.pushTrajectory.configuration': 'Configuration',
- 'com.alibaba.nacos.page.newconfig.new_listing_main': 'Create Configuration',
- 'nacos.page.configurationManagement.Batch_processing0': 'Batch processing',
- 'com.alibaba.nacos.page.configeditor.look': 'View Push Track',
- 'com.alibaba.nacos.page.configsync.sync_configuration':
- 'Synchronize Configuration Successfully',
- 'com.alibaba.nacos.page.configeditor.official': 'Official',
- 'nacos.page.configeditor.Data_encryption0': 'Data encryption',
- 'nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_messag':
- 'Announcement: Node.JS version now available, supporting customized messages.',
- 'com.alibaba.nacos.page.historyDetail.update': 'Update',
- 'com.alibaba.nacos.page.pushTrajectory.user_IP': 'IP',
- 'nacos.component.ImportDialog.Upload_File3': 'Upload File',
- 'com.alibaba.nacos.component.NewDatePicker.60_-_': '60 minutes',
- 'nacos.page.configurationManagement.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_c':
- 'note: ACM is dedicated AK/SK is mainly used for some of the compatibility scenario, it is recommended to Unified the use of Ali cloud AK/SK.',
- 'com.alibaba.nacos.page.newconfig.Data_ID_length': 'Collapse',
- 'nacos.page.configurationManagement.Please_enter_the_name_of_the_app1': 'Enter App Name\n',
- 'com.alibaba.nacos.page.configeditor.toedittitle': 'Edit Configuration',
- 'nacos.component.CloneDialog.configuration_number': 'Items:',
- chaxunfanwei: 'Query Range',
- 'com.alibaba.nacos.page.configeditor.beta_release_notes(default_not_checked)': 'Beta Publish:',
- 'nacos.page.configurationManagement.open_Bulletin_Board7': 'open Bulletin Board',
- 'com.alibaba.nacos.component.SuccessDialog.failure': 'Failed',
- 'com.alibaba.nacos.component.ShowCodeing.loading': 'Loading...',
- 'com.alibaba.nacos.page.configsync.home': 'Application:',
- minute: ' minutes',
- 'cspupcloud.page.historyRollback.Retained_for_30_days': 'Retained for 30 days',
- 'com.alibaba.nacos.page.configRollback.delete': 'Delete',
- 'com.alibaba.nacos.page.configeditor.beta_release:': 'Target Region:',
- 'com.alibaba.nacos.page.consistencyEfficacy.environment_name': 'environment name',
- 'com.alibaba.nacos.component.SuccessDialog.success': 'Successful',
- 'com.alibaba.nacos.page.namespace.configuration': 'Number of Configurations',
- hour: ' hours',
- 'com.alibaba.nacos.page.configRollback.please_confirm_rollback': 'Roll Back',
- 'nacos.page.configurationManagement.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for_use6':
- "ACM's dedicated SecretKey (To be deprecated soon and not recommended):",
- 'nacos.component.ExportDialog.source_space5': 'Source:',
- 'com.alibaba.nacos.component.SuccessDialog.determine': 'OK',
- 'com.alibaba.nacos.component.EnvConfigTopBar.context_switching': 'Switch Region',
- 'nacos.component.DeleteDialog.delete_the_configuration_failed': 'Deleting configuration failed',
- 'com.alibaba.nacos.page.configurationManagement.more': 'More',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter_the_dataID': 'Enter Data ID',
- 'com.alibaba.nacos.page.configRollback.inserted': 'Insert',
- 'com.alibaba.nacos.page.configeditor.Home_application:': 'Group name cannot be empty',
- 'com.alibaba.nacos.page.configurationManagement.environment': 'Region:',
- 'com.alibaba.nacos.component.NewNameSpace.prompt': 'Notice',
- 'com.alibaba.nacos.page.configurationManagement.push_track': 'Push Track',
- 'hanxie.show': 'test',
- 'com.alibaba.nacos.page.configdetail.configuration': 'Configuration Content:',
- 'com.alibaba.nacos.pubshow':
- 'The sub-account is not anthorized. Contact the owner of the primary account to grant permission first.',
- 'com.alibaba.nacos.page.newconfig.stop_fails': 'Failed to stop beta publishing.',
- 'com.alibaba.nacos.page.newconfig.group_placeholder': 'Enter your group name',
- 'nacos.page.namespace._Remove_the_namespace_success': ' Remove the namespace success',
- 'com.alibaba.nacos.component.MiddleWareEnv.from-test': 'Self-Test',
- 'com.alibaba.nacos.component.EditorNameSpace.public_space': 'OK',
- 'com.alibaba.nacos.page.consistencyEfficacy.details': 'Details',
- 'com.alibaba.nacos.page.configeditor.vdchart': 'Illegal characters not allowed',
- 'nacos.page.configurationManagement.Please_enter_application_name1': 'Enter App Name',
- 'com.alibaba.nacos.page.pushTrajectory.query_dimension:': 'Dimension:',
- 'nacos.page.namespace.sure_you_want_to_delete_the_following_namespaces?':
- 'Sure you want to delete the following namespaces?',
- 'nacos.component.ImportDialog.cover2': 'Overwrite',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_stable': 'Daily Stable',
- 'com.alibaba.nacos.component.EditorNameSpace.edit_namespace': 'Loading...',
- 'com.alibaba.nacos.page.newconfig.dataId_is_not_empty':
- 'Data ID cannot exceed 255 characters in length',
- 'com.alibaba.nacos.page.configurationManagement.article_meet_the_requirements':
- 'configuration items',
- 'com.alibaba.nacos.component.NewNameSpace.name': 'Namespace:',
- 'com.alibaba.nacos.page.configeditor.more_advanced_options': 'Collapse',
- 'com.alibaba.nacos.page.historyRollback.details': 'Details',
- 'nacos.page.newconfig._to_go_to_the_opening_of1': ' to go to the opening of',
- 'nacos.page.configurationManagement.please_select_the_required_delete_the_configuration_item':
- 'Select configuration items to delete',
- 'nacos.component.DeleteDialog.deletetitle': 'Delete Configuration',
- 'com.alibaba.nacos.page.configeditor.recipient_from': 'Data ID cannot be empty',
- 'nacos.page.namespace.namespace_ID': 'ID:',
- 'com.alibaba.nacos.component.MiddleWareEnv.Spas_dedicated': 'Spas Dedicated',
- historyRollback: 'Historical Versions',
- 'com.alibaba.nacos.page.newconfig.full_screen': 'Press Esc to exit',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_marked': 'environment marked',
- 'nacos.page.namespace.delete_failed': 'Failed to Delete',
- 'com.alibaba.nacos.page.configsync.configuration': 'Configuration Content:',
- configeditor: 'Edit Configuration',
- 'com.alibaba.nacos.component.NameSpaceList.immediate_use': 'Try Now',
- 'com.alibaba.nacos.page.configRollback.rollback': 'Roll Back',
- 'com.alibaba.nacos.page.configeditor.configuration_format:':
- 'Deselected by default. Learn more about beta publishing.\n',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_name': 'environment name,',
- 'com.alibaba.nacos.page.configeditor.': 'Back',
- 'nacos.component.validateDialog.Click_to_get_verification_code':
- 'Click to Get Verification Code',
- configRollback: 'Configuration Rollback',
- 'com.alibaba.nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_message':
- 'Announcement: Node.js version now available, supporting customized messages.',
- 'nacos.page.configurationManagement.advanced_query9': 'Advanced Query',
- 'com.alibaba.nacos.page.configdetail.official': 'Official',
- 'nacos.page.configurationManagement.process_is_successful,_the_cloned':
- 'Process successfully, cloned ',
- 'nacos.component.ShowCodeing.,_new_PropertiesListener()_{_@Override_public_void_innerReceive(Pro':
- '", new PropertiesListener() {\t\t\t\t\t\t\t\t@Override\t\t\t\tpublic void innerReceive(Properties properties) {\t\t\t\t\t// TODO Auto-generated method stub\t\t\t\t\tacmProperties = properties;\t\t\t\t\tSystem.out.println(properties);\t\t\t\t}\t\t\t});\t\t\t\t\t\t**/\t\t\t\t\t} catch (ConfigException e) {\t\t\te.printStackTrace();\t\t}\t\t// 测试让主线程不退出,因为订阅配置是守护线程,主线程退出守护线程就会退出。 正式代码中无需下面代码\t\twhile (true) {\t\t\ttry {\t\t\t\tThread.sleep(1000);\t\t\t} catch (InterruptedException e) {\t\t\t\te.printStackTrace();\t\t\t}\t\t}\t}\t // 通过get接口把配置值暴露出去使用 public static String getConfig() { return config; } \t// 通过get接口把配置值暴露出去使用\tpublic static Object getPorpertiesValue(String key) {\t\tif (acmProperties != null) {\t\t\treturn acmProperties.get(key);\t\t}\t\treturn null;\t}}',
- 'com.alibaba.nacos.page.listeningToQuery.query_dimension': 'Dimension:',
- 'nacos.component.DeleteDialog.determine': 'OK',
- 'com.alibaba.nacos.page.configurationManagement.details': 'Details',
- pubnodata: 'No results found.',
- configdetail: 'Configuration Details',
- 'com.alibaba.nacos.page.configurationManagement.edit': 'Edit',
- 'com.alibaba.nacos.page.listAllEnvironmental.view_environment_IP': 'View environment IP',
- 'com.alibaba.nacos.page.historyDetail.home': 'Application:',
- 'com.alibaba.nacos.page.configeditor.configuration_formatpre': 'Deselected by default. ',
- 'com.alibaba.nacos.component.AddGroup.prompt': 'Notice',
- 'com.alibaba.nacos.page.consistencyEfficacy.configuration_content_md5':
- 'Configuration Content MD5',
- 'com.alibaba.nacos.component.NameSpaceList.online_customer_support': 'Online Customer Support:',
- 'nacos.page.configurationManagement.Delete_failed': 'Delete failed',
- 'com.alibaba.nacos.page.consistencyEfficacy.edit': 'Edit',
- 'nacos.component.ExportDialog.HOME_Application1': 'Application:',
- 'com.alibaba.nacos.page.configurationManagement.fuzzyd': 'Enter Data ID',
- 'com.alibaba.nacos.page.listeningToQuery.query': 'Search',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_environment_packet': 'Daily Environment Group',
- 'com.alibaba.nacos.component.NewDatePicker.to': 'Search Range:',
- 'nacos.component.ExportDialog.export3': 'Export',
- 'com.alibaba.nacos.layout.noenv.Click_to_learn_the_namespace': 'Learn more about namespace',
- 'com.alibaba.nacos.page.pushTrajectory.determine': 'Search',
- 'com.alibaba.nacos.page.historyRollback.dataid': 'Enter Data ID',
- 'nacos.page.namespace.SecretKey_recommended3':
- 'SecretKey (Recommended for development environment):',
- 'com.alibaba.nacos.page.historyDetail.insert': 'Insert',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_units': 'Daily Units',
- 'nacos.component.validateDialog.confirm': 'confirm',
- 'com.alibaba.nacos.component.EditorNameSpace.please_do': 'Illegal characters not allowed',
- 'nacos.page.configurationManagement.view_details1': 'view details',
- 'com.alibaba.nacos.component.NewDatePicker.to_cancel_the': 'OK',
- 'nacos.component.validateDialog.phoneNumber': 'Mobile phone number:',
- 'com.alibaba.nacos.page.newconfig.Group_ID_cannot_be_longer': 'Application:',
- 'nacos.page.newconfig.The_opening_of_the_data_encryption-related_services0':
- 'The Opening of the Data Encryption-Related Services',
- 'com.alibaba.nacos.component.MiddleWareEnv.cloud_unit': 'Cloud Unit',
- 'com.alibaba.nacos.component.NewDatePicker.recently': 'Cancel',
- 'nacos.page.namespace.Namespace': 'Namespaces',
- 'com.alibaba.nacos.page.listAllEnvironmental.operation': 'operation',
- 'nacos.page.configurationManagement.select_need_to_clone_the_configuration_items1':
- 'Please select configuration items to clone.',
- 'nacos.page.configurationManagement.ACM_dedicated_AccessKey_will_the_waste,_does_not_recommend_the_use_of5':
- "ACM's dedicated AccessKey (To be deprecated soon and not recommended):",
- 'nacos.component.CloneDialog.tags': 'tags:',
- 'com.alibaba.nacos.component.NewNameSpace.confirm': 'OK',
- 'com.alibaba.nacos.page.configRollback.home': 'Application:',
- 'nacos.page.configurationManagement.a_ACM_front-end_monitoring_questionnaire,_the_time_limit_to_receive_Ali_cloud_voucher_details_shoved_stamp_the3':
- 'a ACM front-end monitoring questionnaire, the time limit to receive Ali cloud voucher details shoved stamp: the',
- 'com.alibaba.nacos.page.configeditor.Esc_exit': 'Press F1 to view in full screen',
- 'nacos.page.configurationManagement.click_on_the_obtain_of3': 'Click on the obtain of',
- 'com.alibaba.nacos.page.listAllEnvironmental.view': 'View',
- 'nacos.page.configeditor.Description': 'Description:',
- 'com.alibaba.nacos.page.historyDetail.belongs_to_the_environment': 'Region:',
- 'nacos.page.configurationManagement.off_the_Bulletin_Board5': 'off the Bulletin Board',
- 'com.alibaba.nacos.page.configeditor.release_beta': 'Press Esc to exit ',
- 'com.alibaba.nacos.page.configurationManagement.Remove_configuration': 'Delete Configuration',
- 'nacos.page.namespace.deleted_successfully': 'Deleted successfully',
- 'nacos.component.CloneDialog.configuration_cloning(': 'Clone(',
- 'com.alibaba.nacos.page.configRollback.configuration': 'Configuration Content:',
- 'com.alibaba.nacos.component.DiffEditorDialog.original_value': 'Original Value',
- 'com.alibaba.nacos.page.historyDetail.return': 'Back',
- 'com.alibaba.nacos.page.configeditor.configure_contents_of': 'Format:',
- 'com.alibaba.nacos.page.listeningToQuery.article_meet_the_requirements_of_the_configuration.':
- 'configuration items.',
- 'com.alibaba.nacos.page.configurationManagement.query': 'Search',
- 'com.alibaba.nacos.page.historyRollback.last_update_time': 'Last Modified At',
- 'nacos.component.CloneDialog.source_space': 'Source :',
- 'nacos.component.ShowCodeing.);_/**_*_生产环境通过jvm参数传参,以便使用多个环境,_-Dacm.endpoint=':
- '");\t\t\t\t\t\t/**\t\t\t * 生产环境通过JVM参数传参,以便使用多个环境, -Dacm.endpoint=',
- 'com.alibaba.nacos.layout.noenv.does_not_exist': 'The page you visit does not exist',
- 'com.alibaba.nacos.page.historyDetail.configure_content': 'Configuration Content:',
- 'nacos.component.ShowCodeing.*///_ConfigService.init();_//_主动获取配置_String_content_=_ConfigService.getConfig(':
- '*///\t\t\tConfigService.init();\t\t\t\t\t\t// 主动获取配置\t\t\tString content = ConfigService.getConfig("',
- 'com.alibaba.nacos.page.configurationManagement.query_results': 'Search Results: Found',
- 'nacos.component.ShowCodeing.,_new_ConfigChangeListener()_{_public_void_receiveConfigInfo(String':
- '", new ConfigChangeListener() {\t\t\t\tpublic void receiveConfigInfo(String configInfo) {\t\t\t\t\t// 当配置更新后,通过该回调函数将最新值吐给用户。\t\t\t\t\t// 注意回调函数中不要做阻塞操作,否则阻塞通知线程。\t\t\t\t\tconfig = configInfo;\t\t\t\t\tSystem.out.println(configInfo);\t\t\t\t}\t\t\t});\t\t\t\t\t\t/**\t\t\t * 如果配置值的內容为properties格式(key=value), 可使用下面监听器。以便一个配置管理多个配置项\t\t\t */\t\t\t\t\t\t/**\t\t\tConfigService.addListener("',
- 'com.alibaba.nacos.page.consistencyEfficacy.advanced_query': 'Advanced Query',
- 'com.alibaba.nacos.page.historyDetail.delete': 'Delete',
- 'nacos.component.NameSpaceList.Forum': 'Forum',
- 'com.alibaba.nacos.page.namespace.prompt': 'Notice',
- 'com.alibaba.nacos.page.configdetail.more_advanced_options': 'Advanced Options',
- 'com.alibaba.nacos.page.listeningToQuery.listener_query': 'Listening Query',
- 'com.alibaba.nacos.page.newconfig.the_home_application': 'Target Region:',
- 'nacos.page.namespace.click_on_the_obtain_of1': 'Click on the obtain of',
- 'nacos.component.NameSpaceList.Quick_to_learn0': 'Learning Path',
- 'nacos.component.CloneDialog.get_the_namespace_failed': 'get the namespace failed',
- 'com.alibaba.nacos.component.EditorNameSpace.namespace': 'Namespace cannot be empty',
- 'nacos.component.validateDialog.remark':
- 'Tip: The verification code will be sent through SMS to your bound phone number.',
- 'com.alibaba.nacos.page.consistencyEfficacy.query': 'Query',
- 'com.alibaba.nacos.page.environmentalManagement.environment_name': 'environment name,',
- 'com.alibaba.nacos.page.listAllEnvironmental.environment_IP': 'environment IP',
- 'com.alibaba.nacos.page.listeningToQuery.success': 'Success',
- 'nacos.component.CloneDialog.|_the_selected_entry': '| Selected entry',
- 'com.alibaba.nacos.component.MiddleWareEnv.offline': 'Offline',
- 'com.alibaba.nacos.page.listeningToQuery.please_input_ip': 'Enter IP',
- 'com.alibaba.nacos.page.historyDetail.recipient_from': 'Collapse',
- 'com.alibaba.nacos.page.newconfig.configuration_format': 'Configuration Content',
- 'com.alibaba.nacos.component.NewDatePicker.query_range:': 'Customize',
- 'nacos.component.CloneDialog.skip': 'Skip',
- 'com.alibaba.nacos.page.listeningToQuery.please_enter_the_dataid': 'Enter Data ID',
- 'com.alibaba.nacos.component.NewDatePicker.7_day': '7 days',
- 'nacos.component.ShowCodeing.-Dproject.name=acmtest_-Dspas.identity=CUserswater.lyl.spas_keyacmt':
- '-Dproject.name=acmtest -Dspas.identity=C:Userswater.lyl.spas_keyacmtest\t\t\t * 在本地的acmtest文件中填写accessKey/secretKey,格式如下\t\t\t * accessKey=',
- 'com.alibaba.nacos.service.fill_the_code': 'Please fill out the verification code',
- 'com.alibaba.nacos.page.historyDetail.more_advanced_options': 'Advanced Options',
- 'com.alibaba.nacos.page.newconfig.configure_contents_of': 'Press F1 to view in full screen',
- 'nacos.component.ImportDialog.file_upload_directly_after_importing_the_configuration,_please_be_':
- 'Caution: Data will be imported directly after uploading.',
- 'com.alibaba.nacos.page.newconfig.configuration_contentmax':
- 'Configuration content cannot exceed 10240 characters in length',
- 'com.alibaba.nacos.page.listAllEnvironmental.all_available_environment':
- 'all available environment',
- 'nacos.page.configurationManagement.configuration_management8': 'configuration management',
- 'com.alibaba.nacos.component.NewDatePicker.': 'Last',
- 'nacos.page.configurationManagement.configuration': ' configuration',
- 'nacos.page.configurationManagement._The_process_is_successful,_delete_the':
- 'Process successfully, delete ',
- 'com.alibaba.nacos.page.configsync.target': 'Target Region:',
- 'com.alibaba.nacos.page.newconfig.new_listing': 'Create Configuration',
- Configdetail: 'Configuration Details',
- 'nacos.page.configdetail.Tags': 'Tags:',
- listeningToQuery: 'Listening Query',
- 'nacos.page.configurationManagement.,_wherein': ', wherein ',
- 'com.alibaba.nacos.page.configRollback.retracted': 'Collapse',
- 'nacos.component.validateDialog.title': 'Account Security Verification',
- 'com.alibaba.nacos.page.configsync.belongs_to_the_environment': 'Region:',
- 'com.alibaba.nacos.page.configeditor.return': 'Publish',
- 'com.alibaba.nacos.page.historyRollback.queryresult': 'Search Results: Found',
- 'com.alibaba.nacos.page.configurationManagement.the_sample_code': 'Code Example',
- 'nacos.page.configurationManagement.Cloning_check_fails': 'Cloning check fails',
- 'nacos.page.configurationManagement.process_is_successful,_import_the':
- 'Process successfully, import ',
- 'com.alibaba.nacos.page.consistencyEfficacy.environment_marked': 'environment marked',
- 'com.alibaba.nacos.page.namespace.namespace_names': 'Namespaces ',
- 'nacos.page.namespace.details': 'Details',
- 'com.alibaba.nacos.page.configdetail.error': 'Error',
- 'com.alibaba.nacos.component.AddGroup.a_new_group': 'Create Group',
- 'com.alibaba.nacos.component.DiffEditorDialog.contents': 'Content Comparison',
- 'com.alibaba.nacos.page.configRollback.return': 'Back',
- 'com.alibaba.nacos.page.configurationManagement.configuration_management': 'Configurations',
- 'nacos.page.configurationManagement.import_failed': 'Import Failed',
- 'com.alibaba.nacos.page.consistencyEfficacy.operation': 'Actions',
- 'nacos.component.ExportDialog.configuration_number6': 'Items:',
- 'com.alibaba.nacos.page.pushTrajectory.getconifg': 'Configuration Push or Get Configuration',
- 'com.alibaba.nacos.page.environmentalManagement.view_environment_IP': 'View environment IP',
- historyDetail: 'History Details',
- 'com.alibaba.nacos.component.EditorNameSpace.private': 'Public Space',
- 'com.alibaba.nacos.page.configdetail.beta_release': 'Beta Publish:',
- 'com.alibaba.nacos.page.historyRollback.group': 'Enter Group',
- 'com.alibaba.nacos.component.NameSpaceList.Prompt': 'Notice',
- 'com.alibaba.nacos.page.pushTrajectory.the_query_results': 'Search Results: Found',
- 'com.alibaba.nacos.page.pushTrajectory.used': 'New Configuration Published',
- 'nacos.page.namespace._Details_of6': ' Details of',
- 'nacos.page.namespace.namespace_number': 'Namespace ID',
- 'com.alibaba.nacos.page.historyrollback.query': 'Search',
- 'nacos.component.ExportDialog.tags2': 'Tags:',
- 'nacos.page.configurationManagement.Please_enter_tag': 'Enter Tag',
- 'nacos.component.ImportDialog.You_can_only_upload._zip_file_format0':
- 'Only upload. zip file format',
- 'nacos.component.CloneDialog.|_the_selected_entry4': '| Selected Entry',
- 'com.alibaba.nacos.page.pushTrajectory.track': 'push tracks.',
- 'nacos.page.configurationManagement.HOME_Application0': 'Application:',
- 'com.alibaba.nacos.component.NewDatePicker.24_hours': '24 hours',
- 'com.alibaba.nacos.component.DiffEditorDialog.confirm_that_the': 'Publish',
- 'com.alibaba.nacos.component.EditorNameSpace.prompt': 'Notice',
- 'nacos.page.namespace.AccessKey_recommended1':
- 'AccessKey (Recommended for development environment):',
- 'com.alibaba.nacos.page.configsync.sync': 'Synchronize',
- 'com.alibaba.nacos.page.historyRollback.to_configure':
- 'Historical Versions (Configuration record is retained for 30 days.)',
- 'com.alibaba.nacos.page.pushTrajectory.interval': 'Time Range:',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily': 'Daily',
- pushTrajectory: 'Push Tracks',
- 'com.alibaba.nacos.component.MiddleWareEnv.switch_environment': 'Switch Environment',
- 'com.alibaba.nacos.component.NewDatePicker.determine': 'to',
- 'nacos.page.configdetail.Open0': 'Open',
- 'com.alibaba.nacos.page.historyRollback.article_meet': 'configuration items.',
- 'com.alibaba.nacos.page.configeditor.release': 'Beta Publish',
- 'nacos.page.newconfig.to_the_authorization_of2': 'to the authorization of',
- 'com.alibaba.nacos.component.NewNameSpace.namespacenotnull': 'Namespace cannot be empty',
- 'nacos.page.newconfig.Note_You_are_to_be_a_custom_packet_the_new_configuration,_make_sure_that_the_client_use_the_Pandora_version_higher_than_3._4._0,_otherwise_it_may_read_less_than_the_configuration.0':
- 'Notice: You are going to add configuration to a new group, please make sure that the version of Pandora which clients are using is higher than 3.4.0, otherwise this configuration may be unreadable to clients.',
- 'com.alibaba.nacos.page.configRollback.action_type': 'Action Type:',
- 'nacos.page.configurationManagement.SecretKey_recommended4': 'SecretKey recommended:',
- 'nacos.component.validateDialog.cancel': 'cancel',
- 'com.alibaba.nacos.component.AddGroup.group_name': 'Group name:',
- 'nacos.page.configurationManagement.no_longer_display4': 'no longer display:',
- 'com.alibaba.nacos.component.DiffEditorDialog.of_the_current_area': 'Current Value',
- 'com.alibaba.nacos.page.configRollback.belongs_to': 'Region:',
- 'com.alibaba.nacos.page.configeditor.F1/fn F1(MAC)full_screen': 'Configuration Content',
- recent: 'Last ',
- configurationManagement: 'Configurations',
- 'com.alibaba.nacos.page.historyRollback.operation': 'Actions',
- 'com.alibaba.nacos.page.historyDetail.action_type': 'Action Type:',
- 'com.alibaba.nacos.component.MiddleWareEnv.online': 'Online',
- 'nacos.page.configurationManagement.configuration_item?': 'configuration items?',
- 'com.alibaba.nacos.page.pushTrajectory.configget': 'Get Configuration',
- 'com.alibaba.nacos.page.listeningToQuery._Push_state': 'Push Status',
- 'com.alibaba.nacos.page.listAllEnvironmental.Into_the': 'Into the',
- 'com.alibaba.nacos.page.pushTrajectory.user_Ip:': 'User IP:',
- 'nacos.component.CloneDialog.start_cloning': 'Start Clone',
- 'com.alibaba.nacos.page.configurationManagement.new_listing': 'Create Configuration',
- 'com.alibaba.nacos.component.MiddleWareEnv.online_center': 'Online Center',
- 'nacos.component.ShowCodeing.-Dproject.name=acmtest_-Dspas.identity=CUserswater.lyl.spas_keyacmtest_*_在本地的acmtest文件中填写accessKey/secretKey,格式如下_*_accessKey=':
- '-Dproject.name=acmtest -Dspas.identity=C:Userswater.lyl.spas_keyacmtest\t\t\t * 在本地的acmtest文件中填写accessKey/secretKey,格式如下\t\t\t * accessKey=',
- 'com.alibaba.nacos.page.configRollback.for_more_advanced': 'Advanced Options',
- 'com.alibaba.nacos.page.configurationManagement.last_modified_time': 'Last Modified At',
- namespace: 'Namespaces',
- 'nacos.page.configdetail.Data_encryption0': 'Data encryption',
- 'com.alibaba.nacos.component.NewDatePicker.3_day': '3 days',
- 'nacos.component.ShowCodeing.package_com.alibaba.middleware.acm;import_java.util.Properties;impo':
- 'package com.alibaba.middleware.acm;import java.util.Properties;import com.alibaba.edas.acm.ConfigService;import com.alibaba.edas.acm.exception.ConfigException;import com.alibaba.edas.acm.listener.ConfigChangeListener;import com.alibaba.edas.acm.listener.PropertiesListener;// 示例代码,仅用于示例测试public class ACMTest { // 属性/开关 private static String config = "DefaultValue";\t private static Properties acmProperties = new Properties(); \tpublic static void main(String[] args) {\t\ttry {\t\t\t\t\t\t// 本地调试模式。本机测试无法连接ACM服务集群,因此设置debug模式(该模式下获取值为null,不会进入回调函数)。\t\t\t// ConfigService.setDebug(true);\t\t\t\t\t\t// 初始化配置服务,控制台通过示例代码自动获取下面参数\t\t\tConfigService.init("',
- 'com.alibaba.nacos.page.consistencyEfficacy.query_results': 'Search Results',
- 'com.alibaba.nacos.page.environmentalManagement.environment_marked': 'environment marked',
- 'com.alibaba.nacos.page.listeningToQuery.failure': 'Failure',
- 'com.alibaba.nacos.page.environmentalManagement.view': 'View',
- 'com.alibaba.nacos.page.configdetail.home': 'Application:',
- 'com.alibaba.nacos.page.pushTrajectory.please_enter': 'Enter IP',
- 'com.alibaba.nacos.page.historyRollback.rollback': 'Roll Back',
- 'nacos.page.configurationManagement.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_scenario,_it_is_recommended_to_Unified_the_use_of_Ali_cloud_AK/SK.7':
- "Note: ACM's dedicated AK/SK is mainly used for improved compatibilities. We recommend that you always use Alibaba Cloud AK/SK.",
- 'com.alibaba.nacos.page.consistencyEfficacy.reset': 'Reset',
- 'nacos.component.ExportDialog.export_configuration4': 'Export ( ',
- 'com.alibaba.nacos.page.environmentalManagement.environment_ip': 'environment IP',
- 'com.alibaba.nacos.component.MiddleWareEnv.new_diamond': 'Diamond(New Version)',
- 'com.alibaba.nacos.page.environmentalManagement.Into_the': 'Into the',
- 'com.alibaba.nacos.page.configdetail.recipient_from': 'Collapse',
- 'com.alibaba.nacos.page.configurationManagement.listener_query':
- 'Configuration Listening Query',
- 'com.alibaba.nacos.page.configurationManagement.suredelete':
- 'Are you sure you want to delete the following configuration?',
- 'nacos.component.CloneDialog.cover': 'Cover',
- 'nacos.page.configdetail.Description': 'Description:',
- 'com.alibaba.nacos.component.NewDatePicker.end_time_must_be_greater_than_the_start_time_of_the_t':
- 'The end time must be after the starttime',
- 'nacos.component.ShowCodeing.*///_ConfigService.init();_//_主动获取配置_String_content_=_ConfigService':
- '*///\t\t\tConfigService.init();\t\t\t\t\t\t// 主动获取配置\t\t\tString content = ConfigService.getConfig("',
- 'com.alibaba.nacos.page.environmentalManagement.all_available_environment':
- 'all available environment',
- 'nacos.page.configurationManagement.no_announcement6': 'no announcement',
- 'com.alibaba.nacos.page.listeningToQuery.please_input_group': 'Enter Group',
- 'com.alibaba.nacos.page.configsync.for_more_advanced_options': 'Advanced Options',
- 'com.alibaba.nacos.page.historyDetail.history_details': 'History Details',
- 'com.alibaba.nacos.component.NewDatePicker.custom': 'The time range cannot exceed 45 days',
- 'nacos.component.ShowCodeing.,_6000);_System.out.println(content);_//_初始化的时候,给配置添加监听,配置变更会回调通知_C':
- '", 6000);\t\t\tSystem.out.println(content);\t\t\t// 初始化的时候,给配置添加监听,配置变更会回调通知\t\t\tConfigService.addListener("',
- 'nacos.component.validateDialog.Please_fill_out_the_verification_code':
- 'Enter the verification code:',
- 'com.alibaba.nacos.page.newconfig.the_target_environment': 'Format:',
- 'nacos.page.configurationManagement.questionnaire2': 'questionnaire',
- 'nacos.page.configdetail.off1': 'off',
- 'nacos.page.configurationManagement.clone': 'Clone',
- 'com.alibaba.nacos.component.MiddleWareEnv.daily_test_center': 'Daily Test Center',
- 'com.alibaba.nacos.page.configRollback.the_following_configuration':
- 'the following configuration?',
- 'nacos.page.configurationManagement.failed_entry': 'Failed Entry:',
- 'com.alibaba.nacos.component.NewNameSpace.cancel': 'Cancel',
- 'nacos.component.CloneDialog.select_namespace': 'Select Namespace',
- 'nacos.page.configurationManagement.export': 'Export',
- 'nacos.page.configurationManagement.AccessKey_recommended2': 'AccessKey recommended:',
- 'com.alibaba.nacos.component.MiddleWareEnv.line': 'Online/',
- 'com.alibaba.nacos.component.NewNameSpace.loading': 'Loading...',
- 'nacos.page.newconfig.Note_You_are_to_be_a_custom_packet_the_new_configuration,_make_sure_that_t':
- 'Note: You are to be a custom packet the new configuration, make sure that the client use the Pandora version higher than 3. 4. 0, otherwise it may read less than the configuration.',
- 'com.alibaba.nacos.page.configurationManagement.fuzzyg': 'Enter Group',
- 'com.alibaba.nacos.page.pushTrajectory.interval:': 'Time Range:',
- 'nacos.component.ImportDialog.skip1': 'Skip',
- 'com.alibaba.nacos.page.listeningToQuery.query_results:_query': 'Search Results: Found',
- 'com.alibaba.nacos.page.form.Data_Id_can_not_be_empty': 'Data ID cannot be empty',
- 'com.alibaba.nacos.page.listeningToQuery.group_can_not_be_empty': 'Group cannot be empty',
- 'com.alibaba.nacos.page.pushTrajectory.please_input_Group': 'Enter Group',
- 'com.alibaba.nacos.page.configRollback.rollback_successful': 'Rollback Successful',
- 'com.alibaba.nacos.component.MiddleWareEnv.payTM_daily': 'payTM Daily',
- 'nacos.page.configurationManagement.unprocessed_entry': 'Unprocessed Entry:',
- 'nacos.component.ImportDialog.To_terminate_the_import0': 'Terminate',
- 'nacos.page.configurationManagement.import': 'Import',
- 'com.alibaba.nacos.page.configRollback.configuration_rollback': 'Configuration Rollback',
- 'nacos.page.configurationManagement.HOME_Application': 'Application',
- 'com.alibaba.nacos.layout.noenv.app_configuration_management_acm': 'NACOS',
- 'nacos.page.namespace.SecretKey_recommended2': 'SecretKey recommended:',
- newconfig: 'Create Configuration',
- 'nacos.component.validateDialog.fill_the_code': 'Please fill out the verification code',
- 'nacos.page.configurationManagement.ecs_ram_role':
- 'Automatically issued the AccessKey and SecretKey (Recommended for production environment):',
- 'nacos.component.DeleteDialog.Configuration_management': 'Configuration Management',
- 'com.alibaba.nacos.page.pushTrajectory.The_new_configuration_value_persistent':
- 'Configuration Published',
- 'nacos.page.newconfig.Description': 'Description:',
- 'nacos.component.ImportDialog.Import_configuration4': 'Import ( ',
- 'com.alibaba.nacos.page.configurationManagement.clickfordetail': 'Learn more about ACM SDKs',
- 'com.alibaba.nacos.page.newconfig.collapse': 'Advanced Options',
- 'com.alibaba.nacos.page.configurationManagement.click_to_learn_Group': 'Learn more about Group',
- 'com.alibaba.nacos.component.NewDatePicker.30_minutes': '30 minutes',
- 'com.alibaba.nacos.page.namespace.delete': 'Delete',
- 'nacos.page.namespace.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for_use4':
- 'ACM special SecretKey will be abandoned, not recommended for use:',
- dateinfo2: 'The time range cannot exceed 45 days',
- 'com.alibaba.nacos.page.newconfig.publish_failed':
- 'Publish failed. Make sure parameters are entered correctly.',
- 'com.alibaba.nacos.page.consistencyEfficacy.configuration_consistency_check':
- 'Configuration Consistency Check',
- 'nacos.page.configurationManagement.configuration_export9': 'Export',
- 'com.alibaba.nacos.page.configsync.sync_configuration_main': 'Synchronize Configuration',
- 'com.alibaba.nacos.page.namespace.public': 'public(to retain control)',
- 'com.alibaba.nacos.page.configeditor.wrong': 'Error',
- 'com.alibaba.nacos.page.configsync.error': 'Error',
- 'nacos.page.configurationManagement.ACM_special_SecretKey_will_be_abandoned,_not_recommended_for':
- 'ACM special SecretKey will be abandoned, not recommended for use:',
- 'com.alibaba.nacos.page.newconfig.release': 'Back',
- 'com.alibaba.nacos.component.NewDatePicker.4_hours': '4 hours',
- 'com.alibaba.nacos.page.configeditor.toedit': 'Edit Configuration',
- 'nacos.page.configurationManagement.AccessKey_recommended3':
- 'AccessKey (Recommended for development environment):',
- 'nacos.page.configurationManagement.items_for': ' items are ',
- 'com.alibaba.nacos.page.pushTrajectory.query_dimension': 'Query Dimension:',
- 'com.alibaba.nacos.page.listeningToQuery.configuration': 'Configuration',
- 'com.alibaba.nacos.page.configsync.retracted': 'Collapse',
- 'com.alibaba.nacos.component.NewDatePicker.12_hours': '12 hours',
- 'nacos.page.pushTrajectory.Please_enter_the_user_IP0': 'Enter IP',
- 'com.alibaba.nacos.component.MiddleWareEnv.international': 'Internationalization',
- 'com.alibaba.nacos.page.configeditor.the_target_environment:': 'Application:',
- day: ' days',
- 'nacos.page.configurationManagement.please_input_the_application_name': 'Enter app name',
- 'nacos.component.ImportDialog.file_upload_directly_after_importing_the_configuration,_please_be_sure_to_exercise_caution7':
- 'Caution: data will be imported directly after uploading.',
- 'com.alibaba.nacos.page.configurationManagement.delete': 'Delete',
- 'com.alibaba.nacos.component.SuccessDialog.Configuration_management':
- 'Configuration Management',
- 'com.alibaba.nacos.page.configRollback.updated': 'Update',
- 'com.alibaba.nacos.page.configRollback.determine': 'Are you sure you want to roll back',
- 'nacos.component.DeleteDialog.deleted_successfully_configured': 'Configuration deleted',
- 'nacos.page.configurationManagement.export_check_failed': 'Export check failed.',
- 'com.alibaba.nacos.page.configeditor.configcontent': 'Configuration Content',
- 'nacos.page.namespace.AccessKey_recommended0': 'AccessKey recommended:',
- 'nacos.page.namespace.region_ID': 'Region ID:',
- 'com.alibaba.nacos.component.NewNameSpace.norepeat':
- 'Duplicate namespace. Please enter a different name.',
- 'com.alibaba.nacos.component.EditorNameSpace.load': 'Namespace:',
- 'com.alibaba.nacos.page.configurationManagement.version': 'Historical Versions',
- 'com.alibaba.nacos.page.namespace.operation': 'Actions',
- 'com.alibaba.nacos.page.newconfig': 'Data ID cannot be empty.',
- 'nacos.component.validateDialog.verification_code_error': 'verification code error',
- 'nacos.page.namespace.remove_the_namespace': 'Remove the namespace',
- 'com.alibaba.nacos.component.MiddleWareEnv.performance': 'Performance',
- 'nacos.page.namespace.note_ACM_is_dedicated_AK/SK_is_mainly_used_for_some_of_the_compatibility_s':
- 'note: ACM is dedicated AK/SK is mainly used for some of the compatibility scenario, it is recommended to Unified the use of Ali cloud AK/SK.',
- 'nacos.component.ExportDialog.|_The_selected_entry0': '| Selected Entry',
- 'com.alibaba.nacos.component.EditorNameSpace.confirm_modify': 'Edit Namespace',
- 'com.alibaba.nacos.page.newconfig.do_not_ente': 'Illegal characters not allowed',
- 'nacos.page.newconfig.Data_encryption0': 'Data encryption',
- 'nacos.component.ShowCodeing.,_6000);_System.out.println(content);_//_初始化的时候,给配置添加监听,配置变更会回调通知_ConfigService.addListener(':
- '", 6000);\t\t\tSystem.out.println(content);\t\t\t// 初始化的时候,给配置添加监听,配置变更会回调通知\t\t\tConfigService.addListener("',
- 'nacos.page.configurationManagement.Clone_failed': 'Clone failed',
- 'com.alibaba.nacos.page.configdetail.return': 'Back',
- 'com.alibaba.nacos.page.configeditor.stop_beta': 'Stop Beta Publishing',
- 'com.alibaba.nacos.component.NewNameSpace.input': 'Illegal characters not allowed',
- 'nacos.page.configurationManagement.Tags': 'Tags:',
- 'com.alibaba.nacos.page.pushTrajectory.cluster_synchronization':
- 'Synchronization across Clusters ',
- 'nacos.page.namespace.ecs_ram_role':
- 'Automatically issued the AccessKey and SecretKey (Recommended for production environment):',
- 'nacos.page.configurationManagement.whether_to_delete_the_selected':
- 'Are you sure to delete the selected',
- 'nacos.page.configeditor.Tags': 'Tags:',
- 'com.alibaba.nacos.page.newconfig.stop_beta': 'Stop Beta Publishing',
- 'nacos.component.NameSpaceList.Announcement_nodejs_version_is_developed,supports_a_custom_message':
- 'Announcement: Node.js version now available, supporting customized messages.',
- 'nacos.page.configurationManagement.bulk_delete': 'Delete',
- 'com.alibaba.nacos.page.serviceManagement.service_list': 'Service List',
- 'com.alibaba.nacos.page.serviceManagement.service_name': 'Service Name',
- 'com.alibaba.nacos.page.serviceManagement.please_enter_the_service_name': 'Enter Service Name',
- 'com.alibaba.nacos.page.serviceManagement.table.column.service_name': 'Service Name',
- 'com.alibaba.nacos.page.serviceManagement.table.column.cluster_count': 'Cluster Count',
- 'com.alibaba.nacos.page.serviceManagement.table.column.ip_count': 'Instance Count',
- 'com.alibaba.nacos.page.serviceManagement.table.column.healthy_instance_count':
- 'Healthy Instance Count',
- 'com.alibaba.nacos.page.serviceManagement.table.column.operation': 'Operation',
- 'com.alibaba.nacos.page.serviceManagement.detail': 'Details',
- 'com.alibaba.nacos.page.serviceManagement.delete': 'Delete',
- 'com.alibaba.nacos.page.serviceManagement.prompt': 'Confirm',
- 'com.alibaba.nacos.page.serviceManagement.prompt_delete': 'Do you want to delete the service?',
- 'com.alibaba.nacos.page.serviceManagement.create': 'Create Service',
- 'com.alibaba.nacos.page.serviceManagement.query': 'Search',
- serviceManagement: 'Service Management',
- 'com.alibaba.nacos.page.serviceDetail.service_details': 'Service Details',
- 'com.alibaba.nacos.page.serviceDetail.create_service': 'Create Service',
- 'com.alibaba.nacos.page.serviceDetail.edit_service': 'Edit Service',
- 'com.alibaba.nacos.page.serviceDetail.back': 'Back',
- 'com.alibaba.nacos.page.serviceDetail.service_name': 'Service Name',
- 'com.alibaba.nacos.page.serviceDetail.protect_threshold': 'Protect Threshold',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern': 'Health check pattern',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.service': 'Service',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.client': 'Client',
- 'com.alibaba.nacos.page.serviceDetail.health_check_pattern.none': 'None',
- 'com.alibaba.nacos.page.serviceDetail.metadata': 'Metadata',
- 'com.alibaba.nacos.page.serviceDetail.update_service': 'Update Service',
- 'com.alibaba.nacos.page.serviceDetail.cluster': 'Cluster',
- 'com.alibaba.nacos.page.serviceDetail.edit_cluster': 'Edit Cluster',
- 'com.alibaba.nacos.page.serviceDetail.port': 'Port',
- 'com.alibaba.nacos.page.serviceDetail.weight': 'Weight',
- 'com.alibaba.nacos.page.serviceDetail.healthy': 'Healthy',
- 'com.alibaba.nacos.page.serviceDetail.operation': 'Operation',
- 'com.alibaba.nacos.page.serviceDetail.editor': 'Edit',
- 'com.alibaba.nacos.page.serviceDetail.offline': 'Offline',
- 'com.alibaba.nacos.page.serviceDetail.online': 'Online',
- 'com.alibaba.nacos.page.serviceDetail.check_type': 'Check Type',
- 'com.alibaba.nacos.page.serviceDetail.check_port': 'Check Port',
- 'com.alibaba.nacos.page.serviceDetail.use_ip_port_check': 'Use port of IP',
- 'com.alibaba.nacos.page.serviceDetail.check_path': 'Check Path',
- 'com.alibaba.nacos.page.serviceDetail.check_headers': 'Check Headers',
- 'com.alibaba.nacos.page.serviceDetail.update_cluster': 'Update Cluster',
- 'com.alibaba.nacos.page.serviceDetail.update_instance': 'Update Instance',
- 'com.alibaba.nacos.page.serviceDetail.whether_online': 'Whether Online',
- serviceDetail: 'Service Details',
- 'nacos.page.ConfigEditor.submit_failed': 'Cannot be empty, submit failed',
- },
-};
diff --git a/pigx-register/src/main/resources/static/console-fe/src/index.js b/pigx-register/src/main/resources/static/console-fe/src/index.js
index 6fe257b25..d3e4fddd3 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/index.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/index.js
@@ -30,7 +30,6 @@ import { LANGUAGE_KEY, REDUX_DEVTOOLS } from './constants';
import Login from './pages/Login';
import Namespace from './pages/NameSpace';
-import Password from './pages/Password';
import Newconfig from './pages/ConfigurationManagement/NewConfig';
import Configsync from './pages/ConfigurationManagement/ConfigSync';
import Configdetail from './pages/ConfigurationManagement/ConfigDetail';
@@ -44,6 +43,9 @@ import ServiceList from './pages/ServiceManagement/ServiceList';
import ServiceDetail from './pages/ServiceManagement/ServiceDetail';
import SubscriberList from './pages/ServiceManagement/SubscriberList';
import ClusterNodeList from './pages/ClusterManagement/ClusterNodeList';
+import UserManagement from './pages/AuthorityControl/UserManagement';
+import PermissionsManagement from './pages/AuthorityControl/PermissionsManagement';
+import RolesManagement from './pages/AuthorityControl/RolesManagement';
import Welcome from './pages/Welcome/Welcome';
import reducers from './reducers';
@@ -65,17 +67,13 @@ const reducer = combineReducers({
const store = createStore(
reducer,
- compose(
- applyMiddleware(thunk),
- window[REDUX_DEVTOOLS] ? window[REDUX_DEVTOOLS]() : f => f
- )
+ compose(applyMiddleware(thunk), window[REDUX_DEVTOOLS] ? window[REDUX_DEVTOOLS]() : f => f)
);
const MENU = [
{ path: '/', exact: true, render: () => },
{ path: '/welcome', component: Welcome },
{ path: '/namespace', component: Namespace },
- { path: '/password', component: Password },
{ path: '/newconfig', component: Newconfig },
{ path: '/configsync', component: Configsync },
{ path: '/configdetail', component: Configdetail },
@@ -89,12 +87,12 @@ const MENU = [
{ path: '/serviceDetail', component: ServiceDetail },
{ path: '/subscriberList', component: SubscriberList },
{ path: '/clusterManagement', component: ClusterNodeList },
+ { path: '/userManagement', component: UserManagement },
+ { path: '/rolesManagement', component: RolesManagement },
+ { path: '/permissionsManagement', component: PermissionsManagement },
];
-@connect(
- state => ({ ...state.locale }),
- { changeLanguage }
-)
+@connect(state => ({ ...state.locale }), { changeLanguage })
class App extends React.Component {
static propTypes = {
locale: PropTypes.object,
diff --git a/pigx-register/src/main/resources/static/console-fe/src/index.scss b/pigx-register/src/main/resources/static/console-fe/src/index.scss
index 43296514b..798d08033 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/index.scss
+++ b/pigx-register/src/main/resources/static/console-fe/src/index.scss
@@ -1217,10 +1217,6 @@ form.vertical-margin-lg .form-group {
border-color: #e0e0e0 !important;
}
-.main-container {
- padding: 10px;
-}
-
.row-bg-green {
background-color: #e4fdda;
}
diff --git a/pigx-register/src/main/resources/static/console-fe/src/layouts/Header.js b/pigx-register/src/main/resources/static/console-fe/src/layouts/Header.js
index 4e3e94adc..c1543a7e7 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/layouts/Header.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/layouts/Header.js
@@ -18,14 +18,13 @@ import { connect } from 'react-redux';
import { ConfigProvider, Dropdown, Menu } from '@alifd/next';
import siteConfig from '../config';
import { changeLanguage } from '@/reducers/locale';
+import PasswordReset from '../pages/AuthorityControl/UserManagement/PasswordReset';
+import { passwordReset } from '../reducers/authority';
import './index.scss';
@withRouter
-@connect(
- state => ({ ...state.locale }),
- { changeLanguage }
-)
+@connect(state => ({ ...state.locale }), { changeLanguage })
@ConfigProvider.config
class Header extends React.Component {
static displayName = 'Header';
@@ -38,6 +37,8 @@ class Header extends React.Component {
changeLanguage: PropTypes.func,
};
+ state = { passwordResetUser: '' };
+
switchLang = () => {
const { language = 'en-US', changeLanguage } = this.props;
const currentLanguage = language === 'en-US' ? 'zh-CN' : 'en-US';
@@ -50,16 +51,23 @@ class Header extends React.Component {
};
changePassword = () => {
- this.props.history.push('/password');
+ this.setState({
+ passwordResetUser: this.getUsername(),
+ });
};
getUsername = () => {
const token = window.localStorage.getItem('token');
if (token) {
- const base64Url = token.split('.')[1];
+ const [, base64Url = ''] = token.split('.');
const base64 = base64Url.replace('-', '+').replace('_', '/');
- const parsedToken = JSON.parse(window.atob(base64));
- return parsedToken.sub;
+ try {
+ const parsedToken = JSON.parse(window.atob(base64));
+ return parsedToken.sub;
+ } catch (e) {
+ delete localStorage.token;
+ location.reload();
+ }
}
return '';
};
@@ -71,6 +79,7 @@ class Header extends React.Component {
location: { pathname },
} = this.props;
const { home, docs, blog, community, languageSwitchButton } = locale;
+ const { passwordResetUser = '' } = this.state;
const BASE_URL = `https://nacos.io/${language.toLocaleLowerCase()}/`;
const NAV_MENU = [
{ id: 1, title: home, link: BASE_URL },
@@ -79,45 +88,56 @@ class Header extends React.Component {
{ id: 4, title: community, link: `${BASE_URL}community/index.html` },
];
return (
-
+
+
+ passwordReset(user).then(res => {
+ return res;
+ })
+ }
+ onCancel={() => this.setState({ passwordResetUser: undefined })}
+ />
+ >
);
}
}
diff --git a/pigx-register/src/main/resources/static/console-fe/src/layouts/MainLayout.js b/pigx-register/src/main/resources/static/console-fe/src/layouts/MainLayout.js
index 997338ce6..f9ffcc612 100755
--- a/pigx-register/src/main/resources/static/console-fe/src/layouts/MainLayout.js
+++ b/pigx-register/src/main/resources/static/console-fe/src/layouts/MainLayout.js
@@ -13,506 +13,127 @@
import React from 'react';
import { withRouter } from 'react-router-dom';
-import PropTypes from 'prop-types';
-import { ConfigProvider, Icon } from '@alifd/next';
-import Header from './Header';
-import $ from 'jquery';
import { connect } from 'react-redux';
-import { setParams } from '../globalLib';
+import PropTypes from 'prop-types';
+import { ConfigProvider, Icon, Menu } from '@alifd/next';
+import Header from './Header';
import { getState } from '../reducers/base';
-import _menu from '../menu';
+import getMenuData from './menu';
-import './index.scss';
+const { SubMenu, Item } = Menu;
@withRouter
-@connect(
- state => ({ ...state.locale, ...state.base }),
- { getState }
-)
+@connect(state => ({ ...state.locale, ...state.base }), { getState })
@ConfigProvider.config
class MainLayout extends React.Component {
static displayName = 'MainLayout';
static propTypes = {
- history: PropTypes.object,
- location: PropTypes.object,
locale: PropTypes.object,
- children: PropTypes.any,
+ location: PropTypes.object,
+ history: PropTypes.object,
version: PropTypes.any,
- functionMode: PropTypes.any,
getState: PropTypes.func,
+ functionMode: PropTypes.string,
+ children: PropTypes.object,
};
- constructor(props) {
- super(props);
- this.deepNav = [];
- this.oneLevelNavArr = {}; // 平行导航map
- this.state = {
- navList: [..._menu.data],
- leftBarClose: false,
- showLink: null,
- navRow: [],
- noChild: false,
- };
- }
-
componentDidMount() {
this.props.getState();
- this.refreshNav();
}
goBack() {
this.props.history.goBack();
}
- nacosToggleNav(id, event) {
- event.preventDefault();
- const nowNav = document.getElementById(id);
- const iconClass = nowNav.querySelector('.iconshow');
- const subNav = nowNav.querySelector('.subnavlist');
- const { classList } = iconClass;
- let tmpClassName = 'iconshow ';
- for (let i = 0; i < classList.length; i++) {
- if (classList[i] === 'icon-arrow-down') {
- subNav.style.display = 'none';
- subNav.className += ' hidden';
- tmpClassName += 'icon-arrow-right';
- }
- if (classList[i] === 'icon-arrow-right') {
- tmpClassName += 'icon-arrow-down';
- subNav.className = subNav.className.replace(/hidden/g, '');
- subNav.style.display = 'block';
- }
- }
- iconClass.className = tmpClassName;
- }
-
- /**
- * Click the back button
- * TODO: this.props.history.goBack(); ???
- * @param url
- */
- nacosGoBack(url) {
- const params = window.location.hash.split('?')[1];
- const urlArr = params.split('&') || [];
- const queryParams = [];
- for (let i = 0; i < urlArr.length; i++) {
- if (
- urlArr[i].split('=')[0] !== '_k' &&
- urlArr[i].split('=')[0] !== 'dataId' &&
- urlArr[i].split('=')[0] !== 'group'
- ) {
- if (urlArr[i].split('=')[0] === 'searchDataId') {
- queryParams.push(`dataId=${urlArr[i].split('=')[1]}`);
- } else if (urlArr[i].split('=')[0] === 'searchGroup') {
- queryParams.push(`group=${urlArr[i].split('=')[1]}`);
- } else {
- queryParams.push(urlArr[i]);
- }
- }
- }
- if (localStorage.getItem('namespace')) {
- queryParams.push(`namespace=${localStorage.getItem('namespace')}`);
- }
- this.props.history.push(`/${url}?${queryParams.join('&')}`);
- }
-
- nacosEnterBack() {
- document.getElementById('backarrow').style.color = '#09c';
- }
-
- nacosOutBack() {
- document.getElementById('backarrow').style.color = '#546478';
- }
-
- nacosToggleLeftBar() {
- if (!this.nacosOutDom) return;
- if (!this.state.leftBarClose) {
- // 关闭
- this.nacosOutDom.className = 'viewFramework-product';
- this.nacosLeftBarDom.style.width = 0;
- this.nacosBodyDom.style.left = 0;
- this.nacosToggleIconDom.style.left = 0;
- } else {
- this.nacosOutDom.className = 'viewFramework-product viewFramework-product-col-1';
- this.nacosLeftBarDom.style.width = '180px';
- this.nacosBodyDom.style.left = '180px';
- this.nacosToggleIconDom.style.left = '160px';
- }
-
- this.setState({
- leftBarClose: !this.state.leftBarClose,
- });
- }
-
navTo(url) {
- if (url !== '/configdetail' && url !== '/configeditor') {
- // 二级菜单不清空
- setParams({
- dataId: '',
- group: '',
- });
- }
-
- const params = window.location.hash.split('?')[1];
- const urlArr = params.split('&') || [];
- const queryParams = [];
- for (let i = 0; i < urlArr.length; i++) {
- if (urlArr[i].split('=')[0] !== '_k') {
- queryParams.push(urlArr[i]);
- }
- }
-
- this.props.history.push(`${url}?${queryParams.join('&')}`);
+ const { search } = this.props.location;
+ this.props.history.push([url, search].join(''));
}
- nacosSetSpecialNav(item) {
- item.children.forEach(_item => {
- const obj = _item;
+ isCurrentPath(url) {
+ const { location } = this.props;
+ return url === location.pathname ? 'current-path' : undefined;
+ }
- if (obj.dontUseChild === true) {
- obj.parentName = item.title;
- obj.parentId = item.id;
- obj.parentPath = `/${item.id}`;
- this.deepNav.push(obj);
- }
- if (_item.children) {
- this.nacosSetSpecialNav(_item);
+ defaultOpenKeys() {
+ const MenuData = getMenuData(this.props.functionMode);
+ for (let i = 0, len = MenuData.length; i < len; i++) {
+ const { children } = MenuData[i];
+ if (children && children.filter(({ url }) => url === this.props.location.pathname).length) {
+ return String(i);
}
+ }
+ }
+
+ isShowGoBack() {
+ const urls = [];
+ const MenuData = getMenuData(this.props.functionMode);
+ MenuData.forEach(item => {
+ if (item.url) urls.push(item.url);
+ if (item.children) item.children.forEach(({ url }) => urls.push(url));
});
- }
-
- nacosNavAct(serviceName, match, location) {
- if (!match) {
- const formatpath = location.pathname.substr(1); // 得到当前路径
- const nowpathobj = this.oneLevelNavArr[formatpath]; // 根据平行导航匹配父类
- if (nowpathobj) {
- if (nowpathobj.parent === serviceName) {
- // 如果父类等于当前的导航则高亮
- return true;
- }
- }
-
- return false;
- }
- return true;
- }
-
- nacosLoopNavDeeply(data, parentServiceName) {
- // 深度遍历获取所有的导航数据
- data.forEach(item => {
- if (item) {
- const navObj = item;
-
- const _parentServiceName = item.serviceName;
- navObj.parentServiceName = parentServiceName;
- this.oneLevelNavArr[item.serviceName] = navObj; // 得到每一个层级的导航映射
- if (item.children && item.children.length > 0) {
- this.nacosLoopNavDeeply(item.children, _parentServiceName);
- }
- }
- });
- }
-
- activeNav(id) {
- if (this.preActNav) {
- this.preActNav.removeClass('active');
- }
- const nowNav = $(`#${id}`);
- nowNav.addClass('active');
- this.preActNav = nowNav;
- }
-
- nacosLoopNav(data, _index = 0, parent) {
- const { locale = {}, location = {} } = this.props;
- const { pathname } = location;
- let index = _index;
- // 遍历导航,只显示2级
- const self = this;
- return data.map(item => {
- if (!item) return '';
- index++;
- if (item.dontUseChild === true) return '';
- if (item.children && item.children.length > 0) {
- if (item.isVirtual) {
- // 如果是虚拟菜单需要增加展开箭头
- const icon = item.isExtend ? (
-
- ) : (
-
- );
- const hiddenClass = item.isExtend ? '' : 'hidden';
- return (
-
-
-
- {self.nacosLoopNav(item.children, index)}
-
-
- );
- } else {
- return (
-
-
-
- {locale[item.serviceName]}
-
-
- );
- }
- }
- return (
-
-
-
- {locale[item.serviceName]}
-
-
- );
- });
- }
-
- nacosGetNav(navList) {
- let navRow = ''; // 导航
- if (navList.length > 0) {
- navRow = {this.nacosLoopNav(navList)} ;
- this.nacosLoopNavDeeply(navList); // 深度遍历导航树获得平行map
- }
- return navRow;
- }
-
- renderNav() {
- const { navList } = this.state;
- this.nacosLeftBarDom = document.getElementById('viewFramework-product-navbar');
- this.nacosBodyDom = document.getElementById('viewFramework-product-body');
- this.nacosToggleIconDom = document.getElementById('viewFramework-product-navbar-collapse');
- this.nacosOutDom = document.getElementById('page-header-mask');
- const defaultNav = '/configurationManagement';
- this.props.history.listen(location => {
- if (this.preSimplePath && this.preSimplePath !== '/') {
- if (location.pathname.indexOf(this.preSimplePath) !== -1) {
- return;
- }
- }
- const simplePath = window.location.hash.split('?')[0];
- const navName = simplePath.substr('2');
- this.preSimplePath = simplePath;
-
- if (navName === '') {
- this.props.history.push(defaultNav);
- setTimeout(() => {
- this.activeNav('configurationManagement');
- });
- return;
- }
-
- const nowNavObj = this.oneLevelNavArr[navName];
- if (!nowNavObj) {
- this.setState({
- noChild: true,
- });
- return;
- }
- const { parentServiceName } = nowNavObj;
-
- const parentNav = this.oneLevelNavArr[parentServiceName];
- if (simplePath !== '/' && nowNavObj && parentNav && !parentNav.isVirtual) {
- this.setState({
- showLink: (
-
-
-
- ),
-
- navRow: {this.nacosLoopNav([nowNavObj])} ,
- });
- setTimeout(() => {
- const navid = navName;
- this.activeNav(navid);
- });
- } else {
- this.setState({
- showLink: null,
- navRow: {this.nacosLoopNav(navList)} ,
- });
- setTimeout(() => {
- const navid = navName;
- this.activeNav(navid);
- });
- }
- });
- }
-
- refreshNav() {
- const { navList } = this.state;
- const { location, history, functionMode } = this.props;
- const [configUrl, serviceUrl, clusterUrl] = [
- '/configurationManagement',
- '/serviceManagement',
- '/clusterManagement',
- ];
- this.setState(
- {
- navList: navList.map(item => {
- if (
- item.serviceName === 'configurationManagementVirtual' &&
- (functionMode === null || functionMode === 'config')
- ) {
- item.enable = true;
- }
- if (
- item.serviceName === 'serviceManagementVirtual' &&
- (functionMode === null || functionMode === 'naming')
- ) {
- item.enable = true;
- }
- if (
- item.serviceName === 'clusterManagementVirtual' &&
- (functionMode === null || functionMode === 'cluster')
- ) {
- item.enable = true;
- }
- return item;
- }),
- },
- () => this.setState({ navRow: this.nacosGetNav(navList) }, () => this.renderNav())
- );
- if (functionMode === 'config' && location.pathname === serviceUrl) {
- history.push(configUrl);
- }
- if (functionMode === 'naming' && location.pathname === configUrl) {
- history.push(serviceUrl);
- }
- if (functionMode === 'cluster' && location.pathname === clusterUrl) {
- history.push(clusterUrl);
- }
- }
-
- componentWillReceiveProps() {
- setTimeout(() => this.refreshNav());
+ return !urls.includes(this.props.location.pathname);
}
render() {
- const { locale = {}, version } = this.props;
- const { nacosName, doesNotExist } = locale;
- const { showLink, navRow, leftBarClose, noChild } = this.state;
+ const { locale = {}, version, functionMode } = this.props;
+ const MenuData = getMenuData(functionMode);
return (
-