瀏覽代碼

消息中心基本接入

Huanyi 1 周之前
父節點
當前提交
4f57ae6e06
共有 27 個文件被更改,包括 1020 次插入24 次删除
  1. 1 0
      ruoyi-common/pom.xml
  2. 7 0
      ruoyi-common/ruoyi-common-bom/pom.xml
  3. 37 0
      ruoyi-common/yingpaipay-common-rabbitmq/pom.xml
  4. 40 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/config/RabbitMqConfig.java
  5. 49 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/core/RabbitMqProducer.java
  6. 62 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderAnomalyMessage.java
  7. 158 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderDispatchMessage.java
  8. 63 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderRejectMessage.java
  9. 1 0
      ruoyi-common/yingpaipay-common-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  10. 5 0
      ruoyi-modules/ruoyi-system/pom.xml
  11. 33 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
  12. 6 5
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java
  13. 5 4
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java
  14. 6 6
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java
  15. 77 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderAnomalyListener.java
  16. 58 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderDispatchListener.java
  17. 89 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderRejectListener.java
  18. 7 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java
  19. 11 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java
  20. 5 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfAnamalyController.java
  21. 1 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfAnamalyService.java
  22. 106 2
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfAnamalyServiceImpl.java
  23. 5 0
      ruoyi-modules/yingpaipay-order/pom.xml
  24. 86 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/config/OrderRabbitMqConfig.java
  25. 8 1
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/dubbo/RemoteSubOrderServiceImpl.java
  26. 1 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysOrderServiceImpl.java
  27. 93 5
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java

+ 1 - 0
ruoyi-common/pom.xml

@@ -46,6 +46,7 @@
         <module>ruoyi-common-sse</module>
         <module>yingpaipay-common-platform</module>
         <module>yingpaipay-common-external</module>
+        <module>yingpaipay-common-rabbitmq</module>
     </modules>
 
     <artifactId>ruoyi-common</artifactId>

+ 7 - 0
ruoyi-common/ruoyi-common-bom/pom.xml

@@ -264,6 +264,13 @@
                 <version>${revision}</version>
             </dependency>
 
+            <!-- RabbitMQ消息队列 -->
+            <dependency>
+                <groupId>org.dromara</groupId>
+                <artifactId>yingpaipay-common-rabbitmq</artifactId>
+                <version>${revision}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 </project>

+ 37 - 0
ruoyi-common/yingpaipay-common-rabbitmq/pom.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>yingpaipay-common-rabbitmq</artifactId>
+
+    <description>
+        yingpaipay-common-rabbitmq RabbitMQ消息队列服务
+    </description>
+
+    <dependencies>
+        <!-- RuoYi Common Core-->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+
+        <!-- Spring Boot RabbitMQ -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 40 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/config/RabbitMqConfig.java

@@ -0,0 +1,40 @@
+package org.dromara.common.rabbitmq.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.dromara.common.rabbitmq.core.RabbitMqProducer;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * RabbitMQ配置类
+ * 此代码为AI生成
+ *
+ * @author AI
+ */
+@AutoConfiguration
+public class RabbitMqConfig {
+
+    /**
+     * 配置消息转换器,使用Jackson进行JSON序列化
+     * 此代码为AI生成
+     */
+    @Bean
+    public MessageConverter messageConverter() {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+        return new Jackson2JsonMessageConverter(objectMapper);
+    }
+
+    /**
+     * 注册RabbitMQ消息生产者Bean
+     * 此代码为AI生成
+     */
+    @Bean
+    public RabbitMqProducer rabbitMqProducer(RabbitTemplate rabbitTemplate) {
+        return new RabbitMqProducer(rabbitTemplate);
+    }
+}

+ 49 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/core/RabbitMqProducer.java

@@ -0,0 +1,49 @@
+package org.dromara.common.rabbitmq.core;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.stereotype.Component;
+
+/**
+ * RabbitMQ消息生产者
+ * 此代码为AI生成
+ *
+ * @author AI
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class RabbitMqProducer {
+
+    private final RabbitTemplate rabbitTemplate;
+
+    /**
+     * 发送消息到指定交换机和路由键
+     * 此代码为AI生成
+     *
+     * @param exchange   交换机名称
+     * @param routingKey 路由键
+     * @param message    消息内容
+     */
+    public void sendMessage(String exchange, String routingKey, Object message) {
+        try {
+            rabbitTemplate.convertAndSend(exchange, routingKey, message);
+            log.info("RabbitMQ消息发送成功 - Exchange: {}, RoutingKey: {}, Message: {}", exchange, routingKey, message);
+        } catch (Exception e) {
+            log.error("RabbitMQ消息发送失败 - Exchange: {}, RoutingKey: {}, Message: {}", exchange, routingKey, message, e);
+            throw new RuntimeException("消息发送失败", e);
+        }
+    }
+
+    /**
+     * 发送消息到默认交换机
+     * 此代码为AI生成
+     *
+     * @param routingKey 路由键
+     * @param message    消息内容
+     */
+    public void sendMessage(String routingKey, Object message) {
+        sendMessage("", routingKey, message);
+    }
+}

+ 62 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderAnomalyMessage.java

