Browse Source

add notice module

Mr.qian 2 weeks ago
parent
commit
4cb43c03bb
19 changed files with 743 additions and 27 deletions
  1. 32 13
      mall-service/src/main/java/com/txz/mall/configurer/MybatisConfigurer.java
  2. 0 3
      mall-service/src/main/java/com/txz/mall/controller/BannerController.java
  3. 115 0
      mall-service/src/main/java/com/txz/mall/controller/NoticeController.java
  4. 4 3
      mall-service/src/main/java/com/txz/mall/controller/OrderController.java
  5. 109 1
      mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppNoticeController.java
  6. 0 7
      mall-service/src/main/java/com/txz/mall/core/UserUtil.java
  7. 13 0
      mall-service/src/main/java/com/txz/mall/dao/NoticeMapper.java
  8. 13 0
      mall-service/src/main/java/com/txz/mall/dao/OtherNoticeMapper.java
  9. 102 0
      mall-service/src/main/java/com/txz/mall/enums/NoticeEnum.java
  10. 45 0
      mall-service/src/main/java/com/txz/mall/enums/NoticeGroupEnum.java
  11. 70 0
      mall-service/src/main/java/com/txz/mall/model/Notice.java
  12. 52 0
      mall-service/src/main/java/com/txz/mall/model/OtherNotice.java
  13. 22 0
      mall-service/src/main/java/com/txz/mall/service/NoticeService.java
  14. 12 0
      mall-service/src/main/java/com/txz/mall/service/OtherNoticeService.java
  15. 40 0
      mall-service/src/main/java/com/txz/mall/service/impl/NoticeServiceImpl.java
  16. 19 0
      mall-service/src/main/java/com/txz/mall/service/impl/OtherNoticeServiceImpl.java
  17. 32 0
      mall-service/src/main/java/com/txz/mall/web/ro/OtherNoticeRO.java
  18. 34 0
      mall-service/src/main/java/com/txz/mall/web/ro/SendNoticeRO.java
  19. 29 0
      mall-service/src/main/java/dto/NoticeDTO.java

+ 32 - 13
mall-service/src/main/java/com/txz/mall/configurer/MybatisConfigurer.java

@@ -1,8 +1,8 @@
 package com.txz.mall.configurer;
 
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import com.txz.mall.core.ProjectConstant;
 import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -17,33 +17,52 @@ import java.util.Properties;
  */
 @Configuration
 public class MybatisConfigurer {
-
+    
     @Bean
     public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
-        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
+        // 使用MyBatis-Plus的SqlSessionFactoryBean以支持两个框架
+        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
         factory.setDataSource(dataSource);
         factory.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE);
-
-        //添加XML目录
+        
+        // 添加XML目录
         ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
         factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
         return factory.getObject();
     }
-
-    @Bean
-    public MapperScannerConfigurer mapperScannerConfigurer() {
+    
+    @Bean("tkMapperScannerConfigurer")
+    public MapperScannerConfigurer tkMapperScannerConfigurer() {
         MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
         mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
         mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE);
-
-        //配置通用Mapper,详情请查阅官方文档
+        
+        // 配置通用Mapper,详情请查阅官方文档
         Properties properties = new Properties();
         properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE);
-        properties.setProperty("notEmpty", "false");//insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
+        properties.setProperty("notEmpty", "false");// insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
         properties.setProperty("IDENTITY", "MYSQL");
         mapperScannerConfigurer.setProperties(properties);
-
+        
         return mapperScannerConfigurer;
     }
-
+    
+    /**
+     * MyBatis-Plus Mapper扫描配置
+     */
+    @Bean("mybatisPlusMapperScannerConfigurer")
+    public MapperScannerConfigurer mybatisPlusMapperScannerConfigurer() {
+        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
+        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
+        // 只扫描特定包下的MyBatis-Plus Mapper
+        mapperScannerConfigurer.setBasePackage("com.txz.mall.dao");
+        
+        Properties properties = new Properties();
+        properties.setProperty("notEmpty", "false");
+        properties.setProperty("IDENTITY", "MYSQL");
+        mapperScannerConfigurer.setProperties(properties);
+        
+        return mapperScannerConfigurer;
+    }
+    
 }

