Переглянути джерело

更新 message-service 通知

reghao 7 місяців тому
батько
коміт
db3b988442
23 змінених файлів з 172 додано та 141 видалено
  1. 1 1
      account/account-api/src/main/java/cn/reghao/tnb/account/api/constant/VerifyChannel.java
  2. 2 1
      account/account-service/src/main/java/cn/reghao/tnb/account/app/rpc/AccountQueryImpl.java
  3. 1 1
      account/account-service/src/main/java/cn/reghao/tnb/account/app/service/CodeService.java
  4. 1 1
      account/account-service/src/main/java/cn/reghao/tnb/account/app/util/RabbitProducer.java
  5. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/constant/MsgType.java
  6. 10 11
      message/message-api/src/main/java/cn/reghao/tnb/message/api/constant/MsgType.java
  7. 14 0
      message/message-api/src/main/java/cn/reghao/tnb/message/api/constant/NotifyType.java
  8. 3 1
      message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/BaseMessage.java
  9. 7 4
      message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/LoginMessage.java
  10. 2 1
      message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/RtmpMessage.java
  11. 4 2
      message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/VerifyMessage.java
  12. 54 0
      message/message-service/src/main/java/cn/reghao/tnb/message/app/model/msg/DingMsgUtil.java
  13. 0 33
      message/message-service/src/main/java/cn/reghao/tnb/message/app/model/msg/DingRtmpMsg.java
  14. 1 1
      message/message-service/src/main/java/cn/reghao/tnb/message/app/rabbit/RabbitListeners.java
  15. 35 44
      message/message-service/src/main/java/cn/reghao/tnb/message/app/service/MessageConsumer.java
  16. 6 4
      message/message-service/src/main/java/cn/reghao/tnb/message/app/service/NotifyService.java
  17. 1 1
      message/message-service/src/main/java/cn/reghao/tnb/message/app/service/notifier/ding/DingNotify.java
  18. 0 23
      user/user-api/src/main/java/cn/reghao/tnb/user/api/dto/AdminMessage.java
  19. 2 0
      user/user-api/src/main/java/cn/reghao/tnb/user/api/dto/UserMessageDto.java
  20. 0 2
      user/user-api/src/main/java/cn/reghao/tnb/user/api/iface/UserService.java
  21. 0 6
      user/user-service/src/main/java/cn/reghao/tnb/user/app/rpc/UserServiceImpl.java
  22. 7 3
      user/user-service/src/main/java/cn/reghao/tnb/user/app/rpc/UserWalletServiceImpl.java
  23. 20 0
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserMessageService.java

+ 1 - 1
account/account-api/src/main/java/cn/reghao/tnb/account/api/constant/VerifyChannel.java