@@ -0,0 +1,62 @@
+package org.dromara.common.rabbitmq.message;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 订单异常上报消息
+ * 此代码由AI生成
+ */
+@Data
+public class SubOrderAnomalyMessage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 子订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 异常ID
+     */
+    private Long anamalyId;
+
+    /**
+     * 门店站点ID
+     */
+    private Long storeSite;
+
+    /**
+     * 履约者名称
+     */
+    private String fulfillerName;
+
+    /**
+     * 异常类型
+     */
+    private String anamalyType;
+
+    /**
+     * 异常内容
+     */
+    private String content;
+
+    /**
+     * 履约者ID
+     */
+    private Long fulfillerId;
+
+    /**
+     * 所属门店名称
+     * 此代码由AI生成
+     */
+    private String storeName;
+
+    /**
+     * 异常上报提交时间(格式化后的字符串)
+     * 此代码由AI生成
+     */
+    private String submitTime;
+}

+ 158 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderDispatchMessage.java

@@ -0,0 +1,158 @@
+package org.dromara.common.rabbitmq.message;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 子订单派单消息
+ * 此代码为AI生成
+ *
+ * @author AI
+ */
+@Data
+public class SubOrderDispatchMessage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 子订单ID
+     */
+    private Long id;
+
+    /**
+     * 子订单编号
+     */
+    private String code;
+
+    /**
+     * 主订单ID
+     */
+    private Long orderId;
+
+    /**
+     * 主订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 门店ID
+     */
+    private Long store;
+
+    /**
+     * 门店站点ID
+     */
+    private Long storeSite;
+
+    /**
+     * 下单人
+     */
+    private Long orderPlacer;
+
+    /**
+     * 客户ID
+     */
+    private Long usrCustomer;
+
+    /**
+     * 宠物ID
+     */
+    private Long usrPet;
+
+    /**
+     * 服务ID
+     */
+    private Long service;
+
+    /**
+     * 履约者ID
+     */
+    private Long fulfiller;
+
+    /**
+     * 服务模式
+     */
+    private String mode;
+
+    /**
+     * 服务类型
+     */
+    private String type;
+
+    /**
+     * 联系人
+     */
+    private String contact;
+
+    /**
+     * 联系电话
+     */
+    private String contactPhoneNumber;
+
+    /**
+     * 团购套餐名称
+     */
+    private String groupPurchasePackageName;
+
+    /**
+     * 服务时间
+     */
+    private Date serviceTime;
+
+    /**
+     * 服务结束时间
+     */
+    private Date endServiceTime;
+
+    /**
+     * 起点编码
+     */
+    private String fromCode;
+
+    /**
+     * 起点地址
+     */
+    private String fromAddress;
+
+    /**
+     * 终点编码
+     */
+    private String toCode;
+
+    /**
+     * 终点地址
+     */
+    private String toAddress;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 租户ID
+     */
+    private String tenantId;
+
+    /**
+     * 平台ID
+     */
+    private Long platformId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 派单人ID
+     */
+    private Long dispatcherId;
+
+    /**
+     * 派单人姓名
+     */
+    private String dispatcherName;
+}

+ 63 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/java/org/dromara/common/rabbitmq/message/SubOrderRejectMessage.java

@@ -0,0 +1,63 @@
+package org.dromara.common.rabbitmq.message;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 履约者拒单/取消消息
+ * 此代码由AI生成
+ */
+@Data
+public class SubOrderRejectMessage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 子订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单ID
+     */
+    private Long orderId;
+
+    /**
+     * 门店站点ID
+     */
+    private Long storeSite;
+
+    /**
+     * 履约者名称
+     */
+    private String fulfillerName;
+
+    /**
+     * 拒单/取消原因
+     */
+    private String rejectReason;
+
+    /**
+     * 履约者ID
+     */
+    private Long fulfillerId;
+
+    /**
+     * 所属门店名称
+     * 此代码由AI生成
+     */
+    private String storeName;
+
+    /**
+     * 取消时间(格式化后的字符串)
+     * 此代码由AI生成
+     */
+    private String cancelTime;
+
+    /**
+     * 操作类型标识:REJECT=拒单, CANCEL=取消
+     * 此代码由AI生成
+     */
+    private String actionType;
+}

+ 1 - 0
ruoyi-common/yingpaipay-common-rabbitmq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+org.dromara.common.rabbitmq.config.RabbitMqConfig

+ 5 - 0
ruoyi-modules/ruoyi-system/pom.xml

@@ -110,6 +110,11 @@
             <artifactId>yingpaipay-api-service</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>yingpaipay-common-rabbitmq</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 33 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java

@@ -43,6 +43,39 @@ public class SysNoticeController extends BaseController {
         return noticeService.selectPageNoticeList(bo, pageQuery);
     }
 