+ 0 - 3
mall-service/src/main/java/com/txz/mall/controller/BannerController.java

@@ -1,13 +1,10 @@
 package com.txz.mall.controller;
 
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.extension.api.R;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.txz.mall.core.RedisUtil;
 import com.txz.mall.core.Result;
 import com.txz.mall.core.ResultCode;
-import com.txz.mall.core.UserUtil;
 import com.txz.mall.model.Banner;
 import com.txz.mall.service.BannerService;
 import com.txz.mall.web.param.BannerParam;

+ 115 - 0
mall-service/src/main/java/com/txz/mall/controller/NoticeController.java

@@ -0,0 +1,115 @@
+package com.txz.mall.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.txz.mall.core.Result;
+import com.txz.mall.model.OtherNotice;
+import com.txz.mall.service.NoticeService;
+import com.txz.mall.service.OtherNoticeService;
+import com.txz.mall.web.param.BasePageParam;
+import com.txz.mall.web.ro.OtherNoticeRO;
+import com.txz.mall.web.ro.SendNoticeRO;
+import dto.NoticeDTO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * [后台]通知模板
+ *
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("notice")
+public class NoticeController {
+    
+    private final OtherNoticeService otherNoticeService;
+    
+    private final NoticeService noticeService;
+    
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    public Result<Page<OtherNotice>> page(BasePageParam page, String queryStr) {
+        Page queryPage = new Page(page.getPage(), page.getSize());
+        return Result.success(
+                otherNoticeService.page(queryPage, Wrappers.<OtherNotice>lambdaQuery()
+                        .and(StrUtil.isNotBlank(queryStr),
+                                item -> item
+                                        .like(OtherNotice::getTitle, queryStr)
+                                        .or()
+                                        .like(OtherNotice::getMessage, queryStr)
+                        )
+                )
+        );
+    }
+    
+    /**
+     * 新增
+     */
+    @PostMapping("save")
+    public Result save(@Validated({OtherNoticeRO.Add.class}) @RequestBody OtherNoticeRO ro) {
+        OtherNotice otherNotice = BeanUtil.copyProperties(ro, OtherNotice.class);
+        otherNoticeService.save(otherNotice);
+        return Result.success();
+    }
+    
+    /**
+     * 详情
+     */
+    @GetMapping("info/{id:^\\d+$}")
+    public Result info(@PathVariable("id") Long id) {
+        OtherNotice info = otherNoticeService.getById(id);
+        if (ObjectUtil.isEmpty(info)) {
+            return Result.fail("数据不存在");
+        }
+        return Result.success(info);
+    }
+    
+    /**
+     * 删除
+     */
+    @DeleteMapping("delete/{id:^\\d+$}")
+    public Result delete(@PathVariable("id") Long id) {
+        otherNoticeService.update(Wrappers.<OtherNotice>lambdaUpdate().eq(OtherNotice::getId, id).set(OtherNotice::getIsDelete, 1));
+        return Result.success();
+    }
+    
+    /**
+     * 更新
+     */
+    @PatchMapping("update/{id:^\\d+$}")
+    public Result update(@Validated({OtherNoticeRO.Update.class}) @RequestBody OtherNoticeRO ro, @PathVariable("id") Long id) {
+        OtherNotice info = otherNoticeService.getById(id);
+        if (ObjectUtil.isEmpty(info)) {
+            return Result.fail("数据不存在");
+        }
+        if (info.getIsDelete() == 1) {
+            return Result.fail("数据已删除");
+        }
+        BeanUtil.copyProperties(ro, info);
+        otherNoticeService.updateById(info);
+        return Result.success();
+    }
+    
+    /**
+     * 发送消息
+     */
+    @PostMapping("sendNotice")
+    public Result otherNoticeId(@Validated({SendNoticeRO.Send.class}) @RequestBody SendNoticeRO ro) {
+        OtherNotice info = otherNoticeService.getById(ro.getId());
+        if (ObjectUtil.isEmpty(info)) {
+            return Result.fail("数据不存在");
+        }
+        NoticeDTO dto = BeanUtil.copyProperties(info, NoticeDTO.class);
+        noticeService.addNotice(dto, ro.getUids().stream().toArray(Long[]::new));
+        return Result.success();
+    }
+    
+}

