Browse Source

rocketmq消息队列和消息功能的开发

dongxin 1 year ago
parent
commit
86686fc0ea
69 changed files with 2519 additions and 10 deletions
  1. 1 1
      authentication/src/main/resources/application.yml
  2. 14 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageEditParam.java
  3. 38 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeAddParam.java
  4. 43 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeEditParam.java
  5. 18 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeParam.java
  6. 16 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeUserParam.java
  7. 14 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageParam.java
  8. 12 0
      commons/src/main/java/com/jzg/commons/entity/dto/MessageTemplateParam.java
  9. 46 0
      commons/src/main/java/com/jzg/commons/entity/po/SysMessage.java
  10. 53 0
      commons/src/main/java/com/jzg/commons/entity/po/SysMessageNotice.java
  11. 64 0
      commons/src/main/java/com/jzg/commons/entity/po/SysMessageTemplate.java
  12. 36 0
      commons/src/main/java/com/jzg/commons/entity/po/SysMessageUser.java
  13. 32 0
      commons/src/main/java/com/jzg/commons/entity/po/SysNoticeUser.java
  14. 46 0
      commons/src/main/java/com/jzg/commons/entity/vo/MessageNoticeVo.java
  15. 46 0
      commons/src/main/java/com/jzg/commons/entity/vo/MessageVo.java
  16. 35 0
      commons/src/main/java/com/jzg/commons/entity/vo/NoticeUserVo.java
  17. 1 1
      gateway/src/main/resources/application-dev.yml
  18. 2 1
      gateway/src/main/resources/application-test.yml
  19. 26 0
      pom.xml
  20. 59 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/listener/enhance/EnhanceMemberMessageListener.java
  21. 59 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/listener/enhance/EnhanceOrderMessageListener.java
  22. 39 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumer.java
  23. 20 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumerOrderly.java
  24. 47 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumerWithLifeCycle.java
  25. 23 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/message/MemberMessage.java
  26. 18 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/message/NormalMessage.java
  27. 25 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/message/OrderMessage.java
  28. 37 0
      tenant/organization/src/main/java/com/jzg/organization/consumer/templete/OrderMessageTemplate.java
  29. 65 0
      tenant/organization/src/main/java/com/jzg/organization/controller/EnhanceProduceController.java
  30. 87 0
      tenant/organization/src/main/java/com/jzg/organization/controller/MessageController.java
  31. 119 0
      tenant/organization/src/main/java/com/jzg/organization/controller/MessageNoticeController.java
  32. 110 0
      tenant/organization/src/main/java/com/jzg/organization/controller/NormalProduceController.java
  33. 39 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageMapper.java
  34. 31 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageNoticeMapper.java
  35. 23 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageTemplateMapper.java
  36. 20 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageUserMapper.java
  37. 25 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysNoticeUserMapper.java
  38. 54 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysMessageNoticeService.java
  39. 29 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysMessageService.java
  40. 15 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysMessageTemplateService.java
  41. 13 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysMessageUserService.java
  42. 13 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysNoticeUserService.java
  43. 95 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageNoticeServiceImpl.java
  44. 51 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageServiceImpl.java
  45. 23 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageTemplateServiceImpl.java
  46. 22 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageUserServiceImpl.java
  47. 22 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysNoticeUserServiceImpl.java
  48. 14 6
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java
  49. 31 0
      tenant/organization/src/main/resources/application-dev.yml
  50. 32 0
      tenant/organization/src/main/resources/application-test.yml
  51. 4 1
      tenant/organization/src/main/resources/application.yml
  52. 50 0
      tenant/organization/src/main/resources/mapper/SysMessageMapper.xml
  53. 44 0
      tenant/organization/src/main/resources/mapper/SysMessageNoticeMapper.xml
  54. 32 0
      tenant/organization/src/main/resources/mapper/SysMessageTemplateMapper.xml
  55. 18 0
      tenant/organization/src/main/resources/mapper/SysMessageUserMapper.xml
  56. 27 0
      tenant/organization/src/main/resources/mapper/SysNoticeUserMapper.xml
  57. 10 0
      tenant/pom.xml
  58. 38 0
      tenant/rocketmq/pom.xml
  59. 35 0
      tenant/rocketmq/src/main/java/com/jzg/autoconfigure/EnvironmentIsolationConfig.java
  60. 16 0
      tenant/rocketmq/src/main/java/com/jzg/autoconfigure/RocketEnhanceProperties.java
  61. 66 0
      tenant/rocketmq/src/main/java/com/jzg/autoconfigure/RocketMQEnhanceAutoConfiguration.java
  62. 34 0
      tenant/rocketmq/src/main/java/com/jzg/constant/EnhanceMessageConstant.java
  63. 30 0
      tenant/rocketmq/src/main/java/com/jzg/domain/BaseMessage.java
  64. 23 0
      tenant/rocketmq/src/main/java/com/jzg/domain/message/MemberMessage.java
  65. 18 0
      tenant/rocketmq/src/main/java/com/jzg/domain/message/NormalMessage.java
  66. 25 0
      tenant/rocketmq/src/main/java/com/jzg/domain/message/OrderMessage.java
  67. 159 0
      tenant/rocketmq/src/main/java/com/jzg/handler/EnhanceMessageHandler.java
  68. 85 0
      tenant/rocketmq/src/main/java/com/jzg/templete/RocketMQEnhanceTemplate.java
  69. 2 0
      tenant/rocketmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

+ 1 - 1
authentication/src/main/resources/application.yml

@@ -8,4 +8,4 @@ spring:
 mybatis-plus:
   mapper-locations: classpath*:/mapper/*Mapper.xml
   configuration:
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

+ 14 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageEditParam.java

@@ -0,0 +1,14 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "消息表修改dto")
+@Data
+public class MessageEditParam {
+
+    @NotNull(message = "消息id不能为空")
+    @Schema(description = "消息id")
+    private String id;
+}

+ 38 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeAddParam.java

@@ -0,0 +1,38 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+@Schema(description = "消息通知表新增dto")
+@Data
+public class MessageNoticeAddParam {
+
+    @Schema(description = "通知标题")
+    @Size(min=1,max=50,message = "通知标题长度不能大于50")
+    @NotNull(message = "通知标题不能为空")
+    private String title;
+
+    @Schema(description = "发布机构ID")
+    @NotNull(message = "发布机构不能为空")
+    private String sendDeptId;
+
+    @Schema(description = "发布机构名称")
+    @NotNull(message = "发布机构不能为空")
+    private String sendDeptName;
+
+    @Schema(description = "通知内容")
+    @NotNull(message = "通知内容不能为空")
+    private String content;
+
+    /** 子机构是否发布 0.否 1.是 */
+    @Schema(description = "子机构是否发布 0.否 1.是")
+    @NotNull(message = "请选择子机构是否发布")
+    private Integer isChildren;
+
+    /** 是否强制查看0.否 1.是 */
+    @Schema(description = "是否强制查看0.否 1.是")
+    @NotNull(message = "请选择是否强制查看")
+    private Integer isForce;
+}

+ 43 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeEditParam.java

@@ -0,0 +1,43 @@
+package com.jzg.commons.entity.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+@Schema(description = "消息通知表修改dto")
+@Data
+public class MessageNoticeEditParam
+{
+
+    @NotNull(message = "通知id不能为空")
+    @Schema(description = "通知id")
+    private String id;
+
+    @Schema(description = "通知标题")
+    @Size(min=1,max=50,message = "通知标题长度不能大于50")
+    @NotNull(message = "通知标题不能为空")
+    private String title;
+
+    @Schema(description = "发布机构ID")
+    @NotNull(message = "发布机构不能为空")
+    private String sendDeptId;
+
+    @Schema(description = "发布机构名称")
+    @NotNull(message = "发布机构不能为空")
+    private String sendDeptName;
+
+    @Schema(description = "通知内容")
+    @NotNull(message = "通知内容不能为空")
+    private String content;
+
+    /** 子机构是否发布 0.否 1.是 */
+    @Schema(description = "子机构是否发布 0.否 1.是")
+    @NotNull(message = "请选择子机构是否发布")
+    private Integer isChildren;
+
+    /** 是否强制查看0.否 1.是 */
+    @Schema(description = "是否强制查看0.否 1.是")
+    @NotNull(message = "请选择是否强制查看")
+    private Integer isForce;
+}

+ 18 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeParam.java

@@ -0,0 +1,18 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "消息通知表分页查询dto")
+@Data
+public class MessageNoticeParam extends PageRequest {
+
+    /** 消息通知搜索值 */
+    @Schema(description = "消息通知搜索值")
+    private String searchValue;
+
+    /** 发布机构 */
+    @Schema(description = "发布机构")
+    private String sendDeptId;
+}

+ 16 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageNoticeUserParam.java

@@ -0,0 +1,16 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "消息通知查看人员分页查询dto")
+@Data
+public class MessageNoticeUserParam extends PageRequest {
+
+    /** 消息通知ID */
+    @Schema(description = "消息通知ID")
+    @NotNull(message = "通知id不能为空")
+    private String id;
+}

+ 14 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageParam.java

@@ -0,0 +1,14 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "消息表分页查询dto")
+@Data
+public class MessageParam extends PageRequest {
+
+    /** 模版编号 */
+    @Schema(description = "类型")
+    private Integer type;
+}

+ 12 - 0
commons/src/main/java/com/jzg/commons/entity/dto/MessageTemplateParam.java

@@ -0,0 +1,12 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.core.base.PageRequest;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "消息模板表分页查询dto")
+@Data
+public class MessageTemplateParam extends PageRequest {
+
+
+}

+ 46 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysMessage.java

@@ -0,0 +1,46 @@
+package com.jzg.commons.entity.po;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 消息表
+ * @TableName sys_message
+ */
+@Schema(description = "消息表")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysMessage extends BaseModel {
+
+    /** 消息ID */
+    @Schema(description = "消息ID")
+    private String id;
+
+    /** 消息标题 */
+    @Schema(description = "消息标题")
+    private String title;
+
+    /** 消息内容 */
+    @Schema(description = "消息内容")
+    private String content;
+
+    /** 模版编号 */
+    @Schema(description = "模版id")
+    private String tplId;
+
+    /** 模版编号 */
+    @Schema(description = "模版编号")
+    private String tplCode;
+
+    /** 系统code */
+    @Schema(description = "系统code")
+    private String systemCode;
+
+}

