合并分支 'ProjectThird' 到 'master'
Project third 查看合并请求 JeroBoot/jero-boot!3
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
jero-boot 低代码开发平台
|
jero-boot 低代码开发平台
|
||||||
===============
|
===============
|
||||||
|
|
||||||
当前最新版本: 2.4.2(发布日期:20210126)
|
当前最新版本: 2.4.6(发布日期:20220405)
|
||||||
|
|
||||||
|
|
||||||
## 后端技术架构
|
## 后端技术架构
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|||||||
|
|
||||||
COPY ./tables_nacos.sql /docker-entrypoint-initdb.d
|
COPY ./tables_nacos.sql /docker-entrypoint-initdb.d
|
||||||
|
|
||||||
COPY jeroboot-mysql-5.7.sql /docker-entrypoint-initdb.d
|
COPY jeroboot-mysql-5.7-20220331.sql /docker-entrypoint-initdb.d
|
||||||
|
|
||||||
COPY ./tables_xxl_job.sql /docker-entrypoint-initdb.d
|
COPY ./tables_xxl_job.sql /docker-entrypoint-initdb.d
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,8 @@ CREATE TABLE "DEMO" (
|
|||||||
"CREATE_TIME" DATE NULL ,
|
"CREATE_TIME" DATE NULL ,
|
||||||
"UPDATE_BY" NVARCHAR2(32) NULL ,
|
"UPDATE_BY" NVARCHAR2(32) NULL ,
|
||||||
"UPDATE_TIME" DATE NULL ,
|
"UPDATE_TIME" DATE NULL ,
|
||||||
"SYS_ORG_CODE" NVARCHAR2(64) NULL
|
"SYS_ORG_CODE" NVARCHAR2(64) NULL ,
|
||||||
|
"TENANT_ID" NUMBER NULL
|
||||||
)
|
)
|
||||||
LOGGING
|
LOGGING
|
||||||
NOCOMPRESS
|
NOCOMPRESS
|
||||||
@@ -427,7 +428,8 @@ CREATE TABLE "ONL_AUTH_RELATION" (
|
|||||||
"ROLE_ID" NVARCHAR2(32) NULL ,
|
"ROLE_ID" NVARCHAR2(32) NULL ,
|
||||||
"AUTH_ID" NVARCHAR2(32) NULL ,
|
"AUTH_ID" NVARCHAR2(32) NULL ,
|
||||||
"TYPE" NUMBER(11) NULL ,
|
"TYPE" NUMBER(11) NULL ,
|
||||||
"CGFORM_ID" NVARCHAR2(32) NULL
|
"CGFORM_ID" NVARCHAR2(32) NULL,
|
||||||
|
"AUTH_MODE" NVARCHAR2(50) NULL
|
||||||
)
|
)
|
||||||
LOGGING
|
LOGGING
|
||||||
NOCOMPRESS
|
NOCOMPRESS
|
||||||
@@ -438,6 +440,7 @@ COMMENT ON COLUMN "ONL_AUTH_RELATION"."ROLE_ID" IS '角色id';
|
|||||||
COMMENT ON COLUMN "ONL_AUTH_RELATION"."AUTH_ID" IS '权限id';
|
COMMENT ON COLUMN "ONL_AUTH_RELATION"."AUTH_ID" IS '权限id';
|
||||||
COMMENT ON COLUMN "ONL_AUTH_RELATION"."TYPE" IS '1字段 2按钮 3数据权限';
|
COMMENT ON COLUMN "ONL_AUTH_RELATION"."TYPE" IS '1字段 2按钮 3数据权限';
|
||||||
COMMENT ON COLUMN "ONL_AUTH_RELATION"."CGFORM_ID" IS 'online表单ID';
|
COMMENT ON COLUMN "ONL_AUTH_RELATION"."CGFORM_ID" IS 'online表单ID';
|
||||||
|
COMMENT ON COLUMN "ONL_AUTH_RELATION"."AUTH_MODE" IS '授权方式role角色,depart部门,user人';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of ONL_AUTH_RELATION
|
-- Records of ONL_AUTH_RELATION
|
||||||
@@ -1057,8 +1060,6 @@ NOCACHE
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of QRTZ_CRON_TRIGGERS
|
-- Records of QRTZ_CRON_TRIGGERS
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO "QRTZ_CRON_TRIGGERS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleJob', 'DEFAULT', '0/1 * * * * ?', 'Asia/Shanghai');
|
|
||||||
INSERT INTO "QRTZ_CRON_TRIGGERS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleParamJob', 'DEFAULT', '0/1 * * * * ?', 'Asia/Shanghai');
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for QRTZ_FIRED_TRIGGERS
|
-- Table structure for QRTZ_FIRED_TRIGGERS
|
||||||
@@ -1114,8 +1115,6 @@ NOCACHE
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of QRTZ_JOB_DETAILS
|
-- Records of QRTZ_JOB_DETAILS
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO "QRTZ_JOB_DETAILS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleJob', 'DEFAULT', null, 'com.jero.modules.quartz.job.SampleJob', '0', '0', '0', '0', HexToRaw('30784143454430303035373337323030313536463732363732453731373536313732373437413245344136463632343436313734363134443631373039464230383345384246413942304342303230303030373837323030323636463732363732453731373536313732373437413245373537343639364337333245353337343732363936453637344236353739343436393732373437393436364336313637344436313730383230384538433346424335354432383032303030313541303031333631364336433646373737333534373236313645373336393635364537343434363137343631373837323030314436463732363732453731373536313732373437413245373537343639364337333245343436393732373437393436364336313637344436313730313345363245414432383736304143453032303030323541303030353634363937323734373934433030303336443631373037343030304634433641363137363631324637353734363936433246344436313730334237383730303137333732303031313641363137363631324537353734363936433245343836313733363834443631373030353037444143314333313636304431303330303032343630303041364336463631363434363631363337343646373234393030303937343638373236353733363836463643363437383730334634303030303030303030303030433737303830303030303031303030303030303031373430303039373036313732363136443635373436353732373037383030'));
|
|
||||||
INSERT INTO "QRTZ_JOB_DETAILS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleParamJob', 'DEFAULT', null, 'com.jero.modules.quartz.job.SampleParamJob', '0', '0', '0', '0', HexToRaw('307841434544303030353733373230303135364637323637324537313735363137323734374132453441364636323434363137343631344436313730394642303833453842464139423043423032303030303738373230303236364637323637324537313735363137323734374132453735373436393643373332453533373437323639364536373442363537393434363937323734373934363643363136373444363137303832303845384333464243353544323830323030303135413030313336313643364336463737373335343732363136453733363936353645373434343631373436313738373230303144364637323637324537313735363137323734374132453735373436393643373332453434363937323734373934363643363136373444363137303133453632454144323837363041434530323030303235413030303536343639373237343739344330303033364436313730373430303046344336413631373636313246373537343639364332463444363137303342373837303031373337323030313136413631373636313245373537343639364332453438363137333638344436313730303530374441433143333136363044313033303030323436303030413643364636313634343636313633373436463732343930303039373436383732363537333638364636433634373837303346343030303030303030303030304337373038303030303030313030303030303030313734303030393730363137323631364436353734363537323734303030353733363336463734373437383030'));
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for QRTZ_LOCKS
|
-- Table structure for QRTZ_LOCKS
|
||||||
@@ -1260,8 +1259,6 @@ NOCACHE
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of QRTZ_TRIGGERS
|
-- Records of QRTZ_TRIGGERS
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO "QRTZ_TRIGGERS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleJob', 'DEFAULT', 'com.jero.modules.quartz.job.SampleJob', 'DEFAULT', null, '1588405730000', '1588405729000', '5', 'PAUSED', 'CRON', '1588405237000', '0', null, '0', null);
|
|
||||||
INSERT INTO "QRTZ_TRIGGERS" VALUES ('MyScheduler', 'com.jero.modules.quartz.job.SampleParamJob', 'DEFAULT', 'com.jero.modules.quartz.job.SampleParamJob', 'DEFAULT', null, '1588405236000', '1588405235000', '5', 'PAUSED', 'CRON', '1588405221000', '0', null, '0', null);
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for SYS_ANNOUNCEMENT
|
-- Table structure for SYS_ANNOUNCEMENT
|
||||||
@@ -1735,6 +1732,7 @@ INSERT INTO "SYS_DICT" VALUES ('1209733563293962241', '数据库类型', 'databa
|
|||||||
INSERT INTO "SYS_DICT" VALUES ('1232913193820581889', 'Online表单业务分类', 'ol_form_biz_type', null, '0', 'admin', TO_DATE('2020-02-27 14:19:46', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2020-02-27 14:20:23', 'YYYY-MM-DD HH24:MI:SS'), '0');
|
INSERT INTO "SYS_DICT" VALUES ('1232913193820581889', 'Online表单业务分类', 'ol_form_biz_type', null, '0', 'admin', TO_DATE('2020-02-27 14:19:46', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2020-02-27 14:20:23', 'YYYY-MM-DD HH24:MI:SS'), '0');
|
||||||
INSERT INTO "SYS_DICT" VALUES ('1250687930947620866', '定时任务状态', 'quartz_status', null, '0', 'admin', TO_DATE('2020-04-16 15:30:14', 'YYYY-MM-DD HH24:MI:SS'), null, null, null);
|
INSERT INTO "SYS_DICT" VALUES ('1250687930947620866', '定时任务状态', 'quartz_status', null, '0', 'admin', TO_DATE('2020-04-16 15:30:14', 'YYYY-MM-DD HH24:MI:SS'), null, null, null);
|
||||||
INSERT INTO "SYS_DICT" VALUES ('1280401766745718786', '租户状态', 'tenant_status', '租户状态', '0', 'admin', TO_DATE('2020-07-07 15:22:25', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
INSERT INTO "SYS_DICT" VALUES ('1280401766745718786', '租户状态', 'tenant_status', '租户状态', '0', 'admin', TO_DATE('2020-07-07 15:22:25', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
||||||
|
INSERT INTO "SYS_DICT" VALUES ('1356445645198135298', '开关', 'is_open', '', '0', 'admin', TO_DATE('2021-02-02 11:33:38', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2021-02-02 15:28:12', 'YYYY-MM-DD HH24:MI:SS'), '0');
|
||||||
INSERT INTO "SYS_DICT" VALUES ('236e8a4baff0db8c62c00dd95632834f', '同步工作流引擎', 'activiti_sync', '同步工作流引擎', '0', 'admin', TO_DATE('2019-05-15 15:27:33', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
INSERT INTO "SYS_DICT" VALUES ('236e8a4baff0db8c62c00dd95632834f', '同步工作流引擎', 'activiti_sync', '同步工作流引擎', '0', 'admin', TO_DATE('2019-05-15 15:27:33', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
||||||
INSERT INTO "SYS_DICT" VALUES ('2e02df51611a4b9632828ab7e5338f00', '权限策略', 'perms_type', '权限策略', '0', 'admin', TO_DATE('2019-04-26 18:26:55', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
INSERT INTO "SYS_DICT" VALUES ('2e02df51611a4b9632828ab7e5338f00', '权限策略', 'perms_type', '权限策略', '0', 'admin', TO_DATE('2019-04-26 18:26:55', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0');
|
||||||
INSERT INTO "SYS_DICT" VALUES ('2f0320997ade5dd147c90130f7218c3e', '推送类别', 'msg_type', null, '0', 'admin', TO_DATE('2019-03-17 21:21:32', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2019-03-26 19:57:45', 'YYYY-MM-DD HH24:MI:SS'), '0');
|
INSERT INTO "SYS_DICT" VALUES ('2f0320997ade5dd147c90130f7218c3e', '推送类别', 'msg_type', null, '0', 'admin', TO_DATE('2019-03-17 21:21:32', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2019-03-26 19:57:45', 'YYYY-MM-DD HH24:MI:SS'), '0');
|
||||||
@@ -1873,7 +1871,8 @@ INSERT INTO "SYS_DICT_ITEM" VALUES ('f2a7920421f3335afdf6ad2b342f6b5d', '845da50
|
|||||||
INSERT INTO "SYS_DICT_ITEM" VALUES ('f37f90c496ec9841c4c326b065e00bb2', '83bfb33147013cc81640d5fd9eda030c', '登录日志', '1', null, null, '1', 'admin', TO_DATE('2019-03-18 23:22:37', 'YYYY-MM-DD HH24:MI:SS'), null, null);
|
INSERT INTO "SYS_DICT_ITEM" VALUES ('f37f90c496ec9841c4c326b065e00bb2', '83bfb33147013cc81640d5fd9eda030c', '登录日志', '1', null, null, '1', 'admin', TO_DATE('2019-03-18 23:22:37', 'YYYY-MM-DD HH24:MI:SS'), null, null);
|
||||||
INSERT INTO "SYS_DICT_ITEM" VALUES ('f80a8f6838215753b05e1a5ba3346d22', '880a895c98afeca9d9ac39f29e67c13e', '删除', '4', null, '4', '1', 'admin', TO_DATE('2019-07-22 10:55:14', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2019-07-22 10:55:30', 'YYYY-MM-DD HH24:MI:SS'));
|
INSERT INTO "SYS_DICT_ITEM" VALUES ('f80a8f6838215753b05e1a5ba3346d22', '880a895c98afeca9d9ac39f29e67c13e', '删除', '4', null, '4', '1', 'admin', TO_DATE('2019-07-22 10:55:14', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2019-07-22 10:55:30', 'YYYY-MM-DD HH24:MI:SS'));
|
||||||
INSERT INTO "SYS_DICT_ITEM" VALUES ('fe50b23ae5e68434def76f67cef35d2d', '78bda155fe380b1b3f175f1e88c284c6', '已作废', '4', '已作废', '4', '1', 'admin', TO_DATE('2021-09-09 16:33:43', 'YYYY-MM-DD HH24:MI:SS'), null, TO_DATE('2019-05-09 16:34:40', 'YYYY-MM-DD HH24:MI:SS'));
|
INSERT INTO "SYS_DICT_ITEM" VALUES ('fe50b23ae5e68434def76f67cef35d2d', '78bda155fe380b1b3f175f1e88c284c6', '已作废', '4', '已作废', '4', '1', 'admin', TO_DATE('2021-09-09 16:33:43', 'YYYY-MM-DD HH24:MI:SS'), null, TO_DATE('2019-05-09 16:34:40', 'YYYY-MM-DD HH24:MI:SS'));
|
||||||
|
INSERT INTO "SYS_DICT_ITEM" VALUES ('1356445705549975553', '1356445645198135298', '是', 'Y', '', '1', '1', 'admin', TO_DATE('2021-02-02 11:33:52', 'YYYY-MM-DD HH24:MI:SS'),, NULL, NULL);
|
||||||
|
INSERT INTO "SYS_DICT_ITEM" VALUES ('1356445754212290561', '1356445645198135298', '否', 'N', '', '1', '1', 'admin', TO_DATE('2021-02-02 11:34:04', 'YYYY-MM-DD HH24:MI:SS'),, NULL, NULL);
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for SYS_FILL_RULE
|
-- Table structure for SYS_FILL_RULE
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
@@ -2205,6 +2204,7 @@ INSERT INTO "SYS_PERMISSION" VALUES ('1383956678637334529', '3f915b2769fc80648e9
|
|||||||
INSERT INTO "SYS_PERMISSION" VALUES ('1383956779212550146', '3f915b2769fc80648e92d04e84ca059d', '用户导出', NULL, NULL, NULL, NULL, 2, 'sys:user:export', '1', 1.00, 0, NULL, 1, 1, 0, 0, NULL, 'admin', TO_DATE('2021-04-19 09:14:05', 'YYYY-MM-DD HH24:MI:SS'), NULL, NULL, 0, 0, '1', 0);
|
INSERT INTO "SYS_PERMISSION" VALUES ('1383956779212550146', '3f915b2769fc80648e92d04e84ca059d', '用户导出', NULL, NULL, NULL, NULL, 2, 'sys:user:export', '1', 1.00, 0, NULL, 1, 1, 0, 0, NULL, 'admin', TO_DATE('2021-04-19 09:14:05', 'YYYY-MM-DD HH24:MI:SS'), NULL, NULL, 0, 0, '1', 0);
|
||||||
INSERT INTO "SYS_PERMISSION" VALUES ('1260931366557696001', '3f915b2769fc80648e92d04e84ca059d', '表单性别可见', null, null, null, null, '2', 'user:sex', '1', '1', '0', null, '1', '1', '0', '0', null, 'admin', TO_DATE('2020-05-14 21:53:59', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2020-05-14 21:57:00', 'YYYY-MM-DD HH24:MI:SS'), '0', '0', '1', '0');
|
INSERT INTO "SYS_PERMISSION" VALUES ('1260931366557696001', '3f915b2769fc80648e92d04e84ca059d', '表单性别可见', null, null, null, null, '2', 'user:sex', '1', '1', '0', null, '1', '1', '0', '0', null, 'admin', TO_DATE('2020-05-14 21:53:59', 'YYYY-MM-DD HH24:MI:SS'), 'admin', TO_DATE('2020-05-14 21:57:00', 'YYYY-MM-DD HH24:MI:SS'), '0', '0', '1', '0');
|
||||||
INSERT INTO "SYS_PERMISSION" VALUES ('1260933542969458689', '3f915b2769fc80648e92d04e84ca059d', '禁用生日字段', null, null, null, null, '2', 'user:form:birthday', '2', '1', '0', null, '1', '1', '0', '0', null, 'admin', TO_DATE('2020-05-14 22:02:38', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0', '0', '1', '0');
|
INSERT INTO "SYS_PERMISSION" VALUES ('1260933542969458689', '3f915b2769fc80648e92d04e84ca059d', '禁用生日字段', null, null, null, null, '2', 'user:form:birthday', '2', '1', '0', null, '1', '1', '0', '0', null, 'admin', TO_DATE('2020-05-14 22:02:38', 'YYYY-MM-DD HH24:MI:SS'), null, null, '0', '0', '1', '0');
|
||||||
|
INSERT INTO "SYS_PERMISSION" VALUES ('1404684556047024130', '08e6b9dc3c04489c8e1ff2ce6f105aa4', '在线用户', '/isystem/online', 'system/SysUserOnlineList', NULL, NULL, 1, NULL, '1', NULL, 0, NULL, 1, 1, 0, 0, NULL, '1', 0, 0, 'admin', TO_DATE('2021-06-15 14:17:51', 'YYYY-MM-DD HH24:MI:SS'), NULL, NULL, 0);
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for SYS_PERMISSION_DATA_RULE
|
-- Table structure for SYS_PERMISSION_DATA_RULE
|
||||||
@@ -2664,7 +2664,8 @@ CREATE TABLE "SYS_THIRD_ACCOUNT" (
|
|||||||
"STATUS" NUMBER(4) NULL ,
|
"STATUS" NUMBER(4) NULL ,
|
||||||
"DEL_FLAG" NUMBER(4) NULL ,
|
"DEL_FLAG" NUMBER(4) NULL ,
|
||||||
"REALNAME" NVARCHAR2(100) NULL ,
|
"REALNAME" NVARCHAR2(100) NULL ,
|
||||||
"THIRD_USER_UUID" NVARCHAR2(100) NULL
|
"THIRD_USER_UUID" NVARCHAR2(100) NULL,
|
||||||
|
"THIRD_USER_ID" NVARCHAR2(100)
|
||||||
)
|
)
|
||||||
LOGGING
|
LOGGING
|
||||||
NOCOMPRESS
|
NOCOMPRESS
|
||||||
@@ -2679,6 +2680,7 @@ COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."STATUS" IS '状态(1-正常,2-冻结)';
|
|||||||
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."DEL_FLAG" IS '删除状态(0-正常,1-已删除)';
|
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."DEL_FLAG" IS '删除状态(0-正常,1-已删除)';
|
||||||
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."REALNAME" IS '真实姓名';
|
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."REALNAME" IS '真实姓名';
|
||||||
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."THIRD_USER_UUID" IS '第三方账号';
|
COMMENT ON COLUMN "SYS_THIRD_ACCOUNT"."THIRD_USER_UUID" IS '第三方账号';
|
||||||
|
COMMENT ON COLUMN "JEECGBOOT"."SYS_THIRD_ACCOUNT"."THIRD_USER_ID" IS '第三方app用户账号';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of SYS_THIRD_ACCOUNT
|
-- Records of SYS_THIRD_ACCOUNT
|
||||||
@@ -4030,14 +4032,6 @@ ALTER TABLE "SYS_PERMISSION_DATA_RULE" ADD CHECK ("ID" IS NOT NULL);
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
ALTER TABLE "SYS_PERMISSION_DATA_RULE" ADD PRIMARY KEY ("ID");
|
ALTER TABLE "SYS_PERMISSION_DATA_RULE" ADD PRIMARY KEY ("ID");
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Indexes structure for table SYS_QUARTZ_JOB
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE UNIQUE INDEX "UNIQ_JOB_CLASS_NAME"
|
|
||||||
ON "SYS_QUARTZ_JOB" ("JOB_CLASS_NAME" ASC)
|
|
||||||
LOGGING
|
|
||||||
VISIBLE;
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Checks structure for table SYS_QUARTZ_JOB
|
-- Checks structure for table SYS_QUARTZ_JOB
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ CREATE TABLE [dbo].[demo] (
|
|||||||
[create_time] datetime2(7) NULL,
|
[create_time] datetime2(7) NULL,
|
||||||
[update_by] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
[update_by] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
[update_time] datetime2(7) NULL,
|
[update_time] datetime2(7) NULL,
|
||||||
[sys_org_code] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
|
[sys_org_code] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
|
[tenant_id] int NULL
|
||||||
)
|
)
|
||||||
GO
|
GO
|
||||||
|
|
||||||
@@ -1193,7 +1194,8 @@ CREATE TABLE [dbo].[onl_auth_relation] (
|
|||||||
[role_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
[role_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
[auth_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
[auth_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
[type] int NULL,
|
[type] int NULL,
|
||||||
[cgform_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
|
[cgform_id] nvarchar(32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
|
[auth_mode] nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
|
||||||
)
|
)
|
||||||
GO
|
GO
|
||||||
|
|
||||||
@@ -1228,6 +1230,12 @@ EXEC sp_addextendedproperty
|
|||||||
'COLUMN', N'cgform_id'
|
'COLUMN', N'cgform_id'
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'授权方式role角色,depart部门,user人',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'onl_auth_relation',
|
||||||
|
'COLUMN', N'auth_mode'
|
||||||
|
GO
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of onl_auth_relation
|
-- Records of onl_auth_relation
|
||||||
@@ -4584,6 +4592,9 @@ GO
|
|||||||
INSERT INTO [dbo].[sys_dict] ([id], [dict_name], [dict_code], [description], [del_flag], [create_by], [create_time], [update_by], [update_time], [type]) VALUES (N'fc6cd58fde2e8481db10d3a1e68ce70c', N'用户状态', N'user_status', NULL, N'0', N'admin', N'2019-03-18 21:57:25.0000000', N'admin', N'2019-03-18 23:11:58.0000000', N'1')
|
INSERT INTO [dbo].[sys_dict] ([id], [dict_name], [dict_code], [description], [del_flag], [create_by], [create_time], [update_by], [update_time], [type]) VALUES (N'fc6cd58fde2e8481db10d3a1e68ce70c', N'用户状态', N'user_status', NULL, N'0', N'admin', N'2019-03-18 21:57:25.0000000', N'admin', N'2019-03-18 23:11:58.0000000', N'1')
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
INSERT INTO [dbo].[sys_dict] ([id], [dict_name], [dict_code], [description], [del_flag], [create_by], [create_time], [update_by], [update_time], [type]) VALUES (N'1356445645198135298', N'开关', N'is_open', N'', N'0', N'admin', N'2021-02-02 11:33:38.0000000', N'admin', N'2021-02-02 15:28:12.0000000', N'0')
|
||||||
|
GO
|
||||||
|
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for sys_dict_item
|
-- Table structure for sys_dict_item
|
||||||
@@ -4905,6 +4916,11 @@ GO
|
|||||||
INSERT INTO [dbo].[sys_dict_item] ([id], [dict_id], [item_text], [item_value], [description], [sort_order], [status], [create_by], [create_time], [update_by], [update_time]) VALUES (N'fe50b23ae5e68434def76f67cef35d2d', N'78bda155fe380b1b3f175f1e88c284c6', N'已作废', N'4', N'已作废', N'4', N'1', N'admin', N'2021-09-09 16:33:43.0000000', N'admin', N'2019-05-09 16:34:40.0000000')
|
INSERT INTO [dbo].[sys_dict_item] ([id], [dict_id], [item_text], [item_value], [description], [sort_order], [status], [create_by], [create_time], [update_by], [update_time]) VALUES (N'fe50b23ae5e68434def76f67cef35d2d', N'78bda155fe380b1b3f175f1e88c284c6', N'已作废', N'4', N'已作废', N'4', N'1', N'admin', N'2021-09-09 16:33:43.0000000', N'admin', N'2019-05-09 16:34:40.0000000')
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
INSERT INTO [dbo].[sys_dict_item] ([id], [dict_id], [item_text], [item_value], [description], [sort_order], [status], [create_by], [create_time], [update_by], [update_time]) VALUES (N'1356445705549975553', N'1356445645198135298', N'是', N'Y', N'', N'1', N'1', N'admin', N'2021-02-02 11:33:52.0000000', NULL, NULL)
|
||||||
|
GO
|
||||||
|
|
||||||
|
INSERT INTO [dbo].[sys_dict_item] ([id], [dict_id], [item_text], [item_value], [description], [sort_order], [status], [create_by], [create_time], [update_by], [update_time]) VALUES (N'1356445754212290561', N'1356445645198135298', N'否', N'N', N'', N'1', N'1', N'admin', N'2021-02-02 11:33:52.0000000', NULL, NULL)
|
||||||
|
GO
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for sys_fill_rule
|
-- Table structure for sys_fill_rule
|
||||||
@@ -5917,6 +5933,8 @@ GO
|
|||||||
INSERT INTO [dbo].[sys_permission] ([id], [parent_id], [name], [url], [component], [component_name], [redirect], [menu_type], [perms], [perms_type], [sort_no], [always_show], [icon], [is_route], [is_leaf], [keep_alive], [hidden], [description], [create_by], [create_time], [update_by], [update_time], [del_flag], [rule_flag], [status], [internal_or_external]) VALUES (N'1383957793466560514', N'ebb9d82ea16ad864071158e0c449d186', N'分类字典导出', NULL, NULL, NULL, NULL, N'2', N'sys:category:export', N'1', N'1.00', N'0', NULL, N'1', N'1', N'0', N'0', NULL, N'admin', N'2021-04-19 09:14:05', N'admin', N'2021-04-19 09:14:05', N'0', N'0', N'1', N'0');
|
INSERT INTO [dbo].[sys_permission] ([id], [parent_id], [name], [url], [component], [component_name], [redirect], [menu_type], [perms], [perms_type], [sort_no], [always_show], [icon], [is_route], [is_leaf], [keep_alive], [hidden], [description], [create_by], [create_time], [update_by], [update_time], [del_flag], [rule_flag], [status], [internal_or_external]) VALUES (N'1383957793466560514', N'ebb9d82ea16ad864071158e0c449d186', N'分类字典导出', NULL, NULL, NULL, NULL, N'2', N'sys:category:export', N'1', N'1.00', N'0', NULL, N'1', N'1', N'0', N'0', NULL, N'admin', N'2021-04-19 09:14:05', N'admin', N'2021-04-19 09:14:05', N'0', N'0', N'1', N'0');
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
INSERT INTO [dbo].[sys_permission] ([id], [parent_id], [name], [url], [component], [component_name], [redirect], [menu_type], [perms], [perms_type], [sort_no], [always_show], [icon], [is_route], [is_leaf], [keep_alive], [hidden], [description], [create_by], [create_time], [update_by], [update_time], [del_flag], [rule_flag], [status], [internal_or_external]) VALUES (N'1404684556047024130', N'08e6b9dc3c04489c8e1ff2ce6f105aa4', N'在线用户', N'/isystem/online', N'system/SysUserOnlineList', NULL, NULL, N'1', NULL, N'1', NULL, N'0', NULL, N'1', N'1', N'0', N'0', NULL, N'1', N'0', N'0', N'admin', N'2021-06-15 14:17:51', NULL, NULL, N'0');
|
||||||
|
GO
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for sys_permission_data_rule
|
-- Table structure for sys_permission_data_rule
|
||||||
@@ -7088,7 +7106,8 @@ CREATE TABLE [dbo].[sys_third_account] (
|
|||||||
[status] tinyint NULL,
|
[status] tinyint NULL,
|
||||||
[del_flag] tinyint NULL,
|
[del_flag] tinyint NULL,
|
||||||
[realname] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
[realname] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
[third_user_uuid] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
|
[third_user_uuid] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
|
||||||
|
[third_user_id] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
|
||||||
)
|
)
|
||||||
GO
|
GO
|
||||||
|
|
||||||
@@ -7151,6 +7170,12 @@ EXEC sp_addextendedproperty
|
|||||||
'COLUMN', N'third_user_uuid'
|
'COLUMN', N'third_user_uuid'
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'第三方app用户账号',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'sys_third_account',
|
||||||
|
'COLUMN', N'third_user_id'
|
||||||
|
GO
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of sys_third_account
|
-- Records of sys_third_account
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,28 +0,0 @@
|
|||||||
INSERT INTO SYS_DICT_ITEM(ID, DICT_ID, ITEM_TEXT, ITEM_VALUE, DESCRIPTION, SORT_ORDER, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME) VALUES ('1334440962954936321', '1209733563293962241', 'MYSQL5.7', '4', NULL, '1', '1', 'admin', '2020-12-03 18:16:02', 'admin', '2020-12-03 18:16:02');
|
|
||||||
UPDATE SYS_DICT_ITEM SET ITEM_TEXT = 'MySQL5.5' WHERE ID = '1209733775114702850';
|
|
||||||
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '3' WHERE ID = '1209733839933476865';
|
|
||||||
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '4' WHERE ID = '1209733903020003330';
|
|
||||||
|
|
||||||
ALTER TABLE `sys_gateway_route`
|
|
||||||
CHANGE COLUMN `persist` `persistable` int(3) NULL DEFAULT NULL COMMENT '是否为保留数据:0-否 1-是' AFTER `strip_prefix`;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `test_online_link`;
|
|
||||||
CREATE TABLE `test_online_link` (
|
|
||||||
`id` varchar(32) NOT NULL,
|
|
||||||
`pid` varchar(32) DEFAULT NULL COMMENT 'pid',
|
|
||||||
`name` varchar(255) DEFAULT NULL COMMENT 'name',
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
||||||
INSERT INTO `test_online_link` VALUES ('1', NULL, '中国');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('10', '8', '庐阳区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('11', '7', '黄山市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('2', '1', '山东省');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('3', '2', '济南市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('4', '3', '历城区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('5', '3', '长青区');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('6', '2', '青岛市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('7', '1', '安徽省');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('8', '7', '合肥市');
|
|
||||||
INSERT INTO `test_online_link` VALUES ('9', '8', '包河区');
|
|
||||||
|
|
||||||
update ONL_CGFORM_FIELD set DB_TYPE = 'Date' WHERE DB_TYPE = 'date';
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,10 +0,0 @@
|
|||||||
版本升级方法?
|
|
||||||
|
|
||||||
JeroBoot属于平台级产品,每次升级改动内容较多,目前做不到平滑升级。
|
|
||||||
|
|
||||||
这里给用户的升级建议是这样的:
|
|
||||||
1.代码升级 => 本地版本通过svn或者git做好主干,在分支上做业务开发,jeecg每次版本发布,可以手工覆盖主干的代码,对比代码进行提交;
|
|
||||||
2.数据库升级 => 针对数据库我们每次发布会提供增量升级SQL,可以通过增量SQL实现数据库的升级。
|
|
||||||
3.兼容问题 => 每次版本发布会针对不兼容地方标注说明,需要手工修改不兼容的代码。
|
|
||||||
|
|
||||||
注意: 升级sql目前只提供mysql版本,执行完脚步后,新菜单需要手工进行角色授权,刷新首页才会出现。
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>jero-boot-base-api</artifactId>
|
<artifactId>jero-boot-base-api</artifactId>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
+97
-10
@@ -9,12 +9,10 @@ import com.jero.common.system.api.factory.SysBaseAPIFallbackFactory;
|
|||||||
import com.jero.common.system.vo.*;
|
import com.jero.common.system.vo.*;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,6 +106,14 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||||||
@GetMapping("/sys/api/queryDictItemsByCode")
|
@GetMapping("/sys/api/queryDictItemsByCode")
|
||||||
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code);
|
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有效的数据字典项
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/queryEnableDictItemsByCode")
|
||||||
|
public List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code);
|
||||||
|
|
||||||
/** 11查询所有的父级字典,按照create_time排序 */
|
/** 11查询所有的父级字典,按照create_time排序 */
|
||||||
@GetMapping("/sys/api/queryAllDict")
|
@GetMapping("/sys/api/queryAllDict")
|
||||||
List<DictModel> queryAllDict();
|
List<DictModel> queryAllDict();
|
||||||
@@ -384,30 +390,31 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/sys/api/queryUsersByUsernames")
|
@GetMapping("/sys/api/queryUsersByUsernames")
|
||||||
List<JSONObject> queryUsersByUsernames(String usernames);
|
List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 37根据多个用户ID(逗号分隔),查询返回多个用户信息
|
* 37根据多个用户ID(逗号分隔),查询返回多个用户信息
|
||||||
* @param ids
|
* @param ids
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/sys/api/queryUsersByIds")
|
@RequestMapping("/sys/api/queryUsersByIds")
|
||||||
List<JSONObject> queryUsersByIds(String ids);
|
List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||||
* @param orgCodes
|
* @param orgCodes
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/sys/api/queryDepartsByOrgcodes")
|
@RequestMapping("/sys/api/queryDepartsByOrgcodes")
|
||||||
List<JSONObject> queryDepartsByOrgcodes(String orgCodes);
|
List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 39根据多个部门编码(逗号分隔),查询返回多个部门信息
|
* 39根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||||
* @param ids
|
* @param ids
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/sys/api/queryDepartsByOrgIds")
|
@GetMapping("/sys/api/queryDepartsByOrgIds")
|
||||||
List<JSONObject> queryDepartsByOrgIds(String ids);
|
List<JSONObject> queryDepartsByOrgIds(@RequestParam("ids") String ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 40发送邮件消息
|
* 40发送邮件消息
|
||||||
@@ -438,7 +445,87 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||||||
@GetMapping("/sys/api/listSonDepartsByDepId")
|
@GetMapping("/sys/api/listSonDepartsByDepId")
|
||||||
List<SysDepartTreeModel> listSonDepartsByDepId(@RequestParam("departId") String departId);
|
List<SysDepartTreeModel> listSonDepartsByDepId(@RequestParam("departId") String departId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 41 获取公司下级部门和公司下所有用户id
|
||||||
|
* @param orgCode
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/getDeptUserByOrgCode")
|
||||||
|
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 42 查询分类字典翻译
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/loadCategoryDictItem")
|
||||||
|
List<String> loadCategoryDictItem(@RequestParam("ids") String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 43 根据字典code加载字典text
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param keys 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/loadDictItem")
|
||||||
|
List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 44 根据字典code查询字典项
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param dictCode 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/getDictItems")
|
||||||
|
List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 45 根据多个字典code查询多个字典项
|
||||||
|
*
|
||||||
|
* @param dictCodeList
|
||||||
|
* @return key = dictCode ; value=对应的字典项
|
||||||
|
*/
|
||||||
|
@RequestMapping("/sys/api/getManyDictItems")
|
||||||
|
Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 46 【JSearchSelectTag下拉搜索组件专用接口】
|
||||||
|
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||||
|
*
|
||||||
|
* @param dictCode 字典code格式:table,text,code
|
||||||
|
* @param keyword 过滤关键字
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/loadDictItemByKeyword")
|
||||||
|
List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 47 根据多个部门id(逗号分隔),查询返回多个部门信息
|
||||||
|
* @param ids
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/sys/api/queryDepartsByIds")
|
||||||
|
List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||||
|
* @param dictCodes
|
||||||
|
* @param keys
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@GetMapping("/sys/api/translateManyDict")
|
||||||
|
Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 49 字典表的 翻译,可批量
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param keys 多个用逗号分割
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@GetMapping("/sys/api/translateDictFromTableByKeys")
|
||||||
|
List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+52
@@ -9,6 +9,7 @@ import com.jero.common.system.api.ISysBaseAPI;
|
|||||||
import com.jero.common.system.vo.*;
|
import com.jero.common.system.vo.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,6 +72,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> queryEnableDictItemsByCode(String code) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DictModel> queryAllDict() {
|
public List<DictModel> queryAllDict() {
|
||||||
return null;
|
return null;
|
||||||
@@ -254,6 +260,22 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||||||
public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
|
public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<JSONObject> queryDepartsByIds(String ids) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendEmailMsg(String email,String title,String content) {
|
public void sendEmailMsg(String email,String title,String content) {
|
||||||
|
|
||||||
@@ -269,8 +291,38 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map> getDeptUserByOrgCode(String orgCode) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<JSONObject> queryDepartsByOrgIds(String ids) {
|
public List<JSONObject> queryDepartsByOrgIds(String ids) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> loadCategoryDictItem(String ids) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> loadDictItem(String dictCode, String keys) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> getDictItems(String dictCode) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<DictModel>> getManyDictItems(List<String> dictCodeList) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+100
-10
@@ -1,25 +1,48 @@
|
|||||||
package com.jero.config;
|
package com.jero.config;
|
||||||
|
|
||||||
import feign.Feign;
|
import java.io.IOException;
|
||||||
import feign.Logger;
|
import java.util.ArrayList;
|
||||||
import feign.RequestInterceptor;
|
import java.util.Arrays;
|
||||||
import feign.codec.Encoder;
|
import java.util.List;
|
||||||
import feign.form.spring.SpringFormEncoder;
|
import java.util.SortedMap;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import com.jero.common.constant.CommonConstant;
|
import com.jero.common.constant.CommonConstant;
|
||||||
|
import com.jero.common.util.DateUtils;
|
||||||
|
import com.jero.common.util.PathMatcherUtil;
|
||||||
|
import com.jero.common.config.mqtoken.UserTokenContext;
|
||||||
|
import com.jero.config.sign.interceptor.SignAuthConfiguration;
|
||||||
|
import com.jero.config.sign.util.HttpUtils;
|
||||||
|
import com.jero.config.sign.util.SignUtil;
|
||||||
import org.springframework.beans.factory.ObjectFactory;
|
import org.springframework.beans.factory.ObjectFactory;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||||
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
||||||
|
import org.springframework.cloud.openfeign.support.SpringDecoder;
|
||||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
|
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||||
|
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||||
|
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
|
||||||
|
|
||||||
|
import feign.Feign;
|
||||||
|
import feign.Logger;
|
||||||
|
import feign.RequestInterceptor;
|
||||||
|
import feign.codec.Decoder;
|
||||||
|
import feign.codec.Encoder;
|
||||||
|
import feign.form.spring.SpringFormEncoder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
@ConditionalOnClass(Feign.class)
|
@ConditionalOnClass(Feign.class)
|
||||||
@@ -34,13 +57,42 @@ public class FeignConfig {
|
|||||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
if (null != attributes) {
|
if (null != attributes) {
|
||||||
HttpServletRequest request = attributes.getRequest();
|
HttpServletRequest request = attributes.getRequest();
|
||||||
log.info("Feign request: {}", request.getRequestURI());
|
log.debug("Feign request: {}", request.getRequestURI());
|
||||||
// 将token信息放入header中
|
// 将token信息放入header中
|
||||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
if(token==null){
|
if(token==null || "".equals(token)){
|
||||||
token = request.getParameter("token");
|
token = request.getParameter("token");
|
||||||
}
|
}
|
||||||
log.info("Feign request token: {}", token);
|
log.debug("Feign request token: {}", token);
|
||||||
|
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
|
||||||
|
|
||||||
|
//根据URL地址过滤请求 【字典表参数签名验证】
|
||||||
|
if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.urlList),requestTemplate.path())) {
|
||||||
|
try {
|
||||||
|
log.info("============================ [begin] fegin api url ============================");
|
||||||
|
log.info(requestTemplate.path());
|
||||||
|
log.info(requestTemplate.method());
|
||||||
|
String queryLine = requestTemplate.queryLine();
|
||||||
|
if(queryLine!=null && queryLine.startsWith("?")){
|
||||||
|
queryLine = queryLine.substring(1);
|
||||||
|
}
|
||||||
|
log.info(queryLine);
|
||||||
|
if(requestTemplate.body()!=null){
|
||||||
|
log.info(new String(requestTemplate.body()));
|
||||||
|
}
|
||||||
|
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method());
|
||||||
|
String sign = SignUtil.getParamsSign(allParams);
|
||||||
|
log.info(" Feign request params sign: {}",sign);
|
||||||
|
log.info("============================ [end] fegin api url ============================");
|
||||||
|
requestTemplate.header(CommonConstant.X_SIGN, sign);
|
||||||
|
requestTemplate.header(CommonConstant.X_TIMESTAMP, DateUtils.getCurrentTimestamp().toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
String token = UserTokenContext.getToken();
|
||||||
|
log.debug("Feign request token: {}", token);
|
||||||
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
|
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -72,4 +124,42 @@ public class FeignConfig {
|
|||||||
public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||||
return new SpringFormEncoder(new SpringEncoder(messageConverters));
|
return new SpringFormEncoder(new SpringEncoder(messageConverters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update-begin--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
|
||||||
|
@Bean
|
||||||
|
public Encoder feignEncoder() {
|
||||||
|
return new SpringEncoder(feignHttpMessageConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Decoder feignDecoder() {
|
||||||
|
return new SpringDecoder(feignHttpMessageConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置解码器为fastjson
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
|
||||||
|
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
|
||||||
|
return () -> httpMessageConverters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FastJsonHttpMessageConverter getFastJsonConverter() {
|
||||||
|
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
|
||||||
|
|
||||||
|
List<MediaType> supportedMediaTypes = new ArrayList<>();
|
||||||
|
MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
supportedMediaTypes.add(mediaTypeJson);
|
||||||
|
converter.setSupportedMediaTypes(supportedMediaTypes);
|
||||||
|
FastJsonConfig config = new FastJsonConfig();
|
||||||
|
config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
|
||||||
|
config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
|
||||||
|
converter.setFastJsonConfig(config);
|
||||||
|
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
// update-end--Author:sunjianlei Date:20210604 for: 给 Feign 添加 FastJson 的解析支持 ----------
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>jero-boot-base-api</artifactId>
|
<artifactId>jero-boot-base-api</artifactId>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
+48
@@ -7,6 +7,7 @@ import com.jero.common.api.dto.message.*;
|
|||||||
import com.jero.common.system.vo.*;
|
import com.jero.common.system.vo.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -299,4 +300,51 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||||||
*/
|
*/
|
||||||
List<SysDepartTreeModel> listSonDepartsByDepId(String departId);
|
List<SysDepartTreeModel> listSonDepartsByDepId(String departId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 43 获取公司下级部门和公司下所有用户信息
|
||||||
|
* @param orgCode
|
||||||
|
*/
|
||||||
|
List<Map> getDeptUserByOrgCode(String orgCode);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询分类字典翻译
|
||||||
|
*/
|
||||||
|
List<String> loadCategoryDictItem(String ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典code加载字典text
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param keys 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> loadDictItem(String dictCode, String keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典code查询字典项
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param dictCode 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> getDictItems(String dictCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据多个字典code查询多个字典项
|
||||||
|
* @param dictCodeList
|
||||||
|
* @return key = dictCode ; value=对应的字典项
|
||||||
|
*/
|
||||||
|
Map<String, List<DictModel>> getManyDictItems(List<String> dictCodeList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【JSearchSelectTag下拉搜索组件专用接口】
|
||||||
|
* 大数据量的字典表 走异步加载 即前端输入内容过滤数据
|
||||||
|
*
|
||||||
|
* @param dictCode 字典code格式:table,text,code
|
||||||
|
* @param keyword 过滤关键字
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>jero-boot-base</artifactId>
|
<artifactId>jero-boot-base</artifactId>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-boot-base</artifactId>
|
<artifactId>jero-boot-base</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<repository>
|
<repository>
|
||||||
<id>aliyun</id>
|
<id>aliyun</id>
|
||||||
<name>aliyun Repository</name>
|
<name>aliyun Repository</name>
|
||||||
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<repository>
|
<repository>
|
||||||
<id>jeecg</id>
|
<id>jeecg</id>
|
||||||
<name>jeecg Repository</name>
|
<name>jeecg Repository</name>
|
||||||
<url>http://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
@@ -108,6 +108,7 @@
|
|||||||
<version>${dynamic-datasource-spring-boot-starter.version}</version>
|
<version>${dynamic-datasource-spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 数据库驱动 -->
|
||||||
<!--mysql-->
|
<!--mysql-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
@@ -156,16 +157,6 @@
|
|||||||
<artifactId>shiro-spring-boot-starter</artifactId>
|
<artifactId>shiro-spring-boot-starter</artifactId>
|
||||||
<version>${shiro.version}</version>
|
<version>${shiro.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate</groupId>
|
|
||||||
<artifactId>hibernate-core</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-collections</groupId>
|
|
||||||
<artifactId>commons-collections</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<!-- shiro-redis -->
|
<!-- shiro-redis -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.crazycake</groupId>
|
<groupId>org.crazycake</groupId>
|
||||||
@@ -186,16 +177,6 @@
|
|||||||
<version>${knife4j-spring-boot-starter.version}</version>
|
<version>${knife4j-spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Redis -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-pool2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- AutoPoi Excel工具类-->
|
<!-- AutoPoi Excel工具类-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework</groupId>
|
<groupId>org.jeecgframework</groupId>
|
||||||
|
|||||||
+25
@@ -3,6 +3,7 @@ package com.jero.common.api;
|
|||||||
import com.jero.common.system.vo.*;
|
import com.jero.common.system.vo.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface CommonAPI {
|
public interface CommonAPI {
|
||||||
@@ -85,6 +86,13 @@ public interface CommonAPI {
|
|||||||
*/
|
*/
|
||||||
public List<DictModel> queryDictItemsByCode(String code);
|
public List<DictModel> queryDictItemsByCode(String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有效的数据字典项
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<DictModel> queryEnableDictItemsByCode(String code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 13获取表数据字典
|
* 13获取表数据字典
|
||||||
* @param table
|
* @param table
|
||||||
@@ -94,4 +102,21 @@ public interface CommonAPI {
|
|||||||
*/
|
*/
|
||||||
List<DictModel> queryTableDictItemsByCode(String table, String text, String code);
|
List<DictModel> queryTableDictItemsByCode(String table, String text, String code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||||
|
* @param dictCodes 例如:user_status,sex
|
||||||
|
* @param keys 例如:1,2,0
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 15 字典表的 翻译,可批量
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param keys 多个用逗号分割
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -111,7 +111,16 @@ public class Result<T> implements Serializable {
|
|||||||
r.setResult(data);
|
r.setResult(data);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static<T> Result<T> error(String msg, T data) {
|
||||||
|
Result<T> r = new Result<T>();
|
||||||
|
r.setSuccess(false);
|
||||||
|
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
|
||||||
|
r.setMessage(msg);
|
||||||
|
r.setResult(data);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
public static Result<Object> error(String msg) {
|
public static Result<Object> error(String msg) {
|
||||||
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
|
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@ import com.jero.common.util.SpringContextUtils;
|
|||||||
import com.jero.common.util.oConvertUtils;
|
import com.jero.common.util.oConvertUtils;
|
||||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
@@ -156,7 +157,7 @@ public class AutoLogAspect {
|
|||||||
// https://my.oschina.net/mengzhang6/blog/2395893
|
// https://my.oschina.net/mengzhang6/blog/2395893
|
||||||
Object[] arguments = new Object[paramsArray.length];
|
Object[] arguments = new Object[paramsArray.length];
|
||||||
for (int i = 0; i < paramsArray.length; i++) {
|
for (int i = 0; i < paramsArray.length; i++) {
|
||||||
if (paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
|
if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
|
||||||
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
|
//ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
|
||||||
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
|
//ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+248
-21
@@ -1,5 +1,6 @@
|
|||||||
package com.jero.common.aspect;
|
package com.jero.common.aspect;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
@@ -14,16 +15,20 @@ import com.jero.common.api.CommonAPI;
|
|||||||
import com.jero.common.api.vo.Result;
|
import com.jero.common.api.vo.Result;
|
||||||
import com.jero.common.aspect.annotation.Dict;
|
import com.jero.common.aspect.annotation.Dict;
|
||||||
import com.jero.common.constant.CommonConstant;
|
import com.jero.common.constant.CommonConstant;
|
||||||
import com.jero.modules.base.service.BaseCommonService;
|
import com.jero.common.system.vo.DictModel;
|
||||||
import com.jero.common.util.oConvertUtils;
|
import com.jero.common.util.oConvertUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 字典aop类
|
* @Description: 字典aop类
|
||||||
@@ -38,6 +43,8 @@ public class DictAspect {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CommonAPI commonAPI;
|
private CommonAPI commonAPI;
|
||||||
|
@Autowired
|
||||||
|
public RedisTemplate redisTemplate;
|
||||||
|
|
||||||
// 定义切点Pointcut
|
// 定义切点Pointcut
|
||||||
@Pointcut("execution(public * com.jero.modules..*.*Controller.*(..))")
|
@Pointcut("execution(public * com.jero.modules..*.*Controller.*(..))")
|
||||||
@@ -46,14 +53,14 @@ public class DictAspect {
|
|||||||
|
|
||||||
@Around("excudeService()")
|
@Around("excudeService()")
|
||||||
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||||
long time1=System.currentTimeMillis();
|
long time1=System.currentTimeMillis();
|
||||||
Object result = pjp.proceed();
|
Object result = pjp.proceed();
|
||||||
long time2=System.currentTimeMillis();
|
long time2=System.currentTimeMillis();
|
||||||
log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
|
log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
|
||||||
long start=System.currentTimeMillis();
|
long start=System.currentTimeMillis();
|
||||||
this.parseDictText(result);
|
this.parseDictText(result);
|
||||||
long end=System.currentTimeMillis();
|
long end=System.currentTimeMillis();
|
||||||
log.debug("解析注入JSON数据 耗时"+(end-start)+"ms");
|
log.debug("注入字典到JSON数据 耗时"+(end-start)+"ms");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,32 +90,46 @@ public class DictAspect {
|
|||||||
if (result instanceof Result) {
|
if (result instanceof Result) {
|
||||||
if (((Result) result).getResult() instanceof IPage) {
|
if (((Result) result).getResult() instanceof IPage) {
|
||||||
List<JSONObject> items = new ArrayList<>();
|
List<JSONObject> items = new ArrayList<>();
|
||||||
|
|
||||||
|
//step.1 筛选出加了 Dict 注解的字段列表
|
||||||
|
List<Field> dictFieldList = new ArrayList<>();
|
||||||
|
// 字典数据列表, key = 字典code,value=数据列表
|
||||||
|
Map<String, List<String>> dataListMap = new HashMap<>();
|
||||||
|
|
||||||
for (Object record : ((IPage) ((Result) result).getResult()).getRecords()) {
|
for (Object record : ((IPage) ((Result) result).getResult()).getRecords()) {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
String json="{}";
|
String json="{}";
|
||||||
try {
|
try {
|
||||||
//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
|
//解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
|
||||||
json = mapper.writeValueAsString(record);
|
json = mapper.writeValueAsString(record);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
log.error("json解析失败"+e.getMessage(),e);
|
log.error("json解析失败"+e.getMessage(),e);
|
||||||
}
|
}
|
||||||
JSONObject item = JSONObject.parseObject(json);
|
JSONObject item = JSONObject.parseObject(json);
|
||||||
//update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
//update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
||||||
//for (Field field : record.getClass().getDeclaredFields()) {
|
//for (Field field : record.getClass().getDeclaredFields()) {
|
||||||
|
// 遍历所有字段,把字典Code取出来,放到 map 里
|
||||||
for (Field field : oConvertUtils.getAllFields(record)) {
|
for (Field field : oConvertUtils.getAllFields(record)) {
|
||||||
//update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
String value = item.getString(field.getName());
|
||||||
|
if (oConvertUtils.isEmpty(value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
|
||||||
if (field.getAnnotation(Dict.class) != null) {
|
if (field.getAnnotation(Dict.class) != null) {
|
||||||
|
if (!dictFieldList.contains(field)) {
|
||||||
|
dictFieldList.add(field);
|
||||||
|
}
|
||||||
String code = field.getAnnotation(Dict.class).dicCode();
|
String code = field.getAnnotation(Dict.class).dicCode();
|
||||||
String text = field.getAnnotation(Dict.class).dicText();
|
String text = field.getAnnotation(Dict.class).dicText();
|
||||||
String table = field.getAnnotation(Dict.class).dictTable();
|
String table = field.getAnnotation(Dict.class).dictTable();
|
||||||
String key = String.valueOf(item.get(field.getName()));
|
|
||||||
|
|
||||||
//翻译字典值对应的txt
|
List<String> dataList;
|
||||||
String textValue = translateDictValue(code, text, table, key);
|
String dictCode = code;
|
||||||
|
if (!StringUtils.isEmpty(table)) {
|
||||||
log.debug(" 字典Val : "+ textValue);
|
dictCode = String.format("%s,%s,%s", table, text, code);
|
||||||
log.debug(" __翻译字典字段__ "+field.getName() + CommonConstant.DICT_TEXT_SUFFIX+": "+ textValue);
|
}
|
||||||
item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
|
dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||||
|
this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(",")));
|
||||||
}
|
}
|
||||||
//date类型默认转换string格式化日期
|
//date类型默认转换string格式化日期
|
||||||
if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
|
if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
|
||||||
@@ -118,12 +139,195 @@ public class DictAspect {
|
|||||||
}
|
}
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//step.2 调用翻译方法,一次性翻译
|
||||||
|
Map<String, List<DictModel>> translText = this.translateAllDict(dataListMap);
|
||||||
|
|
||||||
|
//step.3 将翻译结果填充到返回结果里
|
||||||
|
for (JSONObject record : items) {
|
||||||
|
for (Field field : dictFieldList) {
|
||||||
|
String code = field.getAnnotation(Dict.class).dicCode();
|
||||||
|
String text = field.getAnnotation(Dict.class).dicText();
|
||||||
|
String table = field.getAnnotation(Dict.class).dictTable();
|
||||||
|
|
||||||
|
String fieldDictCode = code;
|
||||||
|
if (!StringUtils.isEmpty(table)) {
|
||||||
|
fieldDictCode = String.format("%s,%s,%s", table, text, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = record.getString(field.getName());
|
||||||
|
if (oConvertUtils.isNotEmpty(value)) {
|
||||||
|
List<DictModel> dictModels = translText.get(fieldDictCode);
|
||||||
|
if(dictModels==null || dictModels.size()==0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String textValue = this.translDictText(dictModels, value);
|
||||||
|
log.debug(" 字典Val : " + textValue);
|
||||||
|
log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue);
|
||||||
|
|
||||||
|
// TODO-sun 测试输出,待删
|
||||||
|
log.debug(" ---- dictCode: " + fieldDictCode);
|
||||||
|
log.debug(" ---- value: " + value);
|
||||||
|
log.debug(" ----- text: " + textValue);
|
||||||
|
log.debug(" ---- dictModels: " + JSON.toJSONString(dictModels));
|
||||||
|
|
||||||
|
record.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
((IPage) ((Result) result).getResult()).setRecords(items);
|
((IPage) ((Result) result).getResult()).setRecords(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list 去重添加
|
||||||
|
*/
|
||||||
|
private void listAddAllDeduplicate(List<String> dataList, List<String> addList) {
|
||||||
|
// 筛选出dataList中没有的数据
|
||||||
|
List<String> filterList = addList.stream().filter(i -> !dataList.contains(i)).collect(Collectors.toList());
|
||||||
|
dataList.addAll(filterList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一次性把所有的字典都翻译了
|
||||||
|
* 1. 所有的普通数据字典的所有数据只执行一次SQL
|
||||||
|
* 2. 表字典相同的所有数据只执行一次SQL
|
||||||
|
* @param dataListMap
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Map<String, List<DictModel>> translateAllDict(Map<String, List<String>> dataListMap) {
|
||||||
|
// 翻译后的字典文本,key=dictCode
|
||||||
|
Map<String, List<DictModel>> translText = new HashMap<>();
|
||||||
|
// 需要翻译的数据(有些可以从redis缓存中获取,就不走数据库查询)
|
||||||
|
List<String> needTranslData = new ArrayList<>();
|
||||||
|
//step.1 先通过redis中获取缓存字典数据
|
||||||
|
for (String dictCode : dataListMap.keySet()) {
|
||||||
|
List<String> dataList = dataListMap.get(dictCode);
|
||||||
|
if (dataList.size() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 表字典需要翻译的数据
|
||||||
|
List<String> needTranslDataTable = new ArrayList<>();
|
||||||
|
for (String s : dataList) {
|
||||||
|
String data = s.trim();
|
||||||
|
if (data.length() == 0) {
|
||||||
|
continue; //跳过循环
|
||||||
|
}
|
||||||
|
if (dictCode.contains(",")) {
|
||||||
|
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, data);
|
||||||
|
if (redisTemplate.hasKey(keyString)) {
|
||||||
|
try {
|
||||||
|
String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||||
|
list.add(new DictModel(data, text));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
} else if (!needTranslDataTable.contains(data)) {
|
||||||
|
// 去重添加
|
||||||
|
needTranslDataTable.add(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String keyString = String.format("sys:cache:dict::%s:%s", dictCode, data);
|
||||||
|
if (redisTemplate.hasKey(keyString)) {
|
||||||
|
try {
|
||||||
|
String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||||
|
list.add(new DictModel(data, text));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
} else if (!needTranslData.contains(data)) {
|
||||||
|
// 去重添加
|
||||||
|
needTranslData.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//step.2 调用数据库翻译表字典
|
||||||
|
if (needTranslDataTable.size() > 0) {
|
||||||
|
String[] arr = dictCode.split(",");
|
||||||
|
String table = arr[0], text = arr[1], code = arr[2];
|
||||||
|
String values = String.join(",", needTranslDataTable);
|
||||||
|
log.info("translateDictFromTableByKeys.dictCode:" + dictCode);
|
||||||
|
log.info("translateDictFromTableByKeys.values:" + values);
|
||||||
|
List<DictModel> texts = commonAPI.translateDictFromTableByKeys(table, text, code, values);
|
||||||
|
log.info("translateDictFromTableByKeys.result:" + texts);
|
||||||
|
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||||
|
list.addAll(texts);
|
||||||
|
|
||||||
|
// 做 redis 缓存
|
||||||
|
for (DictModel dict : texts) {
|
||||||
|
String redisKey = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, dict.getValue());
|
||||||
|
try {
|
||||||
|
// 保留10分钟
|
||||||
|
redisTemplate.opsForValue().set(redisKey, dict.getText(), 600, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//step.3 调用数据库进行翻译普通字典
|
||||||
|
if (needTranslData.size() > 0) {
|
||||||
|
List<String> dictCodeList = Arrays.asList(dataListMap.keySet().toArray(new String[]{}));
|
||||||
|
// 将不包含逗号的字典code筛选出来,因为带逗号的是表字典,而不是普通的数据字典
|
||||||
|
List<String> filterDictCodes = dictCodeList.stream().filter(key -> !key.contains(",")).collect(Collectors.toList());
|
||||||
|
String dictCodes = String.join(",", filterDictCodes);
|
||||||
|
String values = String.join(",", needTranslData);
|
||||||
|
log.info("translateManyDict.dictCodes:" + dictCodes);
|
||||||
|
log.info("translateManyDict.values:" + values);
|
||||||
|
Map<String, List<DictModel>> manyDict = commonAPI.translateManyDict(dictCodes, values);
|
||||||
|
log.info("translateManyDict.result:" + manyDict);
|
||||||
|
for (String dictCode : manyDict.keySet()) {
|
||||||
|
List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
|
||||||
|
List<DictModel> newList = manyDict.get(dictCode);
|
||||||
|
list.addAll(newList);
|
||||||
|
|
||||||
|
// 做 redis 缓存
|
||||||
|
for (DictModel dict : newList) {
|
||||||
|
String redisKey = String.format("sys:cache:dict::%s:%s", dictCode, dict.getValue());
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForValue().set(redisKey, dict.getText());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return translText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典值替换文本
|
||||||
|
*
|
||||||
|
* @param dictModels
|
||||||
|
* @param values
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String translDictText(List<DictModel> dictModels, String values) {
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
|
||||||
|
// 允许多个逗号分隔,允许传数组对象
|
||||||
|
String[] splitVal = values.split(",");
|
||||||
|
for (String val : splitVal) {
|
||||||
|
String dictText = val;
|
||||||
|
for (DictModel dict : dictModels) {
|
||||||
|
if (val.equals(dict.getValue())) {
|
||||||
|
dictText = dict.getText();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.add(dictText);
|
||||||
|
}
|
||||||
|
return String.join(",", result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 翻译字典文本
|
* 翻译字典文本
|
||||||
* @param code
|
* @param code
|
||||||
@@ -132,10 +336,11 @@ public class DictAspect {
|
|||||||
* @param key
|
* @param key
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
private String translateDictValue(String code, String text, String table, String key) {
|
private String translateDictValue(String code, String text, String table, String key) {
|
||||||
if(oConvertUtils.isEmpty(key)) {
|
if(oConvertUtils.isEmpty(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuffer textValue=new StringBuffer();
|
StringBuffer textValue=new StringBuffer();
|
||||||
String[] keys = key.split(",");
|
String[] keys = key.split(",");
|
||||||
for (String k : keys) {
|
for (String k : keys) {
|
||||||
@@ -144,12 +349,33 @@ public class DictAspect {
|
|||||||
if (k.trim().length() == 0) {
|
if (k.trim().length() == 0) {
|
||||||
continue; //跳过循环
|
continue; //跳过循环
|
||||||
}
|
}
|
||||||
|
//update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
||||||
if (!StringUtils.isEmpty(table)){
|
if (!StringUtils.isEmpty(table)){
|
||||||
log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
|
log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
|
||||||
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
|
String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
|
||||||
|
if (redisTemplate.hasKey(keyString)){
|
||||||
|
try {
|
||||||
|
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
tmpValue = commonAPI.translateDict(code, k.trim());
|
String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim());
|
||||||
|
if (redisTemplate.hasKey(keyString)){
|
||||||
|
try {
|
||||||
|
tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn(e.getMessage());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
tmpValue = commonAPI.translateDict(code, k.trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
|
||||||
|
|
||||||
if (tmpValue != null) {
|
if (tmpValue != null) {
|
||||||
if (!"".equals(textValue.toString())) {
|
if (!"".equals(textValue.toString())) {
|
||||||
textValue.append(",");
|
textValue.append(",");
|
||||||
@@ -162,3 +388,4 @@ public class DictAspect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ public class PermissionDataAspect {
|
|||||||
String url = "";
|
String url = "";
|
||||||
if(oConvertUtils.isNotEmpty(requestPath)){
|
if(oConvertUtils.isNotEmpty(requestPath)){
|
||||||
url = requestPath.replace("\\", "/");
|
url = requestPath.replace("\\", "/");
|
||||||
url = requestPath.replace("//", "/");
|
url = url.replace("//", "/");
|
||||||
if(url.indexOf("//")>=0){
|
if(url.indexOf("//")>=0){
|
||||||
url = filterUrl(url);
|
url = filterUrl(url);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -223,6 +223,8 @@ public interface CommonConstant {
|
|||||||
public static final Integer USER_IDENTITY_1 = 1;
|
public static final Integer USER_IDENTITY_1 = 1;
|
||||||
public static final Integer USER_IDENTITY_2 = 2;
|
public static final Integer USER_IDENTITY_2 = 2;
|
||||||
|
|
||||||
|
/** sys_user 表 username 唯一键索引 */
|
||||||
|
public static final String SQL_INDEX_INDEX_USER_NAME = "index_user_name";
|
||||||
/** sys_user 表 username 唯一键索引 */
|
/** sys_user 表 username 唯一键索引 */
|
||||||
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
||||||
/** sys_user 表 work_no 唯一键索引 */
|
/** sys_user 表 work_no 唯一键索引 */
|
||||||
@@ -265,7 +267,7 @@ public interface CommonConstant {
|
|||||||
/**
|
/**
|
||||||
* 在线聊天 用户好友缓存前缀
|
* 在线聊天 用户好友缓存前缀
|
||||||
*/
|
*/
|
||||||
public static final String IM_PREFIX_USER_FRIEND_CACHE = "im_prefix_user_friend_";
|
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 考勤补卡业务状态 (1:同意 2:不同意)
|
* 考勤补卡业务状态 (1:同意 2:不同意)
|
||||||
@@ -290,11 +292,13 @@ public interface CommonConstant {
|
|||||||
|
|
||||||
|
|
||||||
public final static String X_ACCESS_TOKEN = "X-Access-Token";
|
public final static String X_ACCESS_TOKEN = "X-Access-Token";
|
||||||
|
public final static String X_SIGN = "X-Sign";
|
||||||
|
public final static String X_TIMESTAMP = "X-TIMESTAMP";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多租户 请求头
|
* 多租户 请求头
|
||||||
*/
|
*/
|
||||||
public final static String TENANT_ID = "tenant_id";
|
public final static String TENANT_ID = "tenant-id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微服务读取配置文件属性 服务地址
|
* 微服务读取配置文件属性 服务地址
|
||||||
|
|||||||
+2
-1
@@ -13,7 +13,8 @@ public interface CommonSendStatus {
|
|||||||
|
|
||||||
public static final String REVOKE_STATUS_2 = "2"; //撤销
|
public static final String REVOKE_STATUS_2 = "2"; //撤销
|
||||||
|
|
||||||
|
//app端推送会话标识后缀
|
||||||
|
public static final String APP_SESSION_SUFFIX = "_app"; //app端推送会话标识后缀
|
||||||
|
|
||||||
/**流程催办——系统通知消息模板*/
|
/**流程催办——系统通知消息模板*/
|
||||||
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
|
public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
|
||||||
|
|||||||
+10
@@ -6,6 +6,7 @@ public interface DataBaseConstant {
|
|||||||
//*********数据库类型****************************************
|
//*********数据库类型****************************************
|
||||||
public static final String DB_TYPE_MYSQL = "MYSQL";
|
public static final String DB_TYPE_MYSQL = "MYSQL";
|
||||||
public static final String DB_TYPE_ORACLE = "ORACLE";
|
public static final String DB_TYPE_ORACLE = "ORACLE";
|
||||||
|
public static final String DB_TYPE_DM = "DM";//达梦数据库
|
||||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||||
|
|
||||||
@@ -110,4 +111,13 @@ public interface DataBaseConstant {
|
|||||||
*/
|
*/
|
||||||
public static final String BPM_STATUS_TABLE = "bpm_status";
|
public static final String BPM_STATUS_TABLE = "bpm_status";
|
||||||
//*********系统建表标准字段****************************************
|
//*********系统建表标准字段****************************************
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 租户ID 实体字段名
|
||||||
|
*/
|
||||||
|
String TENANT_ID = "tenantId";
|
||||||
|
/**
|
||||||
|
* 租户ID 数据库字段名
|
||||||
|
*/
|
||||||
|
String TENANT_ID_TABLE = "tenant_id";
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -26,6 +26,8 @@ public class JeroElasticsearchTemplate {
|
|||||||
/** es服务地址 */
|
/** es服务地址 */
|
||||||
private String baseUrl;
|
private String baseUrl;
|
||||||
private final String FORMAT_JSON = "format=json";
|
private final String FORMAT_JSON = "format=json";
|
||||||
|
/** Elasticsearch 的版本号 */
|
||||||
|
private String version = null;
|
||||||
|
|
||||||
// ElasticSearch 最大可返回条目数
|
// ElasticSearch 最大可返回条目数
|
||||||
public static final int ES_MAX_SIZE = 10000;
|
public static final int ES_MAX_SIZE = 10000;
|
||||||
@@ -37,15 +39,32 @@ public class JeroElasticsearchTemplate {
|
|||||||
// 验证配置的ES地址是否有效
|
// 验证配置的ES地址是否有效
|
||||||
if (checkEnabled) {
|
if (checkEnabled) {
|
||||||
try {
|
try {
|
||||||
|
this.getElasticsearchVersion();
|
||||||
RestUtil.get(this.getBaseUrl().toString());
|
RestUtil.get(this.getBaseUrl().toString());
|
||||||
log.info("ElasticSearch 服务连接成功");
|
log.info("ElasticSearch 服务连接成功");
|
||||||
|
log.info("ElasticSearch version: " + this.version);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
this.version = "";
|
||||||
log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!");
|
log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Elasticsearch 的版本号信息,失败返回null
|
||||||
|
*/
|
||||||
|
private void getElasticsearchVersion() {
|
||||||
|
if (this.version == null) {
|
||||||
|
String url = this.getBaseUrl().toString();
|
||||||
|
JSONObject result = RestUtil.get(url);
|
||||||
|
if (result != null) {
|
||||||
|
JSONObject v = result.getJSONObject("version");
|
||||||
|
this.version = v.getString("number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public StringBuilder getBaseUrl(String indexName, String typeName) {
|
public StringBuilder getBaseUrl(String indexName, String typeName) {
|
||||||
typeName = typeName.trim().toLowerCase();
|
typeName = typeName.trim().toLowerCase();
|
||||||
return this.getBaseUrl(indexName).append("/").append(typeName);
|
return this.getBaseUrl(indexName).append("/").append(typeName);
|
||||||
@@ -185,6 +204,11 @@ public class JeroElasticsearchTemplate {
|
|||||||
*/
|
*/
|
||||||
public JSONObject getIndexMapping(String indexName, String typeName) {
|
public JSONObject getIndexMapping(String indexName, String typeName) {
|
||||||
String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString();
|
String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString();
|
||||||
|
// 针对 es 7.x 版本做兼容
|
||||||
|
this.getElasticsearchVersion();
|
||||||
|
if (oConvertUtils.isNotEmpty(this.version) && this.version.startsWith("7")) {
|
||||||
|
url += "&include_type_name=true";
|
||||||
|
}
|
||||||
log.info("getIndexMapping-url:" + url);
|
log.info("getIndexMapping-url:" + url);
|
||||||
/*
|
/*
|
||||||
* 参考返回JSON结构:
|
* 参考返回JSON结构:
|
||||||
|
|||||||
+53
-4
@@ -1,6 +1,8 @@
|
|||||||
package com.jero.common.system.base.controller;
|
package com.jero.common.system.base.controller;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.beanutils.PropertyUtils;
|
import org.apache.commons.beanutils.PropertyUtils;
|
||||||
@@ -13,6 +15,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
|||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -23,11 +26,8 @@ import org.springframework.web.servlet.ModelAndView;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: Controller基类
|
* @Description: Controller基类
|
||||||
* @Author: dangzhenghui@163.com
|
* @Author: dangzhenghui@163.com
|
||||||
@@ -77,6 +77,55 @@ public class JeroController<T, S extends IService<T>> {
|
|||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据每页sheet数量导出多sheet
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param object 实体类
|
||||||
|
* @param clazz 实体类class
|
||||||
|
* @param title 标题
|
||||||
|
* @param exportFields 导出字段自定义
|
||||||
|
* @param pageNum 每个sheet的数据条数
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class<T> clazz, String title,String exportFields,Integer pageNum) {
|
||||||
|
// Step.1 组装查询条件
|
||||||
|
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||||
|
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||||
|
// Step.2 计算分页sheet数据
|
||||||
|
double total = service.count();
|
||||||
|
int count = (int)Math.ceil(total/pageNum);
|
||||||
|
// Step.3 多sheet处理
|
||||||
|
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
|
||||||
|
for (int i = 1; i <=count ; i++) {
|
||||||
|
Page<T> page = new Page<T>(i, pageNum);
|
||||||
|
IPage<T> pageList = service.page(page, queryWrapper);
|
||||||
|
List<T> records = pageList.getRecords();
|
||||||
|
List<T> exportList = null;
|
||||||
|
// 过滤选中数据
|
||||||
|
String selections = request.getParameter("selections");
|
||||||
|
if (oConvertUtils.isNotEmpty(selections)) {
|
||||||
|
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||||
|
exportList = records.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
exportList = records;
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
//map.put("title",exportParams);//表格Title
|
||||||
|
map.put(NormalExcelConstants.PARAMS,exportParams);//表格Title
|
||||||
|
map.put(NormalExcelConstants.CLASS,clazz);//表格对应实体
|
||||||
|
map.put(NormalExcelConstants.DATA_LIST, exportList);//数据集合
|
||||||
|
listMap.add(map);
|
||||||
|
}
|
||||||
|
// Step.4 AutoPoi 导出Excel
|
||||||
|
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||||
|
mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
|
||||||
|
mv.addObject(NormalExcelConstants.MAP_LIST, listMap);
|
||||||
|
return mv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据权限导出excel,传入导出字段参数
|
* 根据权限导出excel,传入导出字段参数
|
||||||
*
|
*
|
||||||
|
|||||||
+16
-2
@@ -5,9 +5,15 @@ import java.io.Serializable;
|
|||||||
public class QueryCondition implements Serializable {
|
public class QueryCondition implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4740166316629191651L;
|
private static final long serialVersionUID = 4740166316629191651L;
|
||||||
|
|
||||||
private String field;
|
private String field;
|
||||||
|
/** 组件的类型(例如:input、select、radio) */
|
||||||
private String type;
|
private String type;
|
||||||
|
/**
|
||||||
|
* 对应的数据库字段的类型
|
||||||
|
* 支持:int、bigDecimal、short、long、float、double、boolean
|
||||||
|
*/
|
||||||
|
private String dbType;
|
||||||
private String rule;
|
private String rule;
|
||||||
private String val;
|
private String val;
|
||||||
|
|
||||||
@@ -27,6 +33,14 @@ public class QueryCondition implements Serializable {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDbType() {
|
||||||
|
return dbType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDbType(String dbType) {
|
||||||
|
this.dbType = dbType;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
@@ -49,7 +63,7 @@ public class QueryCondition implements Serializable {
|
|||||||
if(field == null || "".equals(field)){
|
if(field == null || "".equals(field)){
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.val);
|
sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.dbType).append(" ").append(this.val);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-21
@@ -1,21 +1,5 @@
|
|||||||
package com.jero.common.system.query;
|
package com.jero.common.system.query;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.beanutils.PropertyUtils;
|
|
||||||
import com.jero.common.constant.CommonConstant;
|
|
||||||
import com.jero.common.constant.DataBaseConstant;
|
|
||||||
import com.jero.common.system.util.JeroDataAutorUtils;
|
|
||||||
import com.jero.common.system.util.JwtUtil;
|
|
||||||
import com.jero.common.system.vo.SysPermissionDataRuleModel;
|
|
||||||
import com.jero.common.util.CommonUtils;
|
|
||||||
import com.jero.common.util.DateUtils;
|
|
||||||
import com.jero.common.util.SqlInjectionUtil;
|
|
||||||
import com.jero.common.util.oConvertUtils;
|
|
||||||
import org.springframework.util.NumberUtils;
|
|
||||||
|
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -28,6 +12,25 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.beanutils.PropertyUtils;
|
||||||
|
import com.jero.common.constant.CommonConstant;
|
||||||
|
import com.jero.common.constant.DataBaseConstant;
|
||||||
|
import com.jero.common.system.util.JeroDataAutorUtils;
|
||||||
|
import com.jero.common.system.util.JwtUtil;
|
||||||
|
import com.jero.common.system.vo.SysPermissionDataRuleModel;
|
||||||
|
import com.jero.common.util.CommonUtils;
|
||||||
|
import com.jero.common.util.DateUtils;
|
||||||
|
import com.jero.common.util.SqlInjectionUtil;
|
||||||
|
import com.jero.common.util.oConvertUtils;
|
||||||
|
import org.springframework.util.NumberUtils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class QueryGenerator {
|
public class QueryGenerator {
|
||||||
public static final String SQL_RULES_COLUMN = "SQL_RULES_COLUMN";
|
public static final String SQL_RULES_COLUMN = "SQL_RULES_COLUMN";
|
||||||
@@ -221,20 +224,31 @@ public class QueryGenerator {
|
|||||||
if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
|
if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
|
||||||
order = parameterMap.get(ORDER_TYPE)[0];
|
order = parameterMap.get(ORDER_TYPE)[0];
|
||||||
}
|
}
|
||||||
log.debug("排序规则>>列:"+column+",排序方式:"+order);
|
log.info("排序规则>>列:" + column + ",排序方式:" + order);
|
||||||
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
|
||||||
//字典字段,去掉字典翻译文本后缀
|
//字典字段,去掉字典翻译文本后缀
|
||||||
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
|
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
|
||||||
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
|
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
|
||||||
}
|
}
|
||||||
//SQL注入check
|
//SQL注入check
|
||||||
SqlInjectionUtil.filterContent(column);
|
SqlInjectionUtil.filterContent(column);
|
||||||
|
|
||||||
|
//update-begin--Author:scott Date:20210531 for:36 多条件排序无效问题修正-------
|
||||||
|
// 排序规则修改
|
||||||
|
// 将现有排序 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1,column2 desc"
|
||||||
|
// 修改为 _ 前端传递排序条件{....,column: 'column1,column2',order: 'desc'} 翻译成sql "column1 desc,column2 desc"
|
||||||
if (order.toUpperCase().indexOf(ORDER_TYPE_ASC)>=0) {
|
if (order.toUpperCase().indexOf(ORDER_TYPE_ASC)>=0) {
|
||||||
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
|
||||||
|
String columnStr = oConvertUtils.camelToUnderline(column);
|
||||||
|
String[] columnArray = columnStr.split(",");
|
||||||
|
queryWrapper.orderByAsc(Arrays.asList(columnArray));
|
||||||
} else {
|
} else {
|
||||||
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
|
||||||
|
String columnStr = oConvertUtils.camelToUnderline(column);
|
||||||
|
String[] columnArray = columnStr.split(",");
|
||||||
|
queryWrapper.orderByDesc(Arrays.asList(columnArray));
|
||||||
}
|
}
|
||||||
|
//update-end--Author:scott Date:20210531 for:36 多条件排序无效问题修正-------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -11,6 +11,7 @@ import java.util.Date;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import com.jero.common.constant.CommonConstant;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import com.jero.common.constant.DataBaseConstant;
|
import com.jero.common.constant.DataBaseConstant;
|
||||||
import com.jero.common.exception.JeroBootException;
|
import com.jero.common.exception.JeroBootException;
|
||||||
@@ -28,7 +29,7 @@ import com.jero.common.util.oConvertUtils;
|
|||||||
public class JwtUtil {
|
public class JwtUtil {
|
||||||
|
|
||||||
// Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
|
// Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
|
||||||
public static final long EXPIRE_TIME = 30 * 60 * 1000;
|
public static final long EXPIRE_TIME = 60 * 60 * 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验token是否正确
|
* 校验token是否正确
|
||||||
@@ -197,6 +198,14 @@ public class JwtUtil {
|
|||||||
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
||||||
returnValue = "1";
|
returnValue = "1";
|
||||||
}
|
}
|
||||||
|
//update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||||
|
else if (key.equals(DataBaseConstant.TENANT_ID) || key.toLowerCase().equals(DataBaseConstant.TENANT_ID_TABLE)){
|
||||||
|
returnValue = sysUser.getRelTenantIds();
|
||||||
|
if(oConvertUtils.isEmpty(returnValue) || (returnValue!=null && returnValue.indexOf(",")>0)){
|
||||||
|
returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20210330 for:多租户ID作为系统变量
|
||||||
if(returnValue!=null){returnValue = returnValue + moshi;}
|
if(returnValue!=null){returnValue = returnValue + moshi;}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.jero.common.system.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询多个字典时用到
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class DictModelMany extends DictModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典code,根据多个字段code查询时才用到,用于区分不同的字典选项
|
||||||
|
*/
|
||||||
|
private String dictCode;
|
||||||
|
|
||||||
|
}
|
||||||
-4
@@ -36,10 +36,6 @@ public class DynamicDataSourceModel {
|
|||||||
* 数据源地址
|
* 数据源地址
|
||||||
*/
|
*/
|
||||||
private java.lang.String dbUrl;
|
private java.lang.String dbUrl;
|
||||||
/**
|
|
||||||
* 数据库名称
|
|
||||||
*/
|
|
||||||
private java.lang.String dbName;
|
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
*/
|
*/
|
||||||
|
|||||||
+50
-18
@@ -1,30 +1,31 @@
|
|||||||
package com.jero.common.util;
|
package com.jero.common.util;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import cn.hutool.crypto.asymmetric.KeyType;
|
import cn.hutool.crypto.asymmetric.KeyType;
|
||||||
import cn.hutool.crypto.asymmetric.RSA;
|
import cn.hutool.crypto.asymmetric.RSA;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import com.jero.common.constant.CommonConstant;
|
import com.jero.common.constant.CommonConstant;
|
||||||
import com.jero.common.constant.DataBaseConstant;
|
import com.jero.common.constant.DataBaseConstant;
|
||||||
import com.jero.common.exception.JeroBootException;
|
import com.jero.common.exception.JeroBootException;
|
||||||
|
import com.jero.common.util.filter.FileTypeFilter;
|
||||||
import com.jero.common.util.oss.OssBootUtil;
|
import com.jero.common.util.oss.OssBootUtil;
|
||||||
import org.jeecgframework.poi.util.PoiPublicUtil;
|
import org.jeecgframework.poi.util.PoiPublicUtil;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
import java.io.*;
|
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.KeyFactory;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CommonUtils {
|
public class CommonUtils {
|
||||||
@@ -79,7 +80,8 @@ public class CommonUtils {
|
|||||||
fileName = fileName.substring(pos + 1);
|
fileName = fileName.substring(pos + 1);
|
||||||
}
|
}
|
||||||
//替换上传文件名字的特殊字符
|
//替换上传文件名字的特殊字符
|
||||||
fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
|
fileName = fileName.replace("=","").replace(",","").replace("&","")
|
||||||
|
.replace("#", "").replace("“", "").replace("”", "");
|
||||||
//替换上传文件名字中的空格
|
//替换上传文件名字中的空格
|
||||||
fileName=fileName.replaceAll("\\s","");
|
fileName=fileName.replaceAll("\\s","");
|
||||||
return fileName;
|
return fileName;
|
||||||
@@ -133,6 +135,9 @@ public class CommonUtils {
|
|||||||
*/
|
*/
|
||||||
public static String uploadLocal(MultipartFile mf,String bizPath, String uploadpath){
|
public static String uploadLocal(MultipartFile mf,String bizPath, String uploadpath){
|
||||||
try {
|
try {
|
||||||
|
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
|
FileTypeFilter.fileTypeFilter(mf);
|
||||||
|
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
String ctxPath = uploadpath;
|
String ctxPath = uploadpath;
|
||||||
String fileName = null;
|
String fileName = null;
|
||||||
File file = new File(ctxPath + File.separator + bizPath + File.separator );
|
File file = new File(ctxPath + File.separator + bizPath + File.separator );
|
||||||
@@ -142,7 +147,7 @@ public class CommonUtils {
|
|||||||
String orgName = mf.getOriginalFilename();// 获取文件名
|
String orgName = mf.getOriginalFilename();// 获取文件名
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
if(orgName.indexOf(".")!=-1){
|
if(orgName.indexOf(".")!=-1){
|
||||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
}else{
|
}else{
|
||||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
@@ -161,11 +166,20 @@ public class CommonUtils {
|
|||||||
return dbpath;
|
return dbpath;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
/** 当前系统数据库类型 */
|
/** 当前系统数据库类型 */
|
||||||
private static String DB_TYPE = "";
|
private static String DB_TYPE = "";
|
||||||
|
private static DbType dbTypeEnum = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局获取平台数据库类型(作废了)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getDatabaseType() {
|
public static String getDatabaseType() {
|
||||||
if(oConvertUtils.isNotEmpty(DB_TYPE)){
|
if(oConvertUtils.isNotEmpty(DB_TYPE)){
|
||||||
return DB_TYPE;
|
return DB_TYPE;
|
||||||
@@ -175,11 +189,29 @@ public class CommonUtils {
|
|||||||
return getDatabaseTypeByDataSource(dataSource);
|
return getDatabaseTypeByDataSource(dataSource);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
//e.printStackTrace();
|
//e.printStackTrace();
|
||||||
log.warn(e.getMessage());
|
log.warn(e.getMessage(), e);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局获取平台数据库类型(对应mybaisPlus枚举)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static DbType getDatabaseTypeEnum() {
|
||||||
|
if (oConvertUtils.isNotEmpty(dbTypeEnum)) {
|
||||||
|
return dbTypeEnum;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
|
||||||
|
dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL());
|
||||||
|
return dbTypeEnum;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据库类型
|
* 获取数据库类型
|
||||||
* @param dataSource
|
* @param dataSource
|
||||||
|
|||||||
+4
@@ -621,6 +621,10 @@ public class DateUtils extends PropertyEditorSupport {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Long getCurrentTimestamp() {
|
||||||
|
return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
|
* String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
|
||||||
* HH:mm:ss“ * @param text String类型的时间值
|
* HH:mm:ss“ * @param text String类型的时间值
|
||||||
|
|||||||
+9
-3
@@ -1,11 +1,11 @@
|
|||||||
package com.jero.common.util;
|
package com.jero.common.util;
|
||||||
|
|
||||||
|
import com.jero.common.util.filter.FileTypeFilter;
|
||||||
import io.minio.*;
|
import io.minio.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.jero.common.util.filter.StrAttackFilter;
|
import com.jero.common.util.filter.StrAttackFilter;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.validation.constraints.Null;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@ public class MinioUtil {
|
|||||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
|
minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
|
||||||
log.info("create a new bucket.");
|
log.info("create a new bucket.");
|
||||||
}
|
}
|
||||||
|
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
|
FileTypeFilter.fileTypeFilter(file);
|
||||||
|
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
InputStream stream = file.getInputStream();
|
InputStream stream = file.getInputStream();
|
||||||
// 获取文件名
|
// 获取文件名
|
||||||
String orgName = file.getOriginalFilename();
|
String orgName = file.getOriginalFilename();
|
||||||
@@ -76,8 +79,11 @@ public class MinioUtil {
|
|||||||
orgName=file.getName();
|
orgName=file.getName();
|
||||||
}
|
}
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
String objectName = bizPath+"/"
|
||||||
|
+( orgName.indexOf(".")==-1
|
||||||
|
?orgName + "_" + System.currentTimeMillis()
|
||||||
|
:orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."))
|
||||||
|
);
|
||||||
// 使用putObject上传一个本地文件到存储桶中。
|
// 使用putObject上传一个本地文件到存储桶中。
|
||||||
if(objectName.startsWith("/")){
|
if(objectName.startsWith("/")){
|
||||||
objectName = objectName.substring(1);
|
objectName = objectName.substring(1);
|
||||||
|
|||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
package com.jero.common.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用Spring自身提供的地址匹配工具匹配URL
|
||||||
|
*/
|
||||||
|
public class PathMatcherUtil {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String url = "/sys/dict/loadDictOrderByValue/tree,s2,2";
|
||||||
|
String p = "/sys/dict/loadDictOrderByValue/*";
|
||||||
|
|
||||||
|
System.out.println(PathMatcherUtil.match(p,url));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际验证路径匹配权限
|
||||||
|
*
|
||||||
|
* @param matchPath 权限url
|
||||||
|
* @param path 访问路径
|
||||||
|
* @return 是否拥有权限
|
||||||
|
*/
|
||||||
|
public static boolean match(String matchPath, String path) {
|
||||||
|
SpringAntMatcher springAntMatcher = new SpringAntMatcher(matchPath, true);
|
||||||
|
return springAntMatcher.matches(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际验证路径匹配权限
|
||||||
|
*
|
||||||
|
* @param list 权限url
|
||||||
|
* @param path 访问路径
|
||||||
|
* @return 是否拥有权限
|
||||||
|
*/
|
||||||
|
public static boolean matches(Collection<String> list, String path) {
|
||||||
|
for (String s : list) {
|
||||||
|
SpringAntMatcher springAntMatcher = new SpringAntMatcher(s, true);
|
||||||
|
if (springAntMatcher.matches(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址表达式匹配工具
|
||||||
|
*/
|
||||||
|
private static class SpringAntMatcher implements Matcher {
|
||||||
|
private final AntPathMatcher antMatcher;
|
||||||
|
private final String pattern;
|
||||||
|
|
||||||
|
private SpringAntMatcher(String pattern, boolean caseSensitive) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.antMatcher = createMatcher(caseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(String path) {
|
||||||
|
return this.antMatcher.match(this.pattern, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> extractUriTemplateVariables(String path) {
|
||||||
|
return this.antMatcher.extractUriTemplateVariables(this.pattern, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AntPathMatcher createMatcher(boolean caseSensitive) {
|
||||||
|
AntPathMatcher matcher = new AntPathMatcher();
|
||||||
|
matcher.setTrimTokens(false);
|
||||||
|
matcher.setCaseSensitive(caseSensitive);
|
||||||
|
return matcher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Matcher {
|
||||||
|
boolean matches(String var1);
|
||||||
|
|
||||||
|
Map<String, String> extractUriTemplateVariables(String var1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -192,6 +192,23 @@ public class ReflectHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取属性值
|
||||||
|
*/
|
||||||
|
public static Object getFieldVal(String fieldName, Object o) {
|
||||||
|
try {
|
||||||
|
// 暴力反射获取属性
|
||||||
|
Field filed = o.getClass().getDeclaredField(fieldName);
|
||||||
|
// 设置反射时取消Java的访问检查,暴力访问
|
||||||
|
filed.setAccessible(true);
|
||||||
|
Object val = filed.get(o);
|
||||||
|
return val;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取属性名数组
|
* 获取属性名数组
|
||||||
*/
|
*/
|
||||||
|
|||||||
+21
@@ -4,6 +4,7 @@ import cn.hutool.crypto.SecureUtil;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.jero.common.exception.JeroBootException;
|
import com.jero.common.exception.JeroBootException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sql注入处理工具类
|
* sql注入处理工具类
|
||||||
@@ -51,6 +52,8 @@ public class SqlInjectionUtil {
|
|||||||
}
|
}
|
||||||
// 统一转为小写
|
// 统一转为小写
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
|
value = value.replaceAll("/\\*.*\\*/","");
|
||||||
|
|
||||||
String[] xssArr = xssStr.split("\\|");
|
String[] xssArr = xssStr.split("\\|");
|
||||||
for (int i = 0; i < xssArr.length; i++) {
|
for (int i = 0; i < xssArr.length; i++) {
|
||||||
if (value.indexOf(xssArr[i]) > -1) {
|
if (value.indexOf(xssArr[i]) > -1) {
|
||||||
@@ -59,6 +62,9 @@ public class SqlInjectionUtil {
|
|||||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Pattern.matches("show\\s+tables", value)){
|
||||||
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +82,8 @@ public class SqlInjectionUtil {
|
|||||||
}
|
}
|
||||||
// 统一转为小写
|
// 统一转为小写
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
|
value = value.replaceAll("/\\*.*\\*/","");
|
||||||
|
|
||||||
for (int i = 0; i < xssArr.length; i++) {
|
for (int i = 0; i < xssArr.length; i++) {
|
||||||
if (value.indexOf(xssArr[i]) > -1) {
|
if (value.indexOf(xssArr[i]) > -1) {
|
||||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||||
@@ -83,6 +91,9 @@ public class SqlInjectionUtil {
|
|||||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Pattern.matches("show\\s+tables", value)){
|
||||||
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,6 +112,8 @@ public class SqlInjectionUtil {
|
|||||||
}
|
}
|
||||||
// 统一转为小写
|
// 统一转为小写
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
|
value = value.replaceAll("/\\*.*\\*/","");
|
||||||
|
|
||||||
for (int i = 0; i < xssArr.length; i++) {
|
for (int i = 0; i < xssArr.length; i++) {
|
||||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||||
@@ -108,6 +121,9 @@ public class SqlInjectionUtil {
|
|||||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Pattern.matches("show\\s+tables", value)){
|
||||||
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +142,8 @@ public class SqlInjectionUtil {
|
|||||||
}
|
}
|
||||||
// 统一转为小写
|
// 统一转为小写
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
|
value = value.replaceAll("/\\*.*\\*/","");
|
||||||
|
|
||||||
for (int i = 0; i < xssArr.length; i++) {
|
for (int i = 0; i < xssArr.length; i++) {
|
||||||
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
|
||||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
|
||||||
@@ -133,6 +151,9 @@ public class SqlInjectionUtil {
|
|||||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Pattern.matches("show\\s+tables", value)){
|
||||||
|
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ public class YouBianCodeUtil {
|
|||||||
*/
|
*/
|
||||||
public static synchronized String getNextYouBianCode(String code) {
|
public static synchronized String getNextYouBianCode(String code) {
|
||||||
String newcode = "";
|
String newcode = "";
|
||||||
if (code == null || code =="") {
|
if (oConvertUtils.isEmpty(code)) {
|
||||||
String zimu = "A";
|
String zimu = "A";
|
||||||
String num = getStrNum(1);
|
String num = getStrNum(1);
|
||||||
newcode = zimu + num;
|
newcode = zimu + num;
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package com.jero.common.util.dynamic.db;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库类型判断
|
||||||
|
* 【有些数据库引擎是一样的,以达到复用目的】
|
||||||
|
*/
|
||||||
|
public class DbTypeUtils {
|
||||||
|
|
||||||
|
public static boolean dbTypeIsMySQL(DbType dbType) {
|
||||||
|
return dbTypeIf(dbType, DbType.MYSQL, DbType.MARIADB, DbType.CLICK_HOUSE, DbType.SQLITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean dbTypeIsOracle(DbType dbType) {
|
||||||
|
return dbTypeIf(dbType, DbType.ORACLE, DbType.ORACLE_12C, DbType.DM);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean dbTypeIsSQLServer(DbType dbType) {
|
||||||
|
return dbTypeIf(dbType, DbType.SQL_SERVER, DbType.SQL_SERVER2005);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean dbTypeIsPostgre(DbType dbType) {
|
||||||
|
return dbTypeIf(dbType, DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.GAUSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断数据库类型
|
||||||
|
*/
|
||||||
|
public static boolean dbTypeIf(DbType dbType, DbType... correctTypes) {
|
||||||
|
for (DbType type : correctTypes) {
|
||||||
|
if (type.equals(dbType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-1
@@ -49,7 +49,7 @@ public class DynamicDBUtil {
|
|||||||
dataSource.setBreakAfterAcquireFailure(true);
|
dataSource.setBreakAfterAcquireFailure(true);
|
||||||
dataSource.setConnectionErrorRetryAttempts(0);
|
dataSource.setConnectionErrorRetryAttempts(0);
|
||||||
dataSource.setUsername(dbUser);
|
dataSource.setUsername(dbUser);
|
||||||
dataSource.setMaxWait(60000);
|
dataSource.setMaxWait(30000);
|
||||||
dataSource.setPassword(dbPassword);
|
dataSource.setPassword(dbPassword);
|
||||||
|
|
||||||
log.info("******************************************");
|
log.info("******************************************");
|
||||||
@@ -151,6 +151,7 @@ public class DynamicDBUtil {
|
|||||||
list = findList(dbKey, sql, param);
|
list = findList(dbKey, sql, param);
|
||||||
if (oConvertUtils.listIsEmpty(list)) {
|
if (oConvertUtils.listIsEmpty(list)) {
|
||||||
log.error("Except one, but not find actually");
|
log.error("Except one, but not find actually");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (list.size() > 1) {
|
if (list.size() > 1) {
|
||||||
log.error("Except one, but more than one actually");
|
log.error("Except one, but more than one actually");
|
||||||
|
|||||||
+164
@@ -0,0 +1,164 @@
|
|||||||
|
package com.jero.common.util.filter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: TODO
|
||||||
|
* @author: lsq
|
||||||
|
* @date: 2021年08月09日 15:29
|
||||||
|
*/
|
||||||
|
public class FileTypeFilter {
|
||||||
|
|
||||||
|
//文件后缀
|
||||||
|
private static String[] forbidType = {"jsp","php"};
|
||||||
|
|
||||||
|
// 初始化文件头类型,不够的自行补充
|
||||||
|
final static HashMap<String, String> fileTypeMap = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
fileTypeMap.put("3c25402070616765206c", "jsp");
|
||||||
|
fileTypeMap.put("3c3f7068700a0a2f2a2a0a202a205048", "php");
|
||||||
|
/* fileTypeMap.put("ffd8ffe000104a464946", "jpg");
|
||||||
|
fileTypeMap.put("89504e470d0a1a0a0000", "png");
|
||||||
|
fileTypeMap.put("47494638396126026f01", "gif");
|
||||||
|
fileTypeMap.put("49492a00227105008037", "tif");
|
||||||
|
fileTypeMap.put("424d228c010000000000", "bmp");
|
||||||
|
fileTypeMap.put("424d8240090000000000", "bmp");
|
||||||
|
fileTypeMap.put("424d8e1b030000000000", "bmp");
|
||||||
|
fileTypeMap.put("41433130313500000000", "dwg");
|
||||||
|
fileTypeMap.put("3c21444f435459504520", "html");
|
||||||
|
fileTypeMap.put("3c21646f637479706520", "htm");
|
||||||
|
fileTypeMap.put("48544d4c207b0d0a0942", "css");
|
||||||
|
fileTypeMap.put("696b2e71623d696b2e71", "js");
|
||||||
|
fileTypeMap.put("7b5c727466315c616e73", "rtf");
|
||||||
|
fileTypeMap.put("38425053000100000000", "psd");
|
||||||
|
fileTypeMap.put("46726f6d3a203d3f6762", "eml");
|
||||||
|
fileTypeMap.put("d0cf11e0a1b11ae10000", "doc");
|
||||||
|
fileTypeMap.put("5374616E64617264204A", "mdb");
|
||||||
|
fileTypeMap.put("252150532D41646F6265", "ps");
|
||||||
|
fileTypeMap.put("255044462d312e350d0a", "pdf");
|
||||||
|
fileTypeMap.put("2e524d46000000120001", "rmvb");
|
||||||
|
fileTypeMap.put("464c5601050000000900", "flv");
|
||||||
|
fileTypeMap.put("00000020667479706d70", "mp4");
|
||||||
|
fileTypeMap.put("49443303000000002176", "mp3");
|
||||||
|
fileTypeMap.put("000001ba210001000180", "mpg");
|
||||||
|
fileTypeMap.put("3026b2758e66cf11a6d9", "wmv");
|
||||||
|
fileTypeMap.put("52494646e27807005741", "wav");
|
||||||
|
fileTypeMap.put("52494646d07d60074156", "avi");
|
||||||
|
fileTypeMap.put("4d546864000000060001", "mid");
|
||||||
|
fileTypeMap.put("504b0304140000000800", "zip");
|
||||||
|
fileTypeMap.put("526172211a0700cf9073", "rar");
|
||||||
|
fileTypeMap.put("235468697320636f6e66", "ini");
|
||||||
|
fileTypeMap.put("504b03040a0000000000", "jar");
|
||||||
|
fileTypeMap.put("4d5a9000030000000400", "exe");
|
||||||
|
fileTypeMap.put("3c25402070616765206c", "jsp");
|
||||||
|
fileTypeMap.put("4d616e69666573742d56", "mf");
|
||||||
|
fileTypeMap.put("3c3f786d6c2076657273", "xml");
|
||||||
|
fileTypeMap.put("494e5345525420494e54", "sql");
|
||||||
|
fileTypeMap.put("7061636b616765207765", "java");
|
||||||
|
fileTypeMap.put("406563686f206f66660d", "bat");
|
||||||
|
fileTypeMap.put("1f8b0800000000000000", "gz");
|
||||||
|
fileTypeMap.put("6c6f67346a2e726f6f74", "properties");
|
||||||
|
fileTypeMap.put("cafebabe0000002e0041", "class");
|
||||||
|
fileTypeMap.put("49545346030000006000", "chm");
|
||||||
|
fileTypeMap.put("04000000010000001300", "mxp");
|
||||||
|
fileTypeMap.put("504b0304140006000800", "docx");
|
||||||
|
fileTypeMap.put("6431303a637265617465", "torrent");
|
||||||
|
fileTypeMap.put("6D6F6F76", "mov");
|
||||||
|
fileTypeMap.put("FF575043", "wpd");
|
||||||
|
fileTypeMap.put("CFAD12FEC5FD746F", "dbx");
|
||||||
|
fileTypeMap.put("2142444E", "pst");
|
||||||
|
fileTypeMap.put("AC9EBD8F", "qdf");
|
||||||
|
fileTypeMap.put("E3828596", "pwl");
|
||||||
|
fileTypeMap.put("2E7261FD", "ram");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileName
|
||||||
|
* @return String
|
||||||
|
* @description 通过文件后缀名获取文件类型
|
||||||
|
*/
|
||||||
|
private static String getFileTypeBySuffix(String fileName) {
|
||||||
|
return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件类型过滤
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
*/
|
||||||
|
public static void fileTypeFilter(MultipartFile file) throws Exception {
|
||||||
|
String suffix = getFileType(file);
|
||||||
|
for (String type : forbidType) {
|
||||||
|
if (type.contains(suffix)) {
|
||||||
|
throw new Exception("上传失败,文件类型异常:" + suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过读取文件头部获得文件类型
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return 文件类型
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static String getFileType(MultipartFile file) throws Exception {
|
||||||
|
String fileExtendName = null;
|
||||||
|
InputStream is;
|
||||||
|
try {
|
||||||
|
//is = new FileInputStream(file);
|
||||||
|
is = file.getInputStream();
|
||||||
|
byte[] b = new byte[10];
|
||||||
|
is.read(b, 0, b.length);
|
||||||
|
String fileTypeHex = String.valueOf(bytesToHexString(b));
|
||||||
|
Iterator<String> keyIter = fileTypeMap.keySet().iterator();
|
||||||
|
while (keyIter.hasNext()) {
|
||||||
|
String key = keyIter.next();
|
||||||
|
// 验证前5个字符比较
|
||||||
|
if (key.toLowerCase().startsWith(fileTypeHex.toLowerCase().substring(0, 5))
|
||||||
|
|| fileTypeHex.toLowerCase().substring(0, 5).startsWith(key.toLowerCase())) {
|
||||||
|
fileExtendName = fileTypeMap.get(key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果不是上述类型,则判断扩展名
|
||||||
|
if (StringUtils.isBlank(fileExtendName)) {
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
return getFileTypeBySuffix(fileName);
|
||||||
|
}
|
||||||
|
is.close();
|
||||||
|
return fileExtendName;
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new Exception(exception.getMessage(), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得文件头部字符串
|
||||||
|
*
|
||||||
|
* @param src
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String bytesToHexString(byte[] src) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
if (src == null || src.length <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < src.length; i++) {
|
||||||
|
int v = src[i] & 0xFF;
|
||||||
|
String hv = Integer.toHexString(v);
|
||||||
|
if (hv.length() < 2) {
|
||||||
|
stringBuilder.append(0);
|
||||||
|
}
|
||||||
|
stringBuilder.append(hv);
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-2
@@ -6,6 +6,7 @@ import com.aliyun.oss.common.auth.DefaultCredentialProvider;
|
|||||||
import com.aliyun.oss.model.CannedAccessControlList;
|
import com.aliyun.oss.model.CannedAccessControlList;
|
||||||
import com.aliyun.oss.model.OSSObject;
|
import com.aliyun.oss.model.OSSObject;
|
||||||
import com.aliyun.oss.model.PutObjectResult;
|
import com.aliyun.oss.model.PutObjectResult;
|
||||||
|
import com.jero.common.util.filter.FileTypeFilter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.tomcat.util.http.fileupload.FileItemStream;
|
import org.apache.tomcat.util.http.fileupload.FileItemStream;
|
||||||
import com.jero.common.util.CommonUtils;
|
import com.jero.common.util.CommonUtils;
|
||||||
@@ -110,8 +111,13 @@ public class OssBootUtil {
|
|||||||
if("" == orgName){
|
if("" == orgName){
|
||||||
orgName=file.getName();
|
orgName=file.getName();
|
||||||
}
|
}
|
||||||
|
//update-begin-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
|
FileTypeFilter.fileTypeFilter(file);
|
||||||
|
//update-end-author:liusq date:20210809 for: 过滤上传文件类型
|
||||||
orgName = CommonUtils.getFileName(orgName);
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
String fileName = orgName.indexOf(".")==-1
|
||||||
|
?orgName + "_" + System.currentTimeMillis()
|
||||||
|
:orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
if (!fileDir.endsWith("/")) {
|
if (!fileDir.endsWith("/")) {
|
||||||
fileDir = fileDir.concat("/");
|
fileDir = fileDir.concat("/");
|
||||||
}
|
}
|
||||||
@@ -134,6 +140,9 @@ public class OssBootUtil {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
}catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return FILE_URL;
|
return FILE_URL;
|
||||||
}
|
}
|
||||||
@@ -145,7 +154,7 @@ public class OssBootUtil {
|
|||||||
*/
|
*/
|
||||||
public static String getOriginalUrl(String url) {
|
public static String getOriginalUrl(String url) {
|
||||||
String originalDomain = "https://" + bucketName + "." + endPoint;
|
String originalDomain = "https://" + bucketName + "." + endPoint;
|
||||||
if(url.indexOf(staticDomain)!=-1){
|
if(oConvertUtils.isNotEmpty(staticDomain) && url.indexOf(staticDomain)!=-1){
|
||||||
url = url.replace(staticDomain,originalDomain);
|
url = url.replace(staticDomain,originalDomain);
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
|
|||||||
+2
-3
@@ -8,9 +8,8 @@ import cn.hutool.crypto.asymmetric.RSA;
|
|||||||
import cn.hutool.crypto.asymmetric.Sign;
|
import cn.hutool.crypto.asymmetric.Sign;
|
||||||
import cn.hutool.crypto.asymmetric.SignAlgorithm;
|
import cn.hutool.crypto.asymmetric.SignAlgorithm;
|
||||||
import cn.hutool.crypto.symmetric.AES;
|
import cn.hutool.crypto.symmetric.AES;
|
||||||
import cn.hutool.json.JSONObject;
|
|
||||||
import com.jero.common.util.security.entity.*;
|
import com.jero.common.util.security.entity.*;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ public class SecurityTools {
|
|||||||
|
|
||||||
String dencrptValue =aes.decryptStr(data);
|
String dencrptValue =aes.decryptStr(data);
|
||||||
//log.info("解密后报文"+dencrptValue);
|
//log.info("解密后报文"+dencrptValue);
|
||||||
resp.setData(new JSONObject(dencrptValue));
|
resp.setData(JSONObject.parseObject(dencrptValue));
|
||||||
|
|
||||||
boolean verify = sign.verify(dencrptValue.getBytes(), Base64Decoder.decode(signData));
|
boolean verify = sign.verify(dencrptValue.getBytes(), Base64Decoder.decode(signData));
|
||||||
resp.setSuccess(verify);
|
resp.setSuccess(verify);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package com.jero.common.util.security.entity;
|
package com.jero.common.util.security.entity;
|
||||||
|
|
||||||
import cn.hutool.json.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
package com.jero.config;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||||
|
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
||||||
|
import com.alibaba.druid.util.Utils;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
|
||||||
|
public class DruidConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带有广告的common.js全路径,druid-1.1.14
|
||||||
|
*/
|
||||||
|
private static final String FILE_PATH = "support/http/resources/js/common.js";
|
||||||
|
/**
|
||||||
|
* 原始脚本,触发构建广告的语句
|
||||||
|
*/
|
||||||
|
private static final String ORIGIN_JS = "this.buildFooter();";
|
||||||
|
/**
|
||||||
|
* 替换后的脚本
|
||||||
|
*/
|
||||||
|
private static final String NEW_JS = "//this.buildFooter();";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 去除Druid监控页面的广告
|
||||||
|
*
|
||||||
|
* @param properties DruidStatProperties属性集合
|
||||||
|
* @return {@link FilterRegistrationBean}
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnWebApplication
|
||||||
|
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
|
||||||
|
public FilterRegistrationBean<RemoveAdFilter> removeDruidAdFilter(
|
||||||
|
DruidStatProperties properties) throws IOException {
|
||||||
|
// 获取web监控页面的参数
|
||||||
|
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
|
||||||
|
// 提取common.js的配置路径
|
||||||
|
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
|
||||||
|
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
|
||||||
|
// 获取common.js
|
||||||
|
String text = Utils.readFromResource(FILE_PATH);
|
||||||
|
// 屏蔽 this.buildFooter(); 不构建广告
|
||||||
|
final String newJs = text.replace(ORIGIN_JS, NEW_JS);
|
||||||
|
FilterRegistrationBean<RemoveAdFilter> registration = new FilterRegistrationBean<>();
|
||||||
|
registration.setFilter(new RemoveAdFilter(newJs));
|
||||||
|
registration.addUrlPatterns(commonJsPattern);
|
||||||
|
return registration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除druid的广告过滤器
|
||||||
|
*
|
||||||
|
* @author BBF
|
||||||
|
*/
|
||||||
|
private class RemoveAdFilter implements Filter {
|
||||||
|
|
||||||
|
private final String newJs;
|
||||||
|
|
||||||
|
public RemoveAdFilter(String newJS) {
|
||||||
|
this.newJs = newJS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
// 重置缓冲区,响应头不会被重置
|
||||||
|
response.resetBuffer();
|
||||||
|
response.getWriter().write(newJs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -20,6 +20,11 @@ public class StaticConfig {
|
|||||||
@Value(value = "${spring.mail.username}")
|
@Value(value = "${spring.mail.username}")
|
||||||
private String emailFrom;
|
private String emailFrom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名密钥串
|
||||||
|
*/
|
||||||
|
@Value(value = "${jero.signatureSecret}")
|
||||||
|
private String signatureSecret;
|
||||||
|
|
||||||
/*@Bean
|
/*@Bean
|
||||||
public void initStatic() {
|
public void initStatic() {
|
||||||
|
|||||||
+15
-11
@@ -1,14 +1,18 @@
|
|||||||
package com.jero.config;
|
package com.jero.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
|
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
@@ -72,9 +76,9 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加Long转json精度丢失是配置
|
* 添加Long转json精度丢失的配置
|
||||||
* @Return: void
|
* @Return: void
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
|
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
|
||||||
@@ -87,13 +91,13 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
|||||||
converters.add(jackson2HttpMessageConverter);
|
converters.add(jackson2HttpMessageConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* SpringBootAdmin的Httptrace不见了
|
// * SpringBootAdmin的Httptrace不见了
|
||||||
* https://blog.csdn.net/u013810234/article/details/110097201
|
// * https://blog.csdn.net/u013810234/article/details/110097201
|
||||||
*/
|
// */
|
||||||
@Bean
|
// @Bean
|
||||||
public InMemoryHttpTraceRepository getInMemoryHttpTrace(){
|
// public InMemoryHttpTraceRepository getInMemoryHttpTrace(){
|
||||||
return new InMemoryHttpTraceRepository();
|
// return new InMemoryHttpTraceRepository();
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-130
@@ -1,130 +0,0 @@
|
|||||||
package com.jero.config.mybatis;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
|
|
||||||
import net.sf.jsqlparser.expression.BinaryExpression;
|
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
|
||||||
import net.sf.jsqlparser.expression.Parenthesis;
|
|
||||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
|
||||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
|
||||||
import net.sf.jsqlparser.expression.operators.relational.*;
|
|
||||||
import net.sf.jsqlparser.schema.Column;
|
|
||||||
import net.sf.jsqlparser.schema.Table;
|
|
||||||
import net.sf.jsqlparser.statement.select.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 复写租户条件
|
|
||||||
*/
|
|
||||||
public class JeroTenantParser extends TenantSqlParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param expression
|
|
||||||
* @param table
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected Expression processTableAlias(Expression expression, Table table) {
|
|
||||||
String tableAliasName;
|
|
||||||
if (table.getAlias() == null) {
|
|
||||||
tableAliasName = table.getName();
|
|
||||||
} else {
|
|
||||||
tableAliasName = table.getAlias().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// in
|
|
||||||
if (expression instanceof InExpression) {
|
|
||||||
InExpression in = (InExpression) expression;
|
|
||||||
if (in.getLeftExpression() instanceof Column) {
|
|
||||||
setTableAliasNameForColumn((Column) in.getLeftExpression(), tableAliasName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 比较操作
|
|
||||||
} else if (expression instanceof BinaryExpression) {
|
|
||||||
BinaryExpression compare = (BinaryExpression) expression;
|
|
||||||
if (compare.getLeftExpression() instanceof Column) {
|
|
||||||
setTableAliasNameForColumn((Column) compare.getLeftExpression(), tableAliasName);
|
|
||||||
} else if (compare.getRightExpression() instanceof Column) {
|
|
||||||
setTableAliasNameForColumn((Column) compare.getRightExpression(), tableAliasName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// between
|
|
||||||
} else if (expression instanceof Between) {
|
|
||||||
Between between = (Between) expression;
|
|
||||||
if (between.getLeftExpression() instanceof Column) {
|
|
||||||
setTableAliasNameForColumn((Column) between.getLeftExpression(), tableAliasName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTableAliasNameForColumn(Column column, String tableAliasName) {
|
|
||||||
column.setColumnName(tableAliasName + "." + column.getColumnName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认是按 tenant_id=1 按等于条件追加
|
|
||||||
*
|
|
||||||
* @param currentExpression 现有的条件:比如你原来的sql查询条件
|
|
||||||
* @param table
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Expression builderExpression(Expression currentExpression, Table table) {
|
|
||||||
final Expression tenantExpression = this.getTenantHandler().getTenantId(true);
|
|
||||||
Expression appendExpression;
|
|
||||||
if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) {
|
|
||||||
appendExpression = new EqualsTo();
|
|
||||||
((EqualsTo) appendExpression).setLeftExpression(this.getAliasColumn(table));
|
|
||||||
((EqualsTo) appendExpression).setRightExpression(tenantExpression);
|
|
||||||
} else {
|
|
||||||
appendExpression = processTableAlias(tenantExpression, table);
|
|
||||||
}
|
|
||||||
if (currentExpression == null) {
|
|
||||||
return appendExpression;
|
|
||||||
}
|
|
||||||
if (currentExpression instanceof BinaryExpression) {
|
|
||||||
BinaryExpression binaryExpression = (BinaryExpression) currentExpression;
|
|
||||||
if (binaryExpression.getLeftExpression() instanceof FromItem) {
|
|
||||||
processFromItem((FromItem) binaryExpression.getLeftExpression());
|
|
||||||
}
|
|
||||||
if (binaryExpression.getRightExpression() instanceof FromItem) {
|
|
||||||
processFromItem((FromItem) binaryExpression.getRightExpression());
|
|
||||||
}
|
|
||||||
} else if (currentExpression instanceof InExpression) {
|
|
||||||
InExpression inExp = (InExpression) currentExpression;
|
|
||||||
ItemsList rightItems = inExp.getRightItemsList();
|
|
||||||
if (rightItems instanceof SubSelect) {
|
|
||||||
processSelectBody(((SubSelect) rightItems).getSelectBody());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentExpression instanceof OrExpression) {
|
|
||||||
return new AndExpression(new Parenthesis(currentExpression), appendExpression);
|
|
||||||
} else {
|
|
||||||
return new AndExpression(currentExpression, appendExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
|
|
||||||
FromItem fromItem = plainSelect.getFromItem();
|
|
||||||
if (fromItem instanceof Table) {
|
|
||||||
Table fromTable = (Table) fromItem;
|
|
||||||
if (!this.getTenantHandler().doTableFilter(fromTable.getName())) {
|
|
||||||
plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
|
|
||||||
if (addColumn) {
|
|
||||||
plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processFromItem(fromItem);
|
|
||||||
}
|
|
||||||
List<Join> joins = plainSelect.getJoins();
|
|
||||||
if (joins != null && joins.size() > 0) {
|
|
||||||
joins.forEach(j -> {
|
|
||||||
processJoin(j);
|
|
||||||
processFromItem(j.getRightItem());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-142
@@ -1,142 +0,0 @@
|
|||||||
package com.jero.config.mybatis;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.parser.ISqlParser;
|
|
||||||
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
|
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
|
||||||
import net.sf.jsqlparser.expression.LongValue;
|
|
||||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
|
||||||
import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
|
||||||
import net.sf.jsqlparser.schema.Column;
|
|
||||||
import org.apache.ibatis.reflection.MetaObject;
|
|
||||||
import com.jero.common.util.oConvertUtils;
|
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 单数据源配置(jero.datasource.open = false时生效)
|
|
||||||
* @Author zhoujf
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
@MapperScan(value={"com.jero.**.mapper*"})
|
|
||||||
public class MybatisPlusConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tenant_id 字段名
|
|
||||||
*/
|
|
||||||
public static final String tenant_field = "tenant_id";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 有哪些表需要做多租户 这些表需要添加一个字段 ,字段名和tenant_field对应的值一样
|
|
||||||
*/
|
|
||||||
private static final List<String> tenantTable = new ArrayList<String>();
|
|
||||||
/**
|
|
||||||
* ddl 关键字 判断不走多租户的sql过滤
|
|
||||||
*/
|
|
||||||
private static final List<String> DDL_KEYWORD = new ArrayList<String>();
|
|
||||||
static {
|
|
||||||
tenantTable.add("jee_bug_danbiao");
|
|
||||||
DDL_KEYWORD.add("alter");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户属于 SQL 解析部分,依赖 MP 分页插件
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public PaginationInterceptor paginationInterceptor() {
|
|
||||||
PaginationInterceptor paginationInterceptor = new PaginationInterceptor().setLimit(-1);
|
|
||||||
//多租户配置 配置后每次执行sql会走一遍他的转化器 如果不需要多租户功能 可以将其注释
|
|
||||||
tenantConfig(paginationInterceptor);
|
|
||||||
return paginationInterceptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户的配置
|
|
||||||
* @param paginationInterceptor
|
|
||||||
*/
|
|
||||||
private void tenantConfig(PaginationInterceptor paginationInterceptor){
|
|
||||||
/*
|
|
||||||
* 【测试多租户】 SQL 解析处理拦截器<br>
|
|
||||||
* 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
|
|
||||||
*/
|
|
||||||
List<ISqlParser> sqlParserList = new ArrayList<>();
|
|
||||||
TenantSqlParser tenantSqlParser = new JeroTenantParser();
|
|
||||||
tenantSqlParser.setTenantHandler(new TenantHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression getTenantId(boolean select) {
|
|
||||||
String tenant_id = oConvertUtils.getString(TenantContext.getTenant(),"0");
|
|
||||||
return new LongValue(tenant_id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String getTenantIdColumn() {
|
|
||||||
return tenant_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean doTableFilter(String tableName) {
|
|
||||||
//true则不加租户条件查询 false则加
|
|
||||||
// return excludeTable.contains(tableName);
|
|
||||||
if(tenantTable.contains(tableName)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Expression in(String ids){
|
|
||||||
final InExpression inExpression = new InExpression();
|
|
||||||
inExpression.setLeftExpression(new Column(getTenantIdColumn()));
|
|
||||||
final ExpressionList itemsList = new ExpressionList();
|
|
||||||
final List<Expression> inValues = new ArrayList<>(2);
|
|
||||||
for(String id:ids.split(",")){
|
|
||||||
inValues.add(new LongValue(id));
|
|
||||||
}
|
|
||||||
itemsList.setExpressions(inValues);
|
|
||||||
inExpression.setRightItemsList(itemsList);
|
|
||||||
return inExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
sqlParserList.add(tenantSqlParser);
|
|
||||||
paginationInterceptor.setSqlParserList(sqlParserList);
|
|
||||||
paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean doFilter(MetaObject metaObject) {
|
|
||||||
String sql = (String) metaObject.getValue(PluginUtils.DELEGATE_BOUNDSQL_SQL);
|
|
||||||
for(String tableName: tenantTable){
|
|
||||||
String sql_lowercase = sql.toLowerCase();
|
|
||||||
if(sql_lowercase.indexOf(tableName.toLowerCase())>=0){
|
|
||||||
for(String key: DDL_KEYWORD){
|
|
||||||
if(sql_lowercase.indexOf(key)>=0){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*if ("mapper路径.方法名".equals(ms.getId())) {
|
|
||||||
//使用这种判断也可以避免走此过滤器
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// /**
|
|
||||||
// * mybatis-plus SQL执行效率插件【生产环境可以关闭】
|
|
||||||
// */
|
|
||||||
// @Bean
|
|
||||||
// public PerformanceInterceptor performanceInterceptor() {
|
|
||||||
// return new PerformanceInterceptor();
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
package com.jero.config.mybatis;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
|
import net.sf.jsqlparser.expression.LongValue;
|
||||||
|
import com.jero.common.util.oConvertUtils;
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单数据源配置(jero.datasource.open = false时生效)
|
||||||
|
* @Author zhoujf
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@MapperScan(value={"com.jero.**.mapper*"})
|
||||||
|
public class MybatisPlusSaasConfig {
|
||||||
|
/**
|
||||||
|
* tenant_id 字段名
|
||||||
|
*/
|
||||||
|
private static final String TENANT_FIELD_NAME = "tenant_id";
|
||||||
|
/**
|
||||||
|
* 哪些表需要做多租户 表需要添加一个字段 tenant_id
|
||||||
|
*/
|
||||||
|
private static final List<String> tenantTable = new ArrayList<String>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
tenantTable.add("demo");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
|
// 先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
|
||||||
|
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
|
||||||
|
@Override
|
||||||
|
public Expression getTenantId() {
|
||||||
|
String tenant_id = oConvertUtils.getString(TenantContext.getTenant(),"0");
|
||||||
|
return new LongValue(tenant_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTenantIdColumn(){
|
||||||
|
return TENANT_FIELD_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回 true 表示不走租户逻辑
|
||||||
|
@Override
|
||||||
|
public boolean ignoreTable(String tableName) {
|
||||||
|
for(String temp: tenantTable){
|
||||||
|
if(temp.equalsIgnoreCase(tableName)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||||
|
return interceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-112
@@ -1,112 +0,0 @@
|
|||||||
package com.jero.config.redis;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import com.jero.common.constant.CacheConstant;
|
|
||||||
import org.springframework.cache.CacheManager;
|
|
||||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
|
||||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
|
||||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.data.redis.serializer.*;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开启缓存支持
|
|
||||||
* @Return:
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@EnableCaching
|
|
||||||
@Configuration
|
|
||||||
public class RedisConfig extends CachingConfigurerSupport {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private LettuceConnectionFactory lettuceConnectionFactory;
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @description 自定义的缓存key的生成策略 若想使用这个key
|
|
||||||
// * 只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
|
|
||||||
// * @return 自定义策略生成的key
|
|
||||||
// */
|
|
||||||
// @Override
|
|
||||||
// @Bean
|
|
||||||
// public KeyGenerator keyGenerator() {
|
|
||||||
// return new KeyGenerator() {
|
|
||||||
// @Override
|
|
||||||
// public Object generate(Object target, Method method, Object... params) {
|
|
||||||
// StringBuilder sb = new StringBuilder();
|
|
||||||
// sb.append(target.getClass().getName());
|
|
||||||
// sb.append(method.getDeclaringClass().getName());
|
|
||||||
// Arrays.stream(params).map(Object::toString).forEach(sb::append);
|
|
||||||
// return sb.toString();
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RedisTemplate配置
|
|
||||||
*
|
|
||||||
* @param lettuceConnectionFactory
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
|
||||||
log.info(" --- redis config init --- ");
|
|
||||||
// 设置序列化
|
|
||||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
|
|
||||||
ObjectMapper om = new ObjectMapper();
|
|
||||||
om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
|
|
||||||
om.enableDefaultTyping(DefaultTyping.NON_FINAL);
|
|
||||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
|
||||||
// 配置redisTemplate
|
|
||||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
|
||||||
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
|
||||||
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
|
|
||||||
redisTemplate.setKeySerializer(stringSerializer);// key序列化
|
|
||||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
|
|
||||||
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
|
|
||||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
|
|
||||||
redisTemplate.afterPropertiesSet();
|
|
||||||
return redisTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存配置管理器
|
|
||||||
*
|
|
||||||
* @param factory
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public CacheManager cacheManager(LettuceConnectionFactory factory) {
|
|
||||||
// 配置序列化(缓存默认有效期 6小时)
|
|
||||||
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
|
|
||||||
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
|
||||||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
|
|
||||||
|
|
||||||
// 以锁写入的方式创建RedisCacheWriter对象
|
|
||||||
//RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
|
|
||||||
// 创建默认缓存配置对象
|
|
||||||
/* 默认配置,设置缓存有效期 1小时*/
|
|
||||||
//RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
|
|
||||||
/* 自定义配置test:demo 的超时时间为 5分钟*/
|
|
||||||
RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(factory)).cacheDefaults(redisCacheConfiguration)
|
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
|
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_RANKING, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
|
||||||
.withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_PAGE_LIST, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues()))
|
|
||||||
.transactionAware().build();
|
|
||||||
return cacheManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+17
-8
@@ -1,6 +1,7 @@
|
|||||||
package com.jero.config.shiro;
|
package com.jero.config.shiro;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||||
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
|
||||||
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
import org.apache.shiro.mgt.DefaultSubjectDAO;
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
@@ -57,7 +58,7 @@ public class ShiroConfig {
|
|||||||
* 2、当设置多个过滤器时,全部验证通过,才视为通过
|
* 2、当设置多个过滤器时,全部验证通过,才视为通过
|
||||||
* 3、部分过滤器可指定参数,如perms,roles
|
* 3、部分过滤器可指定参数,如perms,roles
|
||||||
*/
|
*/
|
||||||
@Bean("shiroFilter")
|
@Bean("shiroFilterFactoryBean")
|
||||||
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
|
||||||
CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean();
|
CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean();
|
||||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||||
@@ -83,7 +84,6 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
|
filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
|
||||||
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
|
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
|
||||||
filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册
|
filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册
|
||||||
filterChainDefinitionMap.put("/sys/user/querySysUser", "anon");//根据手机号获取用户信息
|
|
||||||
filterChainDefinitionMap.put("/sys/user/phoneVerification", "anon");//用户忘记密码验证手机号
|
filterChainDefinitionMap.put("/sys/user/phoneVerification", "anon");//用户忘记密码验证手机号
|
||||||
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
|
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
|
||||||
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
|
||||||
@@ -101,6 +101,7 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/**/*.png", "anon");
|
filterChainDefinitionMap.put("/**/*.png", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.ico", "anon");
|
filterChainDefinitionMap.put("/**/*.ico", "anon");
|
||||||
|
|
||||||
|
//排除字体格式的后缀
|
||||||
filterChainDefinitionMap.put("/**/*.ttf", "anon");
|
filterChainDefinitionMap.put("/**/*.ttf", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.woff", "anon");
|
filterChainDefinitionMap.put("/**/*.woff", "anon");
|
||||||
filterChainDefinitionMap.put("/**/*.woff2", "anon");
|
filterChainDefinitionMap.put("/**/*.woff2", "anon");
|
||||||
@@ -128,14 +129,13 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
|
||||||
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
||||||
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
||||||
filterChainDefinitionMap.put("/eoaSocket/**","anon");//我的聊天
|
|
||||||
|
|
||||||
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
|
//性能监控
|
||||||
filterChainDefinitionMap.put("/actuator/**", "anon");
|
filterChainDefinitionMap.put("/actuator/**", "anon");
|
||||||
|
|
||||||
// 添加自己的过滤器并且取名为jwt
|
// 添加自己的过滤器并且取名为jwt
|
||||||
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
|
||||||
//如果cloudServer为空 则说明是单体 需要加载跨域配置
|
//如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】
|
||||||
Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY);
|
Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY);
|
||||||
filterMap.put("jwt", new JwtFilter(cloudServer==null));
|
filterMap.put("jwt", new JwtFilter(cloudServer==null));
|
||||||
shiroFilterFactoryBean.setFilters(filterMap);
|
shiroFilterFactoryBean.setFilters(filterMap);
|
||||||
@@ -238,12 +238,21 @@ public class ShiroConfig {
|
|||||||
}
|
}
|
||||||
manager = redisManager;
|
manager = redisManager;
|
||||||
}else{
|
}else{
|
||||||
// redis 集群支持,优先使用集群配置 add by jzyadmin@163.com
|
// redis集群支持,优先使用集群配置
|
||||||
RedisClusterManager redisManager = new RedisClusterManager();
|
RedisClusterManager redisManager = new RedisClusterManager();
|
||||||
Set<HostAndPort> portSet = new HashSet<>();
|
Set<HostAndPort> portSet = new HashSet<>();
|
||||||
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
|
||||||
JedisCluster jedisCluster = new JedisCluster(portSet);
|
//update-begin--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||||
redisManager.setJedisCluster(jedisCluster);
|
if (oConvertUtils.isNotEmpty(lettuceConnectionFactory.getPassword())) {
|
||||||
|
JedisCluster jedisCluster = new JedisCluster(portSet, 2000, 2000, 5,
|
||||||
|
lettuceConnectionFactory.getPassword(), new GenericObjectPoolConfig());
|
||||||
|
redisManager.setPassword(lettuceConnectionFactory.getPassword());
|
||||||
|
redisManager.setJedisCluster(jedisCluster);
|
||||||
|
} else {
|
||||||
|
JedisCluster jedisCluster = new JedisCluster(portSet);
|
||||||
|
redisManager.setJedisCluster(jedisCluster);
|
||||||
|
}
|
||||||
|
//update-end--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
|
||||||
manager = redisManager;
|
manager = redisManager;
|
||||||
}
|
}
|
||||||
return manager;
|
return manager;
|
||||||
|
|||||||
+12
-1
@@ -18,6 +18,7 @@ import com.jero.common.system.vo.LoginUser;
|
|||||||
import com.jero.common.util.RedisUtil;
|
import com.jero.common.util.RedisUtil;
|
||||||
import com.jero.common.util.SpringContextUtils;
|
import com.jero.common.util.SpringContextUtils;
|
||||||
import com.jero.common.util.oConvertUtils;
|
import com.jero.common.util.oConvertUtils;
|
||||||
|
import com.jero.config.mybatis.TenantContext;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -126,7 +127,17 @@ public class ShiroRealm extends AuthorizingRealm {
|
|||||||
if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {
|
if (!jwtTokenRefresh(token, username, loginUser.getPassword())) {
|
||||||
throw new AuthenticationException("Token失效,请重新登录!");
|
throw new AuthenticationException("Token失效,请重新登录!");
|
||||||
}
|
}
|
||||||
|
//update-begin-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
||||||
|
String userTenantIds = loginUser.getRelTenantIds();
|
||||||
|
if(oConvertUtils.isNotEmpty(userTenantIds)){
|
||||||
|
String contextTenantId = TenantContext.getTenant();
|
||||||
|
if(oConvertUtils.isNotEmpty(contextTenantId) && !"0".equals(contextTenantId)){
|
||||||
|
if(String.join(",",userTenantIds).indexOf(contextTenantId)<0){
|
||||||
|
throw new AuthenticationException("用户租户信息变更,请重新登陆!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
|
||||||
return loginUser;
|
return loginUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -1,5 +1,6 @@
|
|||||||
package com.jero.config.shiro.filters;
|
package com.jero.config.shiro.filters;
|
||||||
|
|
||||||
|
import com.jero.common.util.oConvertUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||||
@@ -22,6 +23,10 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class JwtFilter extends BasicHttpAuthenticationFilter {
|
public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认开启跨域设置(使用单体)
|
||||||
|
* 微服务情况下,此属性设置为false
|
||||||
|
*/
|
||||||
private boolean allowOrigin = true;
|
private boolean allowOrigin = true;
|
||||||
|
|
||||||
public JwtFilter(){}
|
public JwtFilter(){}
|
||||||
@@ -55,7 +60,7 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
|
|||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||||
// update-begin--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
// update-begin--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
||||||
if(token == null){
|
if (oConvertUtils.isEmpty(token)) {
|
||||||
token = httpServletRequest.getParameter("token");
|
token = httpServletRequest.getParameter("token");
|
||||||
}
|
}
|
||||||
// update-end--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
// update-end--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package com.jero.config.sign.interceptor;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名 拦截器配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SignAuthConfiguration implements WebMvcConfigurer {
|
||||||
|
public static String[] urlList = new String[] {"/sys/dict/getDictItems/*", "/sys/dict/loadDict/*",
|
||||||
|
"/sys/dict/loadDictOrderByValue/*", "/sys/dict/loadDictItem/*", "/sys/dict/loadTreeData",
|
||||||
|
"/sys/api/queryTableDictItemsByCode", "/sys/api/queryFilterTableDictInfo", "/sys/api/queryTableDictByKeys",
|
||||||
|
"/sys/api/translateDictFromTable", "/sys/api/translateDictFromTableByKeys"};
|
||||||
|
@Bean
|
||||||
|
public SignAuthInterceptor signAuthInterceptor() {
|
||||||
|
return new SignAuthInterceptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(signAuthInterceptor()).addPathPatterns(urlList);
|
||||||
|
}
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
package com.jero.config.sign.interceptor;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.jero.common.api.vo.Result;
|
||||||
|
import com.jero.common.constant.CommonConstant;
|
||||||
|
import com.jero.common.util.DateUtils;
|
||||||
|
import com.jero.config.sign.util.BodyReaderHttpServletRequestWrapper;
|
||||||
|
import com.jero.config.sign.util.HttpUtils;
|
||||||
|
import com.jero.config.sign.util.SignUtil;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名拦截器
|
||||||
|
* @author qinfeng
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SignAuthInterceptor implements HandlerInterceptor {
|
||||||
|
/**
|
||||||
|
* 5分钟有效期
|
||||||
|
*/
|
||||||
|
private final static long MAX_EXPIRE = 5 * 60;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
log.info("request URI = " + request.getRequestURI());
|
||||||
|
HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
|
||||||
|
//获取全部参数(包括URL和body上的)
|
||||||
|
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestWrapper);
|
||||||
|
//对参数进行签名验证
|
||||||
|
String headerSign = request.getHeader(CommonConstant.X_SIGN);
|
||||||
|
String timesTamp = request.getHeader(CommonConstant.X_TIMESTAMP);
|
||||||
|
|
||||||
|
//1.校验时间有消息
|
||||||
|
try {
|
||||||
|
DateUtils.parseDate(timesTamp, "yyyyMMddHHmmss");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP格式必须为:yyyyMMddHHmmss");
|
||||||
|
}
|
||||||
|
Long clientTimestamp = Long.parseLong(timesTamp);
|
||||||
|
//判断时间戳 timestamp=201808091113
|
||||||
|
if ((DateUtils.getCurrentTimestamp() - clientTimestamp) > MAX_EXPIRE) {
|
||||||
|
throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
//2.校验签名
|
||||||
|
boolean isSigned = SignUtil.verifySign(allParams,headerSign);
|
||||||
|
|
||||||
|
if (isSigned) {
|
||||||
|
log.debug("Sign 签名通过!Header Sign : {}",headerSign);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("request URI = " + request.getRequestURI());
|
||||||
|
log.error("Sign 签名校验失败!Header Sign : {}",headerSign);
|
||||||
|
//校验失败返回前端
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setContentType("application/json; charset=utf-8");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
Result<?> result = Result.error("Sign签名校验失败!");
|
||||||
|
out.print(JSON.toJSON(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
package com.jero.config.sign.util;
|
||||||
|
|
||||||
|
import javax.servlet.ReadListener;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存过滤器里面的流
|
||||||
|
*
|
||||||
|
* @author jero
|
||||||
|
* @date 20210621
|
||||||
|
*/
|
||||||
|
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
|
||||||
|
private final byte[] body;
|
||||||
|
|
||||||
|
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
|
||||||
|
|
||||||
|
super(request);
|
||||||
|
String sessionStream = getBodyString(request);
|
||||||
|
body = sessionStream.getBytes(Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求Body
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getBodyString(final ServletRequest request) {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
try (InputStream inputStream = cloneInputStream(request.getInputStream());
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description: 复制输入流</br>
|
||||||
|
*
|
||||||
|
* @param inputStream
|
||||||
|
* @return</br>
|
||||||
|
*/
|
||||||
|
public InputStream cloneInputStream(ServletInputStream inputStream) {
|
||||||
|
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len;
|
||||||
|
try {
|
||||||
|
while ((len = inputStream.read(buffer)) > -1) {
|
||||||
|
byteArrayOutputStream.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
byteArrayOutputStream.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedReader getReader() {
|
||||||
|
|
||||||
|
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServletInputStream getInputStream() {
|
||||||
|
|
||||||
|
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||||
|
return new ServletInputStream() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() {
|
||||||
|
|
||||||
|
return bais.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadListener(ReadListener readListener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+184
@@ -0,0 +1,184 @@
|
|||||||
|
package com.jero.config.sign.util;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import com.jero.common.util.oConvertUtils;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http 工具类 获取请求中的参数
|
||||||
|
*
|
||||||
|
* @author jeecg
|
||||||
|
* @date 20210621
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class HttpUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将URL的参数和body参数合并
|
||||||
|
*
|
||||||
|
* @author jeecg
|
||||||
|
* @date 20210621
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public static SortedMap<String, String> getAllParams(HttpServletRequest request) throws IOException {
|
||||||
|
|
||||||
|
SortedMap<String, String> result = new TreeMap<>();
|
||||||
|
// 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username
|
||||||
|
String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);
|
||||||
|
if (pathVariable.contains(",")) {
|
||||||
|
log.info(" pathVariable: {}",pathVariable);
|
||||||
|
String deString = URLDecoder.decode(pathVariable, "UTF-8");
|
||||||
|
log.info(" pathVariable decode: {}",deString);
|
||||||
|
result.put(SignUtil.xPathVariable, deString);
|
||||||
|
}
|
||||||
|
// 获取URL上的参数
|
||||||
|
Map<String, String> urlParams = getUrlParams(request);
|
||||||
|
for (Map.Entry entry : urlParams.entrySet()) {
|
||||||
|
result.put((String)entry.getKey(), (String)entry.getValue());
|
||||||
|
}
|
||||||
|
Map<String, String> allRequestParam = new HashMap<>(16);
|
||||||
|
// get请求不需要拿body参数
|
||||||
|
if (!HttpMethod.GET.name().equals(request.getMethod())) {
|
||||||
|
allRequestParam = getAllRequestParam(request);
|
||||||
|
}
|
||||||
|
// 将URL的参数和body参数进行合并
|
||||||
|
if (allRequestParam != null) {
|
||||||
|
for (Map.Entry entry : allRequestParam.entrySet()) {
|
||||||
|
result.put((String)entry.getKey(), (String)entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将URL的参数和body参数合并
|
||||||
|
*
|
||||||
|
* @author jeecg
|
||||||
|
* @date 20210621
|
||||||
|
* @param queryString
|
||||||
|
*/
|
||||||
|
public static SortedMap<String, String> getAllParams(String url, String queryString, byte[] body, String method)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
SortedMap<String, String> result = new TreeMap<>();
|
||||||
|
// 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username
|
||||||
|
String pathVariable = url.substring(url.lastIndexOf("/") + 1);
|
||||||
|
if (pathVariable.contains(",")) {
|
||||||
|
log.info(" pathVariable: {}",pathVariable);
|
||||||
|
String deString = URLDecoder.decode(pathVariable, "UTF-8");
|
||||||
|
log.info(" pathVariable decode: {}",deString);
|
||||||
|
result.put(SignUtil.xPathVariable, deString);
|
||||||
|
}
|
||||||
|
// 获取URL上的参数
|
||||||
|
Map<String, String> urlParams = getUrlParams(queryString);
|
||||||
|
for (Map.Entry entry : urlParams.entrySet()) {
|
||||||
|
result.put((String)entry.getKey(), (String)entry.getValue());
|
||||||
|
}
|
||||||
|
Map<String, String> allRequestParam = new HashMap<>(16);
|
||||||
|
// get请求不需要拿body参数
|
||||||
|
if (!HttpMethod.GET.name().equals(method)) {
|
||||||
|
allRequestParam = getAllRequestParam(body);
|
||||||
|
}
|
||||||
|
// 将URL的参数和body参数进行合并
|
||||||
|
if (allRequestParam != null) {
|
||||||
|
for (Map.Entry entry : allRequestParam.entrySet()) {
|
||||||
|
result.put((String)entry.getKey(), (String)entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Body 参数
|
||||||
|
*
|
||||||
|
* @date 15:04 20210621
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getAllRequestParam(final HttpServletRequest request) throws IOException {
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
|
||||||
|
String str = "";
|
||||||
|
StringBuilder wholeStr = new StringBuilder();
|
||||||
|
// 一行一行的读取body体里面的内容;
|
||||||
|
while ((str = reader.readLine()) != null) {
|
||||||
|
wholeStr.append(str);
|
||||||
|
}
|
||||||
|
// 转化成json对象
|
||||||
|
return JSONObject.parseObject(wholeStr.toString(), Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Body 参数
|
||||||
|
*
|
||||||
|
* @date 15:04 20210621
|
||||||
|
* @param body
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getAllRequestParam(final byte[] body) throws IOException {
|
||||||
|
if(body==null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String wholeStr = new String(body);
|
||||||
|
// 转化成json对象
|
||||||
|
return JSONObject.parseObject(wholeStr.toString(), Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将URL请求参数转换成Map
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getUrlParams(HttpServletRequest request) {
|
||||||
|
Map<String, String> result = new HashMap<>(16);
|
||||||
|
if (oConvertUtils.isEmpty(request.getQueryString())) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
String param = "";
|
||||||
|
try {
|
||||||
|
param = URLDecoder.decode(request.getQueryString(), "utf-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String[] params = param.split("&");
|
||||||
|
for (String s : params) {
|
||||||
|
int index = s.indexOf("=");
|
||||||
|
result.put(s.substring(0, index), s.substring(index + 1));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将URL请求参数转换成Map
|
||||||
|
*
|
||||||
|
* @param queryString
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getUrlParams(String queryString) {
|
||||||
|
Map<String, String> result = new HashMap<>(16);
|
||||||
|
if (oConvertUtils.isEmpty(queryString)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
String param = "";
|
||||||
|
try {
|
||||||
|
param = URLDecoder.decode(queryString, "utf-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String[] params = param.split("&");
|
||||||
|
for (String s : params) {
|
||||||
|
int index = s.indexOf("=");
|
||||||
|
result.put(s.substring(0, index), s.substring(index + 1));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package com.jero.config.sign.util;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import com.jero.common.exception.JeroBootException;
|
||||||
|
import com.jero.common.util.SpringContextUtils;
|
||||||
|
import com.jero.common.util.oConvertUtils;
|
||||||
|
import com.jero.config.StaticConfig;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.SortedMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名工具类
|
||||||
|
*
|
||||||
|
* @author jeecg
|
||||||
|
* @date 20210621
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SignUtil {
|
||||||
|
public static final String xPathVariable = "x-path-variable";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param params
|
||||||
|
* 所有的请求参数都会在这里进行排序加密
|
||||||
|
* @return 验证签名结果
|
||||||
|
*/
|
||||||
|
public static boolean verifySign(SortedMap<String, String> params,String headerSign) {
|
||||||
|
if (params == null || StringUtils.isEmpty(headerSign)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 把参数加密
|
||||||
|
String paramsSign = getParamsSign(params);
|
||||||
|
log.info("Param Sign : {}", paramsSign);
|
||||||
|
return !StringUtils.isEmpty(paramsSign) && headerSign.equals(paramsSign);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param params
|
||||||
|
* 所有的请求参数都会在这里进行排序加密
|
||||||
|
* @return 得到签名
|
||||||
|
*/
|
||||||
|
public static String getParamsSign(SortedMap<String, String> params) {
|
||||||
|
//去掉 Url 里的时间戳
|
||||||
|
params.remove("_t");
|
||||||
|
String paramsJsonStr = JSONObject.toJSONString(params);
|
||||||
|
log.info("Param paramsJsonStr : {}", paramsJsonStr);
|
||||||
|
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||||
|
String signatureSecret = staticConfig.getSignatureSecret();
|
||||||
|
if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains("${")){
|
||||||
|
throw new JeroBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 !!");
|
||||||
|
}
|
||||||
|
return DigestUtils.md5DigestAsHex((paramsJsonStr + signatureSecret).getBytes()).toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
package com.jero.modules.base.mapper;
|
package com.jero.modules.base.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.SqlParser;
|
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import com.jero.common.api.dto.LogDTO;
|
import com.jero.common.api.dto.LogDTO;
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ public interface BaseCommonMapper {
|
|||||||
* 保存日志
|
* 保存日志
|
||||||
* @param dto
|
* @param dto
|
||||||
*/
|
*/
|
||||||
@SqlParser(filter=true)
|
@InterceptorIgnore(illegalSql = "true", tenantLine = "true")
|
||||||
void saveLog(@Param("dto")LogDTO dto);
|
void saveLog(@Param("dto")LogDTO dto);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>jero-boot-base</artifactId>
|
<artifactId>jero-boot-base</artifactId>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<description>代码生成核心模块</description>
|
<description>代码生成核心模块</description>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>jero-boot-base</artifactId>
|
<artifactId>jero-boot-base</artifactId>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -17,10 +17,23 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-system-local-api</artifactId>
|
<artifactId>jero-system-local-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-collections</groupId>
|
||||||
|
<artifactId>commons-collections</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
+1
-1
@@ -10,7 +10,7 @@ import java.io.Serializable;
|
|||||||
public class OnlCgformButton implements Serializable {
|
public class OnlCgformButton implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import java.io.Serializable;
|
|||||||
public class OnlCgformEnhanceJava implements Serializable {
|
public class OnlCgformEnhanceJava implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import java.io.Serializable;
|
|||||||
public class OnlCgformEnhanceJs implements Serializable {
|
public class OnlCgformEnhanceJs implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import java.io.Serializable;
|
|||||||
public class OnlCgformEnhanceSql implements Serializable {
|
public class OnlCgformEnhanceSql implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.springframework.format.annotation.DateTimeFormat;
|
|||||||
public class OnlCgformField implements Serializable {
|
public class OnlCgformField implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.springframework.format.annotation.DateTimeFormat;
|
|||||||
public class OnlCgformHead implements Serializable {
|
public class OnlCgformHead implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String tableName;
|
private String tableName;
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.springframework.format.annotation.DateTimeFormat;
|
|||||||
public class OnlCgformIndex implements Serializable {
|
public class OnlCgformIndex implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@TableId(
|
@TableId(
|
||||||
type = IdType.UUID
|
type = IdType.ASSIGN_UUID
|
||||||
)
|
)
|
||||||
private String id;
|
private String id;
|
||||||
private String cgformHeadId;
|
private String cgformHeadId;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-boot-base</artifactId>
|
<artifactId>jero-boot-base</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<description>公共模块</description>
|
<description>公共模块</description>
|
||||||
@@ -17,6 +17,15 @@
|
|||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Redis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
<!--加载hutool-->
|
<!--加载hutool-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.jero.common.config.mqtoken;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放token到上下文供队列调用feign使用
|
||||||
|
* @author zyf
|
||||||
|
*/
|
||||||
|
public class TransmitUserTokenFilter implements Filter {
|
||||||
|
|
||||||
|
private static String X_ACCESS_TOKEN="X-Access-Token";
|
||||||
|
|
||||||
|
public TransmitUserTokenFilter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
this.initUserInfo((HttpServletRequest) request);
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initUserInfo(HttpServletRequest request) {
|
||||||
|
String token = request.getHeader(X_ACCESS_TOKEN);
|
||||||
|
if (token!=null) {
|
||||||
|
try {
|
||||||
|
//将token放入上下文中
|
||||||
|
UserTokenContext.setToken(token);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.jero.common.config.mqtoken;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户token上下文
|
||||||
|
* @author zyf
|
||||||
|
*/
|
||||||
|
public class UserTokenContext {
|
||||||
|
|
||||||
|
private static ThreadLocal<String> userToken = new ThreadLocal<String>();
|
||||||
|
|
||||||
|
public UserTokenContext() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getToken(){
|
||||||
|
return userToken.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setToken(String token){
|
||||||
|
userToken.set(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-3
@@ -8,13 +8,18 @@ package com.jero.common.constant;
|
|||||||
public interface CacheConstant {
|
public interface CacheConstant {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典信息缓存
|
* 字典信息缓存(含禁用的字典项)
|
||||||
*/
|
*/
|
||||||
public static final String SYS_DICT_CACHE = "sys:cache:dict";
|
public static final String SYS_DICT_CACHE = "sys:cache:dict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典信息缓存 status为有效的
|
||||||
|
*/
|
||||||
|
public static final String SYS_ENABLE_DICT_CACHE = "sys:cache:dictEnable";
|
||||||
/**
|
/**
|
||||||
* 表字典信息缓存
|
* 表字典信息缓存
|
||||||
*/
|
*/
|
||||||
public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable";
|
public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable";
|
||||||
public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys";
|
public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
+2
-14
@@ -1,4 +1,4 @@
|
|||||||
package com.jero.boot.starter.redis.client;
|
package com.jero.common.modules.redis.client;
|
||||||
|
|
||||||
import com.jero.common.base.BaseMap;
|
import com.jero.common.base.BaseMap;
|
||||||
import com.jero.common.constant.GlobalConstants;
|
import com.jero.common.constant.GlobalConstants;
|
||||||
@@ -6,7 +6,6 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redis客户端
|
* redis客户端
|
||||||
@@ -14,7 +13,7 @@ import java.util.Map;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class JeroRedisClient {
|
public class JeroRedisClient {
|
||||||
|
|
||||||
@Resource(name = "starterRedisTemplate")
|
@Resource
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
|
||||||
@@ -30,15 +29,4 @@ public class JeroRedisClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据key查询缓存
|
|
||||||
*
|
|
||||||
* @param key 键
|
|
||||||
* @return 值
|
|
||||||
*/
|
|
||||||
public <T> T get(String key) {
|
|
||||||
return key == null ? null : (T) redisTemplate.opsForValue().get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+152
@@ -0,0 +1,152 @@
|
|||||||
|
package com.jero.common.modules.redis.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import com.jero.common.constant.CacheConstant;
|
||||||
|
import com.jero.common.constant.GlobalConstants;
|
||||||
|
import com.jero.common.modules.redis.receiver.RedisReceiver;
|
||||||
|
import com.jero.common.modules.redis.writer.JeroRedisCacheWriter;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.listener.ChannelTopic;
|
||||||
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||||
|
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
|
||||||
|
import org.springframework.data.redis.serializer.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启缓存支持
|
||||||
|
* @author zyf
|
||||||
|
* @Return:
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@EnableCaching
|
||||||
|
@Configuration
|
||||||
|
public class RedisConfig extends CachingConfigurerSupport {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LettuceConnectionFactory lettuceConnectionFactory;
|
||||||
|
|
||||||
|
private GenericJackson2JsonRedisSerializer jacksonSerializer = new GenericJackson2JsonRedisSerializer();
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @description 自定义的缓存key的生成策略 若想使用这个key
|
||||||
|
// * 只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
|
||||||
|
// * @return 自定义策略生成的key
|
||||||
|
// */
|
||||||
|
// @Override
|
||||||
|
// @Bean
|
||||||
|
// public KeyGenerator keyGenerator() {
|
||||||
|
// return new KeyGenerator() {
|
||||||
|
// @Override
|
||||||
|
// public Object generate(Object target, Method method, Object... params) {
|
||||||
|
// StringBuilder sb = new StringBuilder();
|
||||||
|
// sb.append(target.getClass().getName());
|
||||||
|
// sb.append(method.getDeclaringClass().getName());
|
||||||
|
// Arrays.stream(params).map(Object::toString).forEach(sb::append);
|
||||||
|
// return sb.toString();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RedisTemplate配置
|
||||||
|
* @param lettuceConnectionFactory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
|
||||||
|
log.info(" --- redis config init --- ");
|
||||||
|
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
|
||||||
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
|
||||||
|
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
|
||||||
|
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
|
||||||
|
|
||||||
|
// key序列化
|
||||||
|
redisTemplate.setKeySerializer(stringSerializer);
|
||||||
|
// value序列化
|
||||||
|
redisTemplate.setValueSerializer(this.jacksonSerializer);
|
||||||
|
// Hash key序列化
|
||||||
|
redisTemplate.setHashKeySerializer(stringSerializer);
|
||||||
|
// Hash value序列化
|
||||||
|
redisTemplate.setHashValueSerializer(this.jacksonSerializer);
|
||||||
|
redisTemplate.afterPropertiesSet();
|
||||||
|
return redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存配置管理器
|
||||||
|
*
|
||||||
|
* @param factory
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CacheManager cacheManager(LettuceConnectionFactory factory) {
|
||||||
|
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = jacksonSerializer();
|
||||||
|
// 配置序列化(解决乱码的问题),并且配置缓存默认有效期 6小时
|
||||||
|
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
|
||||||
|
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||||
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(this.jacksonSerializer));
|
||||||
|
//.disableCachingNullValues();
|
||||||
|
|
||||||
|
// 以锁写入的方式创建RedisCacheWriter对象
|
||||||
|
//update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
|
||||||
|
RedisCacheWriter writer = new JeroRedisCacheWriter(factory, Duration.ofMillis(50L));
|
||||||
|
// 创建默认缓存配置对象
|
||||||
|
RedisCacheManager cacheManager = RedisCacheManager.builder(writer).cacheDefaults(redisCacheConfiguration)
|
||||||
|
.withInitialCacheConfigurations(singletonMap(CacheConstant.SYS_DICT_TABLE_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)).disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(this.jacksonSerializer))))
|
||||||
|
.transactionAware().build();
|
||||||
|
//update-end-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符*
|
||||||
|
return cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redis 监听配置
|
||||||
|
*
|
||||||
|
* @param redisConnectionFactory redis 配置
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, RedisReceiver redisReceiver, MessageListenerAdapter commonListenerAdapter) {
|
||||||
|
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||||
|
container.setConnectionFactory(redisConnectionFactory);
|
||||||
|
container.addMessageListener(commonListenerAdapter, new ChannelTopic(GlobalConstants.REDIS_TOPIC_NAME));
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
MessageListenerAdapter commonListenerAdapter(RedisReceiver redisReceiver) {
|
||||||
|
MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(redisReceiver, "onMessage");
|
||||||
|
messageListenerAdapter.setSerializer(this.jacksonSerializer);
|
||||||
|
return messageListenerAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private Jackson2JsonRedisSerializer jacksonSerializer() {
|
||||||
|
// Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||||
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
//// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||||
|
// objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.EVERYTHING);
|
||||||
|
// jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||||
|
// return jackson2JsonRedisSerializer;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.jero.boot.starter.redis.listener;
|
package com.jero.common.modules.redis.listener;
|
||||||
|
|
||||||
import com.jero.common.base.BaseMap;
|
import com.jero.common.base.BaseMap;
|
||||||
|
|
||||||
+5
-2
@@ -1,14 +1,17 @@
|
|||||||
package com.jero.boot.starter.redis.service;
|
package com.jero.common.modules.redis.receiver;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.jero.common.modules.redis.listener.JeroRedisListerer;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import com.jero.boot.starter.redis.listener.JeroRedisListerer;
|
|
||||||
import com.jero.common.base.BaseMap;
|
import com.jero.common.base.BaseMap;
|
||||||
import com.jero.common.constant.GlobalConstants;
|
import com.jero.common.constant.GlobalConstants;
|
||||||
import com.jero.common.util.SpringContextHolder;
|
import com.jero.common.util.SpringContextHolder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zyf
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Data
|
@Data
|
||||||
public class RedisReceiver {
|
public class RedisReceiver {
|
||||||
+221
@@ -0,0 +1,221 @@
|
|||||||
|
package com.jero.common.modules.redis.writer;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.dao.PessimisticLockingFailureException;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnection;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
|
||||||
|
import org.springframework.data.redis.core.types.Expiration;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该类参照 DefaultRedisCacheWriter 重写了 remove 方法实现通配符*删除
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class JeroRedisCacheWriter implements RedisCacheWriter {
|
||||||
|
|
||||||
|
private final RedisConnectionFactory connectionFactory;
|
||||||
|
private final Duration sleepTime;
|
||||||
|
|
||||||
|
public JeroRedisCacheWriter(RedisConnectionFactory connectionFactory) {
|
||||||
|
this(connectionFactory, Duration.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JeroRedisCacheWriter(RedisConnectionFactory connectionFactory, Duration sleepTime) {
|
||||||
|
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
|
||||||
|
Assert.notNull(sleepTime, "SleepTime must not be null!");
|
||||||
|
this.connectionFactory = connectionFactory;
|
||||||
|
this.sleepTime = sleepTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
Assert.notNull(value, "Value must not be null!");
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
if (shouldExpireWithin(ttl)) {
|
||||||
|
connection.set(key, value, Expiration.from(ttl.toMillis(), TimeUnit.MILLISECONDS), SetOption.upsert());
|
||||||
|
} else {
|
||||||
|
connection.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] get(String name, byte[] key) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
return (byte[])this.execute(name, (connection) -> {
|
||||||
|
return connection.get(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
Assert.notNull(value, "Value must not be null!");
|
||||||
|
return (byte[])this.execute(name, (connection) -> {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doLock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object var7;
|
||||||
|
try {
|
||||||
|
boolean put;
|
||||||
|
if (shouldExpireWithin(ttl)) {
|
||||||
|
put = connection.set(key, value, Expiration.from(ttl), SetOption.ifAbsent());
|
||||||
|
} else {
|
||||||
|
put = connection.setNX(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!put) {
|
||||||
|
byte[] var11 = connection.get(key);
|
||||||
|
return var11;
|
||||||
|
}
|
||||||
|
|
||||||
|
var7 = null;
|
||||||
|
} finally {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte[])var7;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(String name, byte[] key) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(key, "Key must not be null!");
|
||||||
|
String keyString = new String(key);
|
||||||
|
log.info("redis remove key:" + keyString);
|
||||||
|
if(keyString!=null && keyString.endsWith("*")){
|
||||||
|
execute(name, connection -> {
|
||||||
|
// 获取某个前缀所拥有的所有的键,某个前缀开头,后面肯定是*
|
||||||
|
Set<byte[]> keys = connection.keys(key);
|
||||||
|
int delNum = 0;
|
||||||
|
for (byte[] keyByte : keys) {
|
||||||
|
delNum += connection.del(keyByte);
|
||||||
|
}
|
||||||
|
return delNum;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
return connection.del(new byte[][]{key});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clean(String name, byte[] pattern) {
|
||||||
|
Assert.notNull(name, "Name must not be null!");
|
||||||
|
Assert.notNull(pattern, "Pattern must not be null!");
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
boolean wasLocked = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
this.doLock(name, connection);
|
||||||
|
wasLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[][] keys = (byte[][])((Set)Optional.ofNullable(connection.keys(pattern)).orElse(Collections.emptySet())).toArray(new byte[0][]);
|
||||||
|
if (keys.length > 0) {
|
||||||
|
connection.del(keys);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (wasLocked && this.isLockingCacheWriter()) {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock(String name) {
|
||||||
|
this.execute(name, (connection) -> {
|
||||||
|
return this.doLock(name, connection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock(String name) {
|
||||||
|
this.executeLockFree((connection) -> {
|
||||||
|
this.doUnlock(name, connection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean doLock(String name, RedisConnection connection) {
|
||||||
|
return connection.setNX(createCacheLockKey(name), new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long doUnlock(String name, RedisConnection connection) {
|
||||||
|
return connection.del(new byte[][]{createCacheLockKey(name)});
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doCheckLock(String name, RedisConnection connection) {
|
||||||
|
return connection.exists(createCacheLockKey(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLockingCacheWriter() {
|
||||||
|
return !this.sleepTime.isZero() && !this.sleepTime.isNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T execute(String name, Function<RedisConnection, T> callback) {
|
||||||
|
RedisConnection connection = this.connectionFactory.getConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.checkAndPotentiallyWaitUntilUnlocked(name, connection);
|
||||||
|
return callback.apply(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeLockFree(Consumer<RedisConnection> callback) {
|
||||||
|
RedisConnection connection = this.connectionFactory.getConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
callback.accept(connection);
|
||||||
|
} finally {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndPotentiallyWaitUntilUnlocked(String name, RedisConnection connection) {
|
||||||
|
if (this.isLockingCacheWriter()) {
|
||||||
|
try {
|
||||||
|
while(this.doCheckLock(name, connection)) {
|
||||||
|
Thread.sleep(this.sleepTime.toMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException var4) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new PessimisticLockingFailureException(String.format("Interrupted while waiting to unlock cache %s", name), var4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldExpireWithin(@Nullable Duration ttl) {
|
||||||
|
return ttl != null && !ttl.isZero() && !ttl.isNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] createCacheLockKey(String name) {
|
||||||
|
return (name + "~lock").getBytes(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
-1
@@ -6,7 +6,6 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.jero.common.exception.JeroBootException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.*;
|
import org.springframework.data.redis.core.*;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-boot</artifactId>
|
<artifactId>jero-boot</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-boot</artifactId>
|
<artifactId>jero-boot</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -16,17 +16,14 @@
|
|||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-system-local-api</artifactId>
|
<artifactId>jero-system-local-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 如果需要微服务版本,则以上API注释,释放该API
|
<!--引入微服务启动依赖 starter
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
|
<artifactId>jero-boot-starter-cloud</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jero-system-cloud-api</artifactId>
|
<artifactId>jero-boot-starter-job</artifactId>
|
||||||
</dependency>
|
</dependency>-->
|
||||||
-->
|
|
||||||
<!-- 如果需要微服务版本,则引入微服务启动依赖 starter
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jero.boot</groupId>
|
|
||||||
<artifactId>jero-cloud-feign-config</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
+5
-1
@@ -107,7 +107,11 @@ public class MockController {
|
|||||||
public String getCabinetCountInfo() {
|
public String getCabinetCountInfo() {
|
||||||
return readJson("classpath:com/jero/modules/demo/mock/json/getCntrNoCountInfo.json");
|
return readJson("classpath:com/jero/modules/demo/mock/json/getCntrNoCountInfo.json");
|
||||||
}
|
}
|
||||||
|
@GetMapping(value = "/report/getTubiao")
|
||||||
|
public String getTubiao() {
|
||||||
|
return readJson("classpath:org/jero/modules/demo/mock/json/getTubiao.json");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实时磁盘监控
|
* 实时磁盘监控
|
||||||
* @param request
|
* @param request
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
{"data":
|
||||||
|
[
|
||||||
|
{"day": "星期一", "step": 1234, "assess": "良"},
|
||||||
|
{"day": "星期二", "step": 1884, "assess": "优"},
|
||||||
|
{"day": "星期三", "step": 1671, "assess": "良+"},
|
||||||
|
{"day": "星期四", "step": 2197, "assess": "优+"},
|
||||||
|
{"day": "星期五", "step": 1342, "assess": "中"},
|
||||||
|
{"day": "星期六", "step": 545, "assess": "差"},
|
||||||
|
{"day": "星期日", "step": 244, "assess": "极差"}
|
||||||
|
]}
|
||||||
+2
-17
@@ -149,7 +149,8 @@ public class JeroDemoController extends JeroController<JeroDemo, IJeroDemoServic
|
|||||||
public ModelAndView exportXls(HttpServletRequest request, JeroDemo jeroDemo) {
|
public ModelAndView exportXls(HttpServletRequest request, JeroDemo jeroDemo) {
|
||||||
//获取导出表格字段
|
//获取导出表格字段
|
||||||
String exportFields = JeroDemoService.getExportFields();
|
String exportFields = JeroDemoService.getExportFields();
|
||||||
return super.exportXls(request, jeroDemo, JeroDemo.class, "单表模型",exportFields);
|
//分sheet导出表格字段
|
||||||
|
return super.exportXlsSheet(request, jeroDemo, JeroDemo.class, "单表模型",exportFields,500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -280,20 +281,4 @@ public class JeroDemoController extends JeroController<JeroDemo, IJeroDemoServic
|
|||||||
IPage<JeroDemo> pageList = JeroDemoService.queryListWithPermission(pageSize, pageNo);
|
IPage<JeroDemo> pageList = JeroDemoService.queryListWithPermission(pageSize, pageNo);
|
||||||
return Result.OK(pageList);
|
return Result.OK(pageList);
|
||||||
}
|
}
|
||||||
/*----------------------------------------外部获取权限示例------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 测试MQ
|
|
||||||
// */
|
|
||||||
// @GetMapping(value = "/rabbitMqClientTest")
|
|
||||||
// public Result<?> rabbitMqClientTest(HttpServletRequest req) {
|
|
||||||
// BaseMap map = new BaseMap();
|
|
||||||
// map.put("orderId", RandomUtil.randomNumbers(10));
|
|
||||||
// rabbitMqClient.sendMessage("jero_place_order", map);
|
|
||||||
// rabbitMqClient.sendMessage("jero_place_order_time", map,10);
|
|
||||||
// return Result.OK();
|
|
||||||
// }
|
|
||||||
// @Autowired
|
|
||||||
// private RabbitMqClient rabbitMqClient;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -175,7 +175,7 @@ public class JoaDemoController {
|
|||||||
/**
|
/**
|
||||||
* 导出excel
|
* 导出excel
|
||||||
*
|
*
|
||||||
* @param requestFieldPresenceUtil
|
* @param request
|
||||||
* @param response
|
* @param response
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
|
|||||||
+3
@@ -75,4 +75,7 @@ public class JeroDemo extends JeroEntity implements Serializable {
|
|||||||
/** 个人简介 */
|
/** 个人简介 */
|
||||||
@ApiModelProperty(value = "个人简介")
|
@ApiModelProperty(value = "个人简介")
|
||||||
private java.lang.String content;
|
private java.lang.String content;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "租户ID")
|
||||||
|
private java.lang.Integer tenantId;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -22,13 +22,13 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 查询用户已授权字段 -->
|
<!-- 查询用户已授权字段 -->
|
||||||
<select id="queryUserAuth" resultType="java.lang.String">
|
<select id="queryUserAuth" resultType="java.lang.String">
|
||||||
select perms from sys_user_role sur,
|
select DISTINCT perms from sys_user_role sur,
|
||||||
sys_role_permission srp,
|
sys_role_permission srp,
|
||||||
sys_permission sp
|
sys_permission sp
|
||||||
where sur.role_id = srp.role_id
|
where sur.role_id = srp.role_id
|
||||||
and sp.id = srp.permission_id
|
and sp.id = srp.permission_id
|
||||||
and user_id = #{userId}
|
and sur.user_id = #{userId}
|
||||||
and sp.perms like concat(concat('%',#{permsPrefix}),'%')
|
and sp.perms like concat(concat('%',#{permsPrefix}),'%')
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -10,6 +10,6 @@ WORKDIR /jero-boot
|
|||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
ADD ./target/jero-boot-module-system-2.4.2.jar ./
|
ADD ./target/jero-boot-module-system-2.4.6.jar ./
|
||||||
|
|
||||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jero-boot-module-system-2.4.2.jar
|
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jero-boot-module-system-2.4.6.jar
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-boot</artifactId>
|
<artifactId>jero-boot</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>2.4.6</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<repository>
|
<repository>
|
||||||
<id>aliyun</id>
|
<id>aliyun</id>
|
||||||
<name>aliyun Repository</name>
|
<name>aliyun Repository</name>
|
||||||
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<repository>
|
<repository>
|
||||||
<id>jeecg</id>
|
<id>jeecg</id>
|
||||||
<name>jeecg Repository</name>
|
<name>jeecg Repository</name>
|
||||||
<url>http://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
|
||||||
<snapshots>
|
<snapshots>
|
||||||
<enabled>false</enabled>
|
<enabled>false</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
@@ -34,10 +34,6 @@
|
|||||||
<groupId>com.jero.boot</groupId>
|
<groupId>com.jero.boot</groupId>
|
||||||
<artifactId>jero-system-local-api</artifactId>
|
<artifactId>jero-system-local-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.jero.boot</groupId>
|
|
||||||
<artifactId>jero-boot-starter-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- 积木报表 -->
|
<!-- 积木报表 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jimureport</groupId>
|
<groupId>com.jimureport</groupId>
|
||||||
|
|||||||
+21
-5
@@ -2,6 +2,7 @@ package com.jero.config.jimureport;
|
|||||||
|
|
||||||
import com.jero.common.system.api.ISysBaseAPI;
|
import com.jero.common.system.api.ISysBaseAPI;
|
||||||
import com.jero.common.system.util.JwtUtil;
|
import com.jero.common.system.util.JwtUtil;
|
||||||
|
import com.jero.common.system.vo.SysUserCacheInfo;
|
||||||
import com.jero.common.util.RedisUtil;
|
import com.jero.common.util.RedisUtil;
|
||||||
import com.jero.common.util.TokenUtils;
|
import com.jero.common.util.TokenUtils;
|
||||||
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
|
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
|
||||||
@@ -10,13 +11,14 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义积木报表鉴权实现类(如果不进行自定义,则所有请求不做权限控制)
|
* 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
|
||||||
* 1.自定义获取登录token
|
* * 1.自定义获取登录token
|
||||||
* 2.自定义获取登录用户
|
* * 2.自定义获取登录用户
|
||||||
*/
|
*/
|
||||||
@Component
|
|
||||||
class JimuReportTokenService implements JmReportTokenServiceI {
|
class JimuReportTokenService implements JmReportTokenServiceI {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysBaseAPI sysBaseAPI;
|
private ISysBaseAPI sysBaseAPI;
|
||||||
@@ -38,4 +40,18 @@ class JimuReportTokenService implements JmReportTokenServiceI {
|
|||||||
public Boolean verifyToken(String token) {
|
public Boolean verifyToken(String token) {
|
||||||
return TokenUtils.verifyToken(token, sysBaseAPI, redisUtil);
|
return TokenUtils.verifyToken(token, sysBaseAPI, redisUtil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getUserInfo(String token) {
|
||||||
|
String username = JwtUtil.getUsername(token);
|
||||||
|
//此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
|
||||||
|
SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
//设置账号名
|
||||||
|
map.put(SYS_USER_CODE, userInfo.getSysUserCode());
|
||||||
|
//设置部门编码
|
||||||
|
map.put(SYS_ORG_CODE, userInfo.getSysOrgCode());
|
||||||
|
// 将所有信息存放至map 解析sql/api会根据map的键值解析
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+167
-62
@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
@@ -144,6 +145,16 @@ public class SystemAPIController {
|
|||||||
return sysBaseAPI.queryDictItemsByCode(code);
|
return sysBaseAPI.queryDictItemsByCode(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有效的数据字典
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/queryEnableDictItemsByCode")
|
||||||
|
List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code){
|
||||||
|
return sysBaseAPI.queryEnableDictItemsByCode(code);
|
||||||
|
}
|
||||||
|
|
||||||
/** 查询所有的父级字典,按照create_time排序 */
|
/** 查询所有的父级字典,按照create_time排序 */
|
||||||
@GetMapping("/queryAllDict")
|
@GetMapping("/queryAllDict")
|
||||||
List<DictModel> queryAllDict(){
|
List<DictModel> queryAllDict(){
|
||||||
@@ -159,18 +170,6 @@ public class SystemAPIController {
|
|||||||
return sysBaseAPI.queryAllDSysCategory();
|
return sysBaseAPI.queryAllDSysCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取表数据字典
|
|
||||||
* @param table
|
|
||||||
* @param text
|
|
||||||
* @param code
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GetMapping("/queryTableDictItemsByCode")
|
|
||||||
List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){
|
|
||||||
return sysBaseAPI.queryTableDictItemsByCode(table, text, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||||
* @return
|
* @return
|
||||||
@@ -180,34 +179,6 @@ public class SystemAPIController {
|
|||||||
return sysBaseAPI.queryAllDepartBackDictModel();
|
return sysBaseAPI.queryAllDepartBackDictModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询表字典 支持过滤数据
|
|
||||||
* @param table
|
|
||||||
* @param text
|
|
||||||
* @param code
|
|
||||||
* @param filterSql
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GetMapping("/queryFilterTableDictInfo")
|
|
||||||
List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){
|
|
||||||
return sysBaseAPI.queryFilterTableDictInfo(table, text, code, filterSql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询指定table的 text code 获取字典,包含text和value
|
|
||||||
* @param table
|
|
||||||
* @param text
|
|
||||||
* @param code
|
|
||||||
* @param keyArray
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@GetMapping("/queryTableDictByKeys")
|
|
||||||
public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){
|
|
||||||
return sysBaseAPI.queryTableDictByKeys(table, text, code, keyArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有角色 带参
|
* 获取所有角色 带参
|
||||||
* roleIds 默认选中角色
|
* roleIds 默认选中角色
|
||||||
@@ -448,19 +419,6 @@ public class SystemAPIController {
|
|||||||
return sysBaseAPI.getCacheUser(username);
|
return sysBaseAPI.getCacheUser(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 字典表的 翻译
|
|
||||||
* @param table
|
|
||||||
* @param text
|
|
||||||
* @param code
|
|
||||||
* @param key
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GetMapping("/translateDictFromTable")
|
|
||||||
public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){
|
|
||||||
return sysBaseAPI.translateDictFromTable(table, text, code, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 普通字典的翻译
|
* 普通字典的翻译
|
||||||
* @param code
|
* @param code
|
||||||
@@ -478,18 +436,18 @@ public class SystemAPIController {
|
|||||||
* @param usernames
|
* @param usernames
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/queryUsersByUsernames")
|
@RequestMapping("/queryUsersByUsernames")
|
||||||
List<JSONObject> queryUsersByUsernames(String usernames){
|
List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames){
|
||||||
return this.sysBaseAPI.queryUsersByUsernames(usernames);
|
return this.sysBaseAPI.queryUsersByUsernames(usernames);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 37根据多个用户id(逗号分隔),查询返回多个用户信息
|
* 37根据多个用户id(逗号分隔),查询返回多个用户信息
|
||||||
* @param usernames
|
* @param ids
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/queryUsersByIds")
|
@RequestMapping("/queryUsersByIds")
|
||||||
List<JSONObject> queryUsersByIds(String ids){
|
List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids){
|
||||||
return this.sysBaseAPI.queryUsersByIds(ids);
|
return this.sysBaseAPI.queryUsersByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,18 +457,18 @@ public class SystemAPIController {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/queryDepartsByOrgcodes")
|
@GetMapping("/queryDepartsByOrgcodes")
|
||||||
List<JSONObject> queryDepartsByOrgcodes(String orgCodes){
|
List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes){
|
||||||
return this.sysBaseAPI.queryDepartsByOrgcodes(orgCodes);
|
return this.sysBaseAPI.queryDepartsByOrgcodes(orgCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 39根据多个部门ID(逗号分隔),查询返回多个部门信息
|
* 39根据多个部门ID(逗号分隔),查询返回多个部门信息
|
||||||
* @param orgCodes
|
* @param ids
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GetMapping("/queryDepartsByIds")
|
@GetMapping("/queryDepartsByIds")
|
||||||
List<JSONObject> queryDepartsByIds(String orgCodes){
|
List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids){
|
||||||
return this.sysBaseAPI.queryDepartsByIds(orgCodes);
|
return this.sysBaseAPI.queryDepartsByIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -545,7 +503,154 @@ public class SystemAPIController {
|
|||||||
return sysDepartService.listSonDepartsByDepId(departId);
|
return sysDepartService.listSonDepartsByDepId(departId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 41 获取公司下级部门和公司下所有用户信息
|
||||||
|
* @param orgCode
|
||||||
|
*/
|
||||||
|
@GetMapping("/getDeptUserByOrgCode")
|
||||||
|
List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode){
|
||||||
|
return this.sysBaseAPI.getDeptUserByOrgCode(orgCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询分类字典翻译
|
||||||
|
*
|
||||||
|
* @param ids 分类字典表id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/loadCategoryDictItem")
|
||||||
|
public List<String> loadCategoryDictItem(@RequestParam("ids") String ids) {
|
||||||
|
return sysBaseAPI.loadCategoryDictItem(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典code加载字典text
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param keys 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/loadDictItem")
|
||||||
|
public List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) {
|
||||||
|
return sysBaseAPI.loadDictItem(dictCode, keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典code查询字典项
|
||||||
|
*
|
||||||
|
* @param dictCode 顺序:tableName,text,code
|
||||||
|
* @param dictCode 要查询的key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/getDictItems")
|
||||||
|
public List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode) {
|
||||||
|
return sysBaseAPI.getDictItems(dictCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据多个字典code查询多个字典项
|
||||||
|
*
|
||||||
|
* @param dictCodeList
|
||||||
|
* @return key = dictCode ; value=对应的字典项
|
||||||
|
*/
|
||||||
|
@RequestMapping("/getManyDictItems")
|
||||||
|
public Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList) {
|
||||||
|
return sysBaseAPI.getManyDictItems(dictCodeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【下拉搜索】
|
||||||
|
* 大数据量的字典表 走异步加载,即前端输入内容过滤数据
|
||||||
|
*
|
||||||
|
* @param dictCode 字典code格式:table,text,code
|
||||||
|
* @param keyword 过滤关键字
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/loadDictItemByKeyword")
|
||||||
|
public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||||
|
return sysBaseAPI.loadDictItemByKeyword(dictCode, keyword, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割
|
||||||
|
* @param dictCodes
|
||||||
|
* @param keys
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/translateManyDict")
|
||||||
|
public Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys){
|
||||||
|
return this.sysBaseAPI.translateManyDict(dictCodes, keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表数据字典 【接口签名验证】
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/queryTableDictItemsByCode")
|
||||||
|
List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){
|
||||||
|
return sysBaseAPI.queryTableDictItemsByCode(table, text, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询表字典 支持过滤数据 【接口签名验证】
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param filterSql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/queryFilterTableDictInfo")
|
||||||
|
List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){
|
||||||
|
return sysBaseAPI.queryFilterTableDictInfo(table, text, code, filterSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【接口签名验证】
|
||||||
|
* 查询指定table的 text code 获取字典,包含text和value
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param keyArray
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@GetMapping("/queryTableDictByKeys")
|
||||||
|
public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){
|
||||||
|
return sysBaseAPI.queryTableDictByKeys(table, text, code, keyArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典表的 翻译【接口签名验证】
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/translateDictFromTable")
|
||||||
|
public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){
|
||||||
|
return sysBaseAPI.translateDictFromTable(table, text, code, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【接口签名验证】
|
||||||
|
* 49 字典表的 翻译,可批量
|
||||||
|
*
|
||||||
|
* @param table
|
||||||
|
* @param text
|
||||||
|
* @param code
|
||||||
|
* @param keys 多个用逗号分割
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/translateDictFromTableByKeys")
|
||||||
|
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) {
|
||||||
|
return this.sysBaseAPI.translateDictFromTableByKeys(table, text, code, keys);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -59,6 +59,7 @@ public class SendMsgJob implements Job {
|
|||||||
// 发送消息成功
|
// 发送消息成功
|
||||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
// 发送消息出现异常
|
// 发送消息出现异常
|
||||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.FAIL.getCode());
|
sysMessage.setEsSendStatus(SendMsgStatusEnum.FAIL.getCode());
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -1,14 +1,17 @@
|
|||||||
package com.jero.modules.message.websocket;
|
package com.jero.modules.message.websocket;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.jero.boot.starter.redis.listener.JeroRedisListerer;
|
import com.jero.common.constant.CommonSendStatus;
|
||||||
|
import com.jero.common.modules.redis.listener.JeroRedisListerer;
|
||||||
import com.jero.common.base.BaseMap;
|
import com.jero.common.base.BaseMap;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听消息(采用redis发布订阅方式发送消息)
|
* 监听消息(采用redis发布订阅方式发送消息)
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class SocketHandler implements JeroRedisListerer {
|
public class SocketHandler implements JeroRedisListerer {
|
||||||
|
|
||||||
@@ -17,10 +20,14 @@ public class SocketHandler implements JeroRedisListerer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(BaseMap map) {
|
public void onMessage(BaseMap map) {
|
||||||
|
log.info("【SocketHandler消息】Redis Listerer:" + map.toString());
|
||||||
|
|
||||||
String userId = map.get("userId");
|
String userId = map.get("userId");
|
||||||
String message = map.get("message");
|
String message = map.get("message");
|
||||||
if (ObjectUtil.isNotEmpty(userId)) {
|
if (ObjectUtil.isNotEmpty(userId)) {
|
||||||
webSocket.pushMessage(userId, message);
|
webSocket.pushMessage(userId, message);
|
||||||
|
//app端消息推送
|
||||||
|
webSocket.pushMessage(userId + CommonSendStatus.APP_SESSION_SUFFIX, message);
|
||||||
} else {
|
} else {
|
||||||
webSocket.pushMessage(message);
|
webSocket.pushMessage(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -12,7 +12,7 @@ import javax.websocket.Session;
|
|||||||
import javax.websocket.server.PathParam;
|
import javax.websocket.server.PathParam;
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
|
||||||
import com.jero.boot.starter.redis.client.JeroRedisClient;
|
import com.jero.common.modules.redis.client.JeroRedisClient;
|
||||||
import com.jero.common.base.BaseMap;
|
import com.jero.common.base.BaseMap;
|
||||||
import com.jero.common.constant.WebsocketConst;
|
import com.jero.common.constant.WebsocketConst;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -40,6 +40,9 @@ public class WebSocket {
|
|||||||
@Resource
|
@Resource
|
||||||
private JeroRedisClient jeroRedisClient;
|
private JeroRedisClient jeroRedisClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存 webSocket连接到单机服务class中(整体方案支持集群)
|
||||||
|
*/
|
||||||
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
|
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
|
||||||
private static Map<String, Session> sessionPool = new HashMap<String, Session>();
|
private static Map<String, Session> sessionPool = new HashMap<String, Session>();
|
||||||
|
|
||||||
@@ -102,8 +105,10 @@ public class WebSocket {
|
|||||||
//todo 现在有个定时任务刷,应该去掉
|
//todo 现在有个定时任务刷,应该去掉
|
||||||
log.debug("【websocket消息】收到客户端消息:" + message);
|
log.debug("【websocket消息】收到客户端消息:" + message);
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);//业务类型
|
//业务类型
|
||||||
obj.put(WebsocketConst.MSG_TXT, "心跳响应");//消息内容
|
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
|
||||||
|
//消息内容
|
||||||
|
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
|
||||||
for (WebSocket webSocket : webSockets) {
|
for (WebSocket webSocket : webSockets) {
|
||||||
webSocket.pushMessage(message);
|
webSocket.pushMessage(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-14
@@ -89,10 +89,6 @@ public class QuartzJobController {
|
|||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
@RequestMapping(value = "/add", method = RequestMethod.POST)
|
||||||
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
public Result<?> add(@RequestBody QuartzJob quartzJob) {
|
||||||
List<QuartzJob> list = quartzJobService.findByJobClassName(quartzJob.getJobClassName());
|
|
||||||
if (list != null && list.size() > 0) {
|
|
||||||
return Result.error("该定时任务类名已存在");
|
|
||||||
}
|
|
||||||
quartzJobService.saveAndScheduleJob(quartzJob);
|
quartzJobService.saveAndScheduleJob(quartzJob);
|
||||||
return Result.OK("创建定时任务成功");
|
return Result.OK("创建定时任务成功");
|
||||||
}
|
}
|
||||||
@@ -155,39 +151,38 @@ public class QuartzJobController {
|
|||||||
/**
|
/**
|
||||||
* 暂停定时任务
|
* 暂停定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@GetMapping(value = "/pause")
|
@GetMapping(value = "/pause")
|
||||||
@ApiOperation(value = "暂停定时任务")
|
@ApiOperation(value = "暂停定时任务")
|
||||||
public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
|
||||||
QuartzJob job = null;
|
QuartzJob job = quartzJobService.getById(id);
|
||||||
job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
return Result.error("定时任务不存在!");
|
return Result.error("定时任务不存在!");
|
||||||
}
|
}
|
||||||
quartzJobService.pause(job);
|
quartzJobService.pause(job);
|
||||||
return Result.OK("暂停定时任务成功");
|
return Result.ok("暂停定时任务成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动定时任务
|
* 启动定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
//@RequiresRoles("admin")
|
//@RequiresRoles("admin")
|
||||||
@GetMapping(value = "/resume")
|
@GetMapping(value = "/resume")
|
||||||
@ApiOperation(value = "恢复定时任务")
|
@ApiOperation(value = "恢复定时任务")
|
||||||
public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
|
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
|
||||||
QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
|
QuartzJob job = quartzJobService.getById(id);
|
||||||
if (job == null) {
|
if (job == null) {
|
||||||
return Result.error("定时任务不存在!");
|
return Result.error("定时任务不存在!");
|
||||||
}
|
}
|
||||||
quartzJobService.resumeJob(job);
|
quartzJobService.resumeJob(job);
|
||||||
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
|
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
|
||||||
return Result.OK("恢复定时任务成功");
|
return Result.ok("恢复定时任务成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-2
@@ -26,7 +26,7 @@ public class SampleParamJob implements Job {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||||
|
log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
|
||||||
log.info(String.format("welcome %s! jero-boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-26
@@ -16,6 +16,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: 定时任务在线管理
|
* @Description: 定时任务在线管理
|
||||||
@@ -41,42 +42,45 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
return quartzJobMapper.findByJobClassName(jobClassName);
|
return quartzJobMapper.findByJobClassName(jobClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存&启动定时任务
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = JeroBootException.class)
|
||||||
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
public boolean saveAndScheduleJob(QuartzJob quartzJob) {
|
||||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
|
||||||
// 定时器添加
|
|
||||||
this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
|
||||||
}
|
|
||||||
// DB设置修改
|
// DB设置修改
|
||||||
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
quartzJob.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||||
return this.save(quartzJob);
|
boolean success = this.save(quartzJob);
|
||||||
|
if (success) {
|
||||||
|
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||||
|
// 定时器添加
|
||||||
|
this.schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 恢复定时任务
|
* 恢复定时任务
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = JeroBootException.class)
|
||||||
public boolean resumeJob(QuartzJob quartzJob) {
|
public boolean resumeJob(QuartzJob quartzJob) {
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
|
||||||
return this.updateById(quartzJob);
|
return this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑&启停定时任务
|
* 编辑&启停定时任务
|
||||||
* @throws SchedulerException
|
* @throws SchedulerException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = JeroBootException.class)
|
||||||
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
|
||||||
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
schedulerAdd(quartzJob.getId(), quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
|
||||||
}else{
|
}else{
|
||||||
scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
|
scheduler.pauseJob(JobKey.jobKey(quartzJob.getId()));
|
||||||
}
|
}
|
||||||
return this.updateById(quartzJob);
|
return this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
@@ -85,8 +89,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
* 删除&停止删除定时任务
|
* 删除&停止删除定时任务
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = JeroBootException.class)
|
||||||
public boolean deleteAndStopJob(QuartzJob job) {
|
public boolean deleteAndStopJob(QuartzJob job) {
|
||||||
schedulerDelete(job.getJobClassName().trim());
|
schedulerDelete(job.getId());
|
||||||
boolean ok = this.removeById(job.getId());
|
boolean ok = this.removeById(job.getId());
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@@ -98,7 +103,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
||||||
String identity = jobName + ymd;
|
String identity = jobName + ymd;
|
||||||
//3秒后执行 只执行一次
|
//3秒后执行 只执行一次
|
||||||
startDate.setTime(startDate.getTime()+3000L);
|
// update-begin--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||||
|
startDate.setTime(startDate.getTime() + 100L);
|
||||||
|
// update-end--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||||
// 定义一个Trigger
|
// 定义一个Trigger
|
||||||
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
||||||
.withIdentity(identity, JOB_TEST_GROUP)
|
.withIdentity(identity, JOB_TEST_GROUP)
|
||||||
@@ -113,8 +120,9 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = JeroBootException.class)
|
||||||
public void pause(QuartzJob quartzJob){
|
public void pause(QuartzJob quartzJob){
|
||||||
schedulerDelete(quartzJob.getJobClassName().trim());
|
schedulerDelete(quartzJob.getId());
|
||||||
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
quartzJob.setStatus(CommonConstant.STATUS_DISABLE);
|
||||||
this.updateById(quartzJob);
|
this.updateById(quartzJob);
|
||||||
}
|
}
|
||||||
@@ -126,19 +134,19 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
* @param cronExpression
|
* @param cronExpression
|
||||||
* @param parameter
|
* @param parameter
|
||||||
*/
|
*/
|
||||||
private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
|
private void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {
|
||||||
try {
|
try {
|
||||||
// 启动调度器
|
// 启动调度器
|
||||||
scheduler.start();
|
scheduler.start();
|
||||||
|
|
||||||
// 构建job信息
|
// 构建job信息
|
||||||
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();
|
JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData("parameter", parameter).build();
|
||||||
|
|
||||||
// 表达式调度构建器(即任务执行的时间)
|
// 表达式调度构建器(即任务执行的时间)
|
||||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
|
||||||
|
|
||||||
// 按新的cronExpression表达式构建一个新的trigger
|
// 按新的cronExpression表达式构建一个新的trigger
|
||||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
|
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();
|
||||||
|
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
scheduler.scheduleJob(jobDetail, trigger);
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
@@ -152,14 +160,14 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除定时任务
|
* 删除定时任务
|
||||||
*
|
*
|
||||||
* @param jobClassName
|
* @param id
|
||||||
*/
|
*/
|
||||||
private void schedulerDelete(String jobClassName) {
|
private void schedulerDelete(String id) {
|
||||||
try {
|
try {
|
||||||
scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
|
scheduler.pauseTrigger(TriggerKey.triggerKey(id));
|
||||||
scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
|
scheduler.unscheduleJob(TriggerKey.triggerKey(id));
|
||||||
scheduler.deleteJob(JobKey.jobKey(jobClassName));
|
scheduler.deleteJob(JobKey.jobKey(id));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
throw new JeroBootException("删除定时任务失败");
|
throw new JeroBootException("删除定时任务失败");
|
||||||
|
|||||||
+67
@@ -83,6 +83,12 @@ public class CommonController {
|
|||||||
Result<OSSFile> result = new Result<>();
|
Result<OSSFile> result = new Result<>();
|
||||||
String savePath = "";
|
String savePath = "";
|
||||||
String bizPath = request.getParameter("biz");
|
String bizPath = request.getParameter("biz");
|
||||||
|
|
||||||
|
//sys/common/upload接口存在任意文件上传漏洞
|
||||||
|
if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) {
|
||||||
|
throw new JeroBootException("上传目录bizPath,格式非法!");
|
||||||
|
}
|
||||||
|
|
||||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||||
// 获取上传文件对象
|
// 获取上传文件对象
|
||||||
MultipartFile file = multipartRequest.getFile("file");
|
MultipartFile file = multipartRequest.getFile("file");
|
||||||
@@ -269,4 +275,65 @@ public class CommonController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预览图片&下载文件
|
||||||
|
* 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
|
@GetMapping(value = "/static/**")
|
||||||
|
public void view(HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
// ISO-8859-1 ==> UTF-8 进行编码转换
|
||||||
|
String imgPath = extractPathFromPattern(request);
|
||||||
|
if(oConvertUtils.isEmpty(imgPath) || imgPath=="null"){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 其余处理略
|
||||||
|
InputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
imgPath = imgPath.replace("..", "").replace("../","");
|
||||||
|
if (imgPath.endsWith(",")) {
|
||||||
|
imgPath = imgPath.substring(0, imgPath.length() - 1);
|
||||||
|
}
|
||||||
|
String filePath = uploadpath + File.separator + imgPath;
|
||||||
|
File file = new File(filePath);
|
||||||
|
if(!file.exists()){
|
||||||
|
response.setStatus(404);
|
||||||
|
throw new RuntimeException("文件["+imgPath+"]不存在..");
|
||||||
|
}
|
||||||
|
response.setContentType("application/force-download");// 设置强制下载不打开
|
||||||
|
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
|
||||||
|
inputStream = new BufferedInputStream(new FileInputStream(filePath));
|
||||||
|
outputStream = response.getOutputStream();
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = inputStream.read(buf)) > 0) {
|
||||||
|
outputStream.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
response.flushBuffer();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("预览文件失败" + e.getMessage());
|
||||||
|
response.setStatus(404);
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user