mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
JeecgBoot 3.3.0 版本发布,基于代码生成器的企业级低代码平台
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
Jeecg-Boot 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.2.0(发布日期:20220425)
|
||||
当前最新版本: 3.3.0(发布日期:20220725)
|
||||
|
||||
|
||||
## 后端技术架构
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,16 +0,0 @@
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_role_index
|
||||
-- ----------------------------
|
||||
CREATE TABLE `sys_role_index` (
|
||||
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`role_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色编码',
|
||||
`url` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '路由地址',
|
||||
`priority` int(11) NULL DEFAULT 0 COMMENT '优先级',
|
||||
`status` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '状态0:无效 1:有效',
|
||||
`create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人登录名称',
|
||||
`create_time` datetime NULL DEFAULT NULL COMMENT '创建日期',
|
||||
`update_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新人登录名称',
|
||||
`update_time` datetime NULL DEFAULT NULL COMMENT '更新日期',
|
||||
`sys_org_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '所属部门',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色首页表' ROW_FORMAT = Dynamic;
|
||||
22
jeecg-boot/db/增量SQL/3.2升级到3.3增量脚本sql
Normal file
22
jeecg-boot/db/增量SQL/3.2升级到3.3增量脚本sql
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
ALTER TABLE `sys_user`
|
||||
MODIFY COLUMN `org_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '登录会话的机构编码' AFTER `phone`;
|
||||
|
||||
ALTER TABLE `sys_role_index`
|
||||
ADD COLUMN `component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '组件' AFTER `url`,
|
||||
ADD COLUMN `is_route` tinyint(1) NULL DEFAULT 1 COMMENT '是否路由菜单: 0:不是 1:是(默认值1)' AFTER `component`;
|
||||
|
||||
ALTER TABLE `jeecg_order_main`
|
||||
ADD COLUMN `bpm_status` varchar(3) NULL COMMENT '流程状态' AFTER `update_time`;
|
||||
|
||||
UPDATE `sys_dict_item` SET `dict_id` = '4f69be5f507accea8d5df5f11346181a', `item_text` = '文本', `item_value` = '1', `description` = '', `sort_order` = 1, `status` = 1, `create_by` = 'admin', `create_time` = '2023-02-28 10:50:36', `update_by` = 'admin', `update_time` = '2022-07-04 16:29:21' WHERE `id` = '222705e11ef0264d4214affff1fb4ff9';
|
||||
UPDATE `sys_dict_item` SET `dict_id` = '4f69be5f507accea8d5df5f11346181a', `item_text` = '富文本', `item_value` = '2', `description` = '', `sort_order` = 2, `status` = 1, `create_by` = 'admin', `create_time` = '2031-02-28 10:50:44', `update_by` = 'admin', `update_time` = '2022-07-04 16:29:30' WHERE `id` = '6a7a9e1403a7943aba69e54ebeff9762';
|
||||
delete from sys_dict_item where id in ('1199607547704647681', '8bccb963e1cd9e8d42482c54cc609ca2');
|
||||
update sys_sms_template set template_type = '2' where template_type='4';
|
||||
update sys_sms_template set template_type = '1' where template_type='3';
|
||||
|
||||
ALTER TABLE `sys_sms_template`
|
||||
ADD COLUMN `use_status` varchar(1) NULL COMMENT '是否使用中 1是0否' AFTER `update_by`;
|
||||
|
||||
ALTER TABLE `sys_sms`
|
||||
MODIFY COLUMN `es_type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '发送方式:参考枚举MessageTypeEnum' AFTER `es_title`;
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-base-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -536,4 +536,17 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
@GetMapping("/sys/api/translateDictFromTableByKeys")
|
||||
List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys);
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
*/
|
||||
@PostMapping("/sys/api/sendTemplateMessage")
|
||||
void sendTemplateMessage(@RequestBody MessageDTO message);
|
||||
|
||||
/**
|
||||
* 获取模板内容
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getTemplateContent")
|
||||
String getTemplateContent(@RequestParam("code") String code);
|
||||
}
|
||||
|
||||
@ -278,6 +278,15 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTemplateMessage(MessageDTO message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateContent(String code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEmailMsg(String email,String title,String content) {
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@
|
||||
// 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());
|
||||
// requestTemplate.header(CommonConstant.X_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
@ -146,7 +146,7 @@
|
||||
// return new SpringEncoder(feignHttpMessageConverter());
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// @Bean("apiFeignDecoder")
|
||||
// public Decoder feignDecoder() {
|
||||
// return new SpringDecoder(feignHttpMessageConverter());
|
||||
// }
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-base-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -338,4 +338,17 @@ public interface ISysBaseAPI extends CommonAPI {
|
||||
*/
|
||||
List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 发送模板消息
|
||||
* @param message
|
||||
*/
|
||||
void sendTemplateMessage(MessageDTO message);
|
||||
|
||||
/**
|
||||
* 根据模板编码获取模板内容
|
||||
* @param templateCode
|
||||
* @return
|
||||
*/
|
||||
String getTemplateContent(String templateCode);
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-base</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import lombok.Data;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 普通消息
|
||||
@ -72,4 +73,18 @@ public class MessageDTO implements Serializable {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板消息对应的模板编码
|
||||
*/
|
||||
protected String templateCode;
|
||||
/**
|
||||
* 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum
|
||||
*/
|
||||
protected String type;
|
||||
|
||||
/**
|
||||
* 解析模板内容 对应的数据
|
||||
*/
|
||||
protected Map<String, Object> data;
|
||||
|
||||
}
|
||||
|
||||
@ -40,6 +40,8 @@ public class PermissionDataAspect {
|
||||
@Autowired
|
||||
private CommonAPI commonApi;
|
||||
|
||||
private static final String SPOT_DO = ".do";
|
||||
|
||||
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.PermissionData)")
|
||||
public void pointCut() {
|
||||
|
||||
@ -113,7 +115,7 @@ public class PermissionDataAspect {
|
||||
requestPath = requestPath.substring(0, requestPath.indexOf("&"));
|
||||
}
|
||||
if(requestPath.indexOf(QueryRuleEnum.EQ.getValue())!=-1){
|
||||
if(requestPath.indexOf(CommonConstant.SPOT_DO)!=-1){
|
||||
if(requestPath.indexOf(SPOT_DO)!=-1){
|
||||
requestPath = requestPath.substring(0,requestPath.indexOf(".do")+3);
|
||||
}else{
|
||||
requestPath = requestPath.substring(0,requestPath.indexOf("?"));
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package org.jeecg.common.aspect.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 动态table切换
|
||||
*
|
||||
* @author :zyf
|
||||
* @date:2020-04-25
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DynamicTable {
|
||||
/**
|
||||
* 需要动态解析的表名
|
||||
* @return
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@ -9,320 +9,321 @@ public interface CommonConstant {
|
||||
/**
|
||||
* 正常状态
|
||||
*/
|
||||
public static final Integer STATUS_NORMAL = 0;
|
||||
Integer STATUS_NORMAL = 0;
|
||||
|
||||
/**
|
||||
* 禁用状态
|
||||
*/
|
||||
public static final Integer STATUS_DISABLE = -1;
|
||||
Integer STATUS_DISABLE = -1;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
public static final Integer DEL_FLAG_1 = 1;
|
||||
Integer DEL_FLAG_1 = 1;
|
||||
|
||||
/**
|
||||
* 未删除
|
||||
*/
|
||||
public static final Integer DEL_FLAG_0 = 0;
|
||||
Integer DEL_FLAG_0 = 0;
|
||||
|
||||
/**
|
||||
* 系统日志类型: 登录
|
||||
*/
|
||||
public static final int LOG_TYPE_1 = 1;
|
||||
int LOG_TYPE_1 = 1;
|
||||
|
||||
/**
|
||||
* 系统日志类型: 操作
|
||||
*/
|
||||
public static final int LOG_TYPE_2 = 2;
|
||||
int LOG_TYPE_2 = 2;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 查询
|
||||
*/
|
||||
public static final int OPERATE_TYPE_1 = 1;
|
||||
int OPERATE_TYPE_1 = 1;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 添加
|
||||
*/
|
||||
public static final int OPERATE_TYPE_2 = 2;
|
||||
int OPERATE_TYPE_2 = 2;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 更新
|
||||
*/
|
||||
public static final int OPERATE_TYPE_3 = 3;
|
||||
int OPERATE_TYPE_3 = 3;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 删除
|
||||
*/
|
||||
public static final int OPERATE_TYPE_4 = 4;
|
||||
int OPERATE_TYPE_4 = 4;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 倒入
|
||||
*/
|
||||
public static final int OPERATE_TYPE_5 = 5;
|
||||
int OPERATE_TYPE_5 = 5;
|
||||
|
||||
/**
|
||||
* 操作日志类型: 导出
|
||||
*/
|
||||
public static final int OPERATE_TYPE_6 = 6;
|
||||
int OPERATE_TYPE_6 = 6;
|
||||
|
||||
|
||||
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
|
||||
public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
|
||||
Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
|
||||
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
|
||||
public static final Integer SC_OK_200 = 200;
|
||||
Integer SC_OK_200 = 200;
|
||||
|
||||
/**访问权限认证未通过 510*/
|
||||
public static final Integer SC_JEECG_NO_AUTHZ=510;
|
||||
Integer SC_JEECG_NO_AUTHZ=510;
|
||||
|
||||
/** 登录用户Shiro权限缓存KEY前缀 */
|
||||
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:";
|
||||
/** 登录用户Token令牌缓存KEY前缀 */
|
||||
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
|
||||
String PREFIX_USER_TOKEN = "prefix_user_token_";
|
||||
// /** Token缓存时间:3600秒即一小时 */
|
||||
// public static final int TOKEN_EXPIRE_TIME = 3600;
|
||||
// int TOKEN_EXPIRE_TIME = 3600;
|
||||
|
||||
/** 登录二维码 */
|
||||
public static final String LOGIN_QRCODE_PRE = "QRCODELOGIN:";
|
||||
public static final String LOGIN_QRCODE = "LQ:";
|
||||
String LOGIN_QRCODE_PRE = "QRCODELOGIN:";
|
||||
String LOGIN_QRCODE = "LQ:";
|
||||
/** 登录二维码token */
|
||||
public static final String LOGIN_QRCODE_TOKEN = "LQT:";
|
||||
String LOGIN_QRCODE_TOKEN = "LQT:";
|
||||
|
||||
|
||||
/**
|
||||
* 0:一级菜单
|
||||
*/
|
||||
public static final Integer MENU_TYPE_0 = 0;
|
||||
Integer MENU_TYPE_0 = 0;
|
||||
/**
|
||||
* 1:子菜单
|
||||
*/
|
||||
public static final Integer MENU_TYPE_1 = 1;
|
||||
Integer MENU_TYPE_1 = 1;
|
||||
/**
|
||||
* 2:按钮权限
|
||||
*/
|
||||
public static final Integer MENU_TYPE_2 = 2;
|
||||
Integer MENU_TYPE_2 = 2;
|
||||
|
||||
/**通告对象类型(USER:指定用户,ALL:全体用户)*/
|
||||
public static final String MSG_TYPE_UESR = "USER";
|
||||
public static final String MSG_TYPE_ALL = "ALL";
|
||||
String MSG_TYPE_UESR = "USER";
|
||||
String MSG_TYPE_ALL = "ALL";
|
||||
|
||||
/**发布状态(0未发布,1已发布,2已撤销)*/
|
||||
public static final String NO_SEND = "0";
|
||||
public static final String HAS_SEND = "1";
|
||||
public static final String HAS_CANCLE = "2";
|
||||
String NO_SEND = "0";
|
||||
String HAS_SEND = "1";
|
||||
String HAS_CANCLE = "2";
|
||||
|
||||
/**阅读状态(0未读,1已读)*/
|
||||
public static final String HAS_READ_FLAG = "1";
|
||||
public static final String NO_READ_FLAG = "0";
|
||||
String HAS_READ_FLAG = "1";
|
||||
String NO_READ_FLAG = "0";
|
||||
|
||||
/**优先级(L低,M中,H高)*/
|
||||
public static final String PRIORITY_L = "L";
|
||||
public static final String PRIORITY_M = "M";
|
||||
public static final String PRIORITY_H = "H";
|
||||
String PRIORITY_L = "L";
|
||||
String PRIORITY_M = "M";
|
||||
String PRIORITY_H = "H";
|
||||
|
||||
/**
|
||||
* 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板
|
||||
*/
|
||||
public static final String SMS_TPL_TYPE_0 = "0";
|
||||
public static final String SMS_TPL_TYPE_1 = "1";
|
||||
public static final String SMS_TPL_TYPE_2 = "2";
|
||||
String SMS_TPL_TYPE_0 = "0";
|
||||
String SMS_TPL_TYPE_1 = "1";
|
||||
String SMS_TPL_TYPE_2 = "2";
|
||||
|
||||
/**
|
||||
* 状态(0无效1有效)
|
||||
*/
|
||||
public static final String STATUS_0 = "0";
|
||||
public static final String STATUS_1 = "1";
|
||||
String STATUS_0 = "0";
|
||||
String STATUS_1 = "1";
|
||||
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
public static final Integer ACT_SYNC_1 = 1;
|
||||
public static final Integer ACT_SYNC_0 = 0;
|
||||
Integer ACT_SYNC_1 = 1;
|
||||
Integer ACT_SYNC_0 = 0;
|
||||
|
||||
/**
|
||||
* 消息类型1:通知公告2:系统消息
|
||||
*/
|
||||
public static final String MSG_CATEGORY_1 = "1";
|
||||
public static final String MSG_CATEGORY_2 = "2";
|
||||
String MSG_CATEGORY_1 = "1";
|
||||
String MSG_CATEGORY_2 = "2";
|
||||
|
||||
/**
|
||||
* 是否配置菜单的数据权限 1是0否
|
||||
*/
|
||||
public static final Integer RULE_FLAG_0 = 0;
|
||||
public static final Integer RULE_FLAG_1 = 1;
|
||||
Integer RULE_FLAG_0 = 0;
|
||||
Integer RULE_FLAG_1 = 1;
|
||||
|
||||
/**
|
||||
* 是否用户已被冻结 1正常(解冻) 2冻结
|
||||
*/
|
||||
public static final Integer USER_UNFREEZE = 1;
|
||||
public static final Integer USER_FREEZE = 2;
|
||||
Integer USER_UNFREEZE = 1;
|
||||
Integer USER_FREEZE = 2;
|
||||
|
||||
/**字典翻译文本后缀*/
|
||||
public static final String DICT_TEXT_SUFFIX = "_dictText";
|
||||
String DICT_TEXT_SUFFIX = "_dictText";
|
||||
|
||||
/**
|
||||
* 表单设计器主表类型
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
|
||||
Integer DESIGN_FORM_TYPE_MAIN = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器子表表类型
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
|
||||
Integer DESIGN_FORM_TYPE_SUB = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权通过
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
|
||||
Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
|
||||
Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器新增 Flag
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
|
||||
String DESIGN_FORM_URL_TYPE_ADD = "add";
|
||||
/**
|
||||
* 表单设计器修改 Flag
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
|
||||
String DESIGN_FORM_URL_TYPE_EDIT = "edit";
|
||||
/**
|
||||
* 表单设计器详情 Flag
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
|
||||
String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
|
||||
/**
|
||||
* 表单设计器复用数据 Flag
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
|
||||
String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
|
||||
/**
|
||||
* 表单设计器编辑 Flag (已弃用)
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
|
||||
String DESIGN_FORM_URL_TYPE_VIEW = "view";
|
||||
|
||||
/**
|
||||
* online参数值设置(是:Y, 否:N)
|
||||
*/
|
||||
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
|
||||
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
|
||||
String ONLINE_PARAM_VAL_IS_TURE = "Y";
|
||||
String ONLINE_PARAM_VAL_IS_FALSE = "N";
|
||||
|
||||
/**
|
||||
* 文件上传类型(本地:local,Minio:minio,阿里云:alioss)
|
||||
*/
|
||||
public static final String UPLOAD_TYPE_LOCAL = "local";
|
||||
public static final String UPLOAD_TYPE_MINIO = "minio";
|
||||
public static final String UPLOAD_TYPE_OSS = "alioss";
|
||||
String UPLOAD_TYPE_LOCAL = "local";
|
||||
String UPLOAD_TYPE_MINIO = "minio";
|
||||
String UPLOAD_TYPE_OSS = "alioss";
|
||||
|
||||
/**
|
||||
* 文档上传自定义桶名称
|
||||
*/
|
||||
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
|
||||
String UPLOAD_CUSTOM_BUCKET = "eoafile";
|
||||
/**
|
||||
* 文档上传自定义路径
|
||||
*/
|
||||
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
|
||||
String UPLOAD_CUSTOM_PATH = "eoafile";
|
||||
/**
|
||||
* 文件外链接有效天数
|
||||
*/
|
||||
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
|
||||
Integer UPLOAD_EFFECTIVE_DAYS = 1;
|
||||
|
||||
/**
|
||||
* 员工身份 (1:普通员工 2:上级)
|
||||
*/
|
||||
public static final Integer USER_IDENTITY_1 = 1;
|
||||
public static final Integer USER_IDENTITY_2 = 2;
|
||||
Integer USER_IDENTITY_1 = 1;
|
||||
Integer USER_IDENTITY_2 = 2;
|
||||
|
||||
/** sys_user 表 username 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
||||
String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
||||
/** sys_user 表 work_no 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
|
||||
String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
|
||||
/** sys_user 表 phone 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
|
||||
String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
|
||||
/** 达梦数据库升提示。违反表[SYS_USER]唯一性约束 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束";
|
||||
String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束";
|
||||
|
||||
/** sys_user 表 email 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
|
||||
String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
|
||||
/** sys_quartz_job 表 job_class_name 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
|
||||
String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
|
||||
/** sys_position 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
|
||||
String SQL_INDEX_UNIQ_CODE = "uniq_code";
|
||||
/** sys_role 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
|
||||
String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
|
||||
/** sys_depart 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
|
||||
String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
|
||||
/** sys_category 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code";
|
||||
String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code";
|
||||
/**
|
||||
* 在线聊天 是否为默认分组
|
||||
*/
|
||||
public static final String IM_DEFAULT_GROUP = "1";
|
||||
String IM_DEFAULT_GROUP = "1";
|
||||
/**
|
||||
* 在线聊天 图片文件保存路径
|
||||
*/
|
||||
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
|
||||
String IM_UPLOAD_CUSTOM_PATH = "imfile";
|
||||
/**
|
||||
* 在线聊天 用户状态
|
||||
*/
|
||||
public static final String IM_STATUS_ONLINE = "online";
|
||||
String IM_STATUS_ONLINE = "online";
|
||||
|
||||
/**
|
||||
* 在线聊天 SOCKET消息类型
|
||||
*/
|
||||
public static final String IM_SOCKET_TYPE = "chatMessage";
|
||||
String IM_SOCKET_TYPE = "chatMessage";
|
||||
|
||||
/**
|
||||
* 在线聊天 是否开启默认添加好友 1是 0否
|
||||
*/
|
||||
public static final String IM_DEFAULT_ADD_FRIEND = "1";
|
||||
String IM_DEFAULT_ADD_FRIEND = "1";
|
||||
|
||||
/**
|
||||
* 在线聊天 用户好友缓存前缀
|
||||
*/
|
||||
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
|
||||
String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
|
||||
|
||||
/**
|
||||
* 考勤补卡业务状态 (1:同意 2:不同意)
|
||||
*/
|
||||
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
|
||||
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
|
||||
String SIGN_PATCH_BIZ_STATUS_1 = "1";
|
||||
String SIGN_PATCH_BIZ_STATUS_2 = "2";
|
||||
|
||||
/**
|
||||
* 公文文档上传自定义路径
|
||||
*/
|
||||
public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
|
||||
String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
|
||||
/**
|
||||
* 公文文档下载自定义路径
|
||||
*/
|
||||
public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
|
||||
String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
|
||||
|
||||
/**
|
||||
* WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板))
|
||||
*/
|
||||
public static final String WPS_TYPE_1="1";
|
||||
public static final String WPS_TYPE_2="2";
|
||||
String WPS_TYPE_1="1";
|
||||
String WPS_TYPE_2="2";
|
||||
|
||||
|
||||
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 TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!";
|
||||
String X_ACCESS_TOKEN = "X-Access-Token";
|
||||
String X_SIGN = "X-Sign";
|
||||
String X_TIMESTAMP = "X-TIMESTAMP";
|
||||
String TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!";
|
||||
String X_FORWARDED_SCHEME = "X-Forwarded-Scheme";
|
||||
|
||||
/**
|
||||
* 多租户 请求头
|
||||
*/
|
||||
public final static String TENANT_ID = "tenant-id";
|
||||
String TENANT_ID = "tenant-id";
|
||||
|
||||
/**
|
||||
* 微服务读取配置文件属性 服务地址
|
||||
*/
|
||||
public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
|
||||
String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
|
||||
|
||||
/**
|
||||
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
|
||||
*/
|
||||
public final static String THIRD_LOGIN_CODE = "third_login_code";
|
||||
String THIRD_LOGIN_CODE = "third_login_code";
|
||||
|
||||
/**
|
||||
* 第三方APP同步方向:本地 --> 第三方APP
|
||||
@ -361,16 +362,43 @@ public interface CommonConstant {
|
||||
/**String 类型的空值*/
|
||||
String STRING_NULL = "null";
|
||||
|
||||
/**java.util.Date 包*/
|
||||
String JAVA_UTIL_DATE = "java.util.Date";
|
||||
|
||||
/**.do*/
|
||||
String SPOT_DO = ".do";
|
||||
|
||||
|
||||
/**前端vue版本标识*/
|
||||
/**前端vue3版本Header参数名*/
|
||||
String VERSION="X-Version";
|
||||
|
||||
/**前端vue版本*/
|
||||
String VERSION_VUE3="vue3";
|
||||
/**存储在线程变量里的动态表名*/
|
||||
String DYNAMIC_TABLE_NAME="DYNAMIC_TABLE_NAME";
|
||||
/**
|
||||
* http:// http协议
|
||||
*/
|
||||
String HTTP_PROTOCOL = "http://";
|
||||
|
||||
/**
|
||||
* https:// https协议
|
||||
*/
|
||||
String HTTPS_PROTOCOL = "https://";
|
||||
|
||||
/** 部门表唯一key,id */
|
||||
String DEPART_KEY_ID = "id";
|
||||
/** 部门表唯一key,orgCode */
|
||||
String DEPART_KEY_ORG_CODE = "orgCode";
|
||||
|
||||
/**
|
||||
* 发消息 会传递一些信息到map
|
||||
*/
|
||||
String NOTICE_MSG_SUMMARY = "NOTICE_MSG_SUMMARY";
|
||||
|
||||
/**
|
||||
* 发消息 会传递一个业务ID到map
|
||||
*/
|
||||
String NOTICE_MSG_BUS_ID = "NOTICE_MSG_BUS_ID";
|
||||
|
||||
/**
|
||||
* 邮箱消息中地址登录时地址后携带的token,需要替换成真实的token值
|
||||
*/
|
||||
String LOGIN_TOKEN = "{LOGIN_TOKEN}";
|
||||
|
||||
/**
|
||||
* 模板消息中 跳转地址的对应的key
|
||||
*/
|
||||
String MSG_HREF_URL = "url";
|
||||
}
|
||||
|
||||
@ -153,4 +153,14 @@ public interface DataBaseConstant {
|
||||
* sql语句 where
|
||||
*/
|
||||
String SQL_WHERE = "where";
|
||||
|
||||
/**
|
||||
* sql语句 asc
|
||||
*/
|
||||
String SQL_ASC = "asc";
|
||||
|
||||
/**
|
||||
* sqlserver数据库,中间有空格
|
||||
*/
|
||||
String DB_TYPE_SQL_SERVER_BLANK = "sql server";
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* 动态切换表配置常量
|
||||
*
|
||||
* @author: scott
|
||||
* @date: 2022年04月25日 22:30
|
||||
*/
|
||||
public class DynamicTableConstant {
|
||||
/**
|
||||
* 角色首页配置表
|
||||
* vue2表名: sys_role_index
|
||||
* vue3表名: sys_role_index_vue3
|
||||
*/
|
||||
public static final String SYS_ROLE_INDEX = "sys_role_index";
|
||||
}
|
||||
@ -35,9 +35,13 @@ public class ProvinceCityArea {
|
||||
this.initAreaList();
|
||||
if(areaList!=null && areaList.size()>0){
|
||||
for(int i=areaList.size()-1;i>=0;i--){
|
||||
if(text.indexOf(areaList.get(i).getText())>=0){
|
||||
//update-begin-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
||||
String areaText = areaList.get(i).getText();
|
||||
String cityText = areaList.get(i).getAheadText();
|
||||
if(text.indexOf(areaText)>=0 && (cityText!=null && text.indexOf(cityText)>=0)){
|
||||
return areaList.get(i).getId();
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -145,6 +149,9 @@ public class ProvinceCityArea {
|
||||
for(String areaKey:areaJson.keySet()){
|
||||
//System.out.println("········"+areaKey);
|
||||
Area area = new Area(areaKey,areaJson.getString(areaKey),cityKey);
|
||||
//update-begin-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
||||
area.setAheadText(cityJson.getString(cityKey));
|
||||
//update-end-author:taoyan date:2022-5-24 for:VUEN-1088 online 导入 省市区导入后 导入数据错乱 北京市/市辖区/西城区-->山西省/晋城市/城区
|
||||
this.areaList.add(area);
|
||||
}
|
||||
}
|
||||
@ -180,6 +187,8 @@ public class ProvinceCityArea {
|
||||
String id;
|
||||
String text;
|
||||
String pid;
|
||||
// 用于存储上级文本数据,区的上级文本 是市的数据
|
||||
String aheadText;
|
||||
|
||||
public Area(String id,String text,String pid){
|
||||
this.id = id;
|
||||
@ -198,5 +207,12 @@ public class ProvinceCityArea {
|
||||
public String getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
public String getAheadText() {
|
||||
return aheadText;
|
||||
}
|
||||
public void setAheadText(String aheadText) {
|
||||
this.aheadText = aheadText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,4 +86,34 @@ public class SymbolConstant {
|
||||
* 符号:和 &
|
||||
*/
|
||||
public static final String AND = "&";
|
||||
|
||||
/**
|
||||
* 符号:../
|
||||
*/
|
||||
public static final String SPOT_SINGLE_SLASH = "../";
|
||||
|
||||
/**
|
||||
* 符号:..\\
|
||||
*/
|
||||
public static final String SPOT_DOUBLE_BACKSLASH = "..\\";
|
||||
|
||||
/**
|
||||
* 系统变量前缀 #{
|
||||
*/
|
||||
public static final String SYS_VAR_PREFIX = "#{";
|
||||
|
||||
/**
|
||||
* 符号 {{
|
||||
*/
|
||||
public static final String DOUBLE_LEFT_CURLY_BRACKET = "{{";
|
||||
|
||||
/**
|
||||
* 符号:[
|
||||
*/
|
||||
public static final String SQUARE_BRACKETS_LEFT = "[";
|
||||
/**
|
||||
* 符号:]
|
||||
*/
|
||||
public static final String SQUARE_BRACKETS_RIGHT = "]";
|
||||
|
||||
}
|
||||
@ -19,14 +19,15 @@ public enum CgformEnum {
|
||||
* 多表
|
||||
*/
|
||||
MANY(2, "many", "/jeecg/code-template-online", "default.onetomany", "经典风格"),
|
||||
/**
|
||||
* 多表
|
||||
*/
|
||||
ERP(2, "erp", "/jeecg/code-template-online", "erp.onetomany", "ERP风格"),
|
||||
/**
|
||||
* 多表(jvxe风格)
|
||||
* */
|
||||
JVXE_TABLE(2, "jvxe", "/jeecg/code-template-online", "jvxe.onetomany", "JVXE风格"),
|
||||
|
||||
/**
|
||||
* 多表
|
||||
*/
|
||||
ERP(2, "erp", "/jeecg/code-template-online", "erp.onetomany", "ERP风格"),
|
||||
/**
|
||||
* 多表(内嵌子表风格)
|
||||
*/
|
||||
|
||||
@ -15,6 +15,8 @@ public enum LowAppAopEnum {
|
||||
* 删除方法(包含单个和批量删除)
|
||||
*/
|
||||
DELETE,
|
||||
/** 复制表单操作 */
|
||||
COPY,
|
||||
|
||||
/**
|
||||
* Online表单专用:数据库表转Online表单
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
package org.jeecg.common.constant.enums;
|
||||
|
||||
import org.jeecg.common.system.annotation.EnumDict;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@EnumDict("messageType")
|
||||
public enum MessageTypeEnum {
|
||||
|
||||
XT("system", "系统消息"),
|
||||
YJ("email", "邮件消息"),
|
||||
DD("dingtalk", "钉钉消息"),
|
||||
QYWX("wechat_enterprise", "企业微信");
|
||||
|
||||
MessageTypeEnum(String type, String note){
|
||||
this.type = type;
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
String type;
|
||||
|
||||
/**
|
||||
* 类型说明
|
||||
*/
|
||||
String note;
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public void setNote(String note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
* @return
|
||||
*/
|
||||
public static List<DictModel> getDictList(){
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
DictModel dictModel = null;
|
||||
for(MessageTypeEnum e: MessageTypeEnum.values()){
|
||||
dictModel = new DictModel();
|
||||
dictModel.setValue(e.getType());
|
||||
dictModel.setText(e.getNote());
|
||||
list.add(dictModel);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package org.jeecg.common.desensitization.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 解密注解
|
||||
*
|
||||
* 在方法上定义 将方法返回对象中的敏感字段 解密,需要注意的是,如果没有加密过,解密会出问题,返回原字符串
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface SensitiveDecode {
|
||||
|
||||
/**
|
||||
* 指明需要脱敏的实体类class
|
||||
* @return
|
||||
*/
|
||||
Class entity() default Object.class;
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package org.jeecg.common.desensitization.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 加密注解
|
||||
*
|
||||
* 在方法上声明 将方法返回对象中的敏感字段 加密/格式化
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface SensitiveEncode {
|
||||
|
||||
/**
|
||||
* 指明需要脱敏的实体类class
|
||||
* @return
|
||||
*/
|
||||
Class entity() default Object.class;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package org.jeecg.common.desensitization.annotation;
|
||||
|
||||
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 在字段上定义 标识字段存储的信息是敏感的
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface SensitiveField {
|
||||
|
||||
/**
|
||||
* 不同类型处理不同
|
||||
* @return
|
||||
*/
|
||||
SensitiveEnum type() default SensitiveEnum.ENCODE;
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package org.jeecg.common.desensitization.aspect;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveDecode;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveEncode;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感数据切面处理类
|
||||
* @Author taoYan
|
||||
* @Date 2022/4/20 17:45
|
||||
**/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class SensitiveDataAspect {
|
||||
|
||||
/**
|
||||
* 定义切点Pointcut
|
||||
*/
|
||||
@Pointcut("@annotation(org.jeecg.common.desensitization.annotation.SensitiveEncode) || @annotation(org.jeecg.common.desensitization.annotation.SensitiveDecode)")
|
||||
public void sensitivePointCut() {
|
||||
}
|
||||
|
||||
@Around("sensitivePointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
// 处理结果
|
||||
Object result = point.proceed();
|
||||
if(result == null){
|
||||
return result;
|
||||
}
|
||||
Class resultClass = result.getClass();
|
||||
log.debug(" resultClass = {}" , resultClass);
|
||||
|
||||
if(resultClass.isPrimitive()){
|
||||
//是基本类型 直接返回 不需要处理
|
||||
return result;
|
||||
}
|
||||
// 获取方法注解信息:是哪个实体、是加密还是解密
|
||||
boolean isEncode = true;
|
||||
Class entity = null;
|
||||
MethodSignature methodSignature = (MethodSignature) point.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
SensitiveEncode encode = method.getAnnotation(SensitiveEncode.class);
|
||||
if(encode==null){
|
||||
SensitiveDecode decode = method.getAnnotation(SensitiveDecode.class);
|
||||
if(decode!=null){
|
||||
entity = decode.entity();
|
||||
isEncode = false;
|
||||
}
|
||||
}else{
|
||||
entity = encode.entity();
|
||||
}
|
||||
|
||||
long startTime=System.currentTimeMillis();
|
||||
if(resultClass.equals(entity) || entity.equals(Object.class)){
|
||||
// 方法返回实体和注解的entity一样,如果注解没有申明entity属性则认为是(方法返回实体和注解的entity一样)
|
||||
SensitiveInfoUtil.handlerObject(result, isEncode);
|
||||
} else if(result instanceof List){
|
||||
// 方法返回List<实体>
|
||||
SensitiveInfoUtil.handleList(result, entity, isEncode);
|
||||
}else{
|
||||
// 方法返回一个对象
|
||||
SensitiveInfoUtil.handleNestedObject(result, entity, isEncode);
|
||||
}
|
||||
long endTime=System.currentTimeMillis();
|
||||
log.info((isEncode ? "加密操作," : "解密操作,") + "Aspect程序耗时:" + (endTime - startTime) + "ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package org.jeecg.common.desensitization.enums;
|
||||
|
||||
/**
|
||||
* 敏感字段信息类型
|
||||
*/
|
||||
public enum SensitiveEnum {
|
||||
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*/
|
||||
ENCODE,
|
||||
|
||||
/**
|
||||
* 中文名
|
||||
*/
|
||||
CHINESE_NAME,
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
ID_CARD,
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
FIXED_PHONE,
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
MOBILE_PHONE,
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
ADDRESS,
|
||||
|
||||
/**
|
||||
* 电子邮件
|
||||
*/
|
||||
EMAIL,
|
||||
|
||||
/**
|
||||
* 银行卡
|
||||
*/
|
||||
BANK_CARD,
|
||||
|
||||
/**
|
||||
* 公司开户银行联号
|
||||
*/
|
||||
CNAPS_CODE;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,362 @@
|
||||
package org.jeecg.common.desensitization.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.jeecg.common.desensitization.enums.SensitiveEnum;
|
||||
import org.jeecg.common.util.encryption.AesEncryptUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感信息处理工具类
|
||||
* @author taoYan
|
||||
* @date 2022/4/20 18:01
|
||||
**/
|
||||
@Slf4j
|
||||
public class SensitiveInfoUtil {
|
||||
|
||||
/**
|
||||
* 处理嵌套对象
|
||||
* @param obj 方法返回值
|
||||
* @param entity 实体class
|
||||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作)
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static void handleNestedObject(Object obj, Class entity, boolean isEncode) throws IllegalAccessException {
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if(field.getType().isPrimitive()){
|
||||
continue;
|
||||
}
|
||||
if(field.getType().equals(entity)){
|
||||
// 对象里面是实体
|
||||
field.setAccessible(true);
|
||||
Object nestedObject = field.get(obj);
|
||||
handlerObject(nestedObject, isEncode);
|
||||
break;
|
||||
}else{
|
||||
// 对象里面是List<实体>
|
||||
if(field.getGenericType() instanceof ParameterizedType){
|
||||
ParameterizedType pt = (ParameterizedType)field.getGenericType();
|
||||
if(pt.getRawType().equals(List.class)){
|
||||
if(pt.getActualTypeArguments()[0].equals(entity)){
|
||||
field.setAccessible(true);
|
||||
Object nestedObject = field.get(obj);
|
||||
handleList(nestedObject, entity, isEncode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Object
|
||||
* @param obj 方法返回值
|
||||
* @param isEncode 是否加密(true: 加密操作 / false:解密操作)
|
||||
* @return
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static Object handlerObject(Object obj, boolean isEncode) throws IllegalAccessException {
|
||||
log.debug(" obj --> "+ obj.toString());
|
||||
long startTime=System.currentTimeMillis();
|
||||
if (oConvertUtils.isEmpty(obj)) {
|
||||
return obj;
|
||||
}
|
||||
// 判断是不是一个对象
|
||||
Field[] fields = obj.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
boolean isSensitiveField = field.isAnnotationPresent(SensitiveField.class);
|
||||
if(isSensitiveField){
|
||||
// 必须有SensitiveField注解 才作处理
|
||||
if(field.getType().isAssignableFrom(String.class)){
|
||||
//必须是字符串类型 才作处理
|
||||
field.setAccessible(true);
|
||||
String realValue = (String) field.get(obj);
|
||||
if(realValue==null || "".equals(realValue)){
|
||||
continue;
|
||||
}
|
||||
SensitiveField sf = field.getAnnotation(SensitiveField.class);
|
||||
if(isEncode==true){
|
||||
//加密
|
||||
String value = SensitiveInfoUtil.getEncodeData(realValue, sf.type());
|
||||
field.set(obj, value);
|
||||
}else{
|
||||
//解密只处理 encode类型的
|
||||
if(sf.type().equals(SensitiveEnum.ENCODE)){
|
||||
String value = SensitiveInfoUtil.getDecodeData(realValue);
|
||||
field.set(obj, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//long endTime=System.currentTimeMillis();
|
||||
//log.info((isEncode ? "加密操作," : "解密操作,") + "当前程序耗时:" + (endTime - startTime) + "ms");
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 List<实体>
|
||||
* @param obj
|
||||
* @param entity
|
||||
* @param isEncode(true: 加密操作 / false:解密操作)
|
||||
*/
|
||||
public static void handleList(Object obj, Class entity, boolean isEncode){
|
||||
List list = (List)obj;
|
||||
if(list.size()>0){
|
||||
Object first = list.get(0);
|
||||
if(first.getClass().equals(entity)){
|
||||
for(int i=0; i<list.size(); i++){
|
||||
Object temp = list.get(i);
|
||||
try {
|
||||
handlerObject(temp, isEncode);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理数据 获取解密后的数据
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static String getDecodeData(String data){
|
||||
String result = null;
|
||||
try {
|
||||
result = AesEncryptUtil.desEncrypt(data);
|
||||
} catch (Exception exception) {
|
||||
log.warn("数据解密错误,原数据:"+data);
|
||||
}
|
||||
//解决debug模式下,加解密失效导致中文被解密变成空的问题
|
||||
if(oConvertUtils.isEmpty(result) && oConvertUtils.isNotEmpty(data)){
|
||||
result = data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据 获取加密后的数据 或是格式化后的数据
|
||||
* @param data 字符串
|
||||
* @param sensitiveEnum 类型
|
||||
* @return 处理后的字符串
|
||||
*/
|
||||
public static String getEncodeData(String data, SensitiveEnum sensitiveEnum){
|
||||
String result;
|
||||
switch (sensitiveEnum){
|
||||
case ENCODE:
|
||||
try {
|
||||
result = AesEncryptUtil.encrypt(data);
|
||||
} catch (Exception exception) {
|
||||
log.error("数据加密错误", exception.getMessage());
|
||||
result = data;
|
||||
}
|
||||
break;
|
||||
case CHINESE_NAME:
|
||||
result = chineseName(data);
|
||||
break;
|
||||
case ID_CARD:
|
||||
result = idCardNum(data);
|
||||
break;
|
||||
case FIXED_PHONE:
|
||||
result = fixedPhone(data);
|
||||
break;
|
||||
case MOBILE_PHONE:
|
||||
result = mobilePhone(data);
|
||||
break;
|
||||
case ADDRESS:
|
||||
result = address(data, 3);
|
||||
break;
|
||||
case EMAIL:
|
||||
result = email(data);
|
||||
break;
|
||||
case BANK_CARD:
|
||||
result = bankCard(data);
|
||||
break;
|
||||
case CNAPS_CODE:
|
||||
result = cnapsCode(data);
|
||||
break;
|
||||
default:
|
||||
result = data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号
|
||||
* @param fullName 全名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String fullName) {
|
||||
if (oConvertUtils.isEmpty(fullName)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(fullName, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号
|
||||
* @param familyName 姓
|
||||
* @param firstName 名
|
||||
* @return <例子:李**>
|
||||
*/
|
||||
private static String chineseName(String familyName, String firstName) {
|
||||
if (oConvertUtils.isEmpty(familyName) || oConvertUtils.isEmpty(firstName)) {
|
||||
return "";
|
||||
}
|
||||
return chineseName(familyName + firstName);
|
||||
}
|
||||
|
||||
/**
|
||||
* [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。
|
||||
* @param id 身份证号
|
||||
* @return <例子:*************5762>
|
||||
*/
|
||||
private static String idCardNum(String id) {
|
||||
if (oConvertUtils.isEmpty(id)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(id, 4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* [固定电话] 后四位,其他隐藏
|
||||
* @param num 固定电话
|
||||
* @return <例子:****1234>
|
||||
*/
|
||||
private static String fixedPhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
return formatLeft(num, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [手机号码] 前三位,后四位,其他隐藏
|
||||
* @param num 手机号码
|
||||
* @return <例子:138******1234>
|
||||
*/
|
||||
private static String mobilePhone(String num) {
|
||||
if (oConvertUtils.isEmpty(num)) {
|
||||
return "";
|
||||
}
|
||||
int len = num.length();
|
||||
if(len<11){
|
||||
return num;
|
||||
}
|
||||
return formatBetween(num, 3, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护
|
||||
* @param address 地址
|
||||
* @param sensitiveSize 敏感信息长度
|
||||
* @return <例子:北京市海淀区****>
|
||||
*/
|
||||
private static String address(String address, int sensitiveSize) {
|
||||
if (oConvertUtils.isEmpty(address)) {
|
||||
return "";
|
||||
}
|
||||
int len = address.length();
|
||||
if(len<sensitiveSize){
|
||||
return address;
|
||||
}
|
||||
return formatRight(address, sensitiveSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示
|
||||
* @param email 电子邮箱
|
||||
* @return <例子:g**@163.com>
|
||||
*/
|
||||
private static String email(String email) {
|
||||
if (oConvertUtils.isEmpty(email)) {
|
||||
return "";
|
||||
}
|
||||
int index = email.indexOf("@");
|
||||
if (index <= 1){
|
||||
return email;
|
||||
}
|
||||
String begin = email.substring(0, 1);
|
||||
String end = email.substring(index);
|
||||
String stars = "**";
|
||||
return begin + stars + end;
|
||||
}
|
||||
|
||||
/**
|
||||
* [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号
|
||||
* @param cardNum 银行卡号
|
||||
* @return <例子:6222600**********1234>
|
||||
*/
|
||||
private static String bankCard(String cardNum) {
|
||||
if (oConvertUtils.isEmpty(cardNum)) {
|
||||
return "";
|
||||
}
|
||||
return formatBetween(cardNum, 6, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号
|
||||
* @param code 公司开户银行联号
|
||||
* @return <例子:12********>
|
||||
*/
|
||||
private static String cnapsCode(String code) {
|
||||
if (oConvertUtils.isEmpty(code)) {
|
||||
return "";
|
||||
}
|
||||
return formatRight(code, 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将右边的格式化成*
|
||||
* @param str 字符串
|
||||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatRight(String str, int reservedLength){
|
||||
String name = str.substring(0, reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(str.length()-reservedLength, "*"));
|
||||
return name + stars;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将左边的格式化成*
|
||||
* @param str 字符串
|
||||
* @param reservedLength 保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatLeft(String str, int reservedLength){
|
||||
int len = str.length();
|
||||
String show = str.substring(len-reservedLength);
|
||||
String stars = String.join("", Collections.nCopies(len-reservedLength, "*"));
|
||||
return stars + show;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中间的格式化成*
|
||||
* @param str 字符串
|
||||
* @param beginLen 开始保留长度
|
||||
* @param endLen 结尾保留长度
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
private static String formatBetween(String str, int beginLen, int endLen){
|
||||
int len = str.length();
|
||||
String begin = str.substring(0, beginLen);
|
||||
String end = str.substring(len-endLen);
|
||||
String stars = String.join("", Collections.nCopies(len-beginLen-endLen, "*"));
|
||||
return begin + stars + end;
|
||||
}
|
||||
|
||||
}
|
||||
@ -123,7 +123,8 @@ public class JeecgBootExceptionHandler {
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("字段太长,超出数据库字段的长度");
|
||||
//【issues/3624】数据库执行异常handleDataIntegrityViolationException提示有误 #3624
|
||||
return Result.error("执行数据库异常,违反了完整性例如:违反惟一约束、违反非空限制、字段内容超出长度等");
|
||||
}
|
||||
|
||||
@ExceptionHandler(PoolException.class)
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package org.jeecg.common.system.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 将枚举类转化成字典数据
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/8 10:34
|
||||
**/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface EnumDict {
|
||||
|
||||
/**
|
||||
* 作为字典数据的唯一编码
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
@ -53,18 +53,14 @@ public class JeecgController<T, S extends IService<T>> {
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
// Step.2 获取导出数据
|
||||
List<T> pageList = service.list(queryWrapper);
|
||||
List<T> exportList = null;
|
||||
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
|
||||
} else {
|
||||
exportList = pageList;
|
||||
queryWrapper.in("id",selectionList);
|
||||
}
|
||||
// Step.2 获取导出数据
|
||||
List<T> exportList = service.list(queryWrapper);
|
||||
|
||||
// Step.3 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
@ -97,21 +93,20 @@ public class JeecgController<T, S extends IService<T>> {
|
||||
// Step.2 计算分页sheet数据
|
||||
double total = service.count();
|
||||
int count = (int)Math.ceil(total/pageNum);
|
||||
// Step.3 多sheet处理
|
||||
//update-begin-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
||||
// Step.3 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
queryWrapper.in("id",selectionList);
|
||||
}
|
||||
//update-end-author:liusq---date:20220629--for: 多sheet导出根据选择导出写法调整 ---
|
||||
// Step.4 多sheet处理
|
||||
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
|
||||
for (int i = 1; i <=count ; i++) {
|
||||
Page<T> page = new Page<T>(i, pageNum);
|
||||
IPage<T> pageList = service.page(page, queryWrapper);
|
||||
List<T> 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;
|
||||
}
|
||||
List<T> exportList = pageList.getRecords();
|
||||
Map<String, Object> map = new HashMap<>(5);
|
||||
ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath);
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
|
||||
@ -16,6 +16,7 @@ import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.util.JeecgDataAutorUtils;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
|
||||
@ -191,8 +192,8 @@ public class QueryGenerator {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
// 排序逻辑 处理
|
||||
doMultiFieldsOrder(queryWrapper, parameterMap);
|
||||
// 排序逻辑 处理
|
||||
doMultiFieldsOrder(queryWrapper, parameterMap, fieldColumnMap.keySet());
|
||||
|
||||
//高级查询
|
||||
doSuperQuery(queryWrapper, parameterMap, fieldColumnMap);
|
||||
@ -228,8 +229,7 @@ public class QueryGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**多字段排序 TODO 需要修改前端*/
|
||||
private static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
|
||||
private static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap, Set<String> allFields) {
|
||||
String column=null,order=null;
|
||||
if(parameterMap!=null&& parameterMap.containsKey(ORDER_COLUMN)) {
|
||||
column = parameterMap.get(ORDER_COLUMN)[0];
|
||||
@ -243,6 +243,15 @@ public class QueryGenerator {
|
||||
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
|
||||
column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-5-16 for: issues/3676 获取系统用户列表时,使用SQL注入生效
|
||||
//判断column是不是当前实体的
|
||||
log.info("当前字段有:"+ allFields);
|
||||
if (!allColumnExist(column, allFields)) {
|
||||
throw new JeecgBootException("请注意,将要排序的列字段不存在:" + column);
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-16 for: issues/3676 获取系统用户列表时,使用SQL注入生效
|
||||
|
||||
//SQL注入check
|
||||
SqlInjectionUtil.filterContent(column);
|
||||
|
||||
@ -264,6 +273,28 @@ public class QueryGenerator {
|
||||
//update-end--Author:scott Date:20210531 for:36 多条件排序无效问题修正-------
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-5-23 for: issues/3676 获取系统用户列表时,使用SQL注入生效
|
||||
/**
|
||||
* 多字段排序 判断所传字段是否存在
|
||||
* @return
|
||||
*/
|
||||
private static boolean allColumnExist(String columnStr, Set<String> allFields){
|
||||
boolean exist = true;
|
||||
if(columnStr.indexOf(COMMA)>=0){
|
||||
String[] arr = columnStr.split(COMMA);
|
||||
for(String column: arr){
|
||||
if(!allFields.contains(column)){
|
||||
exist = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
exist = allFields.contains(columnStr);
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-23 for: issues/3676 获取系统用户列表时,使用SQL注入生效
|
||||
|
||||
/**
|
||||
* 高级查询
|
||||
@ -825,13 +856,13 @@ public class QueryGenerator {
|
||||
res = field + " in "+getInConditionValue(value, isString);
|
||||
break;
|
||||
case LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value);
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.LIKE);
|
||||
break;
|
||||
case LEFT_LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value);
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.LEFT_LIKE);
|
||||
break;
|
||||
case RIGHT_LIKE:
|
||||
res = field + " like "+getLikeConditionValue(value);
|
||||
res = field + " like "+getLikeConditionValue(value, QueryRuleEnum.RIGHT_LIKE);
|
||||
break;
|
||||
default:
|
||||
res = field+" = "+getFieldConditionValue(value, isString, dataBaseType);
|
||||
@ -914,8 +945,15 @@ public class QueryGenerator {
|
||||
}
|
||||
//update-end-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错
|
||||
}
|
||||
|
||||
private static String getLikeConditionValue(Object value) {
|
||||
|
||||
/**
|
||||
* 先根据值判断 走左模糊还是右模糊
|
||||
* 最后如果值不带任何标识(*或者%),则再根据ruleEnum判断
|
||||
* @param value
|
||||
* @param ruleEnum
|
||||
* @return
|
||||
*/
|
||||
private static String getLikeConditionValue(Object value, QueryRuleEnum ruleEnum) {
|
||||
String str = value.toString().trim();
|
||||
if(str.startsWith(SymbolConstant.ASTERISK) && str.endsWith(SymbolConstant.ASTERISK)) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
@ -951,11 +989,30 @@ public class QueryGenerator {
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
return "N'%"+str+"%'";
|
||||
}else{
|
||||
return "'%"+str+"%'";
|
||||
|
||||
//update-begin-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题
|
||||
// 走到这里说明 value不带有任何模糊查询的标识(*或者%)
|
||||
if (ruleEnum == QueryRuleEnum.LEFT_LIKE) {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'%" + str + "'";
|
||||
} else {
|
||||
return "'%" + str + "'";
|
||||
}
|
||||
} else if (ruleEnum == QueryRuleEnum.RIGHT_LIKE) {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'" + str + "%'";
|
||||
} else {
|
||||
return "'" + str + "%'";
|
||||
}
|
||||
} else {
|
||||
if (DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())) {
|
||||
return "N'%" + str + "%'";
|
||||
} else {
|
||||
return "'%" + str + "%'";
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-6-30 for: issues/3810 数据权限规则问题
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public class JwtUtil {
|
||||
try {
|
||||
os = httpServletResponse.getOutputStream();
|
||||
httpServletResponse.setCharacterEncoding("UTF-8");
|
||||
httpServletResponse.setStatus(401);
|
||||
httpServletResponse.setStatus(code);
|
||||
os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8"));
|
||||
os.flush();
|
||||
os.close();
|
||||
|
||||
@ -0,0 +1,111 @@
|
||||
package org.jeecg.common.system.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.system.annotation.EnumDict;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 资源加载工具类
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/8 10:40
|
||||
**/
|
||||
@Slf4j
|
||||
public class ResourceUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 枚举字典数据
|
||||
*/
|
||||
private final static Map<String, List<DictModel>> enumDictData = new HashMap<>(5);
|
||||
|
||||
/**
|
||||
* 所有java类
|
||||
*/
|
||||
private final static String CLASS_PATTERN="/**/*.class";
|
||||
|
||||
/**
|
||||
* 包路径 org.jeecg
|
||||
*/
|
||||
private final static String BASE_PACKAGE = "org.jeecg";
|
||||
|
||||
/**
|
||||
* 枚举类中获取字典数据的方法名
|
||||
*/
|
||||
private final static String METHOD_NAME = "getDictList";
|
||||
|
||||
/**
|
||||
* 获取枚举类对应的字典数据 SysDictServiceImpl#queryAllDictItems()
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<DictModel>> getEnumDictData(){
|
||||
if(enumDictData.keySet().size()>0){
|
||||
return enumDictData;
|
||||
}
|
||||
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + CLASS_PATTERN;
|
||||
try {
|
||||
Resource[] resources = resourcePatternResolver.getResources(pattern);
|
||||
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
|
||||
for (Resource resource : resources) {
|
||||
MetadataReader reader = readerFactory.getMetadataReader(resource);
|
||||
String classname = reader.getClassMetadata().getClassName();
|
||||
Class<?> clazz = Class.forName(classname);
|
||||
EnumDict enumDict = clazz.getAnnotation(EnumDict.class);
|
||||
if (enumDict != null) {
|
||||
EnumDict annotation = clazz.getAnnotation(EnumDict.class);
|
||||
String key = annotation.value();
|
||||
if(oConvertUtils.isNotEmpty(key)){
|
||||
List<DictModel> list = (List<DictModel>) clazz.getDeclaredMethod(METHOD_NAME).invoke(null);
|
||||
enumDictData.put(key, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("获取枚举类字典数据异常", e.getMessage());
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return enumDictData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于后端字典翻译 SysDictServiceImpl#queryManyDictByKeys(java.util.List, java.util.List)
|
||||
* @param dictCodeList
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, List<DictModel>> queryManyDictByKeys(List<String> dictCodeList, List<String> keys){
|
||||
if(enumDictData.keySet().size()==0){
|
||||
getEnumDictData();
|
||||
}
|
||||
Map<String, List<DictModel>> map = new HashMap<>();
|
||||
for (String code : enumDictData.keySet()) {
|
||||
if(dictCodeList.indexOf(code)>=0){
|
||||
List<DictModel> dictItemList = enumDictData.get(code);
|
||||
for(DictModel dm: dictItemList){
|
||||
String value = dm.getValue();
|
||||
if(keys.indexOf(value)>=0){
|
||||
List<DictModel> list = new ArrayList<>();
|
||||
list.add(new DictModel(value, dm.getText()));
|
||||
map.put(code,list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,6 +2,7 @@ package org.jeecg.common.system.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jeecg.common.desensitization.annotation.SensitiveField;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
@ -26,21 +27,25 @@ public class LoginUser {
|
||||
/**
|
||||
* 登录人id
|
||||
*/
|
||||
@SensitiveField
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 登录人账号
|
||||
*/
|
||||
@SensitiveField
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 登录人名字
|
||||
*/
|
||||
@SensitiveField
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* 登录人密码
|
||||
*/
|
||||
@SensitiveField
|
||||
private String password;
|
||||
|
||||
/**
|
||||
@ -50,11 +55,13 @@ public class LoginUser {
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
@SensitiveField
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
@SensitiveField
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date birthday;
|
||||
@ -67,11 +74,13 @@ public class LoginUser {
|
||||
/**
|
||||
* 电子邮件
|
||||
*/
|
||||
@SensitiveField
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@SensitiveField
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
@ -103,11 +112,13 @@ public class LoginUser {
|
||||
/**
|
||||
* 职务,关联职务表
|
||||
*/
|
||||
@SensitiveField
|
||||
private String post;
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
@SensitiveField
|
||||
private String telephone;
|
||||
|
||||
/**多租户id配置,编辑用户的时候设置*/
|
||||
|
||||
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
import org.jeecg.common.constant.ServiceNameConstants;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.util.filter.FileTypeFilter;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
@ -314,14 +315,14 @@ public class CommonUtils {
|
||||
*/
|
||||
public static String getBaseUrl(HttpServletRequest request) {
|
||||
//1.【兼容】兼容微服务下的 base path-------
|
||||
String xGatewayBasePath = request.getHeader("X_GATEWAY_BASE_PATH");
|
||||
String xGatewayBasePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH);
|
||||
if(oConvertUtils.isNotEmpty(xGatewayBasePath)){
|
||||
log.info("x_gateway_base_path = "+ xGatewayBasePath);
|
||||
return xGatewayBasePath;
|
||||
}
|
||||
//2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题
|
||||
// https://blog.csdn.net/weixin_34376986/article/details/89767950
|
||||
String scheme = request.getHeader("X-Forwarded-Scheme");
|
||||
String scheme = request.getHeader(CommonConstant.X_FORWARDED_SCHEME);
|
||||
if(oConvertUtils.isEmpty(scheme)){
|
||||
scheme = request.getScheme();
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class RestUtil {
|
||||
}
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null) {
|
||||
if (variables != null && !variables.isEmpty()) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
|
||||
@ -4,6 +4,8 @@ import cn.hutool.crypto.SecureUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@ -20,7 +22,11 @@ public class SqlInjectionUtil {
|
||||
private final static String TABLE_DICT_SIGN_SALT = "20200501";
|
||||
private final static String XSS_STR = "and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";
|
||||
|
||||
/**show tables*/
|
||||
/**
|
||||
* 正则 user() 匹配更严谨
|
||||
*/
|
||||
private final static String REGULAR_EXPRE_USER = "user[\\s]*\\([\\s]*\\)";
|
||||
/**正则 show tables*/
|
||||
private final static String SHOW_TABLES = "show\\s+tables";
|
||||
|
||||
/**
|
||||
@ -42,6 +48,13 @@ public class SqlInjectionUtil {
|
||||
log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
* @param value
|
||||
*/
|
||||
public static void filterContent(String value) {
|
||||
filterContent(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
@ -49,7 +62,7 @@ public class SqlInjectionUtil {
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String value) {
|
||||
public static void filterContent(String value, String customXssString) {
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
}
|
||||
@ -66,19 +79,39 @@ public class SqlInjectionUtil {
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if (customXssString != null) {
|
||||
String[] xssArr2 = customXssString.split("\\|");
|
||||
for (int i = 0; i < xssArr2.length; i++) {
|
||||
if (value.indexOf(xssArr2[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
* @param values
|
||||
*/
|
||||
public static void filterContent(String[] values) {
|
||||
filterContent(values, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
*
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
public static void filterContent(String[] values) {
|
||||
public static void filterContent(String[] values, String customXssString) {
|
||||
String[] xssArr = XSS_STR.split("\\|");
|
||||
for (String value : values) {
|
||||
if (value == null || "".equals(value)) {
|
||||
@ -96,7 +129,19 @@ public class SqlInjectionUtil {
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
//update-begin-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if (customXssString != null) {
|
||||
String[] xssArr2 = customXssString.split("\\|");
|
||||
for (int i = 0; i < xssArr2.length; i++) {
|
||||
if (value.indexOf(xssArr2[i]) > -1) {
|
||||
log.error("请注意,存在SQL注入关键词---> {}", xssArr2[i]);
|
||||
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-13 for: 除了XSS_STR这些提前设置好的,还需要额外的校验比如 单引号
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
@ -111,8 +156,8 @@ public class SqlInjectionUtil {
|
||||
* @return
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContent(String value) {
|
||||
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|";
|
||||
public static void specialFilterContentForDictSql(String value) {
|
||||
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|user()";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
@ -129,7 +174,7 @@ public class SqlInjectionUtil {
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
}
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
@ -144,7 +189,7 @@ public class SqlInjectionUtil {
|
||||
*/
|
||||
//@Deprecated
|
||||
public static void specialFilterContentForOnlineReport(String value) {
|
||||
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
|
||||
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |user()";
|
||||
String[] xssArr = specialXssStr.split("\\|");
|
||||
if (value == null || "".equals(value)) {
|
||||
return;
|
||||
@ -162,10 +207,53 @@ public class SqlInjectionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if(Pattern.matches(SHOW_TABLES, value)){
|
||||
if(Pattern.matches(SHOW_TABLES, value) || Pattern.matches(REGULAR_EXPRE_USER, value)){
|
||||
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断给定的字段是不是类中的属性
|
||||
* @param field 字段名
|
||||
* @param clazz 类对象
|
||||
* @return
|
||||
*/
|
||||
public static boolean isClassField(String field, Class clazz){
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for(int i=0;i<fields.length;i++){
|
||||
String fieldName = fields[i].getName();
|
||||
String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
|
||||
if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定的多个字段是不是类中的属性
|
||||
* @param fieldSet 字段名set
|
||||
* @param clazz 类对象
|
||||
* @return
|
||||
*/
|
||||
public static boolean isClassField(Set<String> fieldSet, Class clazz){
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
for(String field: fieldSet){
|
||||
boolean exist = false;
|
||||
for(int i=0;i<fields.length;i++){
|
||||
String fieldName = fields[i].getName();
|
||||
String tableColumnName = oConvertUtils.camelToUnderline(fieldName);
|
||||
if(fieldName.equalsIgnoreCase(field) || tableColumnName.equalsIgnoreCase(field)){
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!exist){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
|
||||
import org.jeecg.common.exception.JeecgBoot401Exception;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
@ -106,9 +107,16 @@ public class TokenUtils {
|
||||
public static LoginUser getLoginUser(String username, CommonAPI commonApi, RedisUtil redisUtil) {
|
||||
LoginUser loginUser = null;
|
||||
String loginUserKey = CacheConstant.SYS_USERS_CACHE + "::" + username;
|
||||
if(redisUtil.hasKey(loginUserKey)){
|
||||
loginUser = (LoginUser) redisUtil.get(loginUserKey);
|
||||
}else{
|
||||
//【重要】此处通过redis原生获取缓存用户,是为了解决微服务下system服务挂了,其他服务互调不通问题---
|
||||
if (redisUtil.hasKey(loginUserKey)) {
|
||||
try {
|
||||
loginUser = (LoginUser) redisUtil.get(loginUserKey);
|
||||
//解密用户
|
||||
SensitiveInfoUtil.handlerObject(loginUser, false);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
// 查询用户信息
|
||||
loginUser = commonApi.getUserByName(username);
|
||||
}
|
||||
|
||||
@ -66,22 +66,20 @@ public class AesEncryptUtil {
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String desEncrypt(String data, String key, String iv) throws Exception {
|
||||
try {
|
||||
byte[] encrypted1 = Base64.decode(data);
|
||||
//update-begin-author:taoyan date:2022-5-23 for:VUEN-1084 【vue3】online表单测试发现的新问题 6、解密报错 ---解码失败应该把异常抛出去,在外面处理
|
||||
byte[] encrypted1 = Base64.decode(data);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
|
||||
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
return originalString;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
//加密解码后的字符串会出现\u0000
|
||||
return originalString.replaceAll("\\u0000", "");
|
||||
//update-end-author:taoyan date:2022-5-23 for:VUEN-1084 【vue3】online表单测试发现的新问题 6、解密报错 ---解码失败应该把异常抛出去,在外面处理
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -168,7 +168,7 @@ public abstract class AbstractQueryBlackListHandler {
|
||||
|
||||
public String getError(){
|
||||
// TODO
|
||||
return "sql黑名单校验不通过,请联系管理员!";
|
||||
return "系统设置了安全规则,敏感表和敏感字段禁止查询,联系管理员授权!";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import org.jeecg.config.vo.DomainUrl;
|
||||
import org.jeecg.config.vo.Path;
|
||||
import org.jeecg.config.vo.Shiro;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -9,9 +11,15 @@ import org.springframework.stereotype.Component;
|
||||
* 加载项目配置
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Component("jeeccgBaseConfig")
|
||||
@Component("jeecgBaseConfig")
|
||||
@ConfigurationProperties(prefix = "jeecg")
|
||||
public class JeeccgBaseConfig {
|
||||
public class JeecgBaseConfig {
|
||||
/**
|
||||
* 签名密钥串(字典等敏感接口)
|
||||
* @TODO 降低使用成本加的默认值,实际以 yml配置 为准
|
||||
*/
|
||||
private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
|
||||
|
||||
/**
|
||||
* 是否启用安全模式
|
||||
*/
|
||||
@ -21,10 +29,16 @@ public class JeeccgBaseConfig {
|
||||
*/
|
||||
private Shiro shiro;
|
||||
/**
|
||||
* 签名密钥串(字典等敏感接口)
|
||||
* @TODO 降低使用成本加的默认值,实际以 yml配置 为准
|
||||
* 上传文件配置
|
||||
*/
|
||||
private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
|
||||
private Path path;
|
||||
|
||||
/**
|
||||
* 前端页面访问地址
|
||||
* pc: http://localhost:3100
|
||||
* app: http://localhost:8051
|
||||
*/
|
||||
private DomainUrl domainUrl;
|
||||
|
||||
public Boolean getSafeMode() {
|
||||
return safeMode;
|
||||
@ -49,4 +63,20 @@ public class JeeccgBaseConfig {
|
||||
public void setShiro(Shiro shiro) {
|
||||
this.shiro = shiro;
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public DomainUrl getDomainUrl() {
|
||||
return domainUrl;
|
||||
}
|
||||
|
||||
public void setDomainUrl(DomainUrl domainUrl) {
|
||||
this.domainUrl = domainUrl;
|
||||
}
|
||||
}
|
||||
@ -145,4 +145,13 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
return () -> meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, "");
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 注册拦截器【拦截器拦截参数,自动切换数据源——后期实现多租户切换数据源功能】
|
||||
// * @param registry
|
||||
// */
|
||||
// @Override
|
||||
// public void addInterceptors(InterceptorRegistry registry) {
|
||||
// registry.addInterceptor(new DynamicDatasourceInterceptor()).addPathPatterns("/test/dynamic/**");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.config;
|
||||
|
||||
import org.jeecg.config.filter.WebsocketFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
@ -19,4 +21,17 @@ public class WebSocketConfig {
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebsocketFilter websocketFilter(){
|
||||
return new WebsocketFilter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean getFilterRegistrationBean(){
|
||||
FilterRegistrationBean bean = new FilterRegistrationBean();
|
||||
bean.setFilter(websocketFilter());
|
||||
bean.addUrlPatterns("/websocket/*", "/eoaSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package org.jeecg.config.filter;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.config.sign.util.BodyReaderHttpServletRequestWrapper;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 针对post请求,将HttpServletRequest包一层 保留body里的参数
|
||||
* @Author taoYan
|
||||
* @Date 2022/4/25 19:19
|
||||
**/
|
||||
public class RequestBodyReserveFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
ServletRequest requestWrapper = null;
|
||||
|
||||
if(servletRequest instanceof HttpServletRequest) {
|
||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
||||
// POST请求类型,才获取POST请求体
|
||||
if(CommonConstant.HTTP_POST.equals(req.getMethod())){
|
||||
requestWrapper = new BodyReaderHttpServletRequestWrapper(req);
|
||||
}
|
||||
}
|
||||
|
||||
if(requestWrapper == null) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
} else {
|
||||
filterChain.doFilter(requestWrapper, servletResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package org.jeecg.config.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.CommonAPI;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* websocket 前端将token放到子协议里传入 与后端建立连接时需要用到http协议,此处用于校验token的有效性
|
||||
* @Author taoYan
|
||||
* @Date 2022/4/21 17:01
|
||||
**/
|
||||
@Slf4j
|
||||
public class WebsocketFilter implements Filter {
|
||||
|
||||
private static final String TOKEN_KEY = "Sec-WebSocket-Protocol";
|
||||
|
||||
private static CommonAPI commonApi;
|
||||
|
||||
private static RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
if (commonApi == null) {
|
||||
commonApi = SpringContextUtils.getBean(CommonAPI.class);
|
||||
}
|
||||
if (redisUtil == null) {
|
||||
redisUtil = SpringContextUtils.getBean(RedisUtil.class);
|
||||
}
|
||||
HttpServletRequest request = (HttpServletRequest)servletRequest;
|
||||
String token = request.getHeader(TOKEN_KEY);
|
||||
|
||||
log.info("websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);
|
||||
|
||||
try {
|
||||
TokenUtils.verifyToken(token, commonApi, redisUtil);
|
||||
} catch (Exception exception) {
|
||||
log.error("websocket连接校验失败,{},token:{}", exception.getMessage(), token);
|
||||
return;
|
||||
}
|
||||
HttpServletResponse response = (HttpServletResponse)servletResponse;
|
||||
response.setHeader(TOKEN_KEY, token);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,6 +3,9 @@ package org.jeecg.config.mybatis;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -71,9 +74,35 @@ public class MybatisPlusSaasConfig {
|
||||
}
|
||||
}));
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||
//update-begin-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
|
||||
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor());
|
||||
//update-end-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态表名切换拦截器,用于适配vue2和vue3同一个表有多个的情况,如sys_role_index在vue3情况下表名为sys_role_index_v3
|
||||
* @return
|
||||
*/
|
||||
private DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {
|
||||
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
|
||||
dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
|
||||
//获取需要动态解析的表名
|
||||
String dynamicTableName = ThreadLocalDataHelper.get(CommonConstant.DYNAMIC_TABLE_NAME);
|
||||
//当dynamicTableName不为空时才走动态表名处理逻辑,否则返回原始表名
|
||||
if (ObjectUtil.isNotEmpty(dynamicTableName) && dynamicTableName.equals(tableName)) {
|
||||
// 获取前端传递的版本号标识
|
||||
Object version = ThreadLocalDataHelper.get(CommonConstant.VERSION);
|
||||
if (ObjectUtil.isNotEmpty(version)) {
|
||||
//拼接表名规则(原始表名+下划线+前端传递的版本号)
|
||||
return tableName + "_" + version;
|
||||
}
|
||||
}
|
||||
return tableName;
|
||||
});
|
||||
return dynamicTableNameInnerInterceptor;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 下个版本会删除,现在为了避免缓存出现问题不得不配置
|
||||
// * @return
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
package org.jeecg.config.mybatis;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 本地线程变量存储工具类
|
||||
* @author: lsq
|
||||
* @date: 2022年03月25日 11:42
|
||||
*/
|
||||
public class ThreadLocalDataHelper {
|
||||
/**
|
||||
* 线程的本地变量
|
||||
*/
|
||||
private static final ThreadLocal<ConcurrentHashMap> REQUEST_DATA = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 存储本地参数
|
||||
*/
|
||||
private static final ConcurrentHashMap DATA_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 设置请求参数
|
||||
*
|
||||
* @param key 参数key
|
||||
* @param value 参数值
|
||||
*/
|
||||
public static void put(String key, Object value) {
|
||||
if(ObjectUtil.isNotEmpty(value)) {
|
||||
DATA_MAP.put(key, value);
|
||||
REQUEST_DATA.set(DATA_MAP);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数值
|
||||
*
|
||||
* @param key 请求参数
|
||||
* @return
|
||||
*/
|
||||
public static <T> T get(String key) {
|
||||
ConcurrentHashMap dataMap = REQUEST_DATA.get();
|
||||
if (CollectionUtils.isNotEmpty(dataMap)) {
|
||||
return (T) dataMap.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数
|
||||
*
|
||||
* @return 请求参数 MAP 对象
|
||||
*/
|
||||
public static void clear() {
|
||||
DATA_MAP.clear();
|
||||
REQUEST_DATA.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
package org.jeecg.config.mybatis.aspect;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.jeecg.common.aspect.annotation.DynamicTable;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.config.mybatis.ThreadLocalDataHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 动态table切换 切面处理
|
||||
*
|
||||
* @author :zyf
|
||||
* @date:2020-04-25
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class DynamicTableAspect {
|
||||
|
||||
|
||||
/**
|
||||
* 定义切面拦截切入点
|
||||
*/
|
||||
@Pointcut("@annotation(org.jeecg.common.aspect.annotation.DynamicTable)")
|
||||
public void dynamicTable() {
|
||||
}
|
||||
|
||||
|
||||
@Around("dynamicTable()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
DynamicTable dynamicTable = method.getAnnotation(DynamicTable.class);
|
||||
HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
|
||||
//获取前端传递的版本标记
|
||||
String version = request.getHeader(CommonConstant.VERSION);
|
||||
//存储版本号到本地线程变量
|
||||
ThreadLocalDataHelper.put(CommonConstant.VERSION, version);
|
||||
//存储表名到本地线程变量
|
||||
ThreadLocalDataHelper.put(CommonConstant.DYNAMIC_TABLE_NAME, dynamicTable.value());
|
||||
//执行方法
|
||||
Object result = point.proceed();
|
||||
//清空本地变量
|
||||
ThreadLocalDataHelper.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package org.jeecg.config.mybatis.interceptor;
|
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 动态数据源切换拦截器
|
||||
*
|
||||
* 测试:拦截参数,自动切换数据源
|
||||
* 未来规划:后面通过此机制,实现多租户切换数据源功能
|
||||
* @author zyf
|
||||
*/
|
||||
@Slf4j
|
||||
public class DynamicDatasourceInterceptor implements HandlerInterceptor {
|
||||
|
||||
/**
|
||||
* 在请求处理之前进行调用(Controller方法调用之前)
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.info("经过多数据源Interceptor,当前路径是{}", requestURI);
|
||||
//获取动态数据源名称
|
||||
String dsName = request.getParameter("dsName");
|
||||
String dsKey = "master";
|
||||
if (StringUtils.isNotEmpty(dsName)) {
|
||||
dsKey = dsName;
|
||||
}
|
||||
DynamicDataSourceContextHolder.push(dsKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
|
||||
*/
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
DynamicDataSourceContextHolder.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ import org.crazycake.shiro.RedisClusterManager;
|
||||
import org.crazycake.shiro.RedisManager;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeeccgBaseConfig;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
|
||||
import org.jeecg.config.shiro.filters.JwtFilter;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
@ -45,11 +45,11 @@ import java.util.*;
|
||||
public class ShiroConfig {
|
||||
|
||||
@Resource
|
||||
LettuceConnectionFactory lettuceConnectionFactory;
|
||||
private LettuceConnectionFactory lettuceConnectionFactory;
|
||||
@Autowired
|
||||
private Environment env;
|
||||
@Autowired
|
||||
JeeccgBaseConfig jeeccgBaseConfig;
|
||||
@Resource
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* Filter Chain定义说明
|
||||
@ -64,11 +64,15 @@ public class ShiroConfig {
|
||||
shiroFilterFactoryBean.setSecurityManager(securityManager);
|
||||
// 拦截器
|
||||
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
|
||||
String shiroExcludeUrls = jeeccgBaseConfig.getShiro().getExcludeUrls();
|
||||
if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
|
||||
String[] permissionUrl = shiroExcludeUrls.split(",");
|
||||
for(String url : permissionUrl){
|
||||
filterChainDefinitionMap.put(url,"anon");
|
||||
|
||||
//支持yml方式,配置拦截排除
|
||||
if(jeecgBaseConfig.getShiro()!=null){
|
||||
String shiroExcludeUrls = jeecgBaseConfig.getShiro().getExcludeUrls();
|
||||
if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
|
||||
String[] permissionUrl = shiroExcludeUrls.split(",");
|
||||
for(String url : permissionUrl){
|
||||
filterChainDefinitionMap.put(url,"anon");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 配置不会被拦截的链接 顺序判断
|
||||
@ -125,9 +129,11 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/jmreport/**", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.js.map", "anon");
|
||||
filterChainDefinitionMap.put("/**/*.css.map", "anon");
|
||||
|
||||
//测试示例
|
||||
filterChainDefinitionMap.put("/test/bigScreen/**", "anon"); //大屏模板例子
|
||||
|
||||
//大屏模板例子
|
||||
filterChainDefinitionMap.put("/test/bigScreen/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
filterChainDefinitionMap.put("/bigscreen/template1/**", "anon");
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
|
||||
//filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
|
||||
@ -137,8 +143,6 @@ public class ShiroConfig {
|
||||
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
|
||||
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
|
||||
|
||||
//wps
|
||||
filterChainDefinitionMap.put("/v1/**","anon");
|
||||
|
||||
//性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
|
||||
filterChainDefinitionMap.put("/actuator/**", "anon");
|
||||
|
||||
@ -69,13 +69,13 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
|
||||
// 设置用户拥有的角色集合,比如“admin,test”
|
||||
Set<String> roleSet = commonApi.queryUserRoles(username);
|
||||
System.out.println(roleSet.toString());
|
||||
//System.out.println(roleSet.toString());
|
||||
info.setRoles(roleSet);
|
||||
|
||||
// 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
|
||||
Set<String> permissionSet = commonApi.queryUserAuths(username);
|
||||
info.addStringPermissions(permissionSet);
|
||||
System.out.println(permissionSet);
|
||||
//System.out.println(permissionSet);
|
||||
log.info("===============Shiro权限认证成功==============");
|
||||
return info;
|
||||
}
|
||||
@ -123,7 +123,7 @@ public class ShiroRealm extends AuthorizingRealm {
|
||||
|
||||
// 查询用户信息
|
||||
log.debug("———校验token是否有效————checkUserTokenIsEffect——————— "+ token);
|
||||
LoginUser loginUser = TokenUtils.getLoginUser(username,commonApi,redisUtil);
|
||||
LoginUser loginUser = TokenUtils.getLoginUser(username, commonApi, redisUtil);
|
||||
//LoginUser loginUser = commonApi.getUserByName(username);
|
||||
if (loginUser == null) {
|
||||
throw new AuthenticationException("用户不存在!");
|
||||
|
||||
@ -107,4 +107,18 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||
|
||||
return super.preHandle(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* JwtFilter中ThreadLocal需要及时清除 #3634
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param exception
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(ServletRequest request, ServletResponse response, Exception exception) throws Exception {
|
||||
//log.info("------清空线程中多租户的ID={}------",TenantContext.getTenant());
|
||||
TenantContext.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.config.sign.interceptor;
|
||||
|
||||
import org.jeecg.config.filter.RequestBodyReserveFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
@ -24,4 +26,22 @@ public class SignAuthConfiguration implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(signAuthInterceptor()).addPathPatterns(SIGN_URL_LIST);
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:20220427 for: issues/I53J5E post请求X_SIGN签名拦截校验后报错, request body 为空
|
||||
@Bean
|
||||
public RequestBodyReserveFilter requestBodyReserveFilter(){
|
||||
return new RequestBodyReserveFilter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean reqBodyFilterRegistrationBean(){
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(requestBodyReserveFilter());
|
||||
registration.setName("requestBodyReserveFilter");
|
||||
// 建议此处只添加post请求地址而不是所有的都需要走过滤器
|
||||
registration.addUrlPatterns(SIGN_URL_LIST);
|
||||
return registration;
|
||||
}
|
||||
//update-end-author:taoyan date:20220427 for: issues/I53J5E post请求X_SIGN签名拦截校验后报错, request body 为空
|
||||
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ public class SignAuthInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
log.info("request URI = " + request.getRequestURI());
|
||||
log.info("Sign Interceptor request URI = " + request.getRequestURI());
|
||||
HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
|
||||
//获取全部参数(包括URL和body上的)
|
||||
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestWrapper);
|
||||
|
||||
@ -6,7 +6,7 @@ import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeeccgBaseConfig;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ -48,8 +48,8 @@ public class SignUtil {
|
||||
String paramsJsonStr = JSONObject.toJSONString(params);
|
||||
log.info("Param paramsJsonStr : {}", paramsJsonStr);
|
||||
//设置签名秘钥
|
||||
JeeccgBaseConfig jeeccgBaseConfig = SpringContextUtils.getBean(JeeccgBaseConfig.class);
|
||||
String signatureSecret = jeeccgBaseConfig.getSignatureSecret();
|
||||
JeecgBaseConfig jeecgBaseConfig = SpringContextUtils.getBean(JeecgBaseConfig.class);
|
||||
String signatureSecret = jeecgBaseConfig.getSignatureSecret();
|
||||
String curlyBracket = SymbolConstant.DOLLAR + SymbolConstant.LEFT_CURLY_BRACKET;
|
||||
if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains(curlyBracket)){
|
||||
throw new JeecgBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 !!");
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package org.jeecg.config.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author taoYan
|
||||
* @Date 2022/7/5 21:16
|
||||
**/
|
||||
@Data
|
||||
public class DomainUrl {
|
||||
|
||||
private String pc;
|
||||
|
||||
private String app;
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package org.jeecg.config.vo;
|
||||
|
||||
import javax.print.DocFlavor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: scott
|
||||
* @date: 2022年04月18日 20:35
|
||||
*/
|
||||
public class Path {
|
||||
private String upload;
|
||||
private String webapp;
|
||||
|
||||
public String getUpload() {
|
||||
return upload;
|
||||
}
|
||||
|
||||
public void setUpload(String upload) {
|
||||
this.upload = upload;
|
||||
}
|
||||
|
||||
public String getWebapp() {
|
||||
return webapp;
|
||||
}
|
||||
|
||||
public void setWebapp(String webapp) {
|
||||
this.webapp = webapp;
|
||||
}
|
||||
}
|
||||
@ -4,19 +4,22 @@
|
||||
|
||||
<!-- 保存日志11 -->
|
||||
<insert id="saveLog" parameterType="Object">
|
||||
insert into sys_log (id, log_type, log_content, method, operate_type, request_param, ip, userid, username, cost_time, create_time)
|
||||
insert into sys_log (id, log_type, log_content, method, operate_type, request_url, request_type, request_param, ip, userid, username, cost_time, create_time,create_by)
|
||||
values(
|
||||
#{dto.id,jdbcType=VARCHAR},
|
||||
#{dto.logType,jdbcType=INTEGER},
|
||||
#{dto.logContent,jdbcType=VARCHAR},
|
||||
#{dto.method,jdbcType=VARCHAR},
|
||||
#{dto.operateType,jdbcType=INTEGER},
|
||||
#{dto.requestUrl,jdbcType=VARCHAR},
|
||||
#{dto.requestType,jdbcType=VARCHAR},
|
||||
#{dto.requestParam,jdbcType=VARCHAR},
|
||||
#{dto.ip,jdbcType=VARCHAR},
|
||||
#{dto.userid,jdbcType=VARCHAR},
|
||||
#{dto.username,jdbcType=VARCHAR},
|
||||
#{dto.costTime,jdbcType=BIGINT},
|
||||
#{dto.createTime,jdbcType=TIMESTAMP}
|
||||
#{dto.createTime,jdbcType=TIMESTAMP},
|
||||
#{dto.createBy,jdbcType=VARCHAR}
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ public class BaseCommonServiceImpl implements BaseCommonService {
|
||||
}
|
||||
//保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
|
||||
try {
|
||||
logDTO.setCreateTime(new Date());
|
||||
baseCommonMapper.saveLog(logDTO);
|
||||
} catch (Exception e) {
|
||||
log.warn(" LogContent length : "+logDTO.getLogContent().length());
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<description>公共模块</description>
|
||||
|
||||
@ -28,9 +28,9 @@ public interface CacheConstant {
|
||||
public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules";
|
||||
|
||||
/**
|
||||
* 缓存用户信息
|
||||
* 缓存用户信息【加密】
|
||||
*/
|
||||
public static final String SYS_USERS_CACHE = "sys:cache:user";
|
||||
public static final String SYS_USERS_CACHE = "sys:cache:encrypt:user";
|
||||
|
||||
/**
|
||||
* 全部部门信息缓存
|
||||
|
||||
@ -97,7 +97,7 @@ public enum SentinelErrorInfoEnum {
|
||||
return null;
|
||||
}
|
||||
|
||||
String exceptionClass=throwable.getClass().getSimpleName();
|
||||
String exceptionClass = throwable.getClass().getSimpleName();
|
||||
for (SentinelErrorInfoEnum e : SentinelErrorInfoEnum.values()) {
|
||||
if (exceptionClass.equals(e.name())) {
|
||||
return e;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.modules.demo.test.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -17,6 +18,7 @@ import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.UUIDGenerator;
|
||||
import org.jeecg.modules.demo.test.entity.JeecgDemo;
|
||||
import org.jeecg.modules.demo.test.service.IJeecgDemoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -325,4 +327,133 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
|
||||
return "hello world!";
|
||||
}
|
||||
|
||||
// =====Vue3 Native 原生页面示例===============================================================================================
|
||||
@GetMapping(value = "/oneNative/list")
|
||||
public Result oneNativeList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize){
|
||||
Object oneNative = redisUtil.get("one-native");
|
||||
JSONArray data = new JSONArray();
|
||||
if(null != oneNative){
|
||||
JSONObject nativeObject = (JSONObject) oneNative;
|
||||
data = nativeObject.getJSONArray("data");
|
||||
}
|
||||
IPage<JSONObject> objectPage = queryDataPage(data, pageNo, pageSize);
|
||||
return Result.OK(objectPage);
|
||||
}
|
||||
|
||||
@PostMapping("/oneNative/add")
|
||||
public Result<String> oneNativeAdd(@RequestBody JSONObject jsonObject){
|
||||
Object oneNative = redisUtil.get("one-native");
|
||||
JSONObject nativeObject = new JSONObject();
|
||||
JSONArray data = new JSONArray();
|
||||
if(null != oneNative){
|
||||
nativeObject = (JSONObject) oneNative;
|
||||
data = nativeObject.getJSONArray("data");
|
||||
}
|
||||
jsonObject.put("id", UUIDGenerator.generate());
|
||||
data.add(jsonObject);
|
||||
nativeObject.put("data",data);
|
||||
redisUtil.set("one-native",nativeObject);
|
||||
return Result.OK("添加成功");
|
||||
}
|
||||
|
||||
@PutMapping("/oneNative/edit")
|
||||
public Result<String> oneNativeEdit(@RequestBody JSONObject jsonObject){
|
||||
JSONObject oneNative = (JSONObject)redisUtil.get("one-native");
|
||||
JSONArray data = oneNative.getJSONArray("data");
|
||||
data = getNativeById(data,jsonObject);
|
||||
oneNative.put("data", data);
|
||||
redisUtil.set("one-native", oneNative);
|
||||
return Result.OK("修改成功");
|
||||
}
|
||||
|
||||
@DeleteMapping("/oneNative/delete")
|
||||
public Result<String> oneNativeDelete(@RequestParam(name = "ids") String ids){
|
||||
Object oneNative = redisUtil.get("one-native");
|
||||
if(null != oneNative){
|
||||
JSONObject nativeObject = (JSONObject) oneNative;
|
||||
JSONArray data = nativeObject.getJSONArray("data");
|
||||
data = deleteNativeById(data,ids);
|
||||
nativeObject.put("data",data);
|
||||
redisUtil.set("one-native",nativeObject);
|
||||
}
|
||||
return Result.OK("删除成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取redis对应id的数据
|
||||
* @param data
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
public JSONArray getNativeById(JSONArray data,JSONObject jsonObject){
|
||||
String dbId = "id";
|
||||
String id = jsonObject.getString(dbId);
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if(id.equals(data.getJSONObject(i).getString(dbId))){
|
||||
data.set(i,jsonObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除redis中包含的id数据
|
||||
* @param data
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public JSONArray deleteNativeById(JSONArray data,String ids){
|
||||
String dbId = "id";
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
//如果id包含直接清除data中的数据
|
||||
if(ids.contains(data.getJSONObject(i).getString(dbId))){
|
||||
data.fluentRemove(i);
|
||||
}
|
||||
//判断data的长度是否还剩1位
|
||||
if(data.size() == 1 && ids.contains(data.getJSONObject(0).getString(dbId))){
|
||||
data.fluentRemove(0);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟查询数据,可以根据父ID查询,可以分页
|
||||
*
|
||||
* @param dataList 数据列表
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 页大小
|
||||
* @return
|
||||
*/
|
||||
private IPage<JSONObject> queryDataPage(JSONArray dataList, Integer pageNo, Integer pageSize) {
|
||||
// 根据父级id查询子级
|
||||
JSONArray dataDb = dataList;
|
||||
// 模拟分页(实际中应用SQL自带的分页)
|
||||
List<JSONObject> records = new ArrayList<>();
|
||||
IPage<JSONObject> page;
|
||||
long beginIndex, endIndex;
|
||||
// 如果任意一个参数为null,则不分页
|
||||
if (pageNo == null || pageSize == null) {
|
||||
page = new Page<>(0, dataDb.size());
|
||||
beginIndex = 0;
|
||||
endIndex = dataDb.size();
|
||||
} else {
|
||||
page = new Page<>(pageNo, pageSize);
|
||||
beginIndex = page.offset();
|
||||
endIndex = page.offset() + page.getSize();
|
||||
}
|
||||
for (long i = beginIndex; (i < endIndex && i < dataDb.size()); i++) {
|
||||
JSONObject data = dataDb.getJSONObject((int) i);
|
||||
data = JSON.parseObject(data.toJSONString());
|
||||
// 不返回 children
|
||||
data.remove("children");
|
||||
records.add(data);
|
||||
}
|
||||
page.setRecords(records);
|
||||
page.setTotal(dataDb.size());
|
||||
return page;
|
||||
}
|
||||
// =====Vue3 Native 原生页面示例===============================================================================================
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
package org.jeecg.modules.demo.test.controller;
|
||||
|
||||
import io.lettuce.core.dynamic.annotation.Param;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.modules.demo.test.entity.JeecgDemo;
|
||||
import org.jeecg.modules.demo.test.service.IJeecgDemoService;
|
||||
import org.jeecg.modules.demo.test.service.IJeecgDynamicDataService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 动态数据源测试
|
||||
* @Author: zyf
|
||||
* @Date:2020-04-21
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "动态数据源测试")
|
||||
@RestController
|
||||
@RequestMapping("/test/dynamic")
|
||||
public class JeecgDynamicDataController extends JeecgController<JeecgDemo, IJeecgDemoService> {
|
||||
|
||||
@Autowired
|
||||
private IJeecgDynamicDataService jeecgDynamicDataService;
|
||||
|
||||
|
||||
/**
|
||||
* 动态切换数据源
|
||||
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/test1")
|
||||
@AutoLog(value = "动态切换数据源")
|
||||
@ApiOperation(value = "动态切换数据源", notes = "动态切换数据源")
|
||||
public Result<List<JeecgDemo>> selectSpelByKey(@RequestParam(required = false) String dsName) {
|
||||
List<JeecgDemo> list = jeecgDynamicDataService.selectSpelByKey(dsName);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -47,4 +47,6 @@ public class JeecgOrderMain implements Serializable {
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
private java.util.Date updateTime;
|
||||
|
||||
private String bpmStatus;
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.modules.demo.test.service;
|
||||
|
||||
import org.jeecg.common.system.base.service.JeecgService;
|
||||
import org.jeecg.modules.demo.test.entity.JeecgDemo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 动态数据源测试
|
||||
* @Author: zyf
|
||||
* @Date:2020-04-21
|
||||
*/
|
||||
public interface IJeecgDynamicDataService extends JeecgService<JeecgDemo> {
|
||||
|
||||
/**
|
||||
* 测试从header获取数据源
|
||||
* @return
|
||||
*/
|
||||
public List<JeecgDemo> selectSpelByHeader();
|
||||
|
||||
/**
|
||||
* 使用spel从参数获取
|
||||
* @param dsName
|
||||
* @return
|
||||
*/
|
||||
public List<JeecgDemo> selectSpelByKey(String dsName);
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.modules.demo.test.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.demo.test.entity.JeecgDemo;
|
||||
import org.jeecg.modules.demo.test.mapper.JeecgDemoMapper;
|
||||
import org.jeecg.modules.demo.test.service.IJeecgDynamicDataService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 动态数据源测试
|
||||
* @Author: zyf
|
||||
* @Date:2020-04-21
|
||||
*/
|
||||
@Service
|
||||
public class JeecgDynamicDataServiceImpl extends ServiceImpl<JeecgDemoMapper, JeecgDemo> implements IJeecgDynamicDataService {
|
||||
|
||||
@Override
|
||||
public List<JeecgDemo> selectSpelByHeader() {
|
||||
return list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JeecgDemo> selectSpelByKey(String dsName) {
|
||||
return list();
|
||||
}
|
||||
}
|
||||
@ -44,5 +44,7 @@ public class JeecgOrderMainPage {
|
||||
private List<JeecgOrderCustomer> jeecgOrderCustomerList;
|
||||
@ExcelCollection(name="机票")
|
||||
private List<JeecgOrderTicket> jeecgOrderTicketList;
|
||||
|
||||
private String bpmStatus;
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
//
|
||||
//package org.jeecg.modules.demo.xxljob;
|
||||
//
|
||||
//import com.xxl.job.core.biz.model.ReturnT;
|
||||
//import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.jeecg.common.config.mqtoken.UserTokenContext;
|
||||
//import org.jeecg.common.constant.CommonConstant;
|
||||
//import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
//import org.jeecg.common.system.util.JwtUtil;
|
||||
//import org.jeecg.common.util.RedisUtil;
|
||||
//import org.jeecg.common.util.SpringContextUtils;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * xxl-job定时任务测试
|
||||
// */
|
||||
//@Component
|
||||
//@Slf4j
|
||||
//public class TestJobHandler {
|
||||
// @Autowired
|
||||
// ISysBaseAPI sysBaseApi;
|
||||
//
|
||||
// /**
|
||||
// * 简单任务
|
||||
// *
|
||||
// * 测试:无token调用feign接口
|
||||
// *
|
||||
// * @param params
|
||||
// * @return
|
||||
// */
|
||||
//
|
||||
// @XxlJob(value = "testJob")
|
||||
// public ReturnT<String> demoJobHandler(String params) {
|
||||
// //1.生成临时令牌Token到线程中
|
||||
// UserTokenContext.setToken(getTemporaryToken());
|
||||
//
|
||||
// log.info("我是 jeecg-demo 服务里的定时任务 testJob , 我执行了...............................");
|
||||
// log.info("我调用 jeecg-system 服务的字典接口:{}",sysBaseApi.queryAllDict());
|
||||
// //。。。此处可以写多个feign接口调用
|
||||
//
|
||||
// //2.使用完,删除临时令牌Token
|
||||
// UserTokenContext.remove();
|
||||
// return ReturnT.SUCCESS;
|
||||
// }
|
||||
//
|
||||
// public void init() {
|
||||
// log.info("init");
|
||||
// }
|
||||
//
|
||||
// public void destroy() {
|
||||
// log.info("destory");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取临时令牌
|
||||
// *
|
||||
// * 模拟登陆接口,获取模拟 Token
|
||||
// * @return
|
||||
// */
|
||||
// public static String getTemporaryToken() {
|
||||
// RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class);
|
||||
// // 模拟登录生成Token
|
||||
// String token = JwtUtil.sign("??", "??");
|
||||
// // 设置Token缓存有效时间为 5 分钟
|
||||
// redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
// redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000);
|
||||
// return token;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
@ -11,6 +11,6 @@ WORKDIR /jeecg-boot
|
||||
EXPOSE 8080
|
||||
|
||||
ADD ./src/main/resources/jeecg ./config/jeecg
|
||||
ADD ./target/jeecg-boot-module-system-3.2.0.jar ./
|
||||
ADD ./target/jeecg-boot-module-system-3.3.0.jar ./
|
||||
|
||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.2.0.jar
|
||||
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.3.0.jar
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
<groupId>org.jeecgframework.jimureport</groupId>
|
||||
<artifactId>jimureport-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DEMO 示例模块 -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
@ -103,4 +102,4 @@
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@ -28,7 +28,8 @@ public class SystemInitListener implements ApplicationListener<ApplicationReadyE
|
||||
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
|
||||
|
||||
log.info(" 服务已启动,初始化路由配置 ###################");
|
||||
if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf("AnnotationConfigServletWebServerApplicationContext") > -1) {
|
||||
String context = "AnnotationConfigServletWebServerApplicationContext";
|
||||
if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf(context) > -1) {
|
||||
sysGatewayRouteService.addRoute2Redis(CacheConstant.GATEWAY_ROUTES);
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ import java.util.Set;
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/api")
|
||||
public class SystemAPIController {
|
||||
public class SystemApiController {
|
||||
|
||||
@Autowired
|
||||
private SysBaseApiImpl sysBaseApi;
|
||||
@ -641,4 +641,23 @@ public class SystemAPIController {
|
||||
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送模板信息
|
||||
* @param message
|
||||
*/
|
||||
@PostMapping("/sendTemplateMessage")
|
||||
public void sendTemplateMessage(@RequestBody MessageDTO message){
|
||||
sysBaseApi.sendTemplateMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息模板内容
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getTemplateContent")
|
||||
public String getTemplateContent(@RequestParam("code") String code){
|
||||
return this.sysBaseApi.getTemplateContent(code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,663 @@
|
||||
package org.jeecg.modules.api.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* 服务化 system模块 对外接口请求类
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/sys/api")
|
||||
public class SystemApiController {
|
||||
|
||||
@Autowired
|
||||
private SysBaseApiImpl sysBaseApi;
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
|
||||
|
||||
/**
|
||||
* 发送系统消息
|
||||
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
|
||||
*/
|
||||
@PostMapping("/sendSysAnnouncement")
|
||||
public void sendSysAnnouncement(@RequestBody MessageDTO message){
|
||||
sysBaseApi.sendSysAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendBusAnnouncement")
|
||||
public void sendBusAnnouncement(@RequestBody BusMessageDTO message){
|
||||
sysBaseApi.sendBusAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过模板发送消息
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendTemplateAnnouncement")
|
||||
public void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message){
|
||||
sysBaseApi.sendTemplateAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过模板发送消息 附带业务参数
|
||||
* @param message 使用构造器赋值参数
|
||||
*/
|
||||
@PostMapping("/sendBusTemplateAnnouncement")
|
||||
public void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message){
|
||||
sysBaseApi.sendBusTemplateAnnouncement(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过消息中心模板,生成推送内容
|
||||
* @param templateDTO 使用构造器赋值参数
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/parseTemplateByCode")
|
||||
public String parseTemplateByCode(@RequestBody TemplateDTO templateDTO){
|
||||
return sysBaseApi.parseTemplateByCode(templateDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据业务类型busType及业务busId修改消息已读
|
||||
*/
|
||||
@GetMapping("/updateSysAnnounReadFlag")
|
||||
public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId){
|
||||
sysBaseApi.updateSysAnnounReadFlag(busType, busId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户账号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserByName")
|
||||
public LoginUser getUserByName(@RequestParam("username") String username){
|
||||
return sysBaseApi.getUserByName(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserById")
|
||||
LoginUser getUserById(@RequestParam("id") String id){
|
||||
return sysBaseApi.getUserById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRolesByUsername")
|
||||
List<String> getRolesByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getRolesByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartIdsByUsername")
|
||||
List<String> getDepartIdsByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门 name
|
||||
* @param username
|
||||
* @return 部门 name
|
||||
*/
|
||||
@GetMapping("/getDepartNamesByUsername")
|
||||
List<String> getDepartNamesByUsername(@RequestParam("username") String username){
|
||||
return sysBaseApi.getDepartNamesByUsername(username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDictItemsByCode")
|
||||
List<DictModel> queryDictItemsByCode(@RequestParam("code") String code){
|
||||
return sysBaseApi.queryDictItemsByCode(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有效的数据字典
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryEnableDictItemsByCode")
|
||||
List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code){
|
||||
return sysBaseApi.queryEnableDictItemsByCode(code);
|
||||
}
|
||||
|
||||
|
||||
/** 查询所有的父级字典,按照create_time排序 */
|
||||
@GetMapping("/queryAllDict")
|
||||
List<DictModel> queryAllDict(){
|
||||
// try{
|
||||
// //睡10秒,gateway网关5秒超时,会触发熔断降级操作
|
||||
// Thread.sleep(10000);
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
log.info("--我是jeecg-system服务节点,微服务接口queryAllDict被调用--");
|
||||
return sysBaseApi.queryAllDict();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有分类字典
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllSysCategory")
|
||||
List<SysCategoryModel> queryAllSysCategory(){
|
||||
return sysBaseApi.queryAllSysCategory();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllDepartBackDictModel")
|
||||
List<DictModel> queryAllDepartBackDictModel(){
|
||||
return sysBaseApi.queryAllDepartBackDictModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有角色 带参
|
||||
* roleIds 默认选中角色
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllRole")
|
||||
public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds){
|
||||
if(roleIds==null || roleIds.length==0){
|
||||
return sysBaseApi.queryAllRole();
|
||||
}else{
|
||||
return sysBaseApi.queryAllRole(roleIds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色Id集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getRoleIdsByUsername")
|
||||
public List<String> getRoleIdsByUsername(@RequestParam("username")String username){
|
||||
return sysBaseApi.getRoleIdsByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过部门编号查询部门id
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDepartIdsByOrgCode")
|
||||
public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode){
|
||||
return sysBaseApi.getDepartIdsByOrgCode(orgCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有部门
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getAllSysDepart")
|
||||
public List<SysDepartModel> getAllSysDepart(){
|
||||
return sysBaseApi.getAllSysDepart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDynamicDbSourceById")
|
||||
DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId")String dbSourceId){
|
||||
return sysBaseApi.getDynamicDbSourceById(dbSourceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据部门Id获取部门负责人
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDeptHeadByDepId")
|
||||
public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId){
|
||||
return sysBaseApi.getDeptHeadByDepId(deptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找父级部门
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getParentDepartId")
|
||||
public DictModel getParentDepartId(@RequestParam("departId")String departId){
|
||||
return sysBaseApi.getParentDepartId(departId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 code 查询数据库中存储的 DynamicDataSourceModel
|
||||
*
|
||||
* @param dbSourceCode
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDynamicDbSourceByCode")
|
||||
public DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode){
|
||||
return sysBaseApi.getDynamicDbSourceByCode(dbSourceCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定用户发消息
|
||||
* @param userIds
|
||||
* @param cmd
|
||||
*/
|
||||
@GetMapping("/sendWebSocketMsg")
|
||||
public void sendWebSocketMsg(String[] userIds, String cmd){
|
||||
sysBaseApi.sendWebSocketMsg(userIds, cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据id获取所有参与用户
|
||||
* userIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUserByIds")
|
||||
public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds){
|
||||
return sysBaseApi.queryAllUserByIds(userIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户 返回ComboModel
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUserBackCombo")
|
||||
public List<ComboModel> queryAllUserBackCombo(){
|
||||
return sysBaseApi.queryAllUserBackCombo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询用户 返回JSONObject
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryAllUser")
|
||||
public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize){
|
||||
return sysBaseApi.queryAllUser(userIds, pageNo, pageSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 将会议签到信息推动到预览
|
||||
* userIds
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
@GetMapping("/meetingSignWebsocket")
|
||||
public void meetingSignWebsocket(@RequestParam("userId")String userId){
|
||||
sysBaseApi.meetingSignWebsocket(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据name获取所有参与用户
|
||||
* userNames
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserByNames")
|
||||
public List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames){
|
||||
return sysBaseApi.queryUserByNames(userNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的角色集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserRoleSet")
|
||||
public Set<String> getUserRoleSet(@RequestParam("username")String username){
|
||||
return sysBaseApi.getUserRoleSet(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的权限集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserPermissionSet")
|
||||
public Set<String> getUserPermissionSet(@RequestParam("username") String username){
|
||||
return sysBaseApi.getUserPermissionSet(username);
|
||||
}
|
||||
|
||||
//-----
|
||||
|
||||
/**
|
||||
* 判断是否有online访问的权限
|
||||
* @param onlineAuthDTO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/hasOnlineAuth")
|
||||
public boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO){
|
||||
return sysBaseApi.hasOnlineAuth(onlineAuthDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户角色信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserRoles")
|
||||
public Set<String> queryUserRoles(@RequestParam("username") String username){
|
||||
return sysUserService.getUserRolesSet(username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询用户权限信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserAuths")
|
||||
public Set<String> queryUserAuths(@RequestParam("username") String username){
|
||||
return sysUserService.getUserPermissionsSet(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过部门id获取部门全部信息
|
||||
*/
|
||||
@GetMapping("/selectAllById")
|
||||
public SysDepartModel selectAllById(@RequestParam("id") String id){
|
||||
return sysBaseApi.selectAllById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户所属公司下所有用户ids
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDeptUsersByUserId")
|
||||
public List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.queryDeptUsersByUserId(userId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询数据权限
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryPermissionDataRule")
|
||||
public List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username){
|
||||
return sysBaseApi.queryPermissionDataRule(component, requestPath, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getCacheUser")
|
||||
public SysUserCacheInfo getCacheUser(@RequestParam("username") String username){
|
||||
return sysBaseApi.getCacheUser(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通字典的翻译
|
||||
* @param code
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/translateDict")
|
||||
public String translateDict(@RequestParam("code") String code, @RequestParam("key") String key){
|
||||
return sysBaseApi.translateDict(code, key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 36根据多个用户账号(逗号分隔),查询返回多个用户信息
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/queryUsersByUsernames")
|
||||
List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames){
|
||||
return this.sysBaseApi.queryUsersByUsernames(usernames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 37根据多个用户id(逗号分隔),查询返回多个用户信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/queryUsersByIds")
|
||||
List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids){
|
||||
return this.sysBaseApi.queryUsersByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 38根据多个部门编码(逗号分隔),查询返回多个部门信息
|
||||
* @param orgCodes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDepartsByOrgcodes")
|
||||
List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes){
|
||||
return this.sysBaseApi.queryDepartsByOrgcodes(orgCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 39根据多个部门ID(逗号分隔),查询返回多个部门信息
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryDepartsByIds")
|
||||
List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids){
|
||||
return this.sysBaseApi.queryDepartsByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 40发送邮件消息
|
||||
* @param email
|
||||
* @param title
|
||||
* @param content
|
||||
*/
|
||||
@GetMapping("/sendEmailMsg")
|
||||
public void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content){
|
||||
this.sysBaseApi.sendEmailMsg(email,title,content);
|
||||
};
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送模板信息
|
||||
* @param message
|
||||
*/
|
||||
@PostMapping("/sendTemplateMessage")
|
||||
public void sendTemplateMessage(@RequestBody MessageDTO message){
|
||||
sysBaseApi.sendTemplateMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息模板内容
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getTemplateContent")
|
||||
public String getTemplateContent(@RequestParam("code") String code){
|
||||
return this.sysBaseApi.getTemplateContent(code);
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,21 +5,17 @@ import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.modules.cas.util.CASServiceUtil;
|
||||
import org.jeecg.modules.cas.util.CasServiceUtil;
|
||||
import org.jeecg.modules.cas.util.XmlUtils;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
@ -65,7 +61,7 @@ public class CasClientController {
|
||||
log.info("Rest api login.");
|
||||
try {
|
||||
String validateUrl = prefixUrl+"/p3/serviceValidate";
|
||||
String res = CASServiceUtil.getSTValidate(validateUrl, ticket, service);
|
||||
String res = CasServiceUtil.getStValidate(validateUrl, ticket, service);
|
||||
log.info("res."+res);
|
||||
final String error = XmlUtils.getTextForElement(res, "authenticationFailure");
|
||||
if(StringUtils.isNotEmpty(error)) {
|
||||
|
||||
@ -17,16 +17,16 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
||||
/**
|
||||
* @Description: CASServiceUtil
|
||||
* @Description: CasServiceUtil
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class CASServiceUtil {
|
||||
public class CasServiceUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate";
|
||||
String service = "http://localhost:3003/user/login";
|
||||
String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3";
|
||||
String res = getSTValidate(serviceUrl,ticket, service);
|
||||
String res = getStValidate(serviceUrl,ticket, service);
|
||||
|
||||
System.out.println("---------res-----"+res);
|
||||
}
|
||||
@ -35,7 +35,7 @@ public class CASServiceUtil {
|
||||
/**
|
||||
* 验证ST
|
||||
*/
|
||||
public static String getSTValidate(String url,String st, String service){
|
||||
public static String getStValidate(String url, String st, String service){
|
||||
try {
|
||||
url = url+"?service="+service+"&ticket="+st;
|
||||
CloseableHttpClient httpclient = createHttpClientWithNoSsl();
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
package org.jeecg.modules.cas.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
||||
/**
|
||||
* @Description: CasServiceUtil
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
public class CasServiceUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate";
|
||||
String service = "http://localhost:3003/user/login";
|
||||
String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3";
|
||||
String res = getStValidate(serviceUrl,ticket, service);
|
||||
|
||||
System.out.println("---------res-----"+res);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证ST
|
||||
*/
|
||||
public static String getStValidate(String url, String st, String service){
|
||||
try {
|
||||
url = url+"?service="+service+"&ticket="+st;
|
||||
CloseableHttpClient httpclient = createHttpClientWithNoSsl();
|
||||
HttpGet httpget = new HttpGet(url);
|
||||
HttpResponse response = httpclient.execute(httpget);
|
||||
String res = readResponse(response);
|
||||
return res == null ? null : (res == "" ? null : res);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读取 response body 内容为字符串
|
||||
*
|
||||
* @param response
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String readResponse(HttpResponse response) throws IOException {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
|
||||
String result = new String();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建模拟客户端(针对 https 客户端禁用 SSL 验证)
|
||||
*
|
||||
* @param cookieStore 缓存的 Cookies 信息
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] certs, String authType) {
|
||||
// don't check
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] certs, String authType) {
|
||||
// don't check
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||
ctx.init(null, trustAllCerts, null);
|
||||
LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx);
|
||||
return HttpClients.custom()
|
||||
.setSSLSocketFactory(sslSocketFactory)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,6 +14,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
@ -30,6 +31,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public final class XmlUtils {
|
||||
|
||||
/**
|
||||
* attributes
|
||||
*/
|
||||
private static final String ATTRIBUTES = "attributes";
|
||||
|
||||
/**
|
||||
* Creates a new namespace-aware DOM document object by parsing the given XML.
|
||||
*
|
||||
@ -218,9 +224,9 @@ public final class XmlUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(final String namespaceURI, final String localName, final String qName,
|
||||
final Attributes attributes) throws SAXException {
|
||||
if ("attributes".equals(localName)) {
|
||||
public void startElement(final String nameSpaceUri, final String localName, final String qName,
|
||||
final Attributes attributes) throws SAXException {
|
||||
if (ATTRIBUTES.equals(localName)) {
|
||||
this.foundAttributes = true;
|
||||
} else if (this.foundAttributes) {
|
||||
this.value = new StringBuilder();
|
||||
@ -236,9 +242,9 @@ public final class XmlUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(final String namespaceURI, final String localName, final String qName)
|
||||
public void endElement(final String nameSpaceUri, final String localName, final String qName)
|
||||
throws SAXException {
|
||||
if ("attributes".equals(localName)) {
|
||||
if (ATTRIBUTES.equals(localName)) {
|
||||
this.foundAttributes = false;
|
||||
this.currentAttribute = null;
|
||||
} else if (this.foundAttributes) {
|
||||
|
||||
@ -6,9 +6,12 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.entity.MsgParams;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
import org.jeecg.modules.message.service.ISysMessageTemplateService;
|
||||
@ -46,6 +49,9 @@ public class SysMessageTemplateController extends JeecgController<SysMessageTemp
|
||||
@Autowired
|
||||
private PushMsgUtil pushMsgUtil;
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseApi;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
@ -152,19 +158,23 @@ public class SysMessageTemplateController extends JeecgController<SysMessageTemp
|
||||
@PostMapping(value = "/sendMsg")
|
||||
public Result<SysMessageTemplate> sendMessage(@RequestBody MsgParams msgParams) {
|
||||
Result<SysMessageTemplate> result = new Result<SysMessageTemplate>();
|
||||
Map<String, String> map = null;
|
||||
try {
|
||||
map = (Map<String, String>) JSON.parse(msgParams.getTestData());
|
||||
MessageDTO md = new MessageDTO();
|
||||
md.setToAll(false);
|
||||
md.setTitle("消息发送测试");
|
||||
md.setTemplateCode(msgParams.getTemplateCode());
|
||||
md.setToUser(msgParams.getReceiver());
|
||||
md.setType(msgParams.getMsgType());
|
||||
String testData = msgParams.getTestData();
|
||||
if(oConvertUtils.isNotEmpty(testData)){
|
||||
Map<String, Object> data = JSON.parseObject(testData, Map.class);
|
||||
md.setData(data);
|
||||
}
|
||||
sysBaseApi.sendTemplateMessage(md);
|
||||
return result.success("消息发送成功!");
|
||||
} catch (Exception e) {
|
||||
result.error500("解析Json出错!");
|
||||
return result;
|
||||
log.error("发送消息出错", e.getMessage());
|
||||
return result.error500("发送消息出错!");
|
||||
}
|
||||
boolean is_sendSuccess = pushMsgUtil.sendMessage(msgParams.getMsgType(), msgParams.getTemplateCode(), map, msgParams.getReceiver());
|
||||
if (is_sendSuccess) {
|
||||
result.success("发送消息任务添加成功!");
|
||||
} else {
|
||||
result.error500("发送消息任务添加失败!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,9 +50,11 @@ public class SysMessage extends JeecgEntity {
|
||||
/**消息标题*/
|
||||
@Excel(name = "消息标题", width = 15)
|
||||
private java.lang.String esTitle;
|
||||
/**推送方式:1短信 2邮件 3微信*/
|
||||
@Excel(name = "推送方式:1短信 2邮件 3微信", width = 15)
|
||||
@Dict(dicCode = "msgType")
|
||||
/**
|
||||
* 推送方式:参考枚举类MessageTypeEnum
|
||||
*/
|
||||
@Excel(name = "推送方式", width = 15)
|
||||
@Dict(dicCode = "messageType")
|
||||
private java.lang.String esType;
|
||||
/**备注*/
|
||||
@Excel(name = "备注", width = 15)
|
||||
|
||||
@ -35,4 +35,9 @@ public class SysMessageTemplate extends JeecgEntity{
|
||||
/**模板类型*/
|
||||
@Excel(name = "模板类型", width = 15)
|
||||
private java.lang.String templateType;
|
||||
|
||||
/**已经应用/未应用 1是0否*/
|
||||
@Excel(name = "应用状态", width = 15)
|
||||
private String useStatus;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.jeecg.modules.message.handle;
|
||||
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
|
||||
/**
|
||||
* @Description: 发送信息接口
|
||||
* @author: jeecg-boot
|
||||
@ -8,9 +10,17 @@ public interface ISendMsgHandle {
|
||||
|
||||
/**
|
||||
* 发送信息
|
||||
* @param es_receiver 发送人
|
||||
* @param es_title 标题
|
||||
* @param es_content 内容
|
||||
* @param esReceiver 发送人
|
||||
* @param esTitle 标题
|
||||
* @param esContent 内容
|
||||
*/
|
||||
void SendMsg(String es_receiver, String es_title, String es_content);
|
||||
void sendMsg(String esReceiver, String esTitle, String esContent);
|
||||
|
||||
/**
|
||||
* 发送信息
|
||||
* @param messageDTO
|
||||
*/
|
||||
default void sendMessage(MessageDTO messageDTO){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Description: 发钉钉消息模板
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("ddSendMsgHandle")
|
||||
public class DdSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Autowired
|
||||
private ThirdAppDingtalkServiceImpl dingtalkService;
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
log.info("发微信消息模板");
|
||||
MessageDTO messageDTO = new MessageDTO();
|
||||
messageDTO.setToUser(esReceiver);
|
||||
messageDTO.setTitle(esTitle);
|
||||
messageDTO.setContent(esContent);
|
||||
messageDTO.setToAll(false);
|
||||
sendMessage(messageDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
dingtalkService.sendMessage(messageDTO, true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,20 +1,34 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.StaticConfig;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 邮箱发送信息
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("emailSendMsgHandle")
|
||||
public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
static String emailFrom;
|
||||
|
||||
@ -22,8 +36,16 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
EmailSendMsgHandle.emailFrom = emailFrom;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
SysUserMapper sysUserMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void SendMsg(String es_receiver, String es_title, String es_content) {
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = null;
|
||||
@ -37,13 +59,53 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
helper = new MimeMessageHelper(message, true);
|
||||
// 设置发送方邮箱地址
|
||||
helper.setFrom(emailFrom);
|
||||
helper.setTo(es_receiver);
|
||||
helper.setSubject(es_title);
|
||||
helper.setText(es_content, true);
|
||||
helper.setTo(esReceiver);
|
||||
helper.setSubject(esTitle);
|
||||
helper.setText(esContent, true);
|
||||
mailSender.send(message);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, arr);
|
||||
List<SysUser> list = sysUserMapper.selectList(query);
|
||||
String content = messageDTO.getContent();
|
||||
String title = messageDTO.getTitle();
|
||||
for(SysUser user: list){
|
||||
String email = user.getEmail();
|
||||
if(email==null || "".equals(email)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(content.indexOf(CommonConstant.LOGIN_TOKEN)>0){
|
||||
String token = getToken(user);
|
||||
try {
|
||||
content = content.replace(CommonConstant.LOGIN_TOKEN, URLEncoder.encode(token, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("邮件消息token编码失败", e.getMessage());
|
||||
}
|
||||
}
|
||||
log.info("邮件内容:"+ content);
|
||||
sendMsg(email, title, content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
private String getToken(SysUser user) {
|
||||
// 生成token
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
// 设置超时时间 1个小时
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Description: 发企业微信消息模板
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("qywxSendMsgHandle")
|
||||
public class QywxSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Autowired
|
||||
private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
|
||||
|
||||
@Override
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
log.info("发微信消息模板");
|
||||
MessageDTO messageDTO = new MessageDTO();
|
||||
messageDTO.setToUser(esReceiver);
|
||||
messageDTO.setTitle(esTitle);
|
||||
messageDTO.setContent(esContent);
|
||||
messageDTO.setToAll(false);
|
||||
sendMessage(messageDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
wechatEnterpriseService.sendMessage(messageDTO, true);
|
||||
}
|
||||
|
||||
}
|
||||
@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
public class SmsSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Override
|
||||
public void SendMsg(String es_receiver, String es_title, String es_content) {
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
// TODO Auto-generated method stub
|
||||
log.info("发短信");
|
||||
}
|
||||
|
||||
@ -1,28 +1,129 @@
|
||||
package org.jeecg.modules.message.handle.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.WebsocketConst;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.message.websocket.WebSocket;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementMapper;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Description: 发送系统消息
|
||||
* @Author: wangshuai
|
||||
* @Date: 2022年3月22日 18:48:20
|
||||
*/
|
||||
@Component("systemSendMsgHandle")
|
||||
public class SystemSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
public static final String FROM_USER="system";
|
||||
|
||||
@Resource
|
||||
private SysAnnouncementMapper sysAnnouncementMapper;
|
||||
|
||||
@Resource
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
|
||||
@Resource
|
||||
private WebSocket webSocket;
|
||||
|
||||
/**
|
||||
* 该方法会发送3种消息:系统消息、企业微信 钉钉
|
||||
* @param esReceiver 发送人
|
||||
* @param esTitle 标题
|
||||
* @param esContent 内容
|
||||
*/
|
||||
@Override
|
||||
public void SendMsg(String es_receiver, String es_title, String es_content) {
|
||||
if(oConvertUtils.isEmpty(es_receiver)){
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
if(oConvertUtils.isEmpty(esReceiver)){
|
||||
throw new JeecgBootException("被发送人不能为空");
|
||||
}
|
||||
ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
|
||||
MessageDTO messageDTO = new MessageDTO(FROM_USER,es_receiver,es_title,es_content);
|
||||
sysBaseAPI.sendSysAnnouncement(messageDTO);
|
||||
ISysBaseAPI sysBaseApi = SpringContextUtils.getBean(ISysBaseAPI.class);
|
||||
MessageDTO messageDTO = new MessageDTO(FROM_USER,esReceiver,esTitle,esContent);
|
||||
sysBaseApi.sendSysAnnouncement(messageDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅发送系统消息
|
||||
* @param messageDTO
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
//原方法不支持 sysBaseApi.sendSysAnnouncement(messageDTO); 有企业微信消息逻辑,
|
||||
String title = messageDTO.getTitle();
|
||||
String content = messageDTO.getContent();
|
||||
String fromUser = messageDTO.getFromUser();
|
||||
Map<String,Object> data = messageDTO.getData();
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
for(String username: arr){
|
||||
doSend(title, content, fromUser, username, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void doSend(String title, String msgContent, String fromUser, String toUser, Map<String, Object> data){
|
||||
SysAnnouncement announcement = new SysAnnouncement();
|
||||
if(data!=null){
|
||||
//摘要信息
|
||||
Object msgAbstract = data.get(CommonConstant.NOTICE_MSG_SUMMARY);
|
||||
if(msgAbstract!=null){
|
||||
announcement.setMsgAbstract(msgAbstract.toString());
|
||||
}
|
||||
// 任务节点ID
|
||||
Object taskId = data.get(CommonConstant.NOTICE_MSG_BUS_ID);
|
||||
if(taskId!=null){
|
||||
announcement.setBusId(taskId.toString());
|
||||
}
|
||||
}
|
||||
announcement.setTitile(title);
|
||||
announcement.setMsgContent(msgContent);
|
||||
announcement.setSender(fromUser);
|
||||
announcement.setPriority(CommonConstant.PRIORITY_M);
|
||||
announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
|
||||
announcement.setSendStatus(CommonConstant.HAS_SEND);
|
||||
announcement.setSendTime(new Date());
|
||||
//系统消息
|
||||
announcement.setMsgCategory("2");
|
||||
announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
sysAnnouncementMapper.insert(announcement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = toUser;
|
||||
String[] userIds = userId.split(",");
|
||||
String anntId = announcement.getId();
|
||||
for(int i=0;i<userIds.length;i++) {
|
||||
if(oConvertUtils.isNotEmpty(userIds[i])) {
|
||||
SysUser sysUser = userMapper.getUserByName(userIds[i]);
|
||||
if(sysUser==null) {
|
||||
continue;
|
||||
}
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
announcementSend.setAnntId(anntId);
|
||||
announcementSend.setUserId(sysUser.getId());
|
||||
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
|
||||
sysAnnouncementSendMapper.insert(announcementSend);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
|
||||
obj.put(WebsocketConst.MSG_ID, announcement.getId());
|
||||
obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
public class WxSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Override
|
||||
public void SendMsg(String es_receiver, String es_title, String es_content) {
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
// TODO Auto-generated method stub
|
||||
log.info("发微信消息模板");
|
||||
}
|
||||
|
||||
@ -1,21 +1,19 @@
|
||||
package org.jeecg.modules.message.job;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.message.handle.enums.SendMsgStatusEnum;
|
||||
import org.jeecg.modules.message.handle.enums.SendMsgTypeEnum;
|
||||
import org.jeecg.modules.message.service.ISysMessageService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发送消息任务
|
||||
@ -28,6 +26,9 @@ public class SendMsgJob implements Job {
|
||||
@Autowired
|
||||
private ISysMessageService sysMessageService;
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
|
||||
@ -41,32 +42,19 @@ public class SendMsgJob implements Job {
|
||||
System.out.println(sysMessages);
|
||||
// 2.根据不同的类型走不通的发送实现类
|
||||
for (SysMessage sysMessage : sysMessages) {
|
||||
ISendMsgHandle sendMsgHandle = null;
|
||||
try {
|
||||
if (sysMessage.getEsType().equals(SendMsgTypeEnum.EMAIL.getType())) {
|
||||
sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.EMAIL.getImplClass()).newInstance();
|
||||
} else if (sysMessage.getEsType().equals(SendMsgTypeEnum.SMS.getType())) {
|
||||
sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SMS.getImplClass()).newInstance();
|
||||
} else if (sysMessage.getEsType().equals(SendMsgTypeEnum.WX.getType())) {
|
||||
sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.WX.getImplClass()).newInstance();
|
||||
} else if(sysMessage.getEsType().equals(SendMsgTypeEnum.SYSTEM_MESSAGE.getType())){
|
||||
//update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------
|
||||
sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SYSTEM_MESSAGE.getImplClass()).newInstance();
|
||||
//update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
Integer sendNum = sysMessage.getEsSendNum();
|
||||
try {
|
||||
//update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------
|
||||
if(null != sendMsgHandle){
|
||||
sendMsgHandle.SendMsg(sysMessage.getEsReceiver(), sysMessage.getEsTitle(),
|
||||
sysMessage.getEsContent().toString());
|
||||
//发送消息成功
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------
|
||||
MessageDTO md = new MessageDTO();
|
||||
md.setTitle(sysMessage.getEsTitle());
|
||||
md.setContent(sysMessage.getEsContent());
|
||||
md.setToUser(sysMessage.getEsReceiver());
|
||||
md.setType(sysMessage.getEsType());
|
||||
md.setToAll(false);
|
||||
sysBaseAPI.sendTemplateMessage(md);
|
||||
//发送消息成功
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||
//update-end-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 发送消息出现异常
|
||||
|
||||
@ -12,6 +12,7 @@ import cn.hutool.core.date.DateUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.monitor.domain.RedisInfo;
|
||||
import org.jeecg.modules.monitor.exception.RedisConnectException;
|
||||
@ -34,6 +35,11 @@ public class RedisServiceImpl implements RedisService {
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
/**
|
||||
* redis信息
|
||||
*/
|
||||
private static final String REDIS_MESSAGE = "3";
|
||||
|
||||
/**
|
||||
* Redis详细信息
|
||||
*/
|
||||
@ -88,7 +94,7 @@ public class RedisServiceImpl implements RedisService {
|
||||
public Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException {
|
||||
Map<String,JSONArray> mapJson=new HashMap(5);
|
||||
JSONArray json = new JSONArray();
|
||||
if("3".equals(type)){
|
||||
if(REDIS_MESSAGE.equals(type)){
|
||||
List<RedisInfo> redisInfo = getRedisInfo();
|
||||
for(RedisInfo info:redisInfo){
|
||||
Map<String, Object> map= Maps.newHashMap();
|
||||
@ -101,7 +107,8 @@ public class RedisServiceImpl implements RedisService {
|
||||
mapJson.put("data",json);
|
||||
return mapJson;
|
||||
}
|
||||
for(int i = 0; i < 5; i++){
|
||||
int length = 5;
|
||||
for(int i = 0; i < length; i++){
|
||||
JSONObject jo = new JSONObject();
|
||||
Map<String, Object> map;
|
||||
if("1".equals(type)){
|
||||
@ -109,11 +116,11 @@ public class RedisServiceImpl implements RedisService {
|
||||
jo.put("value",map.get("dbSize"));
|
||||
}else{
|
||||
map = getMemoryInfo();
|
||||
Integer used_memory = Integer.valueOf(map.get("used_memory").toString());
|
||||
jo.put("value",used_memory/1000);
|
||||
Integer usedMemory = Integer.valueOf(map.get("used_memory").toString());
|
||||
jo.put("value",usedMemory/1000);
|
||||
}
|
||||
String create_time = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
|
||||
jo.put("name",create_time);
|
||||
String createTime = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000));
|
||||
jo.put("name",createTime);
|
||||
json.add(jo);
|
||||
}
|
||||
mapJson.put("data",json);
|
||||
|
||||
@ -2,6 +2,8 @@ package org.jeecg.modules.ngalain.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.ngalain.service.NgAlainService;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
@ -123,12 +125,13 @@ public class NgAlainServiceImpl implements NgAlainService {
|
||||
private JSONObject getPermissionJsonObject(SysPermission permission) {
|
||||
JSONObject json = new JSONObject();
|
||||
//类型(0:一级菜单 1:子菜单 2:按钮)
|
||||
if(permission.getMenuType()==2) {
|
||||
if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) {
|
||||
json.put("action", permission.getPerms());
|
||||
json.put("describe", permission.getName());
|
||||
}else if(permission.getMenuType()==0||permission.getMenuType()==1) {
|
||||
}else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) {
|
||||
json.put("id", permission.getId());
|
||||
if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) {
|
||||
boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL));
|
||||
if(flag) {
|
||||
String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes()));
|
||||
json.put("path", "/sys/link/" +url.replaceAll("=",""));
|
||||
}else {
|
||||
@ -156,7 +159,7 @@ public class NgAlainServiceImpl implements NgAlainService {
|
||||
}else {
|
||||
meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
|
||||
}
|
||||
if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) {
|
||||
if(flag) {
|
||||
meta.put("url", permission.getUrl());
|
||||
}
|
||||
json.put("meta", meta);
|
||||
@ -172,7 +175,7 @@ public class NgAlainServiceImpl implements NgAlainService {
|
||||
*/
|
||||
private String urlToRouteName(String url) {
|
||||
if(oConvertUtils.isNotEmpty(url)) {
|
||||
if(url.startsWith("/")) {
|
||||
if(url.startsWith(SymbolConstant.SINGLE_SLASH)) {
|
||||
url = url.substring(1);
|
||||
}
|
||||
url = url.replace("/", "-");
|
||||
|
||||
@ -5,8 +5,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.oss.entity.OSSFile;
|
||||
import org.jeecg.modules.oss.service.IOSSFileService;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
import org.jeecg.modules.oss.service.IOssFileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -25,20 +25,20 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/sys/oss/file")
|
||||
public class OSSFileController {
|
||||
public class OssFileController {
|
||||
|
||||
@Autowired
|
||||
private IOSSFileService ossFileService;
|
||||
private IOssFileService ossFileService;
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public Result<IPage<OSSFile>> queryPageList(OSSFile file,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
Result<IPage<OSSFile>> result = new Result<>();
|
||||
QueryWrapper<OSSFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap());
|
||||
Page<OSSFile> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OSSFile> pageList = ossFileService.page(page, queryWrapper);
|
||||
public Result<IPage<OssFile>> queryPageList(OssFile file,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
Result<IPage<OssFile>> result = new Result<>();
|
||||
QueryWrapper<OssFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap());
|
||||
Page<OssFile> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OssFile> pageList = ossFileService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
@ -64,15 +64,12 @@ public class OSSFileController {
|
||||
@DeleteMapping("/delete")
|
||||
public Result delete(@RequestParam(name = "id") String id) {
|
||||
Result result = new Result();
|
||||
OSSFile file = ossFileService.getById(id);
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}
|
||||
else {
|
||||
}else {
|
||||
boolean ok = ossFileService.delete(file);
|
||||
if (ok) {
|
||||
result.success("删除成功!");
|
||||
}
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -82,9 +79,9 @@ public class OSSFileController {
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/queryById")
|
||||
public Result<OSSFile> queryById(@RequestParam(name = "id") String id) {
|
||||
Result<OSSFile> result = new Result<>();
|
||||
OSSFile file = ossFileService.getById(id);
|
||||
public Result<OssFile> queryById(@RequestParam(name = "id") String id) {
|
||||
Result<OssFile> result = new Result<>();
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package org.jeecg.modules.oss.controller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.oss.entity.OssFile;
|
||||
import org.jeecg.modules.oss.service.IOssFileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 云存储示例 DEMO
|
||||
* @author: jeecg-boot
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("/sys/oss/file")
|
||||
public class OssFileController {
|
||||
|
||||
@Autowired
|
||||
private IOssFileService ossFileService;
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public Result<IPage<OssFile>> queryPageList(OssFile file,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
|
||||
Result<IPage<OssFile>> result = new Result<>();
|
||||
QueryWrapper<OssFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap());
|
||||
Page<OssFile> page = new Page<>(pageNo, pageSize);
|
||||
IPage<OssFile> pageList = ossFileService.page(page, queryWrapper);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping("/upload")
|
||||
//@RequiresRoles("admin")
|
||||
public Result upload(@RequestParam("file") MultipartFile multipartFile) {
|
||||
Result result = new Result();
|
||||
try {
|
||||
ossFileService.upload(multipartFile);
|
||||
result.success("上传成功!");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.info(ex.getMessage(), ex);
|
||||
result.error500("上传失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@DeleteMapping("/delete")
|
||||
public Result delete(@RequestParam(name = "id") String id) {
|
||||
Result result = new Result();
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
boolean ok = ossFileService.delete(file);
|
||||
result.success("删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询.
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/queryById")
|
||||
public Result<OssFile> queryById(@RequestParam(name = "id") String id) {
|
||||
Result<OssFile> result = new Result<>();
|
||||
OssFile file = ossFileService.getById(id);
|
||||
if (file == null) {
|
||||
result.error500("未找到对应实体");
|
||||
}
|
||||
else {
|
||||
result.setResult(file);
|
||||
result.setSuccess(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user