diff --git a/sql/saber.sql b/sql/saber.sql
index 42287512652ae25ae8fefc3579f3a98b580d6ff4..777ff3f4607ac0b2e821dd3e2565999b970d9e44 100644
--- a/sql/saber.sql
+++ b/sql/saber.sql
@@ -11,7 +11,7 @@
  Target Server Version : 80100
  File Encoding         : 65001
 
- Date: 17/11/2023 02:05:10
+ Date: 21/11/2023 11:31:16
 */
 
 SET NAMES utf8mb4;
@@ -213,7 +213,11 @@ CREATE TABLE `notification` (
   `id` int unsigned NOT NULL AUTO_INCREMENT,
   `title` varchar(255) DEFAULT NULL,
   `content` text,
-  `rule_id` int unsigned NOT NULL,
+  `uid` int unsigned DEFAULT NULL COMMENT '用户ID',
+  `user_id` varchar(255) DEFAULT NULL COMMENT '飞书用户ID',
+  `email` varchar(255) DEFAULT NULL COMMENT '邮箱',
+  `mobile` varchar(255) DEFAULT NULL COMMENT '电话',
+  `chat_id` varchar(255) DEFAULT NULL COMMENT '飞书群组ID',
   `create_by` varchar(255) DEFAULT NULL,
   `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
   `is_deleted` tinyint unsigned DEFAULT '0',
@@ -336,28 +340,6 @@ BEGIN;
 INSERT INTO `notification_sms_attrs` (`rule_id`, `template_id`, `sign_name`, `create_by`, `create_time`, `update_by`, `update_time`, `is_deleted`) VALUES (35, 'SMS_463631137', 'yuleng的天地', 'yuleng.mei', '2023-10-27 09:20:48', 'yuleng.mei', '2023-10-27 09:20:50', 0);
 COMMIT;
 
--- ----------------------------
--- Table structure for notification_user_merge
--- ----------------------------
-DROP TABLE IF EXISTS `notification_user_merge`;
-CREATE TABLE `notification_user_merge` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT,
-  `uid` int unsigned DEFAULT NULL,
-  `notification_id` int unsigned DEFAULT NULL,
-  `is_deleted` tinyint unsigned DEFAULT '0',
-  PRIMARY KEY (`id`),
-  KEY `uid` (`uid`),
-  KEY `notification_id` (`notification_id`),
-  CONSTRAINT `notification_user_merge_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user_info` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
-  CONSTRAINT `notification_user_merge_ibfk_2` FOREIGN KEY (`notification_id`) REFERENCES `notification` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-
--- ----------------------------
--- Records of notification_user_merge
--- ----------------------------
-BEGIN;
-COMMIT;
-
 -- ----------------------------
 -- Table structure for template
 -- ----------------------------
diff --git a/src/main/java/com/steadon/saber/biz/impl/NotificationBiz.java b/src/main/java/com/steadon/saber/biz/impl/NotificationBiz.java
index fa63c6d3fde92d4cf98f802633ce5b62a96add2f..f4ca6f719b13870d499a6aeee3689c922871050b 100644
--- a/src/main/java/com/steadon/saber/biz/impl/NotificationBiz.java
+++ b/src/main/java/com/steadon/saber/biz/impl/NotificationBiz.java
@@ -68,6 +68,9 @@ public class NotificationBiz implements INotificationBiz {
         // 整合短信参数
         messageInfo.setMobileList(request.getMobileList());
 
+        // 整合邮件参数
+        messageInfo.setEmailList(request.getEmailList());
+
         // 使用工厂创建策略实例
         MessageStrategy strategy = messageStrategyFactory.createStrategy(notificationRule);
 
diff --git a/src/main/java/com/steadon/saber/handler/chain/impl/EmailMessageChainServiceImpl.java b/src/main/java/com/steadon/saber/handler/chain/impl/EmailMessageChainServiceImpl.java
index dcb8bf22c26d651ddbdb30a6caa048d7d97dff70..5f0547dabdd34d18665a9427eef15ca352c7a047 100644
--- a/src/main/java/com/steadon/saber/handler/chain/impl/EmailMessageChainServiceImpl.java
+++ b/src/main/java/com/steadon/saber/handler/chain/impl/EmailMessageChainServiceImpl.java
@@ -38,9 +38,14 @@ public class EmailMessageChainServiceImpl implements MessageChainService {
             String content = messageInfo.getContent();
 
             // 提取用户邮箱集合
-            List<String> emailAddrList = messageInfo.getUserInfoList().stream()
-                    .map(UserInfo::getEmail)
-                    .distinct().toList();
+            List<String> emailAddrList;
+            if (messageInfo.getEmailList() != null && !messageInfo.getEmailList().isEmpty()){
+                emailAddrList = messageInfo.getEmailList();
+            } else {
+                emailAddrList = messageInfo.getUserInfoList().stream()
+                        .map(UserInfo::getEmail)
+                        .distinct().toList();
+            }
 
             // 使用Stream API生成邮件
             List<EmailNotification> emails = emailAddrList.stream()
diff --git a/src/main/java/com/steadon/saber/handler/chain/model/MessageInfo.java b/src/main/java/com/steadon/saber/handler/chain/model/MessageInfo.java
index a94af80735f4b4d8502499fe3b5976cff3a3ce73..b7b2d12ab07578e718cf31f002e1848ba0abf0e2 100644
--- a/src/main/java/com/steadon/saber/handler/chain/model/MessageInfo.java
+++ b/src/main/java/com/steadon/saber/handler/chain/model/MessageInfo.java
@@ -26,4 +26,7 @@ public class MessageInfo {
 
     // 短信参数
     private List<String> mobileList; //用户手机号
+
+    // 邮件参数
+    private List<String> emailList; // 用户邮箱
 }
\ No newline at end of file
diff --git a/src/main/java/com/steadon/saber/mapper/NotificationMapper.java b/src/main/java/com/steadon/saber/mapper/NotificationMapper.java
index 1e9a0e4080e93c681720638fc4dee8e53a0b984f..4c440031f1fc06bda974374cd9d9f773d92a65b3 100644
--- a/src/main/java/com/steadon/saber/mapper/NotificationMapper.java
+++ b/src/main/java/com/steadon/saber/mapper/NotificationMapper.java
@@ -1,18 +1,22 @@
 package com.steadon.saber.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.steadon.saber.pojo.domain.Notification;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
  * Mapper 接口
  * </p>
  *
- * @author steadon
- * @since 2023-09-19
+ * @author DoudiNCer
+ * @since 2023-11-21
  */
 @Mapper
 public interface NotificationMapper extends BaseMapper<Notification> {
+    int insertBatch(@Param("list") List<Notification> list);
 
 }
diff --git a/src/main/java/com/steadon/saber/mapper/NotificationUserMergeMapper.java b/src/main/java/com/steadon/saber/mapper/NotificationUserMergeMapper.java
deleted file mode 100644
index 278396bbdcca4743239f82f75a1dcc3625e2f4c9..0000000000000000000000000000000000000000
--- a/src/main/java/com/steadon/saber/mapper/NotificationUserMergeMapper.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.steadon.saber.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.steadon.saber.pojo.domain.NotificationUserMerge;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-/**
- * <p>
- * Mapper 接口
- * </p>
- *
- * @author steadon
- * @since 2023-09-19
- */
-@Mapper
-public interface NotificationUserMergeMapper extends BaseMapper<NotificationUserMerge> {
-    int insertBatch(@Param("list") List<NotificationUserMerge> list);
-}
\ No newline at end of file
diff --git a/src/main/java/com/steadon/saber/pojo/domain/Notification.java b/src/main/java/com/steadon/saber/pojo/domain/Notification.java
index e6ba71dd0bbd1731226320b6dcc6fcbbf15f134d..c2ae9f0a3e5bf6325ebcc2102a04b6e683f58c35 100644
--- a/src/main/java/com/steadon/saber/pojo/domain/Notification.java
+++ b/src/main/java/com/steadon/saber/pojo/domain/Notification.java
@@ -10,8 +10,8 @@ import java.io.Serializable;
  *
  * </p>
  *
- * @author steadon
- * @since 2023-11-10
+ * @author DoudiNCer
+ * @since 2023-11-21
  */
 @Data
 @TableName("notification")
@@ -26,8 +26,35 @@ public class Notification implements Serializable {
     @TableField("content")
     private String content;
 
-    @TableField("rule_id")
-    private Integer ruleId;
+    /**
+     * 用户ID
+     */
+    @TableField("uid")
+    private Integer uid;
+
+    /**
+     * 飞书用户ID
+     */
+    @TableField("user_id")
+    private String userId;
+
+    /**
+     * 邮箱
+     */
+    @TableField("email")
+    private String email;
+
+    /**
+     * 电话
+     */
+    @TableField("mobile")
+    private String mobile;
+
+    /**
+     * 飞书群组ID
+     */
+    @TableField("chat_id")
+    private String chatId;
 
     @TableField("create_by")
     private String createBy;
diff --git a/src/main/java/com/steadon/saber/pojo/domain/NotificationUserMerge.java b/src/main/java/com/steadon/saber/pojo/domain/NotificationUserMerge.java
deleted file mode 100644
index 325ee98ffaf2ac36c4b9ba7830046e50bf971c37..0000000000000000000000000000000000000000
--- a/src/main/java/com/steadon/saber/pojo/domain/NotificationUserMerge.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.steadon.saber.pojo.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * <p>
- *
- * </p>
- *
- * @author steadon
- * @since 2023-09-19
- */
-@Data
-@TableName("notification_user_merge")
-public class NotificationUserMerge implements Serializable {
-
-    @TableId(value = "id", type = IdType.AUTO)
-    private Integer id;
-
-    @TableField("uid")
-    private Integer uid;
-
-    @TableField("notification_id")
-    private Integer notificationId;
-
-    @TableField("is_deleted")
-    @TableLogic
-    private Byte isDeleted;
-}
diff --git a/src/main/java/com/steadon/saber/pojo/model/request/NotificationRequest.java b/src/main/java/com/steadon/saber/pojo/model/request/NotificationRequest.java
index f614334a80e62918c6b915297ec2231afb699476..7bd14eb525be3fce613d9294b230808ac3b7c653 100644
--- a/src/main/java/com/steadon/saber/pojo/model/request/NotificationRequest.java
+++ b/src/main/java/com/steadon/saber/pojo/model/request/NotificationRequest.java
@@ -20,5 +20,7 @@ public class NotificationRequest {
 
     private List<String> mobileList; //用户手机号
 
+    private List<String> emailList; // 用户邮箱
+
     private Map<String, Object> attrsMap; // 动态参数
 }
\ No newline at end of file
diff --git a/src/main/java/com/steadon/saber/service/impl/NotificationServiceImpl.java b/src/main/java/com/steadon/saber/service/impl/NotificationServiceImpl.java
index feea03aeea4fbcf38d506f0043b07612ae44bf59..c6898391212a70d4188b2fe07582fb53b18f5a39 100644
--- a/src/main/java/com/steadon/saber/service/impl/NotificationServiceImpl.java
+++ b/src/main/java/com/steadon/saber/service/impl/NotificationServiceImpl.java
@@ -9,10 +9,10 @@ import com.steadon.saber.handler.chain.model.MessageInfo;
 import com.steadon.saber.handler.token.TokenHandler;
 import com.steadon.saber.mapper.NotificationMapper;
 import com.steadon.saber.mapper.NotificationRuleMapper;
-import com.steadon.saber.mapper.NotificationUserMergeMapper;
+import com.steadon.saber.mapper.UserInfoMapper;
 import com.steadon.saber.pojo.domain.Notification;
 import com.steadon.saber.pojo.domain.NotificationRule;
-import com.steadon.saber.pojo.domain.NotificationUserMerge;
+import com.steadon.saber.pojo.domain.UserInfo;
 import com.steadon.saber.pojo.domain.vo.NotificationRuleVo;
 import com.steadon.saber.pojo.model.pageData.PageData;
 import com.steadon.saber.pojo.model.resultEnum.ResultCode;
@@ -23,6 +23,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import static com.steadon.saber.common.RedisCommon.RULE_CACHE_PREFIX;
@@ -35,32 +36,71 @@ public class NotificationServiceImpl implements NotificationService {
 
     private NotificationRuleMapper notificationRuleMapper;
 
-    private NotificationUserMergeMapper notificationUserMergeMapper;
+    private UserInfoMapper userInfoMapper;
 
     private RedisUtils redisUtils;
 
     @Override
     @Transactional(isolation = Isolation.READ_COMMITTED)
     public void addNotification(MessageInfo messageInfo) {
-        Notification notification = new Notification();
-        notification.setTitle(messageInfo.getTitle());
-        notification.setContent(messageInfo.getContent());
-        notification.setRuleId(messageInfo.getRuleId());
-        notification.setCreateBy(TokenHandler.getUsername());
-        if (notificationMapper.insert(notification) == 0) {
-            throw new SaberDBException();
+        // TODO 自定义手机号、邮箱发送的消息查询其对应 uid
+
+        List<Notification> notificationList;
+        if (messageInfo.getChatId() != null && messageInfo.getChatId().length() != 0){
+            // 指定飞书群组发送通知
+            Notification notification = new Notification();
+            notification.setTitle(messageInfo.getTitle());
+            notification.setContent(messageInfo.getContent());
+            notification.setCreateBy(TokenHandler.getUsername());
+            notification.setChatId(messageInfo.getChatId());
+            notificationList = new ArrayList<>(1);
+            notificationList.add(notification);
+        } else if (messageInfo.getMobileList() != null && !messageInfo.getMobileList().isEmpty()){
+            // 指定手机号发送通知
+            notificationList = messageInfo.getMobileList().stream().map(info -> {
+                Notification notification = new Notification();
+                notification.setTitle(messageInfo.getTitle());
+                notification.setContent(messageInfo.getContent());
+                notification.setMobile(info);
+                notification.setCreateBy(TokenHandler.getUsername());
+                return notification;
+            }).toList();
+        } else if (messageInfo.getEmailList() != null && !messageInfo.getEmailList().isEmpty()){
+            // 指定邮箱发送通知
+            notificationList = messageInfo.getEmailList().stream().map(info -> {
+                Notification notification = new Notification();
+                notification.setTitle(messageInfo.getTitle());
+                notification.setContent(messageInfo.getContent());
+                notification.setEmail(info);
+                notification.setCreateBy(TokenHandler.getUsername());
+                return notification;
+            }).toList();
+        } else if (messageInfo.getUserId() != null && messageInfo.getUserId().length() != 0){
+            // 指定飞书UID发送通知
+            Notification notification = new Notification();
+            List<UserInfo> userInfos = userInfoMapper.selectList(new QueryWrapper<UserInfo>().eq("user_id", messageInfo.getUserId()));
+            if (userInfos != null && userInfos.size() == 1){
+                notification.setUid(userInfos.get(0).getId());
+            }
+            notification.setTitle(messageInfo.getTitle());
+            notification.setContent(messageInfo.getContent());
+            notification.setUserId(messageInfo.getUserId());
+            notification.setCreateBy(TokenHandler.getUsername());
+            notificationList = new ArrayList<>(1);
+            notificationList.add(notification);
+        } else {
+            // 根据预定义规则发送通知
+            notificationList = messageInfo.getUserInfoList().stream().map(info -> {
+                Notification notification = new Notification();
+                notification.setTitle(messageInfo.getTitle());
+                notification.setContent(messageInfo.getContent());
+                notification.setUid(info.getId());
+                notification.setCreateBy(TokenHandler.getUsername());
+                return notification;
+            }).toList();
         }
-        // 存入消息与接收者记录
-        Integer notificationId = notification.getId();
-        List<NotificationUserMerge> mergeList = messageInfo.getUserInfoList().stream().map(info -> {
-            NotificationUserMerge notificationUserMerge = new NotificationUserMerge();
-            notificationUserMerge.setUid(info.getId());
-            notificationUserMerge.setNotificationId(notificationId);
-            return notificationUserMerge;
-        }).toList();
-        // 批量插入通知记录
-        if (!mergeList.isEmpty()) {
-            if (notificationUserMergeMapper.insertBatch(mergeList) == 0) {
+        if (!notificationList.isEmpty()){
+            if (notificationMapper.insertBatch(notificationList) != notificationList.size()){
                 throw new SaberDBException();
             }
         }
diff --git a/src/main/resources/mapper/NotificationMapper.xml b/src/main/resources/mapper/NotificationMapper.xml
index 2695ddb7e600ed23e6c157efff02730716744a78..bf8526293f2efa746dcebbd220dfb42ae4cd702f 100644
--- a/src/main/resources/mapper/NotificationMapper.xml
+++ b/src/main/resources/mapper/NotificationMapper.xml
@@ -2,4 +2,12 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.steadon.saber.mapper.NotificationMapper">
 
+    <insert id="insertBatch">
+        INSERT INTO notification(title, content, uid, user_id, email, mobile, chat_id, create_by)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.title}, #{item.content}, #{item.uid}, #{item.userId}, #{item.email}, #{item.mobile}, #{item.chatId}, #{item.createBy})
+        </foreach>
+    </insert>
+
 </mapper>
diff --git a/src/main/resources/mapper/NotificationUserMergeMapper.xml b/src/main/resources/mapper/NotificationUserMergeMapper.xml
deleted file mode 100644
index b2c53c5c18d852301cd25096995ca891a67aa892..0000000000000000000000000000000000000000
--- a/src/main/resources/mapper/NotificationUserMergeMapper.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?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.steadon.saber.mapper.NotificationUserMergeMapper">
-    <insert id="insertBatch">
-        insert into notification_user_merge(uid, notification_id)
-        values
-        <foreach collection="list" item="item" separator=",">
-            (#{item.uid},#{item.notificationId})
-        </foreach>
-    </insert>
-</mapper>