+    /**
+     * 获取我的通知列表
+     */
+    @GetMapping("/myList")
+    public TableDataInfo<SysNoticeVo> myList(SysNoticeBo bo, PageQuery pageQuery) {
+        bo.setReceiver(org.dromara.common.satoken.utils.LoginHelper.getUserId());
+        return noticeService.selectPageNoticeList(bo, pageQuery);
+    }
+
+    /**
+     * 标记消息为已读
+     */
+    @Log(title = "系统通知信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/read/{id}")
+    public R<Void> read(@PathVariable Long id) {
+        SysNoticeBo bo = new SysNoticeBo();
+        bo.setId(id);
+        bo.setReadFlag(true);
+        bo.setReadTime(new java.util.Date());
+        return toAjax(noticeService.updateNotice(bo));
+    }
+
+    /**
+     * 标记所有未读消息为已读
+     */
+    @Log(title = "系统通知信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/readAll")
+    public R<Void> readAll() {
+        return toAjax(noticeService.readAllNotice(org.dromara.common.satoken.utils.LoginHelper.getUserId()));
+    }
+
     /**
      * 导出系统通知信息列表
      */

+ 6 - 5
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysNotice.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.tenant.core.TenantEntity;
 
 import java.util.Date;
@@ -16,7 +17,7 @@ import java.util.Date;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_notice")
-public class SysNotice extends TenantEntity {
+public class SysNotice extends BaseEntity {
 
     @TableId(value = "id")
     private Long id;
@@ -25,10 +26,6 @@ public class SysNotice extends TenantEntity {
 
     private Long sender;
 
-    private Boolean sendFlag;
-
-    private Date sendTime;
-
     private Integer type;
 
     private String title;
@@ -43,4 +40,8 @@ public class SysNotice extends TenantEntity {
 
     private Date readTime;
 
+    /**
+     * 业务关联ID
+     */
+    private Long businessId;
 }

+ 5 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysNoticeBo.java

@@ -29,10 +29,6 @@ public class SysNoticeBo extends BaseEntity {
     @NotNull(message = "发送方不能为空")
     private Long sender;
 
-    private Boolean sendFlag;
-
-    private Date sendTime;
-
     @NotNull(message = "消息类型不能为空")
     private Integer type;
 
@@ -54,4 +50,9 @@ public class SysNoticeBo extends BaseEntity {
 
     private Date readTime;
 
+    /**
+     * 业务关联ID
+     */
+    private Long businessId;
+
 }

+ 6 - 6
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysNoticeVo.java

@@ -32,12 +32,6 @@ public class SysNoticeVo implements Serializable {
     @ExcelProperty(value = "发送方")
     private Long sender;
 
-    @ExcelProperty(value = "发送标识")
-    private Boolean sendFlag;
-
-    @ExcelProperty(value = "发送时间")
-    private Date sendTime;
-
     @ExcelProperty(value = "消息类型")
     private Integer type;
 
@@ -62,4 +56,10 @@ public class SysNoticeVo implements Serializable {
     @ExcelProperty(value = "创建时间")
     private Date createTime;
 
+    /**
+     * 业务关联ID
+     */
+    @ExcelProperty(value = "业务关联ID")
+    private Long businessId;
+
 }

+ 77 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderAnomalyListener.java

@@ -0,0 +1,77 @@
+package org.dromara.system.listener;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.rabbitmq.message.SubOrderAnomalyMessage;
+import org.dromara.system.domain.SysUserAreaStation;
+import org.dromara.system.domain.bo.SysNoticeBo;
+import org.dromara.system.mapper.SysUserAreaStationMapper;
+import org.dromara.system.service.ISysNoticeService;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 订单异常上报消息监听器
+ * 此代码由AI生成
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class OrderAnomalyListener {
+
+    private final ISysNoticeService sysNoticeService;
+    private final SysUserAreaStationMapper sysUserAreaStationMapper;
+
+    @RabbitListener(queues = "order.notification.anomaly.queue")
+    public void handleOrderAnomaly(SubOrderAnomalyMessage message) {
+        log.info("=== 收到订单异常上报消息 ===");
+        log.info("单号: {}", message.getOrderCode());
+        log.info("上报者: {}", message.getFulfillerName());
+        log.info("异常类型: {}", message.getAnamalyType());
+
+        try {
+            if (message.getStoreSite() == null) {
+                return;
+            }
+            // 查找对应区域站长的用户(接收方规则同拒单通知)
+            List<SysUserAreaStation> users = sysUserAreaStationMapper.selectList(
+                Wrappers.<SysUserAreaStation>lambdaQuery()
+                    .in(SysUserAreaStation::getAreaStationId, Arrays.asList(message.getStoreSite(), 0L))
+            );
+
+            if (users != null && !users.isEmpty()) {
+                // 此代码由AI生成 - 修改通知格式为:履约者姓名,异常上报提交时间,异常原因,订单所属门店
+                String title = "订单异常上报通知";
+                String submitTime = message.getSubmitTime() != null ? message.getSubmitTime() : "未知时间";
+                String storeName = message.getStoreName() != null ? message.getStoreName() : "未知门店";
+                String content = "履约者" + message.getFulfillerName()
+                    + ",异常上报提交时间:" + submitTime
+                    + ",异常原因:" + message.getContent()
+                    + ",订单所属门店:" + storeName;
+
+                for (SysUserAreaStation user : users) {
+                     SysNoticeBo notice = new SysNoticeBo();
+                     // senderType 2为履约者
+                     notice.setSenderType(2);
+                     notice.setSender(message.getFulfillerId() != null ? message.getFulfillerId() : 0L);
+                     // receiverType 1为平台用户
+                     notice.setReceiverType(1);
+                     notice.setReceiver(user.getSysUserId());
+                     // 消息类型 2代表异常上报
+                     notice.setType(2);
+                     notice.setTitle(title);
+                     notice.setContent(content);
+                     notice.setBusinessId(message.getAnamalyId());
+
+                     sysNoticeService.insertNotice(notice);
+                }
+            }
+        } catch (Exception e) {
+            log.error("发送订单异常上报通知失败", e);
+        }
+    }
+}

+ 58 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderDispatchListener.java

@@ -0,0 +1,58 @@
+package org.dromara.system.listener;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.rabbitmq.message.SubOrderDispatchMessage;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+import org.dromara.system.service.ISysNoticeService;
+import org.dromara.system.domain.bo.SysNoticeBo;
+
+/**
+ * 订单派单消息监听器
+ * 此代码为AI生成
+ *
+ * @author AI
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class OrderDispatchListener {
+
+    private final ISysNoticeService sysNoticeService;
+
+    /**
+     * 监听订单派单消息
+     * 此代码为AI生成
+     *
+     * @param message 子订单派单消息
+     */
+    @RabbitListener(queues = "order.notification.queue")
+    public void handleOrderDispatch(SubOrderDispatchMessage message) {
+        
+        /*
+        try {
+            SysNoticeBo notice = new SysNoticeBo();
+            // 发送方类型 1为后台用户
+            notice.setSenderType(1);
+            notice.setSender(message.getDispatcherId() != null ? message.getDispatcherId() : 0L);
+            // 接收方类型 2为履约者
+            notice.setReceiverType(2);
+            notice.setReceiver(message.getFulfiller());
+            // 消息类型 0代表派单通知
+            notice.setType(0);
+            notice.setTitle("新订单待接单");
+            
+            String senderName = message.getDispatcherName() != null ? message.getDispatcherName() : "系统管理员";
+            notice.setContent(senderName + " 派给您新订单 " + message.getCode() + ",请您及时接单");
+            
+            sysNoticeService.insertNotice(notice);
+            log.info("已成功发送系统通知:派单通知");
+        } catch (Exception e) {
+            log.error("发送派单通知失败", e);
+        }
+        */
+        log.info("派单通知功能暂时禁用,不进行通知入库");
+    }
+}

+ 89 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/listener/OrderRejectListener.java

@@ -0,0 +1,89 @@
+package org.dromara.system.listener;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.rabbitmq.message.SubOrderRejectMessage;
+import org.dromara.system.domain.SysUserAreaStation;
+import org.dromara.system.domain.bo.SysNoticeBo;
+import org.dromara.system.mapper.SysUserAreaStationMapper;
+import org.dromara.system.service.ISysNoticeService;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 订单拒单/取消消息监听器
+ * 此代码由AI生成
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class OrderRejectListener {
+
+    private final ISysNoticeService sysNoticeService;
+    private final SysUserAreaStationMapper sysUserAreaStationMapper;
+
+    @RabbitListener(queues = "order.notification.reject.queue")
+    public void handleOrderReject(SubOrderRejectMessage message) {
+        log.info("=== 收到拒单/取消消息 ===");
+        log.info("单号: {}", message.getOrderCode());
+        log.info("履约者: {}", message.getFulfillerName());
+        log.info("原因: {}", message.getRejectReason());
+        log.info("操作类型: {}", message.getActionType());
+
+        try {
+            if (message.getStoreSite() == null) {
+                return;
+            }
+            List<SysUserAreaStation> users = sysUserAreaStationMapper.selectList(
+                Wrappers.<SysUserAreaStation>lambdaQuery()
+                    .in(SysUserAreaStation::getAreaStationId, Arrays.asList(message.getStoreSite(), 0L))
+            );
+
+            if (users != null && !users.isEmpty()) {
+                String cancelTime = message.getCancelTime() != null ? message.getCancelTime() : "未知时间";
+                String storeName = message.getStoreName() != null ? message.getStoreName() : "未知门店";
+
+                // 此代码由AI生成 - 根据actionType区分拒单和取消,生成不同的标题和内容
+                boolean isReject = "REJECT".equals(message.getActionType());
+                String title;
+                String content;
+                if (isReject) {
+                    title = "履约者拒绝接单通知";
+                    content = "履约者" + message.getFulfillerName()
+                        + "在" + cancelTime
+                        + "拒绝接单,原因:" + message.getRejectReason()
+                        + ",所属门店:" + storeName;
+                } else {
+                    title = "履约者取消订单通知";
+                    content = "履约者" + message.getFulfillerName()
+                        + "在" + cancelTime
+                        + "取消订单,原因:" + message.getRejectReason()
+                        + ",所属门店:" + storeName;
+                }
+
+                for (SysUserAreaStation user : users) {
+                     SysNoticeBo notice = new SysNoticeBo();
+                     // senderType 2为履约者
+                     notice.setSenderType(2);
+                     notice.setSender(message.getFulfillerId() != null ? message.getFulfillerId() : 0L);
+                     // receiverType 1为平台用户
+                     notice.setReceiverType(1);
+                     notice.setReceiver(user.getSysUserId());
+                     // 消息类型 1代表拒单/取消通知
+                     notice.setType(1);
+                     notice.setTitle(title);
+                     notice.setContent(content);
+                     notice.setBusinessId(message.getOrderId());
+
+                     sysNoticeService.insertNotice(notice);
+                }
+            }
+        } catch (Exception e) {
+            log.error("发送拒单/取消订单通知失败", e);
+        }
+    }
+}

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysNoticeService.java

@@ -63,4 +63,11 @@ public interface ISysNoticeService {
      */
     Boolean deleteNoticeByIds(List<Long> ids);
 
+    /**
+     * 标记所有未读消息为已读
+     * @param receiver 接收方
+     * @return 结果
+     */
+    Boolean readAllNotice(Long receiver);
+
 }

+ 11 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysNoticeServiceImpl.java

@@ -64,12 +64,22 @@ public class SysNoticeServiceImpl implements ISysNoticeService {
         return baseMapper.deleteByIds(ids) > 0;
     }
 
+    @Override
+    public Boolean readAllNotice(Long receiver) {
+        SysNotice notice = new SysNotice();
+        notice.setReadFlag(true);
+        notice.setReadTime(new java.util.Date());
+        LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SysNotice::getReceiver, receiver);
+        lqw.eq(SysNotice::getReadFlag, false);
+        return baseMapper.update(notice, lqw) > 0;
+    }
+
     private LambdaQueryWrapper<SysNotice> buildQueryWrapper(SysNoticeBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<SysNotice> lqw = Wrappers.lambdaQuery();
         lqw.eq(bo.getSenderType() != null, SysNotice::getSenderType, bo.getSenderType());
         lqw.eq(bo.getSender() != null, SysNotice::getSender, bo.getSender());
-        lqw.eq(bo.getSendFlag() != null, SysNotice::getSendFlag, bo.getSendFlag());
         lqw.eq(bo.getType() != null, SysNotice::getType, bo.getType());
         lqw.like(StringUtils.isNotBlank(bo.getTitle()), SysNotice::getTitle, bo.getTitle());
         lqw.eq(bo.getReceiverType() != null, SysNotice::getReceiverType, bo.getReceiverType());

+ 5 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfAnamalyController.java

@@ -56,4 +56,9 @@ public class FlfAnamalyController extends BaseController {
         return R.ok(flfAnamalyService.getByOrderId(orderId));
     }
 
+    @GetMapping("/getInfo")
+    public R<FlfAnamalyVo> getInfo(@RequestParam Long id) {
+        return R.ok(flfAnamalyService.getById(id));
+    }
+
 }

+ 1 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfAnamalyService.java

@@ -20,4 +20,5 @@ public interface IFlfAnamalyService {
     List<FlfAnamalyOnOrderVo> getByOrderId(Long orderId);
 
     boolean delete(Long id);
+    FlfAnamalyVo getById(Long id);
 }

+ 106 - 2
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfAnamalyServiceImpl.java

@@ -11,6 +11,8 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.utils.WrapperUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.rabbitmq.core.RabbitMqProducer;
+import org.dromara.common.rabbitmq.message.SubOrderAnomalyMessage;
 import org.dromara.fulfiller.domain.FlfAnamaly;
 import org.dromara.fulfiller.domain.FlfFulfiller;
 import org.dromara.fulfiller.domain.bo.*;
@@ -38,6 +40,7 @@ public class FlfAnamalyServiceImpl implements IFlfAnamalyService {
 
     private final FlfAnamalyMapper baseMapper;
     private final FlfFulfillerMapper flfFulfillerMapper;
+    private final RabbitMqProducer rabbitMqProducer;
 
     @DubboReference
     private final RemoteSubOrderService remoteSubOrderService;
@@ -158,7 +161,58 @@ public class FlfAnamalyServiceImpl implements IFlfAnamalyService {
         add.setStatus(bo.getStatus());
         add.setTenantId(vo.getTenantId());
 
-        return baseMapper.insert(add) > 0;
+        boolean success = baseMapper.insert(add) > 0;
+        if (success) {
+            // 发送异常上报通知
+            sendAnomalyNotification(add, vo);
+        }
+        return success;
+    }
+
+    /**
+     * 发送异常上报通知消息
+     * 此代码由AI生成
+     */
+    private void sendAnomalyNotification(FlfAnamaly anamaly, RemoteSubOrderVo orderVo) {
+        try {
+            SubOrderAnomalyMessage message = new SubOrderAnomalyMessage();
+            message.setOrderCode(orderVo.getCode());
+            message.setAnamalyId(anamaly.getId());
+            message.setStoreSite(orderVo.getStoreSite());
+            message.setFulfillerId(anamaly.getFulfiller());
+            message.setAnamalyType(anamaly.getType());
+            message.setContent(anamaly.getContent());
+
+            // 获取履约者姓名
+            FlfFulfiller fulfiller = flfFulfillerMapper.selectById(anamaly.getFulfiller());
+            if (fulfiller != null) {
+                message.setFulfillerName(fulfiller.getName());
+            }
+
+            // 此代码由AI生成 - 获取门店名称
+            if (orderVo.getStore() != null) {
+                List<RemoteStoreVo> stores = remoteStoreService.getByIds(List.of(orderVo.getStore()));
+                if (stores != null && !stores.isEmpty()) {
+                    message.setStoreName(stores.get(0).getName());
+                } else {
+                    message.setStoreName("未知门店");
+                }
+            } else {
+                message.setStoreName("未知门店");
+            }
+
+            // 此代码由AI生成 - 设置提交时间
+            message.setSubmitTime(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
+
+            // 发送消息到交换机
+            rabbitMqProducer.sendMessage(
+                "order.exchange",
+                "order.notification.anomaly",
+                message
+            );
+        } catch (Exception e) {
+            // 消息发送失败不影响主业务逻辑
+        }
     }
 
     @Override
@@ -186,7 +240,12 @@ public class FlfAnamalyServiceImpl implements IFlfAnamalyService {
         RemoteSubOrderVo vo = remoteSubOrderService.getById(bo.getOrderId());
         anamaly.setTenantId(vo.getTenantId());
 
-        return baseMapper.insert(anamaly) > 0;
+        boolean success = baseMapper.insert(anamaly) > 0;
+        if (success) {
+            // 发送异常上报通知
+            sendAnomalyNotification(anamaly, vo);
+        }
+        return success;
     }
 
     @Override
@@ -251,4 +310,49 @@ public class FlfAnamalyServiceImpl implements IFlfAnamalyService {
     public boolean delete(Long id) {
         return baseMapper.deleteById(id) > 0;
     }
+
+    @Override
+    public FlfAnamalyVo getById(Long id) {
+        FlfAnamalyVo vo = baseMapper.selectVoById(id);
+        if (vo == null) {
+            return null;
+        }
+
+        // 补全信息
+        if (vo.getFulfiller() != null) {
+            FlfFulfiller fulfiller = flfFulfillerMapper.selectById(vo.getFulfiller());
+            if (fulfiller != null) {
+                vo.setFulfillerName(fulfiller.getName());
+                vo.setFulfillerPhone(fulfiller.getPhone());
+            }
+        }
+
+        if (vo.getAuditor() != null) {
+            List<RemoteUserVo> users = remoteUserService.getByIds(List.of(vo.getAuditor()));
+            if (!users.isEmpty()) {
+                vo.setAuditorName(users.get(0).getUserName());
+            }
+        }
+
+        if (StringUtils.isNotBlank(vo.getPhotos())) {
+            List<Long> photoIds = Arrays.stream(vo.getPhotos().split(",")).map(Long::valueOf).toList();
+            List<String> photoUrls = new ArrayList<>();
+            remoteFileService.selectByIds(photoIds).forEach(e -> photoUrls.add(e.getUrl()));
+            vo.setPhotosUrls(photoUrls);
+        }
+
+        if (vo.getOrderId() != null) {
+            RemoteSubOrderVo order = remoteSubOrderService.getById(vo.getOrderId());
+            if (order != null) {
+                vo.setOrderCode(order.getCode());
+                RemoteStoreVo store = remoteStoreService.getByIds(List.of(order.getStore())).get(0);
+                if (store != null) {
+                    vo.setStore(store.getId());
+                    vo.setStoreName(store.getName());
+                }
+            }
+        }
+
+        return vo;
+    }
 }

+ 5 - 0
ruoyi-modules/yingpaipay-order/pom.xml

@@ -84,6 +84,11 @@
             <artifactId>ruoyi-common-encrypt</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>yingpaipay-common-rabbitmq</artifactId>
+        </dependency>
+
         <!-- RuoYi Api System -->
         <dependency>
             <groupId>org.dromara</groupId>

+ 86 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/config/OrderRabbitMqConfig.java

@@ -0,0 +1,86 @@
+package org.dromara.order.config;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 订单服务RabbitMQ配置
+ * 此代码为AI生成
+ *
+ * @author AI
+ */
+@Configuration
+public class OrderRabbitMqConfig {
+
+    /**
+     * 订单交换机名称
+     */
+    public static final String ORDER_EXCHANGE = "order.exchange";
+
+    /**
+     * 订单队列名称
+     */
+    public static final String ORDER_QUEUE = "order.notification.queue";
+
+    /**
+     * 订单路由键
+     */
+    public static final String ORDER_ROUTING_KEY = "order.notification";
+
+    public static final String ORDER_REJECT_QUEUE = "order.notification.reject.queue";
+    public static final String ORDER_REJECT_ROUTING_KEY = "order.notification.reject";
+
+    public static final String ORDER_ANOMALY_QUEUE = "order.notification.anomaly.queue";
+    public static final String ORDER_ANOMALY_ROUTING_KEY = "order.notification.anomaly";
+
+    /**
+     * 声明订单交换机
+     * 此代码为AI生成
+     */
+    @Bean
+    public DirectExchange orderExchange() {
+        return new DirectExchange(ORDER_EXCHANGE, true, false);
+    }
+
+    /**
+     * 声明订单队列
+     * 此代码为AI生成
+     */
+    @Bean
+    public Queue orderQueue() {
+        return new Queue(ORDER_QUEUE, true);
+    }
+
+    /**
+     * 绑定队列到交换机
+     * 此代码为AI生成
+     */
+    @Bean
+    public Binding orderBinding(Queue orderQueue, DirectExchange orderExchange) {
+        return BindingBuilder.bind(orderQueue).to(orderExchange).with(ORDER_ROUTING_KEY);
+    }
+
+    @Bean
+    public Queue orderRejectQueue() {
+        return new Queue(ORDER_REJECT_QUEUE, true);
+    }
+
+    @Bean
+    public Binding orderRejectBinding(Queue orderRejectQueue, DirectExchange orderExchange) {
+        return BindingBuilder.bind(orderRejectQueue).to(orderExchange).with(ORDER_REJECT_ROUTING_KEY);
+    }
+
+    @Bean
+    public Queue orderAnomalyQueue() {
+        return new Queue(ORDER_ANOMALY_QUEUE, true);
+    }
+
+    @Bean
+    public Binding orderAnomalyBinding(Queue orderAnomalyQueue, DirectExchange orderExchange) {
+        return BindingBuilder.bind(orderAnomalyQueue).to(orderExchange).with(ORDER_ANOMALY_ROUTING_KEY);
+    }
+}

+ 8 - 1
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/dubbo/RemoteSubOrderServiceImpl.java

@@ -54,7 +54,7 @@ public class RemoteSubOrderServiceImpl implements RemoteSubOrderService {
     public RemoteSubOrderVo getIdByCode(String code) {
         SysSubOrder subOrder = baseMapper.selectOne(
             Wrappers.lambdaQuery(SysSubOrder.class)
-                .select(SysSubOrder::getId, SysSubOrder::getTenantId)
+                .select(SysSubOrder::getId, SysSubOrder::getTenantId, SysSubOrder::getCode, SysSubOrder::getStore, SysSubOrder::getStoreSite)
                 .eq(SysSubOrder::getCode, code)
                 .last("LIMIT 1")
         );
@@ -66,6 +66,10 @@ public class RemoteSubOrderServiceImpl implements RemoteSubOrderService {
         RemoteSubOrderVo vo = new RemoteSubOrderVo();
         vo.setId(subOrder.getId());
         vo.setTenantId(subOrder.getTenantId());
+        vo.setCode(subOrder.getCode());
+        // 此代码由AI生成 - 补充门店相关字段
+        vo.setStore(subOrder.getStore());
+        vo.setStoreSite(subOrder.getStoreSite());
 
         return vo;
     }
@@ -128,6 +132,9 @@ public class RemoteSubOrderServiceImpl implements RemoteSubOrderService {
         vo.setId(order.getId());
         vo.setTenantId(order.getTenantId());
         vo.setStoreSite(order.getStoreSite());
+        vo.setCode(order.getCode());
+        // 此代码由AI生成 - 补充门店ID字段
+        vo.setStore(order.getStore());
 
         return vo;
     }

+ 1 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysOrderServiceImpl.java

@@ -23,6 +23,7 @@ import org.dromara.order.mapper.SysOrderMapper;
 import org.dromara.order.mapper.SysSubOrderLogMapper;
 import org.dromara.order.mapper.SysSubOrderMapper;
 import org.dromara.order.service.ISysOrderService;
+import org.dromara.common.rabbitmq.core.RabbitMqProducer;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 

+ 93 - 5
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java

@@ -21,13 +21,17 @@ import org.dromara.fulfiller.api.RemoteFulfillerService;
 import org.dromara.fulfiller.api.domain.vo.RemoteFulfillerVo;
 import org.dromara.fulfiller.api.model.FulfillerLoginUser;
 import org.dromara.order.api.enums.*;
+import org.dromara.order.config.OrderRabbitMqConfig;
 import org.dromara.order.domain.SysSubOrder;
 import org.dromara.order.domain.SysSubOrderLog;
 import org.dromara.order.domain.bo.*;
 import org.dromara.order.domain.vo.*;
+import org.dromara.common.rabbitmq.message.SubOrderDispatchMessage;
+import org.dromara.common.rabbitmq.message.SubOrderRejectMessage;
 import org.dromara.order.mapper.SysSubOrderLogMapper;
 import org.dromara.order.mapper.SysSubOrderMapper;
 import org.dromara.order.service.ISysSubOrderService;
+import org.dromara.common.rabbitmq.core.RabbitMqProducer;
 import org.dromara.resource.api.RemoteFileService;
 import org.dromara.resource.api.domain.RemoteFile;
 import org.dromara.system.api.RemoteAreaStationService;
@@ -37,9 +41,11 @@ import org.dromara.system.api.RemoteUserService;
 import org.dromara.system.api.domain.vo.RemoteStoreVo;
 import org.dromara.system.api.domain.vo.RemoteUserVo;
 import org.dromara.system.api.model.LoginUser;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
@@ -48,6 +54,9 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 public class SysSubOrderServiceImpl implements ISysSubOrderService {
 
+    // 此代码为AI生成
+    private final RabbitMqProducer rabbitMqProducer;
+
     private final SysSubOrderMapper baseMapper;
     private final SysSubOrderLogMapper subOrderLogMapper;
 
@@ -199,6 +208,28 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             throw new RuntimeException("记录日志失败");
         }
 
+        // 此代码为AI生成 - 派单时发送RabbitMQ消息用于后续消息通知 (暂时禁用)
+        /*
+        try {
+            SubOrderDispatchMessage message = new SubOrderDispatchMessage();
+            BeanUtils.copyProperties(subOrder, message);
+
+            // 补全派单人信息
+            message.setDispatcherId(LoginHelper.getUserId());
+            if (LoginHelper.getLoginUser() != null) {
+                message.setDispatcherName(LoginHelper.getLoginUser().getNickname());
+            }
+
+            rabbitMqProducer.sendMessage(
+                OrderRabbitMqConfig.ORDER_EXCHANGE,
+                OrderRabbitMqConfig.ORDER_ROUTING_KEY,
+                message
+            );
+        } catch (Exception e) {
+            // 消息发送失败不影响派单,仅记录日志
+        }
+        */
+
         return true;
     }
 
@@ -217,7 +248,9 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
         SysSubOrderLog log = new SysSubOrderLog();
 
         LoginUser loginUser = LoginHelper.getLoginUser();
-        if (loginUser.getUserType().equals(UserType.FULFILLER_USER.getUserType())) {
+        // 此代码由AI生成 - 判断是否为履约者取消
+        boolean isFulfillerCancel = loginUser.getUserType().equals(UserType.FULFILLER_USER.getUserType());
+        if (isFulfillerCancel) {
             log.setSubOrderId(subOrder.getId());
             log.setActioner(LoginHelper.getUserId());
             log.setActionerType(OrderLogActionerTypeEnum.FULFILLER.getValue());
@@ -244,12 +277,44 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             throw new RuntimeException("日志追加失败");
         }
 
+        // 此代码由AI生成 - 履约者取消订单时发送消息通知
+        if (isFulfillerCancel) {
+            try {
+                SubOrderRejectMessage msg = new SubOrderRejectMessage();
+                msg.setOrderCode(subOrder.getCode());
+                msg.setOrderId(subOrder.getId());
+                msg.setStoreSite(subOrder.getStoreSite());
+                msg.setFulfillerId(LoginHelper.getUserId());
+                msg.setFulfillerName(loginUser.getNickname());
+                msg.setRejectReason(bo.getReason());
+                // 获取门店名称
+                String storeName = remoteStoreService.getNameById(subOrder.getStore());
+                msg.setStoreName(storeName != null ? storeName : "未知门店");
+                // 设置取消时间
+                msg.setCancelTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+                // 此代码由AI生成 - 标识为取消操作
+                msg.setActionType("CANCEL");
+
+                rabbitMqProducer.sendMessage(
+                    OrderRabbitMqConfig.ORDER_EXCHANGE,
+                    OrderRabbitMqConfig.ORDER_REJECT_ROUTING_KEY,
+                    msg
+                );
+            } catch (Exception e) {
+                // 消息发送失败不影响主流程
+            }
+        }
+
         return true;
     }
 
     @Override
     public SysSubOrderVo getInfo(Long id) {
-        return baseMapper.selectVoById(id);
+        SysSubOrderVo vo = baseMapper.selectVoById(id);
+        if (vo == null) {
+            return null;
+        }
+        return vo;
     }
 
     @Override
@@ -259,11 +324,8 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
 
         if (StringUtils.isNotBlank(bo.getContent())) {
             List<Long> storeIds = remoteStoreService.selectIdsByName(bo.getContent());
-//            orderWrapper.in(SysSubOrder::getStore, WrapperUtils.convertIds(storeIds));
             List<Long> userIds = remoteUserService.selectUserIdsByName(bo.getContent());
-//            orderWrapper.in(SysSubOrder::getOrderPlacer, WrapperUtils.convertIds(userIds));
             List<Long> customerIds = remoteCustomerService.selectIdsByName(bo.getContent());
-//            orderWrapper.in(SysSubOrder::getUsrCustomer, WrapperUtils.convertIds(customerIds));
             orderWrapper.and(w -> w
                 .in(SysSubOrder::getStore, WrapperUtils.convertIds(storeIds)).or()
                 .in(SysSubOrder::getOrderPlacer, WrapperUtils.convertIds(userIds)).or()
@@ -769,6 +831,32 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             throw new RuntimeException("日志新增失败");
         }
 
+        // 此代码由AI生成 - 发送拒单消息(包含门店名称和取消时间)
+        try {
+            SubOrderRejectMessage msg = new SubOrderRejectMessage();
+            msg.setOrderCode(subOrder.getCode());
+            msg.setOrderId(subOrder.getId());
+            msg.setStoreSite(subOrder.getStoreSite());
+            msg.setFulfillerId(LoginHelper.getUserId());
+            msg.setFulfillerName(LoginHelper.getLoginUser().getNickname());
+            msg.setRejectReason(bo.getRejectReason());
+            // 获取门店名称
+            String storeName = remoteStoreService.getNameById(subOrder.getStore());
+            msg.setStoreName(storeName != null ? storeName : "未知门店");
+            // 设置取消时间
+            msg.setCancelTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+            // 此代码由AI生成 - 标识为拒单操作
+            msg.setActionType("REJECT");
+
+            rabbitMqProducer.sendMessage(
+                OrderRabbitMqConfig.ORDER_EXCHANGE,
+                OrderRabbitMqConfig.ORDER_REJECT_ROUTING_KEY,
+                msg
+            );
+        } catch (Exception e) {
+            // 忽略发送异常,以不影响主流程
+        }
+
         return true;
     }