@@ -11,7 +11,7 @@ import java.util.Map;
  */
 public enum VerifyChannel {
     registryChannel(1, "注册通道"),
-    loginChannel(2, "登通道"),
+    loginChannel(2, "登通道"),
     updateChannel(3, "更新手机/邮箱通道"),
     passwordChannel(4, "修改密码通道");
 

+ 2 - 1
account/account-service/src/main/java/cn/reghao/tnb/account/app/rpc/AccountQueryImpl.java

@@ -7,6 +7,7 @@ import cn.reghao.tnb.account.app.db.repository.AccountRepository;
 import cn.reghao.tnb.account.app.model.po.UserAccount;
 import cn.reghao.tnb.account.app.security.form.AccountAuthToken;
 import cn.reghao.tnb.account.app.service.AccountTokenService;
+import cn.reghao.tnb.common.util.ConstantId;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.stereotype.Service;
@@ -98,7 +99,7 @@ public class AccountQueryImpl implements AccountQuery {
     @Override
     public long getByRole(String role) {
         List<Long> userIds = accountRepository.getRoleUsers(role);
-        return userIds.isEmpty() ? -1 : userIds.get(0);
+        return userIds.isEmpty() ? ConstantId.ANONYMOUS_USER_ID : userIds.get(0);
     }
 
     @Override

+ 1 - 1
account/account-service/src/main/java/cn/reghao/tnb/account/app/service/CodeService.java

@@ -102,7 +102,7 @@ public class CodeService {
         redisString.setWithTimeout(RedisKeys.getVerifyCodeKey(channel, receiver), code, sessionTimeout);
 
         String title = "验证码";
-        VerifyMessage verifyMessage = new VerifyMessage(receiver, type, title, code);
+        VerifyMessage verifyMessage = new VerifyMessage(title, code, receiver);
         rabbitProducer.sendVerifyMessage(verifyMessage);
         return Result.success("验证码已发送, 请及时查收");
     }

+ 1 - 1
account/account-service/src/main/java/cn/reghao/tnb/account/app/util/RabbitProducer.java

@@ -23,7 +23,7 @@ public class RabbitProducer {
     public void sendVerifyMessage(VerifyMessage verifyMessage) {
         String routingKey = "tnb.message.account";
         String jsonPayload = JsonConverter.objectToJson(verifyMessage);
-        rabbitTemplate.convertAndSend(routingKey, verifyMessage);
+        rabbitTemplate.convertAndSend(routingKey, jsonPayload);
     }
 
     public void sendLoginMessage(LoginMessage loginMessage) {

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/constant/MsgType.java

@@ -12,7 +12,7 @@ import java.util.Map;
 public enum MsgType {
     all(0, "所有消息"), text(1, "文本消息"), media(2, "音频/视频/图片/文件消息"),
     chatRecord(3, "聊天记录"), codeBlock(4, "代码块"), vote(5, "投票")
-    , login(8, "登"), location(10, "位置");
+    , login(8, "登"), location(10, "位置");
 
     private final Integer code;
     private final String desc;

+ 10 - 11
message/message-api/src/main/java/cn/reghao/tnb/message/api/constant/MsgType.java

@@ -8,13 +8,16 @@ import java.util.Map;
  * @date 2024-09-26 21:55:17
  */
 public enum MsgType {
-    contactMsg(1, "联系人消息"),
-    commentMsg(2, "评论消息"),
-    danmakuMsg(3, "弹幕消息"),
-    chargeMsg(4, "充值消息"),
-    transferMsg(5, "转帐消息"),
-    payMsg(6, "支付消息"),
-    sysMsg(7, "系统消息");
+    verifyMsg(1, "验证码消息"),
+    loginMsg(2, "登入消息"),
+    rtmpMsg(3, "RTMP 消息"),
+    contactMsg(4, "联系人消息"),
+    commentMsg(5, "评论消息"),
+    danmakuMsg(6, "弹幕消息"),
+    chargeMsg(7, "充值消息"),
+    transferMsg(8, "转帐消息"),
+    payMsg(9, "支付消息"),
+    sysMsg(10, "系统消息");
 
     private final int code;
     private final String desc;
@@ -34,10 +37,6 @@ public enum MsgType {
         return code;
     }
 
-    public Integer getCode() {
-        return code;
-    }
-
     public String getDesc() {
         return desc;
     }

+ 14 - 0
message/message-api/src/main/java/cn/reghao/tnb/message/api/constant/NotifyType.java

@@ -1,5 +1,8 @@
 package cn.reghao.tnb.message.api.constant;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * 通知类型
  *
@@ -14,6 +17,13 @@ public enum NotifyType {
         this.value = value;
     }
 
+    private static Map<Integer, NotifyType> map = new HashMap<>();
+    static {
+        for (NotifyType type : NotifyType.values()) {
+            map.put(type.getValue(), type);
+        }
+    }
+
     public String getName() {
         return this.name();
     }
@@ -21,4 +31,8 @@ public enum NotifyType {
     public Integer getValue() {
         return value;
     }
+
+    public static NotifyType getByCode(int code) {
+        return map.get(code);
+    }
 }

+ 3 - 1
message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/BaseMessage.java

@@ -16,12 +16,14 @@ public class BaseMessage implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private int notifyType;
+    private int msgType;
     //@NotBlank(message = "邮箱或手机号不能为空白字符串")
     private String receiver;
     private long timestamp;
 
-    public BaseMessage(int notifyType, String receiver) {
+    public BaseMessage(int notifyType, int msgType, String receiver) {
         this.notifyType = notifyType;
+        this.msgType = msgType;
         this.receiver = receiver;
         this.timestamp = System.currentTimeMillis();
     }

+ 7 - 4
message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/LoginMessage.java

@@ -1,5 +1,8 @@
 package cn.reghao.tnb.message.api.dto.msg;
 
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
+import cn.reghao.tnb.message.api.constant.MsgType;
+import cn.reghao.tnb.message.api.constant.NotifyType;
 import lombok.Getter;
 
 /**
@@ -13,11 +16,11 @@ public class LoginMessage extends BaseMessage {
     private String userAgent;
     private String loginAt;
 
-    public LoginMessage(int notifyType, String receiver, String publicIp, String userAgent, String loginAt) {
-        super(notifyType, receiver);
-        this.title = "登提示";
+    public LoginMessage(String publicIp, String userAgent) {
+        super(NotifyType.webhook.getValue(), MsgType.loginMsg.getValue(), "");
+        this.title = "登提示";
         this.publicIp = publicIp;
         this.userAgent = userAgent;
-        this.loginAt = loginAt;
+        this.loginAt = DateTimeConverter.format(System.currentTimeMillis());
     }
 }

+ 2 - 1
message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/RtmpMessage.java

@@ -1,5 +1,6 @@
 package cn.reghao.tnb.message.api.dto.msg;
 
+import cn.reghao.tnb.message.api.constant.MsgType;
 import cn.reghao.tnb.message.api.constant.NotifyType;
 import lombok.Getter;
 
@@ -15,7 +16,7 @@ public class RtmpMessage extends BaseMessage {
     private String clientAddress;
 
     public RtmpMessage(String callType, String appName, String clientId, String clientAddress) {
-        super(NotifyType.webhook.getValue(), "");
+        super(NotifyType.webhook.getValue(), MsgType.rtmpMsg.getValue(), "");
         this.callType = callType;
         this.appName = appName;
         this.clientId = clientId;

+ 4 - 2
message/message-api/src/main/java/cn/reghao/tnb/message/api/dto/msg/VerifyMessage.java

@@ -1,5 +1,7 @@
 package cn.reghao.tnb.message.api.dto.msg;
 
+import cn.reghao.tnb.message.api.constant.MsgType;
+import cn.reghao.tnb.message.api.constant.NotifyType;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -13,8 +15,8 @@ public class VerifyMessage extends BaseMessage {
     private String title;
     private String content;
 
-    public VerifyMessage(String receiver, int notifyType, String title, String content) {
-        super(notifyType, receiver);
+    public VerifyMessage(String receiver, String title, String content) {
+        super(NotifyType.webhook.getValue(), MsgType.verifyMsg.getValue(), receiver);
         this.title = title;
         this.content = content;
     }

+ 54 - 0
message/message-service/src/main/java/cn/reghao/tnb/message/app/model/msg/DingMsgUtil.java

@@ -0,0 +1,54 @@
+package cn.reghao.tnb.message.app.model.msg;
+
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
+import cn.reghao.tnb.message.api.dto.msg.LoginMessage;
+import cn.reghao.tnb.message.api.dto.msg.RtmpMessage;
+import cn.reghao.tnb.message.api.dto.msg.VerifyMessage;
+import cn.reghao.tnb.message.app.service.notifier.ding.DingMsg;
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2025-10-13 15:31:48
+ */
+@Getter
+public class DingMsgUtil {
+    public static DingMsg getDingMsg(RtmpMessage rtmpMessage) {
+        String title = "RTMP 通知";
+        StringBuilder sb = new StringBuilder();
+        sb.append("# RTMP 通知").append(System.lineSeparator());
+        sb.append("### RTMP 事件: ").append(rtmpMessage.getCallType()).append(System.lineSeparator());
+        sb.append("### 摄像头: ").append(rtmpMessage.getAppName()).append(System.lineSeparator());
+        sb.append("### 客户 ID: ").append(rtmpMessage.getClientId()).append(System.lineSeparator());
+        sb.append("### 客户 IP: ").append(rtmpMessage.getClientAddress()).append(System.lineSeparator());
+        sb.append("### 时间: ").append(DateTimeConverter.format(rtmpMessage.getTimestamp()));
+        String text = sb.toString();
+        return new DingMsg(title, text);
+    }
+
+    public static DingMsg getDingMsg(VerifyMessage verifyMessage) {
+        String title = "验证码通知";
+        StringBuilder sb = new StringBuilder();
+        sb.append("# 验证码通知").append(System.lineSeparator());
+        sb.append("### 用户: ").append(verifyMessage.getReceiver()).append(System.lineSeparator());
+        sb.append("### 标题: ").append(verifyMessage.getTitle()).append(System.lineSeparator());
+        sb.append("### 内容: ").append(verifyMessage.getContent()).append(System.lineSeparator());
+        sb.append("### 时间: ").append(DateTimeConverter.format(verifyMessage.getTimestamp()));
+        String text = sb.toString();
+        return new DingMsg(title, text);
+    }
+
+    public static DingMsg getDingMsg(LoginMessage loginMessage) {
+        String content = String.format("您的帐号在 %s 通过客户端 %s 登入, 登入 IP 为 %s",
+                loginMessage.getLoginAt(), loginMessage.getUserAgent(), loginMessage.getPublicIp());
+        String title = "登入通知";
+        StringBuilder sb = new StringBuilder();
+        sb.append("# 验证码通知").append(System.lineSeparator());
+        sb.append("### 用户: ").append(loginMessage.getReceiver()).append(System.lineSeparator());
+        sb.append("### 标题: ").append(loginMessage.getTitle()).append(System.lineSeparator());
+        sb.append("### 内容: ").append(content).append(System.lineSeparator());
+        sb.append("### 时间: ").append(DateTimeConverter.format(loginMessage.getTimestamp()));
+        String text = sb.toString();
+        return new DingMsg(title, text);
+    }
+}

+ 0 - 33
message/message-service/src/main/java/cn/reghao/tnb/message/app/model/msg/DingRtmpMsg.java

@@ -1,33 +0,0 @@
-package cn.reghao.tnb.message.app.model.msg;
-
-import cn.reghao.jutil.jdk.converter.DateTimeConverter;
-import cn.reghao.tnb.message.api.dto.msg.RtmpMessage;
-import cn.reghao.tnb.message.app.service.notifier.ding.DingMsg;
-import lombok.Getter;
-
-/**
- * @author reghao
- * @date 2025-10-13 15:31:48
- */
-@Getter
-public class DingRtmpMsg {
-    private final RtmpMessage rtmpMessage;
-
-    public DingRtmpMsg(RtmpMessage rtmpMessage) {
-        this.rtmpMessage = rtmpMessage;
-    }
-
-    public DingMsg dingMsg() {
-        String title = "RTMP 通知";
-
-        StringBuilder sb = new StringBuilder();
-        sb.append("# RTMP 通知").append(System.lineSeparator());
-        sb.append("### RTMP 事件: ").append(rtmpMessage.getCallType()).append(System.lineSeparator());
-        sb.append("### 摄像头: ").append(rtmpMessage.getAppName()).append(System.lineSeparator());
-        sb.append("### 客户 ID: ").append(rtmpMessage.getClientId()).append(System.lineSeparator());
-        sb.append("### 客户 IP: ").append(rtmpMessage.getClientAddress()).append(System.lineSeparator());
-        sb.append("### 时间: ").append(DateTimeConverter.format(rtmpMessage.getTimestamp()));
-        String text = sb.toString();
-        return new DingMsg(title, text);
-    }
-}

+ 1 - 1
message/message-service/src/main/java/cn/reghao/tnb/message/app/rabbit/RabbitListeners.java

@@ -76,7 +76,7 @@ public class RabbitListeners {
             ackMode = "MANUAL"
     )
     public void consumeNotifyMessage(@Payload String jsonPayload, Channel channel, Message message) {
-        messageConsumer.sendMessage(jsonPayload);
+        messageConsumer.handleMessage(jsonPayload);
         long deliveryTag = message.getMessageProperties().getDeliveryTag();
         try {
             log.info("手动确认消息 {}", deliveryTag);

+ 35 - 44
message/message-service/src/main/java/cn/reghao/tnb/message/app/service/MessageConsumer.java

@@ -1,15 +1,13 @@
 package cn.reghao.tnb.message.app.service;
 
 import cn.reghao.jutil.jdk.serializer.JsonConverter;
+import cn.reghao.tnb.message.api.constant.MsgType;
 import cn.reghao.tnb.message.api.dto.msg.RtmpMessage;
-import cn.reghao.tnb.message.app.model.msg.DingRtmpMsg;
+import cn.reghao.tnb.message.app.model.msg.DingMsgUtil;
 import cn.reghao.tnb.message.app.service.notifier.ding.DingMsg;
-import cn.reghao.tnb.user.api.dto.AdminMessage;
 import cn.reghao.tnb.message.api.constant.NotifyType;
-import cn.reghao.tnb.message.api.dto.msg.BaseMessage;
 import cn.reghao.tnb.message.api.dto.msg.LoginMessage;
 import cn.reghao.tnb.message.api.dto.msg.VerifyMessage;
-import cn.reghao.tnb.message.app.service.notifier.email.EmailMsg;
 import cn.reghao.tnb.user.api.iface.UserService;
 import com.google.gson.JsonObject;
 import lombok.extern.slf4j.Slf4j;
@@ -31,51 +29,44 @@ public class MessageConsumer {
         this.notifyService = notifyService;
     }
 
-    public void sendMessage(String jsonPayload) {
+    public void handleMessage(String jsonPayload) {
         JsonObject jsonObject = JsonConverter.jsonToJsonElement(jsonPayload).getAsJsonObject();
         int notifyType = jsonObject.get("notifyType").getAsInt();
-        if (notifyType == NotifyType.webhook.getValue()) {
-            RtmpMessage rtmpMessage = JsonConverter.jsonToObject(jsonPayload, RtmpMessage.class);
-            DingMsg dingMsg = new DingRtmpMsg(rtmpMessage).dingMsg();
-            String webhookName = "ding_bdbot";
-            notifyService.notify(webhookName, dingMsg);
+        int msgTypeCode = jsonObject.get("msgType").getAsInt();
+        MsgType msgType = MsgType.getByCode(msgTypeCode);
+        switch (NotifyType.getByCode(notifyType)) {
+            case webhook:
+                handleWebhookMessage(msgType, jsonPayload);
+                break;
+            case email:
+                break;
+            case mobile:
+                break;
         }
     }
 
-    public void sendMessage(BaseMessage baseMessage) {
-        if (baseMessage instanceof LoginMessage) {
-            LoginMessage loginMessage = (LoginMessage) baseMessage;
-            int notifyType = loginMessage.getNotifyType();
-            String receiver = loginMessage.getReceiver();
-            if (notifyType == NotifyType.email.getValue()) {
-                String subject = loginMessage.getTitle();
-                String content = String.format("您的帐号在 %s 通过客户端 %s 登录, 登录 IP 为 %s", loginMessage.getLoginAt(), loginMessage.getUserAgent(), loginMessage.getPublicIp());
-                EmailMsg emailMsg = new EmailMsg(subject, content);
-                notifyService.notify(receiver, emailMsg);
-            } else if (notifyType == NotifyType.mobile.getValue()) {
-                String errMsg = "短信消息尚未实现";
-                AdminMessage adminMessage = new AdminMessage(2, errMsg);
-                userService.sendAdminMessage(adminMessage);
-            }
-        } else if (baseMessage instanceof VerifyMessage) {
-            VerifyMessage verifyMessage = (VerifyMessage) baseMessage;
-            int notifyType = verifyMessage.getNotifyType();
-            if (notifyType == NotifyType.email.getValue()) {
-                String receiver = verifyMessage.getReceiver();
-                EmailMsg emailMsg = new EmailMsg(verifyMessage.getTitle(), verifyMessage.getContent());
-                notifyService.notify(receiver, emailMsg);
-            } else if (notifyType == NotifyType.mobile.getValue()) {
-                String errMsg = "短信验证码尚未实现";
-                AdminMessage adminMessage = new AdminMessage(2, errMsg);
-                userService.sendAdminMessage(adminMessage);
-            }
-        } else if (baseMessage instanceof RtmpMessage) {
-            RtmpMessage rtmpMessage = (RtmpMessage) baseMessage;
-            if (rtmpMessage.getNotifyType() == NotifyType.webhook.getValue()) {
-                DingMsg dingMsg = new DingRtmpMsg(rtmpMessage).dingMsg();
-                String webhookName = "ding_bdbot";
-                notifyService.notify(webhookName, dingMsg);
-            }
+    private void handleWebhookMessage(MsgType msgType, String jsonPayload) {
+        DingMsg dingMsg = null;
+        switch (msgType) {
+            case verifyMsg:
+                VerifyMessage verifyMessage = JsonConverter.jsonToObject(jsonPayload, VerifyMessage.class);
+                dingMsg = DingMsgUtil.getDingMsg(verifyMessage);
+                break;
+            case loginMsg:
+                LoginMessage loginMessage = JsonConverter.jsonToObject(jsonPayload, LoginMessage.class);
+                dingMsg = DingMsgUtil.getDingMsg(loginMessage);
+                break;
+            case rtmpMsg:
+                RtmpMessage rtmpMessage = JsonConverter.jsonToObject(jsonPayload, RtmpMessage.class);
+                dingMsg = DingMsgUtil.getDingMsg(rtmpMessage);
+                break;
+            default:
+                break;
+        }
+
+        if (dingMsg != null) {
+            String webhookName = "ding_bdbot";
+            notifyService.notify(webhookName, dingMsg);
         }
     }
 }

+ 6 - 4
message/message-service/src/main/java/cn/reghao/tnb/message/app/service/NotifyService.java

@@ -1,13 +1,14 @@
 package cn.reghao.tnb.message.app.service;
 
 import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
+import cn.reghao.tnb.common.util.ConstantId;
 import cn.reghao.tnb.message.app.model.po.Webhook;
 import cn.reghao.tnb.message.app.service.notifier.Notify;
 import cn.reghao.tnb.message.app.service.notifier.ding.DingMsg;
 import cn.reghao.tnb.message.app.service.notifier.ding.DingNotify;
 import cn.reghao.tnb.message.app.service.notifier.email.EmailMsg;
 import cn.reghao.tnb.message.app.service.notifier.email.EmailNotify;
-import cn.reghao.tnb.user.api.dto.AdminMessage;
+import cn.reghao.tnb.user.api.dto.UserMessageDto;
 import cn.reghao.tnb.user.api.iface.UserService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
@@ -69,9 +70,10 @@ public class NotifyService {
             try {
                 notify.send(receiver, msg);
             } catch (Exception e) {
-                String errMsg = String.format("发送给 %s 的通知失败 -> %s", receiver, e.getMessage());
-                AdminMessage adminMessage = new AdminMessage(2, errMsg);
-                userService.sendAdminMessage(adminMessage);
+                String title = "发送通知失败";
+                String content = String.format("发送给 %s 的通知失败 -> %s", receiver, e.getMessage());
+                UserMessageDto userMessageDto = new UserMessageDto(title, content, ConstantId.ANONYMOUS_USER_ID);
+                userService.sendUserMessage(userMessageDto);
             }
         }
     }

+ 1 - 1
message/message-service/src/main/java/cn/reghao/tnb/message/app/service/notifier/ding/DingNotify.java

@@ -39,7 +39,7 @@ public class DingNotify implements Notify<DingMsg> {
     public void send(String receiver, DingMsg msg) throws Exception {
         Webhook webhook = webhookMapper.findByName(receiver);
         if (webhook == null) {
-            log.info("没有可用于发送通知的 webhook 配置");
+            log.error("没有可用于发送通知的 webhook 配置");
             return;
         }
 

+ 0 - 23
user/user-api/src/main/java/cn/reghao/tnb/user/api/dto/AdminMessage.java

@@ -1,23 +0,0 @@
-package cn.reghao.tnb.user.api.dto;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2025-10-10 20:30:39
- */
-@AllArgsConstructor
-@NoArgsConstructor
-@Getter
-@Setter
-public class AdminMessage implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private int type;
-    private String content;
-}

+ 2 - 0
user/user-api/src/main/java/cn/reghao/tnb/user/api/dto/UserMessageDto.java

@@ -2,6 +2,7 @@ package cn.reghao.tnb.user.api.dto;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.Setter;
 
 import java.io.Serializable;
 
@@ -10,6 +11,7 @@ import java.io.Serializable;
  * @date 2024-04-18 15:23:11
  */
 @AllArgsConstructor
+@Setter
 @Getter
 public class UserMessageDto implements Serializable {
     private static final long serialVersionUID = 1L;

+ 0 - 2
user/user-api/src/main/java/cn/reghao/tnb/user/api/iface/UserService.java

@@ -1,6 +1,5 @@
 package cn.reghao.tnb.user.api.iface;
 
-import cn.reghao.tnb.user.api.dto.AdminMessage;
 import cn.reghao.tnb.user.api.dto.UserCard;
 import cn.reghao.tnb.user.api.dto.UserMessageDto;
 
@@ -18,5 +17,4 @@ public interface UserService {
     int getRecommendMode(long userId);
     boolean setRecommendMode(long userId, int mode);
     boolean contactContain(long userId, long friendId);
-    void sendAdminMessage(AdminMessage adminMessage);
 }

+ 0 - 6
user/user-service/src/main/java/cn/reghao/tnb/user/app/rpc/UserServiceImpl.java

@@ -1,7 +1,6 @@
 package cn.reghao.tnb.user.app.rpc;
 
 import cn.reghao.tnb.account.api.iface.AccountQuery;
-import cn.reghao.tnb.user.api.dto.AdminMessage;
 import cn.reghao.tnb.user.api.dto.UserCard;
 import cn.reghao.tnb.user.api.dto.UserMessageDto;
 import cn.reghao.tnb.user.api.iface.UserService;
@@ -102,9 +101,4 @@ public class UserServiceImpl implements UserService {
     public boolean contactContain(long userId, long friendId) {
         return userContactMapper.findByOwnerAndFriendId(userId, friendId) != null;
     }
-
-    @Override
-    public void sendAdminMessage(AdminMessage adminMessage) {
-
-    }
 }

+ 7 - 3
user/user-service/src/main/java/cn/reghao/tnb/user/app/rpc/UserWalletServiceImpl.java

@@ -2,7 +2,8 @@ package cn.reghao.tnb.user.app.rpc;
 
 import cn.reghao.jutil.jdk.result.Result;
 import cn.reghao.jutil.tool.id.SnowFlake;
-import cn.reghao.tnb.user.api.dto.AdminMessage;
+import cn.reghao.tnb.common.auth.UserContext;
+import cn.reghao.tnb.common.util.ConstantId;
 import cn.reghao.tnb.user.api.dto.ChargeReq;
 import cn.reghao.tnb.user.api.dto.UserMessageDto;
 import cn.reghao.tnb.user.api.dto.WalletChargeDto;
@@ -53,8 +54,11 @@ public class UserWalletServiceImpl implements UserWalletService {
         WalletCharge walletCharge = new WalletCharge(chargeId, chargeReq);
         walletChargeMapper.save(walletCharge);
 
-        AdminMessage adminMessage = new AdminMessage(1, "新充值请求");
-        userService.sendAdminMessage(adminMessage);
+        long loginUser = UserContext.getUserId();
+        String title = "充值消息";
+        String content = String.format("来自 %s 的充值请求", loginUser);
+        UserMessageDto userMessageDto = new UserMessageDto(title, content, ConstantId.ANONYMOUS_USER_ID);
+        userService.sendUserMessage(userMessageDto);
     }
 
     @Override

+ 20 - 0
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserMessageService.java

@@ -1,9 +1,14 @@
 package cn.reghao.tnb.user.app.service;
 
 import cn.reghao.jutil.tool.id.SnowFlake;
+import cn.reghao.tnb.account.api.iface.AccountQuery;
+import cn.reghao.tnb.common.auth.AccountRole;
+import cn.reghao.tnb.common.util.ConstantId;
 import cn.reghao.tnb.user.api.dto.UserMessageDto;
 import cn.reghao.tnb.user.app.db.mapper.UserMessageMapper;
 import cn.reghao.tnb.user.app.model.po.UserMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -12,8 +17,12 @@ import java.util.List;
  * @author reghao
  * @date 2024-04-18 15:07:14
  */
+@Slf4j
 @Service
 public class UserMessageService {
+    @DubboReference(check = false, retries = 0, timeout = 60_000)
+    private AccountQuery accountQuery;
+
     private final UserMessageMapper userMessageMapper;
     private final SnowFlake idGenerator;
 
@@ -23,6 +32,17 @@ public class UserMessageService {
     }
 
     public void addMessage(UserMessageDto userMessageDto) {
+        long receiverId = userMessageDto.getReceiver();
+        if (receiverId == ConstantId.ANONYMOUS_USER_ID) {
+            long adminUserId = accountQuery.getByRole(AccountRole.admin.getValue());
+            if (adminUserId == ConstantId.ANONYMOUS_USER_ID) {
+                log.error("system not init yet");
+                return;
+            }
+
+            userMessageDto.setReceiver(adminUserId);
+        }
+
         long messageId = idGenerator.nextId();
         UserMessage userMessage = new UserMessage(messageId, userMessageDto);
         userMessageMapper.save(userMessage);