+ 53 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysMessageNotice.java

@@ -0,0 +1,53 @@
+package com.jzg.commons.entity.po;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 消息通知表
+ * @TableName sys_message_notice
+ */
+@Schema(description = "消息通知表")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysMessageNotice extends BaseModel {
+
+    /** 消息通知ID */
+    @Schema(description = "消息通知ID")
+    private String id;
+
+    /** 通知标题 */
+    @Schema(description = "通知标题")
+    private String title;
+
+    /** 通知内容 */
+    @Schema(description = "通知内容")
+    private String content;
+
+    /** 发布机构id */
+    @Schema(description = "发布机构id")
+    private String sendDeptId;
+
+    /** 发布机构名称 */
+    @Schema(description = "发布机构名称")
+    private String sendDeptName;
+
+    /** 子机构是否发布 0.否 1.是 */
+    @Schema(description = "子机构是否发布 0.否 1.是")
+    private Integer isChildren;
+
+    /** 是否强制查看0.否 1.是 */
+    @Schema(description = "是否强制查看0.否 1.是")
+    private Integer isForce;
+
+    /** 系统code */
+    @Schema(description = "系统code")
+    private String systemCode;
+}

+ 64 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysMessageTemplate.java

@@ -0,0 +1,64 @@
+package com.jzg.commons.entity.po;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 消息模版(sys_message_template)
+ * @TableName sys_message_template
+ */
+
+@Schema(description = "消息模版表")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysMessageTemplate extends BaseModel {
+
+    /** 模版ID */
+    @Schema(description = "模版ID")
+    private Long id;
+
+    /** 模版编号 */
+    @Schema(description = "模版编号")
+    private String tplCode;
+
+    /** 模板名称 */
+    @Schema(description = "模板名称")
+    private String tplName;
+
+    /** 类型(0-增员消息 1-待我审核) */
+    @Schema(description = "类型(0-增员消息 1-待我审核)")
+    private Integer type;
+
+    /** 模块 */
+    @Schema(description = "模块")
+    private String model;
+
+    /** 发送场景 */
+    @Schema(description = "发送场景")
+    private String sendPlace;
+
+    /** 模板内容 */
+    @Schema(description = "模板内容")
+    private String content;
+
+    /** 跳转页面 */
+    @Schema(description = "跳转页面")
+    private String linkUrl;
+
+    /** 接收方 */
+    @Schema(description = "接收方")
+    private String receive;
+
+    /** 是否启用 0 启用 1禁用 */
+    @Schema(description = "是否启用 0 启用 1禁用")
+    private Integer isEnable;
+
+}

+ 36 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysMessageUser.java

@@ -0,0 +1,36 @@
+package com.jzg.commons.entity.po;
+
+import java.io.Serializable;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 消息访问用户表
+ * @TableName sys_message_user
+ */
+@Schema(description = "消息访问用户表")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysMessageUser implements Serializable {
+    /**
+     * 主键ID
+     */
+    @Schema(description = "主键id")
+    private String id;
+
+    /** 消息id */
+    @Schema(description = "消息id")
+    private String messageId;
+
+    /** 用户id */
+    @Schema(description = "用户id")
+    private String userId;
+
+    /** 是否已读 0.否 1.是 */
+    @Schema(description = "是否已读 0.否 1.是")
+    private Integer isRead;
+}

+ 32 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysNoticeUser.java

@@ -0,0 +1,32 @@
+package com.jzg.commons.entity.po;
+
+import java.io.Serializable;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 通知访问用户表
+ * @TableName sys_message_user
+ */
+@Schema(description = "通知访问用户表")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysNoticeUser implements Serializable {
+    /** 主键id */
+    @Schema(description = "主键id")
+    private String id;
+
+    /** 通知id */
+    @Schema(description = "通知id")
+    private String noticeId;
+
+    /** 用户id */
+    @Schema(description = "用户id")
+    private String userId;
+
+
+}

+ 46 - 0
commons/src/main/java/com/jzg/commons/entity/vo/MessageNoticeVo.java

@@ -0,0 +1,46 @@
+package com.jzg.commons.entity.vo;
+
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "消息通知表VO")
+@Data
+public class MessageNoticeVo extends BaseModel {
+
+    /** 消息通知ID */
+    @Schema(description = "消息通知ID")
+    private String id;
+
+    /** 通知标题 */
+    @Schema(description = "通知标题")
+    private String title;
+
+    /** 通知内容 */
+    @Schema(description = "通知内容")
+    private String content;
+
+    /** 发布机构id */
+    @Schema(description = "发布机构id")
+    private String sendDeptId;
+
+    /** 发布机构名称 */
+    @Schema(description = "发布机构名称")
+    private String sendDeptName;
+
+    /** 子机构是否发布 0.否 1.是 */
+    @Schema(description = "子机构是否发布 0.否 1.是")
+    private Integer isChildren;
+
+    /** 是否强制查看0.否 1.是 */
+    @Schema(description = "是否强制查看0.否 1.是")
+    private Integer isForce;
+
+    /** 查看人数 */
+    @Schema(description = "查看人数")
+    private Long viewCount;
+
+    /** 系统code */
+    @Schema(description = "系统code")
+    private String systemCode;
+}

+ 46 - 0
commons/src/main/java/com/jzg/commons/entity/vo/MessageVo.java

@@ -0,0 +1,46 @@
+package com.jzg.commons.entity.vo;
+
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "消息表VO")
+@Data
+public class MessageVo extends BaseModel {
+
+    /** 消息ID */
+    @Schema(description = "消息ID")
+    private String id;
+
+    /** 消息标题 */
+    @Schema(description = "消息标题")
+    private String title;
+
+    /** 消息内容 */
+    @Schema(description = "消息内容")
+    private String content;
+
+    /** 模版编号 */
+    @Schema(description = "模版id")
+    private String tplId;
+
+    /** 模版编号 */
+    @Schema(description = "模版编号")
+    private String tplCode;
+
+    /** 模版类型 */
+    @Schema(description = "模版类型")
+    private Integer tplType;
+
+    /** 用户id */
+    @Schema(description = "用户id")
+    private String userId;
+
+    /** 是否已读 0.否 1.是 */
+    @Schema(description = "是否已读 0.否 1.是")
+    private Integer isRead;
+
+    /** 系统code */
+    @Schema(description = "系统code")
+    private String systemCode;
+}

+ 35 - 0
commons/src/main/java/com/jzg/commons/entity/vo/NoticeUserVo.java

@@ -0,0 +1,35 @@
+package com.jzg.commons.entity.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "通知人员表VO")
+@Data
+public class NoticeUserVo extends BaseModel {
+
+    /** 用户id */
+    @Schema(description = "用户id")
+    private String userId;
+
+    /** 姓名 */
+    @Schema(description = "姓名")
+    private String name;
+
+    /** 手机号 */
+    @Schema(description = "手机号")
+    private String mobile;
+
+    @Schema(description = "工号")
+    private String workNumber;
+
+    /** 机构ID */
+    @Schema(description = "机构id")
+    private String deptId;
+
+    /** 机构名称 */
+    @Schema(description = "机构名称")
+    private String deptName;
+
+}

+ 1 - 1
gateway/src/main/resources/application-dev.yml

@@ -15,6 +15,6 @@ spring:
         - id: tenant_route
           uri: http://localhost:8084/
           predicates:
-            - Path=/tenant/**,/dept/**,/area/**,/dict/**,/userInfo/**,/sysOrganization/**,/activity/**
+            - Path=/tenant/**,/dept/**,/area/**,/dict/**,/userInfo/**,/sysOrganization/**,/activity/**,/message/**,/messageNotice/**
 
 

+ 2 - 1
gateway/src/main/resources/application-test.yml

@@ -16,6 +16,7 @@ spring:
         - id: tenant_route
           uri: http://172.24.144.223:9084/
           predicates:
-            - Path=/tenant/**,/dept/**,/area/**,/dict/**,/userInfo/**,/sysOrganization/**,/activity/**
+            - Path=/tenant/**,/dept/**,/area/**,/dict/**,/userInfo/**,/sysOrganization/**,/activity/**,/message/**,/messageNotice/**
+
 
 

+ 26 - 0
pom.xml

@@ -34,6 +34,9 @@
     <openfeign.version>4.1.3</openfeign.version>
     <hutool.version>5.8.31</hutool.version>
     <minio.version>8.0.3</minio.version>
+    <guava.version>29.0-jre</guava.version>
+    <rocketmq.version>2.2.1</rocketmq.version>
+    <rocket.version>1.0-SNAPSHOT</rocket.version>
   </properties>
 
 
@@ -189,6 +192,29 @@
         <scope>import</scope>
       </dependency>
 
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+
+<!--      <dependency>-->
+<!--        <groupId>org.projectlombok</groupId>-->
+<!--        <artifactId>lombok</artifactId>-->
+<!--        <version>${lombok.version}</version>-->
+<!--      </dependency>-->
+
+      <dependency>
+        <groupId>org.apache.rocketmq</groupId>
+        <artifactId>rocketmq-spring-boot-starter</artifactId>
+        <version>${rocketmq.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.jzg</groupId>
+        <artifactId>rocketmq</artifactId>
+        <version>${rocket.version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 

+ 59 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/listener/enhance/EnhanceMemberMessageListener.java

@@ -0,0 +1,59 @@
+package com.jzg.organization.consumer.listener.enhance;
+
+import com.jzg.handler.EnhanceMessageHandler;
+import com.jzg.organization.consumer.message.MemberMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+
+/**
+ * @author dongxin
+ */
+@Slf4j
+//@Component
+@RocketMQMessageListener(
+        consumerGroup = "enhance_consumer_group",
+        topic = "rocket_enhance",
+        selectorExpression = "*",
+        consumeThreadMax = 5 //默认是64个线程并发消息,配置 consumeThreadMax 参数指定并发消费线程数,避免太大导致资源不够
+)
+public class EnhanceMemberMessageListener extends EnhanceMessageHandler<MemberMessage> implements RocketMQListener<MemberMessage> {
+
+    @Override
+    protected void handleMessage(MemberMessage message) throws Exception {
+        // 此时这里才是最终的业务处理,代码只需要处理资源类关闭异常,其他的可以交给父类重试
+        System.out.println("业务消息处理:"+message.getUserName());
+    }
+
+    @Override
+    protected void handleMaxRetriesExceeded(MemberMessage message) {
+        // 当超过指定重试次数消息时此处方法会被调用
+        // 生产中可以进行回退或其他业务操作
+        log.error("消息消费失败,请执行后续处理");
+    }
+
+
+    /**
+     * 是否执行重试机制
+     */
+    @Override
+    protected boolean isRetry() {
+        return true;
+    }
+
+    @Override
+    protected boolean throwException() {
+        // 是否抛出异常,false搭配retry自行处理异常
+        return false;
+    }
+
+    /**
+     * 监听消费消息,不需要执行业务处理,委派给父类做基础操作,父类做完基础操作后会调用子类的实际处理类型
+     */
+    @Override
+    public void onMessage(MemberMessage rocketMqEntityMessage) {
+        super.dispatchMessage(rocketMqEntityMessage);
+    }
+
+
+}

