Преглед на файлове

jeecgboot3.4.2版本发布

zhangdaiscott преди 2 години
родител
ревизия
0ee38b7f4a
променени са 92 файла, в които са добавени 1503 реда и са изтрити 186 реда
  1. 0 10
      jeecg-boot-base-core/pom.xml
  2. 36 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/DataLogDTO.java
  3. 4 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/BusMessageDTO.java
  4. 35 16
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/MessageDTO.java
  5. 8 8
      jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
  6. 20 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
  7. 2 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonSendStatus.java
  8. 1 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/ServiceNameConstants.java
  9. 22 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/TenantConstant.java
  10. 0 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/VxeSocketConst.java
  11. 5 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/WebsocketConst.java
  12. 75 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/FileTypeEnum.java
  13. 20 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/MessageTypeEnum.java
  14. 1 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/desensitization/util/SensitiveInfoUtil.java
  15. 1 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
  16. 70 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/SysFilesModel.java
  17. 17 9
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java
  18. 13 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
  19. 11 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/HTMLUtils.java
  20. 0 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/IpUtils.java
  21. 0 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/Md5Util.java
  22. 9 7
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MinioUtil.java
  23. 13 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java
  24. 1 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SysAnnmentTypeEnum.java
  25. 19 5
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/dynamic/db/FreemarkerParseFactory.java
  26. 1 1
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/FileTypeFilter.java
  27. 8 5
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
  28. 46 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/JdbcSecurityUtil.java
  29. 19 2
      jeecg-boot-base-core/src/main/java/org/jeecg/config/JeecgBaseConfig.java
  30. 3 4
      jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger2Config.java
  31. 2 1
      jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java
  32. 2 1
      jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java
  33. 4 2
      jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java
  34. 2 1
      jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  35. 0 3
      jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java
  36. 8 1
      jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/SignUtil.java
  37. 0 1
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/mock/vxe/websocket/VxeSocket.java
  38. 13 1
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java
  39. 7 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgDemoMapper.java
  40. 6 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgDemoMapper.xml
  41. 8 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/IJeecgDemoService.java
  42. 5 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java
  43. 33 0
      jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  44. 25 0
      jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java
  45. 39 7
      jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  46. 2 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/CodeTemplateInitListener.java
  47. 37 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java
  48. 2 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/TestSocketController.java
  49. 128 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/RangeDateEnum.java
  50. 65 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/Vue3MessageHrefEnum.java
  51. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java
  52. 4 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java
  53. 2 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java
  54. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java
  55. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java
  56. 1 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
  57. 50 6
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java
  58. 13 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java
  59. 11 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDataLogController.java
  60. 4 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
  61. 18 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
  62. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java
  63. 16 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysAnnouncement.java
  64. 5 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysAnnouncementSend.java
  65. 8 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java
  66. 4 4
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysThirdAccount.java
  67. 11 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysAnnouncementMapper.java
  68. 12 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysAnnouncementSendMapper.java
  69. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
  70. 14 9
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysPermissionMapper.java
  71. 9 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepartMapper.java
  72. 31 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysAnnouncementMapper.xml
  73. 40 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysAnnouncementSendMapper.xml
  74. 8 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
  75. 10 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionMapper.xml
  76. 18 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserDepartMapper.xml
  77. 3 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/TreeSelectModel.java
  78. 7 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementSendService.java
  79. 22 3
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java
  80. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java
  81. 10 3
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysPermissionService.java
  82. 9 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java
  83. 5 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementSendServiceImpl.java
  84. 69 10
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java
  85. 77 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java
  86. 3 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java
  87. 41 11
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java
  88. 11 6
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java
  89. 32 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java
  90. 38 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppDingtalkServiceImpl.java
  91. 24 5
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
  92. 9 5
      pom.xml

+ 0 - 10
jeecg-boot-base-core/pom.xml

@@ -146,11 +146,6 @@
 					<groupId>org.apache.shiro</groupId>
 					<artifactId>shiro-core</artifactId>
 				</exclusion>
-				<!-- [issues/3596] 解决启动报错:Cannot resolve com.sun:tools:1.8.0 -->
-				<exclusion>
-					<groupId>com.puppycrawl.tools</groupId>
-					<artifactId>checkstyle</artifactId>
-				</exclusion>
 			</exclusions>
 		</dependency>
 
@@ -187,11 +182,6 @@
 			<groupId>io.minio</groupId>
 			<artifactId>minio</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>com.google.guava</groupId>
-			<artifactId>guava</artifactId>
-			<version>${guava.version}</version>
-		</dependency>
 
 		<!-- 阿里云短信 -->
 		<dependency>

+ 36 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/DataLogDTO.java

@@ -0,0 +1,36 @@
+package org.jeecg.common.api.dto;
+
+import lombok.Data;
+
+/**
+ * @Author taoYan
+ * @Date 2022/7/26 14:44
+ **/
+@Data
+public class DataLogDTO {
+
+    private String tableName;
+
+    private String dataId;
+
+    private String content;
+
+    private String type;
+
+    public DataLogDTO(){
+
+    }
+
+    public DataLogDTO(String tableName, String dataId, String content, String type) {
+        this.tableName = tableName;
+        this.dataId = dataId;
+        this.content = content;
+        this.type = type;
+    }
+
+    public DataLogDTO(String tableName, String dataId, String type) {
+        this.tableName = tableName;
+        this.dataId = dataId;
+        this.type = type;
+    }
+}

+ 4 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/BusMessageDTO.java

