JeecgBoot 3.1.0 版本发布,基于代码生成器的企业级低代码平台

This commit is contained in:
zhangdaiscott
2022-02-24 15:13:05 +08:00
parent 84218c7fee
commit 9a3deba51b
304 changed files with 40313 additions and 230872 deletions

View File

@ -1,7 +1,7 @@
Jeecg-Boot 低代码开发平台
===============
当前最新版本: 3.0发布日期2021-11-01
当前最新版本: 3.1.0发布日期20220301
## 后端技术架构

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

File diff suppressed because one or more lines are too long

View File

@ -1,63 +0,0 @@
-- 字段长度不规范导致转库错误Specified key was too long; max key length is 767 bytes
ALTER TABLE `rep_demo_dxtj`
MODIFY COLUMN `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键' FIRST;
ALTER TABLE `sys_third_account`
MODIFY COLUMN `third_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登录来源' AFTER `third_user_id`;
-- 数据源字典sql整理
DELETE FROM `sys_dict_item` WHERE dict_id ='1209733563293962241';
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733775114702850', '1209733563293962241', 'MySQL5.5', '1', '', 1, 1, 'admin', '2019-12-25 15:13:02', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1334440962954936321', '1209733563293962241', 'MYSQL5.7+', '4', '', 2, 1, 'admin', '2020-12-03 18:16:02', 'admin', '2021-07-15 13:44:29');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733839933476865', '1209733563293962241', 'Oracle', '2', '', 3, 1, 'admin', '2019-12-25 15:13:18', 'admin', '2021-07-15 13:44:08');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1209733903020003330', '1209733563293962241', 'SQLServer', '3', '', 4, 1, 'admin', '2019-12-25 15:13:33', 'admin', '2021-07-15 13:44:11');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1414837074500976641', '1209733563293962241', 'postgresql', '6', '', 5, 1, 'admin', '2021-07-13 14:40:20', 'admin', '2021-07-15 13:44:15');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1415547541091504129', '1209733563293962241', 'marialDB', '5', '', 6, 1, 'admin', '2021-07-15 13:43:28', 'admin', '2021-07-15 13:44:23');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418049969003089922', '1209733563293962241', '达梦', '7', '', 7, 1, 'admin', '2021-07-22 11:27:13', 'admin', '2021-07-22 11:27:30');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050017053036545', '1209733563293962241', '人大金仓', '8', '', 8, 1, 'admin', '2021-07-22 11:27:25', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050075555188737', '1209733563293962241', '神通', '9', '', 9, 1, 'admin', '2021-07-22 11:27:39', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050110669901826', '1209733563293962241', 'SQLite', '10', '', 10, 1, 'admin', '2021-07-22 11:27:47', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050149475602434', '1209733563293962241', 'DB2', '11', '', 11, 1, 'admin', '2021-07-22 11:27:56', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050209823248385', '1209733563293962241', 'Hsqldb', '12', '', 12, 1, 'admin', '2021-07-22 11:28:11', 'admin', '2021-07-22 11:28:27');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418050323111399425', '1209733563293962241', 'Derby', '13', '', 13, 1, 'admin', '2021-07-22 11:28:38', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418117316707590146', '1209733563293962241', 'H2', '14', '', 14, 1, 'admin', '2021-07-22 15:54:50', NULL, NULL);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1418491604048449537', '1209733563293962241', '其他数据库', '15', '', 15, 1, 'admin', '2021-07-23 16:42:07', NULL, NULL);
-- 新增 hideTab 字段
ALTER TABLE `sys_permission`
ADD COLUMN `hide_tab` int(2) NULL COMMENT '是否隐藏tab: 0否,1是' AFTER `hidden`;
-- 【online表单】新增 low_app_id 字段
ALTER TABLE `onl_cgform_head`
ADD COLUMN `low_app_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '关联的应用ID' AFTER `des_form_code`;
-- online老数据,存在字符串类型key值不一致的情况,String改为string
UPDATE onl_cgform_field SET db_type = 'string' where binary db_type = 'String';
-- 积木报表升级
ALTER TABLE `jimu_report`
MODIFY COLUMN `view_count` bigint(15) NULL DEFAULT 0 COMMENT '浏览次数' AFTER `template`;
ALTER TABLE `jimu_report`
MODIFY COLUMN `json_str` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'json字符串' AFTER `type`;
ALTER TABLE `jimu_report_db_field`
ADD COLUMN `search_format` varchar(50) NULL COMMENT '查询时间格式化表达式' AFTER `search_value`;
ALTER TABLE `jimu_report_db_param`
ADD COLUMN `search_format` varchar(50) NULL COMMENT '查询时间格式化表达式' AFTER `dict_code`;
UPDATE jimu_report SET json_str=replace(json_str,'"subtotal":"totalField"','"funcname":"SUM"');
ALTER TABLE `jimu_report`
ADD COLUMN `css_str` text NULL COMMENT 'css增强' AFTER `view_count`,
ADD COLUMN `js_str` text NULL COMMENT 'js增强' AFTER `css_str`;
ALTER TABLE `jimu_report_link`
CHANGE COLUMN `expression` `requirement` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '条件' AFTER `link_chart_id`;
ALTER TABLE `jimu_report_db_field`
ADD COLUMN `ext_json` text NULL COMMENT '参数配置' AFTER `search_format`;
ALTER TABLE `jimu_report_db_param`
ADD COLUMN `ext_json` text NULL COMMENT '参数配置' AFTER `search_format`;
ALTER TABLE `jimu_report_db`
MODIFY COLUMN `is_list` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否是列表0否1是 默认0' AFTER `api_method`;

View File

@ -0,0 +1,36 @@
-- 第三方用户表应该加上创建人,创建时间、修改人、修改时间
ALTER TABLE `sys_third_account`
ADD COLUMN `create_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人登录名称' AFTER `third_user_id`,
ADD COLUMN `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建日期' AFTER `create_by`,
ADD COLUMN `update_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新人登录名称' AFTER `create_time`,
ADD COLUMN `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新日期' AFTER `update_by`;
-- 对象存储字段太短
ALTER TABLE `oss_file`
MODIFY COLUMN `url` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '文件地址' AFTER `file_name`;
-- 地址获取到多个地址, 地址过长导致权限菜单修改失败
ALTER TABLE `sys_role_permission`
MODIFY COLUMN `operate_ip` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作ip' AFTER `operate_date`;
-- 修改 sys_permission 下的两个字段为 tinyint 类型
ALTER TABLE `sys_permission`
MODIFY COLUMN `hidden` tinyint(1) NULL DEFAULT 0 COMMENT '是否隐藏路由: 0否,1是' AFTER `keep_alive`,
MODIFY COLUMN `hide_tab` tinyint(1) NULL DEFAULT NULL COMMENT '是否隐藏tab: 0否,1是' AFTER `hidden`;
-- 默认示例内嵌百度改成jeecg.com官网
UPDATE sys_permission SET name = 'JEECG官方网站' , url = 'http://www.jeecg.com' WHERE id = 'a400e4f4d54f79bf5ce160ae432231af';
-- 菜单名和代码改名 erp风格
UPDATE `sys_permission` SET `parent_id` = '2a470fc0c3954d9dbb61de6d80846549', `name` = '一对多erp风格示例', `url` = '/jeecg/tablist/JeecgOrderDMainList', `component` = 'jeecg/tablist/JeecgOrderDMainList', `component_name` = NULL, `redirect` = NULL, `menu_type` = 1, `perms` = NULL, `perms_type` = NULL, `sort_no` = 2.00, `always_show` = 0, `icon` = NULL, `is_route` = 1, `is_leaf` = 1, `keep_alive` = 0, `hidden` = 0, `description` = NULL, `status` = NULL, `del_flag` = 0, `rule_flag` = 0, `create_by` = 'admin', `create_time` = '2019-02-20 14:45:09', `update_by` = 'admin', `update_time` = '2022-01-17 17:02:51', `internal_or_external` = 0, `hide_tab` = '0' WHERE `id` = '6ad53fd1b220989a8b71ff482d683a5a';
-- 分类字典 列表页 显示数据id
UPDATE sys_category SET code='B01-2-3' WHERE id='1404629269499936770';
UPDATE sys_category SET code='B01-2-2' WHERE id='937fd2e9aa13b8bab1da1ca36d3fd344';
-- 新的表格合计菜单
INSERT INTO `sys_permission`(`id`, `parent_id`, `name`, `url`, `component`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_route`, `is_leaf`, `keep_alive`, `hidden`, `description`, `status`, `del_flag`, `rule_flag`, `create_by`, `create_time`, `update_by`, `update_time`, `internal_or_external`, `hide_tab`) VALUES ('1494641317580423169', '2a470fc0c3954d9dbb61de6d80846549', '表格合计News', '/jeecg/tableOrderTotal', 'jeecg/TableOrderTotal', NULL, NULL, 1, NULL, '1', 3.00, 0, NULL, 1, 1, 0, 0, NULL, '1', 0, 0, 'admin', '2022-02-18 19:53:54', 'admin', '2022-02-18 19:55:04', 0, '0');
-- online老数据,存在字符串类型key值不一致的情况,String改为string
UPDATE onl_cgform_field SET db_type = 'string' where binary db_type = 'String';

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -37,8 +37,8 @@ public interface IBpmBaseExtAPI {
*/
@PostMapping(value = "/act/process/extActProcess/startMutilProcess")
Result<String> startMutilProcess(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
/**
* 24. 流程提交接口(自定义表单设计器)
@ -60,8 +60,8 @@ public interface IBpmBaseExtAPI {
*/
@PostMapping(value = "/act/process/extActProcess/startDesFormMutilProcess")
Result<String> startDesFormMutilProcess(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
/**
* 25. 保存流程草稿箱接口自定义开发表单、online表单
@ -83,7 +83,7 @@ public interface IBpmBaseExtAPI {
*/
@PostMapping(value = "/act/process/extActProcess/saveMutilProcessDraft")
Result<String> saveMutilProcessDraft(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
@RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
@RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
}

View File

@ -15,7 +15,8 @@ import java.util.Map;
* 【Online】Feign API接口
*/
@Component
@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_ONLINE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
//@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_ONLINE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
public interface IOnlineBaseExtAPI {
/**

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -25,7 +25,7 @@ public interface IBpmBaseExtAPI {
* @return
* @throws Exception
*/
Result<String> startMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,String username, String jsonData) throws Exception;
Result<String> startMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile, String username, String jsonData) throws Exception;
/**
* 24. 流程提交接口(自定义表单设计器)
@ -38,7 +38,7 @@ public interface IBpmBaseExtAPI {
* @return
* @throws Exception
*/
Result<String> startDesFormMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,String username,String jsonData) throws Exception;
Result<String> startDesFormMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile, String username, String jsonData) throws Exception;
/**
* 25. 保存流程草稿箱接口自定义开发表单、online表单
* @param flowCode 流程业务关联 例如joa_leave_01
@ -50,6 +50,6 @@ public interface IBpmBaseExtAPI {
* @return
* @throws Exception
*/
Result<String> saveMutilProcessDraft(String flowCode, String id, String formUrl, String formUrlMobile,String username,String jsonData) throws Exception;
Result<String> saveMutilProcessDraft(String flowCode, String id, String formUrl, String formUrlMobile, String username, String jsonData) throws Exception;
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-base</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -71,16 +71,16 @@ public class Result<T> implements Serializable {
}
@Deprecated
public static Result<Object> ok() {
Result<Object> r = new Result<Object>();
public static<T> Result<T> ok() {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
return r;
}
@Deprecated
public static Result<Object> ok(String msg) {
Result<Object> r = new Result<Object>();
public static<T> Result<T> ok(String msg) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
@ -88,8 +88,8 @@ public class Result<T> implements Serializable {
}
@Deprecated
public static Result<Object> ok(Object data) {
Result<Object> r = new Result<Object>();
public static<T> Result<T> ok(T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
@ -103,6 +103,7 @@ public class Result<T> implements Serializable {
return r;
}
@Deprecated
public static<T> Result<T> OK(String msg) {
Result<T> r = new Result<T>();
r.setSuccess(true);
@ -139,12 +140,12 @@ public class Result<T> implements Serializable {
return r;
}
public static Result<Object> error(String msg) {
public static<T> Result<T> error(String msg) {
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static Result<Object> error(int code, String msg) {
Result<Object> r = new Result<Object>();
public static<T> Result<T> error(int code, String msg) {
Result<T> r = new Result<T>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
@ -157,10 +158,11 @@ public class Result<T> implements Serializable {
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static Result<Object> noauth(String msg) {
public static<T> Result<T> noauth(String msg) {
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
}

View File

@ -88,7 +88,7 @@ public class AutoLogAspect {
//设置操作类型
if (dto.getLogType() == CommonConstant.LOG_TYPE_2) {
if (CommonConstant.LOG_TYPE_2 == dto.getLogType()) {
dto.setOperateType(getOperateType(methodName, syslog.operateType()));
}

View File

@ -2,6 +2,7 @@ package org.jeecg.common.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
@ -18,6 +19,7 @@ import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@ -38,14 +40,14 @@ import java.util.stream.Collectors;
@Component
@Slf4j
public class DictAspect {
@Lazy
@Autowired
private CommonAPI commonAPI;
@Autowired
public RedisTemplate redisTemplate;
// 定义切点Pointcut
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
@Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..)) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)")
public void excudeService() {
}
@ -103,7 +105,10 @@ public class DictAspect {
} catch (JsonProcessingException e) {
log.error("json解析失败"+e.getMessage(),e);
}
JSONObject item = JSONObject.parseObject(json);
//update-begin--Author:scott -- Date:20211223 ----for【issues/3303】restcontroller返回json数据后key顺序错乱 -----
JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
//update-end--Author:scott -- Date:20211223 ----for【issues/3303】restcontroller返回json数据后key顺序错乱 -----
//update-begin--Author:scott -- Date:20190603 ----for解决继承实体字段无法翻译问题------
//for (Field field : record.getClass().getDeclaredFields()) {
// 遍历所有字段把字典Code取出来放到 map 里

View File

@ -8,6 +8,7 @@ import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JeecgDataAutorUtils;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
@ -15,6 +16,7 @@ import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@ -31,7 +33,7 @@ import java.util.List;
@Component
@Slf4j
public class PermissionDataAspect {
@Lazy
@Autowired
private CommonAPI commonAPI;
@ -47,11 +49,21 @@ public class PermissionDataAspect {
Method method = signature.getMethod();
PermissionData pd = method.getAnnotation(PermissionData.class);
String component = pd.pageComponent();
String requestMethod = request.getMethod();
String requestPath = request.getRequestURI().substring(request.getContextPath().length());
requestPath = filterUrl(requestPath);
log.debug("拦截请求 >> "+requestPath+";请求类型 >> "+requestMethod);
//update-begin-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
//先判断是否online报表请求
// TODO 参数顺序调整有隐患
if(requestPath.indexOf(UrlMatchEnum.CGREPORT_DATA.getMatch_url())>=0){
// 获取地址栏参数
String urlParamString = request.getParameter(CommonConstant.ONL_REP_URL_PARAM_STR);
if(oConvertUtils.isNotEmpty(urlParamString)){
requestPath+="?"+urlParamString;
}
}
//update-end-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod);
String username = JwtUtil.getUserNameByToken(request);
//查询数据权限信息
//TODO 微服务情况下也得支持缓存机制
@ -86,6 +98,7 @@ public class PermissionDataAspect {
* @param request
* @return
*/
@Deprecated
private String getJgAuthRequsetPath(HttpServletRequest request) {
String queryString = request.getQueryString();
String requestPath = request.getRequestURI();
@ -106,6 +119,7 @@ public class PermissionDataAspect {
return filterUrl(requestPath);
}
@Deprecated
private boolean moHuContain(List<String> list,String key){
for(String str : list){
if(key.contains(str)){

View File

@ -10,8 +10,8 @@ public enum UrlMatchEnum {
CGFORM_EXCEL_DATA("/online/cgform/api/exportXls/", "/online/cgformList/"),
CGFORM_TREE_DATA("/online/cgform/api/getTreeData/", "/online/cgformList/"),
CGREPORT_DATA("/online/cgreport/api/getColumnsAndData/", "/online/cgreport/"),
CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/");
CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/"),
CGREPORT_EXCEL_DATA2("/online/cgreport/api/exportManySheetXls/", "/online/cgreport/");
UrlMatchEnum(String url, String match_url) {
this.url = url;
@ -47,8 +47,10 @@ public enum UrlMatchEnum {
return null;
}
// public static void main(String[] args) {
public String getMatch_url() {
return match_url;
}
// public static void main(String[] args) {
// /**
// * 比如request真实请求URL: /online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a
// * 转换匹配路由URL后对应配置的菜单路径:/online/cgformList/81fcf7d8922d45069b0d5ba983612d3a

View File

@ -0,0 +1,23 @@
package org.jeecg.common.aspect.annotation;
import java.lang.annotation.*;
/**
* 通过此注解声明的接口,自动实现字典翻译
*
* @Author scott
* @email jeecgos@163.com
* @Date 2022年01月05日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoDict {
/**
* 暂时无用
* @return
*/
String value() default "";
}

View File

@ -0,0 +1,33 @@
package org.jeecg.common.aspect.annotation;
import java.lang.annotation.*;
import org.jeecg.common.constant.enums.LowAppAopEnum;
/**
* 自动注入low_app_id
*
* @Author scott
* @email jeecgos@163.com
* @Date 2022年01月05日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoLowApp {
/**
* 切面类型add、delete、db_import等其他操作
*
* @return
*/
LowAppAopEnum action();
/**
* 业务类型cgform等
*
* @return
*/
String bizType();
}

View File

@ -77,7 +77,13 @@ public interface CommonConstant {
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
/** Token缓存时间3600秒即一小时 */
public static final int TOKEN_EXPIRE_TIME = 3600;
/** 登录二维码 */
public static final String LOGIN_QRCODE_PRE = "QRCODELOGIN:";
public static final String LOGIN_QRCODE = "LQ:";
/** 登录二维码token */
public static final String LOGIN_QRCODE_TOKEN = "LQT:";
/**
* 0一级菜单
@ -91,7 +97,7 @@ public interface CommonConstant {
* 2按钮权限
*/
public static final Integer MENU_TYPE_2 = 2;
/**通告对象类型USER:指定用户ALL:全体用户)*/
public static final String MSG_TYPE_UESR = "USER";
public static final String MSG_TYPE_ALL = "ALL";
@ -229,6 +235,9 @@ public interface CommonConstant {
public static final 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";
/** 达梦数据库升提示。违反表[SYS_USER]唯一性约束 */
public static final String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束";
/** sys_user 表 email 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
/** sys_quartz_job 表 job_class_name 唯一键索引 */
@ -239,6 +248,8 @@ public interface CommonConstant {
public static final 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";
/** sys_category 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code";
/**
* 在线聊天 是否为默认分组
*/
@ -325,4 +336,7 @@ public interface CommonConstant {
/** 系统通告消息状态2=已撤销 */
String ANNOUNCEMENT_SEND_STATUS_2 = "2";
/**ONLINE 报表权限用 从request中获取地址栏后的参数*/
String ONL_REP_URL_PARAM_STR="onlRepUrlParamStr";
}

View File

@ -29,7 +29,7 @@ public class ProvinceCityArea {
public String getCode(String text){
this.initAreaList();
if(areaList!=null || areaList.size()>0){
if(areaList!=null && areaList.size()>0){
for(int i=areaList.size()-1;i>=0;i--){
if(text.indexOf(areaList.get(i).getText())>=0){
return areaList.get(i).getId();
@ -39,6 +39,73 @@ public class ProvinceCityArea {
return null;
}
// update-begin-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
/**
* 获取省市区code精准匹配
* @param texts 文本数组,省,市,区
* @return 返回 省市区的code
*/
public String[] getCode(String[] texts) {
if (texts == null || texts.length == 0) {
return null;
}
this.initAreaList();
if (areaList == null || areaList.size() == 0) {
return null;
}
String[] codes = new String[texts.length];
String code = null;
for (int i = 0; i < texts.length; i++) {
String text = texts[i];
Area area;
if (code == null) {
area = getAreaByText(text);
} else {
area = getAreaByPidAndText(code, text);
}
if (area != null) {
code = area.id;
codes[i] = code;
} else {
return null;
}
}
return codes;
}
/**
* 根据text获取area
* @param text
* @return
*/
public Area getAreaByText(String text) {
for (Area area : areaList) {
if (text.equals(area.getText())) {
return area;
}
}
return null;
}
/**
* 通过pid获取 area 对象
* @param pCode 父级编码
* @param text
* @return
*/
public Area getAreaByPidAndText(String pCode, String text) {
this.initAreaList();
if (this.areaList != null && this.areaList.size() > 0) {
for (Area area : this.areaList) {
if (area.getPid().equals(pCode) && area.getText().equals(text)) {
return area;
}
}
}
return null;
}
// update-end-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
public void getAreaByCode(String code,List<String> ls){
for(Area area: areaList){
if(area.getId().equals(code)){

View File

@ -0,0 +1,22 @@
package org.jeecg.common.constant.enums;
/**
* LowApp 切面注解枚举
* @date 2022-1-5
*/
public enum LowAppAopEnum {
/**
* 新增方法
*/
ADD,
/**
* 删除方法(包含单个和批量删除)
*/
DELETE,
/**
* Online表单专用数据库表转Online表单
*/
CGFORM_DB_IMPORT
}

View File

@ -1,24 +1,20 @@
package org.jeecg.common.constant.enums;
import org.jeecg.common.util.oConvertUtils;
import java.util.List;
/**
* 首页自定义
* 通过角色编码与首页组件路径配置
* 枚举的顺序有权限高低权重作用(也就是配置多个角色,在前面的角色首页,会优先生效)
*/
public enum RoleIndexConfigEnum {
/**
* 管理员
*/
ADMIN("admin1", "dashboard/Analysis2"),
/**
* 测试
*/
TEST("test", "dashboard/Analysis"),
/**
* hr
*/
HR("hr", "dashboard/Analysis1");
ADMIN("admin", "dashboard/Analysis"),
//TEST("test", "dashboard/IndexChart"),
HR("hr", "dashboard/IndexBdc");
//DM("dm", "dashboard/IndexTask"),
/**
* 角色编码
@ -44,7 +40,7 @@ public enum RoleIndexConfigEnum {
* @param roleCode 角色编码
* @return
*/
public static RoleIndexConfigEnum getEnumByCode(String roleCode) {
private static RoleIndexConfigEnum getEnumByCode(String roleCode) {
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
if (e.roleCode.equals(roleCode)) {
return e;
@ -57,7 +53,7 @@ public enum RoleIndexConfigEnum {
* @param roleCode 角色编码
* @return
*/
public static String getIndexByCode(String roleCode) {
private static String getIndexByCode(String roleCode) {
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
if (e.roleCode.equals(roleCode)) {
return e.componentUrl;
@ -67,11 +63,10 @@ public enum RoleIndexConfigEnum {
}
public static String getIndexByRoles(List<String> roles) {
for (String role : roles) {
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
if (e.roleCode.equals(role)) {
return e.componentUrl;
}
String[] rolesArray = roles.toArray(new String[roles.size()]);
for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
if (oConvertUtils.isIn(e.roleCode,rolesArray)){
return e.componentUrl;
}
}
return null;

View File

@ -180,8 +180,15 @@ public class JeecgController<T, S extends IService<T>> {
//update-end-author:taoyan date:20190528 for:批量插入数据
return Result.ok("文件导入成功!数据行数:" + list.size());
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:" + e.getMessage());
//update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示
String msg = e.getMessage();
log.error(msg, e);
if(msg!=null && msg.indexOf("Duplicate entry")>=0){
return Result.error("文件导入失败:有重复数据!");
}else{
return Result.error("文件导入失败:" + e.getMessage());
}
//update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
} finally {
try {
file.getInputStream().close();

View File

@ -25,7 +25,6 @@ import org.jeecg.common.util.oConvertUtils;
import org.springframework.util.NumberUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@ -145,20 +144,23 @@ public class QueryGenerator {
//区间查询
doIntervalQuery(queryWrapper, parameterMap, type, name, column);
//判断单值 参数带不同标识字符串 走不同的查询
//TODO 这种前后带逗号的支持分割后模糊查询需要否 使多选字段查询生效
//TODO 这种前后带逗号的支持分割后模糊查询(多选字段查询生效) 示例:,1,3,
if (null != value && value.toString().startsWith(COMMA) && value.toString().endsWith(COMMA)) {
String multiLikeval = value.toString().replace(",,", COMMA);
String[] vals = multiLikeval.substring(1, multiLikeval.length()).split(COMMA);
final String field = oConvertUtils.camelToUnderline(column);
if(vals.length>1) {
queryWrapper.and(j -> {
log.info("---查询过滤器Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
j = j.like(field,vals[0]);
for (int k=1;k<vals.length;k++) {
j = j.or().like(field,vals[k]);
log.info("---查询过滤器Query规则 .or()---field:{}, rule:{}, value:{}", field, "like", vals[k]);
}
//return j;
});
}else {
log.info("---查询过滤器Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
queryWrapper.and(j -> j.like(field,vals[0]));
}
}else {
@ -224,7 +226,7 @@ public class QueryGenerator {
if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
order = parameterMap.get(ORDER_TYPE)[0];
}
log.info("排序规则>>列:" + column + ",排序方式:" + order);
log.debug("排序规则>>列:" + column + ",排序方式:" + order);
if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
//字典字段,去掉字典翻译文本后缀
if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
@ -270,10 +272,21 @@ public class QueryGenerator {
if (conditions == null || conditions.size() == 0) {
return;
}
log.info("---高级查询参数-->" + conditions.toString());
// update-begin-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
List<QueryCondition> filterConditions = conditions.stream().filter(
rule -> oConvertUtils.isNotEmpty(rule.getField())
&& oConvertUtils.isNotEmpty(rule.getRule())
&& oConvertUtils.isNotEmpty(rule.getVal())
).collect(Collectors.toList());
if (filterConditions.size() == 0) {
return;
}
// update-end-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
log.info("---高级查询参数-->" + filterConditions);
queryWrapper.and(andWrapper -> {
for (int i = 0; i < conditions.size(); i++) {
QueryCondition rule = conditions.get(i);
for (int i = 0; i < filterConditions.size(); i++) {
QueryCondition rule = filterConditions.get(i);
if (oConvertUtils.isNotEmpty(rule.getField())
&& oConvertUtils.isNotEmpty(rule.getRule())
&& oConvertUtils.isNotEmpty(rule.getVal())) {
@ -324,7 +337,7 @@ public class QueryGenerator {
//update-end-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错
// 如果拼接方式是OR就拼接OR
if (MatchTypeEnum.OR == matchType && i < (conditions.size() - 1)) {
if (MatchTypeEnum.OR == matchType && i < (filterConditions.size() - 1)) {
andWrapper.or();
}
}
@ -457,15 +470,37 @@ public class QueryGenerator {
private static void addQueryByRule(QueryWrapper<?> queryWrapper,String name,String type,String value,QueryRuleEnum rule) throws ParseException {
if(oConvertUtils.isNotEmpty(value)) {
Object temp;
//update-begin--Author:sunjianlei Date:20220104 for【JTC-409】修复逗号分割情况下没有转换类型导致类型严格的数据库查询报错 -------------------
// 针对数字类型字段,多值查询
if(value.indexOf(COMMA)!=-1){
temp = value;
if(value.contains(COMMA)){
Object[] temp = Arrays.stream(value.split(COMMA)).map(v -> {
try {
return QueryGenerator.parseByType(v, type, rule);
} catch (ParseException e) {
e.printStackTrace();
return v;
}
}).toArray();
addEasyQuery(queryWrapper, name, rule, temp);
return;
}
Object temp = QueryGenerator.parseByType(value, type, rule);
addEasyQuery(queryWrapper, name, rule, temp);
//update-end--Author:sunjianlei Date:20220104 for【JTC-409】修复逗号分割情况下没有转换类型导致类型严格的数据库查询报错 -------------------
}
}
switch (type) {
/**
* 根据类型转换给定的值
* @param value
* @param type
* @param rule
* @return
* @throws ParseException
*/
private static Object parseByType(String value, String type, QueryRuleEnum rule) throws ParseException {
Object temp;
switch (type) {
case "class java.lang.Integer":
temp = Integer.parseInt(value);
break;
@ -490,9 +525,8 @@ public class QueryGenerator {
default:
temp = value;
break;
}
addEasyQuery(queryWrapper, name, rule, temp);
}
return temp;
}
/**
@ -527,12 +561,12 @@ public class QueryGenerator {
* @param rule 查询规则
* @param value 查询条件值
*/
private static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
public static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
if (value == null || rule == null || oConvertUtils.isEmpty(value)) {
return;
}
name = oConvertUtils.camelToUnderline(name);
log.info("--查询规则-->"+name+" "+rule.getValue()+" "+value);
log.info("---查询过滤器Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);
switch (rule) {
case GT:
queryWrapper.gt(name, value);
@ -555,7 +589,7 @@ public class QueryGenerator {
break;
case IN:
if(value instanceof String) {
queryWrapper.in(name, (Object[])value.toString().split(","));
queryWrapper.in(name, (Object[])value.toString().split(COMMA));
}else if(value instanceof String[]) {
queryWrapper.in(name, (Object[]) value);
}

View File

@ -34,8 +34,8 @@ import org.jeecg.common.util.oConvertUtils;
**/
public class JwtUtil {
// Token过期时间30分钟用户登录过期时间是此时间的两倍以token在reids缓存时间为准
public static final long EXPIRE_TIME = 30 * 60 * 1000;
// Token过期时间2小时用户登录过期时间是此时间的两倍以token在reids缓存时间为准
public static final long EXPIRE_TIME = 2 * 60 * 60 * 1000;
/**
*
@ -155,7 +155,6 @@ public class JwtUtil {
* @param user
* @return
*/
//TODO 急待改造 sckjkdsjsfjdk
public static String getUserSystemData(String key,SysUserCacheInfo user) {
if(user==null) {
user = JeecgDataAutorUtils.loadUserInfo();

View File

@ -39,5 +39,11 @@ public class DictModel implements Serializable{
public String getTitle() {
return this.text;
}
/**
* 特殊用途: vue3 Select组件
*/
public String getLabel() {
return this.text;
}
}

View File

@ -14,6 +14,7 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.io.File;
@ -282,4 +283,39 @@ public class CommonUtils {
return DB_TYPE;
}
/**
* 获取服务器地址
*
* @param request
* @return
*/
public static String getBaseUrl(HttpServletRequest request) {
//1.【兼容】兼容微服务下的 base path-------
String x_gateway_base_path = request.getHeader("X_GATEWAY_BASE_PATH");
if(oConvertUtils.isNotEmpty(x_gateway_base_path)){
log.info("x_gateway_base_path = "+ x_gateway_base_path);
return x_gateway_base_path;
}
//2.【兼容】SSL认证之后request.getScheme()获取不到https的问题
// https://blog.csdn.net/weixin_34376986/article/details/89767950
String scheme = request.getHeader("X-Forwarded-Scheme");
if(oConvertUtils.isEmpty(scheme)){
scheme = request.getScheme();
}
//3.常规操作
String serverName = request.getServerName();
int serverPort = request.getServerPort();
String contextPath = request.getContextPath();
//返回 host domain
String baseDomainPath = null;
if(80 == serverPort){
baseDomainPath = scheme + "://" + serverName + contextPath ;
}else{
baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
}
log.info("-----Common getBaseUrl----- : " + baseDomainPath);
return baseDomainPath;
}
}

View File

@ -1,6 +1,7 @@
package org.jeecg.common.util;
import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.filter.StrAttackFilter;
@ -158,9 +159,11 @@ public class MinioUtil {
public static String getObjectURL(String bucketName, String objectName, Integer expires) {
initMinio(minioUrl, minioName,minioPass);
try{
//update-begin---author:liusq Date:20220121 for获取文件外链报错提示method不能为空导致文件下载和预览失败----
GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
.bucket(bucketName)
.expiry(expires).build();
.expiry(expires).method(Method.GET).build();
//update-begin---author:liusq Date:20220121 for获取文件外链报错提示method不能为空导致文件下载和预览失败----
String url = minioClient.getPresignedObjectUrl(objectArgs);
return URLDecoder.decode(url,"UTF-8");
}catch (Exception e){

View File

@ -17,7 +17,7 @@ public class SqlInjectionUtil {
* (上线修改值 20200501同步修改前端的盐值
*/
private final static String TABLE_DICT_SIGN_SALT = "20200501";
private final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+";
private final static String xssStr = "and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";
/*
* 针对表字典进行额外的sign签名校验增加安全机制

View File

@ -25,7 +25,7 @@ public class DbTypeUtils {
dialectMap.put("postgresql", "org.hibernate.dialect.PostgreSQLDialect"); //1 --
dialectMap.put("sqlserver2005", "org.hibernate.dialect.SQLServer2005Dialect");
dialectMap.put("sqlserver", "org.hibernate.dialect.SQLServerDialect"); //1
dialectMap.put("dm", "org.hibernate.dialect.OracleDialect");//达梦数据库 [国产] 1--
dialectMap.put("dm", "org.hibernate.dialect.DmDialect");//达梦数据库 [国产] 1--
dialectMap.put("xugu", "org.hibernate.dialect.HSQLDialect"); //虚谷数据库
dialectMap.put("kingbasees", "org.hibernate.dialect.PostgreSQLDialect"); //人大金仓 [国产] 1
dialectMap.put("phoenix", "org.hibernate.dialect.HSQLDialect"); // Phoenix HBase数据库

View File

@ -258,6 +258,9 @@ public class OssBootUtil {
newBucket = bucket;
}
initOSS(endPoint, accessKeyId, accessKeySecret);
//update-begin---author:liusq Date:20220120 for替换objectName前缀防止key不一致导致获取不到文件----
objectName = OssBootUtil.replacePrefix(objectName,bucket);
//update-end---author:liusq Date:20220120 for替换objectName前缀防止key不一致导致获取不到文件----
OSSObject ossObject = ossClient.getObject(newBucket,objectName);
inputStream = new BufferedInputStream(ossObject.getObjectContent());
}catch (Exception e){
@ -266,14 +269,14 @@ public class OssBootUtil {
return inputStream;
}
/**
* 获取文件流
* @param objectName
* @return
*/
public static InputStream getOssFile(String objectName){
return getOssFile(objectName,null);
}
///**
// * 获取文件流
// * @param objectName
// * @return
// */
//public static InputStream getOssFile(String objectName){
// return getOssFile(objectName,null);
//}
/**
* 获取文件外链
@ -285,6 +288,9 @@ public class OssBootUtil {
public static String getObjectURL(String bucketName, String objectName, Date expires) {
initOSS(endPoint, accessKeyId, accessKeySecret);
try{
//update-begin---author:liusq Date:20220120 for替换objectName前缀防止key不一致导致获取不到文件----
objectName = OssBootUtil.replacePrefix(objectName,bucketName);
//update-end---author:liusq Date:20220120 for替换objectName前缀防止key不一致导致获取不到文件----
if(ossClient.doesObjectExist(bucketName,objectName)){
URL url = ossClient.generatePresignedUrl(bucketName,objectName,expires);
return URLDecoder.decode(url.toString(),"UTF-8");
@ -334,5 +340,27 @@ public class OssBootUtil {
return FILE_URL;
}
/**
* 替换前缀防止key不一致导致获取不到文件
* @param objectName 文件上传路径 key
* @param customBucket 自定义桶
* @date 2022-01-20
* @author lsq
* @return
*/
private static String replacePrefix(String objectName,String customBucket){
log.info("------replacePrefix---替换前---objectName:{}",objectName);
if(oConvertUtils.isNotEmpty(staticDomain)){
objectName= objectName.replace(staticDomain+"/","");
}else{
String newBucket = bucketName;
if(oConvertUtils.isNotEmpty(customBucket)){
newBucket = customBucket;
}
String path ="https://" + newBucket + "." + endPoint + "/";
objectName = objectName.replace(path,"");
}
log.info("------replacePrefix---替换后---objectName:{}",objectName);
return objectName;
}
}

View File

@ -1,6 +1,10 @@
package org.jeecg.config;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.oConvertUtils;
@ -8,9 +12,7 @@ import org.jeecgframework.dict.service.AutoPoiDictServiceI;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
/**
* 描述AutoPoi Excel注解支持字典参数设置
@ -25,6 +27,9 @@ import java.util.List;
@Slf4j
@Service
public class AutoPoiDictConfig implements AutoPoiDictServiceI {
final static String EXCEL_SPLIT_TAG = "_";
final static String TEMP_EXCEL_SPLIT_TAG = "---";
@Lazy
@Resource
private CommonAPI commonAPI;
@ -53,7 +58,14 @@ public class AutoPoiDictConfig implements AutoPoiDictServiceI {
}
for (DictModel t : dictList) {
if(t!=null){
dictReplaces.add(t.getText() + "_" + t.getValue());
//update-begin---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
if(t.getValue().contains(EXCEL_SPLIT_TAG)){
String val = t.getValue().replace(EXCEL_SPLIT_TAG,TEMP_EXCEL_SPLIT_TAG);
dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + val);
}else{
dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + t.getValue());
}
//update-end---author:20211220 Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
}
}
if (dictReplaces != null && dictReplaces.size() != 0) {

View File

@ -1,5 +1,6 @@
package org.jeecg.config;
import org.jeecg.config.vo.Shiro;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ -14,6 +15,15 @@ public class JeeccgBaseConfig {
* 是否启用安全模式
*/
private Boolean safeMode = false;
/**
* shiro拦截排除
*/
private Shiro shiro;
/**
* 签名密钥串(字典等敏感接口)
* @TODO 降低使用成本加的默认值,实际以 yml配置 为准
*/
private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
public Boolean getSafeMode() {
return safeMode;
@ -22,4 +32,20 @@ public class JeeccgBaseConfig {
public void setSafeMode(Boolean safeMode) {
this.safeMode = safeMode;
}
public String getSignatureSecret() {
return signatureSecret;
}
public void setSignatureSecret(String signatureSecret) {
this.signatureSecret = signatureSecret;
}
public Shiro getShiro() {
return shiro;
}
public void setShiro(Shiro shiro) {
this.shiro = shiro;
}
}

View File

@ -20,11 +20,11 @@ public class StaticConfig {
@Value(value = "${spring.mail.username}")
private String emailFrom;
/**
* 签名密钥串
*/
@Value(value = "${jeecg.signatureSecret}")
private String signatureSecret;
// /**
// * 签名密钥串
// */
// @Value(value = "${jeecg.signatureSecret}")
// private String signatureSecret;
/*@Bean

View File

@ -1,3 +1,4 @@
package org.jeecg.config.shiro;
import lombok.extern.slf4j.Slf4j;
@ -15,6 +16,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.shiro.filters.CustomShiroFilterFactoryBean;
import org.jeecg.config.shiro.filters.JwtFilter;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
@ -43,13 +45,12 @@ import java.util.*;
@Configuration
public class ShiroConfig {
@Value("${jeecg.shiro.excludeUrls}")
private String excludeUrls;
@Resource
LettuceConnectionFactory lettuceConnectionFactory;
@Autowired
private Environment env;
@Autowired
JeeccgBaseConfig jeeccgBaseConfig;
/**
* Filter Chain定义说明
@ -64,8 +65,9 @@ public class ShiroConfig {
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
if(oConvertUtils.isNotEmpty(excludeUrls)){
String[] permissionUrl = excludeUrls.split(",");
String shiroExcludeUrls = jeeccgBaseConfig.getShiro().getExcludeUrls();
if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
String[] permissionUrl = shiroExcludeUrls.split(",");
for(String url : permissionUrl){
filterChainDefinitionMap.put(url,"anon");
}
@ -89,6 +91,12 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/doc.html", "anon");
filterChainDefinitionMap.put("/**/*.js", "anon");
@ -130,6 +138,9 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
//wps
filterChainDefinitionMap.put("/v1/**","anon");
//性能监控 TODO 存在安全漏洞泄露TOEKNdurid连接池也有
filterChainDefinitionMap.put("/actuator/**", "anon");

View File

@ -137,9 +137,12 @@ public class ShiroRealm extends AuthorizingRealm {
if(oConvertUtils.isNotEmpty(userTenantIds)){
String contextTenantId = TenantContext.getTenant();
if(oConvertUtils.isNotEmpty(contextTenantId) && !"0".equals(contextTenantId)){
if(String.join(",",userTenantIds).indexOf(contextTenantId)<0){
//update-begin-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
String[] arr = userTenantIds.split(",");
if(!oConvertUtils.isIn(contextTenantId, arr)){
throw new AuthenticationException("用户租户信息变更,请重新登陆!");
}
//update-end-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
}
}
//update-end-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致

View File

@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.StaticConfig;
import org.jeecg.config.JeeccgBaseConfig;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
@ -46,8 +46,9 @@ public class SignUtil {
params.remove("_t");
String paramsJsonStr = JSONObject.toJSONString(params);
log.info("Param paramsJsonStr : {}", paramsJsonStr);
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
String signatureSecret = staticConfig.getSignatureSecret();
//设置签名秘钥
JeeccgBaseConfig jeeccgBaseConfig = SpringContextUtils.getBean(JeeccgBaseConfig.class);
String signatureSecret = jeeccgBaseConfig.getSignatureSecret();
if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains("${")){
throw new JeecgBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 ");
}

View File

@ -0,0 +1,18 @@
package org.jeecg.config.vo;
/**
* @Description: TODO
* @author: scott
* @date: 2022年01月21日 14:23
*/
public class Shiro {
private String excludeUrls = "";
public String getExcludeUrls() {
return excludeUrls;
}
public void setExcludeUrls(String excludeUrls) {
this.excludeUrls = excludeUrls;
}
}

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<description>公共模块</description>

View File

@ -96,4 +96,8 @@ public interface CacheConstant {
* online图表
*/
public static final String ONLINE_GRAPH = "sys:cache:online:graph";
/**
* 拖拽页面信息缓存
*/
public static final String DRAG_PAGE_CACHE = "drag:cache:page";
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -31,7 +31,7 @@ public class MockController {
* @return
*/
@RequestMapping(value = "/json/{filename}", method = RequestMethod.GET)
public String getJsonData(@PathVariable String filename) {
public String getJsonData(@PathVariable("filename") String filename) {
String jsonpath = "classpath:org/jeecg/modules/demo/mock/json/"+filename+".json";
return readJson(jsonpath);
}

View File

@ -0,0 +1,117 @@
package org.jeecg.modules.demo.online;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* Online表单开发 demo 示例
*
* @author sunjianlei
* @date 2021-12-16
*/
@Slf4j
@RestController("onlCgformDemoController")
@RequestMapping("/demo/online/cgform")
public class OnlCgformDemoController {
/**
* Online表单 http 增强list增强示例
* @param params
* @return
*/
@PostMapping("/enhanceJavaListHttp")
public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {
log.info(" --- params" + params.toJSONString());
JSONArray dataList = params.getJSONArray("dataList");
List<DictModel> dict = virtualDictData();
for (int i = 0; i < dataList.size(); i++) {
JSONObject record = dataList.getJSONObject(i);
String province = record.getString("province");
if (province == null) {
continue;
}
String text = dict.stream()
.filter(p -> province.equals(p.getValue()))
.map(DictModel::getText)
.findAny()
.orElse(province);
record.put("province", text);
}
Result<?> res = Result.OK(dataList);
res.setCode(1);
return res;
}
/**
* 模拟字典数据
*
* @return
*/
private List<DictModel> virtualDictData() {
List<DictModel> dict = new ArrayList<>();
dict.add(new DictModel("bj", "北京"));
dict.add(new DictModel("sd", "山东"));
dict.add(new DictModel("ah", "安徽"));
return dict;
}
/**
* Online表单 http 增强add、edit增强示例
* @param params
* @return
*/
@PostMapping("/enhanceJavaHttp")
public Result<?> enhanceJavaHttp(@RequestBody JSONObject params) {
log.info(" --- params" + params.toJSONString());
String tableName = params.getString("tableName");
JSONObject record = params.getJSONObject("record");
/*
* 业务场景一: 获取提交表单数据,进行其他业务关联操作
* (比如:根据入库单,同步更改库存)
*/
log.info(" --- tableName" + tableName);
log.info(" --- 行数据:" + record.toJSONString());
/*
* 业务场景二: 保存数据之前进行数据的校验
* 直接返回错误状态即可
*/
String phone = record.getString("phone");
if (oConvertUtils.isEmpty(phone)) {
return Result.error("手机号不能为空!");
}
/*
* 业务场景三: 保存数据之对数据的处理
* 直接操作 record 即可
*/
record.put("phone", "010-" + phone);
/* 其他业务场景自行实现 */
// 返回场景一: 不对 record 做任何修改的情况下,可以直接返回 code
// 返回 0 = 丢弃当前数据
// 返回 1 = 新增当前数据
// 返回 2 = 修改当前数据 TODO存疑
// return Result.OK(1);
// 返回场景二: 需要对 record 做修改的情况下需要返回一个JSONObject对象或者Map也行
JSONObject res = new JSONObject();
res.put("code", 1);
// 将 record 返回以进行修改
res.put("record", record);
// TODO 不要 code 的概念
return Result.OK(res);
}
}

View File

@ -59,9 +59,10 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
@ApiOperation(value = "获取Demo数据列表", notes = "获取所有Demo数据列表")
@GetMapping(value = "/list")
@PermissionData(pageComponent = "jeecg/JeecgDemoList")
public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
public Result<IPage<JeecgDemo>> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
queryWrapper.orderByDesc("create_time");
Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize);
IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
@ -92,9 +93,9 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
* @param jeecgDemo
* @return
*/
@PutMapping(value = "/edit")
@ApiOperation(value = "编辑DEMO", notes = "编辑DEMO")
@AutoLog(value = "编辑DEMO", operateType = CommonConstant.OPERATE_TYPE_3)
@ApiOperation(value = "编辑DEMO", notes = "编辑DEMO")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody JeecgDemo jeecgDemo) {
jeecgDemoService.updateById(jeecgDemo);
return Result.OK("更新成功!");
@ -316,5 +317,9 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
return Result.OK("1");
}
@GetMapping(value = "/hello")
public String hello(HttpServletRequest req) {
return "hello world!";
}
}

View File

@ -1,10 +1,9 @@
package org.jeecg.modules.demo.test.controller;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
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;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer;
@ -16,20 +15,10 @@ import org.jeecg.modules.demo.test.service.IJeecgOrderTicketService;
import org.jeecg.modules.demo.test.vo.JeecgOrderMainPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
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;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
/**
* @Description: 一对多示例ERP TAB风格
@ -40,7 +29,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/test/order")
public class JeecgOrderTabMainController {
public class JeecgOrderErpMainController {
@Autowired
private IJeecgOrderMainService jeecgOrderMainService;
@ -89,7 +78,7 @@ public class JeecgOrderTabMainController {
* @param jeecgOrderMainPage
* @return
*/
@PutMapping("/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);
@ -186,7 +175,7 @@ public class JeecgOrderTabMainController {
* @param jeecgOrderCustomer
* @return
*/
@PutMapping("/editCustomer")
@RequestMapping(value = "/editCustomer", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> editCustomer(@RequestBody JeecgOrderCustomer jeecgOrderCustomer) {
jeecgOrderCustomerService.updateById(jeecgOrderCustomer);
return Result.ok("添加成功!");
@ -234,7 +223,7 @@ public class JeecgOrderTabMainController {
* @param jeecgOrderTicket
* @return
*/
@PutMapping("/editTicket")
@RequestMapping(value = "/editTicket", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> editTicket(@RequestBody JeecgOrderTicket jeecgOrderTicket) {
jeecgOrderTicketService.updateById(jeecgOrderTicket);
return Result.ok("编辑成功!");

View File

@ -104,7 +104,7 @@ public class JeecgOrderMainController extends JeecgController<JeecgOrderMain, IJ
* @param jeecgOrderMainPage
* @return
*/
@PutMapping(value = "/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> eidt(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);

View File

@ -11,6 +11,6 @@ WORKDIR /jeecg-boot
EXPOSE 8080
ADD ./src/main/resources/jeecg ./config/jeecg
ADD ./target/jeecg-boot-module-system-3.0.jar ./
ADD ./target/jeecg-boot-module-system-3.1.0.jar ./
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.0.jar
CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.1.0.jar

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-parent</artifactId>
<version>3.0</version>
<version>3.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -38,7 +38,7 @@
<dependency>
<groupId>org.jeecgframework</groupId>
<artifactId>jeewx-api</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
<exclusions>
<exclusion>
<artifactId>commons-beanutils</artifactId>
@ -54,7 +54,7 @@
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-spring-boot-starter</artifactId>
<version>1.4.0</version>
<version>1.4.2</version>
</dependency>
@ -62,7 +62,7 @@
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module-demo</artifactId>
<version>3.0</version>
<version>3.1.0</version>
</dependency>
</dependencies>

View File

@ -1,12 +1,19 @@
package org.jeecg;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context;
import org.apache.tomcat.util.scan.StandardJarScanner;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
@ -17,6 +24,7 @@ import java.net.UnknownHostException;
*/
@Slf4j
@SpringBootApplication
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
public class JeecgSystemApplication extends SpringBootServletInitializer {
@Override

View File

@ -1,6 +1,6 @@
package org.jeecg.config.jimureport;
import org.jeecg.common.constant.DataBaseConstant;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.SysUserCacheInfo;
@ -20,6 +20,9 @@ import java.util.Map;
* * 1.自定义获取登录token
* * 2.自定义获取登录用户
*/
@Slf4j
@Component
public class JimuReportTokenService implements JmReportTokenServiceI {
@Autowired
@ -45,10 +48,16 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
@Override
public Map<String, Object> getUserInfo(String token) {
Map<String, Object> map = new HashMap<String, Object>();
String username = JwtUtil.getUsername(token);
//此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
Map<String, Object> map = new HashMap<String, Object>();
SysUserCacheInfo userInfo = null;
try {
userInfo = sysBaseAPI.getCacheUser(username);
} catch (Exception e) {
log.error("获取用户信息异常:"+ e.getMessage());
return map;
}
//设置账号名
map.put(SYS_USER_CODE, userInfo.getSysUserCode());
//设置部门编码

View File

@ -1,46 +1,46 @@
package org.jeecg.modules.ngalain.aop;
import javax.servlet.http.HttpServletRequest;
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.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;;
// 暂时注释掉,提高系统性能
//@Aspect //定义一个切面
//@Configuration
public class LogRecordAspect {
private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
// 定义切点Pointcut
@Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
public void excudeService() {
}
@Around("excudeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
String url = request.getRequestURL().toString();
String method = request.getMethod();
String uri = request.getRequestURI();
String queryString = request.getQueryString();
logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
// result的值就是被拦截方法的返回值
Object result = pjp.proceed();
logger.info("请求结束controller的返回值是 " + result);
return result;
}
}
//package org.jeecg.modules.ngalain.aop;
//
//import javax.servlet.http.HttpServletRequest;
//
//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.springframework.context.annotation.Configuration;
//import org.springframework.web.context.request.RequestAttributes;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;;
//
//
//// 暂时注释掉,提高系统性能
////@Aspect //定义一个切面
////@Configuration
//public class LogRecordAspect {
//private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
//
// // 定义切点Pointcut
// @Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
// public void excudeService() {
// }
//
// @Around("excudeService()")
// public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// RequestAttributes ra = RequestContextHolder.getRequestAttributes();
// ServletRequestAttributes sra = (ServletRequestAttributes) ra;
// HttpServletRequest request = sra.getRequest();
//
// String url = request.getRequestURL().toString();
// String method = request.getMethod();
// String uri = request.getRequestURI();
// String queryString = request.getQueryString();
// logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
//
// // result的值就是被拦截方法的返回值
// Object result = pjp.proceed();
//
// logger.info("请求结束controller的返回值是 " + result);
// return result;
// }
//}

View File

@ -1,86 +1,86 @@
package org.jeecg.modules.ngalain.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.ngalain.service.NgAlainService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/sys/ng-alain")
public class NgAlainController {
@Autowired
private NgAlainService ngAlainService;
@Autowired
private ISysDictService sysDictService;
@RequestMapping(value = "/getAppData")
@ResponseBody
public JSONObject getAppData(HttpServletRequest request) throws Exception {
String token=request.getHeader("X-Access-Token");
JSONObject j = new JSONObject();
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
JSONObject userObjcet = new JSONObject();
userObjcet.put("name", user.getUsername());
userObjcet.put("avatar", user.getAvatar());
userObjcet.put("email", user.getEmail());
userObjcet.put("token", token);
j.put("user", userObjcet);
j.put("menu",ngAlainService.getMenu(user.getUsername()));
JSONObject app = new JSONObject();
app.put("name", "jeecg-boot-angular");
app.put("description", "jeecg+ng-alain整合版本");
j.put("app", app);
return j;
}
@RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
public Object getDictItems(@PathVariable String dictCode) {
log.info(" dictCode : "+ dictCode);
Result<List<DictModel>> result = new Result<List<DictModel>>();
List<DictModel> ls = null;
try {
ls = sysDictService.queryDictItemsByCode(dictCode);
result.setSuccess(true);
result.setResult(ls);
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
return result;
}
List<JSONObject> dictlist=new ArrayList<>();
for (DictModel l : ls) {
JSONObject dict=new JSONObject();
try {
dict.put("value",Integer.parseInt(l.getValue()));
} catch (NumberFormatException e) {
dict.put("value",l.getValue());
}
dict.put("label",l.getText());
dictlist.add(dict);
}
return dictlist;
}
@RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
return this.ngAlainService.getDictByTable(table,key,value);
}
}
//package org.jeecg.modules.ngalain.controller;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//
//import javax.servlet.http.HttpServletRequest;
//
//import org.apache.shiro.SecurityUtils;
//import org.jeecg.common.api.vo.Result;
//import org.jeecg.common.system.vo.DictModel;
//import org.jeecg.common.system.vo.LoginUser;
//import org.jeecg.modules.ngalain.service.NgAlainService;
//import org.jeecg.modules.system.service.ISysDictService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.PathVariable;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RequestMethod;
//import org.springframework.web.bind.annotation.ResponseBody;
//import org.springframework.web.bind.annotation.RestController;
//
//import com.alibaba.fastjson.JSONObject;
//
//import lombok.extern.slf4j.Slf4j;
//
//@Slf4j
//@RestController
//@RequestMapping("/sys/ng-alain")
//public class NgAlainController {
// @Autowired
// private NgAlainService ngAlainService;
// @Autowired
// private ISysDictService sysDictService;
//
// @RequestMapping(value = "/getAppData")
// @ResponseBody
// public JSONObject getAppData(HttpServletRequest request) throws Exception {
// String token=request.getHeader("X-Access-Token");
// JSONObject j = new JSONObject();
// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
// JSONObject userObjcet = new JSONObject();
// userObjcet.put("name", user.getUsername());
// userObjcet.put("avatar", user.getAvatar());
// userObjcet.put("email", user.getEmail());
// userObjcet.put("token", token);
// j.put("user", userObjcet);
// j.put("menu",ngAlainService.getMenu(user.getUsername()));
// JSONObject app = new JSONObject();
// app.put("name", "jeecg-boot-angular");
// app.put("description", "jeecg+ng-alain整合版本");
// j.put("app", app);
// return j;
// }
//
// @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
// public Object getDictItems(@PathVariable String dictCode) {
// log.info(" dictCode : "+ dictCode);
// Result<List<DictModel>> result = new Result<List<DictModel>>();
// List<DictModel> ls = null;
// try {
// ls = sysDictService.queryDictItemsByCode(dictCode);
// result.setSuccess(true);
// result.setResult(ls);
// } catch (Exception e) {
// log.error(e.getMessage(),e);
// result.error500("操作失败");
// return result;
// }
// List<JSONObject> dictlist=new ArrayList<>();
// for (DictModel l : ls) {
// JSONObject dict=new JSONObject();
// try {
// dict.put("value",Integer.parseInt(l.getValue()));
// } catch (NumberFormatException e) {
// dict.put("value",l.getValue());
// }
// dict.put("label",l.getText());
// dictlist.add(dict);
// }
// return dictlist;
// }
// @RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
// public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
// return this.ngAlainService.getDictByTable(table,key,value);
// }
//}

View File

@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.modules.quartz.entity.QuartzJob;
import org.jeecg.modules.quartz.service.IQuartzJobService;
@ -145,14 +147,14 @@ public class QuartzJobController {
*/
//@RequiresRoles("admin")
@GetMapping(value = "/pause")
@ApiOperation(value = "停定时任务")
@ApiOperation(value = "定时任务")
public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
return Result.error("定时任务不存在!");
}
quartzJobService.pause(job);
return Result.ok("停定时任务成功");
return Result.ok("定时任务成功");
}
/**
@ -163,7 +165,7 @@ public class QuartzJobController {
*/
//@RequiresRoles("admin")
@GetMapping(value = "/resume")
@ApiOperation(value = "恢复定时任务")
@ApiOperation(value = "启动定时任务")
public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
QuartzJob job = quartzJobService.getById(id);
if (job == null) {
@ -171,7 +173,7 @@ public class QuartzJobController {
}
quartzJobService.resumeJob(job);
//scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
return Result.ok("恢复定时任务成功");
return Result.ok("启动定时任务成功");
}
/**
@ -202,8 +204,12 @@ public class QuartzJobController {
// 导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表");
mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
//获取当前登录用户
//update-begin---author:wangshuai ---date:20211227 for[JTC-116]导出人写死了------------
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息"));
//update-end---author:wangshuai ---date:20211227 for[JTC-116]导出人写死了------------
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}

View File

@ -17,7 +17,7 @@ public class SampleJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(" Job Execution key"+jobExecutionContext.getJobDetail().getKey());
log.info(String.format(" Jeecg-Boot 普通定时任务 SampleJob ! 时间:" + DateUtils.getTimestamp()));
}
}

View File

@ -47,6 +47,15 @@ public class DuplicateCheckController {
//SQL注入校验只限制非法串改数据库
final String[] sqlInjCheck = {duplicateCheckVo.getTableName(),duplicateCheckVo.getFieldName()};
SqlInjectionUtil.filterContent(sqlInjCheck);
// update-begin-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
if(StringUtils.isEmpty(duplicateCheckVo.getFieldVal())){
Result rs = new Result();
rs.setCode(500);
rs.setSuccess(true);
rs.setMessage("数据为空,不作处理!");
return rs;
}
// update-end-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
// [2].编辑页面校验
num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@ -58,8 +59,6 @@ public class LoginController {
@Resource
private BaseCommonService baseCommonService;
private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
@ApiOperation("登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
@ -82,6 +81,7 @@ public class LoginController {
Object checkCode = redisUtil.get(realKey);
//当进入登录页时,有一定几率出现验证码错误 #1714
if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
log.warn("验证码错误key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
result.error500("验证码错误");
return result;
}
@ -402,7 +402,10 @@ public class LoginController {
// update-begin--Author:sunjianlei Date:20210802 for获取用户租户信息
String tenantIds = sysUser.getRelTenantIds();
if (oConvertUtils.isNotEmpty(tenantIds)) {
List<String> tenantIdList = Arrays.asList(tenantIds.split(","));
List<Integer> tenantIdList = new ArrayList<>();
for(String id: tenantIds.split(",")){
tenantIdList.add(Integer.valueOf(id));
}
// 该方法仅查询有效的租户如果返回0个就说明所有的租户均无效。
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
if (tenantList.size() == 0) {
@ -450,10 +453,17 @@ public class LoginController {
public Result<String> randomImage(HttpServletResponse response,@PathVariable String key){
Result<String> res = new Result<String>();
try {
//生成验证码
final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
//存到redis中
String lowerCaseCode = code.toLowerCase();
String realKey = MD5Util.MD5Encode(lowerCaseCode+key, "utf-8");
log.info("获取验证码Redis checkCode = {}key = {}", code, key);
redisUtil.set(realKey, lowerCaseCode, 60);
//返回前端
String base64 = RandImageUtil.generate(code);
res.setSuccess(true);
res.setResult(base64);
@ -495,13 +505,16 @@ public class LoginController {
if(oConvertUtils.isEmpty(orgCode)) {
//如果当前用户无选择部门 查看部门关联信息
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户没有设置部门及角色点击登录提示暂未归属部一直在登录页面 使用手机号登录 可正常
if (departs == null || departs.size() == 0) {
result.error500("用户暂未归属部门,不可登录!");
return result;
/*result.error500("用户暂未归属部门,不可登录!");
return result;*/
}else{
orgCode = departs.get(0).getOrgCode();
sysUser.setOrgCode(orgCode);
this.sysUserService.updateUserDepart(username, orgCode);
}
orgCode = departs.get(0).getOrgCode();
sysUser.setOrgCode(orgCode);
this.sysUserService.updateUserDepart(username, orgCode);
//update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户没有设置部门及角色点击登录提示暂未归属部一直在登录页面 使用手机号登录 可正常
}
JSONObject obj = new JSONObject();
//用户登录信息
@ -542,5 +555,58 @@ public class LoginController {
}
return Result.ok();
}
/**
* 登录二维码
*/
@ApiOperation(value = "登录二维码", notes = "登录二维码")
@GetMapping("/getLoginQrcode")
public Result<?> getLoginQrcode() {
String qrcodeId = CommonConstant.LOGIN_QRCODE_PRE+IdWorker.getIdStr();
//定义二维码参数
Map params = new HashMap(5);
params.put("qrcodeId", qrcodeId);
//存放二维码唯一标识30秒有效
redisUtil.set(CommonConstant.LOGIN_QRCODE + qrcodeId, qrcodeId, 30);
return Result.OK(params);
}
/**
* 扫码二维码
*/
@ApiOperation(value = "扫码登录二维码", notes = "扫码登录二维码")
@PostMapping("/scanLoginQrcode")
public Result<?> scanLoginQrcode(@RequestParam String qrcodeId, @RequestParam String token) {
Object check = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
if (oConvertUtils.isNotEmpty(check)) {
//存放token给前台读取
redisUtil.set(CommonConstant.LOGIN_QRCODE_TOKEN+qrcodeId, token, 60);
} else {
return Result.error("二维码已过期,请刷新后重试");
}
return Result.OK("扫码成功");
}
/**
* 获取用户扫码后保存的token
*/
@ApiOperation(value = "获取用户扫码后保存的token", notes = "获取用户扫码后保存的token")
@GetMapping("/getQrcodeToken")
public Result getQrcodeToken(@RequestParam String qrcodeId) {
Object token = redisUtil.get(CommonConstant.LOGIN_QRCODE_TOKEN + qrcodeId);
Map result = new HashMap();
Object qrcodeIdExpire = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
if (oConvertUtils.isEmpty(qrcodeIdExpire)) {
//二维码过期通知前台刷新
result.put("token", "-2");
return Result.OK(result);
}
if (oConvertUtils.isNotEmpty(token)) {
result.put("success", true);
result.put("token", token);
} else {
result.put("token", "-1");
}
return Result.OK(result);
}
}

View File

@ -1,19 +0,0 @@
package org.jeecg.modules.system.controller;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.system.entity.SysUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* vue3前端临时接口
*/
@RestController
@RequestMapping("/")
@Slf4j
public class MockVue3Controller {
}

View File

@ -14,6 +14,7 @@ import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.CommonSendStatus;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
@ -93,18 +94,21 @@ public class SysAnnouncementController {
HttpServletRequest req) {
Result<IPage<SysAnnouncement>> result = new Result<IPage<SysAnnouncement>>();
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
QueryWrapper<SysAnnouncement> queryWrapper = new QueryWrapper<SysAnnouncement>(sysAnnouncement);
QueryWrapper<SysAnnouncement> queryWrapper = QueryGenerator.initQueryWrapper(sysAnnouncement, req.getParameterMap());
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
//update-begin-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
//排序逻辑 处理
String column = req.getParameter("column");
String order = req.getParameter("order");
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
if("asc".equals(order)) {
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
}else {
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
}
}
// String column = req.getParameter("column");
// String order = req.getParameter("order");
// if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
// if("asc".equals(order)) {
// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
// }else {
// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
// }
// }
//update-end-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
IPage<SysAnnouncement> pageList = sysAnnouncementService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
@ -337,11 +341,13 @@ public class SysAnnouncementController {
query.eq(SysAnnouncementSend::getUserId,userId);
SysAnnouncementSend one = sysAnnouncementSendService.getOne(query);
if(null==one){
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
announcementSend.setAnntId(announcements.get(i).getId());
announcementSend.setUserId(userId);
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
sysAnnouncementSendService.save(announcementSend);
log.info("listByUser接口新增了SysAnnouncementSendpageSize{}"+pageSize);
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
announcementSend.setAnntId(announcements.get(i).getId());
announcementSend.setUserId(userId);
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
sysAnnouncementSendService.save(announcementSend);
log.info("announcementSend.toString()",announcementSend.toString());
}
//update-end--Author:wangshuai Date:20200803 for 通知公告消息重复LOWCOD-759------------
}
@ -373,7 +379,7 @@ public class SysAnnouncementController {
LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<SysAnnouncement>(sysAnnouncement);
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0);
queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
List<SysAnnouncement> pageList = sysAnnouncementService.list(queryWrapper);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表");

View File

@ -10,6 +10,7 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.entity.SysAnnouncementSend;
@ -69,6 +70,11 @@ public class SysAnnouncementSendController {
//排序逻辑 处理
String column = req.getParameter("column");
String order = req.getParameter("order");
//issues/3331 SQL injection vulnerability
SqlInjectionUtil.filterContent(column);
SqlInjectionUtil.filterContent(order);
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
if("asc".equals(order)) {
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));

View File

@ -9,9 +9,11 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysCategory;
import org.jeecg.modules.system.model.TreeSelectModel;
@ -65,10 +67,16 @@ public class SysCategoryController {
Result<IPage<SysCategory>> result = new Result<IPage<SysCategory>>();
//--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------start
//QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
queryWrapper.eq("pid", sysCategory.getPid());
//--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------end
//--author:liusq---date:20211119 -----for: 【vue3】分类字典页面查询条件配置--------start
QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
String name = sysCategory.getName();
String code = sysCategory.getCode();
//QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
if(StringUtils.isBlank(name)&&StringUtils.isBlank(code)){
queryWrapper.eq("pid", sysCategory.getPid());
}
//--author:liusq---date:20211119 -----for: 分类字典页面查询条件配置--------end
//--author:os_chengtgen---date:20190804 -----for:【vue3】 分类字典页面显示错误,issues:377--------end
Page<SysCategory> page = new Page<SysCategory>(pageNo, pageSize);
IPage<SysCategory> pageList = sysCategoryService.page(page, queryWrapper);
@ -215,10 +223,13 @@ public class SysCategoryController {
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException{
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
// 错误信息
List<String> errorMessage = new ArrayList<>();
int successLines = 0, errorLines = 0;
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
@ -229,7 +240,8 @@ public class SysCategoryController {
//按照编码长度排序
Collections.sort(listSysCategorys);
log.info("排序后的list====>",listSysCategorys);
for (SysCategory sysCategoryExcel : listSysCategorys) {
for (int i = 0; i < listSysCategorys.size(); i++) {
SysCategory sysCategoryExcel = listSysCategorys.get(i);
String code = sysCategoryExcel.getCode();
if(code.length()>3){
String pCode = sysCategoryExcel.getCode().substring(0,code.length()-3);
@ -242,12 +254,25 @@ public class SysCategoryController {
}else{
sysCategoryExcel.setPid("0");
}
sysCategoryService.save(sysCategoryExcel);
try {
sysCategoryService.save(sysCategoryExcel);
successLines++;
} catch (Exception e) {
errorLines++;
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CATEGORY_CODE)) {
errorMessage.add("" + lineNumber + " 行:分类编码已经存在,忽略导入。");
} else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
}
}
}
return Result.ok("文件导入成功!数据行数:" + listSysCategorys.size());
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:"+e.getMessage());
errorMessage.add("发生异常:" + e.getMessage());
log.error(e.getMessage(), e);
} finally {
try {
file.getInputStream().close();
@ -256,7 +281,7 @@ public class SysCategoryController {
}
}
}
return Result.error("文件导入失败!");
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
}

View File

@ -112,7 +112,7 @@ public class SysCheckRuleController extends JeecgController<SysCheckRule, ISysCh
*/
@AutoLog(value = "编码校验规则-编辑")
@ApiOperation(value = "编码校验规则-编辑", notes = "编码校验规则-编辑")
@PutMapping(value = "/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result edit(@RequestBody SysCheckRule sysCheckRule) {
sysCheckRuleService.updateById(sysCheckRule);
return Result.ok("编辑成功!");

View File

@ -14,6 +14,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
@ -57,6 +58,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
*/
@AutoLog(value = "多数据源管理-分页列表查询")
@ApiOperation(value = "多数据源管理-分页列表查询", notes = "多数据源管理-分页列表查询")
//@RequiresRoles("admin")
@GetMapping(value = "/list")
public Result<?> queryPageList(
SysDataSource sysDataSource,

View File

@ -198,7 +198,7 @@ public class SysDepartController {
* @return
*/
//@RequiresRoles({"admin"})
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
public Result<SysDepart> edit(@RequestBody SysDepart sysDepart, HttpServletRequest request) {
String username = JwtUtil.getUserNameByToken(request);
@ -322,7 +322,7 @@ public class SysDepartController {
if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
departIds = user.getDepartIds();
}
List<SysDepartTreeModel> treeList = this.sysDepartService.searhBy(keyWord,myDeptSearch,departIds);
List<SysDepartTreeModel> treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds);
if (treeList == null || treeList.size() == 0) {
result.setSuccess(false);
result.setMessage("未查询匹配数据!");
@ -363,6 +363,8 @@ public class SysDepartController {
/**
* 通过excel导入数据
* 部门导入方案1: 通过机构编码来计算出部门的父级ID,维护上下级关系;
* 部门导入方案2: 你也可以改造下程序,机构编码直接导入,先不设置父ID;全部导入后,写一个sql,补下父ID;
*
* @param request
* @param response
@ -418,6 +420,11 @@ public class SysDepartController {
sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
//update-end---author:liusq Date:20210223 for批量导入部门以后不能追加下一级部门 #2245------------
sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
//update-begin---author:wangshuai ---date:20220105 for[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
sysDepart.setOrgCategory("1");
}
//update-end---author:wangshuai ---date:20220105 for[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
num++;
}

View File

@ -97,7 +97,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
* @return
*/
@ApiOperation(value="部门权限表-编辑", notes="部门权限表-编辑")
@PutMapping(value = "/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
sysDepartPermissionService.updateById(sysDepartPermission);
return Result.ok("编辑成功!");

View File

@ -114,7 +114,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
*/
//@RequiresRoles({"admin"})
@ApiOperation(value="部门角色-编辑", notes="部门角色-编辑")
@PutMapping(value = "/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
sysDepartRoleService.updateById(sysDepartRole);
return Result.ok("编辑成功!");

View File

@ -496,7 +496,7 @@ public class SysDictController {
try {
//导入Excel格式校验看匹配的字段文本概率
Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), SysDictPage.class, params);
if(!t){
if(t!=null && !t){
throw new RuntimeException("导入Excel校验失败 ");
}
List<SysDictPage> list = ExcelImportUtil.importExcel(file.getInputStream(), SysDictPage.class, params);
@ -511,11 +511,22 @@ public class SysDictController {
Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList());
if(integer>0){
successLines++;
}else{
//update-begin---author:wangshuai ---date:20220211 for[JTC-1168]如果字典项值为空,则字典项忽略导入------------
}else if(integer == -1){
errorLines++;
errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。");
}else{
//update-end---author:wangshuai ---date:20220211 for[JTC-1168]如果字典项值为空,则字典项忽略导入------------
errorLines++;
int lineNumber = i + 1;
errorMessage.add("" + lineNumber + " 行:字典编码已经存在,忽略导入。");
}
//update-begin---author:wangshuai ---date:20220209 for[JTC-1168]字典编号不能为空------------
if(oConvertUtils.isEmpty(po.getDictCode())){
errorMessage.add("" + lineNumber + " 行:字典编码不能为空,忽略导入。");
}else{
errorMessage.add("" + lineNumber + " 行:字典编码已经存在,忽略导入。");
}
//update-end---author:wangshuai ---date:20220209 for[JTC-1168]字典编号不能为空------------
}
} catch (Exception e) {
errorLines++;
int lineNumber = i + 1;

View File

@ -93,7 +93,7 @@ public class SysFillRuleController extends JeecgController<SysFillRule, ISysFill
*/
@AutoLog(value = "填值规则-编辑")
@ApiOperation(value = "填值规则-编辑", notes = "填值规则-编辑")
@PutMapping(value = "/edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<?> edit(@RequestBody SysFillRule sysFillRule) {
sysFillRuleService.updateById(sysFillRule);
return Result.ok("编辑成功!");

View File

@ -59,7 +59,7 @@ public class SysPermissionController {
/**
* 加载数据节点
*
*
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ -200,7 +200,7 @@ public class SysPermissionController {
/**
* 查询用户拥有的菜单权限和按钮权限
*
*
* @return
*/
@RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET)
@ -261,32 +261,49 @@ public class SysPermissionController {
}
/**
* 【vue3专用】查询用户拥有的按钮/表单访问权限
* @return
* 【vue3专用】获取
* 1、查询用户拥有的按钮/表单访问权限
* 2、所有权限 (菜单权限配置)
* 3、系统安全模式 (开启则online报表的数据源必填)
*/
@RequestMapping(value = "/getPermCode", method = RequestMethod.GET)
public Result<?> getPermCode() {
Result<List<String>> result = new Result<List<String>>();
try {
//直接获取当前用户
// 直接获取当前用户
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//获取当前用户的权限集合
if (oConvertUtils.isEmpty(loginUser)) {
return Result.error("请登录系统!");
}
// 获取当前用户的权限集合
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
// 按钮权限(用户拥有的权限集合)
List<String> codeList = metaList.stream()
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
.collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
//
JSONArray authArray = new JSONArray();
this.getAuthJsonArray(authArray, metaList);
// 查询所有的权限
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
List<SysPermission> allAuthList = sysPermissionService.list(query);
JSONArray allAuthArray = new JSONArray();
this.getAllAuthJsonArray(allAuthArray, allAuthList);
JSONObject result = new JSONObject();
// 所拥有的权限编码
result.put("codeList", codeList);
//按钮权限(用户拥有的权限集合)
List<String> authList = metaList.stream()
.filter((permission) -> permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)
&& CommonConstant.STATUS_1.equals(permission.getStatus())
)
.collect(() -> new ArrayList<String>(),
(list, permission) -> list.add(permission.getPerms()),
(list1, list2) -> list1.addAll(list2)
);
result.setResult(authList);
result.put("auth", authArray);
//全部权限配置集合(按钮权限,访问权限)
result.put("allAuth", allAuthArray);
// 系统安全模式
result.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
return Result.OK(result);
} catch (Exception e) {
result.error500("查询失败:" + e.getMessage());
log.error(e.getMessage(), e);
return Result.error("查询失败:" + e.getMessage());
}
return result;
}
/**
@ -374,7 +391,7 @@ public class SysPermissionController {
/**
* 获取全部的权限树
*
*
* @return
*/
@RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
@ -720,7 +737,7 @@ public class SysPermissionController {
/**
* 判断是否外网URL 例如: http://localhost:8080/jeecg-boot/swagger-ui.html#/ 支持特殊格式: {{
* window._CONFIG['domianURL'] }}/druid/ {{ JS代码片段 }}前台解析会自动执行JS代码片段
*
*
* @return
*/
private boolean isWWWHttpUrl(String url) {
@ -733,7 +750,7 @@ public class SysPermissionController {
/**
* 通过URL生成路由name去掉URL前缀斜杠替换内容中的斜杠/’为- 举例: URL = /isystem/role RouteName =
* isystem-role
*
*
* @return
*/
private String urlToRouteName(String url) {
@ -753,7 +770,7 @@ public class SysPermissionController {
/**
* 根据菜单id来获取其对应的权限数据
*
*
* @param sysPermissionDataRule
* @return
*/
@ -768,7 +785,7 @@ public class SysPermissionController {
/**
* 添加菜单权限数据
*
*
* @param sysPermissionDataRule
* @return
*/
@ -803,7 +820,7 @@ public class SysPermissionController {
/**
* 删除菜单权限数据
*
*
* @param id
* @return
*/
@ -823,7 +840,7 @@ public class SysPermissionController {
/**
* 查询菜单权限数据
*
*
* @param sysPermissionDataRule
* @return
*/

View File

@ -8,10 +8,12 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.quartz.service.IQuartzJobService;
@ -208,10 +210,11 @@ public class SysPositionController {
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<SysPosition> pageList = sysPositionService.list(queryWrapper);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表");
mv.addObject(NormalExcelConstants.CLASS, SysPosition.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:"+user.getRealname(),"导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}

View File

@ -6,9 +6,11 @@ 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;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysTenant;
import org.jeecg.modules.system.service.ISysTenantService;
@ -16,9 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
* 租户配置信息
@ -132,11 +132,11 @@ public class SysTenantController {
}else {
String[] ls = ids.split(",");
// 过滤掉已被引用的租户
List<String> idList = new ArrayList<>();
List<Integer> idList = new ArrayList<>();
for (String id : ls) {
int userCount = sysTenantService.countUserLinkTenant(id);
if (userCount == 0) {
idList.add(id);
idList.add(Integer.parseInt(id));
}
}
if (idList.size() > 0) {
@ -190,4 +190,32 @@ public class SysTenantController {
result.setResult(ls);
return result;
}
/**
* 查询当前用户的所有有效租户 【当前用于vue3版本】
* @return
*/
@RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET)
public Result<Map<String,Object>> getCurrentUserTenant() {
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
try {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String tenantIds = sysUser.getRelTenantIds();
Map<String,Object> map = new HashMap<String,Object>();
if (oConvertUtils.isNotEmpty(tenantIds)) {
List<Integer> tenantIdList = new ArrayList<>();
for(String id: tenantIds.split(",")){
tenantIdList.add(Integer.valueOf(id));
}
// 该方法仅查询有效的租户如果返回0个就说明所有的租户均无效。
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
map.put("list", tenantList);
}
result.setSuccess(true);
result.setResult(map);
}catch(Exception e) {
log.error(e.getMessage(), e);
result.error500("查询失败!");
}
return result;
}
}

View File

@ -108,12 +108,38 @@ public class SysUserController {
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<IPage<SysUser>> result = new Result<IPage<SysUser>>();
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(user, req.getParameterMap());
//TODO 外部模拟登陆临时账号,列表不显示
//update-begin-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户通过code查询id
//部门ID
String departId = req.getParameter("departId");
if(oConvertUtils.isNotEmpty(departId)){
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
query.eq(SysUserDepart::getDepId,departId);
List<SysUserDepart> list = sysUserDepartService.list(query);
List<String> userIds = list.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
queryWrapper.in("id",userIds);
}
//用户ID
String code = req.getParameter("code");
if(oConvertUtils.isNotEmpty(code)){
queryWrapper.in("id",Arrays.asList(code.split(",")));
pageSize = code.split(",").length;
}
//update-end-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户通过code查询id
//update-begin-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件选择用户都能看到被冻结的用户
String status = req.getParameter("status");
if(oConvertUtils.isNotEmpty(status)){
queryWrapper.eq("status", Integer.parseInt(status));
}
//update-end-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件选择用户都能看到被冻结的用户
//TODO 外部模拟登陆临时账号,列表不显示
queryWrapper.ne("username","_reserve_user_external");
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
IPage<SysUser> pageList = sysUserService.page(page, queryWrapper);
//批量查询用户的所属部门
//批量查询用户的所属部门
//step.1 先拿到全部的 useids
//step.2 通过 useids一次性查询用户的所属部门名字
List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
@ -492,6 +518,8 @@ public class SysUserController {
errorMessage.add("" + lineNumber + " 行:手机号已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) {
errorMessage.add("" + lineNumber + " 行:电子邮件已经存在,忽略导入。");
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) {
errorMessage.add("" + lineNumber + " 行:违反表唯一性约束。");
} else {
errorMessage.add("" + lineNumber + " 行:未知错误,忽略导入");
log.error(e.getMessage(), e);
@ -1187,7 +1215,7 @@ public class SysUserController {
* @param jsonObject
* @return
*/
@RequestMapping(value = "/appEdit", method = RequestMethod.PUT)
@RequestMapping(value = "/appEdit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<SysUser> appEdit(HttpServletRequest request,@RequestBody JSONObject jsonObject) {
Result<SysUser> result = new Result<SysUser>();
try {
@ -1305,7 +1333,9 @@ public class SysUserController {
* @return
*/
@GetMapping("/appQueryUser")
public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword) {
public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Result<List<SysUser>> result = new Result<List<SysUser>>();
LambdaQueryWrapper<SysUser> queryWrapper =new LambdaQueryWrapper<SysUser>();
//TODO 外部模拟登陆临时账号,列表不显示
@ -1313,18 +1343,19 @@ public class SysUserController {
if(StringUtils.isNotBlank(keyword)){
queryWrapper.and(i -> i.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname, keyword));
}
List<SysUser> list = sysUserService.list(queryWrapper);
Page<SysUser> page = new Page<>(pageNo, pageSize);
IPage<SysUser> pageList = this.sysUserService.page(page, queryWrapper);
//批量查询用户的所属部门
//step.1 先拿到全部的 useids
//step.2 通过 useids一次性查询用户的所属部门名字
List<String> userIds = list.stream().map(SysUser::getId).collect(Collectors.toList());
List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
if(userIds!=null && userIds.size()>0){
Map<String,String> useDepNames = sysUserService.getDepNamesByUserIds(userIds);
list.forEach(item->{
pageList.getRecords().forEach(item->{
item.setOrgCodeTxt(useDepNames.get(item.getId()));
});
}
result.setResult(list);
result.setResult(pageList.getRecords());
return result;
}
@ -1374,6 +1405,9 @@ public class SysUserController {
@GetMapping("/getMultiUser")
public List<SysUser> getMultiUser(SysUser sysUser){
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(sysUser, null);
//update-begin---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
queryWrapper.eq("status",Integer.parseInt(CommonConstant.STATUS_1));
//update-end---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
List<SysUser> ls = this.sysUserService.list(queryWrapper);
for(SysUser user: ls){
user.setPassword(null);

View File

@ -1,8 +1,7 @@
package org.jeecg.modules.system.controller;
import java.util.*;
import javax.annotation.Resource;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
@ -21,9 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @Description: 在线用户
@ -63,8 +64,20 @@ public class SysUserOnlineController {
online.setToken(token);
//TODO 改成一次性查询
LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
BeanUtils.copyProperties(loginUser, online);
onlineList.add(online);
if (loginUser != null) {
//update-begin---author:wangshuai ---date:20220104 for[JTC-382]在线用户查询无效------------
//验证用户名是否与传过来的用户名相同
boolean isMatchUsername=true;
//判断用户名是否为空并且当前循环的用户不包含传过来的用户名那么就设成false
if(oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)){
isMatchUsername = false;
}
if(isMatchUsername){
BeanUtils.copyProperties(loginUser, online);
onlineList.add(online);
}
//update-end---author:wangshuai ---date:20220104 for[JTC-382]在线用户查询无效------------
}
}
}
Collections.reverse(onlineList);

View File

@ -91,8 +91,12 @@ public class ThirdAppController {
@GetMapping("/sync/wechatEnterprise/depart/toApp")
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
boolean flag = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
}
@ -125,8 +129,12 @@ public class ThirdAppController {
@GetMapping("/sync/dingtalk/depart/toApp")
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
boolean flag = dingtalkService.syncLocalDepartmentToThirdApp(ids);
return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
SyncInfoVo syncInfo = dingtalkService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}

View File

@ -45,7 +45,7 @@ public class SysDepart implements Serializable {
/**描述*/
@Excel(name="描述",width=15)
private String description;
/**机构类别 1公司2组织机构2岗位*/
/**机构类别 1=公司2=组织机构,3=岗位*/
@Excel(name="机构类别",width=15,dicCode="org_category")
private String orgCategory;
/**机构类型*/

View File

@ -54,7 +54,6 @@ public class SysPosition {
/**
* 公司id
*/
@Excel(name = "公司id", width = 15)
@ApiModelProperty(value = "公司id")
private java.lang.String companyId;
/**
@ -84,7 +83,6 @@ public class SysPosition {
/**
* 组织机构编码
*/
@Excel(name = "组织机构编码", width = 15)
@ApiModelProperty(value = "组织机构编码")
private java.lang.String sysOrgCode;
}

View File

@ -3,12 +3,14 @@ package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: 第三方登录账号表
@ -25,7 +27,7 @@ public class SysThirdAccount {
/**编号*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "编号")
@ApiModelProperty(value = "编号")
private java.lang.String id;
/**第三方登录id*/
@Excel(name = "第三方登录id", width = 15)
@ -59,4 +61,20 @@ public class SysThirdAccount {
@Excel(name = "第三方用户账号", width = 15)
@ApiModelProperty(value = "第三方用户账号")
private java.lang.String thirdUserId;
/**创建人*/
@Excel(name = "创建人", width = 15)
private java.lang.String createBy;
/**创建日期*/
@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date createTime;
/**修改人*/
@Excel(name = "修改人", width = 15)
private java.lang.String updateBy;
/**修改日期*/
@Excel(name = "修改日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date updateTime;
}

View File

@ -193,4 +193,15 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
*/
@Deprecated
List<DictModel> queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
/**
* 查询字典表的数据
* @param table 表名
* @param text 显示字段名
* @param code 存储字段名
* @param filterSql 条件sql
* @param codeValues 存储字段值 作为查询条件in
* @return
*/
List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql, @Param("codeValues") List<String> codeValues);
}

View File

@ -134,19 +134,24 @@
${pidField} as parentId
from ${table}
where
<choose>
<when test="pid != null and pid != ''">
${pidField} = #{pid}
</when>
<otherwise>
(${pidField} = '' OR ${pidField} IS NULL)
</otherwise>
</choose>
<!-- udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
<if test="query == null">
<choose>
<when test="pid != null and pid != ''">
${pidField} = #{pid}
</when>
<otherwise>
(${pidField} = '' OR ${pidField} IS NULL)
</otherwise>
</choose>
</if>
<if test="query!= null">
1 = 1
<foreach collection="query.entrySet()" item="value" index="key" >
and ${key} = #{value}
and ${key} LIKE #{value}
</foreach>
</if>
<!-- udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
</select>
@ -179,5 +184,18 @@
</select>
<!-- 查询字典表的数据 支持设置过滤条件、设置存储值作为in查询条件 -->
<select id="queryTableDictByKeysAndFilterSql" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
select ${text} as "text", ${code} as "value" from ${table} where ${code} IN (
<foreach item="key" collection="codeValues" separator=",">
#{key}
</foreach>
)
<if test="filterSql != null and filterSql != ''">
and ${filterSql}
</if>
</select>
</mapper>

View File

@ -14,7 +14,9 @@
join sys_depart c on b.dep_id = c.id
where a.del_flag = 0 and c.org_code like '${orgCode}%'
<if test="realname!=null and realname!=''">
and a.realname like '%${realname}%'
<!-- update by sunjianlei 20220119【#3348】SQL injection exists in /sys/user/queryUserByDepId -->
<bind name="bindRealname" value="'%'+realname+'%'"/>
and a.realname like #{bindRealname}
</if>
</select>
@ -23,12 +25,14 @@
select a.*, c.depart_name as org_code_txt from sys_user a
join sys_user_depart b on b.user_id = a.id
join sys_depart c on b.dep_id = c.id
where a.del_flag = 0 and c.org_code like '${orgCode}%'
where a.del_flag = 0 and a.status = 1 and c.org_code like '${orgCode}%'
<if test="username!=null and username!=''">
and a.username like '%${username}%'
<bind name="bindUsername" value="'%'+username+'%'"/>
and a.username like #{bindUsername}
</if>
<if test="realname!=null and realname!=''">
and a.realname like '%${realname}%'
<bind name="bindRealname" value="'%'+realname+'%'"/>
and a.realname like #{bindRealname}
</if>
</select>
</mapper>

View File

@ -1,15 +1,12 @@
package org.jeecg.modules.system.model;
import java.io.Serializable;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* @Description: 用户通告阅读标记表

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.system.rule;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.handler.IFillRuleHandler;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.YouBianCodeUtil;
@ -16,12 +17,14 @@ import java.util.List;
* @Date 2019/12/9 11:32
* @Description: 分类字典编码生成规则
*/
@Slf4j
public class CategoryCodeRule implements IFillRuleHandler {
public static final String ROOT_PID_VALUE = "0";
@Override
public Object execute(JSONObject params, JSONObject formData) {
log.info("系统自定义编码规则[category_code_rule]params{} formData {}", params, formData);
String categoryPid = ROOT_PID_VALUE;
String categoryCode = null;

View File

@ -67,7 +67,7 @@ public interface ISysDepartService extends IService<SysDepart>{
* @param keyWord
* @return
*/
List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds);
List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds);
/**
* 根据部门id删除并删除其可能存在的子级部门

View File

@ -14,7 +14,7 @@ public interface ISysTenantService extends IService<SysTenant> {
* @param idList
* @return
*/
List<SysTenant> queryEffectiveTenant(Collection<String> idList);
List<SysTenant> queryEffectiveTenant(Collection<Integer> idList);
/**
* 返回某个租户被多少个用户引用了

View File

@ -21,7 +21,7 @@ public interface IThirdAppService {
*
* @return 成功返回true
*/
boolean syncLocalDepartmentToThirdApp(String ids);
SyncInfoVo syncLocalDepartmentToThirdApp(String ids);
/**
* 将第三方App部门同步到本地<br>

View File

@ -146,7 +146,9 @@ public class SysBaseApiImpl implements ISysBaseAPI {
//通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制)
String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
queryQserMatch.eq(SysPermission::getMenuType, 1);
// update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
//queryQserMatch.eq(SysPermission::getMenuType, 1);
// update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
queryQserMatch.eq(SysPermission::getDelFlag, 0);
queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
if(oConvertUtils.isNotEmpty(userMatchUrl)){

View File

@ -69,7 +69,7 @@ public class SysDepartPermissionServiceImpl extends ServiceImpl<SysDepartPermiss
@Override
public List<SysPermissionDataRule> getPermRuleListByDeptIdAndPermId(String departId, String permissionId) {
SysDepartPermission departPermission = this.getOne(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId).eq(SysDepartPermission::getPermissionId, permissionId));
if(departPermission != null){
if(departPermission != null && oConvertUtils.isNotEmpty(departPermission.getDataRuleIds())){
LambdaQueryWrapper<SysPermissionDataRule> query = new LambdaQueryWrapper<SysPermissionDataRule>();
query.in(SysPermissionDataRule::getId, Arrays.asList(departPermission.getDataRuleIds().split(",")));
query.orderByDesc(SysPermissionDataRule::getCreateTime);

View File

@ -300,7 +300,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
* </p>
*/
@Override
public List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds) {
public List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds) {
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
List<SysDepartTreeModel> newList = new ArrayList<>();
//myDeptSearch不为空时为我的部门搜索只搜索所负责部门
@ -311,9 +311,15 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
}
//根据部门id获取所负责部门
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
for(int i=0;i<codeArr.length;i++){
query.or().likeRight(SysDepart::getOrgCode,codeArr[i]);
//update-begin-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
if (codeArr != null && codeArr.length > 0) {
query.nested(i -> {
for (String s : codeArr) {
i.or().likeRight(SysDepart::getOrgCode, s);
}
});
}
//update-end-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
}
query.like(SysDepart::getDepartName, keyWord);
@ -499,7 +505,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
}
};
LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper();
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0);
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
lqw.func(square);
lqw.orderByDesc(SysDepart::getDepartOrder);
List<SysDepart> list = list(lqw);

View File

@ -163,7 +163,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
@Override
public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) {
return sysDictMapper.queryTableDictTextByKeys(table, text, code, keys);
//update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
String filterSql = null;
if(table.toLowerCase().indexOf("where")>0){
String[] arr = table.split(" (?i)where ");
table = arr[0];
filterSql = arr[1];
}
return sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, keys);
//update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
}
@Override
@ -225,6 +233,11 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
insert = sysDictMapper.insert(sysDict);
if (sysDictItemList != null) {
for (SysDictItem entity : sysDictItemList) {
//update-begin---author:wangshuai ---date:20220211 for[JTC-1168]如果字典项值为空,则字典项忽略导入------------
if(oConvertUtils.isEmpty(entity.getItemValue())){
return -1;
}
//update-end---author:wangshuai ---date:20220211 for[JTC-1168]如果字典项值为空,则字典项忽略导入------------
entity.setDictId(sysDict.getId());
entity.setStatus(1);
sysDictItemMapper.insert(entity);
@ -255,7 +268,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
Page<DictModel> page = new Page<DictModel>(1, pageSize);
page.setSearchCount(false);
String filterSql = getFilterSql(text, code, condition, keyword);
String filterSql = getFilterSql(table, text, code, condition, keyword);
IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
return pageList.getRecords();
}
@ -268,12 +281,19 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
* @param keyword
* @return
*/
private String getFilterSql(String text, String code, String condition, String keyword){
private String getFilterSql(String table, String text, String code, String condition, String keyword){
String keywordSql = null, filterSql = "", sql_where = " where ";
// update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
if (table.toLowerCase().contains(" where ")) {
sql_where = " and ";
}
// update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
if(oConvertUtils.isNotEmpty(keyword)){
// 判断是否是多选
if (keyword.contains(",")) {
String inKeywords = "\"" + keyword.replaceAll(",", "\",\"") + "\"";
//update-begin--author:scott--date:20220105--forJTC-529【表单设计器】 编辑页面报错in参数采用双引号导致 ----
String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
//update-end--author:scott--date:20220105--forJTC-529【表单设计器】 编辑页面报错in参数采用双引号导致----
keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
} else {
keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
@ -290,14 +310,20 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
}
@Override
public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword) {
String filterSql = getFilterSql(text, code, condition, keyword);
String filterSql = getFilterSql(table, text, code, condition, keyword);
List<DictModel> ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql);
return ls;
}
@Override
public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
List<TreeSelectModel> result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
// udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
if (query != null) {
result.forEach(r -> r.setLeaf(true));
}
return result;
// udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
}
@Override

View File

@ -24,10 +24,10 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
ISysUserService userService;
@Override
public List<SysTenant> queryEffectiveTenant(Collection<String> idList) {
public List<SysTenant> queryEffectiveTenant(Collection<Integer> idList) {
LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(SysTenant::getId, idList);
queryWrapper.eq(SysTenant::getStatus, CommonConstant.STATUS_1);
queryWrapper.eq(SysTenant::getStatus, Integer.valueOf(CommonConstant.STATUS_1));
//此处查询忽略时间条件
return super.list(queryWrapper);
}
@ -50,7 +50,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
if (userCount > 0) {
throw new JeecgBootException("该租户已被引用,无法删除!");
}
return super.removeById(id);
return super.removeById(Integer.parseInt(id));
}
}

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.PasswordUtil;
@ -30,6 +31,7 @@ import java.util.List;
* @Version: V1.0
*/
@Service
@Slf4j
public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMapper, SysThirdAccount> implements ISysThirdAccountService {
@Autowired
@ -116,6 +118,7 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
@Override
public SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType) {
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
log.info("getSysUserId: {} ,getThirdType: {}",sysUserId,thirdType);
queryWrapper.eq(SysThirdAccount::getSysUserId, sysUserId);
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
return super.getOne(queryWrapper);

View File

@ -1,15 +1,10 @@
package org.jeecg.modules.system.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
@ -22,8 +17,11 @@ import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <P>
@ -128,6 +126,9 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
if(oConvertUtils.isEmpty(departId)){
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
//update-begin---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
//update-end---author:wangshuai ---date:20220104 for[JTC-297]已冻结用户仍可设置为代理人------------
if(oConvertUtils.isNotEmpty(username)){
query.like(SysUser::getUsername, username);
}

View File

@ -399,6 +399,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
@Override
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
public boolean revertLogicDeleted(List<String> userIds, SysUser updateEntity) {
String ids = String.format("'%s'", String.join("','", userIds));
return userMapper.revertLogicDeleted(ids, updateEntity) > 0;

View File

@ -85,18 +85,31 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
return null;
}
// update2022-1-21updateBysunjianlei; for 【JTC-704】【钉钉】部门同步成功实际没成后台提示ip白名单
@Override
public boolean syncLocalDepartmentToThirdApp(String ids) {
public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
SyncInfoVo syncInfo = new SyncInfoVo();
String accessToken = this.getAccessToken();
if (accessToken == null) {
return false;
syncInfo.addFailInfo("accessToken获取失败");
return syncInfo;
}
// 获取【钉钉】所有的部门
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
List<Response<Department>> departments = JdtDepartmentAPI.listAllResponse(accessToken);
// 删除钉钉有但本地没有的部门(以本地部门数据为主)(钉钉不能创建同名部门,只能先删除)
List<SysDepart> sysDepartList = sysDepartService.list();
for1:
for (Department department : departments) {
for (Response<Department> departmentRes : departments) {
// 判断部门是否查询成功
if (!departmentRes.isSuccess()) {
syncInfo.addFailInfo(departmentRes.getErrmsg());
// 88 是 ip 不在白名单的错误码,如果遇到此错误码,后面的操作都可以不用进行了,因为肯定都是失败的
if (new Integer(88).equals(departmentRes.getErrcode())) {
return syncInfo;
}
continue;
}
Department department = departmentRes.getResult();
for (SysDepart depart : sysDepartList) {
// id相同代表已存在不删除
String sourceIdentifier = department.getSource_identifier();
@ -124,24 +137,34 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
Department parent = new Department();
parent.setDept_id(1);
// 递归同步部门
departments = JdtDepartmentAPI.listAll(accessToken);
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
return true;
departments = JdtDepartmentAPI.listAllResponse(accessToken);
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken, syncInfo);
return syncInfo;
}
// 递归同步部门到本地
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Response<Department>> departments, Department parent, String accessToken, SyncInfoVo syncInfo) {
if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
for1:
for (SysDepartTreeModel depart : sysDepartsTree) {
for (Department department : departments) {
for (Response<Department> departmentRes : departments) {
// 判断部门是否查询成功
if (!departmentRes.isSuccess()) {
syncInfo.addFailInfo(departmentRes.getErrmsg());
continue;
}
Department department = departmentRes.getResult();
// id相同代表已存在执行修改操作
String sourceIdentifier = department.getSource_identifier();
if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
this.sysDepartToDtDepartment(depart, department, parent.getDept_id());
JdtDepartmentAPI.update(department, accessToken);
// 紧接着同步子级
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
Response<JSONObject> response = JdtDepartmentAPI.update(department, accessToken);
if (response.isSuccess()) {
// 紧接着同步子级
this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken, syncInfo);
}
// 收集错误信息
this.syncDepartCollectErrInfo(response, depart, syncInfo);
// 跳出外部循环
continue for1;
}
@ -154,10 +177,10 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
Department newParent = new Department();
newParent.setDept_id(response.getResult());
// 紧接着同步子级
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken, syncInfo);
}
// 收集错误信息
// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
this.syncDepartCollectErrInfo(response, depart, syncInfo);
}
}
}
@ -209,6 +232,11 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
SysDepart newSysDepart = this.dtDepartmentToSysDepart(departmentTree, null);
if (sysParentId != null) {
newSysDepart.setParentId(sysParentId);
// 2 = 组织机构
newSysDepart.setOrgCategory("2");
} else {
// 1 = 公司
newSysDepart.setOrgCategory("1");
}
try {
sysDepartService.saveDepartData(newSysDepart, username);
@ -246,6 +274,20 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
return false;
}
/**
* 【同步部门】收集同步过程中的错误信息
*/
private boolean syncDepartCollectErrInfo(Response<?> response, SysDepartTreeModel depart, SyncInfoVo syncInfo) {
if (!response.isSuccess()) {
String str = String.format("部门 %s(%s) 同步失败!错误码:%s——%s", depart.getDepartName(), depart.getOrgCode(), response.getErrcode(), response.getErrmsg());
syncInfo.addFailInfo(str);
return false;
} else {
String str = String.format("部门户 %s(%s) 同步成功!", depart.getDepartName(), depart.getOrgCode());
syncInfo.addSuccessInfo(str);
return true;
}
}
@Override
public SyncInfoVo syncLocalUserToThirdApp(String ids) {
@ -279,7 +321,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
/*
* 判断是否同步过的逻辑:
* 1. 查询 sys_third_account第三方账号表是否有数据如果有代表已同步
* 2. 本地表里没有就先用手机号判断不通过再用username判断。
* 2. 本地表里没有就先用手机号判断不通过再用username(用户账号)判断。
*/
SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), THIRD_TYPE);
if (sysThirdAccount != null && oConvertUtils.isNotEmpty(sysThirdAccount.getThirdUserId())) {
@ -528,6 +570,12 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
// update-begin--Author:liusq Date:20210713 for钉钉同步到本地的人员没有状态导致同步之后无法登录 #I3ZC2L
sysUser.setStatus(1);
// update-end--Author:liusq Date:20210713 for钉钉同步到本地的人员没有状态导致同步之后无法登录 #I3ZC2L
// 设置工号如果工号为空则使用username
if (oConvertUtils.isEmpty(dtUser.getJob_number())) {
sysUser.setWorkNo(dtUser.getUserid());
} else {
sysUser.setWorkNo(dtUser.getJob_number());
}
return this.dtUserToSysUser(dtUser, sysUser);
}

View File

@ -96,15 +96,18 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
}
@Override
public boolean syncLocalDepartmentToThirdApp(String ids) {
public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
SyncInfoVo syncInfo = new SyncInfoVo();
String accessToken = this.getAccessToken();
if (accessToken == null) {
return false;
syncInfo.addFailInfo("accessToken获取失败");
return syncInfo;
}
// 获取企业微信所有的部门
List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
if (departments == null) {
return false;
syncInfo.addFailInfo("获取企业微信所有部门失败!");
return syncInfo;
}
// 删除企业微信有但本地没有的部门(以本地部门数据为主)(以为企业微信不能创建同名部门,所以只能先删除)
List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
@ -117,7 +120,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
// 递归同步部门
departments = JwDepartmentAPI.getAllDepartment(accessToken);
this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
return true;
return syncInfo;
}
// 递归删除部门以及子部门,由于企业微信不允许删除带有成员和子部门的部门,所以需要递归删除下子部门,然后把部门成员移动端根部门下
@ -250,6 +253,11 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
if (sysParentId != null) {
newSysDepart.setParentId(sysParentId);
// 2 = 组织机构
newSysDepart.setOrgCategory("2");
} else {
// 1 = 公司
newSysDepart.setOrgCategory("1");
}
try {
sysDepartService.saveDepartData(newSysDepart, username);
@ -604,6 +612,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
BeanUtils.copyProperties(oldSysUser, sysUser);
sysUser.setRealname(qwUser.getName());
sysUser.setPost(qwUser.getPosition());
// 设置工号,由于企业微信没有工号的概念,所以只能用 userId 代替
if (oConvertUtils.isEmpty(sysUser.getWorkNo())) {
sysUser.setWorkNo(qwUser.getUserid());
}
try {
sysUser.setSex(Integer.parseInt(qwUser.getGender()));
} catch (NumberFormatException ignored) {

View File

@ -197,7 +197,7 @@ jeecg :
# ElasticSearch 设置
elasticsearch:
cluster-name: jeecg-ES
cluster-nodes: 81.70.47.128:9200
cluster-nodes: 127.0.0.1:9200
check-enabled: true
# 表单设计器配置
desform:

Some files were not shown because too many files have changed in this diff Show More