+ 59 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/listener/enhance/EnhanceOrderMessageListener.java

@@ -0,0 +1,59 @@
+package com.jzg.organization.consumer.listener.enhance;
+
+import com.jzg.handler.EnhanceMessageHandler;
+import com.jzg.organization.consumer.message.OrderMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author dongxin
+ */
+@Slf4j
+@Component
+@RocketMQMessageListener(
+        consumerGroup = "enhance_consumer_group",
+        topic = "rocket_enhance",
+        selectorExpression = "*",
+        consumeThreadMax = 5 //默认是64个线程并发消息,配置 consumeThreadMax 参数指定并发消费线程数,避免太大导致资源不够
+)
+public class EnhanceOrderMessageListener extends EnhanceMessageHandler<OrderMessage> implements RocketMQListener<OrderMessage> {
+
+    @Override
+    protected void handleMessage(OrderMessage message) throws Exception {
+        // 此时这里才是最终的业务处理,代码只需要处理资源类关闭异常,其他的可以交给父类重试
+        System.out.println("业务消息处理:"+message.getBody());
+        int a = 10 /0;
+    }
+
+    @Override
+    protected void handleMaxRetriesExceeded(OrderMessage message) {
+        // 当超过指定重试次数消息时此处方法会被调用
+        // 生产中可以进行回退或其他业务操作
+        log.error("消息消费失败,请执行后续处理");
+    }
+
+
+    /**
+     * 是否执行重试机制
+     */
+    @Override
+    protected boolean isRetry() {
+        return true;
+    }
+
+    @Override
+    protected boolean throwException() {
+        // 是否抛出异常,false搭配retry自行处理异常
+        return false;
+    }
+
+    /**
+     * 监听消费消息,不需要执行业务处理,委派给父类做基础操作,父类做完基础操作后会调用子类的实际处理类型
+     */
+    @Override
+    public void onMessage(OrderMessage orderMessage) {
+        super.dispatchMessage(orderMessage);
+    }
+}

+ 39 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumer.java

@@ -0,0 +1,39 @@
+package com.jzg.organization.consumer.listener.normal;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.organization.consumer.message.NormalMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author dongxin
+ * 普通消息监听器
+ */
+
+@Component
+@RocketMQMessageListener(
+        consumerGroup = "springboot_consumer_group",
+        topic = "rocket_normal",
+        selectorExpression = "*",
+        consumeThreadMax = 5 //默认是64个线程并发消息,配置 consumeThreadMax 参数指定并发消费线程数,避免太大导致资源不够
+)
+@Slf4j
+public class NormalConsumer implements RocketMQListener<NormalMessage> {
+    @Override
+    public void onMessage(NormalMessage message) {
+        log.info("消费者收到消息[{}]", JSONObject.toJSON(message));
+        // 方法执行完成之后会自动进行进行ack ,如果方法出现异常,将会进入重试队列
+        try {
+            TimeUnit.SECONDS.sleep(3);
+//            int a = 10 / 0;
+        }catch (InterruptedException e) {
+            log.error(e.getMessage());
+        }
+        log.info("Message {} 休眠了3s后消费完成",message.getKey());
+    }
+
+}

+ 20 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumerOrderly.java

@@ -0,0 +1,20 @@
+package com.jzg.organization.consumer.listener.normal;
+
+import com.jzg.organization.consumer.message.NormalMessage;
+import org.apache.rocketmq.spring.annotation.ConsumeMode;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+
+/**
+ * @author dongxin
+ * 顺序消息
+ */
+
+//@Component
+@RocketMQMessageListener(consumerGroup = "springboot_consumer_group",topic = "consumer_topic",consumeMode = ConsumeMode.ORDERLY)
+public class NormalConsumerOrderly implements RocketMQListener<NormalMessage> {
+    @Override
+    public void onMessage(NormalMessage normalMessage) {
+        System.out.println("消费消息-" + normalMessage);
+    }
+}

+ 47 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/listener/normal/NormalConsumerWithLifeCycle.java

@@ -0,0 +1,47 @@
+package com.jzg.organization.consumer.listener.normal;
+
+import com.jzg.organization.consumer.message.NormalMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author dongxin
+ * 普通消息监听器
+ */
+
+//@Component
+@RocketMQMessageListener(
+        consumerGroup = "springboot_consumer_group",
+        topic = "consumer_topic",
+        selectorExpression = "*",
+        consumeThreadMax = 5 //默认是64个线程并发消息,配置 consumeThreadMax 参数指定并发消费线程数,避免太大导致资源不够
+)
+@Slf4j
+public class NormalConsumerWithLifeCycle implements RocketMQListener<NormalMessage>, RocketMQPushConsumerLifecycleListener {
+    @Override
+    public void onMessage(NormalMessage message) {
+        // 方法执行完成之后会自动进行进行ack ,如果方法出现异常,将会进入重试队列
+        System.out.println("received message -" + message);
+        try {
+            TimeUnit.SECONDS.sleep(3);
+        }catch (InterruptedException e) {
+            log.error(e.getMessage());
+        }
+        log.info("休眠了3s后消费完成");
+
+    }
+
+    /**
+     * 当普通的RocketMQListener提供的功能无法满足时可通过实现RocketMQPushConsumerLifecycleListener进行增强
+     */
+    @Override
+    public void prepareStart(DefaultMQPushConsumer consumer) {
+        //设置最大重试次数
+        consumer.setMaxReconsumeTimes(3);
+    }
+}

+ 23 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/message/MemberMessage.java

@@ -0,0 +1,23 @@
+package com.jzg.organization.consumer.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+/**
+ * @author dongxin
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberMessage extends BaseMessage {
+
+    private String userName;
+
+    private LocalDate birthday;
+}

+ 18 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/message/NormalMessage.java

@@ -0,0 +1,18 @@
+package com.jzg.organization.consumer.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author dongxin
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class NormalMessage extends BaseMessage {
+    private String message;
+}

+ 25 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/message/OrderMessage.java

@@ -0,0 +1,25 @@
+package com.jzg.organization.consumer.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author jam
+ * 公众号:JAVA日知录
+ * @date 2023/3/30 11:32
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderMessage extends BaseMessage {
+
+    private LocalDateTime tradeTime;
+
+    private String body;
+}

+ 37 - 0
tenant/organization/src/main/java/com/jzg/organization/consumer/templete/OrderMessageTemplate.java

@@ -0,0 +1,37 @@
+package com.jzg.organization.consumer.templete;
+
+import com.jzg.organization.consumer.message.OrderMessage;
+import com.jzg.templete.RocketMQEnhanceTemplate;
+import jakarta.validation.constraints.NotNull;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author dongxin
+ * 订单类发送消息模板工具类
+ */
+@Component
+public class OrderMessageTemplate extends RocketMQEnhanceTemplate {
+
+    public OrderMessageTemplate(RocketMQTemplate template) {
+        super(template);
+    }
+
+    /**
+     * 入参只需要传入是哪个订单号和业务体消息即可,其他操作根据需要处理
+     * 这样对于调用者而言,可以更加简化调用
+     */
+    public SendResult sendOrderPaid(@NotNull String orderId, String body) {
+        OrderMessage message = new OrderMessage();
+        message.setKey(orderId);
+        message.setSource("ORDER");
+        message.setBody(body);
+        // 这两个字段只是为了测试
+        message.setTradeTime(LocalDateTime.now());
+        return send("rocket_enhance", "CREATE", message);
+    }
+
+}

+ 65 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/EnhanceProduceController.java

@@ -0,0 +1,65 @@
+package com.jzg.organization.controller;
+
+import com.jzg.organization.consumer.message.MemberMessage;
+import com.jzg.organization.consumer.templete.OrderMessageTemplate;
+import com.jzg.templete.RocketMQEnhanceTemplate;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.util.UUID;
+
+/**
+ * @author dongxin
+ * 使用增强类发送消息
+ */
+@RestController
+@RequestMapping("enhance")
+@Slf4j
+public class EnhanceProduceController {
+
+    @Setter(onMethod_ = @Autowired)
+    private RocketMQEnhanceTemplate rocketMQEnhanceTemplate;
+
+    @Setter(onMethod_ = @Autowired)
+    private OrderMessageTemplate orderMessageTemplate;
+
+    private static final String topic = "rocket_enhance";
+    private static final String tag = "member";
+
+    /**
+     * 发送实体消息
+     */
+    @GetMapping("/member")
+    public SendResult member() {
+        String key = UUID.randomUUID().toString();
+        MemberMessage message = new MemberMessage();
+        // 设置业务key
+        message.setKey(key);
+        // 设置消息来源,便于查询
+        message.setSource("MEMBER");
+        // 业务消息内容
+        message.setUserName("dongxin");
+        message.setBirthday(LocalDate.now());
+
+
+        return rocketMQEnhanceTemplate.send(topic, tag, message);
+    }
+
+
+    /**
+     * 定制模板消息
+     */
+    @GetMapping("/order")
+    public SendResult order() {
+        String key = "ORDER:"+ UUID.randomUUID();
+        return orderMessageTemplate.sendOrderPaid(key, "客户下单了,请备货");
+    }
+
+
+}

+ 87 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/MessageController.java

