Commit 805c4053c1e14cb2753d59ab6f8911b98f264073

Authored by zhangdaiscott
1 parent 789277c4

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

Showing 237 changed files with 11319 additions and 849 deletions

Too many changes to show.

To preserve performance only 100 of 237 files are displayed.

jeecg-boot/README.md
1 1 Jeecg-Boot 低代码开发平台
2 2 ===============
3 3  
4   -当前最新版本: 3.0(发布日期:2021-11-01)
  4 +当前最新版本: 3.1.0(发布日期:20220301)
5 5  
6 6  
7 7 ## 后端技术架构
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/pom.xml
... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <artifactId>jeecg-boot-base-api</artifactId>
7 7 <groupId>org.jeecgframework.boot</groupId>
8   - <version>3.0</version>
  8 + <version>3.1.0</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11 11  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/bpm/api/IBpmBaseExtAPI.java deleted
1   -package org.jeecg.common.bpm.api;
2   -
3   -import org.jeecg.common.api.vo.Result;
4   -import org.jeecg.common.constant.ServiceNameConstants;
5   -import org.jeecg.common.online.api.factory.OnlineBaseExtAPIFallbackFactory;
6   -import org.springframework.cloud.openfeign.FeignClient;
7   -import org.springframework.stereotype.Component;
8   -import org.springframework.web.bind.annotation.PostMapping;
9   -import org.springframework.web.bind.annotation.RequestParam;
10   -
11   -/**
12   - * 流程接口
13   - *
14   - * @author scott
15   - */
16   -@Component
17   -@FeignClient(contextId = "bpmBaseRemoteApi", value = ServiceNameConstants.SYSTEM_SERVICE,
18   - fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
19   -public interface IBpmBaseExtAPI {
20   - /**
21   - * 23. 流程提交接口(online,自定义开发)
22   - *
23   - * @param flowCode
24   - * 流程业务关联 例如:joa_leave_01
25   - * @param id
26   - * 表单业务数据data id
27   - * @param formUrl
28   - * 流程审批时附件页面默认展示的PC端表单组件(地址)
29   - * @param formUrlMobile
30   - * 流程审批时附件页面默认展示的移动端表单组件(地址)
31   - * @param username
32   - * 流程发起人账号
33   - * @param jsonData
34   - * Json串,额外扩展的流程变量值 【非必填】
35   - * @return
36   - * @throws Exception
37   - */
38   - @PostMapping(value = "/act/process/extActProcess/startMutilProcess")
39   - Result<String> startMutilProcess(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
40   - @RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
41   - @RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
42   -
43   - /**
44   - * 24. 流程提交接口(自定义表单设计器)
45   - *
46   - * @param flowCode
47   - * 流程业务关联 例如:joa_leave_01
48   - * @param id
49   - * 表单业务数据data id
50   - * @param formUrl
51   - * 流程审批时附件页面默认展示的PC端表单组件(地址)
52   - * @param formUrlMobile
53   - * 流程审批时附件页面默认展示的移动端表单组件(地址)
54   - * @param username
55   - * 流程发起人账号
56   - * @param jsonData
57   - * Json串,额外扩展的流程变量值 【非必填】
58   - * @return
59   - * @throws Exception
60   - */
61   - @PostMapping(value = "/act/process/extActProcess/startDesFormMutilProcess")
62   - Result<String> startDesFormMutilProcess(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
63   - @RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
64   - @RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
65   -
66   - /**
67   - * 25. 保存流程草稿箱接口(自定义开发表单、online表单)
68   - *
69   - * @param flowCode
70   - * 流程业务关联 例如:joa_leave_01
71   - * @param id
72   - * 表单业务数据data id
73   - * @param formUrl
74   - * 流程审批时附件页面默认展示的PC端表单组件(地址) 【非必填】
75   - * @param formUrlMobile
76   - * 流程审批时附件页面默认展示的移动端表单组件(地址) 【非必填】
77   - * @param username
78   - * 流程发起人账号
79   - * @param jsonData
80   - * Json串,额外扩展的流程变量值 【非必填】
81   - * @return
82   - * @throws Exception
83   - */
84   - @PostMapping(value = "/act/process/extActProcess/saveMutilProcessDraft")
85   - Result<String> saveMutilProcessDraft(@RequestParam("flowCode") String flowCode, @RequestParam("id") String id,
86   - @RequestParam("formUrl") String formUrl, @RequestParam("formUrlMobile") String formUrlMobile,
87   - @RequestParam("username") String username, @RequestParam("jsonData") String jsonData) throws Exception;
88   -
89   -}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/bpm/api/factory/BpmBaseExtAPIFallbackFactory.java deleted
1   -package org.jeecg.common.bpm.api.factory;
2   -
3   -import org.jeecg.common.bpm.api.IBpmBaseExtAPI;
4   -import org.jeecg.common.bpm.api.fallback.BpmBaseExtAPIFallback;
5   -import org.springframework.stereotype.Component;
6   -
7   -import feign.hystrix.FallbackFactory;
8   -
9   -@Component
10   -public class BpmBaseExtAPIFallbackFactory implements FallbackFactory<IBpmBaseExtAPI> {
11   -
12   - @Override
13   - public IBpmBaseExtAPI create(Throwable throwable) {
14   - BpmBaseExtAPIFallback fallback = new BpmBaseExtAPIFallback();
15   - fallback.setCause(throwable);
16   - return fallback;
17   - }
18   -}
19 0 \ No newline at end of file
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/bpm/api/fallback/BpmBaseExtAPIFallback.java deleted
1   -package org.jeecg.common.bpm.api.fallback;
2   -
3   -import java.util.List;
4   -import java.util.Map;
5   -
6   -import org.jeecg.common.api.vo.Result;
7   -import org.jeecg.common.bpm.api.IBpmBaseExtAPI;
8   -import org.jeecg.common.online.api.IOnlineBaseExtAPI;
9   -import org.jeecg.common.system.vo.DictModel;
10   -
11   -import com.alibaba.fastjson.JSONObject;
12   -
13   -import lombok.Setter;
14   -import lombok.extern.slf4j.Slf4j;
15   -
16   -/**
17   - * 进入fallback的方法 检查是否token未设置
18   - */
19   -@Slf4j
20   -public class BpmBaseExtAPIFallback implements IBpmBaseExtAPI {
21   -
22   - @Setter
23   - private Throwable cause;
24   -
25   - @Override
26   - public Result<String> startMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,
27   - String username, String jsonData) throws Exception {
28   - return null;
29   - }
30   -
31   - @Override
32   - public Result<String> startDesFormMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,
33   - String username, String jsonData) throws Exception {
34   - return null;
35   - }
36   -
37   - @Override
38   - public Result<String> saveMutilProcessDraft(String flowCode, String id, String formUrl, String formUrlMobile,
39   - String username, String jsonData) throws Exception {
40   - return null;
41   - }
42   -}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/online/api/IOnlineBaseExtAPI.java
... ... @@ -15,7 +15,8 @@ import java.util.Map;
15 15 * 【Online】Feign API接口
16 16 */
17 17 @Component
18   -@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_ONLINE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
  18 +@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
  19 +//@FeignClient(contextId = "onlineBaseRemoteApi", value = ServiceNameConstants.SYSTEM_ONLINE, fallbackFactory = OnlineBaseExtAPIFallbackFactory.class)
19 20 public interface IOnlineBaseExtAPI {
20 21  
21 22 /**
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/pom.xml
... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <artifactId>jeecg-boot-base-api</artifactId>
7 7 <groupId>org.jeecgframework.boot</groupId>
8   - <version>3.0</version>
  8 + <version>3.1.0</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11 11  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/jeecg-system-local-api/src/main/java/org/jeecg/common/bpm/api/IBpmBaseExtAPI.java deleted
1   -package org.jeecg.common.bpm.api;
2   -
3   -import java.util.List;
4   -import java.util.Map;
5   -
6   -import org.jeecg.common.api.vo.Result;
7   -import org.jeecg.common.system.vo.DictModel;
8   -
9   -import com.alibaba.fastjson.JSONObject;
10   -
11   -/**
12   - * 流程接口
13   - *
14   - * @author scott
15   - */
16   -public interface IBpmBaseExtAPI {
17   - /**
18   - * 23. 流程提交接口(online,自定义开发)
19   - * @param flowCode 流程业务关联 例如:joa_leave_01
20   - * @param id 表单业务数据data id
21   - * @param formUrl 流程审批时附件页面默认展示的PC端表单组件(地址)
22   - * @param formUrlMobile 流程审批时附件页面默认展示的移动端表单组件(地址)
23   - * @param username 流程发起人账号
24   - * @param jsonData Json串,额外扩展的流程变量值 【非必填】
25   - * @return
26   - * @throws Exception
27   - */
28   - Result<String> startMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,String username, String jsonData) throws Exception;
29   -
30   - /**
31   - * 24. 流程提交接口(自定义表单设计器)
32   - * @param flowCode 流程业务关联 例如:joa_leave_01
33   - * @param id 表单业务数据data id
34   - * @param formUrl 流程审批时附件页面默认展示的PC端表单组件(地址)
35   - * @param formUrlMobile 流程审批时附件页面默认展示的移动端表单组件(地址)
36   - * @param username 流程发起人账号
37   - * @param jsonData Json串,额外扩展的流程变量值 【非必填】
38   - * @return
39   - * @throws Exception
40   - */
41   - Result<String> startDesFormMutilProcess(String flowCode, String id, String formUrl, String formUrlMobile,String username,String jsonData) throws Exception;
42   - /**
43   - * 25. 保存流程草稿箱接口(自定义开发表单、online表单)
44   - * @param flowCode 流程业务关联 例如:joa_leave_01
45   - * @param id 表单业务数据data id
46   - * @param formUrl 流程审批时附件页面默认展示的PC端表单组件(地址) 【非必填】
47   - * @param formUrlMobile 流程审批时附件页面默认展示的移动端表单组件(地址) 【非必填】
48   - * @param username 流程发起人账号
49   - * @param jsonData Json串,额外扩展的流程变量值 【非必填】
50   - * @return
51   - * @throws Exception
52   - */
53   - Result<String> saveMutilProcessDraft(String flowCode, String id, String formUrl, String formUrlMobile,String username,String jsonData) throws Exception;
54   -
55   -}
jeecg-boot/jeecg-boot-base/jeecg-boot-base-api/pom.xml
... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <artifactId>jeecg-boot-base</artifactId>
7 7 <groupId>org.jeecgframework.boot</groupId>
8   - <version>3.0</version>
  8 + <version>3.1.0</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11 11  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/pom.xml
... ... @@ -4,7 +4,7 @@
4 4 <parent>
5 5 <groupId>org.jeecgframework.boot</groupId>
6 6 <artifactId>jeecg-boot-base</artifactId>
7   - <version>3.0</version>
  7 + <version>3.1.0</version>
8 8 </parent>
9 9 <modelVersion>4.0.0</modelVersion>
10 10  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/vo/Result.java
... ... @@ -103,6 +103,7 @@ public class Result&lt;T&gt; implements Serializable {
103 103 return r;
104 104 }
105 105  
  106 + @Deprecated
106 107 public static<T> Result<T> OK(String msg) {
107 108 Result<T> r = new Result<T>();
108 109 r.setSuccess(true);
... ... @@ -157,6 +158,7 @@ public class Result&lt;T&gt; implements Serializable {
157 158 this.success = false;
158 159 return this;
159 160 }
  161 +
160 162 /**
161 163 * 无权限访问返回结果
162 164 */
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java
... ... @@ -88,7 +88,7 @@ public class AutoLogAspect {
88 88  
89 89  
90 90 //设置操作类型
91   - if (dto.getLogType() == CommonConstant.LOG_TYPE_2) {
  91 + if (CommonConstant.LOG_TYPE_2 == dto.getLogType()) {
92 92 dto.setOperateType(getOperateType(methodName, syslog.operateType()));
93 93 }
94 94  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
... ... @@ -2,6 +2,7 @@ package org.jeecg.common.aspect;
2 2  
3 3 import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.alibaba.fastjson.parser.Feature;
5 6 import com.baomidou.mybatisplus.core.metadata.IPage;
6 7 import com.fasterxml.jackson.annotation.JsonFormat;
7 8 import com.fasterxml.jackson.core.JsonProcessingException;
... ... @@ -18,6 +19,7 @@ import org.jeecg.common.constant.CommonConstant;
18 19 import org.jeecg.common.system.vo.DictModel;
19 20 import org.jeecg.common.util.oConvertUtils;
20 21 import org.springframework.beans.factory.annotation.Autowired;
  22 +import org.springframework.context.annotation.Lazy;
21 23 import org.springframework.data.redis.core.RedisTemplate;
22 24 import org.springframework.stereotype.Component;
23 25 import org.springframework.util.StringUtils;
... ... @@ -38,14 +40,14 @@ import java.util.stream.Collectors;
38 40 @Component
39 41 @Slf4j
40 42 public class DictAspect {
41   -
  43 + @Lazy
42 44 @Autowired
43 45 private CommonAPI commonAPI;
44 46 @Autowired
45 47 public RedisTemplate redisTemplate;
46 48  
47 49 // 定义切点Pointcut
48   - @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
  50 + @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..)) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)")
49 51 public void excudeService() {
50 52 }
51 53  
... ... @@ -103,7 +105,10 @@ public class DictAspect {
103 105 } catch (JsonProcessingException e) {
104 106 log.error("json解析失败"+e.getMessage(),e);
105 107 }
106   - JSONObject item = JSONObject.parseObject(json);
  108 + //update-begin--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----
  109 + JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
  110 + //update-end--Author:scott -- Date:20211223 ----for:【issues/3303】restcontroller返回json数据后key顺序错乱 -----
  111 +
107 112 //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
108 113 //for (Field field : record.getClass().getDeclaredFields()) {
109 114 // 遍历所有字段,把字典Code取出来,放到 map 里
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/PermissionDataAspect.java
... ... @@ -8,6 +8,7 @@ import org.aspectj.lang.annotation.Pointcut;
8 8 import org.aspectj.lang.reflect.MethodSignature;
9 9 import org.jeecg.common.api.CommonAPI;
10 10 import org.jeecg.common.aspect.annotation.PermissionData;
  11 +import org.jeecg.common.constant.CommonConstant;
11 12 import org.jeecg.common.system.util.JeecgDataAutorUtils;
12 13 import org.jeecg.common.system.util.JwtUtil;
13 14 import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
... ... @@ -15,6 +16,7 @@ import org.jeecg.common.system.vo.SysUserCacheInfo;
15 16 import org.jeecg.common.util.SpringContextUtils;
16 17 import org.jeecg.common.util.oConvertUtils;
17 18 import org.springframework.beans.factory.annotation.Autowired;
  19 +import org.springframework.context.annotation.Lazy;
18 20 import org.springframework.stereotype.Component;
19 21  
20 22 import javax.servlet.http.HttpServletRequest;
... ... @@ -31,7 +33,7 @@ import java.util.List;
31 33 @Component
32 34 @Slf4j
33 35 public class PermissionDataAspect {
34   -
  36 + @Lazy
35 37 @Autowired
36 38 private CommonAPI commonAPI;
37 39  
... ... @@ -47,11 +49,21 @@ public class PermissionDataAspect {
47 49 Method method = signature.getMethod();
48 50 PermissionData pd = method.getAnnotation(PermissionData.class);
49 51 String component = pd.pageComponent();
50   -
51 52 String requestMethod = request.getMethod();
52 53 String requestPath = request.getRequestURI().substring(request.getContextPath().length());
53 54 requestPath = filterUrl(requestPath);
54   - log.debug("拦截请求 >> "+requestPath+";请求类型 >> "+requestMethod);
  55 + //update-begin-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
  56 + //先判断是否online报表请求
  57 + // TODO 参数顺序调整有隐患
  58 + if(requestPath.indexOf(UrlMatchEnum.CGREPORT_DATA.getMatch_url())>=0){
  59 + // 获取地址栏参数
  60 + String urlParamString = request.getParameter(CommonConstant.ONL_REP_URL_PARAM_STR);
  61 + if(oConvertUtils.isNotEmpty(urlParamString)){
  62 + requestPath+="?"+urlParamString;
  63 + }
  64 + }
  65 + //update-end-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效
  66 + log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod);
55 67 String username = JwtUtil.getUserNameByToken(request);
56 68 //查询数据权限信息
57 69 //TODO 微服务情况下也得支持缓存机制
... ... @@ -86,6 +98,7 @@ public class PermissionDataAspect {
86 98 * @param request
87 99 * @return
88 100 */
  101 + @Deprecated
89 102 private String getJgAuthRequsetPath(HttpServletRequest request) {
90 103 String queryString = request.getQueryString();
91 104 String requestPath = request.getRequestURI();
... ... @@ -106,6 +119,7 @@ public class PermissionDataAspect {
106 119 return filterUrl(requestPath);
107 120 }
108 121  
  122 + @Deprecated
109 123 private boolean moHuContain(List<String> list,String key){
110 124 for(String str : list){
111 125 if(key.contains(str)){
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/UrlMatchEnum.java
... ... @@ -10,8 +10,8 @@ public enum UrlMatchEnum {
10 10 CGFORM_EXCEL_DATA("/online/cgform/api/exportXls/", "/online/cgformList/"),
11 11 CGFORM_TREE_DATA("/online/cgform/api/getTreeData/", "/online/cgformList/"),
12 12 CGREPORT_DATA("/online/cgreport/api/getColumnsAndData/", "/online/cgreport/"),
13   - CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/");
14   -
  13 + CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/"),
  14 + CGREPORT_EXCEL_DATA2("/online/cgreport/api/exportManySheetXls/", "/online/cgreport/");
15 15  
16 16 UrlMatchEnum(String url, String match_url) {
17 17 this.url = url;
... ... @@ -47,8 +47,10 @@ public enum UrlMatchEnum {
47 47 return null;
48 48 }
49 49  
50   -
51   -// public static void main(String[] args) {
  50 + public String getMatch_url() {
  51 + return match_url;
  52 + }
  53 + // public static void main(String[] args) {
52 54 // /**
53 55 // * 比如request真实请求URL: /online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a
54 56 // * 转换匹配路由URL后(对应配置的菜单路径):/online/cgformList/81fcf7d8922d45069b0d5ba983612d3a
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/AutoDict.java 0 → 100644
  1 +package org.jeecg.common.aspect.annotation;
  2 +
  3 +import java.lang.annotation.*;
  4 +
  5 +/**
  6 + * 通过此注解声明的接口,自动实现字典翻译
  7 + *
  8 + * @Author scott
  9 + * @email jeecgos@163.com
  10 + * @Date 2022年01月05日
  11 + */
  12 +@Target(ElementType.METHOD)
  13 +@Retention(RetentionPolicy.RUNTIME)
  14 +@Documented
  15 +public @interface AutoDict {
  16 +
  17 + /**
  18 + * 暂时无用
  19 + * @return
  20 + */
  21 + String value() default "";
  22 +
  23 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/AutoLowApp.java 0 → 100644
  1 +package org.jeecg.common.aspect.annotation;
  2 +
  3 +import java.lang.annotation.*;
  4 +
  5 +import org.jeecg.common.constant.enums.LowAppAopEnum;
  6 +
  7 +/**
  8 + * 自动注入low_app_id
  9 + *
  10 + * @Author scott
  11 + * @email jeecgos@163.com
  12 + * @Date 2022年01月05日
  13 + */
  14 +@Target(ElementType.METHOD)
  15 +@Retention(RetentionPolicy.RUNTIME)
  16 +@Documented
  17 +public @interface AutoLowApp {
  18 +
  19 + /**
  20 + * 切面类型(add、delete、db_import等其他操作)
  21 + *
  22 + * @return
  23 + */
  24 + LowAppAopEnum action();
  25 +
  26 + /**
  27 + * 业务类型(cgform等)
  28 + *
  29 + * @return
  30 + */
  31 + String bizType();
  32 +
  33 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
... ... @@ -77,7 +77,13 @@ public interface CommonConstant {
77 77 public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
78 78 /** Token缓存时间:3600秒即一小时 */
79 79 public static final int TOKEN_EXPIRE_TIME = 3600;
80   -
  80 +
  81 + /** 登录二维码 */
  82 + public static final String LOGIN_QRCODE_PRE = "QRCODELOGIN:";
  83 + public static final String LOGIN_QRCODE = "LQ:";
  84 + /** 登录二维码token */
  85 + public static final String LOGIN_QRCODE_TOKEN = "LQT:";
  86 +
81 87  
82 88 /**
83 89 * 0:一级菜单
... ... @@ -91,7 +97,7 @@ public interface CommonConstant {
91 97 * 2:按钮权限
92 98 */
93 99 public static final Integer MENU_TYPE_2 = 2;
94   -
  100 +
95 101 /**通告对象类型(USER:指定用户,ALL:全体用户)*/
96 102 public static final String MSG_TYPE_UESR = "USER";
97 103 public static final String MSG_TYPE_ALL = "ALL";
... ... @@ -229,6 +235,9 @@ public interface CommonConstant {
229 235 public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
230 236 /** sys_user 表 phone 唯一键索引 */
231 237 public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
  238 + /** 达梦数据库升提示。违反表[SYS_USER]唯一性约束 */
  239 + public static final String SQL_INDEX_UNIQ_SYS_USER = "唯一性约束";
  240 +
232 241 /** sys_user 表 email 唯一键索引 */
233 242 public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
234 243 /** sys_quartz_job 表 job_class_name 唯一键索引 */
... ... @@ -239,6 +248,8 @@ public interface CommonConstant {
239 248 public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
240 249 /** sys_depart 表 code 唯一键索引 */
241 250 public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
  251 + /** sys_category 表 code 唯一键索引 */
  252 + public static final String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code";
242 253 /**
243 254 * 在线聊天 是否为默认分组
244 255 */
... ... @@ -325,4 +336,7 @@ public interface CommonConstant {
325 336 /** 系统通告消息状态:2=已撤销 */
326 337 String ANNOUNCEMENT_SEND_STATUS_2 = "2";
327 338  
  339 + /**ONLINE 报表权限用 从request中获取地址栏后的参数*/
  340 + String ONL_REP_URL_PARAM_STR="onlRepUrlParamStr";
  341 +
328 342 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/ProvinceCityArea.java
... ... @@ -29,7 +29,7 @@ public class ProvinceCityArea {
29 29  
30 30 public String getCode(String text){
31 31 this.initAreaList();
32   - if(areaList!=null || areaList.size()>0){
  32 + if(areaList!=null && areaList.size()>0){
33 33 for(int i=areaList.size()-1;i>=0;i--){
34 34 if(text.indexOf(areaList.get(i).getText())>=0){
35 35 return areaList.get(i).getId();
... ... @@ -39,6 +39,73 @@ public class ProvinceCityArea {
39 39 return null;
40 40 }
41 41  
  42 + // update-begin-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
  43 + /**
  44 + * 获取省市区code,精准匹配
  45 + * @param texts 文本数组,省,市,区
  46 + * @return 返回 省市区的code
  47 + */
  48 + public String[] getCode(String[] texts) {
  49 + if (texts == null || texts.length == 0) {
  50 + return null;
  51 + }
  52 + this.initAreaList();
  53 + if (areaList == null || areaList.size() == 0) {
  54 + return null;
  55 + }
  56 + String[] codes = new String[texts.length];
  57 + String code = null;
  58 + for (int i = 0; i < texts.length; i++) {
  59 + String text = texts[i];
  60 + Area area;
  61 + if (code == null) {
  62 + area = getAreaByText(text);
  63 + } else {
  64 + area = getAreaByPidAndText(code, text);
  65 + }
  66 + if (area != null) {
  67 + code = area.id;
  68 + codes[i] = code;
  69 + } else {
  70 + return null;
  71 + }
  72 + }
  73 + return codes;
  74 + }
  75 +
  76 + /**
  77 + * 根据text获取area
  78 + * @param text
  79 + * @return
  80 + */
  81 + public Area getAreaByText(String text) {
  82 + for (Area area : areaList) {
  83 + if (text.equals(area.getText())) {
  84 + return area;
  85 + }
  86 + }
  87 + return null;
  88 + }
  89 +
  90 + /**
  91 + * 通过pid获取 area 对象
  92 + * @param pCode 父级编码
  93 + * @param text
  94 + * @return
  95 + */
  96 + public Area getAreaByPidAndText(String pCode, String text) {
  97 + this.initAreaList();
  98 + if (this.areaList != null && this.areaList.size() > 0) {
  99 + for (Area area : this.areaList) {
  100 + if (area.getPid().equals(pCode) && area.getText().equals(text)) {
  101 + return area;
  102 + }
  103 + }
  104 + }
  105 + return null;
  106 + }
  107 + // update-end-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省
  108 +
42 109 public void getAreaByCode(String code,List<String> ls){
43 110 for(Area area: areaList){
44 111 if(area.getId().equals(code)){
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/LowAppAopEnum.java 0 → 100644
  1 +package org.jeecg.common.constant.enums;
  2 +
  3 +/**
  4 + * LowApp 切面注解枚举
  5 + * @date 2022-1-5
  6 + */
  7 +public enum LowAppAopEnum {
  8 +
  9 + /**
  10 + * 新增方法
  11 + */
  12 + ADD,
  13 + /**
  14 + * 删除方法(包含单个和批量删除)
  15 + */
  16 + DELETE,
  17 +
  18 + /**
  19 + * Online表单专用:数据库表转Online表单
  20 + */
  21 + CGFORM_DB_IMPORT
  22 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/RoleIndexConfigEnum.java
1 1 package org.jeecg.common.constant.enums;
2 2  
  3 +import org.jeecg.common.util.oConvertUtils;
  4 +
3 5 import java.util.List;
4 6  
5 7 /**
6 8 * 首页自定义
7 9 * 通过角色编码与首页组件路径配置
  10 + * 枚举的顺序有权限高低权重作用(也就是配置多个角色,在前面的角色首页,会优先生效)
8 11 */
9 12 public enum RoleIndexConfigEnum {
10   - /**
11   - * 管理员
12   - */
13   - ADMIN("admin1", "dashboard/Analysis2"),
14   - /**
15   - * 测试
16   - */
17   - TEST("test", "dashboard/Analysis"),
18   - /**
19   - * hr
20   - */
21   - HR("hr", "dashboard/Analysis1");
  13 +
  14 + ADMIN("admin", "dashboard/Analysis"),
  15 + //TEST("test", "dashboard/IndexChart"),
  16 + HR("hr", "dashboard/IndexBdc");
  17 + //DM("dm", "dashboard/IndexTask"),
22 18  
23 19 /**
24 20 * 角色编码
... ... @@ -44,7 +40,7 @@ public enum RoleIndexConfigEnum {
44 40 * @param roleCode 角色编码
45 41 * @return
46 42 */
47   - public static RoleIndexConfigEnum getEnumByCode(String roleCode) {
  43 + private static RoleIndexConfigEnum getEnumByCode(String roleCode) {
48 44 for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
49 45 if (e.roleCode.equals(roleCode)) {
50 46 return e;
... ... @@ -57,7 +53,7 @@ public enum RoleIndexConfigEnum {
57 53 * @param roleCode 角色编码
58 54 * @return
59 55 */
60   - public static String getIndexByCode(String roleCode) {
  56 + private static String getIndexByCode(String roleCode) {
61 57 for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
62 58 if (e.roleCode.equals(roleCode)) {
63 59 return e.componentUrl;
... ... @@ -67,11 +63,10 @@ public enum RoleIndexConfigEnum {
67 63 }
68 64  
69 65 public static String getIndexByRoles(List<String> roles) {
70   - for (String role : roles) {
71   - for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
72   - if (e.roleCode.equals(role)) {
73   - return e.componentUrl;
74   - }
  66 + String[] rolesArray = roles.toArray(new String[roles.size()]);
  67 + for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) {
  68 + if (oConvertUtils.isIn(e.roleCode,rolesArray)){
  69 + return e.componentUrl;
75 70 }
76 71 }
77 72 return null;
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java
... ... @@ -180,8 +180,15 @@ public class JeecgController&lt;T, S extends IService&lt;T&gt;&gt; {
180 180 //update-end-author:taoyan date:20190528 for:批量插入数据
181 181 return Result.ok("文件导入成功!数据行数:" + list.size());
182 182 } catch (Exception e) {
183   - log.error(e.getMessage(), e);
184   - return Result.error("文件导入失败:" + e.getMessage());
  183 + //update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示
  184 + String msg = e.getMessage();
  185 + log.error(msg, e);
  186 + if(msg!=null && msg.indexOf("Duplicate entry")>=0){
  187 + return Result.error("文件导入失败:有重复数据!");
  188 + }else{
  189 + return Result.error("文件导入失败:" + e.getMessage());
  190 + }
  191 + //update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
185 192 } finally {
186 193 try {
187 194 file.getInputStream().close();
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
... ... @@ -25,7 +25,6 @@ import org.jeecg.common.util.oConvertUtils;
25 25 import org.springframework.util.NumberUtils;
26 26  
27 27 import com.alibaba.fastjson.JSON;
28   -import com.baomidou.mybatisplus.annotation.DbType;
29 28 import com.baomidou.mybatisplus.annotation.TableField;
30 29 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
31 30  
... ... @@ -145,20 +144,23 @@ public class QueryGenerator {
145 144 //区间查询
146 145 doIntervalQuery(queryWrapper, parameterMap, type, name, column);
147 146 //判断单值 参数带不同标识字符串 走不同的查询
148   - //TODO 这种前后带逗号的支持分割后模糊查询需要否 使多选字段的查询生效
  147 + //TODO 这种前后带逗号的支持分割后模糊查询(多选字段查询生效) 示例:,1,3,
149 148 if (null != value && value.toString().startsWith(COMMA) && value.toString().endsWith(COMMA)) {
150 149 String multiLikeval = value.toString().replace(",,", COMMA);
151 150 String[] vals = multiLikeval.substring(1, multiLikeval.length()).split(COMMA);
152 151 final String field = oConvertUtils.camelToUnderline(column);
153 152 if(vals.length>1) {
154 153 queryWrapper.and(j -> {
  154 + log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
155 155 j = j.like(field,vals[0]);
156 156 for (int k=1;k<vals.length;k++) {
157 157 j = j.or().like(field,vals[k]);
  158 + log.info("---查询过滤器,Query规则 .or()---field:{}, rule:{}, value:{}", field, "like", vals[k]);
158 159 }
159 160 //return j;
160 161 });
161 162 }else {
  163 + log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}", field, "like", vals[0]);
162 164 queryWrapper.and(j -> j.like(field,vals[0]));
163 165 }
164 166 }else {
... ... @@ -224,7 +226,7 @@ public class QueryGenerator {
224 226 if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
225 227 order = parameterMap.get(ORDER_TYPE)[0];
226 228 }
227   - log.info("排序规则>>列:" + column + ",排序方式:" + order);
  229 + log.debug("排序规则>>列:" + column + ",排序方式:" + order);
228 230 if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
229 231 //字典字段,去掉字典翻译文本后缀
230 232 if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
... ... @@ -270,10 +272,21 @@ public class QueryGenerator {
270 272 if (conditions == null || conditions.size() == 0) {
271 273 return;
272 274 }
273   - log.info("---高级查询参数-->" + conditions.toString());
  275 + // update-begin-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
  276 + List<QueryCondition> filterConditions = conditions.stream().filter(
  277 + rule -> oConvertUtils.isNotEmpty(rule.getField())
  278 + && oConvertUtils.isNotEmpty(rule.getRule())
  279 + && oConvertUtils.isNotEmpty(rule.getVal())
  280 + ).collect(Collectors.toList());
  281 + if (filterConditions.size() == 0) {
  282 + return;
  283 + }
  284 + // update-end-author:sunjianlei date:20220119 for: 【JTC-573】 过滤空条件查询,防止 sql 拼接多余的 and
  285 + log.info("---高级查询参数-->" + filterConditions);
  286 +
274 287 queryWrapper.and(andWrapper -> {
275   - for (int i = 0; i < conditions.size(); i++) {
276   - QueryCondition rule = conditions.get(i);
  288 + for (int i = 0; i < filterConditions.size(); i++) {
  289 + QueryCondition rule = filterConditions.get(i);
277 290 if (oConvertUtils.isNotEmpty(rule.getField())
278 291 && oConvertUtils.isNotEmpty(rule.getRule())
279 292 && oConvertUtils.isNotEmpty(rule.getVal())) {
... ... @@ -324,7 +337,7 @@ public class QueryGenerator {
324 337 //update-end-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错
325 338  
326 339 // 如果拼接方式是OR,就拼接OR
327   - if (MatchTypeEnum.OR == matchType && i < (conditions.size() - 1)) {
  340 + if (MatchTypeEnum.OR == matchType && i < (filterConditions.size() - 1)) {
328 341 andWrapper.or();
329 342 }
330 343 }
... ... @@ -457,15 +470,37 @@ public class QueryGenerator {
457 470  
458 471 private static void addQueryByRule(QueryWrapper<?> queryWrapper,String name,String type,String value,QueryRuleEnum rule) throws ParseException {
459 472 if(oConvertUtils.isNotEmpty(value)) {
460   - Object temp;
  473 + //update-begin--Author:sunjianlei Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 -------------------
461 474 // 针对数字类型字段,多值查询
462   - if(value.indexOf(COMMA)!=-1){
463   - temp = value;
  475 + if(value.contains(COMMA)){
  476 + Object[] temp = Arrays.stream(value.split(COMMA)).map(v -> {
  477 + try {
  478 + return QueryGenerator.parseByType(v, type, rule);
  479 + } catch (ParseException e) {
  480 + e.printStackTrace();
  481 + return v;
  482 + }
  483 + }).toArray();
464 484 addEasyQuery(queryWrapper, name, rule, temp);
465 485 return;
466 486 }
  487 + Object temp = QueryGenerator.parseByType(value, type, rule);
  488 + addEasyQuery(queryWrapper, name, rule, temp);
  489 + //update-end--Author:sunjianlei Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 -------------------
  490 + }
  491 + }
467 492  
468   - switch (type) {
  493 + /**
  494 + * 根据类型转换给定的值
  495 + * @param value
  496 + * @param type
  497 + * @param rule
  498 + * @return
  499 + * @throws ParseException
  500 + */
  501 + private static Object parseByType(String value, String type, QueryRuleEnum rule) throws ParseException {
  502 + Object temp;
  503 + switch (type) {
469 504 case "class java.lang.Integer":
470 505 temp = Integer.parseInt(value);
471 506 break;
... ... @@ -490,9 +525,8 @@ public class QueryGenerator {
490 525 default:
491 526 temp = value;
492 527 break;
493   - }
494   - addEasyQuery(queryWrapper, name, rule, temp);
495 528 }
  529 + return temp;
496 530 }
497 531  
498 532 /**
... ... @@ -527,12 +561,12 @@ public class QueryGenerator {
527 561 * @param rule 查询规则
528 562 * @param value 查询条件值
529 563 */
530   - private static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
  564 + public static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
531 565 if (value == null || rule == null || oConvertUtils.isEmpty(value)) {
532 566 return;
533 567 }
534 568 name = oConvertUtils.camelToUnderline(name);
535   - log.info("--查询规则-->"+name+" "+rule.getValue()+" "+value);
  569 + log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value);
536 570 switch (rule) {
537 571 case GT:
538 572 queryWrapper.gt(name, value);
... ... @@ -555,7 +589,7 @@ public class QueryGenerator {
555 589 break;
556 590 case IN:
557 591 if(value instanceof String) {
558   - queryWrapper.in(name, (Object[])value.toString().split(","));
  592 + queryWrapper.in(name, (Object[])value.toString().split(COMMA));
559 593 }else if(value instanceof String[]) {
560 594 queryWrapper.in(name, (Object[]) value);
561 595 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java
... ... @@ -34,8 +34,8 @@ import org.jeecg.common.util.oConvertUtils;
34 34 **/
35 35 public class JwtUtil {
36 36  
37   - // Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
38   - public static final long EXPIRE_TIME = 30 * 60 * 1000;
  37 + // Token过期时间2小时(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
  38 + public static final long EXPIRE_TIME = 2 * 60 * 60 * 1000;
39 39  
40 40 /**
41 41 *
... ... @@ -155,7 +155,6 @@ public class JwtUtil {
155 155 * @param user
156 156 * @return
157 157 */
158   - //TODO 急待改造 sckjkdsjsfjdk
159 158 public static String getUserSystemData(String key,SysUserCacheInfo user) {
160 159 if(user==null) {
161 160 user = JeecgDataAutorUtils.loadUserInfo();
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/DictModel.java
... ... @@ -39,5 +39,11 @@ public class DictModel implements Serializable{
39 39 public String getTitle() {
40 40 return this.text;
41 41 }
  42 + /**
  43 + * 特殊用途: vue3 Select组件
  44 + */
  45 + public String getLabel() {
  46 + return this.text;
  47 + }
42 48  
43 49 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java
... ... @@ -14,6 +14,7 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource;
14 14 import org.springframework.util.FileCopyUtils;
15 15 import org.springframework.web.multipart.MultipartFile;
16 16  
  17 +import javax.servlet.http.HttpServletRequest;
17 18 import javax.sql.DataSource;
18 19 import java.io.ByteArrayInputStream;
19 20 import java.io.File;
... ... @@ -282,4 +283,39 @@ public class CommonUtils {
282 283 return DB_TYPE;
283 284  
284 285 }
  286 + /**
  287 + * 获取服务器地址
  288 + *
  289 + * @param request
  290 + * @return
  291 + */
  292 + public static String getBaseUrl(HttpServletRequest request) {
  293 + //1.【兼容】兼容微服务下的 base path-------
  294 + String x_gateway_base_path = request.getHeader("X_GATEWAY_BASE_PATH");
  295 + if(oConvertUtils.isNotEmpty(x_gateway_base_path)){
  296 + log.info("x_gateway_base_path = "+ x_gateway_base_path);
  297 + return x_gateway_base_path;
  298 + }
  299 + //2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题
  300 + // https://blog.csdn.net/weixin_34376986/article/details/89767950
  301 + String scheme = request.getHeader("X-Forwarded-Scheme");
  302 + if(oConvertUtils.isEmpty(scheme)){
  303 + scheme = request.getScheme();
  304 + }
  305 +
  306 + //3.常规操作
  307 + String serverName = request.getServerName();
  308 + int serverPort = request.getServerPort();
  309 + String contextPath = request.getContextPath();
  310 +
  311 + //返回 host domain
  312 + String baseDomainPath = null;
  313 + if(80 == serverPort){
  314 + baseDomainPath = scheme + "://" + serverName + contextPath ;
  315 + }else{
  316 + baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
  317 + }
  318 + log.info("-----Common getBaseUrl----- : " + baseDomainPath);
  319 + return baseDomainPath;
  320 + }
285 321 }
286 322 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MinioUtil.java
1 1 package org.jeecg.common.util;
2 2  
3 3 import io.minio.*;
  4 +import io.minio.http.Method;
4 5 import lombok.extern.slf4j.Slf4j;
5 6 import org.jeecg.common.util.filter.FileTypeFilter;
6 7 import org.jeecg.common.util.filter.StrAttackFilter;
... ... @@ -158,9 +159,11 @@ public class MinioUtil {
158 159 public static String getObjectURL(String bucketName, String objectName, Integer expires) {
159 160 initMinio(minioUrl, minioName,minioPass);
160 161 try{
  162 + //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败----
161 163 GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
162 164 .bucket(bucketName)
163   - .expiry(expires).build();
  165 + .expiry(expires).method(Method.GET).build();
  166 + //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败----
164 167 String url = minioClient.getPresignedObjectUrl(objectArgs);
165 168 return URLDecoder.decode(url,"UTF-8");
166 169 }catch (Exception e){
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java
... ... @@ -17,7 +17,7 @@ public class SqlInjectionUtil {
17 17 * (上线修改值 20200501,同步修改前端的盐值)
18 18 */
19 19 private final static String TABLE_DICT_SIGN_SALT = "20200501";
20   - private final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+";
  20 + private final static String xssStr = "and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()";
21 21  
22 22 /*
23 23 * 针对表字典进行额外的sign签名校验(增加安全机制)
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/dynamic/db/DbTypeUtils.java
... ... @@ -25,7 +25,7 @@ public class DbTypeUtils {
25 25 dialectMap.put("postgresql", "org.hibernate.dialect.PostgreSQLDialect"); //1 --
26 26 dialectMap.put("sqlserver2005", "org.hibernate.dialect.SQLServer2005Dialect");
27 27 dialectMap.put("sqlserver", "org.hibernate.dialect.SQLServerDialect"); //1
28   - dialectMap.put("dm", "org.hibernate.dialect.OracleDialect");//达梦数据库 [国产] 1--
  28 + dialectMap.put("dm", "org.hibernate.dialect.DmDialect");//达梦数据库 [国产] 1--
29 29 dialectMap.put("xugu", "org.hibernate.dialect.HSQLDialect"); //虚谷数据库
30 30 dialectMap.put("kingbasees", "org.hibernate.dialect.PostgreSQLDialect"); //人大金仓 [国产] 1
31 31 dialectMap.put("phoenix", "org.hibernate.dialect.HSQLDialect"); // Phoenix HBase数据库
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
... ... @@ -258,6 +258,9 @@ public class OssBootUtil {
258 258 newBucket = bucket;
259 259 }
260 260 initOSS(endPoint, accessKeyId, accessKeySecret);
  261 + //update-begin---author:liusq Date:20220120 for:替换objectName前缀,防止key不一致导致获取不到文件----
  262 + objectName = OssBootUtil.replacePrefix(objectName,bucket);
  263 + //update-end---author:liusq Date:20220120 for:替换objectName前缀,防止key不一致导致获取不到文件----
261 264 OSSObject ossObject = ossClient.getObject(newBucket,objectName);
262 265 inputStream = new BufferedInputStream(ossObject.getObjectContent());
263 266 }catch (Exception e){
... ... @@ -266,14 +269,14 @@ public class OssBootUtil {
266 269 return inputStream;
267 270 }
268 271  
269   - /**
270   - * 获取文件流
271   - * @param objectName
272   - * @return
273   - */
274   - public static InputStream getOssFile(String objectName){
275   - return getOssFile(objectName,null);
276   - }
  272 + ///**
  273 + // * 获取文件流
  274 + // * @param objectName
  275 + // * @return
  276 + // */
  277 + //public static InputStream getOssFile(String objectName){
  278 + // return getOssFile(objectName,null);
  279 + //}
277 280  
278 281 /**
279 282 * 获取文件外链
... ... @@ -285,6 +288,9 @@ public class OssBootUtil {
285 288 public static String getObjectURL(String bucketName, String objectName, Date expires) {
286 289 initOSS(endPoint, accessKeyId, accessKeySecret);
287 290 try{
  291 + //update-begin---author:liusq Date:20220120 for:替换objectName前缀,防止key不一致导致获取不到文件----
  292 + objectName = OssBootUtil.replacePrefix(objectName,bucketName);
  293 + //update-end---author:liusq Date:20220120 for:替换objectName前缀,防止key不一致导致获取不到文件----
288 294 if(ossClient.doesObjectExist(bucketName,objectName)){
289 295 URL url = ossClient.generatePresignedUrl(bucketName,objectName,expires);
290 296 return URLDecoder.decode(url.toString(),"UTF-8");
... ... @@ -334,5 +340,27 @@ public class OssBootUtil {
334 340 return FILE_URL;
335 341 }
336 342  
337   -
  343 + /**
  344 + * 替换前缀,防止key不一致导致获取不到文件
  345 + * @param objectName 文件上传路径 key
  346 + * @param customBucket 自定义桶
  347 + * @date 2022-01-20
  348 + * @author lsq
  349 + * @return
  350 + */
  351 + private static String replacePrefix(String objectName,String customBucket){
  352 + log.info("------replacePrefix---替换前---objectName:{}",objectName);
  353 + if(oConvertUtils.isNotEmpty(staticDomain)){
  354 + objectName= objectName.replace(staticDomain+"/","");
  355 + }else{
  356 + String newBucket = bucketName;
  357 + if(oConvertUtils.isNotEmpty(customBucket)){
  358 + newBucket = customBucket;
  359 + }
  360 + String path ="https://" + newBucket + "." + endPoint + "/";
  361 + objectName = objectName.replace(path,"");
  362 + }
  363 + log.info("------replacePrefix---替换后---objectName:{}",objectName);
  364 + return objectName;
  365 + }
338 366 }
339 367 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/AutoPoiDictConfig.java
1 1 package org.jeecg.config;
2 2  
3   -import lombok.extern.slf4j.Slf4j;
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +
  6 +import javax.annotation.Resource;
  7 +
4 8 import org.jeecg.common.api.CommonAPI;
5 9 import org.jeecg.common.system.vo.DictModel;
6 10 import org.jeecg.common.util.oConvertUtils;
... ... @@ -8,9 +12,7 @@ import org.jeecgframework.dict.service.AutoPoiDictServiceI;
8 12 import org.springframework.context.annotation.Lazy;
9 13 import org.springframework.stereotype.Service;
10 14  
11   -import javax.annotation.Resource;
12   -import java.util.ArrayList;
13   -import java.util.List;
  15 +import lombok.extern.slf4j.Slf4j;
14 16  
15 17 /**
16 18 * 描述:AutoPoi Excel注解支持字典参数设置
... ... @@ -25,6 +27,9 @@ import java.util.List;
25 27 @Slf4j
26 28 @Service
27 29 public class AutoPoiDictConfig implements AutoPoiDictServiceI {
  30 + final static String EXCEL_SPLIT_TAG = "_";
  31 + final static String TEMP_EXCEL_SPLIT_TAG = "---";
  32 +
28 33 @Lazy
29 34 @Resource
30 35 private CommonAPI commonAPI;
... ... @@ -53,7 +58,14 @@ public class AutoPoiDictConfig implements AutoPoiDictServiceI {
53 58 }
54 59 for (DictModel t : dictList) {
55 60 if(t!=null){
56   - dictReplaces.add(t.getText() + "_" + t.getValue());
  61 + //update-begin---author:scott Date:20211220 for:[issues/I4MBB3]@Excel dicText字段的值有下划线时,导入功能不能正确解析---
  62 + if(t.getValue().contains(EXCEL_SPLIT_TAG)){
  63 + String val = t.getValue().replace(EXCEL_SPLIT_TAG,TEMP_EXCEL_SPLIT_TAG);
  64 + dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + val);
  65 + }else{
  66 + dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + t.getValue());
  67 + }
  68 + //update-end---author:20211220 Date:20211220 for:[issues/I4MBB3]@Excel dicText字段的值有下划线时,导入功能不能正确解析---
57 69 }
58 70 }
59 71 if (dictReplaces != null && dictReplaces.size() != 0) {
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/JeeccgBaseConfig.java
1 1 package org.jeecg.config;
2 2  
  3 +import org.jeecg.config.vo.Shiro;
3 4 import org.springframework.boot.context.properties.ConfigurationProperties;
4 5 import org.springframework.stereotype.Component;
5 6  
... ... @@ -14,6 +15,15 @@ public class JeeccgBaseConfig {
14 15 * 是否启用安全模式
15 16 */
16 17 private Boolean safeMode = false;
  18 + /**
  19 + * shiro拦截排除
  20 + */
  21 + private Shiro shiro;
  22 + /**
  23 + * 签名密钥串(字典等敏感接口)
  24 + * @TODO 降低使用成本加的默认值,实际以 yml配置 为准
  25 + */
  26 + private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a";
17 27  
18 28 public Boolean getSafeMode() {
19 29 return safeMode;
... ... @@ -22,4 +32,20 @@ public class JeeccgBaseConfig {
22 32 public void setSafeMode(Boolean safeMode) {
23 33 this.safeMode = safeMode;
24 34 }
  35 +
  36 + public String getSignatureSecret() {
  37 + return signatureSecret;
  38 + }
  39 +
  40 + public void setSignatureSecret(String signatureSecret) {
  41 + this.signatureSecret = signatureSecret;
  42 + }
  43 +
  44 + public Shiro getShiro() {
  45 + return shiro;
  46 + }
  47 +
  48 + public void setShiro(Shiro shiro) {
  49 + this.shiro = shiro;
  50 + }
25 51 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/StaticConfig.java
... ... @@ -20,11 +20,11 @@ public class StaticConfig {
20 20 @Value(value = "${spring.mail.username}")
21 21 private String emailFrom;
22 22  
23   - /**
24   - * 签名密钥串
25   - */
26   - @Value(value = "${jeecg.signatureSecret}")
27   - private String signatureSecret;
  23 +// /**
  24 +// * 签名密钥串
  25 +// */
  26 +// @Value(value = "${jeecg.signatureSecret}")
  27 +// private String signatureSecret;
28 28  
29 29  
30 30 /*@Bean
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  1 +
1 2 package org.jeecg.config.shiro;
2 3  
3 4 import lombok.extern.slf4j.Slf4j;
... ... @@ -15,6 +16,7 @@ import org.crazycake.shiro.RedisClusterManager;
15 16 import org.crazycake.shiro.RedisManager;
16 17 import org.jeecg.common.constant.CommonConstant;
17 18 import org.jeecg.common.util.oConvertUtils;
  19 +import org.jeecg.config.JeeccgBaseConfig;
18 20 import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
19 21 import org.jeecg.config.shiro.filters.JwtFilter;
20 22 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
... ... @@ -43,13 +45,12 @@ import java.util.*;
43 45 @Configuration
44 46 public class ShiroConfig {
45 47  
46   - @Value("${jeecg.shiro.excludeUrls}")
47   - private String excludeUrls;
48 48 @Resource
49 49 LettuceConnectionFactory lettuceConnectionFactory;
50 50 @Autowired
51 51 private Environment env;
52   -
  52 + @Autowired
  53 + JeeccgBaseConfig jeeccgBaseConfig;
53 54  
54 55 /**
55 56 * Filter Chain定义说明
... ... @@ -64,8 +65,9 @@ public class ShiroConfig {
64 65 shiroFilterFactoryBean.setSecurityManager(securityManager);
65 66 // 拦截器
66 67 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
67   - if(oConvertUtils.isNotEmpty(excludeUrls)){
68   - String[] permissionUrl = excludeUrls.split(",");
  68 + String shiroExcludeUrls = jeeccgBaseConfig.getShiro().getExcludeUrls();
  69 + if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
  70 + String[] permissionUrl = shiroExcludeUrls.split(",");
69 71 for(String url : permissionUrl){
70 72 filterChainDefinitionMap.put(url,"anon");
71 73 }
... ... @@ -89,6 +91,12 @@ public class ShiroConfig {
89 91 filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
90 92 filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
91 93 filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
  94 +
  95 + filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
  96 + filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
  97 + filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
  98 +
  99 +
92 100 filterChainDefinitionMap.put("/", "anon");
93 101 filterChainDefinitionMap.put("/doc.html", "anon");
94 102 filterChainDefinitionMap.put("/**/*.js", "anon");
... ... @@ -130,6 +138,9 @@ public class ShiroConfig {
130 138 filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
131 139 filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
132 140  
  141 + //wps
  142 + filterChainDefinitionMap.put("/v1/**","anon");
  143 +
133 144 //性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有)
134 145 filterChainDefinitionMap.put("/actuator/**", "anon");
135 146  
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java
... ... @@ -137,9 +137,12 @@ public class ShiroRealm extends AuthorizingRealm {
137 137 if(oConvertUtils.isNotEmpty(userTenantIds)){
138 138 String contextTenantId = TenantContext.getTenant();
139 139 if(oConvertUtils.isNotEmpty(contextTenantId) && !"0".equals(contextTenantId)){
140   - if(String.join(",",userTenantIds).indexOf(contextTenantId)<0){
  140 + //update-begin-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
  141 + String[] arr = userTenantIds.split(",");
  142 + if(!oConvertUtils.isIn(contextTenantId, arr)){
141 143 throw new AuthenticationException("用户租户信息变更,请重新登陆!");
142 144 }
  145 + //update-end-author:taoyan date:20211227 for: /issues/I4O14W 用户租户信息变更判断漏洞
143 146 }
144 147 }
145 148 //update-end-author:taoyan date:20210609 for:校验用户的tenant_id和前端传过来的是否一致
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/SignUtil.java
... ... @@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
5 5 import org.jeecg.common.exception.JeecgBootException;
6 6 import org.jeecg.common.util.SpringContextUtils;
7 7 import org.jeecg.common.util.oConvertUtils;
8   -import org.jeecg.config.StaticConfig;
  8 +import org.jeecg.config.JeeccgBaseConfig;
9 9 import org.springframework.util.DigestUtils;
10 10 import org.springframework.util.StringUtils;
11 11  
... ... @@ -46,8 +46,9 @@ public class SignUtil {
46 46 params.remove("_t");
47 47 String paramsJsonStr = JSONObject.toJSONString(params);
48 48 log.info("Param paramsJsonStr : {}", paramsJsonStr);
49   - StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
50   - String signatureSecret = staticConfig.getSignatureSecret();
  49 + //设置签名秘钥
  50 + JeeccgBaseConfig jeeccgBaseConfig = SpringContextUtils.getBean(JeeccgBaseConfig.class);
  51 + String signatureSecret = jeeccgBaseConfig.getSignatureSecret();
51 52 if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains("${")){
52 53 throw new JeecgBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 !!");
53 54 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/vo/Shiro.java 0 → 100644
  1 +package org.jeecg.config.vo;
  2 +
  3 +/**
  4 + * @Description: TODO
  5 + * @author: scott
  6 + * @date: 2022年01月21日 14:23
  7 + */
  8 +public class Shiro {
  9 + private String excludeUrls = "";
  10 +
  11 + public String getExcludeUrls() {
  12 + return excludeUrls;
  13 + }
  14 +
  15 + public void setExcludeUrls(String excludeUrls) {
  16 + this.excludeUrls = excludeUrls;
  17 + }
  18 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-tools/pom.xml
... ... @@ -4,7 +4,7 @@
4 4 <parent>
5 5 <groupId>org.jeecgframework.boot</groupId>
6 6 <artifactId>jeecg-boot-base</artifactId>
7   - <version>3.0</version>
  7 + <version>3.1.0</version>
8 8 </parent>
9 9 <modelVersion>4.0.0</modelVersion>
10 10 <description>公共模块</description>
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-tools/src/main/java/org/jeecg/common/constant/CacheConstant.java
... ... @@ -96,4 +96,8 @@ public interface CacheConstant {
96 96 * online图表
97 97 */
98 98 public static final String ONLINE_GRAPH = "sys:cache:online:graph";
  99 + /**
  100 + * 拖拽页面信息缓存
  101 + */
  102 + public static final String DRAG_PAGE_CACHE = "drag:cache:page";
99 103 }
... ...
jeecg-boot/jeecg-boot-base/pom.xml
... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <artifactId>jeecg-boot-parent</artifactId>
7 7 <groupId>org.jeecgframework.boot</groupId>
8   - <version>3.0</version>
  8 + <version>3.1.0</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11 11  
... ...
jeecg-boot/jeecg-boot-module-demo/pom.xml
... ... @@ -5,7 +5,7 @@
5 5 <parent>
6 6 <artifactId>jeecg-boot-parent</artifactId>
7 7 <groupId>org.jeecgframework.boot</groupId>
8   - <version>3.0</version>
  8 + <version>3.1.0</version>
9 9 </parent>
10 10 <modelVersion>4.0.0</modelVersion>
11 11  
... ...
jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/mock/MockController.java
... ... @@ -31,7 +31,7 @@ public class MockController {
31 31 * @return
32 32 */
33 33 @RequestMapping(value = "/json/{filename}", method = RequestMethod.GET)
34   - public String getJsonData(@PathVariable String filename) {
  34 + public String getJsonData(@PathVariable("filename") String filename) {
35 35 String jsonpath = "classpath:org/jeecg/modules/demo/mock/json/"+filename+".json";
36 36 return readJson(jsonpath);
37 37 }
... ...
jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/online/OnlCgformDemoController.java 0 → 100644
  1 +package org.jeecg.modules.demo.online;
  2 +
  3 +import com.alibaba.fastjson.JSONArray;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.jeecg.common.api.vo.Result;
  7 +import org.jeecg.common.system.vo.DictModel;
  8 +import org.jeecg.common.util.oConvertUtils;
  9 +import org.springframework.web.bind.annotation.PostMapping;
  10 +import org.springframework.web.bind.annotation.RequestBody;
  11 +import org.springframework.web.bind.annotation.RequestMapping;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import java.util.ArrayList;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * Online表单开发 demo 示例
  19 + *
  20 + * @author sunjianlei
  21 + * @date 2021-12-16
  22 + */
  23 +@Slf4j
  24 +@RestController("onlCgformDemoController")
  25 +@RequestMapping("/demo/online/cgform")
  26 +public class OnlCgformDemoController {
  27 +
  28 + /**
  29 + * Online表单 http 增强,list增强示例
  30 + * @param params
  31 + * @return
  32 + */
  33 + @PostMapping("/enhanceJavaListHttp")
  34 + public Result<?> enhanceJavaListHttp(@RequestBody JSONObject params) {
  35 + log.info(" --- params:" + params.toJSONString());
  36 + JSONArray dataList = params.getJSONArray("dataList");
  37 + List<DictModel> dict = virtualDictData();
  38 + for (int i = 0; i < dataList.size(); i++) {
  39 + JSONObject record = dataList.getJSONObject(i);
  40 + String province = record.getString("province");
  41 + if (province == null) {
  42 + continue;
  43 + }
  44 + String text = dict.stream()
  45 + .filter(p -> province.equals(p.getValue()))
  46 + .map(DictModel::getText)
  47 + .findAny()
  48 + .orElse(province);
  49 + record.put("province", text);
  50 + }
  51 + Result<?> res = Result.OK(dataList);
  52 + res.setCode(1);
  53 + return res;
  54 + }
  55 +
  56 + /**
  57 + * 模拟字典数据
  58 + *
  59 + * @return
  60 + */
  61 + private List<DictModel> virtualDictData() {
  62 + List<DictModel> dict = new ArrayList<>();
  63 + dict.add(new DictModel("bj", "北京"));
  64 + dict.add(new DictModel("sd", "山东"));
  65 + dict.add(new DictModel("ah", "安徽"));
  66 + return dict;
  67 + }
  68 +
  69 +
  70 + /**
  71 + * Online表单 http 增强,add、edit增强示例
  72 + * @param params
  73 + * @return
  74 + */
  75 + @PostMapping("/enhanceJavaHttp")
  76 + public Result<?> enhanceJavaHttp(@RequestBody JSONObject params) {
  77 + log.info(" --- params:" + params.toJSONString());
  78 + String tableName = params.getString("tableName");
  79 + JSONObject record = params.getJSONObject("record");
  80 + /*
  81 + * 业务场景一: 获取提交表单数据,进行其他业务关联操作
  82 + * (比如:根据入库单,同步更改库存)
  83 + */
  84 + log.info(" --- tableName:" + tableName);
  85 + log.info(" --- 行数据:" + record.toJSONString());
  86 + /*
  87 + * 业务场景二: 保存数据之前进行数据的校验
  88 + * 直接返回错误状态即可
  89 + */
  90 + String phone = record.getString("phone");
  91 + if (oConvertUtils.isEmpty(phone)) {
  92 + return Result.error("手机号不能为空!");
  93 + }
  94 + /*
  95 + * 业务场景三: 保存数据之对数据的处理
  96 + * 直接操作 record 即可
  97 + */
  98 + record.put("phone", "010-" + phone);
  99 +
  100 + /* 其他业务场景自行实现 */
  101 +
  102 + // 返回场景一: 不对 record 做任何修改的情况下,可以直接返回 code,
  103 + // 返回 0 = 丢弃当前数据
  104 + // 返回 1 = 新增当前数据
  105 + // 返回 2 = 修改当前数据 TODO(?)存疑
  106 +// return Result.OK(1);
  107 +
  108 + // 返回场景二: 需要对 record 做修改的情况下,需要返回一个JSONObject对象(或者Map也行)
  109 + JSONObject res = new JSONObject();
  110 + res.put("code", 1);
  111 + // 将 record 返回以进行修改
  112 + res.put("record", record);
  113 + // TODO 不要 code 的概念
  114 + return Result.OK(res);
  115 + }
  116 +
  117 +}
... ...
jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java
... ... @@ -62,6 +62,7 @@ public class JeecgDemoController extends JeecgController&lt;JeecgDemo, IJeecgDemoSe
62 62 public Result<?> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
63 63 HttpServletRequest req) {
64 64 QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
  65 + queryWrapper.orderByDesc("create_time");
65 66 Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize);
66 67  
67 68 IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
... ... @@ -92,9 +93,9 @@ public class JeecgDemoController extends JeecgController&lt;JeecgDemo, IJeecgDemoSe
92 93 * @param jeecgDemo
93 94 * @return
94 95 */
95   - @PutMapping(value = "/edit")
96   - @ApiOperation(value = "编辑DEMO", notes = "编辑DEMO")
97 96 @AutoLog(value = "编辑DEMO", operateType = CommonConstant.OPERATE_TYPE_3)
  97 + @ApiOperation(value = "编辑DEMO", notes = "编辑DEMO")
  98 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
98 99 public Result<?> edit(@RequestBody JeecgDemo jeecgDemo) {
99 100 jeecgDemoService.updateById(jeecgDemo);
100 101 return Result.OK("更新成功!");
... ... @@ -316,5 +317,9 @@ public class JeecgDemoController extends JeecgController&lt;JeecgDemo, IJeecgDemoSe
316 317 return Result.OK("1");
317 318 }
318 319  
  320 + @GetMapping(value = "/hello")
  321 + public String hello(HttpServletRequest req) {
  322 + return "hello world!";
  323 + }
319 324  
320 325 }
... ...
jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderTabMainController.java renamed to jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderErpMainController.java
1 1 package org.jeecg.modules.demo.test.controller;
2 2  
3   -import java.util.Arrays;
4   -import java.util.List;
5   -
6   -import javax.servlet.http.HttpServletRequest;
7   -
  3 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4 +import com.baomidou.mybatisplus.core.metadata.IPage;
  5 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6 +import lombok.extern.slf4j.Slf4j;
8 7 import org.jeecg.common.api.vo.Result;
9 8 import org.jeecg.common.system.query.QueryGenerator;
10 9 import org.jeecg.modules.demo.test.entity.JeecgOrderCustomer;
... ... @@ -16,20 +15,10 @@ import org.jeecg.modules.demo.test.service.IJeecgOrderTicketService;
16 15 import org.jeecg.modules.demo.test.vo.JeecgOrderMainPage;
17 16 import org.springframework.beans.BeanUtils;
18 17 import org.springframework.beans.factory.annotation.Autowired;
19   -import org.springframework.web.bind.annotation.DeleteMapping;
20   -import org.springframework.web.bind.annotation.GetMapping;
21   -import org.springframework.web.bind.annotation.PostMapping;
22   -import org.springframework.web.bind.annotation.PutMapping;
23   -import org.springframework.web.bind.annotation.RequestBody;
24   -import org.springframework.web.bind.annotation.RequestMapping;
25   -import org.springframework.web.bind.annotation.RequestParam;
26   -import org.springframework.web.bind.annotation.RestController;
  18 +import org.springframework.web.bind.annotation.*;
27 19  
28   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
29   -import com.baomidou.mybatisplus.core.metadata.IPage;
30   -import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
31   -
32   -import lombok.extern.slf4j.Slf4j;
  20 +import javax.servlet.http.HttpServletRequest;
  21 +import java.util.Arrays;
33 22  
34 23 /**
35 24 * @Description: 一对多示例(ERP TAB风格)
... ... @@ -40,7 +29,7 @@ import lombok.extern.slf4j.Slf4j;
40 29 @Slf4j
41 30 @RestController
42 31 @RequestMapping("/test/order")
43   -public class JeecgOrderTabMainController {
  32 +public class JeecgOrderErpMainController {
44 33  
45 34 @Autowired
46 35 private IJeecgOrderMainService jeecgOrderMainService;
... ... @@ -89,7 +78,7 @@ public class JeecgOrderTabMainController {
89 78 * @param jeecgOrderMainPage
90 79 * @return
91 80 */
92   - @PutMapping("/edit")
  81 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
93 82 public Result<?> edit(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
94 83 JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
95 84 BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);
... ... @@ -186,7 +175,7 @@ public class JeecgOrderTabMainController {
186 175 * @param jeecgOrderCustomer
187 176 * @return
188 177 */
189   - @PutMapping("/editCustomer")
  178 + @RequestMapping(value = "/editCustomer", method = {RequestMethod.PUT,RequestMethod.POST})
190 179 public Result<?> editCustomer(@RequestBody JeecgOrderCustomer jeecgOrderCustomer) {
191 180 jeecgOrderCustomerService.updateById(jeecgOrderCustomer);
192 181 return Result.ok("添加成功!");
... ... @@ -234,7 +223,7 @@ public class JeecgOrderTabMainController {
234 223 * @param jeecgOrderTicket
235 224 * @return
236 225 */
237   - @PutMapping("/editTicket")
  226 + @RequestMapping(value = "/editTicket", method = {RequestMethod.PUT,RequestMethod.POST})
238 227 public Result<?> editTicket(@RequestBody JeecgOrderTicket jeecgOrderTicket) {
239 228 jeecgOrderTicketService.updateById(jeecgOrderTicket);
240 229 return Result.ok("编辑成功!");
... ...
jeecg-boot/jeecg-boot-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgOrderMainController.java
... ... @@ -104,7 +104,7 @@ public class JeecgOrderMainController extends JeecgController&lt;JeecgOrderMain, IJ
104 104 * @param jeecgOrderMainPage
105 105 * @return
106 106 */
107   - @PutMapping(value = "/edit")
  107 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
108 108 public Result<?> eidt(@RequestBody JeecgOrderMainPage jeecgOrderMainPage) {
109 109 JeecgOrderMain jeecgOrderMain = new JeecgOrderMain();
110 110 BeanUtils.copyProperties(jeecgOrderMainPage, jeecgOrderMain);
... ...
jeecg-boot/jeecg-boot-module-system/Dockerfile
... ... @@ -11,6 +11,6 @@ WORKDIR /jeecg-boot
11 11 EXPOSE 8080
12 12  
13 13 ADD ./src/main/resources/jeecg ./config/jeecg
14   -ADD ./target/jeecg-boot-module-system-3.0.jar ./
  14 +ADD ./target/jeecg-boot-module-system-3.1.0.jar ./
15 15  
16   -CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.0.jar
17 16 \ No newline at end of file
  17 +CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-3.1.0.jar
18 18 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/pom.xml
... ... @@ -4,7 +4,7 @@
4 4 <parent>
5 5 <groupId>org.jeecgframework.boot</groupId>
6 6 <artifactId>jeecg-boot-parent</artifactId>
7   - <version>3.0</version>
  7 + <version>3.1.0</version>
8 8 </parent>
9 9 <modelVersion>4.0.0</modelVersion>
10 10  
... ... @@ -38,7 +38,7 @@
38 38 <dependency>
39 39 <groupId>org.jeecgframework</groupId>
40 40 <artifactId>jeewx-api</artifactId>
41   - <version>1.4.6</version>
  41 + <version>1.4.7</version>
42 42 <exclusions>
43 43 <exclusion>
44 44 <artifactId>commons-beanutils</artifactId>
... ... @@ -54,7 +54,7 @@
54 54 <dependency>
55 55 <groupId>org.jeecgframework.jimureport</groupId>
56 56 <artifactId>jimureport-spring-boot-starter</artifactId>
57   - <version>1.4.0</version>
  57 + <version>1.4.2</version>
58 58 </dependency>
59 59  
60 60  
... ... @@ -62,7 +62,7 @@
62 62 <dependency>
63 63 <groupId>org.jeecgframework.boot</groupId>
64 64 <artifactId>jeecg-boot-module-demo</artifactId>
65   - <version>3.0</version>
  65 + <version>3.1.0</version>
66 66 </dependency>
67 67  
68 68 </dependencies>
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/JeecgSystemApplication.java
1 1 package org.jeecg;
2 2  
3 3 import lombok.extern.slf4j.Slf4j;
  4 +import org.apache.catalina.Context;
  5 +import org.apache.tomcat.util.scan.StandardJarScanner;
4 6 import org.jeecg.common.util.oConvertUtils;
5 7 import org.springframework.boot.SpringApplication;
  8 +//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  9 +import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
6 10 import org.springframework.boot.autoconfigure.SpringBootApplication;
  11 +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
7 12 import org.springframework.boot.builder.SpringApplicationBuilder;
  13 +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
8 14 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
9 15 import org.springframework.context.ConfigurableApplicationContext;
  16 +import org.springframework.context.annotation.Bean;
10 17 import org.springframework.core.env.Environment;
11 18  
12 19 import java.net.InetAddress;
... ... @@ -17,6 +24,7 @@ import java.net.UnknownHostException;
17 24 */
18 25 @Slf4j
19 26 @SpringBootApplication
  27 +@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
20 28 public class JeecgSystemApplication extends SpringBootServletInitializer {
21 29  
22 30 @Override
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/jimureport/JimuReportTokenService.java
1 1 package org.jeecg.config.jimureport;
2 2  
3   -import org.jeecg.common.constant.DataBaseConstant;
  3 +import lombok.extern.slf4j.Slf4j;
4 4 import org.jeecg.common.system.api.ISysBaseAPI;
5 5 import org.jeecg.common.system.util.JwtUtil;
6 6 import org.jeecg.common.system.vo.SysUserCacheInfo;
... ... @@ -20,6 +20,9 @@ import java.util.Map;
20 20 * * 1.自定义获取登录token
21 21 * * 2.自定义获取登录用户
22 22 */
  23 +
  24 +
  25 +@Slf4j
23 26 @Component
24 27 public class JimuReportTokenService implements JmReportTokenServiceI {
25 28 @Autowired
... ... @@ -45,10 +48,16 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
45 48  
46 49 @Override
47 50 public Map<String, Object> getUserInfo(String token) {
  51 + Map<String, Object> map = new HashMap<String, Object>();
48 52 String username = JwtUtil.getUsername(token);
49 53 //此处通过token只能拿到一个信息 用户账号 后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
50   - SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
51   - Map<String, Object> map = new HashMap<String, Object>();
  54 + SysUserCacheInfo userInfo = null;
  55 + try {
  56 + userInfo = sysBaseAPI.getCacheUser(username);
  57 + } catch (Exception e) {
  58 + log.error("获取用户信息异常:"+ e.getMessage());
  59 + return map;
  60 + }
52 61 //设置账号名
53 62 map.put(SYS_USER_CODE, userInfo.getSysUserCode());
54 63 //设置部门编码
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/aop/LogRecordAspect.java
1   -package org.jeecg.modules.ngalain.aop;
2   -
3   -import javax.servlet.http.HttpServletRequest;
4   -
5   -import org.aspectj.lang.ProceedingJoinPoint;
6   -import org.aspectj.lang.annotation.Around;
7   -import org.aspectj.lang.annotation.Aspect;
8   -import org.aspectj.lang.annotation.Pointcut;
9   -import org.springframework.context.annotation.Configuration;
10   -import org.springframework.web.context.request.RequestAttributes;
11   -import org.springframework.web.context.request.RequestContextHolder;
12   -import org.springframework.web.context.request.ServletRequestAttributes;
13   -import org.slf4j.Logger;
14   -import org.slf4j.LoggerFactory;;
15   -
16   -
17   -// 暂时注释掉,提高系统性能
18   -//@Aspect //定义一个切面
19   -//@Configuration
20   -public class LogRecordAspect {
21   -private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
22   -
23   - // 定义切点Pointcut
24   - @Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
25   - public void excudeService() {
26   - }
27   -
28   - @Around("excudeService()")
29   - public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
30   - RequestAttributes ra = RequestContextHolder.getRequestAttributes();
31   - ServletRequestAttributes sra = (ServletRequestAttributes) ra;
32   - HttpServletRequest request = sra.getRequest();
33   -
34   - String url = request.getRequestURL().toString();
35   - String method = request.getMethod();
36   - String uri = request.getRequestURI();
37   - String queryString = request.getQueryString();
38   - logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
39   -
40   - // result的值就是被拦截方法的返回值
41   - Object result = pjp.proceed();
42   -
43   - logger.info("请求结束,controller的返回值是 " + result);
44   - return result;
45   - }
46   -}
47 1 \ No newline at end of file
  2 +//package org.jeecg.modules.ngalain.aop;
  3 +//
  4 +//import javax.servlet.http.HttpServletRequest;
  5 +//
  6 +//import org.aspectj.lang.ProceedingJoinPoint;
  7 +//import org.aspectj.lang.annotation.Around;
  8 +//import org.aspectj.lang.annotation.Aspect;
  9 +//import org.aspectj.lang.annotation.Pointcut;
  10 +//import org.springframework.context.annotation.Configuration;
  11 +//import org.springframework.web.context.request.RequestAttributes;
  12 +//import org.springframework.web.context.request.RequestContextHolder;
  13 +//import org.springframework.web.context.request.ServletRequestAttributes;
  14 +//import org.slf4j.Logger;
  15 +//import org.slf4j.LoggerFactory;;
  16 +//
  17 +//
  18 +//// 暂时注释掉,提高系统性能
  19 +////@Aspect //定义一个切面
  20 +////@Configuration
  21 +//public class LogRecordAspect {
  22 +//private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);
  23 +//
  24 +// // 定义切点Pointcut
  25 +// @Pointcut("execution(public * org.jeecg.modules.*.*.*Controller.*(..))")
  26 +// public void excudeService() {
  27 +// }
  28 +//
  29 +// @Around("excudeService()")
  30 +// public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
  31 +// RequestAttributes ra = RequestContextHolder.getRequestAttributes();
  32 +// ServletRequestAttributes sra = (ServletRequestAttributes) ra;
  33 +// HttpServletRequest request = sra.getRequest();
  34 +//
  35 +// String url = request.getRequestURL().toString();
  36 +// String method = request.getMethod();
  37 +// String uri = request.getRequestURI();
  38 +// String queryString = request.getQueryString();
  39 +// logger.info("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);
  40 +//
  41 +// // result的值就是被拦截方法的返回值
  42 +// Object result = pjp.proceed();
  43 +//
  44 +// logger.info("请求结束,controller的返回值是 " + result);
  45 +// return result;
  46 +// }
  47 +//}
48 48 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/controller/NgAlainController.java
1   -package org.jeecg.modules.ngalain.controller;
2   -
3   -import java.util.ArrayList;
4   -import java.util.List;
5   -import java.util.Map;
6   -
7   -import javax.servlet.http.HttpServletRequest;
8   -
9   -import org.apache.shiro.SecurityUtils;
10   -import org.jeecg.common.api.vo.Result;
11   -import org.jeecg.common.system.vo.DictModel;
12   -import org.jeecg.common.system.vo.LoginUser;
13   -import org.jeecg.modules.ngalain.service.NgAlainService;
14   -import org.jeecg.modules.system.service.ISysDictService;
15   -import org.springframework.beans.factory.annotation.Autowired;
16   -import org.springframework.web.bind.annotation.PathVariable;
17   -import org.springframework.web.bind.annotation.RequestMapping;
18   -import org.springframework.web.bind.annotation.RequestMethod;
19   -import org.springframework.web.bind.annotation.ResponseBody;
20   -import org.springframework.web.bind.annotation.RestController;
21   -
22   -import com.alibaba.fastjson.JSONObject;
23   -
24   -import lombok.extern.slf4j.Slf4j;
25   -
26   -@Slf4j
27   -@RestController
28   -@RequestMapping("/sys/ng-alain")
29   -public class NgAlainController {
30   - @Autowired
31   - private NgAlainService ngAlainService;
32   - @Autowired
33   - private ISysDictService sysDictService;
34   -
35   - @RequestMapping(value = "/getAppData")
36   - @ResponseBody
37   - public JSONObject getAppData(HttpServletRequest request) throws Exception {
38   - String token=request.getHeader("X-Access-Token");
39   - JSONObject j = new JSONObject();
40   - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
41   - JSONObject userObjcet = new JSONObject();
42   - userObjcet.put("name", user.getUsername());
43   - userObjcet.put("avatar", user.getAvatar());
44   - userObjcet.put("email", user.getEmail());
45   - userObjcet.put("token", token);
46   - j.put("user", userObjcet);
47   - j.put("menu",ngAlainService.getMenu(user.getUsername()));
48   - JSONObject app = new JSONObject();
49   - app.put("name", "jeecg-boot-angular");
50   - app.put("description", "jeecg+ng-alain整合版本");
51   - j.put("app", app);
52   - return j;
53   - }
54   -
55   - @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
56   - public Object getDictItems(@PathVariable String dictCode) {
57   - log.info(" dictCode : "+ dictCode);
58   - Result<List<DictModel>> result = new Result<List<DictModel>>();
59   - List<DictModel> ls = null;
60   - try {
61   - ls = sysDictService.queryDictItemsByCode(dictCode);
62   - result.setSuccess(true);
63   - result.setResult(ls);
64   - } catch (Exception e) {
65   - log.error(e.getMessage(),e);
66   - result.error500("操作失败");
67   - return result;
68   - }
69   - List<JSONObject> dictlist=new ArrayList<>();
70   - for (DictModel l : ls) {
71   - JSONObject dict=new JSONObject();
72   - try {
73   - dict.put("value",Integer.parseInt(l.getValue()));
74   - } catch (NumberFormatException e) {
75   - dict.put("value",l.getValue());
76   - }
77   - dict.put("label",l.getText());
78   - dictlist.add(dict);
79   - }
80   - return dictlist;
81   - }
82   - @RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
83   - public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
84   - return this.ngAlainService.getDictByTable(table,key,value);
85   - }
86   -}
  1 +//package org.jeecg.modules.ngalain.controller;
  2 +//
  3 +//import java.util.ArrayList;
  4 +//import java.util.List;
  5 +//import java.util.Map;
  6 +//
  7 +//import javax.servlet.http.HttpServletRequest;
  8 +//
  9 +//import org.apache.shiro.SecurityUtils;
  10 +//import org.jeecg.common.api.vo.Result;
  11 +//import org.jeecg.common.system.vo.DictModel;
  12 +//import org.jeecg.common.system.vo.LoginUser;
  13 +//import org.jeecg.modules.ngalain.service.NgAlainService;
  14 +//import org.jeecg.modules.system.service.ISysDictService;
  15 +//import org.springframework.beans.factory.annotation.Autowired;
  16 +//import org.springframework.web.bind.annotation.PathVariable;
  17 +//import org.springframework.web.bind.annotation.RequestMapping;
  18 +//import org.springframework.web.bind.annotation.RequestMethod;
  19 +//import org.springframework.web.bind.annotation.ResponseBody;
  20 +//import org.springframework.web.bind.annotation.RestController;
  21 +//
  22 +//import com.alibaba.fastjson.JSONObject;
  23 +//
  24 +//import lombok.extern.slf4j.Slf4j;
  25 +//
  26 +//@Slf4j
  27 +//@RestController
  28 +//@RequestMapping("/sys/ng-alain")
  29 +//public class NgAlainController {
  30 +// @Autowired
  31 +// private NgAlainService ngAlainService;
  32 +// @Autowired
  33 +// private ISysDictService sysDictService;
  34 +//
  35 +// @RequestMapping(value = "/getAppData")
  36 +// @ResponseBody
  37 +// public JSONObject getAppData(HttpServletRequest request) throws Exception {
  38 +// String token=request.getHeader("X-Access-Token");
  39 +// JSONObject j = new JSONObject();
  40 +// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
  41 +// JSONObject userObjcet = new JSONObject();
  42 +// userObjcet.put("name", user.getUsername());
  43 +// userObjcet.put("avatar", user.getAvatar());
  44 +// userObjcet.put("email", user.getEmail());
  45 +// userObjcet.put("token", token);
  46 +// j.put("user", userObjcet);
  47 +// j.put("menu",ngAlainService.getMenu(user.getUsername()));
  48 +// JSONObject app = new JSONObject();
  49 +// app.put("name", "jeecg-boot-angular");
  50 +// app.put("description", "jeecg+ng-alain整合版本");
  51 +// j.put("app", app);
  52 +// return j;
  53 +// }
  54 +//
  55 +// @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
  56 +// public Object getDictItems(@PathVariable String dictCode) {
  57 +// log.info(" dictCode : "+ dictCode);
  58 +// Result<List<DictModel>> result = new Result<List<DictModel>>();
  59 +// List<DictModel> ls = null;
  60 +// try {
  61 +// ls = sysDictService.queryDictItemsByCode(dictCode);
  62 +// result.setSuccess(true);
  63 +// result.setResult(ls);
  64 +// } catch (Exception e) {
  65 +// log.error(e.getMessage(),e);
  66 +// result.error500("操作失败");
  67 +// return result;
  68 +// }
  69 +// List<JSONObject> dictlist=new ArrayList<>();
  70 +// for (DictModel l : ls) {
  71 +// JSONObject dict=new JSONObject();
  72 +// try {
  73 +// dict.put("value",Integer.parseInt(l.getValue()));
  74 +// } catch (NumberFormatException e) {
  75 +// dict.put("value",l.getValue());
  76 +// }
  77 +// dict.put("label",l.getText());
  78 +// dictlist.add(dict);
  79 +// }
  80 +// return dictlist;
  81 +// }
  82 +// @RequestMapping(value = "/getDictItemsByTable/{table}/{key}/{value}", method = RequestMethod.GET)
  83 +// public Object getDictItemsByTable(@PathVariable String table,@PathVariable String key,@PathVariable String value) {
  84 +// return this.ngAlainService.getDictByTable(table,key,value);
  85 +// }
  86 +//}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
... ... @@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
6 6 import io.swagger.annotations.Api;
7 7 import io.swagger.annotations.ApiOperation;
8 8 import lombok.extern.slf4j.Slf4j;
  9 +import org.apache.shiro.SecurityUtils;
9 10 import org.apache.shiro.authz.annotation.RequiresRoles;
10 11 import org.jeecg.common.api.vo.Result;
11 12 import org.jeecg.common.constant.CommonConstant;
12 13 import org.jeecg.common.system.query.QueryGenerator;
  14 +import org.jeecg.common.system.vo.LoginUser;
13 15 import org.jeecg.common.util.ImportExcelUtil;
14 16 import org.jeecg.modules.quartz.entity.QuartzJob;
15 17 import org.jeecg.modules.quartz.service.IQuartzJobService;
... ... @@ -145,14 +147,14 @@ public class QuartzJobController {
145 147 */
146 148 //@RequiresRoles("admin")
147 149 @GetMapping(value = "/pause")
148   - @ApiOperation(value = "暂停定时任务")
  150 + @ApiOperation(value = "停止定时任务")
149 151 public Result<Object> pauseJob(@RequestParam(name = "id") String id) {
150 152 QuartzJob job = quartzJobService.getById(id);
151 153 if (job == null) {
152 154 return Result.error("定时任务不存在!");
153 155 }
154 156 quartzJobService.pause(job);
155   - return Result.ok("暂停定时任务成功");
  157 + return Result.ok("停止定时任务成功");
156 158 }
157 159  
158 160 /**
... ... @@ -163,7 +165,7 @@ public class QuartzJobController {
163 165 */
164 166 //@RequiresRoles("admin")
165 167 @GetMapping(value = "/resume")
166   - @ApiOperation(value = "恢复定时任务")
  168 + @ApiOperation(value = "启动定时任务")
167 169 public Result<Object> resumeJob(@RequestParam(name = "id") String id) {
168 170 QuartzJob job = quartzJobService.getById(id);
169 171 if (job == null) {
... ... @@ -171,7 +173,7 @@ public class QuartzJobController {
171 173 }
172 174 quartzJobService.resumeJob(job);
173 175 //scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
174   - return Result.ok("恢复定时任务成功");
  176 + return Result.ok("启动定时任务成功");
175 177 }
176 178  
177 179 /**
... ... @@ -202,8 +204,12 @@ public class QuartzJobController {
202 204 // 导出文件名称
203 205 mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表");
204 206 mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class);
205   - mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:Jeecg", "导出信息"));
206   - mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
  207 + //获取当前登录用户
  208 + //update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
  209 + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
  210 + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息"));
  211 + //update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
  212 + mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
207 213 return mv;
208 214 }
209 215  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java
... ... @@ -17,7 +17,7 @@ public class SampleJob implements Job {
17 17  
18 18 @Override
19 19 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
20   -
  20 + log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
21 21 log.info(String.format(" Jeecg-Boot 普通定时任务 SampleJob ! 时间:" + DateUtils.getTimestamp()));
22 22 }
23 23 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/DuplicateCheckController.java
... ... @@ -47,6 +47,15 @@ public class DuplicateCheckController {
47 47 //SQL注入校验(只限制非法串改数据库)
48 48 final String[] sqlInjCheck = {duplicateCheckVo.getTableName(),duplicateCheckVo.getFieldName()};
49 49 SqlInjectionUtil.filterContent(sqlInjCheck);
  50 + // update-begin-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
  51 + if(StringUtils.isEmpty(duplicateCheckVo.getFieldVal())){
  52 + Result rs = new Result();
  53 + rs.setCode(500);
  54 + rs.setSuccess(true);
  55 + rs.setMessage("数据为空,不作处理!");
  56 + return rs;
  57 + }
  58 + // update-end-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志
50 59 if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
51 60 // [2].编辑页面校验
52 61 num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.util.RandomUtil;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.aliyuncs.exceptions.ClientException;
6 6 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  7 +import com.baomidou.mybatisplus.core.toolkit.IdWorker;
7 8 import io.swagger.annotations.Api;
8 9 import io.swagger.annotations.ApiOperation;
9 10 import lombok.extern.slf4j.Slf4j;
... ... @@ -58,8 +59,6 @@ public class LoginController {
58 59 @Resource
59 60 private BaseCommonService baseCommonService;
60 61  
61   - private static final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
62   -
63 62 @ApiOperation("登录接口")
64 63 @RequestMapping(value = "/login", method = RequestMethod.POST)
65 64 public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
... ... @@ -82,6 +81,7 @@ public class LoginController {
82 81 Object checkCode = redisUtil.get(realKey);
83 82 //当进入登录页时,有一定几率出现验证码错误 #1714
84 83 if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
  84 + log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
85 85 result.error500("验证码错误");
86 86 return result;
87 87 }
... ... @@ -402,7 +402,10 @@ public class LoginController {
402 402 // update-begin--Author:sunjianlei Date:20210802 for:获取用户租户信息
403 403 String tenantIds = sysUser.getRelTenantIds();
404 404 if (oConvertUtils.isNotEmpty(tenantIds)) {
405   - List<String> tenantIdList = Arrays.asList(tenantIds.split(","));
  405 + List<Integer> tenantIdList = new ArrayList<>();
  406 + for(String id: tenantIds.split(",")){
  407 + tenantIdList.add(Integer.valueOf(id));
  408 + }
406 409 // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
407 410 List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
408 411 if (tenantList.size() == 0) {
... ... @@ -450,10 +453,17 @@ public class LoginController {
450 453 public Result<String> randomImage(HttpServletResponse response,@PathVariable String key){
451 454 Result<String> res = new Result<String>();
452 455 try {
  456 + //生成验证码
  457 + final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
453 458 String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
  459 +
  460 + //存到redis中
454 461 String lowerCaseCode = code.toLowerCase();
455 462 String realKey = MD5Util.MD5Encode(lowerCaseCode+key, "utf-8");
  463 + log.info("获取验证码,Redis checkCode = {},key = {}", code, key);
456 464 redisUtil.set(realKey, lowerCaseCode, 60);
  465 +
  466 + //返回前端
457 467 String base64 = RandImageUtil.generate(code);
458 468 res.setSuccess(true);
459 469 res.setResult(base64);
... ... @@ -495,13 +505,16 @@ public class LoginController {
495 505 if(oConvertUtils.isEmpty(orgCode)) {
496 506 //如果当前用户无选择部门 查看部门关联信息
497 507 List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
  508 + //update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
498 509 if (departs == null || departs.size() == 0) {
499   - result.error500("用户暂未归属部门,不可登录!");
500   - return result;
  510 + /*result.error500("用户暂未归属部门,不可登录!");
  511 + return result;*/
  512 + }else{
  513 + orgCode = departs.get(0).getOrgCode();
  514 + sysUser.setOrgCode(orgCode);
  515 + this.sysUserService.updateUserDepart(username, orgCode);
501 516 }
502   - orgCode = departs.get(0).getOrgCode();
503   - sysUser.setOrgCode(orgCode);
504   - this.sysUserService.updateUserDepart(username, orgCode);
  517 + //update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
505 518 }
506 519 JSONObject obj = new JSONObject();
507 520 //用户登录信息
... ... @@ -542,5 +555,58 @@ public class LoginController {
542 555 }
543 556 return Result.ok();
544 557 }
  558 + /**
  559 + * 登录二维码
  560 + */
  561 + @ApiOperation(value = "登录二维码", notes = "登录二维码")
  562 + @GetMapping("/getLoginQrcode")
  563 + public Result<?> getLoginQrcode() {
  564 + String qrcodeId = CommonConstant.LOGIN_QRCODE_PRE+IdWorker.getIdStr();
  565 + //定义二维码参数
  566 + Map params = new HashMap(5);
  567 + params.put("qrcodeId", qrcodeId);
  568 + //存放二维码唯一标识30秒有效
  569 + redisUtil.set(CommonConstant.LOGIN_QRCODE + qrcodeId, qrcodeId, 30);
  570 + return Result.OK(params);
  571 + }
  572 + /**
  573 + * 扫码二维码
  574 + */
  575 + @ApiOperation(value = "扫码登录二维码", notes = "扫码登录二维码")
  576 + @PostMapping("/scanLoginQrcode")
  577 + public Result<?> scanLoginQrcode(@RequestParam String qrcodeId, @RequestParam String token) {
  578 + Object check = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
  579 + if (oConvertUtils.isNotEmpty(check)) {
  580 + //存放token给前台读取
  581 + redisUtil.set(CommonConstant.LOGIN_QRCODE_TOKEN+qrcodeId, token, 60);
  582 + } else {
  583 + return Result.error("二维码已过期,请刷新后重试");
  584 + }
  585 + return Result.OK("扫码成功");
  586 + }
  587 +
  588 +
  589 + /**
  590 + * 获取用户扫码后保存的token
  591 + */
  592 + @ApiOperation(value = "获取用户扫码后保存的token", notes = "获取用户扫码后保存的token")
  593 + @GetMapping("/getQrcodeToken")
  594 + public Result getQrcodeToken(@RequestParam String qrcodeId) {
  595 + Object token = redisUtil.get(CommonConstant.LOGIN_QRCODE_TOKEN + qrcodeId);
  596 + Map result = new HashMap();
  597 + Object qrcodeIdExpire = redisUtil.get(CommonConstant.LOGIN_QRCODE + qrcodeId);
  598 + if (oConvertUtils.isEmpty(qrcodeIdExpire)) {
  599 + //二维码过期通知前台刷新
  600 + result.put("token", "-2");
  601 + return Result.OK(result);
  602 + }
  603 + if (oConvertUtils.isNotEmpty(token)) {
  604 + result.put("success", true);
  605 + result.put("token", token);
  606 + } else {
  607 + result.put("token", "-1");
  608 + }
  609 + return Result.OK(result);
  610 + }
545 611  
546 612 }
547 613 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/MockVue3Controller.java deleted
1   -package org.jeecg.modules.system.controller;
2   -
3   -import lombok.extern.slf4j.Slf4j;
4   -import org.jeecg.common.api.vo.Result;
5   -import org.jeecg.modules.system.entity.SysUser;
6   -import org.springframework.web.bind.annotation.GetMapping;
7   -import org.springframework.web.bind.annotation.RequestMapping;
8   -import org.springframework.web.bind.annotation.RestController;
9   -
10   -/**
11   - * vue3前端临时接口
12   - */
13   -@RestController
14   -@RequestMapping("/")
15   -@Slf4j
16   -public class MockVue3Controller {
17   -
18   -
19   -}
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java
... ... @@ -14,6 +14,7 @@ import org.jeecg.common.constant.CommonConstant;
14 14 import org.jeecg.common.constant.CommonSendStatus;
15 15 import org.jeecg.common.constant.WebsocketConst;
16 16 import org.jeecg.common.system.api.ISysBaseAPI;
  17 +import org.jeecg.common.system.query.QueryGenerator;
17 18 import org.jeecg.common.system.util.JwtUtil;
18 19 import org.jeecg.common.system.vo.LoginUser;
19 20 import org.jeecg.common.util.RedisUtil;
... ... @@ -93,18 +94,21 @@ public class SysAnnouncementController {
93 94 HttpServletRequest req) {
94 95 Result<IPage<SysAnnouncement>> result = new Result<IPage<SysAnnouncement>>();
95 96 sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
96   - QueryWrapper<SysAnnouncement> queryWrapper = new QueryWrapper<SysAnnouncement>(sysAnnouncement);
  97 + QueryWrapper<SysAnnouncement> queryWrapper = QueryGenerator.initQueryWrapper(sysAnnouncement, req.getParameterMap());
97 98 Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
  99 +
  100 + //update-begin-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC;故注释此段代码
98 101 //排序逻辑 处理
99   - String column = req.getParameter("column");
100   - String order = req.getParameter("order");
101   - if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
102   - if("asc".equals(order)) {
103   - queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
104   - }else {
105   - queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
106   - }
107   - }
  102 +// String column = req.getParameter("column");
  103 +// String order = req.getParameter("order");
  104 +// if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
  105 +// if("asc".equals(order)) {
  106 +// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
  107 +// }else {
  108 +// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
  109 +// }
  110 +// }
  111 + //update-end-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC;故注释此段代码
108 112 IPage<SysAnnouncement> pageList = sysAnnouncementService.page(page, queryWrapper);
109 113 result.setSuccess(true);
110 114 result.setResult(pageList);
... ... @@ -337,11 +341,13 @@ public class SysAnnouncementController {
337 341 query.eq(SysAnnouncementSend::getUserId,userId);
338 342 SysAnnouncementSend one = sysAnnouncementSendService.getOne(query);
339 343 if(null==one){
340   - SysAnnouncementSend announcementSend = new SysAnnouncementSend();
341   - announcementSend.setAnntId(announcements.get(i).getId());
342   - announcementSend.setUserId(userId);
343   - announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
344   - sysAnnouncementSendService.save(announcementSend);
  344 + log.info("listByUser接口新增了SysAnnouncementSend:pageSize{}:"+pageSize);
  345 + SysAnnouncementSend announcementSend = new SysAnnouncementSend();
  346 + announcementSend.setAnntId(announcements.get(i).getId());
  347 + announcementSend.setUserId(userId);
  348 + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
  349 + sysAnnouncementSendService.save(announcementSend);
  350 + log.info("announcementSend.toString()",announcementSend.toString());
345 351 }
346 352 //update-end--Author:wangshuai Date:20200803 for: 通知公告消息重复LOWCOD-759------------
347 353 }
... ... @@ -373,7 +379,7 @@ public class SysAnnouncementController {
373 379 LambdaQueryWrapper<SysAnnouncement> queryWrapper = new LambdaQueryWrapper<SysAnnouncement>(sysAnnouncement);
374 380 //Step.2 AutoPoi 导出Excel
375 381 ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
376   - queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0);
  382 + queryWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
377 383 List<SysAnnouncement> pageList = sysAnnouncementService.list(queryWrapper);
378 384 //导出文件名称
379 385 mv.addObject(NormalExcelConstants.FILE_NAME, "系统通告列表");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java
... ... @@ -10,6 +10,7 @@ import org.jeecg.common.api.vo.Result;
10 10 import org.jeecg.common.constant.CommonConstant;
11 11 import org.jeecg.common.constant.WebsocketConst;
12 12 import org.jeecg.common.system.vo.LoginUser;
  13 +import org.jeecg.common.util.SqlInjectionUtil;
13 14 import org.jeecg.common.util.oConvertUtils;
14 15 import org.jeecg.modules.message.websocket.WebSocket;
15 16 import org.jeecg.modules.system.entity.SysAnnouncementSend;
... ... @@ -69,6 +70,11 @@ public class SysAnnouncementSendController {
69 70 //排序逻辑 处理
70 71 String column = req.getParameter("column");
71 72 String order = req.getParameter("order");
  73 +
  74 + //issues/3331 SQL injection vulnerability
  75 + SqlInjectionUtil.filterContent(column);
  76 + SqlInjectionUtil.filterContent(order);
  77 +
72 78 if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
73 79 if("asc".equals(order)) {
74 80 queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java
... ... @@ -9,9 +9,11 @@ import lombok.extern.slf4j.Slf4j;
9 9 import org.apache.commons.lang.StringUtils;
10 10 import org.apache.shiro.SecurityUtils;
11 11 import org.jeecg.common.api.vo.Result;
  12 +import org.jeecg.common.constant.CommonConstant;
12 13 import org.jeecg.common.system.query.QueryGenerator;
13 14 import org.jeecg.common.system.vo.DictModel;
14 15 import org.jeecg.common.system.vo.LoginUser;
  16 +import org.jeecg.common.util.ImportExcelUtil;
15 17 import org.jeecg.common.util.oConvertUtils;
16 18 import org.jeecg.modules.system.entity.SysCategory;
17 19 import org.jeecg.modules.system.model.TreeSelectModel;
... ... @@ -65,10 +67,16 @@ public class SysCategoryController {
65 67 Result<IPage<SysCategory>> result = new Result<IPage<SysCategory>>();
66 68  
67 69 //--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------start
68   - //QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
69   - QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
70   - queryWrapper.eq("pid", sysCategory.getPid());
71   - //--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------end
  70 + //--author:liusq---date:20211119 -----for: 【vue3】分类字典页面查询条件配置--------start
  71 + QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap());
  72 + String name = sysCategory.getName();
  73 + String code = sysCategory.getCode();
  74 + //QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<SysCategory>();
  75 + if(StringUtils.isBlank(name)&&StringUtils.isBlank(code)){
  76 + queryWrapper.eq("pid", sysCategory.getPid());
  77 + }
  78 + //--author:liusq---date:20211119 -----for: 分类字典页面查询条件配置--------end
  79 + //--author:os_chengtgen---date:20190804 -----for:【vue3】 分类字典页面显示错误,issues:377--------end
72 80  
73 81 Page<SysCategory> page = new Page<SysCategory>(pageNo, pageSize);
74 82 IPage<SysCategory> pageList = sysCategoryService.page(page, queryWrapper);
... ... @@ -215,10 +223,13 @@ public class SysCategoryController {
215 223 * @return
216 224 */
217 225 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
218   - public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
  226 + public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException{
219 227 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
220 228 Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
221   - for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
  229 + // 错误信息
  230 + List<String> errorMessage = new ArrayList<>();
  231 + int successLines = 0, errorLines = 0;
  232 + for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
222 233 MultipartFile file = entity.getValue();// 获取上传文件对象
223 234 ImportParams params = new ImportParams();
224 235 params.setTitleRows(2);
... ... @@ -229,7 +240,8 @@ public class SysCategoryController {
229 240 //按照编码长度排序
230 241 Collections.sort(listSysCategorys);
231 242 log.info("排序后的list====>",listSysCategorys);
232   - for (SysCategory sysCategoryExcel : listSysCategorys) {
  243 + for (int i = 0; i < listSysCategorys.size(); i++) {
  244 + SysCategory sysCategoryExcel = listSysCategorys.get(i);
233 245 String code = sysCategoryExcel.getCode();
234 246 if(code.length()>3){
235 247 String pCode = sysCategoryExcel.getCode().substring(0,code.length()-3);
... ... @@ -242,12 +254,25 @@ public class SysCategoryController {
242 254 }else{
243 255 sysCategoryExcel.setPid("0");
244 256 }
245   - sysCategoryService.save(sysCategoryExcel);
  257 + try {
  258 + sysCategoryService.save(sysCategoryExcel);
  259 + successLines++;
  260 + } catch (Exception e) {
  261 + errorLines++;
  262 + String message = e.getMessage().toLowerCase();
  263 + int lineNumber = i + 1;
  264 + // 通过索引名判断出错信息
  265 + if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CATEGORY_CODE)) {
  266 + errorMessage.add("第 " + lineNumber + " 行:分类编码已经存在,忽略导入。");
  267 + } else {
  268 + errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
  269 + log.error(e.getMessage(), e);
  270 + }
  271 + }
246 272 }
247   - return Result.ok("文件导入成功!数据行数:" + listSysCategorys.size());
248 273 } catch (Exception e) {
249   - log.error(e.getMessage(), e);
250   - return Result.error("文件导入失败:"+e.getMessage());
  274 + errorMessage.add("发生异常:" + e.getMessage());
  275 + log.error(e.getMessage(), e);
251 276 } finally {
252 277 try {
253 278 file.getInputStream().close();
... ... @@ -256,7 +281,7 @@ public class SysCategoryController {
256 281 }
257 282 }
258 283 }
259   - return Result.error("文件导入失败!");
  284 + return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
260 285 }
261 286  
262 287  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCheckRuleController.java
... ... @@ -112,7 +112,7 @@ public class SysCheckRuleController extends JeecgController&lt;SysCheckRule, ISysCh
112 112 */
113 113 @AutoLog(value = "编码校验规则-编辑")
114 114 @ApiOperation(value = "编码校验规则-编辑", notes = "编码校验规则-编辑")
115   - @PutMapping(value = "/edit")
  115 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
116 116 public Result edit(@RequestBody SysCheckRule sysCheckRule) {
117 117 sysCheckRuleService.updateById(sysCheckRule);
118 118 return Result.ok("编辑成功!");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java
... ... @@ -14,6 +14,7 @@ import io.swagger.annotations.Api;
14 14 import io.swagger.annotations.ApiOperation;
15 15 import lombok.extern.slf4j.Slf4j;
16 16 import org.apache.commons.lang.StringUtils;
  17 +import org.apache.shiro.authz.annotation.RequiresRoles;
17 18 import org.jeecg.common.api.vo.Result;
18 19 import org.jeecg.common.aspect.annotation.AutoLog;
19 20 import org.jeecg.common.system.base.controller.JeecgController;
... ... @@ -57,6 +58,7 @@ public class SysDataSourceController extends JeecgController&lt;SysDataSource, ISys
57 58 */
58 59 @AutoLog(value = "多数据源管理-分页列表查询")
59 60 @ApiOperation(value = "多数据源管理-分页列表查询", notes = "多数据源管理-分页列表查询")
  61 + //@RequiresRoles("admin")
60 62 @GetMapping(value = "/list")
61 63 public Result<?> queryPageList(
62 64 SysDataSource sysDataSource,
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java
... ... @@ -198,7 +198,7 @@ public class SysDepartController {
198 198 * @return
199 199 */
200 200 //@RequiresRoles({"admin"})
201   - @RequestMapping(value = "/edit", method = RequestMethod.PUT)
  201 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
202 202 @CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
203 203 public Result<SysDepart> edit(@RequestBody SysDepart sysDepart, HttpServletRequest request) {
204 204 String username = JwtUtil.getUserNameByToken(request);
... ... @@ -322,7 +322,7 @@ public class SysDepartController {
322 322 if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
323 323 departIds = user.getDepartIds();
324 324 }
325   - List<SysDepartTreeModel> treeList = this.sysDepartService.searhBy(keyWord,myDeptSearch,departIds);
  325 + List<SysDepartTreeModel> treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds);
326 326 if (treeList == null || treeList.size() == 0) {
327 327 result.setSuccess(false);
328 328 result.setMessage("未查询匹配数据!");
... ... @@ -363,6 +363,8 @@ public class SysDepartController {
363 363  
364 364 /**
365 365 * 通过excel导入数据
  366 + * 部门导入方案1: 通过机构编码来计算出部门的父级ID,维护上下级关系;
  367 + * 部门导入方案2: 你也可以改造下程序,机构编码直接导入,先不设置父ID;全部导入后,写一个sql,补下父ID;
366 368 *
367 369 * @param request
368 370 * @param response
... ... @@ -418,6 +420,11 @@ public class SysDepartController {
418 420 sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
419 421 //update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
420 422 sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
  423 + //update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
  424 + if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
  425 + sysDepart.setOrgCategory("1");
  426 + }
  427 + //update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
421 428 ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
422 429 num++;
423 430 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java
... ... @@ -97,7 +97,7 @@ public class SysDepartPermissionController extends JeecgController&lt;SysDepartPerm
97 97 * @return
98 98 */
99 99 @ApiOperation(value="部门权限表-编辑", notes="部门权限表-编辑")
100   - @PutMapping(value = "/edit")
  100 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
101 101 public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
102 102 sysDepartPermissionService.updateById(sysDepartPermission);
103 103 return Result.ok("编辑成功!");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartRoleController.java
... ... @@ -114,7 +114,7 @@ public class SysDepartRoleController extends JeecgController&lt;SysDepartRole, ISys
114 114 */
115 115 //@RequiresRoles({"admin"})
116 116 @ApiOperation(value="部门角色-编辑", notes="部门角色-编辑")
117   - @PutMapping(value = "/edit")
  117 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
118 118 public Result<?> edit(@RequestBody SysDepartRole sysDepartRole) {
119 119 sysDepartRoleService.updateById(sysDepartRole);
120 120 return Result.ok("编辑成功!");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
... ... @@ -496,7 +496,7 @@ public class SysDictController {
496 496 try {
497 497 //导入Excel格式校验,看匹配的字段文本概率
498 498 Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), SysDictPage.class, params);
499   - if(!t){
  499 + if(t!=null && !t){
500 500 throw new RuntimeException("导入Excel校验失败 !");
501 501 }
502 502 List<SysDictPage> list = ExcelImportUtil.importExcel(file.getInputStream(), SysDictPage.class, params);
... ... @@ -511,11 +511,22 @@ public class SysDictController {
511 511 Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList());
512 512 if(integer>0){
513 513 successLines++;
514   - }else{
  514 + //update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
  515 + }else if(integer == -1){
  516 + errorLines++;
  517 + errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。");
  518 + }else{
  519 + //update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
515 520 errorLines++;
516 521 int lineNumber = i + 1;
517   - errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
518   - }
  522 + //update-begin---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
  523 + if(oConvertUtils.isEmpty(po.getDictCode())){
  524 + errorMessage.add("第 " + lineNumber + " 行:字典编码不能为空,忽略导入。");
  525 + }else{
  526 + errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
  527 + }
  528 + //update-end---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
  529 + }
519 530 } catch (Exception e) {
520 531 errorLines++;
521 532 int lineNumber = i + 1;
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysFillRuleController.java
... ... @@ -93,7 +93,7 @@ public class SysFillRuleController extends JeecgController&lt;SysFillRule, ISysFill
93 93 */
94 94 @AutoLog(value = "填值规则-编辑")
95 95 @ApiOperation(value = "填值规则-编辑", notes = "填值规则-编辑")
96   - @PutMapping(value = "/edit")
  96 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
97 97 public Result<?> edit(@RequestBody SysFillRule sysFillRule) {
98 98 sysFillRuleService.updateById(sysFillRule);
99 99 return Result.ok("编辑成功!");
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
... ... @@ -59,7 +59,7 @@ public class SysPermissionController {
59 59  
60 60 /**
61 61 * 加载数据节点
62   - *
  62 + *
63 63 * @return
64 64 */
65 65 @RequestMapping(value = "/list", method = RequestMethod.GET)
... ... @@ -200,7 +200,7 @@ public class SysPermissionController {
200 200  
201 201 /**
202 202 * 查询用户拥有的菜单权限和按钮权限
203   - *
  203 + *
204 204 * @return
205 205 */
206 206 @RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET)
... ... @@ -261,32 +261,49 @@ public class SysPermissionController {
261 261 }
262 262  
263 263 /**
264   - * 【vue3专用】查询用户拥有的按钮/表单访问权限
265   - * @return
  264 + * 【vue3专用】获取
  265 + * 1、查询用户拥有的按钮/表单访问权限
  266 + * 2、所有权限 (菜单权限配置)
  267 + * 3、系统安全模式 (开启则online报表的数据源必填)
266 268 */
267 269 @RequestMapping(value = "/getPermCode", method = RequestMethod.GET)
268 270 public Result<?> getPermCode() {
269   - Result<List<String>> result = new Result<List<String>>();
270 271 try {
271   - //直接获取当前用户
  272 + // 直接获取当前用户
272 273 LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
273   - //获取当前用户的权限集合
  274 + if (oConvertUtils.isEmpty(loginUser)) {
  275 + return Result.error("请登录系统!");
  276 + }
  277 + // 获取当前用户的权限集合
274 278 List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
  279 + // 按钮权限(用户拥有的权限集合)
  280 + List<String> codeList = metaList.stream()
  281 + .filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
  282 + .collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
  283 + //
  284 + JSONArray authArray = new JSONArray();
  285 + this.getAuthJsonArray(authArray, metaList);
  286 + // 查询所有的权限
  287 + LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
  288 + query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
  289 + query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
  290 + List<SysPermission> allAuthList = sysPermissionService.list(query);
  291 + JSONArray allAuthArray = new JSONArray();
  292 + this.getAllAuthJsonArray(allAuthArray, allAuthList);
  293 + JSONObject result = new JSONObject();
  294 + // 所拥有的权限编码
  295 + result.put("codeList", codeList);
275 296 //按钮权限(用户拥有的权限集合)
276   - List<String> authList = metaList.stream()
277   - .filter((permission) -> permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)
278   - && CommonConstant.STATUS_1.equals(permission.getStatus())
279   - )
280   - .collect(() -> new ArrayList<String>(),
281   - (list, permission) -> list.add(permission.getPerms()),
282   - (list1, list2) -> list1.addAll(list2)
283   - );
284   - result.setResult(authList);
  297 + result.put("auth", authArray);
  298 + //全部权限配置集合(按钮权限,访问权限)
  299 + result.put("allAuth", allAuthArray);
  300 + // 系统安全模式
  301 + result.put("sysSafeMode", jeeccgBaseConfig.getSafeMode());
  302 + return Result.OK(result);
285 303 } catch (Exception e) {
286   - result.error500("查询失败:" + e.getMessage());
287 304 log.error(e.getMessage(), e);
  305 + return Result.error("查询失败:" + e.getMessage());
288 306 }
289   - return result;
290 307 }
291 308  
292 309 /**
... ... @@ -374,7 +391,7 @@ public class SysPermissionController {
374 391  
375 392 /**
376 393 * 获取全部的权限树
377   - *
  394 + *
378 395 * @return
379 396 */
380 397 @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
... ... @@ -720,7 +737,7 @@ public class SysPermissionController {
720 737 /**
721 738 * 判断是否外网URL 例如: http://localhost:8080/jeecg-boot/swagger-ui.html#/ 支持特殊格式: {{
722 739 * window._CONFIG['domianURL'] }}/druid/ {{ JS代码片段 }},前台解析会自动执行JS代码片段
723   - *
  740 + *
724 741 * @return
725 742 */
726 743 private boolean isWWWHttpUrl(String url) {
... ... @@ -733,7 +750,7 @@ public class SysPermissionController {
733 750 /**
734 751 * 通过URL生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-) 举例: URL = /isystem/role RouteName =
735 752 * isystem-role
736   - *
  753 + *
737 754 * @return
738 755 */
739 756 private String urlToRouteName(String url) {
... ... @@ -753,7 +770,7 @@ public class SysPermissionController {
753 770  
754 771 /**
755 772 * 根据菜单id来获取其对应的权限数据
756   - *
  773 + *
757 774 * @param sysPermissionDataRule
758 775 * @return
759 776 */
... ... @@ -768,7 +785,7 @@ public class SysPermissionController {
768 785  
769 786 /**
770 787 * 添加菜单权限数据
771   - *
  788 + *
772 789 * @param sysPermissionDataRule
773 790 * @return
774 791 */
... ... @@ -803,7 +820,7 @@ public class SysPermissionController {
803 820  
804 821 /**
805 822 * 删除菜单权限数据
806   - *
  823 + *
807 824 * @param id
808 825 * @return
809 826 */
... ... @@ -823,7 +840,7 @@ public class SysPermissionController {
823 840  
824 841 /**
825 842 * 查询菜单权限数据
826   - *
  843 + *
827 844 * @param sysPermissionDataRule
828 845 * @return
829 846 */
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java
... ... @@ -8,10 +8,12 @@ import io.swagger.annotations.Api;
8 8 import io.swagger.annotations.ApiOperation;
9 9 import lombok.extern.slf4j.Slf4j;
10 10 import org.apache.poi.ss.formula.functions.T;
  11 +import org.apache.shiro.SecurityUtils;
11 12 import org.jeecg.common.api.vo.Result;
12 13 import org.jeecg.common.aspect.annotation.AutoLog;
13 14 import org.jeecg.common.constant.CommonConstant;
14 15 import org.jeecg.common.system.query.QueryGenerator;
  16 +import org.jeecg.common.system.vo.LoginUser;
15 17 import org.jeecg.common.util.ImportExcelUtil;
16 18 import org.jeecg.common.util.oConvertUtils;
17 19 import org.jeecg.modules.quartz.service.IQuartzJobService;
... ... @@ -208,10 +210,11 @@ public class SysPositionController {
208 210 //Step.2 AutoPoi 导出Excel
209 211 ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
210 212 List<SysPosition> pageList = sysPositionService.list(queryWrapper);
  213 + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
211 214 //导出文件名称
212 215 mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表");
213 216 mv.addObject(NormalExcelConstants.CLASS, SysPosition.class);
214   - mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:Jeecg", "导出信息"));
  217 + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:"+user.getRealname(),"导出信息"));
215 218 mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
216 219 return mv;
217 220 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java
... ... @@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
6 6 import com.baomidou.mybatisplus.core.metadata.IPage;
7 7 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
8 8 import lombok.extern.slf4j.Slf4j;
  9 +import org.apache.shiro.SecurityUtils;
9 10 import org.jeecg.common.api.vo.Result;
10 11 import org.jeecg.common.aspect.annotation.PermissionData;
11 12 import org.jeecg.common.system.query.QueryGenerator;
  13 +import org.jeecg.common.system.vo.LoginUser;
12 14 import org.jeecg.common.util.oConvertUtils;
13 15 import org.jeecg.modules.system.entity.SysTenant;
14 16 import org.jeecg.modules.system.service.ISysTenantService;
... ... @@ -16,9 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
16 18 import org.springframework.web.bind.annotation.*;
17 19  
18 20 import javax.servlet.http.HttpServletRequest;
19   -import java.util.ArrayList;
20   -import java.util.Date;
21   -import java.util.List;
  21 +import java.util.*;
22 22  
23 23 /**
24 24 * 租户配置信息
... ... @@ -132,11 +132,11 @@ public class SysTenantController {
132 132 }else {
133 133 String[] ls = ids.split(",");
134 134 // 过滤掉已被引用的租户
135   - List<String> idList = new ArrayList<>();
  135 + List<Integer> idList = new ArrayList<>();
136 136 for (String id : ls) {
137 137 int userCount = sysTenantService.countUserLinkTenant(id);
138 138 if (userCount == 0) {
139   - idList.add(id);
  139 + idList.add(Integer.parseInt(id));
140 140 }
141 141 }
142 142 if (idList.size() > 0) {
... ... @@ -190,4 +190,32 @@ public class SysTenantController {
190 190 result.setResult(ls);
191 191 return result;
192 192 }
  193 + /**
  194 + * 查询当前用户的所有有效租户 【当前用于vue3版本】
  195 + * @return
  196 + */
  197 + @RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET)
  198 + public Result<Map<String,Object>> getCurrentUserTenant() {
  199 + Result<Map<String,Object>> result = new Result<Map<String,Object>>();
  200 + try {
  201 + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
  202 + String tenantIds = sysUser.getRelTenantIds();
  203 + Map<String,Object> map = new HashMap<String,Object>();
  204 + if (oConvertUtils.isNotEmpty(tenantIds)) {
  205 + List<Integer> tenantIdList = new ArrayList<>();
  206 + for(String id: tenantIds.split(",")){
  207 + tenantIdList.add(Integer.valueOf(id));
  208 + }
  209 + // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
  210 + List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
  211 + map.put("list", tenantList);
  212 + }
  213 + result.setSuccess(true);
  214 + result.setResult(map);
  215 + }catch(Exception e) {
  216 + log.error(e.getMessage(), e);
  217 + result.error500("查询失败!");
  218 + }
  219 + return result;
  220 + }
193 221 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java
... ... @@ -108,12 +108,38 @@ public class SysUserController {
108 108 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
109 109 Result<IPage<SysUser>> result = new Result<IPage<SysUser>>();
110 110 QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(user, req.getParameterMap());
111   - //TODO 外部模拟登陆临时账号,列表不显示
  111 +
  112 + //update-begin-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
  113 + //部门ID
  114 + String departId = req.getParameter("departId");
  115 + if(oConvertUtils.isNotEmpty(departId)){
  116 + LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
  117 + query.eq(SysUserDepart::getDepId,departId);
  118 + List<SysUserDepart> list = sysUserDepartService.list(query);
  119 + List<String> userIds = list.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
  120 + queryWrapper.in("id",userIds);
  121 + }
  122 + //用户ID
  123 + String code = req.getParameter("code");
  124 + if(oConvertUtils.isNotEmpty(code)){
  125 + queryWrapper.in("id",Arrays.asList(code.split(",")));
  126 + pageSize = code.split(",").length;
  127 + }
  128 + //update-end-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
  129 +
  130 + //update-begin-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
  131 + String status = req.getParameter("status");
  132 + if(oConvertUtils.isNotEmpty(status)){
  133 + queryWrapper.eq("status", Integer.parseInt(status));
  134 + }
  135 + //update-end-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
  136 +
  137 + //TODO 外部模拟登陆临时账号,列表不显示
112 138 queryWrapper.ne("username","_reserve_user_external");
113 139 Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
114 140 IPage<SysUser> pageList = sysUserService.page(page, queryWrapper);
115 141  
116   - //批量查询用户的所属部门
  142 + //批量查询用户的所属部门
117 143 //step.1 先拿到全部的 useids
118 144 //step.2 通过 useids,一次性查询用户的所属部门名字
119 145 List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
... ... @@ -492,6 +518,8 @@ public class SysUserController {
492 518 errorMessage.add("第 " + lineNumber + " 行:手机号已经存在,忽略导入。");
493 519 } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) {
494 520 errorMessage.add("第 " + lineNumber + " 行:电子邮件已经存在,忽略导入。");
  521 + } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) {
  522 + errorMessage.add("第 " + lineNumber + " 行:违反表唯一性约束。");
495 523 } else {
496 524 errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
497 525 log.error(e.getMessage(), e);
... ... @@ -1187,7 +1215,7 @@ public class SysUserController {
1187 1215 * @param jsonObject
1188 1216 * @return
1189 1217 */
1190   - @RequestMapping(value = "/appEdit", method = RequestMethod.PUT)
  1218 + @RequestMapping(value = "/appEdit", method = {RequestMethod.PUT,RequestMethod.POST})
1191 1219 public Result<SysUser> appEdit(HttpServletRequest request,@RequestBody JSONObject jsonObject) {
1192 1220 Result<SysUser> result = new Result<SysUser>();
1193 1221 try {
... ... @@ -1305,7 +1333,9 @@ public class SysUserController {
1305 1333 * @return
1306 1334 */
1307 1335 @GetMapping("/appQueryUser")
1308   - public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword) {
  1336 + public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword,
  1337 + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
  1338 + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
1309 1339 Result<List<SysUser>> result = new Result<List<SysUser>>();
1310 1340 LambdaQueryWrapper<SysUser> queryWrapper =new LambdaQueryWrapper<SysUser>();
1311 1341 //TODO 外部模拟登陆临时账号,列表不显示
... ... @@ -1313,18 +1343,19 @@ public class SysUserController {
1313 1343 if(StringUtils.isNotBlank(keyword)){
1314 1344 queryWrapper.and(i -> i.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname, keyword));
1315 1345 }
1316   - List<SysUser> list = sysUserService.list(queryWrapper);
  1346 + Page<SysUser> page = new Page<>(pageNo, pageSize);
  1347 + IPage<SysUser> pageList = this.sysUserService.page(page, queryWrapper);
1317 1348 //批量查询用户的所属部门
1318 1349 //step.1 先拿到全部的 useids
1319 1350 //step.2 通过 useids,一次性查询用户的所属部门名字
1320   - List<String> userIds = list.stream().map(SysUser::getId).collect(Collectors.toList());
  1351 + List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
1321 1352 if(userIds!=null && userIds.size()>0){
1322 1353 Map<String,String> useDepNames = sysUserService.getDepNamesByUserIds(userIds);
1323   - list.forEach(item->{
  1354 + pageList.getRecords().forEach(item->{
1324 1355 item.setOrgCodeTxt(useDepNames.get(item.getId()));
1325 1356 });
1326 1357 }
1327   - result.setResult(list);
  1358 + result.setResult(pageList.getRecords());
1328 1359 return result;
1329 1360 }
1330 1361  
... ... @@ -1374,6 +1405,9 @@ public class SysUserController {
1374 1405 @GetMapping("/getMultiUser")
1375 1406 public List<SysUser> getMultiUser(SysUser sysUser){
1376 1407 QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(sysUser, null);
  1408 + //update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
  1409 + queryWrapper.eq("status",Integer.parseInt(CommonConstant.STATUS_1));
  1410 + //update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
1377 1411 List<SysUser> ls = this.sysUserService.list(queryWrapper);
1378 1412 for(SysUser user: ls){
1379 1413 user.setPassword(null);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java
1 1 package org.jeecg.modules.system.controller;
2 2  
3   -import java.util.*;
4   -
5   -import javax.annotation.Resource;
  3 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4 +import lombok.extern.slf4j.Slf4j;
6 5 import org.apache.commons.lang.StringUtils;
7 6 import org.apache.shiro.SecurityUtils;
8 7 import org.jeecg.common.api.vo.Result;
... ... @@ -21,9 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired;
21 20 import org.springframework.data.redis.core.RedisTemplate;
22 21 import org.springframework.web.bind.annotation.*;
23 22  
24   -import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
25   -
26   -import lombok.extern.slf4j.Slf4j;
  23 +import javax.annotation.Resource;
  24 +import java.util.ArrayList;
  25 +import java.util.Collection;
  26 +import java.util.Collections;
  27 +import java.util.List;
27 28  
28 29 /**
29 30 * @Description: 在线用户
... ... @@ -63,8 +64,20 @@ public class SysUserOnlineController {
63 64 online.setToken(token);
64 65 //TODO 改成一次性查询
65 66 LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
66   - BeanUtils.copyProperties(loginUser, online);
67   - onlineList.add(online);
  67 + if (loginUser != null) {
  68 + //update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
  69 + //验证用户名是否与传过来的用户名相同
  70 + boolean isMatchUsername=true;
  71 + //判断用户名是否为空,并且当前循环的用户不包含传过来的用户名,那么就设成false
  72 + if(oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)){
  73 + isMatchUsername = false;
  74 + }
  75 + if(isMatchUsername){
  76 + BeanUtils.copyProperties(loginUser, online);
  77 + onlineList.add(online);
  78 + }
  79 + //update-end---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
  80 + }
68 81 }
69 82 }
70 83 Collections.reverse(onlineList);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java
... ... @@ -91,8 +91,12 @@ public class ThirdAppController {
91 91 @GetMapping("/sync/wechatEnterprise/depart/toApp")
92 92 public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
93 93 if (thirdAppConfig.isWechatEnterpriseEnabled()) {
94   - boolean flag = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
95   - return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
  94 + SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
  95 + if (syncInfo.getFailInfo().size() == 0) {
  96 + return Result.OK("同步成功", null);
  97 + } else {
  98 + return Result.error("同步失败", syncInfo);
  99 + }
96 100 }
97 101 return Result.error("企业微信同步功能已禁用");
98 102 }
... ... @@ -125,8 +129,12 @@ public class ThirdAppController {
125 129 @GetMapping("/sync/dingtalk/depart/toApp")
126 130 public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
127 131 if (thirdAppConfig.isDingtalkEnabled()) {
128   - boolean flag = dingtalkService.syncLocalDepartmentToThirdApp(ids);
129   - return flag ? Result.OK("同步成功", null) : Result.error("同步失败");
  132 + SyncInfoVo syncInfo = dingtalkService.syncLocalDepartmentToThirdApp(ids);
  133 + if (syncInfo.getFailInfo().size() == 0) {
  134 + return Result.OK("同步成功", null);
  135 + } else {
  136 + return Result.error("同步失败", syncInfo);
  137 + }
130 138 }
131 139 return Result.error("钉钉同步功能已禁用");
132 140 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysDepart.java
... ... @@ -45,7 +45,7 @@ public class SysDepart implements Serializable {
45 45 /**描述*/
46 46 @Excel(name="描述",width=15)
47 47 private String description;
48   - /**机构类别 1公司,2组织机构,2岗位*/
  48 + /**机构类别 1=公司,2=组织机构,3=岗位*/
49 49 @Excel(name="机构类别",width=15,dicCode="org_category")
50 50 private String orgCategory;
51 51 /**机构类型*/
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysPosition.java
... ... @@ -54,7 +54,6 @@ public class SysPosition {
54 54 /**
55 55 * 公司id
56 56 */
57   - @Excel(name = "公司id", width = 15)
58 57 @ApiModelProperty(value = "公司id")
59 58 private java.lang.String companyId;
60 59 /**
... ... @@ -84,7 +83,6 @@ public class SysPosition {
84 83 /**
85 84 * 组织机构编码
86 85 */
87   - @Excel(name = "组织机构编码", width = 15)
88 86 @ApiModelProperty(value = "组织机构编码")
89 87 private java.lang.String sysOrgCode;
90 88 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysThirdAccount.java
... ... @@ -3,12 +3,14 @@ package org.jeecg.modules.system.entity;
3 3 import com.baomidou.mybatisplus.annotation.IdType;
4 4 import com.baomidou.mybatisplus.annotation.TableId;
5 5 import com.baomidou.mybatisplus.annotation.TableName;
  6 +import com.fasterxml.jackson.annotation.JsonFormat;
6 7 import io.swagger.annotations.ApiModel;
7 8 import io.swagger.annotations.ApiModelProperty;
8 9 import lombok.Data;
9 10 import lombok.EqualsAndHashCode;
10 11 import lombok.experimental.Accessors;
11 12 import org.jeecgframework.poi.excel.annotation.Excel;
  13 +import org.springframework.format.annotation.DateTimeFormat;
12 14  
13 15 /**
14 16 * @Description: 第三方登录账号表
... ... @@ -25,7 +27,7 @@ public class SysThirdAccount {
25 27  
26 28 /**编号*/
27 29 @TableId(type = IdType.ASSIGN_ID)
28   - @ApiModelProperty(value = "编号")
  30 + @ApiModelProperty(value = "编号")
29 31 private java.lang.String id;
30 32 /**第三方登录id*/
31 33 @Excel(name = "第三方登录id", width = 15)
... ... @@ -59,4 +61,20 @@ public class SysThirdAccount {
59 61 @Excel(name = "第三方用户账号", width = 15)
60 62 @ApiModelProperty(value = "第三方用户账号")
61 63 private java.lang.String thirdUserId;
  64 + /**创建人*/
  65 + @Excel(name = "创建人", width = 15)
  66 + private java.lang.String createBy;
  67 + /**创建日期*/
  68 + @Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
  69 + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
  70 + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
  71 + private java.util.Date createTime;
  72 + /**修改人*/
  73 + @Excel(name = "修改人", width = 15)
  74 + private java.lang.String updateBy;
  75 + /**修改日期*/
  76 + @Excel(name = "修改日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
  77 + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
  78 + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
  79 + private java.util.Date updateTime;
62 80 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
... ... @@ -193,4 +193,15 @@ public interface SysDictMapper extends BaseMapper&lt;SysDict&gt; {
193 193 */
194 194 @Deprecated
195 195 List<DictModel> queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql);
  196 +
  197 + /**
  198 + * 查询字典表的数据
  199 + * @param table 表名
  200 + * @param text 显示字段名
  201 + * @param code 存储字段名
  202 + * @param filterSql 条件sql
  203 + * @param codeValues 存储字段值 作为查询条件in
  204 + * @return
  205 + */
  206 + List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql, @Param("codeValues") List<String> codeValues);
196 207 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
... ... @@ -134,19 +134,24 @@
134 134 ${pidField} as parentId
135 135 from ${table}
136 136 where
137   - <choose>
138   - <when test="pid != null and pid != ''">
139   - ${pidField} = #{pid}
140   - </when>
141   - <otherwise>
142   - (${pidField} = '' OR ${pidField} IS NULL)
143   - </otherwise>
144   - </choose>
  137 + <!-- udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
  138 + <if test="query == null">
  139 + <choose>
  140 + <when test="pid != null and pid != ''">
  141 + ${pidField} = #{pid}
  142 + </when>
  143 + <otherwise>
  144 + (${pidField} = '' OR ${pidField} IS NULL)
  145 + </otherwise>
  146 + </choose>
  147 + </if>
145 148 <if test="query!= null">
  149 + 1 = 1
146 150 <foreach collection="query.entrySet()" item="value" index="key" >
147   - and ${key} = #{value}
  151 + and ${key} LIKE #{value}
148 152 </foreach>
149 153 </if>
  154 + <!-- udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 -->
150 155 </select>
151 156  
152 157  
... ... @@ -179,5 +184,18 @@
179 184 </select>
180 185  
181 186  
  187 + <!-- 查询字典表的数据 支持设置过滤条件、设置存储值作为in查询条件 -->
  188 + <select id="queryTableDictByKeysAndFilterSql" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
  189 + select ${text} as "text", ${code} as "value" from ${table} where ${code} IN (
  190 + <foreach item="key" collection="codeValues" separator=",">
  191 + #{key}
  192 + </foreach>
  193 + )
  194 + <if test="filterSql != null and filterSql != ''">
  195 + and ${filterSql}
  196 + </if>
  197 + </select>
  198 +
  199 +
182 200  
183 201 </mapper>
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserDepartMapper.xml
... ... @@ -14,7 +14,9 @@
14 14 join sys_depart c on b.dep_id = c.id
15 15 where a.del_flag = 0 and c.org_code like '${orgCode}%'
16 16 <if test="realname!=null and realname!=''">
17   - and a.realname like '%${realname}%'
  17 + <!-- update by sunjianlei 20220119【#3348】SQL injection exists in /sys/user/queryUserByDepId; -->
  18 + <bind name="bindRealname" value="'%'+realname+'%'"/>
  19 + and a.realname like #{bindRealname}
18 20 </if>
19 21 </select>
20 22  
... ... @@ -23,12 +25,14 @@
23 25 select a.*, c.depart_name as org_code_txt from sys_user a
24 26 join sys_user_depart b on b.user_id = a.id
25 27 join sys_depart c on b.dep_id = c.id
26   - where a.del_flag = 0 and c.org_code like '${orgCode}%'
  28 + where a.del_flag = 0 and a.status = 1 and c.org_code like '${orgCode}%'
27 29 <if test="username!=null and username!=''">
28   - and a.username like '%${username}%'
  30 + <bind name="bindUsername" value="'%'+username+'%'"/>
  31 + and a.username like #{bindUsername}
29 32 </if>
30 33 <if test="realname!=null and realname!=''">
31   - and a.realname like '%${realname}%'
  34 + <bind name="bindRealname" value="'%'+realname+'%'"/>
  35 + and a.realname like #{bindRealname}
32 36 </if>
33 37 </select>
34 38 </mapper>
35 39 \ No newline at end of file
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/AnnouncementSendModel.java
1 1 package org.jeecg.modules.system.model;
2 2  
3   -import java.io.Serializable;
4   -
5   -import org.springframework.format.annotation.DateTimeFormat;
6   -
7 3 import com.baomidou.mybatisplus.annotation.IdType;
8 4 import com.baomidou.mybatisplus.annotation.TableId;
9   -import com.baomidou.mybatisplus.annotation.TableName;
10 5 import com.fasterxml.jackson.annotation.JsonFormat;
11   -
12 6 import lombok.Data;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.io.Serializable;
13 10  
14 11 /**
15 12 * @Description: 用户通告阅读标记表
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/rule/CategoryCodeRule.java
... ... @@ -2,6 +2,7 @@ package org.jeecg.modules.system.rule;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5 +import lombok.extern.slf4j.Slf4j;
5 6 import org.jeecg.common.handler.IFillRuleHandler;
6 7 import org.jeecg.common.util.SpringContextUtils;
7 8 import org.jeecg.common.util.YouBianCodeUtil;
... ... @@ -16,12 +17,14 @@ import java.util.List;
16 17 * @Date 2019/12/9 11:32
17 18 * @Description: 分类字典编码生成规则
18 19 */
  20 +@Slf4j
19 21 public class CategoryCodeRule implements IFillRuleHandler {
20 22  
21 23 public static final String ROOT_PID_VALUE = "0";
22 24  
23 25 @Override
24 26 public Object execute(JSONObject params, JSONObject formData) {
  27 + log.info("系统自定义编码规则[category_code_rule],params:{} ,formData: {}", params, formData);
25 28  
26 29 String categoryPid = ROOT_PID_VALUE;
27 30 String categoryCode = null;
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java
... ... @@ -67,7 +67,7 @@ public interface ISysDepartService extends IService&lt;SysDepart&gt;{
67 67 * @param keyWord
68 68 * @return
69 69 */
70   - List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds);
  70 + List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds);
71 71  
72 72 /**
73 73 * 根据部门id删除并删除其可能存在的子级部门
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysTenantService.java
... ... @@ -14,7 +14,7 @@ public interface ISysTenantService extends IService&lt;SysTenant&gt; {
14 14 * @param idList
15 15 * @return
16 16 */
17   - List<SysTenant> queryEffectiveTenant(Collection<String> idList);
  17 + List<SysTenant> queryEffectiveTenant(Collection<Integer> idList);
18 18  
19 19 /**
20 20 * 返回某个租户被多少个用户引用了
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/IThirdAppService.java
... ... @@ -21,7 +21,7 @@ public interface IThirdAppService {
21 21 *
22 22 * @return 成功返回true
23 23 */
24   - boolean syncLocalDepartmentToThirdApp(String ids);
  24 + SyncInfoVo syncLocalDepartmentToThirdApp(String ids);
25 25  
26 26 /**
27 27 * 将第三方App部门同步到本地<br>
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java
... ... @@ -146,7 +146,9 @@ public class SysBaseApiImpl implements ISysBaseAPI {
146 146 //通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制)
147 147 String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
148 148 LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
149   - queryQserMatch.eq(SysPermission::getMenuType, 1);
  149 + // update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
  150 + //queryQserMatch.eq(SysPermission::getMenuType, 1);
  151 + // update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
150 152 queryQserMatch.eq(SysPermission::getDelFlag, 0);
151 153 queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
152 154 if(oConvertUtils.isNotEmpty(userMatchUrl)){
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartPermissionServiceImpl.java
... ... @@ -69,7 +69,7 @@ public class SysDepartPermissionServiceImpl extends ServiceImpl&lt;SysDepartPermiss
69 69 @Override
70 70 public List<SysPermissionDataRule> getPermRuleListByDeptIdAndPermId(String departId, String permissionId) {
71 71 SysDepartPermission departPermission = this.getOne(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId).eq(SysDepartPermission::getPermissionId, permissionId));
72   - if(departPermission != null){
  72 + if(departPermission != null && oConvertUtils.isNotEmpty(departPermission.getDataRuleIds())){
73 73 LambdaQueryWrapper<SysPermissionDataRule> query = new LambdaQueryWrapper<SysPermissionDataRule>();
74 74 query.in(SysPermissionDataRule::getId, Arrays.asList(departPermission.getDataRuleIds().split(",")));
75 75 query.orderByDesc(SysPermissionDataRule::getCreateTime);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java
... ... @@ -300,7 +300,7 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
300 300 * </p>
301 301 */
302 302 @Override
303   - public List<SysDepartTreeModel> searhBy(String keyWord,String myDeptSearch,String departIds) {
  303 + public List<SysDepartTreeModel> searchByKeyWord(String keyWord,String myDeptSearch,String departIds) {
304 304 LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
305 305 List<SysDepartTreeModel> newList = new ArrayList<>();
306 306 //myDeptSearch不为空时为我的部门搜索,只搜索所负责部门
... ... @@ -311,9 +311,15 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
311 311 }
312 312 //根据部门id获取所负责部门
313 313 String[] codeArr = this.getMyDeptParentOrgCode(departIds);
314   - for(int i=0;i<codeArr.length;i++){
315   - query.or().likeRight(SysDepart::getOrgCode,codeArr[i]);
  314 + //update-begin-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
  315 + if (codeArr != null && codeArr.length > 0) {
  316 + query.nested(i -> {
  317 + for (String s : codeArr) {
  318 + i.or().likeRight(SysDepart::getOrgCode, s);
  319 + }
  320 + });
316 321 }
  322 + //update-end-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
317 323 query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
318 324 }
319 325 query.like(SysDepart::getDepartName, keyWord);
... ... @@ -499,7 +505,7 @@ public class SysDepartServiceImpl extends ServiceImpl&lt;SysDepartMapper, SysDepart
499 505 }
500 506 };
501 507 LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper();
502   - lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0);
  508 + lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
503 509 lqw.func(square);
504 510 lqw.orderByDesc(SysDepart::getDepartOrder);
505 511 List<SysDepart> list = list(lqw);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java
... ... @@ -163,7 +163,15 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
163 163  
164 164 @Override
165 165 public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) {
166   - return sysDictMapper.queryTableDictTextByKeys(table, text, code, keys);
  166 + //update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
  167 + String filterSql = null;
  168 + if(table.toLowerCase().indexOf("where")>0){
  169 + String[] arr = table.split(" (?i)where ");
  170 + table = arr[0];
  171 + filterSql = arr[1];
  172 + }
  173 + return sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, keys);
  174 + //update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
167 175 }
168 176  
169 177 @Override
... ... @@ -225,6 +233,11 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
225 233 insert = sysDictMapper.insert(sysDict);
226 234 if (sysDictItemList != null) {
227 235 for (SysDictItem entity : sysDictItemList) {
  236 + //update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
  237 + if(oConvertUtils.isEmpty(entity.getItemValue())){
  238 + return -1;
  239 + }
  240 + //update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
228 241 entity.setDictId(sysDict.getId());
229 242 entity.setStatus(1);
230 243 sysDictItemMapper.insert(entity);
... ... @@ -255,7 +268,7 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
255 268 public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) {
256 269 Page<DictModel> page = new Page<DictModel>(1, pageSize);
257 270 page.setSearchCount(false);
258   - String filterSql = getFilterSql(text, code, condition, keyword);
  271 + String filterSql = getFilterSql(table, text, code, condition, keyword);
259 272 IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql);
260 273 return pageList.getRecords();
261 274 }
... ... @@ -268,12 +281,19 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
268 281 * @param keyword
269 282 * @return
270 283 */
271   - private String getFilterSql(String text, String code, String condition, String keyword){
  284 + private String getFilterSql(String table, String text, String code, String condition, String keyword){
272 285 String keywordSql = null, filterSql = "", sql_where = " where ";
  286 + // update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
  287 + if (table.toLowerCase().contains(" where ")) {
  288 + sql_where = " and ";
  289 + }
  290 + // update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
273 291 if(oConvertUtils.isNotEmpty(keyword)){
274 292 // 判断是否是多选
275 293 if (keyword.contains(",")) {
276   - String inKeywords = "\"" + keyword.replaceAll(",", "\",\"") + "\"";
  294 + //update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
  295 + String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
  296 + //update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
277 297 keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
278 298 } else {
279 299 keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
... ... @@ -290,14 +310,20 @@ public class SysDictServiceImpl extends ServiceImpl&lt;SysDictMapper, SysDict&gt; impl
290 310 }
291 311 @Override
292 312 public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword) {
293   - String filterSql = getFilterSql(text, code, condition, keyword);
  313 + String filterSql = getFilterSql(table, text, code, condition, keyword);
294 314 List<DictModel> ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql);
295 315 return ls;
296 316 }
297 317  
298 318 @Override
299 319 public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
300   - return baseMapper.queryTreeList(query,table, text, code, pidField, pid,hasChildField);
  320 + List<TreeSelectModel> result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
  321 + // udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
  322 + if (query != null) {
  323 + result.forEach(r -> r.setLeaf(true));
  324 + }
  325 + return result;
  326 + // udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点
301 327 }
302 328  
303 329 @Override
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysTenantServiceImpl.java
... ... @@ -24,10 +24,10 @@ public class SysTenantServiceImpl extends ServiceImpl&lt;SysTenantMapper, SysTenant
24 24 ISysUserService userService;
25 25  
26 26 @Override
27   - public List<SysTenant> queryEffectiveTenant(Collection<String> idList) {
  27 + public List<SysTenant> queryEffectiveTenant(Collection<Integer> idList) {
28 28 LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
29 29 queryWrapper.in(SysTenant::getId, idList);
30   - queryWrapper.eq(SysTenant::getStatus, CommonConstant.STATUS_1);
  30 + queryWrapper.eq(SysTenant::getStatus, Integer.valueOf(CommonConstant.STATUS_1));
31 31 //此处查询忽略时间条件
32 32 return super.list(queryWrapper);
33 33 }
... ... @@ -50,7 +50,7 @@ public class SysTenantServiceImpl extends ServiceImpl&lt;SysTenantMapper, SysTenant
50 50 if (userCount > 0) {
51 51 throw new JeecgBootException("该租户已被引用,无法删除!");
52 52 }
53   - return super.removeById(id);
  53 + return super.removeById(Integer.parseInt(id));
54 54 }
55 55  
56 56 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysThirdAccountServiceImpl.java
... ... @@ -2,6 +2,7 @@ package org.jeecg.modules.system.service.impl;
2 2  
3 3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 4 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5 +import lombok.extern.slf4j.Slf4j;
5 6 import org.jeecg.common.constant.CommonConstant;
6 7 import org.jeecg.common.util.DateUtils;
7 8 import org.jeecg.common.util.PasswordUtil;
... ... @@ -30,6 +31,7 @@ import java.util.List;
30 31 * @Version: V1.0
31 32 */
32 33 @Service
  34 +@Slf4j
33 35 public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMapper, SysThirdAccount> implements ISysThirdAccountService {
34 36  
35 37 @Autowired
... ... @@ -116,6 +118,7 @@ public class SysThirdAccountServiceImpl extends ServiceImpl&lt;SysThirdAccountMappe
116 118 @Override
117 119 public SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType) {
118 120 LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
  121 + log.info("getSysUserId: {} ,getThirdType: {}",sysUserId,thirdType);
119 122 queryWrapper.eq(SysThirdAccount::getSysUserId, sysUserId);
120 123 queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
121 124 return super.getOne(queryWrapper);
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java
1 1 package org.jeecg.modules.system.service.impl;
2 2  
3   -import java.util.ArrayList;
4   -import java.util.HashMap;
5   -import java.util.List;
6   -import java.util.Map;
7   -import java.util.stream.Collectors;
8   -import java.util.stream.Collectors;
9   -
10   -import com.baomidou.mybatisplus.core.conditions.Wrapper;
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
11 4 import com.baomidou.mybatisplus.core.metadata.IPage;
12 5 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7 +import org.jeecg.common.constant.CommonConstant;
13 8 import org.jeecg.common.util.oConvertUtils;
14 9 import org.jeecg.modules.system.entity.SysDepart;
15 10 import org.jeecg.modules.system.entity.SysUser;
... ... @@ -22,8 +17,11 @@ import org.jeecg.modules.system.service.ISysUserService;
22 17 import org.springframework.beans.factory.annotation.Autowired;
23 18 import org.springframework.stereotype.Service;
24 19  
25   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
26   -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  20 +import java.util.ArrayList;
  21 +import java.util.HashMap;
  22 +import java.util.List;
  23 +import java.util.Map;
  24 +import java.util.stream.Collectors;
27 25  
28 26 /**
29 27 * <P>
... ... @@ -128,6 +126,9 @@ public class SysUserDepartServiceImpl extends ServiceImpl&lt;SysUserDepartMapper, S
128 126 Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
129 127 if(oConvertUtils.isEmpty(departId)){
130 128 LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
  129 + //update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
  130 + query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
  131 + //update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
131 132 if(oConvertUtils.isNotEmpty(username)){
132 133 query.like(SysUser::getUsername, username);
133 134 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
... ... @@ -399,6 +399,7 @@ public class SysUserServiceImpl extends ServiceImpl&lt;SysUserMapper, SysUser&gt; impl
399 399 }
400 400  
401 401 @Override
  402 + @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
402 403 public boolean revertLogicDeleted(List<String> userIds, SysUser updateEntity) {
403 404 String ids = String.format("'%s'", String.join("','", userIds));
404 405 return userMapper.revertLogicDeleted(ids, updateEntity) > 0;
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppDingtalkServiceImpl.java
... ... @@ -85,18 +85,31 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
85 85 return null;
86 86 }
87 87  
  88 + // update:2022-1-21,updateBy:sunjianlei; for 【JTC-704】【钉钉】部门同步成功,实际没成,后台提示ip白名单
88 89 @Override
89   - public boolean syncLocalDepartmentToThirdApp(String ids) {
  90 + public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
  91 + SyncInfoVo syncInfo = new SyncInfoVo();
90 92 String accessToken = this.getAccessToken();
91 93 if (accessToken == null) {
92   - return false;
  94 + syncInfo.addFailInfo("accessToken获取失败!");
  95 + return syncInfo;
93 96 }
94 97 // 获取【钉钉】所有的部门
95   - List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
  98 + List<Response<Department>> departments = JdtDepartmentAPI.listAllResponse(accessToken);
96 99 // 删除钉钉有但本地没有的部门(以本地部门数据为主)(钉钉不能创建同名部门,只能先删除)
97 100 List<SysDepart> sysDepartList = sysDepartService.list();
98 101 for1:
99   - for (Department department : departments) {
  102 + for (Response<Department> departmentRes : departments) {
  103 + // 判断部门是否查询成功
  104 + if (!departmentRes.isSuccess()) {
  105 + syncInfo.addFailInfo(departmentRes.getErrmsg());
  106 + // 88 是 ip 不在白名单的错误码,如果遇到此错误码,后面的操作都可以不用进行了,因为肯定都是失败的
  107 + if (new Integer(88).equals(departmentRes.getErrcode())) {
  108 + return syncInfo;
  109 + }
  110 + continue;
  111 + }
  112 + Department department = departmentRes.getResult();
100 113 for (SysDepart depart : sysDepartList) {
101 114 // id相同,代表已存在,不删除
102 115 String sourceIdentifier = department.getSource_identifier();
... ... @@ -124,24 +137,34 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
124 137 Department parent = new Department();
125 138 parent.setDept_id(1);
126 139 // 递归同步部门
127   - departments = JdtDepartmentAPI.listAll(accessToken);
128   - this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
129   - return true;
  140 + departments = JdtDepartmentAPI.listAllResponse(accessToken);
  141 + this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken, syncInfo);
  142 + return syncInfo;
130 143 }
131 144  
132 145 // 递归同步部门到本地
133   - public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Department> departments, Department parent, String accessToken) {
  146 + public void syncDepartmentRecursion(List<SysDepartTreeModel> sysDepartsTree, List<Response<Department>> departments, Department parent, String accessToken, SyncInfoVo syncInfo) {
134 147 if (sysDepartsTree != null && sysDepartsTree.size() != 0) {
135 148 for1:
136 149 for (SysDepartTreeModel depart : sysDepartsTree) {
137   - for (Department department : departments) {
  150 + for (Response<Department> departmentRes : departments) {
  151 + // 判断部门是否查询成功
  152 + if (!departmentRes.isSuccess()) {
  153 + syncInfo.addFailInfo(departmentRes.getErrmsg());
  154 + continue;
  155 + }
  156 + Department department = departmentRes.getResult();
138 157 // id相同,代表已存在,执行修改操作
139 158 String sourceIdentifier = department.getSource_identifier();
140 159 if (sourceIdentifier != null && sourceIdentifier.equals(depart.getId())) {
141 160 this.sysDepartToDtDepartment(depart, department, parent.getDept_id());
142   - JdtDepartmentAPI.update(department, accessToken);
143   - // 紧接着同步子级
144   - this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken);
  161 + Response<JSONObject> response = JdtDepartmentAPI.update(department, accessToken);
  162 + if (response.isSuccess()) {
  163 + // 紧接着同步子级
  164 + this.syncDepartmentRecursion(depart.getChildren(), departments, department, accessToken, syncInfo);
  165 + }
  166 + // 收集错误信息
  167 + this.syncDepartCollectErrInfo(response, depart, syncInfo);
145 168 // 跳出外部循环
146 169 continue for1;
147 170 }
... ... @@ -154,10 +177,10 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
154 177 Department newParent = new Department();
155 178 newParent.setDept_id(response.getResult());
156 179 // 紧接着同步子级
157   - this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken);
  180 + this.syncDepartmentRecursion(depart.getChildren(), departments, newParent, accessToken, syncInfo);
158 181 }
159 182 // 收集错误信息
160   -// this.syncUserCollectErrInfo(errCode, sysUser, errInfo);
  183 + this.syncDepartCollectErrInfo(response, depart, syncInfo);
161 184 }
162 185 }
163 186 }
... ... @@ -209,6 +232,11 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
209 232 SysDepart newSysDepart = this.dtDepartmentToSysDepart(departmentTree, null);
210 233 if (sysParentId != null) {
211 234 newSysDepart.setParentId(sysParentId);
  235 + // 2 = 组织机构
  236 + newSysDepart.setOrgCategory("2");
  237 + } else {
  238 + // 1 = 公司
  239 + newSysDepart.setOrgCategory("1");
212 240 }
213 241 try {
214 242 sysDepartService.saveDepartData(newSysDepart, username);
... ... @@ -246,6 +274,20 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
246 274 return false;
247 275 }
248 276  
  277 + /**
  278 + * 【同步部门】收集同步过程中的错误信息
  279 + */
  280 + private boolean syncDepartCollectErrInfo(Response<?> response, SysDepartTreeModel depart, SyncInfoVo syncInfo) {
  281 + if (!response.isSuccess()) {
  282 + String str = String.format("部门 %s(%s) 同步失败!错误码:%s——%s", depart.getDepartName(), depart.getOrgCode(), response.getErrcode(), response.getErrmsg());
  283 + syncInfo.addFailInfo(str);
  284 + return false;
  285 + } else {
  286 + String str = String.format("部门户 %s(%s) 同步成功!", depart.getDepartName(), depart.getOrgCode());
  287 + syncInfo.addSuccessInfo(str);
  288 + return true;
  289 + }
  290 + }
249 291  
250 292 @Override
251 293 public SyncInfoVo syncLocalUserToThirdApp(String ids) {
... ... @@ -279,7 +321,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
279 321 /*
280 322 * 判断是否同步过的逻辑:
281 323 * 1. 查询 sys_third_account(第三方账号表)是否有数据,如果有代表已同步
282   - * 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
  324 + * 2. 本地表里没有,就先用手机号判断,不通过再用username(用户账号)判断。
283 325 */
284 326 SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneBySysUserId(sysUser.getId(), THIRD_TYPE);
285 327 if (sysThirdAccount != null && oConvertUtils.isNotEmpty(sysThirdAccount.getThirdUserId())) {
... ... @@ -528,6 +570,12 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
528 570 // update-begin--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
529 571 sysUser.setStatus(1);
530 572 // update-end--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
  573 + // 设置工号,如果工号为空,则使用username
  574 + if (oConvertUtils.isEmpty(dtUser.getJob_number())) {
  575 + sysUser.setWorkNo(dtUser.getUserid());
  576 + } else {
  577 + sysUser.setWorkNo(dtUser.getJob_number());
  578 + }
531 579 return this.dtUserToSysUser(dtUser, sysUser);
532 580 }
533 581  
... ...
jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
... ... @@ -96,15 +96,18 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
96 96 }
97 97  
98 98 @Override
99   - public boolean syncLocalDepartmentToThirdApp(String ids) {
  99 + public SyncInfoVo syncLocalDepartmentToThirdApp(String ids) {
  100 + SyncInfoVo syncInfo = new SyncInfoVo();
100 101 String accessToken = this.getAccessToken();
101 102 if (accessToken == null) {
102   - return false;
  103 + syncInfo.addFailInfo("accessToken获取失败!");
  104 + return syncInfo;
103 105 }
104 106 // 获取企业微信所有的部门
105 107 List<Department> departments = JwDepartmentAPI.getAllDepartment(accessToken);
106 108 if (departments == null) {
107   - return false;
  109 + syncInfo.addFailInfo("获取企业微信所有部门失败!");
  110 + return syncInfo;
108 111 }
109 112 // 删除企业微信有但本地没有的部门(以本地部门数据为主)(以为企业微信不能创建同名部门,所以只能先删除)
110 113 List<JwDepartmentTreeVo> departmentTreeList = JwDepartmentTreeVo.listToTree(departments);
... ... @@ -117,7 +120,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
117 120 // 递归同步部门
118 121 departments = JwDepartmentAPI.getAllDepartment(accessToken);
119 122 this.syncDepartmentRecursion(sysDepartsTree, departments, parent, accessToken);
120   - return true;
  123 + return syncInfo;
121 124 }
122 125  
123 126 // 递归删除部门以及子部门,由于企业微信不允许删除带有成员和子部门的部门,所以需要递归删除下子部门,然后把部门成员移动端根部门下
... ... @@ -250,6 +253,11 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
250 253 SysDepart newSysDepart = this.qwDepartmentToSysDepart(departmentTree, null);
251 254 if (sysParentId != null) {
252 255 newSysDepart.setParentId(sysParentId);
  256 + // 2 = 组织机构
  257 + newSysDepart.setOrgCategory("2");
  258 + } else {
  259 + // 1 = 公司
  260 + newSysDepart.setOrgCategory("1");
253 261 }
254 262 try {
255 263 sysDepartService.saveDepartData(newSysDepart, username);
... ... @@ -604,6 +612,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
604 612 BeanUtils.copyProperties(oldSysUser, sysUser);
605 613 sysUser.setRealname(qwUser.getName());
606 614 sysUser.setPost(qwUser.getPosition());
  615 + // 设置工号,由于企业微信没有工号的概念,所以只能用 userId 代替
  616 + if (oConvertUtils.isEmpty(sysUser.getWorkNo())) {
  617 + sysUser.setWorkNo(qwUser.getUserid());
  618 + }
607 619 try {
608 620 sysUser.setSex(Integer.parseInt(qwUser.getGender()));
609 621 } catch (NumberFormatException ignored) {
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml
... ... @@ -197,7 +197,7 @@ jeecg :
197 197 # ElasticSearch 设置
198 198 elasticsearch:
199 199 cluster-name: jeecg-ES
200   - cluster-nodes: 81.70.47.128:9200
  200 + cluster-nodes: 127.0.0.1:9200
201 201 check-enabled: true
202 202 # 表单设计器配置
203 203 desform:
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt
... ... @@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE}
9 9  
10 10  
11 11 ${AnsiColor.BRIGHT_GREEN}
12   -Jeecg Boot Version: 3.0
  12 +Jeecg Boot Version: 3.1.0
13 13 Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
14 14 ${AnsiColor.BLACK}
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl
... ... @@ -115,9 +115,9 @@
115 115 <#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}'}">
116 116 <#else>
117 117 <#if po.classType=="sel_search" || po.classType=="list_multi">
118   - <#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}',dictTable:'${superQuery_dictTable}', dictText:'${superQuery_dictText}', dictCode:'${po.dictField}'}">
  118 + <#return "{type:'${po.classType}',value:'${po.fieldName}',text:'${po.filedComment}',dictTable:\"${superQuery_dictTable}\", dictText:'${superQuery_dictText}', dictCode:'${po.dictField}'}">
119 119 <#elseif po.dictTable?? && po.dictTable!="" && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
120   - <#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:'${po.dictTable},${po.dictText},${po.dictField}'}">
  120 + <#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:\"${po.dictTable},${po.dictText},${po.dictField}\"}">
121 121 <#elseif po.dictField?? && po.classType!="sel_tree" && po.classType!="cat_tree" && po.classType!="link_down">
122 122 <#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}',dictCode:'${po.dictField}'}">
123 123 <#elseif po.fieldDbType=="Text">
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... ... @@ -65,10 +65,10 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
65 65 * @param req
66 66 * @return
67 67 */
68   - @AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
  68 + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
69 69 @ApiOperation(value="${tableVo.ftlDescription}-分页列表查询", notes="${tableVo.ftlDescription}-分页列表查询")
70 70 @GetMapping(value = "/list")
71   - public Result<?> queryPageList(${entityName} ${entityName?uncap_first},
  71 + public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
72 72 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
73 73 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
74 74 HttpServletRequest req) {
... ... @@ -87,7 +87,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
87 87 @AutoLog(value = "${tableVo.ftlDescription}-添加")
88 88 @ApiOperation(value="${tableVo.ftlDescription}-添加", notes="${tableVo.ftlDescription}-添加")
89 89 @PostMapping(value = "/add")
90   - public Result<?> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
  90 + public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
91 91 <#if bpm_flag>
92 92 ${entityName?uncap_first}.setBpmStatus("1");
93 93 </#if>
... ... @@ -103,8 +103,8 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
103 103 */
104 104 @AutoLog(value = "${tableVo.ftlDescription}-编辑")
105 105 @ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
106   - @PutMapping(value = "/edit")
107   - public Result<?> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
  106 + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
  107 + public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
108 108 ${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
109 109 return Result.OK("编辑成功!");
110 110 }
... ... @@ -118,7 +118,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
118 118 @AutoLog(value = "${tableVo.ftlDescription}-通过id删除")
119 119 @ApiOperation(value="${tableVo.ftlDescription}-通过id删除", notes="${tableVo.ftlDescription}-通过id删除")
120 120 @DeleteMapping(value = "/delete")
121   - public Result<?> delete(@RequestParam(name="id",required=true) String id) {
  121 + public Result<String> delete(@RequestParam(name="id",required=true) String id) {
122 122 ${entityName?uncap_first}Service.removeById(id);
123 123 return Result.OK("删除成功!");
124 124 }
... ... @@ -132,7 +132,7 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
132 132 @AutoLog(value = "${tableVo.ftlDescription}-批量删除")
133 133 @ApiOperation(value="${tableVo.ftlDescription}-批量删除", notes="${tableVo.ftlDescription}-批量删除")
134 134 @DeleteMapping(value = "/deleteBatch")
135   - public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
  135 + public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
136 136 this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
137 137 return Result.OK("批量删除成功!");
138 138 }
... ... @@ -143,13 +143,13 @@ public class ${entityName}Controller extends JeecgController&lt;${entityName}, I${e
143 143 * @param id
144 144 * @return
145 145 */
146   - @AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
  146 + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
147 147 @ApiOperation(value="${tableVo.ftlDescription}-通过id查询", notes="${tableVo.ftlDescription}-通过id查询")
148 148 @GetMapping(value = "/queryById")
149   - public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
  149 + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
150 150 ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
151 151 if(${entityName?uncap_first}==null) {
152   - return Result.error("未找到对应数据");
  152 + return Result.error("未找到对应数据",null);
153 153 }
154 154 return Result.OK(${entityName?uncap_first});
155 155 }
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... ... @@ -108,8 +108,8 @@
108 108 </#if>
109 109 </#list>
110 110 <#if bpm_flag>
111   - <a-col v-if="showFlowSubmitButton" :span="24" style="text-align: center">
112   - <a-button @click="submitForm">提 交</a-button>
  111 + <a-col v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;">
  112 + <a-button icon="check" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
113 113 </a-col>
114 114 </#if>
115 115 </a-row>
... ...
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei 0 → 100644
  1 +<template>
  2 + <div>
  3 +<#assign list_need_category=false>
  4 +<#assign list_need_pca=false>
  5 +<#assign bpm_flag=false>
  6 +
  7 +<#-- 开始循环 -->
  8 +<#list columns as po>
  9 +<#if po.fieldDbName=='bpm_status'>
  10 + <#assign bpm_flag=true>
  11 +</#if>
  12 +<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0>
  13 +<#assign list_need_category=true>
  14 +</#if>
  15 +<#if po.classType=='pca'>
  16 +<#assign list_need_pca=true>
  17 +</#if>
  18 +</#list>
  19 +<#-- 结束循环 -->
  20 + <!--引用表格-->
  21 + <BasicTable @register="registerTable" :rowSelection="rowSelection">
  22 + <!--插槽:table标题-->
  23 + <template #tableTitle>
  24 + <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
  25 + <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
  26 + <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
  27 + <a-dropdown v-if="checkedKeys.length > 0">
  28 + <template #overlay>
  29 + <a-menu>
  30 + <a-menu-item key="1" @click="batchHandleDelete">
  31 + <Icon icon="ant-design:delete-outlined"></Icon>
  32 + 删除
  33 + </a-menu-item>
  34 + </a-menu>
  35 + </template>
  36 + <a-button>批量操作
  37 + <Icon icon="mdi:chevron-down"></Icon>
  38 + </a-button>
  39 + </a-dropdown>
  40 + </template>
  41 + <!--操作栏-->
  42 + <template #action="{ record }">
  43 + <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
  44 + </template>
  45 + <!--字段回显插槽-->
  46 + <template #htmlSlot="{text}">
  47 + <div v-html="text"></div>
  48 + </template>
  49 + <template #fileSlot="{text}">
  50 + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
  51 + <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button>
  52 + </template>
  53 + </BasicTable>
  54 + <!-- 表单区域 -->
  55 + <${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal>
  56 + </div>
  57 +</template>
  58 +
  59 +<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup>
  60 + import {ref, computed, unref} from 'vue';
  61 + import {BasicTable, useTable, TableAction} from '/@/components/Table';
  62 + import {useModal} from '/@/components/Modal';
  63 + import { useListPage } from '/@/hooks/system/useListPage'
  64 + import ${entityName}Modal from './components/${entityName}Modal.vue'
  65 + import {columns, searchFormSchema} from './${entityName?uncap_first}.data';
  66 + import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName?uncap_first}.api';
  67 + <#if list_need_category>
  68 + import { loadCategoryData } from '/@/api/common/api'
  69 + import { getAuthCache, setAuthCache } from '/@/utils/auth';
  70 + import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
  71 + </#if>
  72 + const checkedKeys = ref<Array<string | number>>([]);
  73 + //注册model
  74 + const [registerModal, {openModal}] = useModal();
  75 + //注册table数据
  76 + const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
  77 + tableProps:{
  78 + title: '${tableVo.ftlDescription}',
  79 + api: list,
  80 + columns,
  81 + canResize:false,
  82 + formConfig: {
  83 + labelWidth: 120,
  84 + schemas: searchFormSchema,
  85 + autoSubmitOnEnter:true,
  86 + showAdvancedButton:true,
  87 + fieldMapToTime: [
  88 + <#list columns as po>
  89 + <#if po.isQuery=='Y'>
  90 + <#if po.queryMode!='single'>
  91 + <#if po.classType=='date'>
  92 + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'],
  93 + <#elseif po.classType=='datetime'>
  94 + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'],
  95 + </#if>
  96 + </#if>
  97 + </#if>
  98 + </#list>
  99 + ],
  100 + },
  101 + actionColumn: {
  102 + width: 120,
  103 + },
  104 + },
  105 + exportConfig: {
  106 + name:"${tableVo.ftlDescription}",
  107 + url: getExportUrl,
  108 + },
  109 + importConfig: {
  110 + url: getImportUrl
  111 + },
  112 + })
  113 +
  114 + const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
  115 +
  116 + /**
  117 + * 新增事件
  118 + */
  119 + function handleAdd() {
  120 + openModal(true, {
  121 + isUpdate: false,
  122 + showFooter: true,
  123 + });
  124 + }
  125 + /**
  126 + * 编辑事件
  127 + */
  128 + function handleEdit(record: Recordable) {
  129 + openModal(true, {
  130 + record,
  131 + isUpdate: true,
  132 + showFooter: true,
  133 + });
  134 + }
  135 + /**
  136 + * 详情
  137 + */
  138 + function handleDetail(record: Recordable) {
  139 + openModal(true, {
  140 + record,
  141 + isUpdate: true,
  142 + showFooter: false,
  143 + });
  144 + }
  145 + /**
  146 + * 删除事件
  147 + */
  148 + async function handleDelete(record) {
  149 + await deleteOne({id: record.id}, reload);
  150 + }
  151 + /**
  152 + * 批量删除事件
  153 + */
  154 + async function batchHandleDelete() {
  155 + await batchDelete({ids: checkedKeys.value}, reload);
  156 + }
  157 + /**
  158 + * 成功回调
  159 + */
  160 + function handleSuccess() {
  161 + reload();
  162 + }
  163 + /**
  164 + * 操作栏
  165 + */
  166 + function getTableAction(record){
  167 + return [
  168 + {
  169 + label: '编辑',
  170 + onClick: handleEdit.bind(null, record),
  171 + }
  172 + ]
  173 + }
  174 + /**
  175 + * 下拉操作栏
  176 + */
  177 + function getDropDownAction(record){
  178 + return [
  179 + {
  180 + label: '详情',
  181 + onClick: handleDetail.bind(null, record),
  182 + }, {
  183 + label: '删除',
  184 + popConfirm: {
  185 + title: '是否确认删除',
  186 + confirm: handleDelete.bind(null, record),
  187 + }
  188 + }
  189 + ]
  190 + }
  191 + <#if list_need_category>
  192 + /**
  193 + * 初始化字典配置
  194 + */
  195 + function initDictConfig(){
  196 + <#list columns as po>
  197 + <#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'>
  198 + <#if po.classType=='cat_tree' && list_need_category==true>
  199 + loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => {
  200 + if (res) {
  201 + let allDictDate = getAuthCache(DB_DICT_DATA_KEY);
  202 + if(!allDictDate['${po.dictField?default("")}']){
  203 + Object.assign(allDictDate,{'${po.dictField?default("")}':res})
  204 + }
  205 + setAuthCache(DB_DICT_DATA_KEY,allDictDate)
  206 + }
  207 + })
  208 + </#if>
  209 + </#if>
  210 + </#list>
  211 + }
  212 + initDictConfig();
  213 + </#if>
  214 +</script>
  215 +
  216 +<style scoped>
  217 +
  218 +</style>
0 219 \ No newline at end of file
... ...