@@ -6,8 +6,10 @@ import java.io.Serializable;
 
 /**
  * 带业务参数的消息
- * @author: jeecg-boot
- */
+* 
+* @author: taoyan
+* @date: 2022/8/17
+*/
 @Data
 public class BusMessageDTO extends MessageDTO implements Serializable {
 

+ 35 - 16
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/message/MessageDTO.java

@@ -12,9 +12,8 @@ import java.util.Map;
  */
 @Data
 public class MessageDTO implements Serializable {
-
     private static final long serialVersionUID = -5690444483968058442L;
-
+    
     /**
      * 发送人(用户登录账户)
      */
@@ -45,9 +44,36 @@ public class MessageDTO implements Serializable {
      */
     protected String category;
 
+    //-----------------------------------------------------------------------
+    //update-begin---author:taoyan ---date:20220705  for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
 
-    public MessageDTO(){
+    /**
+     * 模板消息对应的模板编码
+     */
+    protected String templateCode;
+    /**
+     * 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum
+     *  XT("system",  "系统消息")
+     *  YJ("email",  "邮件消息")
+     *  DD("dingtalk", "钉钉消息")
+     *  QYWX("wechat_enterprise", "企业微信")
+     */
+    protected String type;
+    
+    /**
+     * 是否发送Markdown格式的消息
+     */
+    protected boolean isMarkdown;
 
+    /**
+     * 解析模板内容 对应的数据
+     */
+    protected Map<String, Object> data;
+    //update-end---author:taoyan ---date::20220705  for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
+    //-----------------------------------------------------------------------
+    
+    
+    public MessageDTO(){
     }
 
     /**
@@ -73,18 +99,11 @@ public class MessageDTO implements Serializable {
         this.category = category;
     }
 
-    /**
-     * 模板消息对应的模板编码
-     */
-    protected String templateCode;
-    /**
-     * 消息类型:org.jeecg.common.constant.enums.MessageTypeEnum
-     */
-    protected String type;
-
-    /**
-     * 解析模板内容 对应的数据
-     */
-    protected Map<String, Object> data;
+    public boolean isMarkdown() {
+        return this.isMarkdown;
+    }
 
+    public void setIsMarkdown(boolean isMarkdown) {
+        this.isMarkdown = isMarkdown;
+    }
 }

+ 8 - 8
jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java

@@ -108,7 +108,7 @@ public class DictAspect {
                     return result;
                 }
 
-                log.info(" __ 进入字典翻译切面 DictAspect —— " );
+                log.debug(" __ 进入字典翻译切面 DictAspect —— " );
                 //update-end--Author:zyf -- Date:20220606 ----for:【VUEN-1230】 判断是否含有字典注解,没有注解返回-----
                 for (Object record : records) {
                     String json="{}";
@@ -274,10 +274,10 @@ public class DictAspect {
                 String[] arr = dictCode.split(",");
                 String table = arr[0], text = arr[1], code = arr[2];
                 String values = String.join(",", needTranslDataTable);
-                log.info("translateDictFromTableByKeys.dictCode:" + dictCode);
-                log.info("translateDictFromTableByKeys.values:" + values);
+                log.debug("translateDictFromTableByKeys.dictCode:" + dictCode);
+                log.debug("translateDictFromTableByKeys.values:" + values);
                 List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values);
-                log.info("translateDictFromTableByKeys.result:" + texts);
+                log.debug("translateDictFromTableByKeys.result:" + texts);
                 List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
                 list.addAll(texts);
 
@@ -303,10 +303,10 @@ public class DictAspect {
             List<String> filterDictCodes = dictCodeList.stream().filter(key -> !key.contains(",")).collect(Collectors.toList());
             String dictCodes = String.join(",", filterDictCodes);
             String values = String.join(",", needTranslData);
-            log.info("translateManyDict.dictCodes:" + dictCodes);
-            log.info("translateManyDict.values:" + values);
+            log.debug("translateManyDict.dictCodes:" + dictCodes);
+            log.debug("translateManyDict.values:" + values);
             Map<String, List<DictModel>> manyDict = commonApi.translateManyDict(dictCodes, values);
-            log.info("translateManyDict.result:" + manyDict);
+            log.debug("translateManyDict.result:" + manyDict);
             for (String dictCode : manyDict.keySet()) {
                 List<DictModel> list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>());
                 List<DictModel> newList = manyDict.get(dictCode);
@@ -374,7 +374,7 @@ public class DictAspect {
             }
             //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
             if (!StringUtils.isEmpty(table)){
-                log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
+                log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
                 String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
                     if (redisTemplate.hasKey(keyString)){
                     try {

+ 20 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java

@@ -261,7 +261,7 @@ public interface CommonConstant {
     /**
      * 在线聊天 图片文件保存路径
      */
-    String IM_UPLOAD_CUSTOM_PATH = "imfile";
+    String IM_UPLOAD_CUSTOM_PATH = "biz/user_imgs";
     /**
      * 在线聊天 用户状态
      */
@@ -406,4 +406,23 @@ public interface CommonConstant {
      * 模板消息中 跳转地址的对应的key
      */
     String MSG_HREF_URL = "url";
+
+    /**
+     * sys_data_log表的类型 用于区别评论区域的日志数据
+     */
+    String DATA_LOG_TYPE_COMMENT = "comment";
+
+    /**
+     * sys_data_log表的类型 老的数据比较 类型都设置为json
+     */
+    String DATA_LOG_TYPE_JSON = "json";
+
+    /** 消息模板:markdown */
+    String MSG_TEMPLATE_TYPE_MD = "5";
+
+    /**
+     * 短信验证码redis-key的前缀
+     */
+    String PHONE_REDIS_KEY_PRE = "phone_msg";
+
 }

+ 2 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonSendStatus.java

@@ -30,6 +30,8 @@ public interface CommonSendStatus {
 
 	/**流程催办——系统通知消息模板*/
 	public static final String TZMB_BPM_CUIBAN = "bpm_cuiban";
+	/**流程催办——邮件通知消息模板*/
+	public static final String TZMB_BPM_CUIBAN_EMAIL = "bpm_cuiban_email";
 	/**标准模板—系统消息通知*/
 	public static final String TZMB_SYS_TS_NOTE = "sys_ts_note";
 	/**流程超时提醒——系统通知消息模板*/

+ 1 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/ServiceNameConstants.java

@@ -30,7 +30,7 @@ public interface ServiceNameConstants {
 	 */
 	String SERVICE_SYSTEM = "jeecg-system";
 	/**
-	 * 微服务名:Demo模块
+	 * 微服务名: demo模块
 	 */
 	String SERVICE_DEMO = "jeecg-demo";
 

+ 22 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/TenantConstant.java

@@ -0,0 +1,22 @@
+package org.jeecg.common.constant;
+
+/**
+ * @Description: TenantConstant
+ * @author: scott
+ * @date: 2022年08月29日 15:29
+ */
+public interface TenantConstant {
+
+    /**
+     * 应用ID——表字段
+     */
+    String DB_FIELD_LOW_APP_ID = "low_app_id";
+    /**
+     * 应用ID——实体字段
+     */
+    String FIELD_LOW_APP_ID = "lowAppId";
+    /**
+     * 租户ID
+     */
+    String TENANT_ID = "tenantId";
+}

+ 0 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/VxeSocketConst.java

@@ -2,8 +2,6 @@ package org.jeecg.common.constant;
 
 /**
  * VXESocket 常量
- *
- * update: 【类名改了大小写】 date: 2022-04-18
  * @author: jeecg-boot
  */
 public class VxeSocketConst {

+ 5 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/WebsocketConst.java

@@ -28,6 +28,11 @@ public class WebsocketConst {
      */
     public static final String MSG_USER_ID = "userId";
 
+    /**
+     * 消息json key:chat
+     */
+    public static final String MSG_CHAT = "chat";
+
     /**
      * 消息类型 heartcheck
      */

+ 75 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/FileTypeEnum.java

@@ -0,0 +1,75 @@
+package org.jeecg.common.constant.enums;
+
+import org.jeecg.common.util.oConvertUtils;
+
+/**
+ * 文件类型
+ */
+public enum FileTypeEnum {
+    //    文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片  archive:其他文档 video:视频)
+//    FOLDER
+    xls(".xls","excel","excel"),
+    xlsx(".xlsx","excel","excel"),
+    doc(".doc","doc","word"),
+    docx(".docx","doc","word"),
+    ppt(".ppt","pp","ppt"),
+    pptx(".pptx","pp","ppt"),
+    gif(".gif","image","图片"),
+    jpg(".jpg","image","图片"),
+    jpeg(".jpeg","image","图片"),
+    png(".png","image","图片"),
+    txt(".txt","text","文本"),
+    avi(".avi","video","视频"),
+    mov(".mov","video","视频"),
+    rmvb(".rmvb","video","视频"),
+    rm(".rm","video","视频"),
+    flv(".flv","video","视频"),
+    mp4(".mp4","video","视频"),
+    zip(".zip","zip","压缩包"),
+    pdf(".pdf","pdf","pdf");
+
+    private String type;
+    private String value;
+    private String text;
+    private FileTypeEnum(String type,String value,String text){
+        this.type = type;
+        this.value = value;
+        this.text = text;
+    }
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public static FileTypeEnum getByType(String type){
+        if (oConvertUtils.isEmpty(type)) {
+            return null;
+        }
+        for (FileTypeEnum val : values()) {
+            if (val.getType().equals(type)) {
+                return val;
+            }
+        }
+        return null;
+    }
+
+}

+ 20 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/MessageTypeEnum.java

@@ -13,9 +13,13 @@ import java.util.List;
 @EnumDict("messageType")
 public enum MessageTypeEnum {
 
+    /** 系统消息 */
     XT("system",  "系统消息"),
+    /** 邮件消息 */
     YJ("email",  "邮件消息"),
+    /** 钉钉消息 */
     DD("dingtalk", "钉钉消息"),
+    /** 企业微信 */
     QYWX("wechat_enterprise", "企业微信");
 
     MessageTypeEnum(String type, String note){
@@ -65,4 +69,20 @@ public enum MessageTypeEnum {
         }
         return list;
     }
+
+    /**
+     * 根据type获取枚举
+     *
+     * @param type
+     * @return
+     */
+    public static MessageTypeEnum valueOfType(String type) {
+        for (MessageTypeEnum e : MessageTypeEnum.values()) {
+            if (e.getType().equals(type)) {
+                return e;
+            }
+        }
+        return null;
+    }
+
 }

+ 1 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/desensitization/util/SensitiveInfoUtil.java

@@ -135,7 +135,7 @@ public class SensitiveInfoUtil {
         try {
             result = AesEncryptUtil.desEncrypt(data);
         } catch (Exception exception) {
-            log.warn("数据解密错误,原数据:"+data);
+            log.debug("数据解密错误,原数据:"+data);
         }
         //解决debug模式下,加解密失效导致中文被解密变成空的问题
         if(oConvertUtils.isEmpty(result) && oConvertUtils.isNotEmpty(data)){

+ 1 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/QueryGenerator.java

@@ -246,7 +246,7 @@ public class QueryGenerator {
 
 			//update-begin-author:taoyan date:2022-5-16 for: issues/3676 获取系统用户列表时,使用SQL注入生效
 			//判断column是不是当前实体的
-			log.info("当前字段有:"+ allFields);
+			log.debug("当前字段有:"+ allFields);
 			if (!allColumnExist(column, allFields)) {
 				throw new JeecgBootException("请注意,将要排序的列字段不存在:" + column);
 			}

+ 70 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/SysFilesModel.java

@@ -0,0 +1,70 @@
+package org.jeecg.common.system.vo;
+
+
+/**
+ * @Description: 系统文件实体类
+ * @author: wangshuai
+ * @date: 2022年08月11日 9:48
+ */
+public class SysFilesModel {
+    /**主键id*/
+    private String id;
+    /**文件名称*/
+    private String fileName;
+    /**文件地址*/
+    private String url;
+    /**文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片  archive:其他文档 video:视频)*/
+    private String fileType;
+    /**文件上传类型(temp/本地上传(临时文件) manage/知识库)*/
+    private String storeType;
+    /**文件大小(kb)*/
+    private Double fileSize;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getFileType() {
+        return fileType;
+    }
+
+    public void setFileType(String fileType) {
+        this.fileType = fileType;
+    }
+
+    public String getStoreType() {
+        return storeType;
+    }
+
+    public void setStoreType(String storeType) {
+        this.storeType = storeType;
+    }
+
+    public Double getFileSize() {
+        return fileSize;
+    }
+
+    public void setFileSize(Double fileSize) {
+        this.fileSize = fileSize;
+    }
+}

+ 17 - 9
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java

@@ -127,10 +127,14 @@ public class CommonUtils {
      */
     public static String upload(MultipartFile file, String bizPath, String uploadType) {
         String url = "";
-        if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
-            url = MinioUtil.upload(file,bizPath);
-        }else{
-            url = OssBootUtil.upload(file,bizPath);
+        try {
+            if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
+                url = MinioUtil.upload(file, bizPath);
+            } else {
+                url = OssBootUtil.upload(file, bizPath);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
         }
         return url;
     }
@@ -186,10 +190,14 @@ public class CommonUtils {
      */
     public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) {
         String url = "";
-        if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
-            url = MinioUtil.upload(file,bizPath,customBucket);
-        }else{
-            url = OssBootUtil.upload(file,bizPath,customBucket);
+        try {
+            if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
+                url = MinioUtil.upload(file, bizPath, customBucket);
+            } else {
+                url = OssBootUtil.upload(file, bizPath, customBucket);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
         }
         return url;
     }
@@ -340,7 +348,7 @@ public class CommonUtils {
         }else{
             baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
         }
-        log.info("-----Common getBaseUrl----- : " + baseDomainPath);
+        log.debug("-----Common getBaseUrl----- : " + baseDomainPath);
         return baseDomainPath;
     }
 }

+ 13 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -671,4 +671,17 @@ public class DateUtils extends PropertyEditorSupport {
         return calendar.get(Calendar.YEAR);
     }
 
+    /**
+     * 将字符串转成时间
+     * @param str
+     * @return
+     */
+    public static Date parseDatetime(String str){
+        try {
+            return datetimeFormat.get().parse(str);
+        }catch (Exception e){
+        }
+        return null;
+    }
+
 }

+ 11 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/HTMLUtils.java

@@ -1,6 +1,7 @@
 package org.jeecg.common.util;
 
 import org.apache.commons.lang3.StringUtils;
+import org.pegdown.PegDownProcessor;
 import org.springframework.web.util.HtmlUtils;
 
 /**
@@ -29,4 +30,14 @@ public class HTMLUtils {
         return "";
     }
 
+    /**
+     * 将Markdown解析成Html
+     * @param markdownContent
+     * @return
+     */
+    public static String parseMarkdown(String markdownContent) {
+        PegDownProcessor pdp = new PegDownProcessor();
+        return pdp.markdownToHtml(markdownContent);
+    }
+
 }

+ 0 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/IpUtils.java

@@ -11,8 +11,6 @@ import org.slf4j.LoggerFactory;
  * IP地址
  * 
  * @Author scott
- *
- * update: 【类名改了大小写】 date: 2022-04-18
  * @email jeecgos@163.com
  * @Date 2019年01月14日
  */

+ 0 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/Md5Util.java

@@ -4,8 +4,6 @@ import java.security.MessageDigest;
 
 /**
  * @Description: 加密工具
- *
- * update: 【类名改了大小写】 date: 2022-04-18
  * @author: jeecg-boot
  */
 public class Md5Util {

+ 9 - 7
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/MinioUtil.java

@@ -53,11 +53,16 @@ public class MinioUtil {
      * @param file
      * @return
      */
-    public static String upload(MultipartFile file, String bizPath, String customBucket) {
+    public static String upload(MultipartFile file, String bizPath, String customBucket) throws Exception {
         String fileUrl = "";
         //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
-        bizPath=StrAttackFilter.filter(bizPath);
+        bizPath = StrAttackFilter.filter(bizPath);
         //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
+
+        //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
+        FileTypeFilter.fileTypeFilter(file);
+        //update-end-author:liusq date:20210809 for: 过滤上传文件类型
+
         String newBucket = bucketName;
         if(oConvertUtils.isNotEmpty(customBucket)){
             newBucket = customBucket;
@@ -72,9 +77,6 @@ public class MinioUtil {
                 minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
                 log.info("create a new bucket.");
             }
-            //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
-            FileTypeFilter.fileTypeFilter(file);
-            //update-end-author:liusq date:20210809 for: 过滤上传文件类型
             InputStream stream = file.getInputStream();
             // 获取文件名
             String orgName = file.getOriginalFilename();
@@ -111,8 +113,8 @@ public class MinioUtil {
      * @param bizPath
      * @return
      */
-    public static String upload(MultipartFile file, String bizPath) {
-        return  upload(file,bizPath,null);
+    public static String upload(MultipartFile file, String bizPath) throws Exception {
+        return upload(file,bizPath,null);
     }
 
     /**

+ 13 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/RestUtil.java

@@ -3,6 +3,7 @@ package org.jeecg.common.util;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.jeecg.config.JeecgBaseConfig;
 import org.springframework.http.*;
 import org.springframework.http.client.SimpleClientHttpRequestFactory;
 import org.springframework.http.converter.StringHttpMessageConverter;
@@ -46,7 +47,18 @@ public class RestUtil {
     }
 
     public static String getBaseUrl() {
-        String basepath = getDomain() + getPath();
+        String basepath = null;
+        try {
+            basepath = getDomain() + getPath();
+        } catch (Exception e) {
+            log.warn(e.getMessage(),e);
+        }
+
+        //定时任务情况下,通过request是获取不到domain的,这种情况下通过配置获取pc后台域名
+        if(oConvertUtils.isEmpty(basepath)){
+            JeecgBaseConfig jeecgBaseConfig = SpringContextUtils.getBean(JeecgBaseConfig.class);
+            basepath = jeecgBaseConfig.getDomainUrl().getPc();
+        }
         log.info(" RestUtil.getBaseUrl: " + basepath);
         return basepath;
     }

+ 1 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/SysAnnmentTypeEnum.java

@@ -10,7 +10,7 @@ public enum SysAnnmentTypeEnum {
      */
     EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"),
     /**
-     * 工作流跳转链接我的办公
+     * 流程跳转到我的任务
      */
     BPM("bpm", "url", "/bpm/task/MyTaskList");
 

+ 19 - 5
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/dynamic/db/FreemarkerParseFactory.java

@@ -2,6 +2,7 @@ package org.jeecg.common.util.dynamic.db;
 
 import freemarker.cache.StringTemplateLoader;
 import freemarker.core.ParseException;
+import freemarker.core.TemplateClassResolver;
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import lombok.extern.slf4j.Slf4j;
@@ -53,6 +54,11 @@ public class FreemarkerParseFactory {
         SQL_CONFIG.setNumberFormat("0.#####################");
         //classic_compatible设置,解决报空指针错误
         SQL_CONFIG.setClassicCompatible(true);
+
+        //update-begin-author:taoyan date:2022-8-10 for: freemarker模板注入问题 禁止解析ObjectConstructor,Execute和freemarker.template.utility.JythonRuntime。
+        //https://ackcent.com/in-depth-freemarker-template-injection/
+        SQL_CONFIG.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
+        //update-end-author:taoyan date:2022-8-10 for: freemarker模板注入问题 禁止解析ObjectConstructor,Execute和freemarker.template.utility.JythonRuntime。
     }
 
     /**
@@ -115,8 +121,10 @@ public class FreemarkerParseFactory {
      * @param paras      参数
      * @return String 模板解析后内容
      */
-    public static String parseTemplateContent(String tplContent,
-                                              Map<String, Object> paras) {
+    public static String parseTemplateContent(String tplContent,Map<String, Object> paras) {
+        return parseTemplateContent(tplContent, paras, false);
+    }
+    public static String parseTemplateContent(String tplContent, Map<String, Object> paras, boolean keepSpace) {
         try {
             String sqlUnderline="sql_";
             StringWriter swriter = new StringWriter();
@@ -129,7 +137,7 @@ public class FreemarkerParseFactory {
             }
             paras.put(MINI_DAO_FORMAT, new SimpleFormat());
             mytpl.process(paras, swriter);
-            String sql = getSqlText(swriter.toString());
+            String sql = getSqlText(swriter.toString(), keepSpace);
             paras.remove(MINI_DAO_FORMAT);
             return sql;
         } catch (Exception e) {
@@ -145,10 +153,16 @@ public class FreemarkerParseFactory {
      * 除去无效字段,去掉注释 不然批量处理可能报错 去除无效的等于
      */
     private static String getSqlText(String sql) {
+        return getSqlText(sql, false);
+    }
+
+    private static String getSqlText(String sql, boolean keepSpace) {
         // 将注释替换成""
         sql = NOTES_PATTERN.matcher(sql).replaceAll("");
-        sql = sql.replaceAll("\\n", " ").replaceAll("\\t", " ")
-                .replaceAll("\\s{1,}", " ").trim();
+        if (!keepSpace) {
+            sql = sql.replaceAll("\\n", " ").replaceAll("\\t", " ")
+                    .replaceAll("\\s{1,}", " ").trim();
+        }
         // 去掉 最后是 where这样的问题
         //where空格 "where "
         String whereSpace = DataBaseConstant.SQL_WHERE+" ";

+ 1 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/filter/FileTypeFilter.java

@@ -98,7 +98,7 @@ public class FileTypeFilter {
         String suffix = getFileType(file);
         for (String type : forbidType) {
             if (type.contains(suffix)) {
-                throw new Exception("上传失败,文件类型异常:" + suffix);
+                throw new Exception("上传失败,非法文件类型:" + suffix);
             }
         }
     }

+ 8 - 5
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java

@@ -96,7 +96,11 @@ public class OssBootUtil {
      * @param fileDir 文件保存目录
      * @return oss 中的相对文件路径
      */
-    public static String upload(MultipartFile file, String fileDir,String customBucket) {
+    public static String upload(MultipartFile file, String fileDir,String customBucket) throws Exception {
+        //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
+        FileTypeFilter.fileTypeFilter(file);
+        //update-end-author:liusq date:20210809 for: 过滤上传文件类型
+
         String filePath = null;
         initOss(endPoint, accessKeyId, accessKeySecret);
         StringBuilder fileUrl = new StringBuilder();
@@ -114,9 +118,6 @@ public class OssBootUtil {
             if("" == orgName){
               orgName=file.getName();
             }
-            //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
-            FileTypeFilter.fileTypeFilter(file);
-            //update-end-author:liusq date:20210809 for: 过滤上传文件类型
             orgName = CommonUtils.getFileName(orgName);
             String fileName = orgName.indexOf(".")==-1
                               ?orgName + "_" + System.currentTimeMillis()
@@ -169,7 +170,7 @@ public class OssBootUtil {
      * @param fileDir
      * @return
      */
-    public static String upload(MultipartFile file, String fileDir) {
+    public static String upload(MultipartFile file, String fileDir) throws Exception {
         return upload(file, fileDir,null);
     }
 
@@ -235,6 +236,8 @@ public class OssBootUtil {
         } else {
             bucketUrl = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH;
         }
+        //TODO 暂时不允许删除云存储的文件
+        //initOss(endPoint, accessKeyId, accessKeySecret);
         url = url.replace(bucketUrl,"");
         ossClient.deleteObject(newBucket, url);
     }

+ 46 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/security/JdbcSecurityUtil.java

@@ -0,0 +1,46 @@
+package org.jeecg.common.util.security;
+
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.common.util.oConvertUtils;
+
+/**
+ * jdbc连接校验
+ * @Author taoYan
+ * @Date 2022/8/10 18:15
+ **/
+public class JdbcSecurityUtil {
+
+    /**
+     * 连接驱动漏洞 最新版本修复后,可删除相应的key
+     * postgre:authenticationPluginClassName, sslhostnameverifier, socketFactory, sslfactory, sslpasswordcallback
+     * https://github.com/pgjdbc/pgjdbc/security/advisories/GHSA-v7wg-cpwc-24m4
+     * 
+     */
+    public static final String[] notAllowedProps = new String[]{"authenticationPluginClassName", "sslhostnameverifier", "socketFactory", "sslfactory", "sslpasswordcallback"};
+
+    /**
+     * 校验sql是否有特定的key
+     * @param jdbcUrl
+     * @return
+     */
+    public static void validate(String jdbcUrl){
+        if(oConvertUtils.isEmpty(jdbcUrl)){
+            return;
+        }
+        String urlConcatChar = "?";
+        if(jdbcUrl.indexOf(urlConcatChar)<0){
+            return;
+        }
+        String argString = jdbcUrl.substring(jdbcUrl.indexOf(urlConcatChar)+1);
+        String[] keyAndValues = argString.split("&");
+        for(String temp: keyAndValues){
+            String key = temp.split("=")[0];
+            for(String prop: notAllowedProps){
+                if(prop.equalsIgnoreCase(key)){
+                    throw new JeecgBootException("连接地址有安全风险,【"+key+"】");
+                }
+            }
+        }
+    }
+    
+}

+ 19 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/config/JeecgBaseConfig.java

@@ -23,7 +23,11 @@ public class JeecgBaseConfig {
      * 需要加强校验的接口清单
      */
     private String signUrls;
-
+    /**
+     * 上传模式  
+     * 本地:local\Minio:minio\阿里云:alioss
+     */
+    private String uploadType;
     /**
      * 是否启用安全模式
      */
@@ -44,6 +48,11 @@ public class JeecgBaseConfig {
      */
     private DomainUrl domainUrl;
 
+    /**
+     * 文件预览
+     */
+    private String fileViewDomain;
+
     public Boolean getSafeMode() {
         return safeMode;
     }
@@ -83,7 +92,6 @@ public class JeecgBaseConfig {
     public void setDomainUrl(DomainUrl domainUrl) {
         this.domainUrl = domainUrl;
     }
-
     public String getSignUrls() {
         return signUrls;
     }
@@ -91,4 +99,13 @@ public class JeecgBaseConfig {
     public void setSignUrls(String signUrls) {
         this.signUrls = signUrls;
     }
+
+
+    public String getFileViewDomain() {
+        return fileViewDomain;
+    }
+
+    public void setFileViewDomain(String fileViewDomain) {
+        this.fileViewDomain = fileViewDomain;
+    }
 }

+ 3 - 4
jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger2Config.java

@@ -75,8 +75,8 @@ public class Swagger2Config implements WebMvcConfigurer {
                 .paths(PathSelectors.any())
                 .build()
                 .securitySchemes(Collections.singletonList(securityScheme()))
-                .securityContexts(securityContexts());
-                //.globalOperationParameters(setHeaderToken());
+                .securityContexts(securityContexts())
+                .globalOperationParameters(setHeaderToken());
     }
 
     /***
@@ -109,7 +109,7 @@ public class Swagger2Config implements WebMvcConfigurer {
     private ApiInfo apiInfo() {
         return new ApiInfoBuilder()
                 // //大标题
-                .title("Jeecg-Boot 后台服务API接口文档")
+                .title("JeecgBoot 后台服务API接口文档")
                 // 版本号
                 .version("1.0")
 //				.termsOfServiceUrl("NO terms of service")
@@ -117,7 +117,6 @@ public class Swagger2Config implements WebMvcConfigurer {
                 .description("后台API接口")
                 // 作者
                 .contact(new Contact("北京国炬信息技术有限公司","www.jeccg.com","jeecgos@163.com"))
-               // .contact("JEECG团队")
                 .license("The Apache License, Version 2.0")
                 .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                 .build();

+ 2 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/config/WebMvcConfiguration.java

@@ -29,6 +29,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -45,7 +46,7 @@ import java.util.List;
 @Configuration
 public class WebMvcConfiguration implements WebMvcConfigurer {
 
-    @Autowired
+    @Resource
     JeecgBaseConfig jeecgBaseConfig;
     @Value("${spring.resource.static-locations:}")
     private String staticLocations;

+ 2 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java

@@ -30,7 +30,8 @@ public class WebSocketConfig {
     public FilterRegistrationBean getFilterRegistrationBean(){
         FilterRegistrationBean bean = new FilterRegistrationBean();
         bean.setFilter(websocketFilter());
-        bean.addUrlPatterns("/websocket/*", "/eoaSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
+        //TODO 临时注释掉,测试下线上socket总断的问题
+        bean.addUrlPatterns("/websocket/*","/eoaSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
         return bean;
     }
 

+ 4 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java

@@ -5,6 +5,7 @@ import org.jeecg.common.api.CommonAPI;
 import org.jeecg.common.util.RedisUtil;
 import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.TokenUtils;
+import org.jeecg.common.util.oConvertUtils;
 
 import javax.servlet.*;
 import javax.servlet.http.HttpServletRequest;
@@ -36,12 +37,13 @@ public class WebsocketFilter implements Filter {
         HttpServletRequest request = (HttpServletRequest)servletRequest;
         String token = request.getHeader(TOKEN_KEY);
 
-        log.info("websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);
+        log.debug("Websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);
 
         try {
             TokenUtils.verifyToken(token, commonApi, redisUtil);
         } catch (Exception exception) {
-            log.error("websocket连接校验失败,{},token:{}", exception.getMessage(), token);
+            //log.error("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());
+            log.debug("Websocket连接 Token安全校验失败,IP:{}, Token:{}, Path = {},异常:{}", oConvertUtils.getIpAddrByRequest(request), token, request.getRequestURI(), exception.getMessage());
             return;
         }
         HttpServletResponse response = (HttpServletResponse)servletResponse;

+ 2 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

@@ -66,7 +66,7 @@ public class ShiroConfig {
         Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
 
         //支持yml方式,配置拦截排除
-        if(jeecgBaseConfig.getShiro()!=null){
+        if(jeecgBaseConfig!=null && jeecgBaseConfig.getShiro()!=null){
             String shiroExcludeUrls = jeecgBaseConfig.getShiro().getExcludeUrls();
             if(oConvertUtils.isNotEmpty(shiroExcludeUrls)){
                 String[] permissionUrl = shiroExcludeUrls.split(",");
@@ -109,6 +109,7 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/**/*.pdf", "anon");
         filterChainDefinitionMap.put("/**/*.jpg", "anon");
         filterChainDefinitionMap.put("/**/*.png", "anon");
+        filterChainDefinitionMap.put("/**/*.gif", "anon");
         filterChainDefinitionMap.put("/**/*.ico", "anon");
 
         // update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀

+ 0 - 3
jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/interceptor/SignAuthConfiguration.java

@@ -2,7 +2,6 @@ package org.jeecg.config.sign.interceptor;
 
 import org.apache.commons.lang3.StringUtils;
 import org.jeecg.common.util.PathMatcherUtil;
-import org.jeecg.common.util.SpringContextHolder;
 import org.jeecg.config.JeecgBaseConfig;
 import org.jeecg.config.filter.RequestBodyReserveFilter;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
@@ -12,8 +11,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 import javax.annotation.Resource;
-import java.util.Arrays;
-import java.util.List;
 
 /**
  * 签名 拦截器配置

+ 8 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/SignUtil.java

@@ -10,6 +10,7 @@ import org.jeecg.config.JeecgBaseConfig;
 import org.springframework.util.DigestUtils;
 import org.springframework.util.StringUtils;
 
+import java.io.UnsupportedEncodingException;
 import java.util.SortedMap;
 
 /**
@@ -54,6 +55,12 @@ public class SignUtil {
         if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains(curlyBracket)){
             throw new JeecgBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 !!");
         }
-        return DigestUtils.md5DigestAsHex((paramsJsonStr + signatureSecret).getBytes()).toUpperCase();
+        try {
+            //【issues/I484RW】2.4.6部署后,下拉搜索框提示“sign签名检验失败”
+            return DigestUtils.md5DigestAsHex((paramsJsonStr + signatureSecret).getBytes("UTF-8")).toUpperCase();
+        } catch (UnsupportedEncodingException e) {
+            log.error(e.getMessage(),e);
+            return null;
+        }
     }
 }

+ 0 - 1
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/mock/vxe/websocket/VxeSocket.java

@@ -18,7 +18,6 @@ import java.util.Map;
 
 /**
  * vxe WebSocket,用于实现实时无痕刷新的功能
- * update: 【类名改了大小写】 date: 2022-04-18
  * @author: jeecg-boot
  */
 @Slf4j

+ 13 - 1
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/controller/JeecgDemoController.java

@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
@@ -455,5 +457,15 @@ public class JeecgDemoController extends JeecgController<JeecgDemo, IJeecgDemoSe
         return page;
     }
     // =====Vue3 Native  原生页面示例===============================================================================================
-    
+
+
+    /**
+     * 获取创建人
+     * @return
+     */
+    @GetMapping(value = "/groupList")
+    public Result<?> groupList() {
+        return Result.ok(jeecgDemoService.getCreateByList());
+    }
+
 }

+ 7 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/JeecgDemoMapper.java

@@ -47,4 +47,11 @@ public interface JeecgDemoMapper extends BaseMapper<JeecgDemo> {
 	 */
 	public List<String> queryUserAuth(@Param("userId")String userId,@Param("permsPrefix")String permsPrefix);
 
+
+	/**
+	 * 获取创建人
+	 * @return
+	 */
+	List<String> getCreateByList();
+
 }

+ 6 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/mapper/xml/JeecgDemoMapper.xml

@@ -31,4 +31,10 @@
         and sur.user_id = #{userId}
         and sp.perms like concat(concat('%',#{permsPrefix}),'%')
     </select>
+
+    <!--  获取创建人 -->
+    <select id="getCreateByList" resultType="java.lang.String">
+        select create_by from demo group by create_by
+    </select>
+    
 </mapper>

+ 8 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/IJeecgDemoService.java

@@ -5,6 +5,8 @@ import org.jeecg.modules.demo.test.entity.JeecgDemo;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import java.util.List;
+
 /**
  * @Description: jeecg 测试demo
  * @Author: jeecg-boot
@@ -38,4 +40,10 @@ public interface IJeecgDemoService extends JeecgService<JeecgDemo> {
 	 * @return
 	 */
 	String getExportFields();
+
+	/**
+	 * 获取创建人
+	 * @return
+	 */
+	List<String> getCreateByList();
 }

+ 5 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/test/service/impl/JeecgDemoServiceImpl.java

@@ -108,4 +108,9 @@ public class JeecgDemoServiceImpl extends ServiceImpl<JeecgDemoMapper, JeecgDemo
 		return exportFieldsList != null && exportFieldsList.size()>0 ? String.join(",", exportFieldsList) : "";
 	}
 
+	@Override
+	public List<String> getCreateByList() {
+		return jeecgDemoMapper.getCreateByList();
+	}
+
 }

+ 33 - 0
jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -2,6 +2,7 @@ package org.jeecg.common.system.api;
 
 import com.alibaba.fastjson.JSONObject;
 import org.jeecg.common.api.CommonAPI;
+import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.constant.ServiceNameConstants;
@@ -549,4 +550,36 @@ public interface ISysBaseAPI extends CommonAPI {
      */
     @GetMapping("/sys/api/getTemplateContent")
     String getTemplateContent(@RequestParam("code") String code);
+
+    /**
+     * 新增数据日志
+     * @param dataLogDto
+     */
+    @PostMapping("/sys/api/saveDataLog")
+    void saveDataLog(DataLogDTO dataLogDto);
+
+    /**
+     * 添加文件到知识库
+     * @param sysFilesModel
+     */
+    @PostMapping("/sys/api/addSysFiles")
+    void addSysFiles(SysFilesModel sysFilesModel);
+
+    /**
+     * 通过文件路径获取文件id
+     * @param fileId
+     */
+    @GetMapping("/sys/api/getFileUrl")
+    String getFileUrl(@RequestParam(name="fileId") String fileId);
+
+    /**
+     * 更新头像
+     * @param loginUser
+     * @return
+     */
+    @PutMapping("/updateAvatar")
+    void updateAvatar(@RequestBody LoginUser loginUser);
+
+    @GetMapping("/sendAppChatSocket")
+    void sendAppChatSocket(@RequestParam(name="userId") String userId);
 }

+ 25 - 0
jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java

@@ -3,6 +3,7 @@ package org.jeecg.common.system.api.fallback;
 import com.alibaba.fastjson.JSONObject;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.system.api.ISysBaseAPI;
@@ -287,6 +288,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
         return null;
     }
 
+    @Override
+    public void saveDataLog(DataLogDTO dataLogDto) {
+
+    }
+
     @Override
     public void sendEmailMsg(String email,String title,String content) {
 
@@ -326,4 +332,23 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
         return null;
     }
+
+
+    @Override
+    public void addSysFiles(SysFilesModel sysFilesModel) {
+
+    }
+
+    @Override
+    public String getFileUrl(String fileId) {
+        return null;
+    }
+
+    @Override
+    public void updateAvatar(LoginUser loginUser) { }
+
+    @Override
+    public void sendAppChatSocket(String userId) {
+        
+    }
 }

+ 39 - 7
jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -2,6 +2,7 @@ package org.jeecg.common.system.api;
 
 import com.alibaba.fastjson.JSONObject;
 import org.jeecg.common.api.CommonAPI;
+import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.system.vo.*;
@@ -50,6 +51,21 @@ public interface ISysBaseAPI extends CommonAPI {
      */
     String parseTemplateByCode(TemplateDTO templateDTO);
 
+    //update-begin---author:taoyan ---date:20220705  for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
+    /**
+     * 发送模板消息【新,支持自定义推送类型】
+     * @param message
+     */
+    void sendTemplateMessage(MessageDTO message);
+
+    /**
+     * 根据模板编码获取模板内容【新,支持自定义推送类型】
+     * @param templateCode
+     * @return
+     */
+    String getTemplateContent(String templateCode);
+    //update-begin---author:taoyan ---date:20220705  for:支持自定义推送类型,邮件、钉钉、企业微信、系统消息-----------
+    
     /**
      * 6根据用户id查询用户信息
      * @param id
@@ -339,16 +355,32 @@ public interface ISysBaseAPI extends CommonAPI {
     List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize);
 
     /**
-     * 发送模板消息
-     * @param message
+     * 新增数据日志
+     * @param dataLogDto
      */
-    void sendTemplateMessage(MessageDTO message);
+    void saveDataLog(DataLogDTO dataLogDto);
 
     /**
-     * 根据模板编码获取模板内容
-     * @param templateCode
-     * @return
+     * 添加文件到知识库
+     * @param sysFilesModel
      */
-    String getTemplateContent(String templateCode);
+    void addSysFiles(SysFilesModel sysFilesModel);
+
+    /**
+     * 通过文件路径获取文件id
+     * @param fileId
+     */
+    String getFileUrl(String fileId);
 
+    /**
+     * 更新头像
+     * @param loginUser
+     */
+    void updateAvatar(LoginUser loginUser);
+
+    /**
+     * 向app端 websocket推送聊天刷新消息
+     * @param userId
+     */
+    void sendAppChatSocket(String userId);
 }

+ 2 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/init/CodeTemplateInitListener.java

@@ -18,6 +18,7 @@ import java.nio.charset.StandardCharsets;
  * <p>
  * 解决JAR发布需要手工配置代码生成器模板问题
  * http://doc.jeecg.com/2043922
+ * @author zhang
  */
 @Slf4j
 @Component
@@ -58,7 +59,7 @@ public class CodeTemplateInitListener implements ApplicationListener<Application
                 continue;
             }
             if (!FileUtil.exist(createFilePath)) {
-                log.debug("create file codeTemplate = " + createFilePath);
+                log.info("create file codeTemplate = " + createFilePath);
                 FileUtil.writeString(IOUtils.toString(url, StandardCharsets.UTF_8), createFilePath, "UTF-8");
             }
         }

+ 37 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java

@@ -2,6 +2,7 @@ package org.jeecg.modules.api.controller;
 
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.system.vo.*;
@@ -660,4 +661,40 @@ public class SystemApiController {
         return this.sysBaseApi.getTemplateContent(code);
     }
 
+    /**
+     * 保存数据日志
+     * @param dataLogDto
+     */
+    @PostMapping("/saveDataLog")
+    public void saveDataLog(@RequestBody DataLogDTO dataLogDto){
+        this.sysBaseApi.saveDataLog(dataLogDto);
+    }
+
+    @PostMapping("/addSysFiles")
+    public void addSysFiles(@RequestBody SysFilesModel sysFilesModel){this.sysBaseApi.addSysFiles(sysFilesModel);}
+
+    @GetMapping("/getFileUrl")
+    public String getFileUrl(@RequestParam(name="fileId") String fileId){
+        return this.sysBaseApi.getFileUrl(fileId);
+    }
+
+    /**
+     * 更新头像
+     * @param loginUser
+     * @return
+     */
+    @PutMapping("/updateAvatar")
+    public void updateAvatar(@RequestBody LoginUser loginUser){
+        this.sysBaseApi.updateAvatar(loginUser);
+    }
+
+    /**
+     * 向app端 websocket推送聊天刷新消息
+     * @param userId
+     * @return
+     */
+    @GetMapping("/sendAppChatSocket")
+    public void sendAppChatSocket(@RequestParam(name="userId") String userId){
+        this.sysBaseApi.sendAppChatSocket(userId);
+    }
 }

+ 2 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/TestSocketController.java

@@ -1,7 +1,8 @@
-package org.jeecg.modules.message.websocket;
+package org.jeecg.modules.message.controller;
 
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.WebsocketConst;
+import org.jeecg.modules.message.websocket.WebSocket;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;

+ 128 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/RangeDateEnum.java

@@ -0,0 +1,128 @@
+package org.jeecg.modules.message.enums;
+
+import org.jeecg.common.constant.enums.MessageTypeEnum;
+import org.jeecg.common.system.annotation.EnumDict;
+import org.jeecg.common.system.vo.DictModel;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 用于消息数据查询【vue3】
+ * 新版系统通知查询条件
+ * @Author taoYan
+ * @Date 2022/8/19 20:41
+ **/
+@EnumDict("rangeDate")
+public enum RangeDateEnum {
+
+    JT("jt", "今天"),
+    ZT("zt", "昨天"),
+    QT("qt", "前天"),
+    BZ("bz","本周"),
+    SZ("sz", "上周"),
+    BY("by", "本月"),
+    SY("sy", "上月"),
+    ZDY("zdy", "自定义日期");
+
+    String key;
+
+    String title;
+
+    RangeDateEnum(String key, String title){
+        this.key = key;
+        this.title = title;
+    }
+
+    /**
+     * 获取字典数据
+     * @return
+     */
+    public static List<DictModel> getDictList(){
+        List<DictModel> list = new ArrayList<>();
+        DictModel dictModel = null;
+        for(RangeDateEnum e: RangeDateEnum.values()){
+            dictModel = new DictModel();
+            dictModel.setValue(e.key);
+            dictModel.setText(e.title);
+            list.add(dictModel);
+        }
+        return list;
+    }
+
+    /**
+     * 根据key 获取范围时间值
+     * @param key
+     * @return
+     */
+    public static Date[] getRangeArray(String key){
+        Calendar calendar1 = Calendar.getInstance();
+        Calendar calendar2 = Calendar.getInstance();
+        Date[] array = new Date[2];
+        boolean flag = false;
+        if(JT.key.equals(key)){
+            //今天
+        } else if(ZT.key.equals(key)){
+            //昨天
+            calendar1.add(Calendar.DAY_OF_YEAR, -1);
+            calendar2.add(Calendar.DAY_OF_YEAR, -1);
+        } else if(QT.key.equals(key)){
+            //前天
+            calendar1.add(Calendar.DAY_OF_YEAR, -2);
+            calendar2.add(Calendar.DAY_OF_YEAR, -2);
+        } else if(BZ.key.equals(key)){
+            //本周
+            calendar1.set(Calendar.DAY_OF_WEEK, 2);
+
+            calendar2.add(Calendar.WEEK_OF_MONTH,1);
+            calendar2.add(Calendar.DAY_OF_WEEK,-1);
+        } else if(SZ.key.equals(key)){
+            //本周一减一周
+            calendar1.set(Calendar.DAY_OF_WEEK, 2);
+            calendar1.add(Calendar.WEEK_OF_MONTH, -1);
+
+            // 本周一减一天
+            calendar2.set(Calendar.DAY_OF_WEEK, 2);
+            calendar2.add(Calendar.DAY_OF_WEEK,-1);
+        } else if(BY.key.equals(key)){
+            //本月
+            calendar1.set(Calendar.DAY_OF_MONTH, 1);
+
+            calendar2.set(Calendar.DAY_OF_MONTH, 1);
+            calendar2.add(Calendar.MONTH, 1);
+            calendar2.add(Calendar.DAY_OF_MONTH, -1);
+        } else if(SY.key.equals(key)){
+            //本月第一天减一月
+            calendar1.set(Calendar.DAY_OF_MONTH, 1);
+            calendar1.add(Calendar.MONTH, -1);
+
+            //本月第一天减一天
+            calendar2.set(Calendar.DAY_OF_MONTH, 1);
+            calendar2.add(Calendar.DAY_OF_MONTH, -1);
+        }else{
+            flag = true;
+        }
+        if(flag){
+            return null;
+        }
+        // 开始时间00:00:00 结束时间23:59:59
+        calendar1.set(Calendar.HOUR, 0);
+        calendar1.set(Calendar.MINUTE, 0);
+        calendar1.set(Calendar.SECOND, 0);
+        calendar1.set(Calendar.MILLISECOND, 0);
+        calendar2.set(Calendar.HOUR, 23);
+        calendar2.set(Calendar.MINUTE, 59);
+        calendar2.set(Calendar.SECOND, 59);
+        calendar2.set(Calendar.MILLISECOND, 999);
+        array[0] = calendar1.getTime();
+        array[1] = calendar2.getTime();
+        return array;
+    }
+    
+    public String getKey(){
+        return this.key;
+    }
+
+}

+ 65 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/Vue3MessageHrefEnum.java

@@ -0,0 +1,65 @@
+package org.jeecg.modules.message.enums;
+
+import org.jeecg.common.system.annotation.EnumDict;
+import org.jeecg.common.system.vo.DictModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 消息跳转【vue3】
+ * @Author taoYan
+ * @Date 2022/8/19 20:41
+ **/
+@EnumDict("messageHref")
+public enum Vue3MessageHrefEnum {
+
+    /**
+     * 流程催办
+     */
+    BPM("bpm", "/task/myHandleTaskInfo"),
+
+    /**
+     * 节点通知
+     */
+    BPM_TASK("bpm_task", "/task/myHandleTaskInfo"),
+
+    /**
+     * 邮件消息
+     */
+    EMAIL("email", "/eoa/email");
+    
+    String busType;
+    
+    String path;
+
+    Vue3MessageHrefEnum(String busType, String path) {
+        this.busType = busType;
+        this.path = path;
+    }
+
+    public String getBusType() {
+        return busType;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * 获取字典数据
+     * @return
+     */
+    public static List<DictModel> getDictList(){
+        List<DictModel> list = new ArrayList<>();
+        DictModel dictModel = null;
+        for(Vue3MessageHrefEnum e: Vue3MessageHrefEnum.values()){
+            dictModel = new DictModel();
+            dictModel.setValue(e.getBusType());
+            dictModel.setText(e.getPath());
+            list.add(dictModel);
+        }
+        return list;
+    }
+    
+}

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java

@@ -10,7 +10,7 @@ public interface ISendMsgHandle {
 
     /**
      * 发送信息
-     * @param esReceiver 发送
+     * @param esReceiver 接受
      * @param esTitle 标题
      * @param esContent 内容
      */

+ 4 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java

@@ -76,12 +76,15 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
         List<SysUser> list = sysUserMapper.selectList(query);
         String content = messageDTO.getContent();
         String title = messageDTO.getTitle();
+        String realNameExp = "{REALNAME}";
         for(SysUser user: list){
             String email = user.getEmail();
             if(email==null || "".equals(email)){
                 continue;
             }
-
+            if(content.indexOf(realNameExp)>0){
+                content = content.replace(realNameExp, user.getRealname());
+            }
             if(content.indexOf(CommonConstant.LOGIN_TOKEN)>0){
                 String token = getToken(user);
                 try {

+ 2 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java

@@ -8,6 +8,7 @@ import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.api.ISysBaseAPI;
 import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.message.enums.Vue3MessageHrefEnum;
 import org.jeecg.modules.message.handle.ISendMsgHandle;
 import org.jeecg.modules.message.websocket.WebSocket;
 import org.jeecg.modules.system.entity.SysAnnouncement;
@@ -89,6 +90,7 @@ public class SystemSendMsgHandle implements ISendMsgHandle {
             Object taskId = data.get(CommonConstant.NOTICE_MSG_BUS_ID);
             if(taskId!=null){
                 announcement.setBusId(taskId.toString());
+                announcement.setBusType(Vue3MessageHrefEnum.BPM_TASK.getBusType());
             }
         }
         announcement.setTitile(title);

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java

@@ -17,7 +17,7 @@ public interface IOssFileService extends IService<OssFile> {
      * @param multipartFile
      * @throws IOException
      */
-	void upload(MultipartFile multipartFile) throws IOException;
+	void upload(MultipartFile multipartFile) throws Exception;
 
     /**
      * oss文件删除

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java

@@ -19,7 +19,7 @@ import java.io.IOException;
 public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> implements IOssFileService {
 
 	@Override
-	public void upload(MultipartFile multipartFile) throws IOException {
+	public void upload(MultipartFile multipartFile) throws Exception {
 		String fileName = multipartFile.getOriginalFilename();
 		fileName = CommonUtils.getFileName(fileName);
 		OssFile ossFile = new OssFile();

+ 1 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java

@@ -280,4 +280,5 @@ public class QuartzJobController {
 		}
 		return Result.ok("执行成功!");
 	}
+
 }

+ 50 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.system.controller;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -16,9 +17,11 @@ import org.jeecg.common.constant.WebsocketConst;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.util.JwtUtil;
 import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.DateUtils;
 import org.jeecg.common.util.RedisUtil;
 import org.jeecg.common.util.TokenUtils;
 import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.message.enums.RangeDateEnum;
 import org.jeecg.modules.message.websocket.WebSocket;
 import org.jeecg.modules.system.entity.SysAnnouncement;
 import org.jeecg.modules.system.entity.SysAnnouncementSend;
@@ -45,10 +48,8 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
 
@@ -70,9 +71,9 @@ public class SysAnnouncementController {
 	@Resource
     private WebSocket webSocket;
 	@Autowired
-	ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
+    ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
 	@Autowired
-	ThirdAppDingtalkServiceImpl dingtalkService;
+    ThirdAppDingtalkServiceImpl dingtalkService;
 	@Autowired
 	private SysBaseApiImpl sysBaseApi;
 	@Autowired
@@ -506,4 +507,47 @@ public class SysAnnouncementController {
         return modelAndView;
     }
 
+	/**
+	 * 【vue3用】 消息列表查询
+	 * @param fromUser
+	 * @param beginDate
+	 * @param endDate
+	 * @param pageNo
+	 * @param pageSize
+	 * @return
+	 */
+	@RequestMapping(value = "/vue3List", method = RequestMethod.GET)
+	public Result<List<SysAnnouncement>> vue3List(@RequestParam(name="fromUser", required = false) String fromUser,
+												  @RequestParam(name="starFlag", required = false) String starFlag,
+                                                  @RequestParam(name="rangeDateKey", required = false) String rangeDateKey,
+                                                  @RequestParam(name="beginDate", required = false) String beginDate, @RequestParam(name="endDate", required = false) String endDate,
+                                                  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
+		// 后台获取开始时间/结束时间
+		Date bd=null, ed=null;
+		if(RangeDateEnum.ZDY.getKey().equals(rangeDateKey)){
+			if(oConvertUtils.isNotEmpty(beginDate)){
+				bd = DateUtils.parseDatetime(beginDate);
+			}
+			if(oConvertUtils.isNotEmpty(endDate)){
+				ed = DateUtils.parseDatetime(endDate);
+			}
+		}else{
+			Date[] arr = RangeDateEnum.getRangeArray(rangeDateKey);
+			if(arr!=null){
+				bd = arr[0];
+				ed = arr[1];
+			}
+		}
+		List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag, bd, ed);
+		//查询出来的消息全部设置为已读
+		if(ls!=null && ls.size()>0){
+			String readed = "1";
+			List<String> annoceIdList = ls.stream().filter(item->!readed.equals(item.getReadFlag())).map(item->item.getId()).collect(Collectors.toList());
+			if(annoceIdList!=null && annoceIdList.size()>0){
+				sysAnnouncementService.updateReaded(annoceIdList);
+			}
+		}
+		return Result.ok(ls);
+	}
+
 }

+ 13 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java

@@ -126,7 +126,7 @@ public class SysAnnouncementSendController {
 			boolean ok = sysAnnouncementSendService.updateById(sysAnnouncementSend);
 			//TODO 返回false说明什么?
 			if(ok) {
-				result.success("修改成功!");
+				result.success("操作成功!");
 			}
 		}
 		
@@ -253,4 +253,16 @@ public class SysAnnouncementSendController {
 		result.setMessage("全部已读");
 		return result;
 	}
+
+
+	 /**
+	  * 根据消息发送记录ID获取消息内容
+	  * @param sendId
+	  * @return
+	  */
+	 @GetMapping(value = "/getOne")
+	 public Result<AnnouncementSendModel> getOne(@RequestParam(name="sendId",required=true) String sendId) {
+		 AnnouncementSendModel model = sysAnnouncementSendService.getOne(sendId);
+		 return Result.ok(model);
+	 }
 }

+ 11 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDataLogController.java

@@ -6,6 +6,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysDataLog;
@@ -37,6 +38,7 @@ public class SysDataLogController {
 	public Result<IPage<SysDataLog>> queryPageList(SysDataLog dataLog,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
 									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
 		Result<IPage<SysDataLog>> result = new Result<IPage<SysDataLog>>();
+		dataLog.setType(CommonConstant.DATA_LOG_TYPE_JSON);
 		QueryWrapper<SysDataLog> queryWrapper = QueryGenerator.initQueryWrapper(dataLog, req.getParameterMap());
 		Page<SysDataLog> page = new Page<SysDataLog>(pageNo, pageSize);
 		IPage<SysDataLog> pageList = service.page(page, queryWrapper);
@@ -85,6 +87,15 @@ public class SysDataLogController {
 		QueryWrapper<SysDataLog> queryWrapper = new QueryWrapper<SysDataLog>();
 		queryWrapper.eq("data_table", dataTable);
 		queryWrapper.eq("data_id", dataId);
+		//update-begin-author:taoyan date:2022-7-26 for: 新增查询条件-type
+		String type = req.getParameter("type");
+		if (oConvertUtils.isNotEmpty(type)) {
+			queryWrapper.eq("type", type);
+		}
+		// 按时间倒序排
+		queryWrapper.orderByDesc("create_time");
+		//update-end-author:taoyan date:2022-7-26 for:新增查询条件-type
+
 		List<SysDataLog> list = service.list(queryWrapper);
 		if(list==null||list.size()<=0) {
 			result.error500("未找到版本信息");

+ 4 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictController.java

@@ -304,6 +304,8 @@ public class SysDictController {
 	/**
 	 * 【接口签名验证】
 	 * 根据表名——显示字段-存储字段 pid 加载树形数据
+	 * @param hasChildField 是否叶子节点字段
+	 * @param converIsLeafVal 是否需要系统转换 是否叶子节点的值 (0标识不转换、1标准系统自动转换)
 	 */
 	@SuppressWarnings("unchecked")
 	@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
@@ -312,6 +314,7 @@ public class SysDictController {
 												  @RequestParam(name="text") String text,
 												  @RequestParam(name="code") String code,
 												  @RequestParam(name="hasChildField") String hasChildField,
+												  @RequestParam(name="converIsLeafVal",defaultValue ="1") int converIsLeafVal,
 												  @RequestParam(name="condition") String condition,
 												  @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
 		Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
@@ -322,7 +325,7 @@ public class SysDictController {
 		// SQL注入漏洞 sign签名校验(表名,label字段,val字段,条件)
 		String dictCode = tbname+","+text+","+code+","+condition;
         SqlInjectionUtil.filterContent(dictCode);
-		List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tbname, text, code, pidField, pid,hasChildField);
+		List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tbname, text, code, pidField, pid,hasChildField,converIsLeafVal);
 		result.setSuccess(true);
 		result.setResult(ls);
 		return result;

+ 18 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java

@@ -78,16 +78,32 @@ public class SysPermissionController {
 	 * @return
 	 */
 	@RequestMapping(value = "/list", method = RequestMethod.GET)
-	public Result<List<SysPermissionTree>> list() {
+	public Result<List<SysPermissionTree>> list(SysPermission sysPermission, HttpServletRequest req) {
         long start = System.currentTimeMillis();
 		Result<List<SysPermissionTree>> result = new Result<>();
 		try {
 			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
 			query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
 			query.orderByAsc(SysPermission::getSortNo);
+			
+			//支持通过菜单名字,模糊查询
+			if(oConvertUtils.isNotEmpty(sysPermission.getName())){
+				query.like(SysPermission::getName, sysPermission.getName());
+			}
 			List<SysPermission> list = sysPermissionService.list(query);
 			List<SysPermissionTree> treeList = new ArrayList<>();
-			getTreeList(treeList, list, null);
+
+			//如果有菜单名查询条件,则平铺数据 不做上下级
+			if(oConvertUtils.isNotEmpty(sysPermission.getName())){
+				if(list!=null && list.size()>0){
+					treeList = list.stream().map(e -> {
+						e.setLeaf(true);
+						return new SysPermissionTree(e);
+					}).collect(Collectors.toList());
+				}
+			}else{
+				getTreeList(treeList, list, null);
+			}
 			result.setResult(treeList);
 			result.setSuccess(true);
             log.info("======获取全部菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java

@@ -33,7 +33,7 @@ public class SysUploadController {
      * @param request
      */
     @PostMapping(value = "/uploadMinio")
-    public Result<?> uploadMinio(HttpServletRequest request) {
+    public Result<?> uploadMinio(HttpServletRequest request) throws Exception {
         Result<?> result = new Result<>();
         String bizPath = request.getParameter("biz");
 

+ 16 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysAnnouncement.java

@@ -146,5 +146,20 @@ public class SysAnnouncement implements Serializable {
     /**
      * 钉钉task_id,用于撤回消息
      */
-    private java.lang.String dtTaskId;
+    private String dtTaskId;
+
+    /**
+     * 阅读状态 1表示已经阅读
+     */
+    private transient String readFlag;
+
+    /**
+     * 标星状态 1表示标星
+     */
+    private transient String starFlag;
+
+    /**
+     * 发送记录ID
+     */
+    private transient String sendId;
 }

+ 5 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysAnnouncementSend.java

@@ -45,4 +45,9 @@ public class SysAnnouncementSend implements Serializable {
 	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
 	private java.util.Date updateTime;
+
+	/**
+	 * 是否标星 当值为1是标星消息
+	 */
+	private String starFlag;
 }

+ 8 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java

@@ -72,4 +72,12 @@ public class SysDataLog implements Serializable {
      * 版本号
      */
     private String dataVersion;
+
+
+    //update-begin-author:taoyan date:2022-7-26 for: 用于表单评论记录日志 区分数据
+    /**
+     * 类型
+     */
+    private String type;
+    //update-end-author:taoyan date:2022-7-26 for: 用于表单评论记录日志 区分数据
 }

+ 4 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysThirdAccount.java

@@ -53,11 +53,11 @@ public class SysThirdAccount {
 	@Excel(name = "真实姓名", width = 15)
 	@ApiModelProperty(value = "真实姓名")
 	private java.lang.String realname;
-	/**真实姓名*/
-	@Excel(name = "真实姓名", width = 15)
-	@ApiModelProperty(value = "真实姓名")
+	/**第三方用户uuid*/
+	@Excel(name = "第三方用户uuid", width = 15)
+	@ApiModelProperty(value = "第三方用户uuid")
 	private java.lang.String thirdUserUuid;
-	/**真实姓名*/
+	/**第三方用户账号*/
 	@Excel(name = "第三方用户账号", width = 15)
 	@ApiModelProperty(value = "第三方用户账号")
 	private java.lang.String thirdUserId;

+ 11 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysAnnouncementMapper.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.system.mapper;
 
+import java.util.Date;
 import java.util.List;
 
 import org.apache.ibatis.annotations.Param;
@@ -25,4 +26,14 @@ public interface SysAnnouncementMapper extends BaseMapper<SysAnnouncement> {
      */
 	List<SysAnnouncement> querySysCementListByUserId(Page<SysAnnouncement> page, @Param("userId")String userId,@Param("msgCategory")String msgCategory);
 
+    /**
+     * 分页查询消息列表
+     * @param page
+     * @param userId
+     * @param fromUser
+     * @param beginDate
+     * @param endDate
+     * @return
+     */
+	List<SysAnnouncement> queryMessageList(Page<SysAnnouncement> page, @Param("userId")String userId, @Param("fromUser")String fromUser, @Param("starFlag")String starFlag, @Param("beginDate")Date beginDate, @Param("endDate")Date endDate);
 }

+ 12 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysAnnouncementSendMapper.java

@@ -32,4 +32,16 @@ public interface SysAnnouncementSendMapper extends BaseMapper<SysAnnouncementSen
 	 */
 	public List<AnnouncementSendModel> getMyAnnouncementSendList(Page<AnnouncementSendModel> page,@Param("announcementSendModel") AnnouncementSendModel announcementSendModel);
 
+	/**
+	 * 获取一条记录
+	 * @param sendId
+	 * @return
+	 */
+	AnnouncementSendModel getOne(@Param("sendId") String sendId);
+
+
+	/**
+	 * 修改为已读消息
+	 */
+	void updateReaded(@Param("userId") String userId, @Param("annoceIdList") List<String> annoceIdList);
 }

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java

@@ -194,7 +194,7 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
 	 * @return
 	 */
 	@Deprecated
-	List<TreeSelectModel> queryTreeList(@Param("query") Map<String, String> query,@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("pidField") String pidField,@Param("pid") String pid,@Param("hasChildField") String hasChildField);
+	List<TreeSelectModel> queryTreeList(@Param("query") Map<String, String> query,@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("pidField") String pidField,@Param("pid") String pid,@Param("hasChildField") String hasChildField,@Param("converIsLeafVal") int converIsLeafVal);
 
 	/**
 	 * 删除

+ 14 - 9
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysPermissionMapper.java

@@ -25,14 +25,6 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
 	 * @return
 	 */
 	public List<TreeModel> queryListByParentId(@Param("parentId") String parentId);
-
-	/**
-	 * 切换vue3菜单
-	 */
-	@Update("alter table sys_permission rename to sys_permission_v2")
-	public void backupVue2Menu();
-	@Update("alter table sys_permission_v3 rename to sys_permission")
-	public void changeVue3Menu();
 	
 	/**
 	 * 根据用户查询用户权限
@@ -49,6 +41,14 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
 	 */
 	@Update("update sys_permission set is_leaf=#{leaf} where id = #{id}")
 	public int setMenuLeaf(@Param("id") String id,@Param("leaf") int leaf);
+
+	/**
+	 * 切换vue3菜单
+	 */
+	@Update("alter table sys_permission rename to sys_permission_v2")
+	public void backupVue2Menu();
+	@Update("alter table sys_permission_v3 rename to sys_permission")
+	public void changeVue3Menu();
 	
 	/**
 	 * 获取模糊匹配规则的数据权限URL
@@ -67,5 +67,10 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
 	public int queryCountByUsername(@Param("username") String username, @Param("permission") SysPermission sysPermission);
 
 
-
+	/**
+	 * 查询部门权限数据
+	 * @param departId
+	 * @return
+	 */
+	List<SysPermission> queryDepartPermissionList(@Param("departId") String departId);
 }

+ 9 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepartMapper.java

@@ -38,4 +38,13 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
 	 * @return
 	 */
 	IPage<SysUser> queryDepartUserPageList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname);
+
+    /**
+     * 获取用户信息
+     * @param page
+     * @param orgCode
+     * @param keyword
+     * @return
+     */
+    IPage<SysUser> getUserInformation(Page<SysUser> page,  @Param("orgCode") String orgCode,  @Param("keyword") String keyword,@Param("userId") String userId);
 }

+ 31 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysAnnouncementMapper.xml

@@ -25,6 +25,10 @@
 		<result column="bus_id" property="busId" jdbcType="VARCHAR"/>
 		<result column="open_type" property="openType" jdbcType="VARCHAR"/>
 		<result column="open_page" property="openPage" jdbcType="VARCHAR"/>
+
+		<result column="read_flag" property="readFlag" jdbcType="VARCHAR"/>
+		<result column="star_flag" property="starFlag" jdbcType="VARCHAR"/>
+		<result column="send_id" property="sendId" jdbcType="VARCHAR"/>
 	</resultMap>
 	
 	
@@ -37,4 +41,31 @@
 	   order by create_time DESC
 	</select>
 
+
+	<!-- 查询消息记录 -->
+	<select id="queryMessageList" resultMap="SysAnnouncement">
+	   select a.*, 
+	   		b.read_flag, 
+	   		b.star_flag,
+	   		b.id as send_id
+	   from sys_announcement a
+	   join sys_announcement_send b on b.annt_id = a.id
+	   where a.send_status = '1' and a.del_flag = '0' and b.user_id = #{userId}
+		<if test="fromUser!=null and fromUser!=''">
+			and a.sender = #{fromUser}
+		</if>
+	
+		<if test="beginDate!=null">
+			and a.create_time &gt;= #{beginDate}
+		</if>
+		<if test="endDate!=null">
+			and a.create_time &lt;= #{endDate}
+		</if>
+
+		<if test="starFlag!=null and starFlag!=''">
+			and b.star_flag = #{starFlag}
+		</if>
+	   order by b.read_flag ASC,a.create_time DESC
+	</select>
+	
 </mapper>

+ 40 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysAnnouncementSendMapper.xml

@@ -13,6 +13,7 @@
 		<result column="msg_category" property="msgCategory" jdbcType="VARCHAR"/>
 		<result column="send_time" property="sendTime" jdbcType="TIMESTAMP"/>
 		<result column="bus_id" property="busId" jdbcType="VARCHAR"/>
+		<result column="bus_type" property="busType" jdbcType="VARCHAR"/>
 		<result column="open_type" property="openType" jdbcType="VARCHAR"/>
 		<result column="open_page" property="openPage" jdbcType="VARCHAR"/>
 	</resultMap>
@@ -35,6 +36,7 @@
 	   		sa.msg_category,
 	   		sa.send_time as send_time,
 	   		sa.bus_id as bus_id,
+	   		sa.bus_type as bus_type,
 			sa.open_type as open_type,
 			sa.open_page as open_page,
 			sa.msg_abstract
@@ -64,4 +66,42 @@
 	   order by sas.read_flag,sa.send_time desc
 	</select>
 
+
+
+	<!-- 查询一条消息 -->
+	<select id="getOne" parameterType="String" resultMap="AnnouncementSendModel">
+		select
+		sas.id,
+		sas.annt_id,
+		sas.user_id,
+		sas.read_flag,
+		sa.titile as titile,
+		sa.msg_content as msg_content,
+		sa.sender as sender,
+		sa.priority as priority,
+		sa.msg_category,
+		sa.send_time as send_time,
+		sa.bus_id as bus_id,
+		sa.open_type as open_type,
+		sa.open_page as open_page,
+		sa.msg_abstract
+		from sys_announcement_send sas
+		left join sys_announcement sa ON sas.annt_id = sa.id
+		where sa.send_status = '1'
+		and sa.del_flag = '0'
+		and sas.id = #{sendId}
+	</select>
+
+
+	<!-- 修改为已读消息 -->
+	<update id="updateReaded">
+		update sys_announcement_send set read_flag = '1'
+		 where user_id = #{userId} 
+			and annt_id in
+		<foreach collection="annoceIdList" index="index" item="id" open="(" separator="," close=")">
+			#{id}
+		</foreach>
+	</update>
+	
+
 </mapper>

+ 8 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml

@@ -128,7 +128,14 @@
 			   ${code} as "key",
 				<!-- udapte-begin-author:taoyan date:20211115 for: 自定义树控件只显示父节点,子节点无法展开 (此处还原不可再改) /issues/I4HZAL -->
 			   <if test="hasChildField != null and hasChildField != ''">
-			   	(case when ${hasChildField} = '1' then 0 else 1 end) as isLeaf,
+				   <choose>
+					   <when test="converIsLeafVal!=null and converIsLeafVal==1">
+						   (case when ${hasChildField} = '1' then 0 else 1 end) as isLeaf,
+					   </when>
+					   <otherwise>
+						   ${hasChildField} as isLeaf,
+					   </otherwise>
+				   </choose>
 			   </if>
 				<!-- udapte-end-author:taoyan date:20211115 for: 自定义树控件只显示父节点,子节点无法展开 (此处还原不可再改) /issues/I4HZAL -->
 			   ${pidField} as parentId

+ 10 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionMapper.xml

@@ -103,6 +103,15 @@
 			</if>
 		) temp
 	</select>
-	
+
+	<!-- 查询部门权限数据 -->
+	<select id="queryDepartPermissionList" parameterType="String"  resultType="org.jeecg.modules.system.entity.SysPermission">
+		SELECT * FROM sys_permission
+		where del_flag = 0
+		and id in (
+			select permission_id from sys_depart_permission where depart_id = #{departId}
+		)
+		order by sort_no ASC 
+	</select>
 
 </mapper>

+ 18 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserDepartMapper.xml

@@ -27,7 +27,7 @@
 		join sys_user_depart b on b.user_id = a.id
 		join sys_depart c on b.dep_id = c.id
 		<bind name="bindOrgCode" value="orgCode+'%'"/>
-		where a.del_flag = 0 and a.status = 1 and c.org_code like #{bindOrgCode}
+		where a.del_flag = 0 and a.status = 1 and c.org_code like #{bindOrgCode} and a.username!='_reserve_user_external'
 		<if test="username!=null and username!=''">
 			<bind name="bindUsername" value="'%'+username+'%'"/>
 			and a.username like #{bindUsername}
@@ -37,4 +37,21 @@
 			and a.realname like #{bindRealname}
 		</if>
 	</select>
+
+    <!--获取用户信息(聊天专用)-->
+    <select id="getUserInformation" resultType="org.jeecg.modules.system.entity.SysUser">
+        select DISTINCT a.* from sys_user a
+        left join sys_user_depart b on b.user_id = a.id
+        left join sys_depart c on b.dep_id = c.id
+        <bind name="bindOrgCode" value="orgCode+'%'"/>
+        where
+          a.del_flag = 0 and a.status = 1
+          and c.org_code like #{bindOrgCode}
+          and a.username!='_reserve_user_external'
+          and a.id !=#{userId}
+        <if test="keyword!=null and keyword!=''">
+            <bind name="bindKeyword" value="'%'+keyword+'%'"/>
+            and (a.username like #{bindKeyword} or a.realname like #{bindKeyword})
+        </if>
+    </select>
 </mapper>

+ 3 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/TreeSelectModel.java

@@ -14,7 +14,9 @@ public class TreeSelectModel implements Serializable {
 	private String key;
 	
 	private String title;
-	
+	/**
+	 * 是否叶子节点
+	 */
 	private boolean isLeaf;
 	
 	private String icon;

+ 7 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementSendService.java

@@ -31,4 +31,11 @@ public interface ISysAnnouncementSendService extends IService<SysAnnouncementSen
 	 */
 	public Page<AnnouncementSendModel> getMyAnnouncementSendPage(Page<AnnouncementSendModel> page,AnnouncementSendModel announcementSendModel);
 
+	/**
+	 * 根据消息发送记录ID获取消息内容
+	 * @return
+	 */
+	AnnouncementSendModel getOne(String sendId);
+	
+
 }

+ 22 - 3
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java

@@ -1,9 +1,11 @@
 package org.jeecg.modules.system.service;
 
-import org.jeecg.modules.system.entity.SysAnnouncement;
-
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.system.entity.SysAnnouncement;
+
+import java.util.Date;
+import java.util.List;
 
 /**
  * @Description: 系统通告表
@@ -40,7 +42,24 @@ public interface ISysAnnouncementService extends IService<SysAnnouncement> {
      * @param msgCategory 消息类型
      * @return Page<SysAnnouncement>
      */
-	public Page<SysAnnouncement> querySysCementPageByUserId(Page<SysAnnouncement> page,String userId,String msgCategory);
+	public Page<SysAnnouncement> querySysCementPageByUserId(Page<SysAnnouncement> page, String userId, String msgCategory);
+
+
+    /**
+     *  补全当前登录用户的消息阅读记录 
+     */
+	void completeAnnouncementSendInfo();
+
+
+    /**
+     * 分页查询当前登录用户的消息, 并且标记哪些是未读消息
+     */
+    List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, Date beginDate, Date endDate);
+
+    /**
+     * 修改为已读消息
+     */
+    void updateReaded(List<String> annoceIdList);
 
 
 }

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java

@@ -205,7 +205,7 @@ public interface ISysDictService extends IService<SysDict> {
 	 * @return
 	 */
 	@Deprecated
-	List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField);
+	List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField,int converIsLeafVal);
 
 	/**
 	 * 真实删除

+ 10 - 3
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysPermissionService.java

@@ -18,9 +18,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @since 2018-12-21
  */
 public interface ISysPermissionService extends IService<SysPermission> {
-	/**
-	 * 切换vue3菜单
-	 */
+    /**
+     * 切换vue3菜单
+     */
 	public void switchVue3Menu();
 	
     /**
@@ -93,4 +93,11 @@ public interface ISysPermissionService extends IService<SysPermission> {
 	 * @return
 	 */
 	public boolean hasPermission(String username, String url);
+
+	/**
+	 * 查询部门权限数据
+	 * @param departId
+	 * @return
+	 */
+	List<SysPermission> queryDepartPermissionList(String departId);
 }

+ 9 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java

@@ -55,4 +55,13 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
 	 */
 	IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id);
 
+    /**
+     * 获取用户信息
+     * @param departId
+     * @param keyword
+     * @param pageSize
+     * @param pageNo
+     * @return
+     */
+    IPage<SysUser> getUserInformation(String departId, String keyword, Integer pageSize, Integer pageNo);
 }

+ 5 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementSendServiceImpl.java

@@ -36,4 +36,9 @@ public class SysAnnouncementSendServiceImpl extends ServiceImpl<SysAnnouncementS
 		 return page.setRecords(sysAnnouncementSendMapper.getMyAnnouncementSendList(page, announcementSendModel));
 	}
 
+	@Override
+	public AnnouncementSendModel getOne(String sendId) {
+		return sysAnnouncementSendMapper.getOne(sendId);
+	}
+
 }

+ 69 - 10
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysAnnouncementServiceImpl.java

@@ -1,13 +1,12 @@
 package org.jeecg.modules.system.service.impl;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
-import javax.annotation.Resource;
-
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysAnnouncement;
 import org.jeecg.modules.system.entity.SysAnnouncementSend;
@@ -17,9 +16,11 @@ import org.jeecg.modules.system.service.ISysAnnouncementService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
 
 /**
  * @Description: 系统通告表
@@ -28,6 +29,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  * @Version: V1.0
  */
 @Service
+@Slf4j
 public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMapper, SysAnnouncement> implements ISysAnnouncementService {
 
 	@Resource
@@ -126,4 +128,61 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
 		}
 	}
 
+	@Override
+	public void completeAnnouncementSendInfo() {
+		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		String userId = sysUser.getId();
+		// 1.将系统消息补充到用户通告阅读标记表中
+		LambdaQueryWrapper<SysAnnouncement> querySaWrapper = new LambdaQueryWrapper<SysAnnouncement>();
+		//全部人员
+		querySaWrapper.eq(SysAnnouncement::getMsgType, CommonConstant.MSG_TYPE_ALL);
+		//未删除
+		querySaWrapper.eq(SysAnnouncement::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
+		//已发布
+		querySaWrapper.eq(SysAnnouncement::getSendStatus, CommonConstant.HAS_SEND);
+		//新注册用户不看结束通知
+		querySaWrapper.ge(SysAnnouncement::getEndTime, sysUser.getCreateTime());
+		//update-begin--Author:liusq  Date:20210108 for:[JT-424] 【开源issue】bug处理--------------------
+		querySaWrapper.notInSql(SysAnnouncement::getId,"select annt_id from sys_announcement_send where user_id='"+userId+"'");
+		//update-begin--Author:liusq  Date:20210108  for: [JT-424] 【开源issue】bug处理--------------------
+		List<SysAnnouncement> announcements = this.list(querySaWrapper);
+		if(announcements.size()>0) {
+			for(int i=0;i<announcements.size();i++) {
+				//update-begin--Author:wangshuai  Date:20200803  for: 通知公告消息重复LOWCOD-759--------------------
+				//因为websocket没有判断是否存在这个用户,要是判断会出现问题,故在此判断逻辑
+				LambdaQueryWrapper<SysAnnouncementSend> query = new LambdaQueryWrapper<>();
+				query.eq(SysAnnouncementSend::getAnntId,announcements.get(i).getId());
+				query.eq(SysAnnouncementSend::getUserId,userId);
+				SysAnnouncementSend one = sysAnnouncementSendMapper.selectOne(query);
+				if(null==one){
+					SysAnnouncementSend announcementSend = new SysAnnouncementSend();
+					announcementSend.setAnntId(announcements.get(i).getId());
+					announcementSend.setUserId(userId);
+					announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
+					sysAnnouncementSendMapper.insert(announcementSend);
+					log.info("announcementSend.toString()",announcementSend.toString());
+				}
+				//update-end--Author:wangshuai  Date:20200803  for: 通知公告消息重复LOWCOD-759------------
+			}
+		}
+		
+	}
+
+	@Override
+	public List<SysAnnouncement> querySysMessageList(int pageSize, int pageNo, String fromUser, String starFlag, Date beginDate, Date endDate) {
+		//1. 补全send表的数据
+		completeAnnouncementSendInfo();
+		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
+		// 2. 查询消息数据
+		List<SysAnnouncement> list = baseMapper.queryMessageList(page, sysUser.getId(), fromUser, starFlag, beginDate, endDate);
+		return list;
+	}
+
+	@Override
+	public void updateReaded(List<String> annoceIdList) {
+		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		sysAnnouncementSendMapper.updateReaded(sysUser.getId(), annoceIdList);
+	}
+
 }

+ 77 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java

@@ -12,6 +12,7 @@ import com.google.common.base.Joiner;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.aspect.UrlMatchEnum;
@@ -22,6 +23,7 @@ import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.api.ISysBaseAPI;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.vo.*;
+import org.jeecg.common.util.HTMLUtils;
 import org.jeecg.common.util.SysAnnmentTypeEnum;
 import org.jeecg.common.util.YouBianCodeUtil;
 import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory;
@@ -101,6 +103,10 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 	ISysCategoryService sysCategoryService;
 	@Autowired
 	private ISysUserService sysUserService;
+	@Autowired
+	private ISysDataLogService sysDataLogService;
+	@Autowired
+	private ISysFilesService sysFilesService;
 
 	@Override
 	//@SensitiveDecode
@@ -1191,10 +1197,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 		//update-begin-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
 		String templateCode = message.getTemplateCode();
 		if(oConvertUtils.isNotEmpty(templateCode)){
-			String content = getTemplateContent(templateCode);
+			SysMessageTemplate templateEntity = getTemplateEntity(templateCode);
+			boolean isMarkdown = CommonConstant.MSG_TEMPLATE_TYPE_MD.equals(templateEntity.getTemplateType());
+			String content = templateEntity.getTemplateContent();
 			if(oConvertUtils.isNotEmpty(content) && null!=message.getData()){
-				content = FreemarkerParseFactory.parseTemplateContent(content, message.getData());
+				content = FreemarkerParseFactory.parseTemplateContent(content, message.getData(), isMarkdown);
 			}
+			message.setIsMarkdown(isMarkdown);
 			message.setContent(content);
 		}
 		if(oConvertUtils.isEmpty(message.getContent())){
@@ -1202,8 +1211,16 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 		}
 		//update-end-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
 		if(MessageTypeEnum.XT.getType().equals(messageType)){
+			if (message.isMarkdown()) {
+				// 系统消息要解析Markdown
+				message.setContent(HTMLUtils.parseMarkdown(message.getContent()));
+			}
 			systemSendMsgHandle.sendMessage(message);
 		}else if(MessageTypeEnum.YJ.getType().equals(messageType)){
+			if (message.isMarkdown()) {
+				// 邮件消息要解析Markdown
+				message.setContent(HTMLUtils.parseMarkdown(message.getContent()));
+			}
 			emailSendMsgHandle.sendMessage(message);
 		}else if(MessageTypeEnum.DD.getType().equals(messageType)){
 			ddSendMsgHandle.sendMessage(message);
@@ -1220,6 +1237,64 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 		}
 		return list.get(0).getTemplateContent();
 	}
+
+	/**
+	 * 获取模板内容,解析markdown
+	 *
+	 * @param code
+	 * @return
+	 */
+	public SysMessageTemplate getTemplateEntity(String code) {
+		List<SysMessageTemplate> list = sysMessageTemplateService.selectByCode(code);
+		if (list == null || list.size() == 0) {
+			return null;
+		}
+		return list.get(0);
+	}
+
 	//-------------------------------------流程节点发送模板消息-----------------------------------------------
 
+	@Override
+	public void saveDataLog(DataLogDTO dataLogDto) {
+		SysDataLog entity = new SysDataLog();
+		entity.setDataTable(dataLogDto.getTableName());
+		entity.setDataId(dataLogDto.getDataId());
+		entity.setDataContent(dataLogDto.getContent());
+		entity.setType(dataLogDto.getType());
+		entity.setDataVersion("1");
+		sysDataLogService.save(entity);
+	}
+
+    @Override
+    public void addSysFiles(SysFilesModel sysFilesModel) {
+        SysFiles sysFiles = new SysFiles();
+        BeanUtils.copyProperties(sysFilesModel,sysFiles);
+        String defaultValue = "0";
+        sysFiles.setIzStar(defaultValue);
+        sysFiles.setIzFolder(defaultValue);
+        sysFiles.setIzRootFolder(defaultValue);
+        sysFiles.setDelFlag(defaultValue);
+        sysFilesService.save(sysFiles);
+    }
+
+    @Override
+    public String getFileUrl(String fileId) {
+        SysFiles sysFiles = sysFilesService.getById(fileId);
+        return sysFiles.getUrl();
+    }
+
+    @Override
+    public void updateAvatar(LoginUser loginUser) {
+        SysUser sysUser = new SysUser();
+        BeanUtils.copyProperties(loginUser, sysUser);
+        sysUserService.updateById(sysUser);
+    }
+
+	@Override
+	public void sendAppChatSocket(String userId) {
+		JSONObject obj = new JSONObject();
+		obj.put(WebsocketConst.MSG_CMD, WebsocketConst.MSG_CHAT);
+		obj.put(WebsocketConst.MSG_USER_ID, userId);
+		webSocket.sendMessage(userId, obj.toJSONString());
+	}
 }

+ 3 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import io.netty.util.internal.StringUtil;
 import org.apache.commons.lang.StringUtils;
@@ -138,8 +139,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
 			if (sysDepart.getParentId() == null) {
 				sysDepart.setParentId("");
 			}
-			String s = UUID.randomUUID().toString().replace("-", "");
-			sysDepart.setId(s);
+			//String s = UUID.randomUUID().toString().replace("-", "");
+			sysDepart.setId(IdWorker.getIdStr(sysDepart));
 			// 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
 			// 获取父级ID
 			String parentId = sysDepart.getParentId();

+ 41 - 11
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java

@@ -311,17 +311,33 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
             sqlWhere = " and ";
 		}
 		// update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
-		if(oConvertUtils.isNotEmpty(keyword)){
-			// 判断是否是多选
-			if (keyword.contains(SymbolConstant.COMMA)) {
-                //update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
-				String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
-                //update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
-				keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
-			} else {
-				keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
+
+		//update-begin-author:taoyan date:2022-8-15 for: 下拉搜索组件 支持传入排序信息 查询排序
+		String orderField = "", orderType = "";
+		if (oConvertUtils.isNotEmpty(keyword)) {
+			// 关键字里面如果写入了 排序信息 xxxxx[orderby:create_time,desc]
+			String orderKey = "[orderby";
+			if (keyword.indexOf(orderKey) >= 0 && keyword.endsWith("]")) {
+				String orderInfo = keyword.substring(keyword.indexOf(orderKey) + orderKey.length() + 1, keyword.length() - 1);
+				keyword = keyword.substring(0, keyword.indexOf(orderKey));
+				String[] orderInfoArray = orderInfo.split(SymbolConstant.COMMA);
+				orderField = orderInfoArray[0];
+				orderType = orderInfoArray[1];
+			}
+
+			if (oConvertUtils.isNotEmpty(keyword)) {
+				// 判断是否是多选
+				if (keyword.contains(SymbolConstant.COMMA)) {
+					//update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
+					String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
+					//update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
+					keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
+				} else {
+					keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
+				}
 			}
 		}
+		//update-end-author:taoyan date:2022-8-15 for: 下拉搜索组件 支持传入排序信息 查询排序
 		if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
 			filterSql+= sqlWhere + condition + " and " + keywordSql;
 		}else if(oConvertUtils.isNotEmpty(condition)){
@@ -329,6 +345,12 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 		}else if(oConvertUtils.isNotEmpty(keywordSql)){
 			filterSql+= sqlWhere + keywordSql;
 		}
+		//update-begin-author:taoyan date:2022-8-15 for: 下拉搜索组件 支持传入排序信息 查询排序
+		// 增加排序逻辑
+		if (oConvertUtils.isNotEmpty(orderField)) {
+			filterSql += " order by " + orderField + " " + orderType;
+		}
+		//update-end-author:taoyan date:2022-8-15 for: 下拉搜索组件 支持传入排序信息 查询排序
 		return filterSql;
 	}
 	@Override
@@ -339,8 +361,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 	}
 
 	@Override
-	public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) {
-		return baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField);
+	public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField,int converIsLeafVal) {
+		return baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField,converIsLeafVal);
 	}
 
 	@Override
@@ -398,6 +420,14 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 			//字典表
 			ls = this.queryDictItemsByCode(dictCode);
 		}
+		//update-begin-author:taoyan date:2022-8-30 for: 字典获取可以获取枚举类的数据
+		if (ls == null || ls.size() == 0) {
+			Map<String, List<DictModel>> map = ResourceUtil.getEnumDictData();
+			if (map.containsKey(dictCode)) {
+				return map.get(dictCode);
+			}
+		}
+		//update-end-author:taoyan date:2022-8-30 for: 字典获取可以获取枚举类的数据
 		return ls;
 	}
 

+ 11 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java

@@ -55,17 +55,17 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
 	@Resource
 	private SysDepartRolePermissionMapper sysDepartRolePermissionMapper;
 
-	@Override
-	public List<TreeModel> queryListByParentId(String parentId) {
-		return sysPermissionMapper.queryListByParentId(parentId);
-	}
-
 	@Override
 	public void switchVue3Menu() {
 		sysPermissionMapper.backupVue2Menu();
 		sysPermissionMapper.changeVue3Menu();
 	}
-	
+
+	@Override
+	public List<TreeModel> queryListByParentId(String parentId) {
+		return sysPermissionMapper.queryListByParentId(parentId);
+	}
+
 	/**
 	  * 真实删除
 	 */
@@ -272,4 +272,9 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
 		}
 	}
 
+	@Override
+	public List<SysPermission> queryDepartPermissionList(String departId) {
+		return sysPermissionMapper.queryDepartPermissionList(departId);
+	}
+
 }

+ 32 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java

@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysDepart;
 import org.jeecg.modules.system.entity.SysUser;
@@ -57,7 +59,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
 				}
 			queryDep.in(SysDepart::getId, depIdList);
 			List<SysDepart> depList = sysDepartService.list(queryDep);
-			//[jeecg-boot/issues/3906] 逻辑判断有问题
+			//jeecg-boot/issues/3906
 			if(depList != null && depList.size() > 0) {
 				for(SysDepart depart : depList) {
 					depIdModelList.add(new DepartIdModel().convertByUserDepart(depart));
@@ -139,7 +141,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
                 query.eq(SysUser::getId, id);
             }
             //update-end---author:wangshuai ---date:20220608  for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
-			pageList = sysUserMapper.selectPage(page, query);
+            //update-begin---author:wangshuai ---date:20220902  for:[VUEN-2121]临时用户不能直接显示------------
+            query.ne(SysUser::getUsername,"_reserve_user_external");
+            //update-end---author:wangshuai ---date:20220902  for:[VUEN-2121]临时用户不能直接显示------------
+            pageList = sysUserMapper.selectPage(page, query);
 		}else{
 			// 有部门ID 需要走自定义sql
 			SysDepart sysDepart = sysDepartService.getById(departId);
@@ -166,6 +171,31 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
 		return pageList;
 	}
 
+    @Override
+    public IPage<SysUser> getUserInformation(String departId, String keyword, Integer pageSize, Integer pageNo) {
+        IPage<SysUser> pageList = null;
+        // 部门ID不存在 直接查询用户表即可
+        Page<SysUser> page = new Page<>(pageNo, pageSize);
+        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        if(oConvertUtils.isEmpty(departId)){
+            LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
+            query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
+            query.ne(SysUser::getUsername,"_reserve_user_external");
+            //排除自己
+            query.ne(SysUser::getId,sysUser.getId());
+            //这个语法可以将or用括号包起来,避免数据查不到
+            query.and((wrapper) -> wrapper.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname,keyword));
+            pageList = sysUserMapper.selectPage(page, query);
+        }else{
+            // 有部门ID 需要走自定义sql
+            SysDepart sysDepart = sysDepartService.getById(departId);
+            //update-begin---author:wangshuai ---date:20220908  for:部门排除自己------------
+            pageList = this.baseMapper.getUserInformation(page, sysDepart.getOrgCode(), keyword,sysUser.getId());
+            //update-end---author:wangshuai ---date:20220908  for:部门排除自己--------------
+        }
+        return pageList;
+    }
+
 	/**
 	 * 升级SpringBoot2.6.6,不允许循环依赖
 	 * @param userIds

+ 38 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppDingtalkServiceImpl.java

@@ -12,6 +12,7 @@ import com.jeecg.dingtalk.api.department.JdtDepartmentAPI;
 import com.jeecg.dingtalk.api.department.vo.Department;
 import com.jeecg.dingtalk.api.message.JdtMessageAPI;
 import com.jeecg.dingtalk.api.message.vo.ActionCardMessage;
+import com.jeecg.dingtalk.api.message.vo.MarkdownMessage;
 import com.jeecg.dingtalk.api.message.vo.Message;
 import com.jeecg.dingtalk.api.message.vo.TextMessage;
 import com.jeecg.dingtalk.api.oauth2.JdtOauth2API;
@@ -739,13 +740,49 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
      */
     @Override
     public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
-        Response<String> response = this.sendMessageResponse(message, verifyConfig);
+        Response<String> response;
+        if (message.isMarkdown()) {
+            response = this.sendMarkdownResponse(message, verifyConfig);
+        } else {
+            response = this.sendMessageResponse(message, verifyConfig);
+        }
         if (response != null) {
             return response.isSuccess();
         }
         return false;
     }
 
+    /**
+     * 发送Markdown消息
+     * @param message
+     * @param verifyConfig
+     * @return
+     */
+    public Response<String> sendMarkdownResponse(MessageDTO message, boolean verifyConfig) {
+        if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
+            return null;
+        }
+        String accessToken = this.getAccessToken();
+        if (accessToken == null) {
+            return null;
+        }
+        // 封装钉钉消息
+        String title = message.getTitle();
+        String content = message.getContent();
+        int agentId = thirdAppConfig.getDingtalk().getAgentIdInt();
+        Message<MarkdownMessage> mdMessage = new Message<>(agentId, new MarkdownMessage(title, content));
+        if (message.getToAll()) {
+            mdMessage.setTo_all_user(true);
+        } else {
+            String[] toUsers = message.getToUser().split(",");
+            // 通过第三方账号表查询出第三方userId
+            List<SysThirdAccount> thirdAccountList = sysThirdAccountService.listThirdUserIdByUsername(toUsers, THIRD_TYPE);
+            List<String> dtUserIds = thirdAccountList.stream().map(SysThirdAccount::getThirdUserId).collect(Collectors.toList());
+            mdMessage.setUserid_list(dtUserIds);
+        }
+        return JdtMessageAPI.sendMarkdownMessage(mdMessage, accessToken);
+    }
+
     public Response<String> sendMessageResponse(MessageDTO message, boolean verifyConfig) {
         if (verifyConfig && !thirdAppConfig.isDingtalkEnabled()) {
             return null;

+ 24 - 5
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java

@@ -9,10 +9,7 @@ import com.jeecg.qywx.api.department.JwDepartmentAPI;
 import com.jeecg.qywx.api.department.vo.DepartMsgResponse;
 import com.jeecg.qywx.api.department.vo.Department;
 import com.jeecg.qywx.api.message.JwMessageAPI;
-import com.jeecg.qywx.api.message.vo.Text;
-import com.jeecg.qywx.api.message.vo.TextCard;
-import com.jeecg.qywx.api.message.vo.TextCardEntity;
-import com.jeecg.qywx.api.message.vo.TextEntity;
+import com.jeecg.qywx.api.message.vo.*;
 import com.jeecg.qywx.api.user.JwUserAPI;
 import com.jeecg.qywx.api.user.vo.User;
 import lombok.extern.slf4j.Slf4j;
@@ -747,7 +744,12 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
 
     @Override
     public boolean sendMessage(MessageDTO message, boolean verifyConfig) {
-        JSONObject response = this.sendMessageResponse(message, verifyConfig);
+        JSONObject response;
+        if (message.isMarkdown()) {
+            response = this.sendMarkdownResponse(message, verifyConfig);
+        } else {
+            response = this.sendMessageResponse(message, verifyConfig);
+        }
         if (response != null) {
             return response.getIntValue("errcode") == 0;
         }
@@ -772,6 +774,23 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
         return JwMessageAPI.sendTextMessage(text, accessToken);
     }
 
+    public JSONObject sendMarkdownResponse(MessageDTO message, boolean verifyConfig) {
+        if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
+            return null;
+        }
+        String accessToken = this.getAppAccessToken();
+        if (accessToken == null) {
+            return null;
+        }
+        Markdown markdown = new Markdown();
+        markdown.setTouser(this.getTouser(message.getToUser(), message.getToAll()));
+        MarkdownEntity entity = new MarkdownEntity();
+        entity.setContent(message.getContent());
+        markdown.setMarkdown(entity);
+        markdown.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
+        return JwMessageAPI.sendMarkdownMessage(markdown, accessToken);
+    }
+
     /**
      * 发送文本卡片消息(SysAnnouncement定制)
      *

+ 9 - 5
pom.xml

@@ -25,6 +25,7 @@
 
 		<xxl-job-core.version>2.2.0</xxl-job-core.version>
         <fastjson.version>1.2.83</fastjson.version>
+		<pegdown.version>1.6.0</pegdown.version>
 		<knife4j-spring-boot-starter.version>3.0.3</knife4j-spring-boot-starter.version>
 		<knife4j-spring-ui.version>2.0.9</knife4j-spring-ui.version>
 		<!-- 数据库驱动 -->
@@ -33,9 +34,6 @@
 		<sqljdbc4.version>4.0</sqljdbc4.version>
 		<mysql-connector-java.version>8.0.27</mysql-connector-java.version>
 		<hutool.version>5.3.8</hutool.version>
-		<redisson.version>3.16.1</redisson.version>
-		<commons-beanutils.version>1.9.4</commons-beanutils.version>
-		<guava.version>29.0-jre</guava.version>
 
 		<!-- 持久层 -->
 		<mybatis-plus.version>3.5.1</mybatis-plus.version>
@@ -44,7 +42,7 @@
 		<minidao.version>1.9.0</minidao.version>
 
 		<!-- 积木报表-->
-		<jimureport-spring-boot-starter.version>1.5.2</jimureport-spring-boot-starter.version>
+		<jimureport-spring-boot-starter.version>1.5.3</jimureport-spring-boot-starter.version>
 		<commons.version>2.6</commons.version>
 		<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
 		<aliyun.oss.version>3.11.2</aliyun.oss.version>
@@ -121,6 +119,12 @@
 			<artifactId>fastjson</artifactId>
 			<version>${fastjson.version}</version>
 		</dependency>
+		<!-- markdown -->
+		<dependency>
+			<groupId>org.pegdown</groupId>
+			<artifactId>pegdown</artifactId>
+			<version>${pegdown.version}</version>
+		</dependency>
 	</dependencies>
 
 	<dependencyManagement>
@@ -293,7 +297,7 @@
 			<dependency>
 				<groupId>org.jeecgframework</groupId>
 				<artifactId>jeewx-api</artifactId>
-				<version>1.4.8</version>
+				<version>1.4.9</version>
 				<exclusions>
 					<exclusion>
 						<artifactId>commons-beanutils</artifactId>