@@ -0,0 +1,87 @@
+package com.jzg.organization.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.core.base.BaseController;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.*;
+import com.jzg.commons.entity.po.*;
+import com.jzg.commons.entity.vo.MessageNoticeVo;
+import com.jzg.commons.entity.vo.MessageVo;
+import com.jzg.commons.util.AssertionUtils;
+import com.jzg.organization.service.*;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Objects;
+
+/**
+ * 消息管理接口
+ *
+ * @author dongxin
+ */
+@Tag(name="消息管理接口")
+@RestController
+@RequestMapping("/message")
+public class MessageController extends BaseController {
+
+    @Autowired
+    private SysMessageService messageService;
+
+    @Autowired
+    private SysMessageUserService messageUserService;
+
+    @Autowired
+    private SysUserService userService;
+
+    @Autowired
+    private SysUserJzgInfoService userJzgInfoService;
+
+    /**
+     * 消息列表分页
+     * @return
+     */
+    @PostMapping("/messageList")
+    @Operation(summary = "消息列表分页")
+    public HttpResult messageList(@RequestBody MessageParam param){
+        Page<MessageVo> result = messageService.queryPage(param);
+        return HttpResult.ok(result);
+    }
+
+    /**
+     * 获取消息数量
+     * @return
+     */
+    @Operation(summary = "获取消息数量", description = "获取消息数量")
+    @GetMapping(value = "/getMessageCount")
+    public HttpResult getMessageCount() {
+        return HttpResult.ok(messageService.getMessageCount());
+    }
+
+    /**
+     * 消息已读状态编辑
+     * @return
+     */
+    @Operation(summary = "消息已读状态编辑")
+    @PostMapping("/readEdit")
+    public HttpResult readEdit(@Validated @RequestBody MessageEditParam param) {
+        String userName = getUserName();
+        SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>()
+                .eq(SysUser::getMobile, userName));
+        SysUserJzgInfo info = userJzgInfoService.getOne(new LambdaQueryWrapper<SysUserJzgInfo>()
+                .eq(SysUserJzgInfo::getUserId, sysUser.getId())
+        );
+        LambdaUpdateWrapper<SysMessageUser>  wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(SysMessageUser::getUserId, info.getId())
+                .eq(SysMessageUser::getMessageId, param.getId())
+                .set(SysMessageUser::getIsRead, 1);
+        messageUserService.update(wrapper);
+        return HttpResult.ok("修改成功");
+    }
+
+}

+ 119 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/MessageNoticeController.java

@@ -0,0 +1,119 @@
+package com.jzg.organization.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.core.base.BaseController;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.*;
+import com.jzg.commons.entity.po.SysDept;
+import com.jzg.commons.entity.vo.MessageNoticeVo;
+import com.jzg.commons.entity.vo.NoticeUserVo;
+import com.jzg.commons.util.AssertionUtils;
+import com.jzg.commons.util.StringUtils;
+import com.jzg.organization.service.SysDeptService;
+import com.jzg.organization.service.SysMessageNoticeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 消息通知管理接口
+ *
+ * @author dongxin
+ */
+@Tag(name="消息通知管理接口")
+@RestController
+@RequestMapping("/messageNotice")
+public class MessageNoticeController extends BaseController {
+
+    @Autowired
+    private SysMessageNoticeService messageNoticeService;
+
+    @Autowired
+    private SysDeptService deptService;
+    /**
+     * 消息通知列表分页
+     * @param param
+     * @return
+     */
+    @PostMapping("/noticeList")
+    @Operation(summary = "消息通知列表分页")
+    public HttpResult noticeList(@RequestBody MessageNoticeParam param){
+        Page<MessageNoticeVo> result = messageNoticeService.queryPage(param);
+        return HttpResult.ok(result);
+    }
+
+    /**
+     * 消息通知人员分页列表
+     * @param param
+     * @return
+     */
+    @PostMapping("/userList")
+    @Operation(summary = "消息通知人员分页列表")
+    public HttpResult userList(@RequestBody MessageNoticeUserParam param){
+        Page<NoticeUserVo> result = messageNoticeService.queryUserPage(param);
+        return HttpResult.ok(result);
+    }
+
+
+    /**
+     * 消息通知信息查询
+     * @param id
+     * @return
+     */
+    @GetMapping(value = { "/noticeGet"})
+    @Operation(summary = "消息通知信息查询")
+    public HttpResult noticeGet(String id) {
+        return HttpResult.ok(messageNoticeService.getById(id));
+    }
+
+    /**
+     * 消息通知添加
+     * @param param
+     * @return
+     */
+    @Operation(summary = "消息通知添加")
+    @PostMapping("/noticeAdd")
+    public HttpResult noticeAdd(@Validated @RequestBody MessageNoticeAddParam param) {
+        // 编码和名称不允许重复
+        SysDept dept = deptService.getById(param.getSendDeptId());
+        Boolean isExists = false;
+        if(Objects.isNull(dept) || dept.getIsDelete().equals(1)){isExists = true;}
+        AssertionUtils.isFail(isExists,"机构已经删除,请重新选择!");
+        messageNoticeService.noticeAdd(param);
+        return HttpResult.ok("新增成功");
+    }
+
+    /**
+     * 消息通知编辑
+     * @param param
+     * @return
+     */
+    @Operation(summary = "消息通知编辑")
+    @PostMapping("/noticeEdit")
+    public HttpResult noticeEdit(@Validated @RequestBody MessageNoticeEditParam param) {
+        // 编码和名称不允许重复
+        SysDept dept = deptService.getById(param.getSendDeptId());
+        Boolean isExists = false;
+        if(Objects.isNull(dept) || dept.getIsDelete().equals(1)){isExists = true;}
+        AssertionUtils.isFail(isExists,"机构已经删除,请重新选择!");
+        messageNoticeService.noticeEdit(param);
+        return HttpResult.ok("修改成功");
+    }
+
+    /**
+     * 批量删除消息通知
+     *
+     * @param ids 主键串
+     */
+    @Operation(summary = "批量删除消息通知")
+    @DeleteMapping("/noticeDelete")
+    public HttpResult sysDelete(String[] ids) {
+        return HttpResult.ok(messageNoticeService.deleteByIds(List.of(ids))? "删除成功":"删除失败");
+    }
+
+}

+ 110 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/NormalProduceController.java

@@ -0,0 +1,110 @@
+package com.jzg.organization.controller;
+
+import com.jzg.organization.consumer.message.NormalMessage;
+import com.jzg.templete.RocketMQEnhanceTemplate;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.apache.rocketmq.spring.support.RocketMQHeaders;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.UUID;
+
+/**
+ * @author dongxin
+ */
+@RestController
+@RequestMapping("normal")
+@Slf4j
+public class NormalProduceController {
+    @Setter(onMethod_ = @Autowired)
+    private RocketMQTemplate rocketmqTemplate;
+
+    @Setter(onMethod_ = @Autowired)
+    private RocketMQEnhanceTemplate rocketMQEnhanceTemplate;
+    private static final String topic = "rocket_normal";
+    private static final String tag = "test";
+
+    /**
+     * 发送实体消息
+     */
+    @GetMapping("/test")
+    public void test() {
+        String key = UUID.randomUUID().toString();
+        NormalMessage message = new NormalMessage();
+        // 设置业务key
+        message.setKey(key);
+        // 设置消息来源,便于查询
+        message.setSource("NORMAL");
+        // 业务消息内容
+        message.setMessage("Hello,RocketMQ");
+
+
+        Message<NormalMessage> buildMessage = MessageBuilder.withPayload(message)
+                .setHeader(RocketMQHeaders.KEYS, message.getKey()) // 业务Keys
+                .build();
+
+        //构建topic + tag 的格式
+        String destination = topic + ":" + tag;
+
+        //1. 发送同步消息
+        SendResult sendResult = rocketmqTemplate.syncSend(destination, buildMessage);
+        log.info("发送结果:" + sendResult.toString());
+
+        //2. 发送延时消息
+//        SendResult sendResult = rocketmqTemplate.syncSend(destination, buildMessage, 10000, EnhanceMessageConstant.FIVE_SECOND);
+//        log.info("[{}]延迟等级[{}]消息[{}]发送结果[{}]", destination, EnhanceMessageConstant.FIVE_SECOND, JSONObject.toJSON(message), JSONObject.toJSON(sendResult));
+        //3. 发送同步顺序消息
+        //发送同步有序消息,需要指定hashKey,可以用业务唯一键
+        //rocketmqTemplate.syncSendOrderly(destination,buildMessage,rocketMessage.getId().toString());
+
+        //4. 发送异步消息
+//        rocketmqTemplate.asyncSend(destination, buildMessage, new SendCallback() {
+//            @Override
+//            public void onSuccess(SendResult sendResult) {
+//                log.info("消息发送成功:{}",sendResult.getMsgId());
+//            }
+//
+//            @Override
+//            public void onException(Throwable throwable) {
+//                log.error("消息发送异常:{}",throwable.getMessage());
+//            }
+//        });
+
+        //5. 发送单向消息
+//        rocketmqTemplate.sendOneWay(destination,buildMessage);
+
+        // 6. 发送批量消息
+//        List<Message<RocketMessage>> messageList = new ArrayList<>();
+//        messageList.add(buildMessage);
+//
+//        rocketmqTemplate.syncSend(destination,messageList);
+    }
+
+
+    /**
+     * 发送普通消息如何实现自动隔离呢?
+     * 需要重新构建destination
+     */
+    @RequestMapping("/message")
+    public SendResult convertAndSend() {
+        String key = UUID.randomUUID().toString();
+        NormalMessage message = new NormalMessage();
+        // 设置业务key
+        message.setKey(key);
+        // 设置消息来源,便于查询
+        message.setSource("NORMAL");
+        // 业务消息内容
+        message.setMessage("Hello,world");
+        //生成环境隔离后的目的地
+        String destination = rocketMQEnhanceTemplate.buildDestination(topic, tag);
+        // 如果要走内部方法发送则必须要按照标准来,否则就使用原生的消息发送
+        return rocketmqTemplate.syncSend(destination, message);
+    }
+}

+ 39 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageMapper.java

@@ -0,0 +1,39 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.entity.dto.MessageParam;
+import com.jzg.commons.entity.po.SysMessage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.vo.MessageVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message】的数据库操作Mapper
+* @createDate 2025-02-10 18:23:03
+* @Entity generator.domain.SysMessage
+*/
+@Mapper
+public interface SysMessageMapper extends BaseMapper<SysMessage> {
+
+    /**
+     * 消息列表分页
+     * @param page
+     * @param param
+     * @return
+     */
+    Page<MessageVo> queryPage(Page page, @Param("param") MessageParam param);
+
+    /**
+     * 消息列表
+     * @return
+     */
+    List<MessageVo> queryList();
+}
+
+
+
+

