Commit e9223bf3406ddb651590ad044ea0c57849bb14d2

Authored by 张志伟
1 parent dc302772

:tada: 主体代码编写完成

Showing 21 changed files with 552 additions and 82 deletions
fw-hestia-common/src/main/java/cn/fw/hestia/common/constant/MessageStr.java
... ... @@ -9,4 +9,6 @@ package cn.fw.hestia.common.constant;
9 9 public interface MessageStr {
10 10 String QUERY_FAILURE = "查询失败";
11 11 String SAVE_FAILURE = "操作失败";
  12 +
  13 + String SUCCEED_STR = "succeed";
12 14 }
... ...
fw-hestia-domain/src/main/java/cn/fw/hestia/domain/db/MessageHistory.java
1 1 package cn.fw.hestia.domain.db;
2 2  
3   -import cn.fw.hestia.domain.enums.SendStateEnum;
  3 +import cn.fw.hestia.domain.enums.MessageStateEnum;
4 4 import com.baomidou.mybatisplus.annotation.*;
5 5 import com.baomidou.mybatisplus.extension.activerecord.Model;
6 6 import lombok.Data;
... ... @@ -65,7 +65,11 @@ public class MessageHistory extends Model<MessageHistory> {
65 65 /**
66 66 * 发送状态
67 67 */
68   - private SendStateEnum sendState;
  68 + private MessageStateEnum state;
  69 + /**
  70 + * 是否有效
  71 + */
  72 + private Boolean yn;
69 73 /**
70 74 * 创建时间
71 75 */
... ...
fw-hestia-domain/src/main/java/cn/fw/hestia/domain/enums/SendStateEnum.java renamed to fw-hestia-domain/src/main/java/cn/fw/hestia/domain/enums/MessageStateEnum.java
... ... @@ -11,15 +11,15 @@ import lombok.Getter;
11 11 * @description : 发送状态
12 12 * @date: 2020-08-11 17:37
13 13 */
14   -public enum SendStateEnum implements IEnum<Integer> {
  14 +public enum MessageStateEnum implements IEnum<Integer> {
15 15 /**
16   - * 等待回调
  16 + * 未处理
17 17 */
18   - OK(1, "发送成功"),
  18 + MADA(1, "未处理"),
19 19 /**
20   - * 完成回调
  20 + * 已处理
21 21 */
22   - FAIL(2, "发送失败"),
  22 + SUMI(2, "已处理"),
23 23 ;
24 24  
25 25 /**
... ... @@ -32,7 +32,7 @@ public enum SendStateEnum implements IEnum&lt;Integer&gt; {
32 32 @Getter
33 33 private final String name;
34 34  
35   - SendStateEnum(final Integer value, final String name) {
  35 + MessageStateEnum(final Integer value, final String name) {
36 36 this.value = value;
37 37 this.name = name;
38 38 }
... ... @@ -41,8 +41,8 @@ public enum SendStateEnum implements IEnum&lt;Integer&gt; {
41 41 * 根据枚举值获取枚举对象
42 42 */
43 43 @JsonCreator
44   - public static SendStateEnum ofValue(final Integer value) {
45   - for (final SendStateEnum stateEnum : SendStateEnum.values()) {
  44 + public static MessageStateEnum ofValue(final Integer value) {
  45 + for (final MessageStateEnum stateEnum : MessageStateEnum.values()) {
46 46 if (stateEnum.value.equals(value)) {
47 47 return stateEnum;
48 48 }
... ... @@ -68,7 +68,7 @@ public enum SendStateEnum implements IEnum&lt;Integer&gt; {
68 68 */
69 69 @JsonCreator
70 70 public static String getNameByVale(final Integer value) {
71   - for (final SendStateEnum stateEnum : SendStateEnum.values()) {
  71 + for (final MessageStateEnum stateEnum : MessageStateEnum.values()) {
72 72 if (stateEnum.value.equals(value)) {
73 73 return stateEnum.getName();
74 74 }
... ...
fw-hestia-domain/src/main/java/cn/fw/hestia/domain/vo/Demo.java deleted
1   -package cn.fw.hestia.domain.vo;
2   -
3   -/**
4   - * @author : kurisu
5   - * @className : Demo
6   - * @description :
7   - * @date: 2021-09-23 15:26
8   - */
9   -public class Demo {
10   -}
fw-hestia-domain/src/main/java/cn/fw/hestia/domain/vo/HistoryQuery.java 0 → 100644
  1 +package cn.fw.hestia.domain.vo;
  2 +
  3 +import cn.fw.common.page.BasePageQuery;
  4 +import cn.fw.common.web.annotation.LoginContextField;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +/**
  10 + * @author : kurisu
  11 + * @className : HistoryQuery
  12 + * @description : 查询条件
  13 + * @date: 2021-09-25 10:45
  14 + */
  15 +@Data
  16 +@ToString(callSuper = true)
  17 +@EqualsAndHashCode(callSuper = true)
  18 +public class HistoryQuery extends BasePageQuery {
  19 +
  20 + @LoginContextField(LoginContextField.Name.USER_ID)
  21 + private Long memberId;
  22 +}
... ...
fw-hestia-domain/src/main/java/cn/fw/hestia/domain/vo/MessageHistoryVO.java 0 → 100644
  1 +package cn.fw.hestia.domain.vo;
  2 +
  3 +import cn.fw.hestia.domain.db.MessageHistory;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +import java.util.Date;
  8 +import java.util.Objects;
  9 +
  10 +/**
  11 + * @author : kurisu
  12 + * @className : Demo
  13 + * @description :
  14 + * @date: 2021-09-23 15:26
  15 + */
  16 +@Data
  17 +@ToString
  18 +public class MessageHistoryVO {
  19 + private Long messageId;
  20 + /**
  21 + * 会员id
  22 + */
  23 + private Long memberId;
  24 + /**
  25 + * 消息内容
  26 + */
  27 + private String title;
  28 + /**
  29 + * 备注
  30 + */
  31 + private String remark;
  32 + /**
  33 + * 是否已读
  34 + */
  35 + private Boolean readz;
  36 + /**
  37 + * 发送时间
  38 + */
  39 + private Date messageTime;
  40 +
  41 + public static MessageHistoryVO with(MessageHistory history) {
  42 + if (Objects.isNull(history)) {
  43 + return null;
  44 + }
  45 + MessageHistoryVO vo = new MessageHistoryVO();
  46 + vo.setMessageId(history.getId());
  47 + vo.setMemberId(history.getMemberId());
  48 + vo.setTitle(history.getTitle());
  49 + vo.setReadz(history.getReadz());
  50 + vo.setRemark(history.getRemark());
  51 + vo.setMessageTime(history.getCreateTime());
  52 + return vo;
  53 + }
  54 +}
... ...
fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/TemplateMessageService.java
1 1 package cn.fw.hestia.rpc.passport;
2 2  
3 3 import cn.fw.data.base.domain.common.Message;
  4 +import cn.fw.hestia.common.constant.MessageStr;
4 5 import cn.fw.hestia.common.utils.StringUtils;
5 6 import cn.fw.hestia.rpc.passport.dto.TMParam;
6 7 import cn.fw.passport.sdk.api.WxMpTemplateMessageApi;
7 8 import cn.fw.passport.sdk.api.param.WxMpTempMessageData;
8 9 import cn.fw.passport.sdk.api.param.WxMpTempMessageParam;
9   -import lombok.Getter;
  10 +import com.alibaba.fastjson.JSONArray;
10 11 import lombok.extern.slf4j.Slf4j;
11 12 import org.springframework.stereotype.Service;
12 13  
13   -import java.util.Arrays;
14 14 import java.util.List;
15 15  
16 16 /**
... ... @@ -31,12 +31,6 @@ public class TemplateMessageService {
31 31 }
32 32  
33 33 /**
34   - * 消息模板Code
35   - */
36   - @Getter
37   - private final String templateCode = "OPENTM412432053";
38   -
39   - /**
40 34 * 发送消息通知
41 35 *
42 36 * @param messageParam
... ... @@ -46,34 +40,33 @@ public class TemplateMessageService {
46 40 try {
47 41 WxMpTempMessageParam param = new WxMpTempMessageParam();
48 42 param.setCusId(messageParam.getMemberId());
49   - param.setTempCode(getTemplateCode());
  43 + param.setTempCode(messageParam.getTemplateCode());
50 44 WxMpTempMessageData remark = new WxMpTempMessageData();
51 45 remark.setValue(messageParam.getRemark());
52   - remark.setColor("#a61b29");
53 46 param.setRemark(remark);
54 47 param.setTitle(new WxMpTempMessageData(messageParam.getTitle()));
55   - List<WxMpTempMessageData> keywords = Arrays.asList(
56   - new WxMpTempMessageData(messageParam.getChangeType()),
57   - //门店
58   - new WxMpTempMessageData(messageParam.getChangeResult())
59   - //到期时间
60   - );
61   - param.setKeyWordList(keywords);
62   - param.setPagePath(getPagePath(messageParam.getPath(), messageParam.getSceneToken()));
  48 + if (StringUtils.isValid(messageParam.getKeywords())) {
  49 + List<WxMpTempMessageData> keywords = JSONArray.parseArray(messageParam.getKeywords(), WxMpTempMessageData.class);
  50 + param.setKeyWordList(keywords);
  51 + }
  52 + String pagePath = getPagePath(messageParam.getPath(), messageParam.getSceneToken());
  53 + if (StringUtils.isValid(pagePath)) {
  54 + param.setPagePath(pagePath);
  55 + }
63 56 Message<?> msg = wxMpTemplateMessageApi.send(param);
64 57 if (!msg.isSuccess()) {
65 58 log.error("【passport系统】发送模板消息失败:{}", msg.getResult());
66 59 return msg.getResult();
67 60 }
68   - return "";
  61 + return MessageStr.SUCCEED_STR;
69 62 } catch (Exception e) {
70 63 log.error("发送模板消息失败", e);
71   - return "系统异常";
  64 + return "系统调用异常";
72 65 }
73 66 }
74 67  
75 68  
76   - private String getPagePath(String path, String sceneToken) {
  69 + private String getPagePath(String path, Long sceneToken) {
77 70 if (StringUtils.isEmpty(path)) {
78 71 return null;
79 72 }
... ...
fw-hestia-rpc/src/main/java/cn/fw/hestia/rpc/passport/dto/TMParam.java
... ... @@ -28,26 +28,20 @@ public class TMParam {
28 28 * 标题
29 29 */
30 30 private String title;
  31 +
  32 + private String keywords;
31 33 /**
32 34 * 备注
33 35 */
34 36 private String remark;
35   - /**
36   - * 变更类型
37   - */
38   - private String changeType;
39   - /**
40   - * 变更结果
41   - */
42   - private String changeResult;
  37 +
43 38 /**
44 39 * 如需跳转小程序,则是小程序页面路径
45 40 */
46 41 private String path;
47   - /**
48   - * 跳转小程序所携带的参数
49   - */
50   - private Map<String, String> paramMap;
51 42  
52   - private String sceneToken;
  43 +
  44 + private Long sceneToken;
  45 +
  46 + private String templateCode;
53 47 }
... ...
fw-hestia-sdk/src/main/java/cn/fw/hestia/sdk/api/IMessageCenterService.java
... ... @@ -3,10 +3,12 @@ package cn.fw.hestia.sdk.api;
3 3 import cn.fw.data.base.domain.common.Message;
4 4 import cn.fw.hestia.sdk.params.TemplateMessageParam;
5 5 import org.springframework.cloud.openfeign.FeignClient;
  6 +import org.springframework.web.bind.annotation.DeleteMapping;
6 7 import org.springframework.web.bind.annotation.PostMapping;
7 8 import org.springframework.web.bind.annotation.RequestBody;
8 9  
9 10 import javax.validation.Valid;
  11 +import javax.validation.constraints.NotNull;
10 12  
11 13 /**
12 14 * @author : kurisu
... ... @@ -16,19 +18,22 @@ import javax.validation.Valid;
16 18 */
17 19 @FeignClient(value = "fw-hestia", path = "/api/hestia/mc")
18 20 public interface IMessageCenterService {
  21 +
19 22 /**
20   - * 异步发送模板消息
  23 + * 发送模板消息
  24 + *
21 25 * @param templateMessageParam
22 26 * @return
23 27 */
24   - @PostMapping("/asynSend")
25   - Message<Long> asynSend(@Valid @RequestBody TemplateMessageParam templateMessageParam);
  28 + @PostMapping("/send")
  29 + Message<Long> send(@Valid @RequestBody TemplateMessageParam templateMessageParam);
26 30  
27 31 /**
28   - * 同步
29   - * @param templateMessageParam
  32 + * 撤回消息
  33 + *
  34 + * @param sceneToken
30 35 * @return
31 36 */
32   - @PostMapping("/send")
33   - Message<Long> send(@Valid @RequestBody TemplateMessageParam templateMessageParam);
  37 + @DeleteMapping("/send")
  38 + Message<Boolean> revokeMessage(@NotNull(message = "Token不能为空") Long sceneToken);
34 39 }
... ...
fw-hestia-sdk/src/main/java/cn/fw/hestia/sdk/params/TemplateMessageParam.java
... ... @@ -3,6 +3,8 @@ package cn.fw.hestia.sdk.params;
3 3 import lombok.Data;
4 4 import lombok.ToString;
5 5  
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.NotNull;
6 8 import java.util.Map;
7 9  
8 10 /**
... ... @@ -15,6 +17,12 @@ import java.util.Map;
15 17 * 变更结果:{{keyword2.DATA}}
16 18 * {{remark.DATA}}
17 19 *
  20 + * 示例:
  21 + * 尊敬的客户,您的业务状态已经发生变更 变更详情如下:
  22 + * 变更类型:组局地点
  23 + * 变更结果:由清水河改为滨江
  24 + * 如有疑问,请拨打客服电话
  25 + *
18 26 * @author kurisu
19 27 */
20 28 @Data
... ... @@ -23,10 +31,12 @@ public class TemplateMessageParam {
23 31 /**
24 32 * 会员id
25 33 */
  34 + @NotNull(message = "会员id不能为空")
26 35 private Long memberId;
27 36 /**
28   - * 标题 对应「first」字段
  37 + * 标题内容 对应「first」字段
29 38 */
  39 + @NotBlank(message = "标题内容不能为空")
30 40 private String title;
31 41 /**
32 42 * 备注
... ... @@ -35,10 +45,12 @@ public class TemplateMessageParam {
35 45 /**
36 46 * 变更类型
37 47 */
  48 + @NotBlank(message = "变更类型不能为空")
38 49 private String changeType;
39 50 /**
40 51 * 变更结果
41 52 */
  53 + @NotBlank(message = "变更结果不能为空")
42 54 private String changeResult;
43 55 /**
44 56 * 如需跳转小程序,则是小程序页面路径
... ...
fw-hestia-sdk/src/main/java/cn/fw/hestia/sdk/result/MessageSendMq.java 0 → 100644
  1 +package cn.fw.hestia.sdk.result;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +import java.util.Date;
  8 +
  9 +/**
  10 + * @author : kurisu
  11 + * @className : MessageSendMQ
  12 + * @description : 消息发送成功的通知
  13 + * @date: 2021-09-25 09:27
  14 + */
  15 +@Data
  16 +@AllArgsConstructor
  17 +@NoArgsConstructor
  18 +public class MessageSendMq {
  19 + public final static String TOPIC = "message_send";
  20 + /**
  21 + * 唯一标识
  22 + */
  23 + private Long sceneToken;
  24 + /**
  25 + * 发送时间
  26 + */
  27 + private Date sendTime;
  28 +}
... ...
fw-hestia-server/src/main/java/cn/fw/hestia/server/controller/api/MessageCenterServiceImpl.java
... ... @@ -4,13 +4,15 @@ import cn.fw.common.web.annotation.ControllerMethod;
4 4 import cn.fw.data.base.domain.common.Message;
5 5 import cn.fw.hestia.sdk.api.IMessageCenterService;
6 6 import cn.fw.hestia.sdk.params.TemplateMessageParam;
  7 +import cn.fw.hestia.service.buz.MessageCenterBizService;
7 8 import lombok.extern.slf4j.Slf4j;
8   -import org.springframework.web.bind.annotation.PostMapping;
9   -import org.springframework.web.bind.annotation.RequestBody;
10   -import org.springframework.web.bind.annotation.RequestMapping;
11   -import org.springframework.web.bind.annotation.RestController;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.web.bind.annotation.*;
12 11  
13 12 import javax.validation.Valid;
  13 +import javax.validation.constraints.NotNull;
  14 +
  15 +import static cn.fw.common.web.util.ResultBuilder.success;
14 16  
15 17 /**
16 18 * @author : kurisu
... ... @@ -22,18 +24,24 @@ import javax.validation.Valid;
22 24 @RestController
23 25 @RequestMapping("/api/hestia/mc")
24 26 public class MessageCenterServiceImpl implements IMessageCenterService {
  27 + private final MessageCenterBizService messageCenterBizService;
25 28  
26   - @PostMapping("/asynSend")
27   - @Override
28   - @ControllerMethod("保存进站记录")
29   - public Message<Long> asynSend(@Valid @RequestBody TemplateMessageParam templateMessageParam) {
30   - return null;
  29 + @Autowired
  30 + public MessageCenterServiceImpl(final MessageCenterBizService messageCenterBizService) {
  31 + this.messageCenterBizService = messageCenterBizService;
31 32 }
32 33  
33 34 @PostMapping("/send")
34 35 @Override
35   - @ControllerMethod("保存进站记录")
  36 + @ControllerMethod("发送模板消息")
36 37 public Message<Long> send(@Valid @RequestBody TemplateMessageParam templateMessageParam) {
37   - return null;
  38 + return success(messageCenterBizService.saveMessage(templateMessageParam));
  39 + }
  40 +
  41 + @Override
  42 + @DeleteMapping("/revoke")
  43 + @ControllerMethod("撤回消息")
  44 + public Message<Boolean> revokeMessage(@NotNull(message = "Token不能为空") Long sceneToken) {
  45 + return success(messageCenterBizService.revokeMessage(sceneToken));
38 46 }
39 47 }
... ...
fw-hestia-server/src/main/java/cn/fw/hestia/server/controller/wx/MessageCenterController.java 0 → 100644
  1 +package cn.fw.hestia.server.controller.wx;
  2 +
  3 +import cn.fw.common.page.AppPage;
  4 +import cn.fw.common.web.annotation.ControllerMethod;
  5 +import cn.fw.common.web.auth.PassportAuthBean;
  6 +import cn.fw.common.web.auth.annotation.CurrentUser;
  7 +import cn.fw.data.base.domain.common.Message;
  8 +import cn.fw.hestia.domain.vo.HistoryQuery;
  9 +import cn.fw.hestia.domain.vo.MessageHistoryVO;
  10 +import cn.fw.hestia.service.buz.MessageCenterBizService;
  11 +import cn.fw.security.auth.client.annotation.Authorization;
  12 +import cn.fw.security.auth.client.enums.AuthType;
  13 +import lombok.extern.slf4j.Slf4j;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.GetMapping;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RestController;
  19 +
  20 +import javax.validation.constraints.NotNull;
  21 +import java.util.Map;
  22 +
  23 +import static cn.fw.common.web.util.ResultBuilder.success;
  24 +
  25 +/**
  26 + * @author : kurisu
  27 + * @className : MessageCenterController
  28 + * @description :
  29 + * @date: 2021-09-23 15:39
  30 + */
  31 +@Slf4j
  32 +@Validated
  33 +@RestController
  34 +@Authorization(AuthType.WECHAT)
  35 +@RequestMapping("/wx/message")
  36 +public class MessageCenterController {
  37 + private final MessageCenterBizService messageCenterBizService;
  38 +
  39 + @Autowired
  40 + public MessageCenterController(final MessageCenterBizService messageCenterBizService) {
  41 + this.messageCenterBizService = messageCenterBizService;
  42 + }
  43 +
  44 + @GetMapping("/unread")
  45 + @ControllerMethod("查询消息未读数")
  46 + public Message<Integer> send(@CurrentUser PassportAuthBean user) {
  47 + return success(messageCenterBizService.unreadCount(user.getUserId()));
  48 + }
  49 +
  50 + @GetMapping("/query/pageParams")
  51 + @ControllerMethod("查询小程序页面的参数")
  52 + public Message<Map<String, String>> queryPageParams(@NotNull(message = "sceneToken不能为空") final Long sceneToken) {
  53 + return success(messageCenterBizService.queryPageParams(sceneToken));
  54 + }
  55 +
  56 + @GetMapping("/query/history")
  57 + @ControllerMethod("查询消息历史记录")
  58 + public Message<AppPage<MessageHistoryVO>> queryHistory(HistoryQuery query) {
  59 + return success(messageCenterBizService.queryHistory(query));
  60 + }
  61 +}
... ...
fw-hestia-server/src/main/java/cn/fw/hestia/server/task/SendMessageTask.java 0 → 100644
  1 +package cn.fw.hestia.server.task;
  2 +
  3 +import cn.fw.hestia.domain.db.MessageHistory;
  4 +import cn.fw.hestia.domain.enums.MessageStateEnum;
  5 +import cn.fw.hestia.service.buz.MessageCenterBizService;
  6 +import cn.fw.hestia.service.data.MessageHistoryService;
  7 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  10 +import org.springframework.scheduling.annotation.Scheduled;
  11 +import org.springframework.stereotype.Component;
  12 +import org.springframework.transaction.annotation.Transactional;
  13 +import org.springframework.util.CollectionUtils;
  14 +
  15 +import java.util.Date;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * @author : kurisu
  20 + * @className : FollowNoticeTask
  21 + * @description : 服务号消息定时任务
  22 + * @date: 2020-08-25 16:57
  23 + */
  24 +@Component
  25 +@ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
  26 +public class SendMessageTask {
  27 + private final MessageCenterBizService messageCenterBizService;
  28 + private final MessageHistoryService messageHistoryService;
  29 +
  30 + private final static int MAX_FREQUENCY = 5;
  31 +
  32 + @Autowired
  33 + public SendMessageTask(final MessageCenterBizService messageCenterBizService,
  34 + final MessageHistoryService messageHistoryService) {
  35 + this.messageCenterBizService = messageCenterBizService;
  36 + this.messageHistoryService = messageHistoryService;
  37 + }
  38 +
  39 + /**
  40 + * 发送模板消息
  41 + */
  42 + @Scheduled(initialDelay = 1000 * 10, fixedRate = 1000 * 10)
  43 + @Transactional(rollbackFor = Exception.class)
  44 + public void sendNotice() {
  45 + List<MessageHistory> list = messageHistoryService.list(Wrappers.<MessageHistory>lambdaQuery()
  46 + .eq(MessageHistory::getState, MessageStateEnum.MADA)
  47 + .eq(MessageHistory::getYn, Boolean.TRUE)
  48 + .lt(MessageHistory::getFrequency, MAX_FREQUENCY)
  49 + .lt(MessageHistory::getSendTime, new Date())
  50 + );
  51 + if (CollectionUtils.isEmpty(list)) {
  52 + return;
  53 + }
  54 + for (MessageHistory history : list) {
  55 + messageCenterBizService.sendMessage(history);
  56 + }
  57 + }
  58 +}
... ...
fw-hestia-server/src/main/resources/application.yml
... ... @@ -37,7 +37,7 @@ spring:
37 37 max-wait: 1S
38 38 min-idle: 3
39 39 port: 6379
40   - database: 3
  40 + database: 4
41 41 rest-result-processor:
42 42 enabled: false
43 43 servlet:
... ... @@ -91,7 +91,7 @@ jedis:
91 91 test-while-idle: true
92 92 host: 192.168.0.8
93 93 port: 6379
94   - db: 3
  94 + db: 4
95 95 mybatis-plus:
96 96 configuration:
97 97 cache-enabled: false
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/component/SendMsgProducer.java 0 → 100644
  1 +package cn.fw.hestia.component;
  2 +
  3 +import cn.fw.hestia.sdk.result.MessageSendMq;
  4 +import lombok.extern.slf4j.Slf4j;
  5 +import org.apache.rocketmq.spring.core.RocketMQTemplate;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.stereotype.Component;
  8 +import org.springframework.web.bind.annotation.RequestMapping;
  9 +
  10 +/**
  11 + * @author kurisu
  12 + */
  13 +@Slf4j
  14 +@Component
  15 +public class SendMsgProducer {
  16 + @Autowired
  17 + private RocketMQTemplate rocketMQTemplate;
  18 +
  19 + @RequestMapping(value = "send")
  20 + public void send(MessageSendMq messageSendMq) {
  21 + try {
  22 + log.info("模板消息发送成功mq: body:[{}]", messageSendMq);
  23 + rocketMQTemplate.syncSend(MessageSendMq.TOPIC + ":*", messageSendMq);
  24 + } catch (Exception e) {
  25 + e.printStackTrace();
  26 + }
  27 + }
  28 +}
0 29 \ No newline at end of file
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/service/buz/MessageCenterBizService.java 0 → 100644
  1 +package cn.fw.hestia.service.buz;
  2 +
  3 +import cn.fw.common.data.mybatis.pagination.PageData;
  4 +import cn.fw.common.page.AppPage;
  5 +import cn.fw.hestia.common.constant.MessageStr;
  6 +import cn.fw.hestia.common.utils.DateUtil;
  7 +import cn.fw.hestia.common.utils.StringUtils;
  8 +import cn.fw.hestia.component.SendMsgProducer;
  9 +import cn.fw.hestia.domain.db.MessageHistory;
  10 +import cn.fw.hestia.domain.db.SendLog;
  11 +import cn.fw.hestia.domain.enums.MessageStateEnum;
  12 +import cn.fw.hestia.domain.vo.HistoryQuery;
  13 +import cn.fw.hestia.domain.vo.MessageHistoryVO;
  14 +import cn.fw.hestia.rpc.passport.TemplateMessageService;
  15 +import cn.fw.hestia.rpc.passport.dto.TMParam;
  16 +import cn.fw.hestia.sdk.params.TemplateMessageParam;
  17 +import cn.fw.hestia.sdk.result.MessageSendMq;
  18 +import cn.fw.hestia.service.data.MessageHistoryService;
  19 +import cn.fw.hestia.service.data.SendLogService;
  20 +import cn.fw.passport.sdk.api.param.WxMpTempMessageData;
  21 +import com.alibaba.fastjson.JSON;
  22 +import com.alibaba.fastjson.JSONArray;
  23 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  24 +import lombok.Getter;
  25 +import lombok.RequiredArgsConstructor;
  26 +import lombok.extern.slf4j.Slf4j;
  27 +import org.springframework.stereotype.Service;
  28 +import org.springframework.transaction.annotation.Transactional;
  29 +import org.springframework.util.CollectionUtils;
  30 +
  31 +import java.util.*;
  32 +import java.util.stream.Collectors;
  33 +
  34 +import static cn.fw.common.businessvalidator.Validator.BV;
  35 +
  36 +/**
  37 + * @author : kurisu
  38 + * @className : MessageCenterBizService
  39 + * @description : 消息中心处理类
  40 + * @date: 2021-09-24 17:10
  41 + */
  42 +@Service
  43 +@RequiredArgsConstructor
  44 +@Slf4j
  45 +public class MessageCenterBizService {
  46 + private final MessageHistoryService messageHistoryService;
  47 + private final SendLogService sendLogService;
  48 + private final TemplateMessageService templateMessageService;
  49 + private final SendMsgProducer sendMsgProducer;
  50 +
  51 + /**
  52 + * 消息模板Code
  53 + */
  54 + @Getter
  55 + private final String templateCode = "OPENTM412432053";
  56 +
  57 + /**
  58 + * 发送
  59 + *
  60 + * @param templateMessageParam
  61 + * @return token
  62 + */
  63 + @Transactional(rollbackFor = Exception.class)
  64 + public Long saveMessage(TemplateMessageParam templateMessageParam) {
  65 + MessageHistory messageHistory = createBean(templateMessageParam);
  66 + messageHistoryService.save(messageHistory);
  67 + return messageHistory.getId();
  68 + }
  69 +
  70 +
  71 + /**
  72 + * 发送模板消息
  73 + *
  74 + * @param history
  75 + */
  76 + @Transactional(rollbackFor = Exception.class)
  77 + public void sendMessage(MessageHistory history) {
  78 + TMParam tmParam = createTmParam(history);
  79 + String result = templateMessageService.sendTemplateMessage(tmParam);
  80 + boolean succeed = MessageStr.SUCCEED_STR.equals(result);
  81 + final int frequency = history.getFrequency() + 1;
  82 + history.setFrequency(frequency);
  83 + if (succeed) {
  84 + history.setState(MessageStateEnum.SUMI);
  85 + //发送成功发送mq
  86 + sendMsgProducer.send(new MessageSendMq(history.getId(), new Date()));
  87 + } else {
  88 + history.setSendTime(DateUtil.getExpired(history.getSendTime(), 1 << frequency, Calendar.MINUTE));
  89 + }
  90 + messageHistoryService.updateById(history);
  91 + SendLog sendLog = new SendLog();
  92 + sendLog.setMessageId(history.getId());
  93 + sendLog.setSendTime(new Date());
  94 + sendLog.setSucceed(succeed);
  95 + sendLog.setResult(result);
  96 + sendLogService.save(sendLog);
  97 + }
  98 +
  99 + /**
  100 + * 撤回消息
  101 + *
  102 + * @param sceneToken
  103 + * @return
  104 + */
  105 + @Transactional(rollbackFor = Exception.class)
  106 + public Boolean revokeMessage(Long sceneToken) {
  107 + MessageHistory history = messageHistoryService.getById(sceneToken);
  108 + if (Objects.isNull(history)) {
  109 + return Boolean.TRUE;
  110 + }
  111 + history.setYn(Boolean.FALSE);
  112 + return messageHistoryService.updateById(history);
  113 + }
  114 +
  115 + /**
  116 + * 查询未读数
  117 + *
  118 + * @param memberId
  119 + * @return
  120 + */
  121 + public int unreadCount(Long memberId) {
  122 + return messageHistoryService.count(Wrappers.<MessageHistory>lambdaQuery()
  123 + .eq(MessageHistory::getMemberId, memberId)
  124 + .eq(MessageHistory::getReadz, Boolean.FALSE)
  125 + .eq(MessageHistory::getYn, Boolean.TRUE)
  126 + );
  127 + }
  128 +
  129 + /**
  130 + * 查询页面所需参数
  131 + *
  132 + * @param sceneToken
  133 + * @return
  134 + */
  135 + public Map<String, String> queryPageParams(Long sceneToken) {
  136 + MessageHistory history = messageHistoryService.getById(sceneToken);
  137 + BV.notNull(history, () -> "消息不存在或者已经被撤销");
  138 + readMessage(history);
  139 + String pageParams = history.getPageParams();
  140 + if (StringUtils.isEmpty(pageParams)) {
  141 + return new HashMap<>(0);
  142 + }
  143 + return JSON.<HashMap<String, String>>parseObject(pageParams, HashMap.class);
  144 + }
  145 +
  146 + /**
  147 + * 查询历史消息记录
  148 + * @param query
  149 + * @return
  150 + */
  151 + public AppPage<MessageHistoryVO> queryHistory(HistoryQuery query) {
  152 + PageData<MessageHistory> pageData = messageHistoryService.page(new PageData<>(query), Wrappers.<MessageHistory>lambdaQuery()
  153 + .eq(MessageHistory::getMemberId, query.getMemberId())
  154 + .eq(MessageHistory::getYn, Boolean.TRUE)
  155 + .orderByDesc(MessageHistory::getCreateTime)
  156 + );
  157 + AppPage<MessageHistoryVO> page = AppPage.empty(query);
  158 + page.setCurrent((int) pageData.getCurrent());
  159 + page.setPageSize((int) pageData.getSize());
  160 + page.setTotal(pageData.getTotal());
  161 + page.setData(new ArrayList<>());
  162 + if (!CollectionUtils.isEmpty(pageData.getRecords())) {
  163 + List<MessageHistoryVO> voList = pageData.getRecords().stream().map(MessageHistoryVO::with).collect(Collectors.toList());
  164 + page.setData(voList);
  165 + }
  166 + return page;
  167 + }
  168 +
  169 + @Transactional(rollbackFor = Exception.class)
  170 + protected void readMessage(MessageHistory history) {
  171 + if (Boolean.FALSE.equals(history.getReadz())) {
  172 + history.setReadz(Boolean.TRUE);
  173 + messageHistoryService.updateById(history);
  174 + }
  175 + }
  176 +
  177 + private MessageHistory createBean(TemplateMessageParam param) {
  178 + MessageHistory messageHistory = new MessageHistory();
  179 + messageHistory.setMemberId(param.getMemberId());
  180 + messageHistory.setTemplateCode(getTemplateCode());
  181 + messageHistory.setTitle(param.getTitle());
  182 + messageHistory.setRemark(param.getRemark());
  183 + messageHistory.setPagePath(param.getPath());
  184 + messageHistory.setReadz(Boolean.FALSE);
  185 + messageHistory.setFrequency(0);
  186 + messageHistory.setYn(Boolean.TRUE);
  187 + messageHistory.setSendTime(new Date());
  188 + messageHistory.setState(MessageStateEnum.MADA);
  189 + List<WxMpTempMessageData> keywords = Arrays.asList(
  190 + new WxMpTempMessageData(param.getChangeType()),
  191 + new WxMpTempMessageData(param.getChangeResult())
  192 + );
  193 + messageHistory.setKeywords(JSONArray.toJSONString(keywords));
  194 + if (!CollectionUtils.isEmpty(param.getParamMap())) {
  195 + messageHistory.setPageParams(JSON.toJSONString(param.getParamMap()));
  196 + }
  197 + return messageHistory;
  198 + }
  199 +
  200 + private TMParam createTmParam(MessageHistory history) {
  201 + TMParam tmParam = new TMParam();
  202 + tmParam.setSceneToken(history.getId());
  203 + tmParam.setTitle(history.getTitle());
  204 + tmParam.setRemark(history.getRemark());
  205 + tmParam.setPath(history.getPagePath());
  206 + tmParam.setTemplateCode(history.getTemplateCode());
  207 + tmParam.setMemberId(history.getMemberId());
  208 + tmParam.setKeywords(history.getKeywords());
  209 + return tmParam;
  210 + }
  211 +}
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/service/MessageHistoryService.java renamed to fw-hestia-service/src/main/java/cn/fw/hestia/service/data/MessageHistoryService.java
1   -package cn.fw.hestia.service;
  1 +package cn.fw.hestia.service.data;
2 2  
3 3 import cn.fw.hestia.domain.db.MessageHistory;
4 4 import com.baomidou.mybatisplus.extension.service.IService;
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/service/SendLogService.java renamed to fw-hestia-service/src/main/java/cn/fw/hestia/service/data/SendLogService.java
1   -package cn.fw.hestia.service;
  1 +package cn.fw.hestia.service.data;
2 2  
3 3 import cn.fw.hestia.domain.db.SendLog;
4 4 import com.baomidou.mybatisplus.extension.service.IService;
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/service/impl/MessageHistoryServiceImpl.java renamed to fw-hestia-service/src/main/java/cn/fw/hestia/service/data/impl/MessageHistoryServiceImpl.java
1   -package cn.fw.hestia.service.impl;
  1 +package cn.fw.hestia.service.data.impl;
2 2  
3 3 import cn.fw.hestia.dao.MessageHistoryDao;
4 4 import cn.fw.hestia.domain.db.MessageHistory;
5   -import cn.fw.hestia.service.MessageHistoryService;
  5 +import cn.fw.hestia.service.data.MessageHistoryService;
6 6 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 7 import org.springframework.stereotype.Service;
8 8  
... ...
fw-hestia-service/src/main/java/cn/fw/hestia/service/impl/SendLogServiceImpl.java renamed to fw-hestia-service/src/main/java/cn/fw/hestia/service/data/impl/SendLogServiceImpl.java
1   -package cn.fw.hestia.service.impl;
  1 +package cn.fw.hestia.service.data.impl;
2 2  
3 3 import cn.fw.hestia.dao.SendLogDao;
4 4 import cn.fw.hestia.domain.db.SendLog;
5   -import cn.fw.hestia.service.SendLogService;
  5 +import cn.fw.hestia.service.data.SendLogService;
6 6 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 7 import org.springframework.stereotype.Service;
8 8  
... ...