+ 4 - 3
mall-service/src/main/java/com/txz/mall/controller/OrderController.java

@@ -1,7 +1,6 @@
 package com.txz.mall.controller;
 
 import com.alibaba.fastjson.annotation.JSONField;
-import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.txz.mall.business.OrderServiceBusiness;
 import com.txz.mall.core.AuthService;
@@ -10,7 +9,9 @@ import com.txz.mall.core.ResultCode;
 import com.txz.mall.enums.PinkOrderStatusEnum;
 import com.txz.mall.model.StoreOrder;
 import com.txz.mall.service.StoreOrderService;
-import dto.*;
+import dto.CreateOrderRequest;
+import dto.StoreOrderDTO;
+import dto.StoreOrderDeliveryDTO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
@@ -106,7 +107,7 @@ public class OrderController {
     
     @PostMapping("/list")
     @ApiOperation(value = "订单获取列表")
-    public Result<List<StoreOrderVO>> list(@RequestBody StoreOrderDTO dto) {
+    public Result<PageInfo<StoreOrderVO>> list(@RequestBody StoreOrderDTO dto) {
         try {
             return Result.success(storeOrderService.orderList(dto));
         } catch (Exception e) {

+ 109 - 1
mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppNoticeController.java

@@ -1,9 +1,117 @@
 package com.txz.mall.controller.appcontroller;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.txz.mall.core.AuthService;
+import com.txz.mall.core.Result;
+import com.txz.mall.enums.NoticeGroupEnum;
+import com.txz.mall.model.Notice;
+import com.txz.mall.service.NoticeService;
+import com.txz.mall.web.param.BasePageParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
 /**
+ * app端通知
+ *
  * @author: MTD®️
  * @date: 2025/8/26
  */
-
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("app/notice")
 public class AppNoticeController {
+    
+    private final NoticeService noticeService;
+    
+    /**
+     * 获取未读条数
+     */
+    @GetMapping("unread")
+    public Result unread() {
+        return Result.success(noticeService.count(Wrappers.<Notice>lambdaQuery()
+                        .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                        .eq(Notice::getUserDel, Boolean.FALSE)
+                        .eq(Notice::getReadFlag, Boolean.FALSE)
+                )
+        );
+    }
+    
+    /**
+     * 获取消息分页
+     */
+    @GetMapping("page")
+    public Result page(NoticeGroupEnum type, BasePageParam page) {
+        Page queryPage = new Page(page.getPage(), page.getSize());
+        return Result.success(
+                noticeService.page(queryPage, Wrappers.<Notice>lambdaQuery()
+                        .likeRight(ObjectUtil.isNotEmpty(type), Notice::getNoticeType, type.getData())
+                        .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                        .eq(Notice::getUserDel, Boolean.FALSE)
+                )
+        );
+    }
+    
+    /**
+     * 已读
+     */
+    @PatchMapping("read/{id:^\\d+$}")
+    public Result read(@PathVariable("id") Long id) {
+        Notice readInfo = noticeService.getOne(Wrappers.<Notice>lambdaQuery()
+                .eq(Notice::getId, id)
+                .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                .eq(Notice::getUserDel, Boolean.FALSE)
+                .eq(Notice::getReadFlag, Boolean.FALSE)
+        );
+        if (ObjectUtil.isNotEmpty(readInfo)) {
+            readInfo.setReadFlag(Boolean.TRUE);
+            noticeService.updateById(readInfo);
+        }
+        return Result.success();
+    }
+    
+    /**
+     * 一键已读
+     */
+    @PatchMapping("readAll")
+    public Result readAll(NoticeGroupEnum type) {
+        noticeService.update(Wrappers.<Notice>lambdaUpdate()
+                .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                .eq(Notice::getUserDel, Boolean.FALSE)
+                .eq(Notice::getReadFlag, Boolean.FALSE)
+                .set(Notice::getReadFlag, Boolean.TRUE)
+                .likeRight(ObjectUtil.isNotEmpty(type), Notice::getNoticeType, type.getData())
+        );
+        return Result.success();
+    }
+    
+    /**
+     * 删除消息
+     */
+    @DeleteMapping("delete/{id:^\\d+$}")
+    public Result delete(@PathVariable("id") Long id) {
+        noticeService.update(Wrappers.<Notice>lambdaUpdate()
+                .eq(Notice::getId, id)
+                .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                .set(Notice::getUserDel, Boolean.TRUE)
+                .set(Notice::getReadFlag, Boolean.TRUE)
+        );
+        return Result.success();
+    }
+    
+    /**
+     * 一键删除消息
+     */
+    @DeleteMapping("delete")
+    public Result delete(NoticeGroupEnum type) {
+        noticeService.update(Wrappers.<Notice>lambdaUpdate()
+                .likeRight(ObjectUtil.isNotEmpty(type), Notice::getNoticeType, type.getData())
+                .eq(Notice::getUid, AuthService.getTokenUserId(null))
+                .set(Notice::getUserDel, Boolean.TRUE)
+                .set(Notice::getReadFlag, Boolean.TRUE)
+        );
+        return Result.success();
+    }
+    
 }

+ 0 - 7
mall-service/src/main/java/com/txz/mall/core/UserUtil.java

@@ -1,12 +1,6 @@
 package com.txz.mall.core;
 
-import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.extension.api.R;
-import com.txz.mall.core.cache.CacheKey;
-import com.txz.mall.core.cache.CacheType;
-import com.txz.mall.util.EasyToUseUtil;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.context.request.RequestContextHolder;
@@ -15,7 +9,6 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import java.util.Set;
 
 /**
  * @Date: 2019/10/10 10:12

+ 13 - 0
mall-service/src/main/java/com/txz/mall/dao/NoticeMapper.java

@@ -0,0 +1,13 @@
+package com.txz.mall.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.txz.mall.model.Notice;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Mapper
+public interface NoticeMapper extends BaseMapper<Notice> {
+}

+ 13 - 0
mall-service/src/main/java/com/txz/mall/dao/OtherNoticeMapper.java

@@ -0,0 +1,13 @@
+package com.txz.mall.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.txz.mall.model.OtherNotice;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Mapper
+public interface OtherNoticeMapper extends BaseMapper<OtherNotice> {
+}

+ 102 - 0
mall-service/src/main/java/com/txz/mall/enums/NoticeEnum.java

@@ -0,0 +1,102 @@
+package com.txz.mall.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@AllArgsConstructor
+public enum NoticeEnum {
+    
+    /**
+     * 订单通知_拼团支付成功
+     */
+    ORDER_GROUP_BUY_PAYMENT_SUCCESS("ORDER_GROUP_BUY_PAYMENT_SUCCESS", "订单通知_拼团支付成功"),
+    
+    /**
+     * 订单通知_订单拼团成功&抽中
+     */
+    ORDER_GROUP_BUY_SUCCESS_WIN("ORDER_GROUP_BUY_SUCCESS_WIN", "订单通知_订单拼团成功&抽中"),
+    
+    /**
+     * 订单通知_订单拼团成功&未抽中
+     */
+    ORDER_GROUP_BUY_SUCCESS_LOSE("ORDER_GROUP_BUY_SUCCESS_LOSE", "订单通知_订单拼团成功&未抽中"),
+    
+    /**
+     * 订单通知_订单补充收货地址
+     */
+    ORDER_PROVIDE_SHIPPING_ADDRESS("ORDER_PROVIDE_SHIPPING_ADDRESS", "订单通知_订单补充收货地址"),
+    
+    /**
+     * 订单通知_订单拼团失败
+     */
+    ORDER_GROUP_BUY_FAIL("ORDER_GROUP_BUY_FAIL", "订单通知_订单拼团失败"),
+    
+    /**
+     * 订单通知_订单发货
+     */
+    ORDER_SHIPPED_SUCCESS("ORDER_SHIPPED_SUCCESS", "订单通知_订单发货"),
+    
+    /**
+     * 收益通知_邀请好友奖励
+     */
+    REWARD_REFER_FRIENDS("REWARD_REFER_FRIENDS", "收益通知_邀请好友奖励"),
+    
+    /**
+     * 收益通知_拼团/开团奖励
+     */
+    REWARD_GROUP_BUY("REWARD_GROUP_BUY", "收益通知_拼团/开团奖励"),
+    
+    /**
+     * 收益通知_邀请好友奖励
+     */
+    REWARD_DIRECT_REFERRAL("REWARD_DIRECT_REFERRAL", "收益通知_邀请好友奖励"),
+    
+    /**
+     * 收益通知_签到奖励
+     */
+    REWARD_CHECKIN("REWARD_CHECKIN", "收益通知_签到奖励"),
+    
+    /**
+     * 充值/提现通知_充值成功
+     */
+    MONEY_RECHARGE_SUCCESS("MONEY_RECHARGE_SUCCESS", "充值/提现通知_充值成功"),
+    
+    /**
+     * 充值/提现通知_提现成功-收益
+     */
+    MONEY_WITHDRAWAL_ACCOUNT_SUCCESS("MONEY_WITHDRAWAL_ACCOUNT_SUCCESS", "充值/提现通知_提现成功-收益"),
+    
+    /**
+     * 充值/提现通知_提现成功-钱包
+     */
+    MONEY_WITHDRAWAL_WALLET_SUCCESS("MONEY_WITHDRAWAL_WALLET_SUCCESS", "充值/提现通知_提现成功-钱包"),
+    
+    /**
+     * 充值/提现通知_提现失败
+     */
+    MONEY_WITHDRAWAL_FAIL("MONEY_WITHDRAWAL_FAIL", "充值/提现通知_提现失败"),
+    
+    /**
+     * 其他
+     */
+    OTHER("OTHER", "其他"),
+    
+    ;
+    
+    @JsonValue
+    @EnumValue
+    @Getter
+    @Setter
+    private String data;
+    
+    @Getter
+    @Setter
+    private String description;
+}

+ 45 - 0
mall-service/src/main/java/com/txz/mall/enums/NoticeGroupEnum.java

@@ -0,0 +1,45 @@
+package com.txz.mall.enums;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@AllArgsConstructor
+public enum NoticeGroupEnum {
+    
+    /**
+     * 订单通知
+     */
+    ORDER("ORDER", "订单通知"),
+    
+    /**
+     * 收益通知
+     */
+    REWARD("REWARD", "收益通知"),
+    
+    /**
+     * 充值/提现通知
+     */
+    MONEY("MONEY", "充值/提现通知"),
+    
+    /**
+     * 其他
+     */
+    OTHER("OTHER", "其他"),
+    
+    ;
+    
+    @JsonValue
+    @Getter
+    @Setter
+    private String data;
+    
+    @Getter
+    @Setter
+    private String description;
+}

+ 70 - 0
mall-service/src/main/java/com/txz/mall/model/Notice.java

@@ -0,0 +1,70 @@
+package com.txz.mall.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.txz.mall.enums.NoticeEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("m_notice")
+public class Notice extends Model<Notice> {
+    
+    /**
+     * null
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    
+    /**
+     * 用户id
+     */
+    private Long uid;
+    
+    /**
+     * 通知类型
+     */
+    private NoticeEnum noticeType;
+    
+    /**
+     * 其他类型通知模板id
+     */
+    private Long otherId;
+    
+    /**
+     * 通知内容
+     */
+    private String noticeMessage;
+    
+    /**
+     * 已读标识
+     */
+    private Boolean readFlag;
+    
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+    
+    /**
+     * 用户删除标识
+     */
+    private Boolean userDel;
+    
+}

+ 52 - 0
mall-service/src/main/java/com/txz/mall/model/OtherNotice.java

@@ -0,0 +1,52 @@
+package com.txz.mall.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+
+@Data
+@TableName("m_other_notice")
+@EqualsAndHashCode(callSuper = true)
+public class OtherNotice extends Model<OtherNotice> {
+    
+    /**
+     * null
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    
+    /**
+     * 标题
+     */
+    private String title;
+    
+    /**
+     * 内容
+     */
+    private String message;
+    
+    /**
+     * null
+     */
+    private Integer isDelete;
+    
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+}

+ 22 - 0
mall-service/src/main/java/com/txz/mall/service/NoticeService.java

@@ -0,0 +1,22 @@
+package com.txz.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.txz.mall.model.Notice;
+import dto.NoticeDTO;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+
+public interface NoticeService extends IService<Notice> {
+    
+    /**
+     * 添加通知消息
+     *
+     * @param notice 通知数据传输对象,包含通知的详细信息
+     * @param uids   可变长参数,表示接收通知的用户ID列表
+     */
+    void addNotice(NoticeDTO notice, Long... uids);
+    
+}

+ 12 - 0
mall-service/src/main/java/com/txz/mall/service/OtherNoticeService.java

@@ -0,0 +1,12 @@
+package com.txz.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.txz.mall.model.OtherNotice;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+
+public interface OtherNoticeService extends IService<OtherNotice> {
+}

+ 40 - 0
mall-service/src/main/java/com/txz/mall/service/impl/NoticeServiceImpl.java

@@ -0,0 +1,40 @@
+package com.txz.mall.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.txz.mall.dao.NoticeMapper;
+import com.txz.mall.model.Notice;
+import com.txz.mall.service.NoticeService;
+import dto.NoticeDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Slf4j
+@Service
+public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {
+    
+    @Override
+    public void addNotice(NoticeDTO notice, Long... uids) {
+        if (CollectionUtil.isEmpty(Arrays.asList(uids))) {
+            return;
+        }
+        List<Notice> saveBatch = new ArrayList<>();
+        Notice info = BeanUtil.copyProperties(notice, Notice.class);
+        Arrays.stream(uids).forEach(uid -> {
+            info.setUid(uid);
+            info.setReadFlag(Boolean.FALSE);
+            info.setUserDel(Boolean.FALSE);
+            saveBatch.add(info);
+        });
+        this.saveBatch(saveBatch);
+    }
+}

+ 19 - 0
mall-service/src/main/java/com/txz/mall/service/impl/OtherNoticeServiceImpl.java

@@ -0,0 +1,19 @@
+package com.txz.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.txz.mall.dao.OtherNoticeMapper;
+import com.txz.mall.model.OtherNotice;
+import com.txz.mall.service.OtherNoticeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Slf4j
+@Service
+public class OtherNoticeServiceImpl extends ServiceImpl<OtherNoticeMapper, OtherNotice> implements OtherNoticeService {
+
+
+}

+ 32 - 0
mall-service/src/main/java/com/txz/mall/web/ro/OtherNoticeRO.java

@@ -0,0 +1,32 @@
+package com.txz.mall.web.ro;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Data
+public class OtherNoticeRO {
+    
+    /**
+     * 标题
+     */
+    @NotBlank(message = "标题不能为空", groups = {Add.class, Update.class})
+    private String title;
+    
+    /**
+     * 内容
+     */
+    @NotBlank(message = "内容不能为空", groups = {Add.class, Update.class})
+    private String message;
+    
+    public interface Add {
+    }
+    
+    public interface Update {
+    }
+    
+}

+ 34 - 0
mall-service/src/main/java/com/txz/mall/web/ro/SendNoticeRO.java

@@ -0,0 +1,34 @@
+package com.txz.mall.web.ro;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Data
+public class SendNoticeRO {
+    
+    /**
+     * 消息模板id
+     */
+    @NotEmpty(message = "消息模板id不能为空", groups = {Send.class})
+    private Long id;
+    
+    /**
+     * 用户id
+     */
+    @NotNull(message = "用户id不能为空", groups = {Send.class})
+    @Size(min = 1, message = "用户id不能为空", groups = {Send.class})
+    private List<Long> uids;
+    
+    public interface Send {
+    }
+    
+    
+}

+ 29 - 0
mall-service/src/main/java/dto/NoticeDTO.java

@@ -0,0 +1,29 @@
+package dto;
+
+import com.txz.mall.enums.NoticeEnum;
+import lombok.Data;
+
+/**
+ * @author: MTD®️
+ * @date: 2025/8/26
+ */
+@Data
+public class NoticeDTO {
+    
+    /**
+     * 通知类型
+     */
+    private NoticeEnum noticeType;
+    
+    /**
+     * 其他类型通知模板id
+     */
+    private Long otherId;
+    
+    /**
+     * 通知内容
+     * 订单相关的传订单号
+     * 自定义传 自定义字符串
+     */
+    private String noticeMessage;
+}