+ 31 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageNoticeMapper.java

@@ -0,0 +1,31 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.entity.dto.MessageNoticeParam;
+import com.jzg.commons.entity.po.SysMessageNotice;
+import com.jzg.commons.entity.vo.MessageNoticeVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_notice(消息通知表)】的数据库操作Mapper
+* @createDate 2025-02-10 18:23:10
+* @Entity generator.domain.SysMessageNotice
+*/
+@Mapper
+public interface SysMessageNoticeMapper extends BaseMapper<SysMessageNotice> {
+
+    /**
+     * 消息通知分页列表
+     * @param page
+     * @param param
+     * @return
+     */
+    Page<MessageNoticeVo> queryPage(Page page, @Param("param") MessageNoticeParam param);
+}
+
+
+
+

+ 23 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageTemplateMapper.java

@@ -0,0 +1,23 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.entity.dto.MessageTemplateParam;
+import com.jzg.commons.entity.po.SysMessageTemplate;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_template(消息模版(sys_message_template))】的数据库操作Mapper
+* @createDate 2025-02-08 17:56:29
+* @Entity generator.domain.SysMessageTemplate
+*/
+@Mapper
+public interface SysMessageTemplateMapper extends BaseMapper<SysMessageTemplate> {
+
+}
+
+
+
+

+ 20 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysMessageUserMapper.java

@@ -0,0 +1,20 @@
+package com.jzg.organization.mapper;
+
+import com.jzg.commons.entity.po.SysMessageUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(消息用户表)】的数据库操作Mapper
+* @createDate 2025-02-11 10:57:51
+* @Entity generator.domain.SysMessageUser
+*/
+@Mapper
+public interface SysMessageUserMapper extends BaseMapper<SysMessageUser> {
+
+}
+
+
+
+

+ 25 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysNoticeUserMapper.java

@@ -0,0 +1,25 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.entity.dto.MessageNoticeUserParam;
+import com.jzg.commons.entity.po.SysNoticeUser;
+import com.jzg.commons.entity.vo.NoticeUserVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(通知访问用户表)】的数据库操作Mapper
+* @createDate 2025-02-10 18:23:13
+* @Entity generator.domain.SysMessageUser
+*/
+@Mapper
+public interface SysNoticeUserMapper extends BaseMapper<SysNoticeUser> {
+
+    Page<NoticeUserVo> queryUserPage(Page page, @Param("param") MessageNoticeUserParam param);
+}
+
+
+
+

+ 54 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysMessageNoticeService.java

@@ -0,0 +1,54 @@
+package com.jzg.organization.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.entity.dto.MessageNoticeAddParam;
+import com.jzg.commons.entity.dto.MessageNoticeEditParam;
+import com.jzg.commons.entity.dto.MessageNoticeParam;
+import com.jzg.commons.entity.dto.MessageNoticeUserParam;
+import com.jzg.commons.entity.po.SysMessageNotice;
+import com.jzg.commons.entity.vo.MessageNoticeVo;
+import com.jzg.commons.entity.vo.NoticeUserVo;
+
+import java.util.List;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_notice(消息通知表)】的数据库操作Service
+* @createDate 2025-02-10 18:23:10
+*/
+public interface SysMessageNoticeService extends IService<SysMessageNotice> {
+
+    /**
+     * 消息通知分页列表
+     * @param param
+     * @return
+     */
+    Page<MessageNoticeVo> queryPage(MessageNoticeParam param);
+
+    /**
+     * 消息通知新增
+     * @param param
+     */
+    void noticeAdd(MessageNoticeAddParam param);
+
+    /**
+     * 消息通知修改
+     * @param param
+     */
+    void noticeEdit(MessageNoticeEditParam param);
+
+    /**
+     * 消息通知批量删除
+     * @param ids
+     * @return
+     */
+    boolean deleteByIds(List<String> ids);
+
+    /**
+     * 消息通知人员分页列表
+     * @param param
+     * @return
+     */
+    Page<NoticeUserVo> queryUserPage(MessageNoticeUserParam param);
+}

+ 29 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysMessageService.java

@@ -0,0 +1,29 @@
+package com.jzg.organization.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.entity.dto.MessageParam;
+import com.jzg.commons.entity.po.SysMessage;
+import com.jzg.commons.entity.vo.MessageVo;
+
+import java.util.Map;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message】的数据库操作Service
+* @createDate 2025-02-10 18:23:03
+*/
+public interface SysMessageService extends IService<SysMessage> {
+
+    /**
+     * 消息分页列表
+     * @return
+     */
+    Page<MessageVo> queryPage(MessageParam param);
+
+    /**
+     * 消息数量获取
+     * @return
+     */
+    Map<Integer, Long> getMessageCount();
+}

+ 15 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysMessageTemplateService.java

@@ -0,0 +1,15 @@
+package com.jzg.organization.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jzg.commons.entity.dto.MessageTemplateParam;
+import com.jzg.commons.entity.po.SysMessageTemplate;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_template(消息模版(sys_message_template))】的数据库操作Service
+* @createDate 2025-02-08 17:56:29
+*/
+public interface SysMessageTemplateService extends IService<SysMessageTemplate> {
+
+}

+ 13 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysMessageUserService.java

@@ -0,0 +1,13 @@
+package com.jzg.organization.service;
+
+import com.jzg.commons.entity.po.SysMessageUser;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(消息用户表)】的数据库操作Service
+* @createDate 2025-02-11 10:57:51
+*/
+public interface SysMessageUserService extends IService<SysMessageUser> {
+
+}

+ 13 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysNoticeUserService.java

@@ -0,0 +1,13 @@
+package com.jzg.organization.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.entity.po.SysNoticeUser;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(通知访问用户表)】的数据库操作Service
+* @createDate 2025-02-10 18:23:13
+*/
+public interface SysNoticeUserService extends IService<SysNoticeUser> {
+
+}

+ 95 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageNoticeServiceImpl.java

@@ -0,0 +1,95 @@
+package com.jzg.organization.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+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 com.jzg.commons.entity.dto.MessageNoticeAddParam;
+import com.jzg.commons.entity.dto.MessageNoticeEditParam;
+import com.jzg.commons.entity.dto.MessageNoticeParam;
+import com.jzg.commons.entity.dto.MessageNoticeUserParam;
+import com.jzg.commons.entity.po.SysDept;
+import com.jzg.commons.entity.po.SysMessageNotice;
+import com.jzg.commons.entity.po.SysNoticeUser;
+import com.jzg.commons.entity.po.SysSystem;
+import com.jzg.commons.entity.vo.MessageNoticeVo;
+import com.jzg.commons.entity.vo.NoticeUserVo;
+import com.jzg.organization.mapper.SysDeptMapper;
+import com.jzg.organization.mapper.SysMessageNoticeMapper;
+import com.jzg.organization.mapper.SysNoticeUserMapper;
+import com.jzg.organization.service.SysMessageNoticeService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_notice(消息通知表)】的数据库操作Service实现
+* @createDate 2025-02-10 18:23:10
+*/
+@Service
+public class SysMessageNoticeServiceImpl extends ServiceImpl<SysMessageNoticeMapper, SysMessageNotice>
+    implements SysMessageNoticeService {
+
+    @Autowired
+    private SysNoticeUserMapper noticeUserMapper;
+
+    @Autowired
+    private SysDeptMapper deptMapper;
+
+    @Override
+    public Page<MessageNoticeVo> queryPage(MessageNoticeParam param) {
+        return baseMapper.queryPage(param.getPage(),param);
+    }
+
+    @Override
+    public void noticeAdd(MessageNoticeAddParam param) {
+        SysMessageNotice notice = new SysMessageNotice();
+        BeanUtils.copyProperties(param, notice);
+        this.save(notice);
+    }
+
+    @Override
+    public void noticeEdit(MessageNoticeEditParam param) {
+        SysMessageNotice notice = new SysMessageNotice();
+        BeanUtils.copyProperties(param, notice);
+        this.updateById(notice);
+    }
+
+    @Override
+    public boolean deleteByIds(List<String> ids) {
+        // 删除 通知用户表
+        LambdaQueryWrapper<SysNoticeUser> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(SysNoticeUser::getId, ids);
+        noticeUserMapper.delete(wrapper);
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    @Override
+    public Page<NoticeUserVo> queryUserPage(MessageNoticeUserParam param) {
+        Page<NoticeUserVo> page = noticeUserMapper.queryUserPage(param.getPage(), param);
+        List<NoticeUserVo> voList = page.getRecords();
+        if(CollUtil.isNotEmpty(voList)){
+            List<String> deptIds = voList.stream().map(NoticeUserVo::getDeptId)
+                    .collect(Collectors.toList());
+            List<SysDept> deptList = deptMapper.selectBatchIds(deptIds);
+            Map<String, SysDept> deptMap = deptList.stream()
+                    .collect(Collectors.toMap(SysDept::getId, Function.identity()));
+            for (NoticeUserVo noticeUserVo : voList) {
+                if(deptMap.containsKey(noticeUserVo.getDeptId())){
+                    noticeUserVo.setDeptName(deptMap.get(noticeUserVo.getDeptId()).getName());
+                }
+            }
+        }
+        return page;
+    }
+}
+
+
+
+

+ 51 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageServiceImpl.java

@@ -0,0 +1,51 @@
+package com.jzg.organization.service.impl;
+
+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 com.jzg.commons.entity.dto.MessageParam;
+import com.jzg.commons.entity.po.SysMessage;
+import com.jzg.commons.entity.vo.MessageVo;
+import com.jzg.commons.util.StringUtils;
+import com.jzg.organization.mapper.SysMessageMapper;
+import com.jzg.organization.service.SysMessageService;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message】的数据库操作Service实现
+* @createDate 2025-02-10 18:23:03
+*/
+@Service
+public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMessage>
+    implements SysMessageService {
+
+    @Override
+    public Page<MessageVo> queryPage(MessageParam param) {
+        return baseMapper.queryPage(param.getPage(), param);
+    }
+
+    @Override
+    public Map<Integer, Long> getMessageCount() {
+        List<MessageVo> messageVoList = baseMapper.queryList();
+        Map<Integer, Long> countResult = messageVoList.stream()
+                .filter(x -> x.getIsRead().equals(0))
+                .collect(Collectors.groupingBy(MessageVo::getTplType, Collectors.counting()));
+        Stream<Map.Entry<Integer, Long>> entryStream = countResult.entrySet().stream();
+        Long total = entryStream
+                .mapToLong(Map.Entry::getValue)
+                .sum();
+        countResult.put(999, total);
+        return countResult;
+    }
+}
+
+
+
+

+ 23 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageTemplateServiceImpl.java

@@ -0,0 +1,23 @@
+package com.jzg.organization.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.entity.dto.MessageTemplateParam;
+import com.jzg.commons.entity.po.SysMessageTemplate;
+import com.jzg.organization.mapper.SysMessageTemplateMapper;
+import com.jzg.organization.service.SysMessageTemplateService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_template(消息模版(sys_message_template))】的数据库操作Service实现
+* @createDate 2025-02-08 17:56:29
+*/
+@Service
+public class SysMessageTemplateServiceImpl extends ServiceImpl<SysMessageTemplateMapper, SysMessageTemplate>
+    implements SysMessageTemplateService {
+}
+
+
+
+

+ 22 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysMessageUserServiceImpl.java

@@ -0,0 +1,22 @@
+package com.jzg.organization.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.entity.po.SysMessageUser;
+import com.jzg.organization.mapper.SysMessageUserMapper;
+import com.jzg.organization.service.SysMessageUserService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(消息用户表)】的数据库操作Service实现
+* @createDate 2025-02-11 10:57:51
+*/
+@Service
+public class SysMessageUserServiceImpl extends ServiceImpl<SysMessageUserMapper, SysMessageUser>
+    implements SysMessageUserService {
+
+}
+
+
+
+

+ 22 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysNoticeUserServiceImpl.java

@@ -0,0 +1,22 @@
+package com.jzg.organization.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.entity.po.SysNoticeUser;
+import com.jzg.organization.mapper.SysNoticeUserMapper;
+import com.jzg.organization.service.SysNoticeUserService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author dongxin
+* @description 针对表【sys_message_user(通知访问用户表)】的数据库操作Service实现
+* @createDate 2025-02-10 18:23:13
+*/
+@Service
+public class SysNoticeUserServiceImpl extends ServiceImpl<SysNoticeUserMapper, SysNoticeUser>
+    implements SysNoticeUserService {
+
+}
+
+
+
+

+ 14 - 6
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java

@@ -210,17 +210,25 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public AuditCountVo getAuditCount(SysUserInfoParam sysUserInfoParam) {
         AuditCountVo auditCountVo = new AuditCountVo();
-        LambdaQueryWrapper<SysUserJzgInfo> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(StringUtils.isNotEmpty(sysUserInfoParam.getTypeAttr()), SysUserJzgInfo::getTypeAttr, sysUserInfoParam.getTypeAttr())
+        LambdaQueryWrapper<SysUserJzgInfo> queryWrapper1 = new LambdaQueryWrapper<>();
+        queryWrapper1.eq(StringUtils.isNotEmpty(sysUserInfoParam.getTypeAttr()), SysUserJzgInfo::getTypeAttr, sysUserInfoParam.getTypeAttr())
                 .eq(StringUtils.isNotEmpty(sysUserInfoParam.getDeptId()),SysUserJzgInfo::getDeptId, sysUserInfoParam.getDeptId())
                 .eq(SysUserJzgInfo::getIsDelete,0)
                 .eq(SysUserJzgInfo::getIsEnable,0)
         ;
 
-        queryWrapper.eq(SysUserJzgInfo::getStatus,4); // 未审核
-        Long noCount = sysUserJzgInfoService.count(queryWrapper);
-        queryWrapper.eq(SysUserJzgInfo::getStatus,6); // 审核失败
-        Long failCount = sysUserJzgInfoService.count(queryWrapper);
+        queryWrapper1.eq(SysUserJzgInfo::getStatus,4); // 未审核
+        Long noCount = sysUserJzgInfoService.count(queryWrapper1);
+
+        LambdaQueryWrapper<SysUserJzgInfo> queryWrapper2 = new LambdaQueryWrapper<>();
+        queryWrapper2.eq(StringUtils.isNotEmpty(sysUserInfoParam.getTypeAttr()), SysUserJzgInfo::getTypeAttr, sysUserInfoParam.getTypeAttr())
+                .eq(StringUtils.isNotEmpty(sysUserInfoParam.getDeptId()),SysUserJzgInfo::getDeptId, sysUserInfoParam.getDeptId())
+                .eq(SysUserJzgInfo::getIsDelete,0)
+                .eq(SysUserJzgInfo::getIsEnable,0)
+        ;
+
+        queryWrapper2.eq(SysUserJzgInfo::getStatus,6); // 审核失败
+        Long failCount = sysUserJzgInfoService.count(queryWrapper2);
         auditCountVo.setNoAuditCount(noCount);
         auditCountVo.setFailAuditCount(failCount);
         return auditCountVo;

+ 31 - 0
tenant/organization/src/main/resources/application-dev.yml

@@ -47,6 +47,9 @@ tenant:
     - sys_activity
     - sys_activity_award
     - sys_poster_org
+    - sys_message_template
+    - sys_message_user
+    - sys_notice_user
   ignoreLoginNames:
 
 data-scope:
@@ -59,3 +62,31 @@ minio:
   access-key: v7Zb8XhyLcYNcSHlxvyK
   secret-key: 58YibMwpxGKtXcekPL065OM4GonC1hf2tFMjI9EN
   bucket-name: jzg
+
+rocketmq:
+  consumer:
+    group: springboot_consumer_group
+    # 一次拉取消息最大值,注意是拉取消息的最大值而非消费最大值
+    pull-batch-size: 10
+  name-server: 39.98.199.213:9876
+  producer:
+    # 发送同一类消息的设置为同一个group,保证唯一
+    group: springboot_producer_group
+    # 发送消息超时时间,默认3000
+    sendMessageTimeout: 10000
+    # 发送消息失败重试次数,默认2
+    retryTimesWhenSendFailed: 2
+    # 异步消息重试此处,默认2
+    retryTimesWhenSendAsyncFailed: 2
+    # 消息最大长度,默认1024 * 1024 * 4(默认4M)
+    maxMessageSize: 4096
+    # 压缩消息阈值,默认4k(1024 * 4)
+    compressMessageBodyThreshold: 4096
+    # 是否在内部发送失败时重试另一个broker,默认false
+    retryNextServer: false
+  enhance:
+    # 启动隔离,用于激活配置类EnvironmentIsolationConfig
+    # 启动后会自动在topic上拼接激活的配置文件,达到自动隔离的效果
+    enabledIsolation: true
+    # 隔离环境名称,拼接到topic后,topic_dev,默认空字符串
+    environment: dev

+ 32 - 0
tenant/organization/src/main/resources/application-test.yml

@@ -48,6 +48,9 @@ tenant:
     - sys_activity
     - sys_activity_award
     - sys_poster_org
+    - sys_message_template
+    - sys_message_user
+    - sys_notice_user
   ignoreLoginNames:
 
 data-scope:
@@ -60,3 +63,32 @@ minio:
   access-key: N8hf40VDM3Uf2xJ5vnvE
   secret-key: CDe1raroqIMo5R2KhHl6ZQbJOhdq0mrtCI78g3vq
   bucket-name: jzg
+
+
+rocketmq:
+  consumer:
+    group: springboot_consumer_group
+    # 一次拉取消息最大值,注意是拉取消息的最大值而非消费最大值
+    pull-batch-size: 10
+  name-server: 127.0.0.1:9876
+  producer:
+    # 发送同一类消息的设置为同一个group,保证唯一
+    group: springboot_producer_group
+    # 发送消息超时时间,默认3000
+    sendMessageTimeout: 10000
+    # 发送消息失败重试次数,默认2
+    retryTimesWhenSendFailed: 2
+    # 异步消息重试此处,默认2
+    retryTimesWhenSendAsyncFailed: 2
+    # 消息最大长度,默认1024 * 1024 * 4(默认4M)
+    maxMessageSize: 4096
+    # 压缩消息阈值,默认4k(1024 * 4)
+    compressMessageBodyThreshold: 4096
+    # 是否在内部发送失败时重试另一个broker,默认false
+    retryNextServer: false
+  enhance:
+    # 启动隔离,用于激活配置类EnvironmentIsolationConfig
+    # 启动后会自动在topic上拼接激活的配置文件,达到自动隔离的效果
+    enabledIsolation: true
+    # 隔离环境名称,拼接到topic后,topic_dev,默认空字符串
+    environment: test

+ 4 - 1
tenant/organization/src/main/resources/application.yml

@@ -36,9 +36,12 @@ tenant:
     - sys_activity
     - sys_activity_award
     - sys_poster_org
+    - sys_message_template
+    - sys_message_user
+    - sys_notice_user
   ignoreLoginNames:
 
-data-scope:
+ata-scope:
   tables:
     - sys_user_jzg_info
     - sys_dept

+ 50 - 0
tenant/organization/src/main/resources/mapper/SysMessageMapper.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.SysMessageMapper">
+
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.po.SysMessage">
+            <id property="id" column="id" jdbcType="VARCHAR"/>
+            <result property="title" column="title" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="tplId" column="tpl_id" jdbcType="VARCHAR"/>
+            <result property="tplCode" column="tpl_code" jdbcType="VARCHAR"/>
+            <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,title,content,tpl_id
+        tpl_code,create_by,create_time,
+        update_by,update_time,is_delete
+    </sql>
+    <select id="queryPage" resultType="com.jzg.commons.entity.vo.MessageVo">
+        SELECT sm.id, sm.title, sm.content, sm.tpl_id AS tplId,
+        sm.tpl_code AS tplCode,sm.create_by as createBy,sm.create_time as createTime,
+        sm.update_by as updateBy,sm.update_time as updateTime,sm.is_delete as isDelete,sm.system_code as systemCode,
+        smu.user_id as userId, smu.is_read as isRead ,smt.type as tplType
+        FROM sys_message_user smu
+        LEFT JOIN sys_message sm on smu.message_id = sm.id
+        LEFT JOIN sys_message_template smt on sm.tpl_id = smt.id
+        <where>
+            <if test="param.type != null">
+                and smt.type = #{param.type}
+            </if>
+        </where>
+        ORDER BY sm.create_time DESC
+    </select>
+    <select id="queryList" resultType="com.jzg.commons.entity.vo.MessageVo">
+        SELECT sm.id, sm.title, sm.content, sm.tpl_id AS tplId,
+        sm.tpl_code AS tplCode,sm.create_by as createBy,sm.create_time as createTime,
+        sm.update_by as updateBy,sm.update_time as updateTime,sm.is_delete as isDelete,sm.system_code as systemCode,
+        smu.user_id as userId, smu.is_read as isRead ,smt.type as tplType
+        FROM sys_message_user smu
+        LEFT JOIN sys_message sm on smu.message_id = sm.id
+        LEFT JOIN sys_message_template smt on sm.tpl_id = smt.id
+        ORDER BY sm.create_time DESC
+    </select>
+</mapper>

+ 44 - 0
tenant/organization/src/main/resources/mapper/SysMessageNoticeMapper.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.SysMessageNoticeMapper">
+
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.po.SysMessageNotice">
+            <id property="id" column="id" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="sendDeptId" column="send_dept_id" jdbcType="VARCHAR"/>
+            <result property="isChildren" column="is_children" jdbcType="TINYINT"/>
+            <result property="isForce" column="is_force" jdbcType="TINYINT"/>
+            <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        smn.id,smn.title,smn.content,smn.send_dept_id,smn.send_dept_name,
+        smn.is_children,smn.is_force,smn.create_by,
+        smn.create_time,smn.update_by,smn.update_time,
+        smn.is_delete,smn.system_code
+    </sql>
+    <select id="queryPage" resultType="com.jzg.commons.entity.vo.MessageNoticeVo">
+        select <include refid="Base_Column_List"/>,COUNT(snu.id) as viewCount
+        FROM sys_message_notice smn
+        LEFT JOIN sys_notice_user snu on smn.id = snu.notice_id
+        <where>
+            smn.is_delete = 0
+            <if test="param.sendDeptId != null and param.sendDeptId != ''">
+                and smn.send_dept_id = #{param.sendDeptId}
+            </if>
+            <if test="param.searchValue != null and param.searchValue != ''">
+                and ( smn.title = #{param.searchValue} or smn.content = #{param.searchValue})
+            </if>
+        </where>
+        GROUP BY smn.id
+        order by smn.create_time desc
+    </select>
+
+
+</mapper>

+ 32 - 0
tenant/organization/src/main/resources/mapper/SysMessageTemplateMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.SysMessageTemplateMapper">
+
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.po.SysMessageTemplate">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="tplCode" column="tpl_code" jdbcType="VARCHAR"/>
+            <result property="tplName" column="tpl_name" jdbcType="VARCHAR"/>
+            <result property="type" column="type" jdbcType="TINYINT"/>
+            <result property="model" column="model" jdbcType="VARCHAR"/>
+            <result property="sendPlace" column="send_place" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="linkUrl" column="link_url" jdbcType="VARCHAR"/>
+            <result property="receive" column="receive" jdbcType="VARCHAR"/>
+            <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
+            <result property="isEnable" column="is_enable" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,tpl_code,tpl_name,
+        type,model,send_place,
+        content,link_url,receive,
+        create_by,create_time,update_by,
+        update_time,is_delete,is_enable
+    </sql>
+</mapper>

+ 18 - 0
tenant/organization/src/main/resources/mapper/SysMessageUserMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.SysMessageUserMapper">
+
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.po.SysMessageUser">
+            <id property="id" column="id" jdbcType="VARCHAR"/>
+            <result property="messageId" column="message_id" jdbcType="VARCHAR"/>
+            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
+            <result property="isRead" column="is_read" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,message_id,user_id,
+        isRead
+    </sql>
+</mapper>

+ 27 - 0
tenant/organization/src/main/resources/mapper/SysNoticeUserMapper.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jzg.organization.mapper.SysNoticeUserMapper">
+
+    <resultMap id="BaseResultMap" type="com.jzg.commons.entity.po.SysNoticeUser">
+            <id property="id" column="id" jdbcType="VARCHAR"/>
+            <result property="noticeId" column="notice_id" jdbcType="VARCHAR"/>
+            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,notice_id,user_id
+    </sql>
+    <select id="queryUserPage" resultType="com.jzg.commons.entity.vo.NoticeUserVo">
+        SELECT snu.user_id as userId ,suji.name, su.mobile, suji.work_number as workNumber,suji.dept_id,snu.create_time as createTime
+        FROM sys_notice_user snu
+        LEFT JOIN sys_user_jzg_info suji on snu.user_id = suji.id
+        LEFT JOIN sys_user su on su.id = suji.user_id
+        <where>
+            <if test="param.id != null and param.id != ''">
+                and snu.notice_id = #{param.id}
+            </if>
+        </where>
+    </select>
+</mapper>

+ 10 - 0
tenant/pom.xml

@@ -14,6 +14,7 @@
         <module>organization</module>
         <module>openfeign</module>
         <module>insurance</module>
+        <module>rocketmq</module>
     </modules>
     <dependencies>
         <dependency>
@@ -47,6 +48,15 @@
             <artifactId>lombok</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.jzg</groupId>
+            <artifactId>rocketmq</artifactId>
+        </dependency>
+
     </dependencies>
 
     <dependencyManagement>

+ 38 - 0
tenant/rocketmq/pom.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.jzg</groupId>
+        <artifactId>jzg</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>rocketmq</artifactId>
+    <name>rocketmq Maven Webapp</name>
+    <url>http://maven.apache.org</url>
+
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+    </properties>
+    <dependencies>
+        <!--SpringFramework-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 35 - 0
tenant/rocketmq/src/main/java/com/jzg/autoconfigure/EnvironmentIsolationConfig.java

@@ -0,0 +1,35 @@
+package com.jzg.autoconfigure;
+
+import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author dongxin
+ */
+public class EnvironmentIsolationConfig implements BeanPostProcessor {
+    private RocketEnhanceProperties rocketEnhanceProperties;
+
+    public EnvironmentIsolationConfig(RocketEnhanceProperties rocketEnhanceProperties) {
+        this.rocketEnhanceProperties = rocketEnhanceProperties;
+    }
+
+
+    /**
+     * 在装载Bean之前实现参数修改
+     */
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+        if(bean instanceof DefaultRocketMQListenerContainer){
+
+            DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean;
+
+            if(rocketEnhanceProperties.isEnabledIsolation() && StringUtils.hasText(rocketEnhanceProperties.getEnvironment())){
+                container.setTopic(String.join("_", container.getTopic(),rocketEnhanceProperties.getEnvironment()));
+            }
+            return container;
+        }
+        return bean;
+    }
+}

+ 16 - 0
tenant/rocketmq/src/main/java/com/jzg/autoconfigure/RocketEnhanceProperties.java

@@ -0,0 +1,16 @@
+package com.jzg.autoconfigure;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author dongxin
+ */
+@ConfigurationProperties(prefix = "rocketmq.enhance")
+@Data
+public class RocketEnhanceProperties {
+
+    private boolean enabledIsolation;
+
+    private String environment;
+}

+ 66 - 0
tenant/rocketmq/src/main/java/com/jzg/autoconfigure/RocketMQEnhanceAutoConfiguration.java

@@ -0,0 +1,66 @@
+package com.jzg.autoconfigure;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.jzg.templete.RocketMQEnhanceTemplate;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.messaging.converter.MappingJackson2MessageConverter;
+import org.springframework.messaging.converter.MessageConverter;
+
+import java.util.List;
+
+/**
+ * @author dongxin
+ * rocketmq 自动增强配置类
+ */
+@Configuration
+@EnableConfigurationProperties(RocketEnhanceProperties.class)
+public class RocketMQEnhanceAutoConfiguration {
+
+    /**
+     * 注入增强的RocketMQEnhanceTemplate
+     */
+    @Bean
+    public RocketMQEnhanceTemplate rocketMQEnhanceTemplate(RocketMQTemplate rocketMQTemplate){
+        return new RocketMQEnhanceTemplate(rocketMQTemplate);
+    }
+
+    /**
+     * 解决RocketMQ Jackson不支持Java时间类型配置
+     * 源码参考:{@link org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration}
+     */
+    @Bean
+    @Primary
+    public RocketMQMessageConverter enhanceRocketMQMessageConverter(){
+        RocketMQMessageConverter converter = new RocketMQMessageConverter();
+        CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
+        List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
+        for (MessageConverter messageConverter : messageConverterList) {
+            if(messageConverter instanceof MappingJackson2MessageConverter){
+                MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
+                ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
+                objectMapper.registerModules(new JavaTimeModule());
+            }
+        }
+        return converter;
+    }
+
+
+    /**
+     * 环境隔离配置
+     */
+    @Bean
+    @ConditionalOnProperty(name="rocketmq.enhance.enabledIsolation", havingValue="true")
+    public EnvironmentIsolationConfig environmentSetup(RocketEnhanceProperties rocketEnhanceProperties){
+        return new EnvironmentIsolationConfig(rocketEnhanceProperties);
+
+    }
+
+}

+ 34 - 0
tenant/rocketmq/src/main/java/com/jzg/constant/EnhanceMessageConstant.java

@@ -0,0 +1,34 @@
+package com.jzg.constant;
+
+import lombok.experimental.UtilityClass;
+
+/**
+ * @author dongxin
+ * Rocketmq的演示级别
+ */
+@UtilityClass
+public class EnhanceMessageConstant {
+    public final int ONE_SECOND = 1;
+    public final int FIVE_SECOND = 2;
+
+    public final int TEN_SECOND = 3;
+    public final int THIRTY_SECOND = 4;
+    public final int ONE_MINUTE = 5;
+    public final int TWO_MINUTE = 6;
+    public final int THREE_MINUTE = 7;
+    public final int FOUR_MINUTE = 8;
+    public final int FIVE_MINUTE = 9;
+    public final int SIX_MINUTE = 10;
+    public final int SEVEN_MINUTE = 11;
+    public final int EIGHT_MINUTE = 12;
+    public final int NINE_MINUTE = 13;
+    public final int TEN_MINUTE = 14;
+    public final int TWENTY_MINUTE = 15;
+    public final int THIRTY_MINUTE = 16;
+    public final int ONE_HOUR = 17;
+    public final int TWO_HOUR = 18;
+
+    public final String RETRY_PREFIX = "RETRY_";
+
+
+}

+ 30 - 0
tenant/rocketmq/src/main/java/com/jzg/domain/BaseMessage.java

@@ -0,0 +1,30 @@
+package com.jzg.domain;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 消息实体,所有消息都需要继承此类
+ */
+@Data
+public abstract class BaseMessage {
+    /**
+     * 业务键,用于RocketMQ控制台查看消费情况
+     */
+    protected String key;
+    /**
+     * 发送消息来源,用于排查问题
+     */
+    protected String source = "";
+
+    /**
+     * 发送时间
+     */
+    protected LocalDateTime sendTime = LocalDateTime.now();
+
+    /**
+     * 重试次数,用于判断重试次数,超过重试次数发送异常警告
+     */
+    protected Integer retryTimes = 0;
+}

+ 23 - 0
tenant/rocketmq/src/main/java/com/jzg/domain/message/MemberMessage.java

@@ -0,0 +1,23 @@
+package com.jzg.domain.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+/**
+ * @author dongxin
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberMessage extends BaseMessage {
+
+    private String userName;
+
+    private LocalDate birthday;
+}

+ 18 - 0
tenant/rocketmq/src/main/java/com/jzg/domain/message/NormalMessage.java

@@ -0,0 +1,18 @@
+package com.jzg.domain.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author dongxin
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class NormalMessage extends BaseMessage {
+    private String message;
+}

+ 25 - 0
tenant/rocketmq/src/main/java/com/jzg/domain/message/OrderMessage.java

@@ -0,0 +1,25 @@
+package com.jzg.domain.message;
+
+import com.jzg.domain.BaseMessage;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author jam
+ * 公众号:JAVA日知录
+ * @date 2023/3/30 11:32
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderMessage extends BaseMessage {
+
+    private LocalDateTime tradeTime;
+
+    private String body;
+}

+ 159 - 0
tenant/rocketmq/src/main/java/com/jzg/handler/EnhanceMessageHandler.java

@@ -0,0 +1,159 @@
+package com.jzg.handler;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.constant.EnhanceMessageConstant;
+import com.jzg.domain.BaseMessage;
+import com.jzg.templete.RocketMQEnhanceTemplate;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+
+
+/**
+ * @author dongxin
+ * 抽象消息监听器,封装了所有公共处理业务,如
+ * 1、基础日志记录
+ * 2、异常处理
+ * 3、消息重试
+ * 4、警告通知
+ * ...
+ */
+@Slf4j
+public abstract class EnhanceMessageHandler<T extends BaseMessage> {
+    /**
+     * 默认重试次数
+     */
+    private static final int MAX_RETRY_TIMES = 3;
+
+    /**
+     * 延时等级
+     */
+    private static final int DELAY_LEVEL = EnhanceMessageConstant.FIVE_SECOND;
+
+
+    @Resource
+    private RocketMQEnhanceTemplate rocketMQEnhanceTemplate;
+
+    /**
+     * 消息处理
+     *
+     * @param message 待处理消息
+     * @throws Exception 消费异常
+     */
+    protected abstract void handleMessage(T message) throws Exception;
+
+    /**
+     * 超过重试次数消息,需要启用isRetry
+     *
+     * @param message 待处理消息
+     */
+    protected abstract void handleMaxRetriesExceeded(T message);
+
+
+    /**
+     * 是否需要根据业务规则过滤消息,去重逻辑可以在此处处理
+     * @param message 待处理消息
+     * @return true: 本次消息被过滤,false:不过滤
+     */
+    protected boolean filter(T message) {
+        return false;
+    }
+
+    /**
+     * 是否异常时重复发送
+     *
+     * @return true: 消息重试,false:不重试
+     */
+    protected abstract boolean isRetry();
+
+    /**
+     * 消费异常时是否抛出异常
+     * 返回true,则由rocketmq机制自动重试
+     * false:消费异常(如果没有开启重试则消息会被自动ack)
+     */
+    protected abstract boolean throwException();
+
+    /**
+     * 最大重试次数
+     *
+     * @return 最大重试次数,默认5次
+     */
+    protected int getMaxRetryTimes() {
+        return MAX_RETRY_TIMES;
+    }
+
+    /**
+     * isRetry开启时,重新入队延迟时间
+     * @return -1:立即入队重试
+     */
+    protected int getDelayLevel() {
+        return DELAY_LEVEL;
+    }
+
+    /**
+     * 使用模板模式构建消息消费框架,可自由扩展或删减
+     */
+    public void dispatchMessage(T message) {
+        // 基础日志记录被父类处理了
+        log.info("消费者收到消息[{}]", JSONObject.toJSON(message));
+
+        if (filter(message)) {
+            log.info("消息id{}不满足消费条件,已过滤。",message.getKey());
+            return;
+        }
+        // 超过最大重试次数时调用子类方法处理
+        if (message.getRetryTimes() > getMaxRetryTimes()) {
+            handleMaxRetriesExceeded(message);
+            return;
+        }
+        try {
+            long now = System.currentTimeMillis();
+            handleMessage(message);
+            long costTime = System.currentTimeMillis() - now;
+            log.info("消息{}消费成功,耗时[{}ms]", message.getKey(),costTime);
+        } catch (Exception e) {
+            log.error("消息{}消费异常", message.getKey(),e);
+            // 是捕获异常还是抛出,由子类决定
+            if (throwException()) {
+                //抛出异常,由DefaultMessageListenerConcurrently类处理
+                throw new RuntimeException(e);
+            }
+            //此时如果不开启重试机制,则默认ACK了
+            if (isRetry()) {
+                handleRetry(message);
+            }
+        }
+    }
+
+    protected void handleRetry(T message) {
+        // 获取子类RocketMQMessageListener注解拿到topic和tag
+        RocketMQMessageListener annotation = this.getClass().getAnnotation(RocketMQMessageListener.class);
+        if (annotation == null) {
+            return;
+        }
+        //重新构建消息体
+        String messageSource = message.getSource();
+        if(!messageSource.startsWith(EnhanceMessageConstant.RETRY_PREFIX)){
+            message.setSource(EnhanceMessageConstant.RETRY_PREFIX + messageSource);
+        }
+        message.setRetryTimes(message.getRetryTimes() + 1);
+
+        SendResult sendResult;
+
+        try {
+            // 如果消息发送不成功,则再次重新发送,如果发送异常则抛出由MQ再次处理(异常时不走延迟消息)
+            sendResult = rocketMQEnhanceTemplate.send(annotation.topic(), annotation.selectorExpression(), message, getDelayLevel());
+        } catch (Exception ex) {
+            // 此处捕获之后,相当于此条消息被消息完成然后重新发送新的消息
+            //由生产者直接发送
+            throw new RuntimeException(ex);
+        }
+        // 发送失败的处理就是不进行ACK,由RocketMQ重试
+        if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
+            throw new RuntimeException("重试消息发送失败");
+        }
+
+    }
+}

+ 85 - 0
tenant/rocketmq/src/main/java/com/jzg/templete/RocketMQEnhanceTemplate.java

@@ -0,0 +1,85 @@
+package com.jzg.templete;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.autoconfigure.RocketEnhanceProperties;
+import com.jzg.domain.BaseMessage;
+import jakarta.annotation.Resource;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.apache.rocketmq.spring.support.RocketMQHeaders;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author dongxin
+ * RocketMQ增强模板类,优先使用
+ */
+@Slf4j
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class RocketMQEnhanceTemplate {
+    private final RocketMQTemplate template;
+
+    @Resource
+    private RocketEnhanceProperties rocketEnhanceProperties;
+
+    public RocketMQTemplate getTemplate() {
+        return template;
+    }
+
+    /**
+     * 根据系统上下文自动构建隔离后的topic
+     * 构建目的地
+     */
+    public String buildDestination(String topic, String tag) {
+        topic = reBuildTopic(topic);
+        return topic + ":" + tag;
+    }
+
+    /**
+     * 根据环境重新隔离topic
+     * @param topic 原始topic
+     */
+    private String reBuildTopic(String topic) {
+        if(rocketEnhanceProperties.isEnabledIsolation() && StringUtils.hasText(rocketEnhanceProperties.getEnvironment())){
+            return topic +"_" + rocketEnhanceProperties.getEnvironment();
+        }
+        return topic;
+    }
+
+    /**
+     * 发送同步消息
+     */
+    public <T extends BaseMessage> SendResult send(String topic, String tag, T message) {
+        // 注意分隔符
+        return send(buildDestination(topic,tag), message);
+    }
+
+
+    public <T extends BaseMessage> SendResult send(String destination, T message) {
+        // 设置业务键,此处根据公共的参数进行处理
+        // 更多的其它基础业务处理...
+        Message<T> sendMessage = MessageBuilder.withPayload(message).setHeader(RocketMQHeaders.KEYS, message.getKey()).build();
+        SendResult sendResult = template.syncSend(destination, sendMessage);
+        // 此处为了方便查看给日志转了json,根据选择选择日志记录方式,例如ELK采集
+        log.info("[{}]同步消息[{}]发送结果[{}]", destination, JSONObject.toJSON(message), JSONObject.toJSON(sendResult));
+        return sendResult;
+    }
+
+    /**
+     * 发送延迟消息
+     */
+    public <T extends BaseMessage> SendResult send(String topic, String tag, T message, int delayLevel) {
+        return send(buildDestination(topic,tag), message, delayLevel);
+    }
+
+    public <T extends BaseMessage> SendResult send(String destination, T message, int delayLevel) {
+        Message<T> sendMessage = MessageBuilder.withPayload(message).setHeader(RocketMQHeaders.KEYS, message.getKey()).build();
+        SendResult sendResult = template.syncSend(destination, sendMessage, 3000, delayLevel);
+        log.info("[{}]延迟等级[{}]消息[{}]发送结果[{}]", destination, delayLevel, JSONObject.toJSON(message), JSONObject.toJSON(sendResult));
+        return sendResult;
+    }
+}

+ 2 - 0
tenant/rocketmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1,2 @@
+org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration
+com.jzg.autoconfigure.RocketMQEnhanceAutoConfiguration