rust: Mediator Pattern

项目结构:

rust 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : process_dtos.rs
//! DTO(数据传输对象)定义
//!
//! 用于跨层(表现层 → 接口层 → 应用层 → 领域层)传递数据,仅承载数据、无业务逻辑。
//! - `ProcessRequestDto`:业务流程执行请求
//! - `ProcessResponseDto`:业务流程执行响应

use crate::domain::entities::jewelry::Jewelry;

/// 业务流程执行请求 DTO
///
/// `department` / `operator` 为溯源扩展字段(预留给审计场景),
/// 当前演示中同事自行声明所属部门,未读取该两字段。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessRequestDto {
    /// 流程类型标识(如 PROCUREMENT / DESIGN / PRODUCTION 等)
    pub process_type: String,
    /// 关联珠宝实体
    pub jewelry: Jewelry,
    /// 发起部门(如 采购部 / 设计部 / 生产部 等)
    pub department: String,
    /// 操作人(如 Mediator 中介者 / 具体岗位名称)
    pub operator: String,
}

impl ProcessRequestDto {
    /// 创建业务流程执行请求 DTO
    ///
    /// # 参数
    /// - `process_type`:流程类型标识
    /// - `jewelry`:关联珠宝
    /// - `department`:发起部门
    /// - `operator`:操作人
    ///
    /// # 返回
    /// 请求 DTO
    pub fn new(process_type: &str, jewelry: Jewelry, department: &str, operator: &str) -> Self {
        Self {
            process_type: process_type.to_string(),
            jewelry,
            department: department.to_string(),
            operator: operator.to_string(),
        }
    }
}

/// 业务流程执行响应 DTO
///
/// `instance_id` 预留给需要回传实例编号的上层调用方,演示中编号已写入日志。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessResponseDto {
    /// 流程实例编号(如 PROCUREMENT-000001)
    pub instance_id: String,
    /// 流程名称(中文)
    pub process_name: String,
    /// 是否成功
    pub success: bool,
    /// 结果消息(成功摘要或失败原因)
    pub message: String,
}

impl ProcessResponseDto {
    /// 创建流程响应 DTO
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `process_name`:流程名称
    /// - `success`:是否成功
    /// - `message`:结果消息
    ///
    /// # 返回
    /// 响应 DTO
    pub fn new(instance_id: &str, process_name: &str, success: bool, message: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            process_name: process_name.to_string(),
            success,
            message: message.to_string(),
        }
    }
}

//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : jewelry.rs
//! 珠宝行业领域实体定义
//!
//! 包含:
//! - `Jewelry`:珠宝业务实体(贯穿采购→设计→生产→质检→包装→物流→财务→
//!   营销→销售等全部流程)
//! - `ProcessOutcome`:业务流程执行产出(同事业务执行的返回载体)
//! - 全局自增流水号生成器(线程安全,用于生成唯一编号)

use std::sync::atomic::{AtomicU64, Ordering};

/// 全局自增流水号(线程安全,跨线程共享生成唯一序号)
static NEXT_SEQUENCE: AtomicU64 = AtomicU64::new(1);

/// 获取下一个业务流水号(原子递增,高并发安全)
///
/// # 返回
/// 下一个自增序号
pub fn next_sequence() -> u64 {
    NEXT_SEQUENCE.fetch_add(1, Ordering::SeqCst)
}

/// 珠宝业务实体(领域实体,跨全流程共享)
///
/// `id` / `status` / `with_status` 为领域状态演进预留(如 `PROCURED`→`DELIVERED`),
/// 当前演示以值传递共享珠宝实体,未对状态字段做持久化演进,属预留 API。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Jewelry {
    /// 珠宝编号(如 JWL-000001)
    pub id: String,
    /// 珠宝名称
    pub name: String,
    /// 材质(黄金 / 铂金 / 钻石 / K金 / 银)
    pub material: String,
    /// 重量(克)
    pub weight_grams: f64,
    /// 零售价(元)
    pub price: f64,
    /// 当前状态(INIT 初始 / PROCURED 已采购 / DESIGNED 已设计 /
    /// PRODUCED 已生产 / INSPECTED 已质检 / PACKED 已包装 / DELIVERED 已发货)
    pub status: String,
}

impl Jewelry {
    /// 创建珠宝实体
    ///
    /// # 参数
    /// - `name`:珠宝名称
    /// - `material`:材质
    /// - `weight_grams`:重量(克)
    /// - `price`:零售价(元)
    ///
    /// # 返回
    /// 初始状态为 `INIT` 的珠宝实体
    pub fn new(name: &str, material: &str, weight_grams: f64, price: f64) -> Self {
        Self {
            id: format!("JWL-{:06}", next_sequence()),
            name: name.to_string(),
            material: material.to_string(),
            weight_grams,
            price,
            status: "INIT".to_string(),
        }
    }

    /// 更新珠宝状态(返回新实体,保持不可变语义便于并发共享)
    ///
    /// # 参数
    /// - `status`:新状态
    ///
    /// # 返回
    /// 更新状态后的珠宝实体副本
    #[allow(dead_code)]
    pub fn with_status(&self, status: &str) -> Self {
        let mut cloned = self.clone();
        cloned.status = status.to_string();
        cloned
    }
}

/// 业务流程执行产出(同事业务执行的返回载体)
///
/// `instance_id` 预留给产出追溯使用,当前已写入执行记录(`ProcessRecord`),
/// 此处字段作为冗余追溯标识保留。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessOutcome {
    /// 流程实例编号
    pub instance_id: String,
    /// 产出摘要(中文描述)
    pub summary: String,
    /// 是否成功
    pub success: bool,
}

impl ProcessOutcome {
    /// 创建成功产出
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `summary`:产出摘要
    ///
    /// # 返回
    /// 成功产出
    pub fn success(instance_id: &str, summary: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            summary: summary.to_string(),
            success: true,
        }
    }

    /// 创建失败产出
    ///
    /// 预留 API:当前演示业务执行失败时直接返回错误,不构造失败产出;
    /// 该构造器预留给需要显式失败产出的场景。
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `summary`:产出摘要
    ///
    /// # 返回
    /// 失败产出
    #[allow(dead_code)]
    pub fn failure(instance_id: &str, summary: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            summary: summary.to_string(),
            success: false,
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : colleague.rs
//! 中介者模式核心:Colleague(同事)抽象
//!
//! 同事是参与协同的业务部门。核心约束:**同事之间不直接相互引用**,
//! 而是通过注入的中介者(`Arc<dyn BusinessMediator>`)通信------
//! 执行业务后可向中介者广播事件、查询其他部门产出。

use std::sync::Arc;
use std::sync::Mutex;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 同事共享支持(中介者引用存储 + 日志),供各具体同事组合复用
pub struct ColleagueSupport {
    /// 统一日志对象(依赖注入)
    logger: Arc<dyn Logger>,
    /// 中介者引用(由中介者注册时注入,受互斥锁保护,线程安全)
    mediator: Mutex<Option<Arc<dyn BusinessMediator>>>,
}

impl ColleagueSupport {
    /// 创建同事共享支持
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事支持实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            logger,
            mediator: Mutex::new(None),
        }
    }

    /// 注入中介者
    ///
    /// # 参数
    /// - `mediator`:中介者实例
    pub fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        *self.mediator.lock().unwrap() = Some(mediator);
    }

    /// 获取中介者(可能尚未注入)
    ///
    /// # 返回
    /// 中介者实例(可能为空)
    pub fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.mediator.lock().unwrap().clone()
    }

    /// 获取统一日志对象
    ///
    /// # 返回
    /// 统一日志对象引用
    pub fn logger(&self) -> &Arc<dyn Logger> {
        &self.logger
    }
}

/// 同事抽象(Colleague trait,线程安全)
///
/// 约束 `Send + Sync`,保证可经 `Arc<dyn Colleague>` 注入中介者,
/// 并在多线程高并发环境下共享执行。
pub trait Colleague: Send + Sync {
    /// 获取同事标识(如 PROCUREMENT)
    ///
    /// # 返回
    /// 同事标识
    fn colleague_id(&self) -> &'static str;

    /// 获取同事名称(中文,如 原料采购核验)
    ///
    /// # 返回
    /// 同事名称
    fn colleague_name(&self) -> &'static str;

    /// 获取所属部门(如 采购部)
    ///
    /// # 返回
    /// 部门名称
    fn department(&self) -> &'static str;

    /// 获取统一日志对象(由依赖注入提供)
    ///
    /// # 返回
    /// 统一日志对象引用
    fn logger(&self) -> &Arc<dyn Logger>;

    /// 注入中介者(由中介者注册时调用)
    ///
    /// # 参数
    /// - `mediator`:中介者实例
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>);

    /// 获取注入的中介者(可能为空)
    ///
    /// # 返回
    /// 中介者实例(可能为空)
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>>;

    /// **执行业务动作**(同事核心业务,子类必须实现)
    ///
    /// # 参数
    /// - `ctx`:命令上下文
    ///
    /// # 返回
    /// - `Ok(ProcessOutcome)`:业务成功产出
    /// - `Err(ProcessError)`:业务失败
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError>;

    /// 响应中介者转发的业务事件(默认空实现,子类可按需覆盖)
    ///
    /// 用于体现同事间经中介者的间接协同。
    ///
    /// # 参数
    /// - `event`:业务事件
    /// - `ctx`:命令上下文
    ///
    /// # 返回
    /// - `Ok(())`:响应成功
    /// - `Err(ProcessError)`:响应失败
    fn on_event(&self, _event: BusinessEvent, _ctx: &CommandContext) -> Result<(), ProcessError> {
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : command_ctx.rs
//! 命令上下文定义
//!
//! 定义中介者模式中同事执行所需的上下文(`CommandContext`),
//! 承载一次业务执行所需的实例编号与请求 DTO。

use crate::domain::dtos::process_dtos::ProcessRequestDto;
use crate::domain::entities::jewelry::Jewelry;

/// 命令执行上下文(一次同事业务执行所需的输入与实例编号)
#[derive(Debug, Clone)]
pub struct CommandContext {
    /// 流程实例编号(唯一,如 PROCUREMENT-000001)
    pub instance_id: String,
    /// 请求 DTO
    pub request: ProcessRequestDto,
}

impl CommandContext {
    /// 创建命令上下文
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `request`:请求 DTO
    ///
    /// # 返回
    /// 命令上下文
    pub fn new(instance_id: &str, request: ProcessRequestDto) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            request,
        }
    }

    /// 获取关联珠宝实体
    ///
    /// # 返回
    /// 珠宝实体引用
    pub fn jewelry(&self) -> &Jewelry {
        &self.request.jewelry
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : mediator.rs
//! 中介者模式核心:Mediator(中介者)抽象
//!
//! 中介者封装一组对象(同事)之间的交互,集中管理:
//! - 同事注册表
//! - 部门产出查询/记录(同事通过中介者间接获取其他部门产出)
//! - 业务事件路由(dispatch:把某部门完成的事件转发给相关部门)

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::Colleague;
use crate::domain::mediator::command_ctx::CommandContext;

/// 业务事件(部门完成后的业务事件,供中介者路由协调)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BusinessEvent {
    /// 原料采购核验完成
    ProcurementCompleted,
    /// 设计制图完成
    DesignCompleted,
    /// 加工生产完成
    ProductionCompleted,
    /// 质检完成
    InspectionCompleted,
    /// 包装完成
    PackagingCompleted,
    /// 物流发货完成
    LogisticsCompleted,
    /// 财务核算完成
    FinanceCompleted,
    /// 营销推广完成
    MarketingCompleted,
    /// 业务销售完成
    SalesCompleted,
    /// 人事行政完成
    HrAdminCompleted,
    /// IT 完成
    ItCompleted,
    /// 培训完成
    TrainingCompleted,
}

impl BusinessEvent {
    /// 由同事标识获取其完成事件
    ///
    /// # 参数
    /// - `colleague_id`:同事标识(如 PROCUREMENT)
    ///
    /// # 返回
    /// 对应完成事件
    pub fn from_colleague(colleague_id: &str) -> BusinessEvent {
        match colleague_id {
            "PROCUREMENT" => BusinessEvent::ProcurementCompleted,
            "DESIGN" => BusinessEvent::DesignCompleted,
            "PRODUCTION" => BusinessEvent::ProductionCompleted,
            "INSPECTION" => BusinessEvent::InspectionCompleted,
            "PACKAGING" => BusinessEvent::PackagingCompleted,
            "LOGISTICS" => BusinessEvent::LogisticsCompleted,
            "FINANCE" => BusinessEvent::FinanceCompleted,
            "MARKETING" => BusinessEvent::MarketingCompleted,
            "SALES" => BusinessEvent::SalesCompleted,
            "HR_ADMIN" => BusinessEvent::HrAdminCompleted,
            "IT" => BusinessEvent::ItCompleted,
            "TRAINING" => BusinessEvent::TrainingCompleted,
            _ => BusinessEvent::TrainingCompleted,
        }
    }

    /// 获取事件标签(用于日志输出)
    ///
    /// # 返回
    /// 事件标签字符串
    pub fn tag(&self) -> &'static str {
        match self {
            BusinessEvent::ProcurementCompleted => "采购完成",
            BusinessEvent::DesignCompleted => "设计完成",
            BusinessEvent::ProductionCompleted => "生产完成",
            BusinessEvent::InspectionCompleted => "质检完成",
            BusinessEvent::PackagingCompleted => "包装完成",
            BusinessEvent::LogisticsCompleted => "物流完成",
            BusinessEvent::FinanceCompleted => "财务完成",
            BusinessEvent::MarketingCompleted => "营销完成",
            BusinessEvent::SalesCompleted => "销售完成",
            BusinessEvent::HrAdminCompleted => "人事完成",
            BusinessEvent::ItCompleted => "IT完成",
            BusinessEvent::TrainingCompleted => "培训完成",
        }
    }
}

/// 中介者抽象(Mediator trait,线程安全)
///
/// 约束 `Send + Sync`,保证可经 `Arc<dyn BusinessMediator>` 注入到多个同事,
/// 并在多线程高并发环境下共享协调。
pub trait BusinessMediator: Send + Sync {
    /// 注册同事
    ///
    /// # 参数
    /// - `colleague`:同事实例
    fn register(&self, colleague: Arc<dyn Colleague>);

    /// 按标识查找同事
    ///
    /// # 参数
    /// - `colleague_id`:同事标识
    ///
    /// # 返回
    /// 找到的同事实例(可能为空)
    fn colleague(&self, colleague_id: &str) -> Option<Arc<dyn Colleague>>;

    /// 获取全部已注册同事
    ///
    /// # 返回
    /// 全部同事实例
    fn colleagues(&self) -> Vec<Arc<dyn Colleague>>;

    /// 记录某部门的业务产出(供其他部门经中介者查询)
    ///
    /// # 参数
    /// - `colleague_id`:部门标识
    /// - `outcome`:业务产出
    fn record(&self, colleague_id: &str, outcome: ProcessOutcome);

    /// 查询某部门的业务产出(同事经中介者间接获取其他部门产出)
    ///
    /// # 参数
    /// - `colleague_id`:部门标识
    ///
    /// # 返回
    /// 该部门产出(可能为空)
    fn query(&self, colleague_id: &str) -> Option<ProcessOutcome>;

    /// 分发业务事件给相关同事(中介者集中管理部门间交互)
    ///
    /// # 参数
    /// - `sender_id`:发送事件的部门标识
    /// - `event`:业务事件
    /// - `ctx`:命令上下文
    ///
    /// # 返回
    /// - `Ok(())`:分发完成
    /// - `Err(ProcessError)`:分发失败
    fn dispatch(
        &self,
        sender_id: &str,
        event: BusinessEvent,
        ctx: &CommandContext,
    ) -> Result<(), ProcessError>;
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : process_repository.rs
//! 业务流程仓储接口(领域层抽象,由基础设施层实现)
//!
//! 仓储用于持久化每次同事业务执行的记录,供统计与追溯使用。
//! 领域层只定义接口,具体存储(内存 / 数据库)由基础设施层按 DI 注入。

use crate::common::error::ProcessError;
use crate::domain::entities::jewelry::ProcessOutcome;

/// 业务流程执行记录(持久化载体)
#[derive(Debug, Clone)]
pub struct ProcessRecord {
    /// 流程实例编号
    pub instance_id: String,
    /// 流程名称(中文)
    pub process_name: String,
    /// 执行产出
    pub outcome: ProcessOutcome,
    /// 执行时间(格式:YYYY-MM-DD HH:MM:SS)
    pub executed_at: String,
}

/// 业务流程仓储抽象接口(线程安全)
pub trait ProcessRepository: Send + Sync {
    /// 保存业务执行记录
    ///
    /// # 参数
    /// - `record`:执行记录
    ///
    /// # 返回
    /// - `Ok(())`:保存成功
    /// - `Err(ProcessError)`:保存失败
    fn save(&self, record: ProcessRecord) -> Result<(), ProcessError>;

    /// 查询全部执行记录
    ///
    /// # 返回
    /// 全部执行记录
    fn find_all(&self) -> Vec<ProcessRecord>;

    /// 统计成功/失败数量
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn count(&self) -> (usize, usize);
}
rust 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : container.rs
//! 依赖注入容器(组合根 Composition Root)
//!
//! 职责:集中装配(new)全部依赖并暴露访问方法,实现构造器注入。
//! - 统一日志(`Arc<dyn Logger>`)单例
//! - 重试 + 熔断适配器单例(`Arc<RetryCircuitBreaker>`)
//! - 具体中介者(`ConcreteMediator`)单例
//! - 12 个同事(Colleague 子类)注册到中介者
//! - 内存仓储单例
//! - 业务流程应用服务
//!
//! 依赖方向严格单向:presentation → interface → application → domain → common,
//! 基础设施层向上提供实现,由容器完成组装。

use std::sync::Arc;
use std::time::Duration;

use crate::application::colleagues::business_sales::BusinessSalesColleague;
use crate::application::colleagues::design::DesignColleague;
use crate::application::colleagues::finance::FinanceColleague;
use crate::application::colleagues::hr_admin::HrAdminColleague;
use crate::application::colleagues::inspection::InspectionColleague;
use crate::application::colleagues::it::ItColleague;
use crate::application::colleagues::logistics::LogisticsColleague;
use crate::application::colleagues::marketing::MarketingColleague;
use crate::application::colleagues::packaging::PackagingColleague;
use crate::application::colleagues::procurement::ProcurementColleague;
use crate::application::colleagues::production::ProductionColleague;
use crate::application::colleagues::training::TrainingColleague;
use crate::application::mediator::concrete_mediator::ConcreteMediator;
use crate::application::services::process_service::ProcessService;
use crate::common::logging::Logger;
use crate::common::resilience::retry_circuit_breaker::RetryCircuitBreaker;
use crate::domain::mediator::colleague::Colleague;
use crate::domain::mediator::mediator::BusinessMediator;
use crate::infrastructure::logging::file_logger::FileLogger;
use crate::infrastructure::persistence::memory_process_repository::MemoryProcessRepository;

/// 依赖注入容器(组合根)
pub struct ServiceContainer {
    /// 统一日志(单例)
    logger: Arc<dyn Logger>,
    /// 重试 + 熔断适配器(单例,预留给扩展组件复用)
    #[allow(dead_code)]
    resilience: Arc<RetryCircuitBreaker>,
    /// 具体中介者(单例,由应用服务内部使用;此处持有以便装配与扩展)
    #[allow(dead_code)]
    mediator: Arc<ConcreteMediator>,
    /// 内存仓储(单例,预留给扩展组件复用)
    #[allow(dead_code)]
    repository: Arc<MemoryProcessRepository>,
    /// 业务流程应用服务
    service: Arc<ProcessService>,
}

impl ServiceContainer {
    /// 构建依赖注入容器(组合根,统一装配全部服务与同事)
    ///
    /// # 返回
    /// 已装配完成的容器实例
    pub fn new() -> Self {
        // 1. 基础设施依赖(单例)
        let logger: Arc<dyn Logger> = Arc::new(FileLogger::new("./Logs"));
        // 重试 2 次、连续失败 3 次熔断、冷却 5 秒
        let resilience = Arc::new(RetryCircuitBreaker::new(2, 3, Duration::from_secs(5)));
        let repository = Arc::new(MemoryProcessRepository::new());

        // 2. 创建具体中介者(注入统一日志 + 重试熔断适配器)
        let mediator = Arc::new(ConcreteMediator::new(logger.clone(), resilience.clone()));

        // 3. 创建 12 个同事并注入中介者引用
        let colleagues: Vec<Arc<dyn Colleague>> = vec![
            Arc::new(ProcurementColleague::new(logger.clone())),
            Arc::new(DesignColleague::new(logger.clone())),
            Arc::new(ProductionColleague::new(logger.clone())),
            Arc::new(InspectionColleague::new(logger.clone())),
            Arc::new(PackagingColleague::new(logger.clone())),
            Arc::new(LogisticsColleague::new(logger.clone())),
            Arc::new(FinanceColleague::new(logger.clone())),
            Arc::new(MarketingColleague::new(logger.clone())),
            Arc::new(BusinessSalesColleague::new(logger.clone())),
            Arc::new(HrAdminColleague::new(logger.clone())),
            Arc::new(ItColleague::new(logger.clone())),
            Arc::new(TrainingColleague::new(logger.clone())),
        ];
        // 为每个同事注入中介者引用(构造器注入 + 中介者注册)
        for colleague in &colleagues {
            colleague.set_mediator(mediator.clone());
            mediator.register(colleague.clone());
        }

        // 4. 应用层服务(构造器注入)
        let service = Arc::new(ProcessService::new(
            mediator.clone(),
            repository.clone(),
            logger.clone(),
        ));

        Self {
            logger,
            resilience,
            mediator,
            repository,
            service,
        }
    }

    /// 获取业务流程应用服务
    ///
    /// # 返回
    /// 应用服务(`Arc` 共享)
    pub fn service(&self) -> Arc<ProcessService> {
        self.service.clone()
    }

    /// 获取具体中介者
    ///
    /// # 返回
    /// 中介者(`Arc` 共享)
    #[allow(dead_code)]
    pub fn mediator(&self) -> Arc<ConcreteMediator> {
        self.mediator.clone()
    }

    /// 获取统一日志对象
    ///
    /// # 返回
    /// 统一日志(`Arc<dyn Logger>`)
    pub fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : file_logger.rs
//! 文件日志实现(按日期分文件夹、按日志等级分文件)
//!
//! 目录结构(示例,日期为当日):
//! ```text
//! Logs/
//!   2026-07-06/
//!     app-info.log
//!     app-error.log
//!     app-debug.log
//!     app-warn.log
//! ```
//!
//! 设计要点:
//! - **线程安全 / 高并发**:每个日志等级使用独立的 `Mutex<BufWriter<File>>`,
//!   同一等级写操作串行化,不同等级互不阻塞;可被 `Arc` 共享到多线程。
//! - **日期滚动**:每次写入检测日期目录,跨天自动切换到新的日期文件夹。
//! - **控制台与文件一致**:统一格式化 `[时间] [等级] 消息`,
//!   同时输出到控制台(stdout/stderr)与对应文件。

use std::fs::{self, File, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
use std::sync::Mutex;

use crate::common::logging::{LogLevel, Logger};

/// 单日志等级的文件写入句柄(受互斥锁保护)
struct LevelWriter {
    /// 当前打开的缓冲写入器
    writer: Option<std::io::BufWriter<File>>,
    /// 该句柄对应的日期文件夹(用于跨天滚动判断)
    opened_date: String,
}

impl LevelWriter {
    /// 创建空的等级写入器
    fn new() -> Self {
        Self {
            writer: None,
            opened_date: String::new(),
        }
    }
}

/// 文件日志实现(线程安全、支持高并发写入)
pub struct FileLogger {
    /// 日志根目录(默认 ./Logs)
    base_dir: PathBuf,
    /// 调试日志写入器
    debug_writer: Mutex<LevelWriter>,
    /// 信息日志写入器
    info_writer: Mutex<LevelWriter>,
    /// 警告日志写入器
    warn_writer: Mutex<LevelWriter>,
    /// 错误日志写入器
    error_writer: Mutex<LevelWriter>,
}

impl FileLogger {
    /// 创建文件日志
    ///
    /// # 参数
    /// - `base_dir`:日志根目录(如 "./Logs")
    ///
    /// # 返回
    /// 文件日志实例
    pub fn new(base_dir: &str) -> Self {
        Self {
            base_dir: PathBuf::from(base_dir),
            debug_writer: Mutex::new(LevelWriter::new()),
            info_writer: Mutex::new(LevelWriter::new()),
            warn_writer: Mutex::new(LevelWriter::new()),
            error_writer: Mutex::new(LevelWriter::new()),
        }
    }

    /// 获取当前日期文件夹名(如 2026-07-06)
    ///
    /// # 返回
    /// 日期字符串
    fn date_folder(&self) -> String {
        chrono::Local::now().format("%Y-%m-%d").to_string()
    }

    /// 确保日期目录存在并返回目录路径
    ///
    /// # 参数
    /// - `date_folder`:日期文件夹名
    ///
    /// # 返回
    /// 日期目录路径
    fn ensure_dir(&self, date_folder: &str) -> PathBuf {
        let dir = self.base_dir.join(date_folder);
        let _ = fs::create_dir_all(&dir);
        dir
    }

    /// 以追加模式打开指定等级日志文件(返回缓冲写入器)
    ///
    /// # 参数
    /// - `level`:日志等级
    ///
    /// # 返回
    /// 缓冲写入器
    fn open_writer(&self, level: LogLevel) -> std::io::BufWriter<File> {
        let date_folder = self.date_folder();
        let dir = self.ensure_dir(&date_folder);
        let path = dir.join(level.file_name());
        let file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(&path)
            .unwrap_or_else(|e| panic!("无法打开日志文件 {}:{}", path.display(), e));
        std::io::BufWriter::new(file)
    }

    /// 写入日志(统一格式;控制台与文件同时输出)
    ///
    /// # 参数
    /// - `level`:日志等级
    /// - `message`:日志消息
    fn write(&self, level: LogLevel, message: &str) {
        let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
        let line = format!("[{}] [{}] {}", timestamp, level.tag(), message);

        // ① 输出到控制台(错误走 stderr,其余走 stdout)
        match level {
            LogLevel::Error => eprintln!("{}", line),
            _ => println!("{}", line),
        }

        // ② 输出到文件(按等级互斥锁串行化,保证线程安全)
        let target = match level {
            LogLevel::Debug => &self.debug_writer,
            LogLevel::Info => &self.info_writer,
            LogLevel::Warn => &self.warn_writer,
            LogLevel::Error => &self.error_writer,
        };
        let mut guard = target.lock().unwrap();
        let date_folder = self.date_folder();
        // 跨天或未打开 → 重新打开文件(实现按日期滚动)
        if guard.opened_date != date_folder || guard.writer.is_none() {
            guard.opened_date = date_folder.clone();
            guard.writer = Some(self.open_writer(level));
        }
        if let Some(writer) = guard.writer.as_mut() {
            let _ = writeln!(writer, "{}", line);
            let _ = writer.flush();
        }
    }
}

/// 实现统一日志接口(`Arc<dyn Logger>` 可注入各组件)
impl Logger for FileLogger {
    /// 输出调试日志
    fn debug(&self, message: &str) {
        self.write(LogLevel::Debug, message);
    }

    /// 输出信息日志
    fn info(&self, message: &str) {
        self.write(LogLevel::Info, message);
    }

    /// 输出警告日志
    fn warn(&self, message: &str) {
        self.write(LogLevel::Warn, message);
    }

    /// 输出错误日志
    fn error(&self, message: &str) {
        self.write(LogLevel::Error, message);
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : memory_process_repository.rs
//! 内存仓储实现(线程安全)
//!
//! 以 `Mutex<HashMap>` 实现 `ProcessRepository` 接口,供业务执行记录
//! 的保存、查询与统计使用。演示场景使用内存存储;生产环境可替换为数据库实现。

use std::collections::HashMap;
use std::sync::Mutex;

use crate::common::error::ProcessError;
use crate::domain::repository::process_repository::{ProcessRecord, ProcessRepository};

/// 内存仓储实现
pub struct MemoryProcessRepository {
    /// 内部存储(以流程实例编号为键,受互斥锁保护,保证并发安全)
    store: Mutex<HashMap<String, ProcessRecord>>,
}

impl MemoryProcessRepository {
    /// 创建内存仓储
    ///
    /// # 返回
    /// 内存仓储实例
    pub fn new() -> Self {
        Self {
            store: Mutex::new(HashMap::new()),
        }
    }
}

impl ProcessRepository for MemoryProcessRepository {
    /// 保存业务执行记录
    ///
    /// # 参数
    /// - `record`:执行记录
    ///
    /// # 返回
    /// - `Ok(())`:保存成功
    /// - `Err(ProcessError)`:保存失败
    fn save(&self, record: ProcessRecord) -> Result<(), ProcessError> {
        let mut store = self.store.lock().unwrap();
        store.insert(record.instance_id.clone(), record);
        Ok(())
    }

    /// 查询全部执行记录
    ///
    /// # 返回
    /// 全部执行记录
    fn find_all(&self) -> Vec<ProcessRecord> {
        let store = self.store.lock().unwrap();
        store.values().cloned().collect()
    }

    /// 统计成功/失败数量
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn count(&self) -> (usize, usize) {
        let store = self.store.lock().unwrap();
        let total = store.values().len();
        let success = store.values().filter(|r| r.outcome.success).count();
        (success, total - success)
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : contracts.rs
//! 对外交互契约(Contracts)
//!
//! 定义外部调用方与系统交互的统一契约结构(业务信封),
//! 承载「部门标识 + 执行请求」,供表现层/外部系统装配。

use crate::domain::dtos::process_dtos::ProcessRequestDto;

/// 业务信封(外部提交一个部门业务的载体)
#[derive(Debug, Clone)]
pub struct BusinessEnvelope {
    /// 部门/同事标识(如 PROCUREMENT)
    pub colleague_id: String,
    /// 执行请求 DTO
    pub request: ProcessRequestDto,
}

impl BusinessEnvelope {
    /// 创建业务信封
    ///
    /// # 参数
    /// - `colleague_id`:部门/同事标识
    /// - `request`:执行请求
    ///
    /// # 返回
    /// 业务信封
    pub fn new(colleague_id: &str, request: ProcessRequestDto) -> Self {
        Self {
            colleague_id: colleague_id.to_string(),
            request,
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : ports.rs
//! 对外 API 端口契约(Ports)
//!
//! 定义表现层(presentation)与外部调用方可消费的应用端口,
//! 将「应用能力」与「具体实现」解耦;具体实现由表现层/应用层提供。

use crate::common::error::ProcessError;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::repository::process_repository::ProcessRecord;

/// 对外应用 API 端口契约(线程安全)
///
/// 表现层实现该端口并向外部暴露;外部仅依赖本端口,不依赖具体实现。
pub trait BusinessApiPort: Send + Sync {
    /// 派发并执行单个部门业务(经中介者)
    ///
    /// # 参数
    /// - `colleague_id`:同事标识(如 PROCUREMENT)
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:执行响应
    /// - `Err(ProcessError)`:执行失败
    fn dispatch(
        &self,
        colleague_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError>;

    /// 获取业务执行统计(成功数量,失败数量)
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn statistics(&self) -> (usize, usize);

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    ///
    /// # 返回
    /// 全部执行记录
    fn records(&self) -> Vec<ProcessRecord>;
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : mod.rs
//! 应用控制器(表现层,控制台入口)
//!
//! 职责:
//! - 从组合根(DI 容器)获取应用服务与统一日志
//! - 实现 `interface::ports::BusinessApiPort` 端口契约(对外 API)
//! - 创建贯穿全流程的珠宝实体,驱动中介者顺序协调与并发调度演示
//! - 输出调度统计与业务执行结果汇总
//!
//! 依赖方向:presentation → interface → application → domain → common,
//! 符合严格分层(六层结构)。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::Jewelry;
use crate::domain::repository::process_repository::ProcessRecord;
use crate::infrastructure::di::container::ServiceContainer;
use crate::interface::contracts::BusinessEnvelope;
use crate::interface::ports::BusinessApiPort;

/// 应用控制器(控制台表现层,实现对外端口契约)
pub struct ApplicationController {
    /// 依赖注入容器(组合根)
    container: Arc<ServiceContainer>,
    /// 统一日志对象
    logger: Arc<dyn Logger>,
}

impl ApplicationController {
    /// 创建应用控制器
    ///
    /// # 参数
    /// - `container`:依赖注入容器
    ///
    /// # 返回
    /// 应用控制器实例
    pub fn new(container: Arc<ServiceContainer>) -> Self {
        let logger = container.logger();
        Self { container, logger }
    }

    /// 启动珠宝行业全程业务流程(中介者模式)演示
    ///
    /// 流程:
    /// ① 打印标题与配置
    /// ② 创建珠宝实体
    /// ③ 中介者顺序协调全部 12 个部门(含事件路由)
    /// ④ 输出执行统计与记录明细
    /// ⑤ 中介者并发调度全部部门(高并发演示)
    /// ⑥ 通过端口契约派发单部门业务
    pub fn run(&self) {
        // ① 标题与运行说明
        self.logger.info("================================================================");
        self.logger.info("   中介者模式 Mediator Pattern");
        self.logger.info("   珠宝行业企业级全程业务流程(DDD 六层分层)");
        self.logger.info("   业务:原料采购核验 · 设计制图 · 加工生产 · 质检 · 包装 · 物流");
        self.logger.info("        · 财务 · 营销推广 · 业务销售 · 人事行政 · IT · 培训");
        self.logger.info("   日志:Logs/<日期>/app-{info,error,debug,warn}.log(按日期/等级分文件)");
        self.logger.info("================================================================");

        // ② 创建贯穿全流程的珠宝实体
        let jewelry = Jewelry::new("六福传承金镯", "黄金", 35.68, 26800.0);
        self.logger.info(&format!(
            "创建珠宝实体:{},材质={},重量={} 克,零售价={} 元",
            jewelry.name, jewelry.material, jewelry.weight_grams, jewelry.price
        ));

        // ③ 中介者顺序协调全部 12 个部门(含事件路由,体现部门经中介者协同)
        let request = ProcessRequestDto::new("ALL", jewelry.clone(), "调度中心", "Mediator");
        self.container.service().coordinate(request);
        self.logger.info("================================================================");

        // ④ 输出执行统计(读取内存仓储)
        self.print_summary();

        // ⑤ 中介者并发调度全部部门(高并发演示)
        self.logger.info("【高并发演示】中介者并发调度全部部门......");
        let concurrent_request = ProcessRequestDto::new("ALL", jewelry.clone(), "调度中心", "Concurrent");
        self.container.service().coordinate_concurrent(concurrent_request);
        self.print_summary();

        // ⑥ 通过端口契约派发单部门业务(BusinessEnvelope + dispatch)
        let envelope = BusinessEnvelope::new(
            "TRAINING",
            ProcessRequestDto::new("TRAINING", jewelry, "培训部", "PortTest"),
        );
        match self.dispatch(&envelope.colleague_id, envelope.request) {
            Ok(resp) => self.logger.info(&format!(
                "端口契约派发单部门业务成功:{} / {}",
                resp.process_name, resp.message
            )),
            Err(err) => self.logger.warn(&format!("端口契约派发单部门业务失败:{}", err)),
        }

        // ⑦ 输出已注册同事(部门)清单
        let colleagues = self.container.service().colleagues();
        self.logger
            .info(&format!("已注册同事(部门)数:{}", colleagues.len()));
        for colleague in colleagues {
            self.logger.info(&format!(
                "  - [{}] {} / {}",
                colleague.colleague_id(),
                colleague.department(),
                colleague.colleague_name()
            ));
        }
        self.logger.info("================================================================");
    }

    /// 输出执行统计与记录明细(基于仓储数据)
    fn print_summary(&self) {
        let (success, failure) = self.statistics();
        self.logger.info(&format!(
            "业务调度汇总:成功 {} 项,失败 {} 项(详见当日日志目录)",
            success, failure
        ));
        let records = self.records();
        self.logger.info(&format!("执行记录明细(共 {} 条):", records.len()));
        for record in records {
            let flag = if record.outcome.success { "成功" } else { "失败" };
            self.logger.info(&format!(
                "  - {} | {} | 状态:{} | 时间:{}",
                record.instance_id, record.process_name, flag, record.executed_at
            ));
        }
    }
}

/// 实现对外 API 端口契约(interface 层定义)
impl BusinessApiPort for ApplicationController {
    /// 派发并执行单部门业务(经中介者)
    fn dispatch(
        &self,
        colleague_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError> {
        self.container.service().execute_one(colleague_id, request)
    }

    /// 获取业务执行统计(成功数量,失败数量)
    fn statistics(&self) -> (usize, usize) {
        self.container.service().statistics()
    }

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    fn records(&self) -> Vec<ProcessRecord> {
        self.container.service().records()
    }
}
rust 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : business_sales.rs
//! 业务销售同事(中介者模式 Colleague 子类)
//!
//! 封装业务部业务:促成订单成交、定金与尾款收取。
//! 覆盖 `on_event`:收到「物流完成」「财务完成」「营销完成」事件时确认交付条件,
//! 体现销售环节经中介者对多部门的协同依赖。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 业务销售同事
pub struct BusinessSalesColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl BusinessSalesColleague {
    /// 创建业务销售同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for BusinessSalesColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "SALES"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "业务销售"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "业务部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:促成订单并收定金
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【业务销售】客户下单购买 {},售价 {} 元,收取 30% 定金",
            jewelry.name, jewelry.price
        ));
        self.logger()
            .info(&format!("【业务销售】生成销售订单并锁定库存"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "订单成交,定金已收取,待尾款结清后交付",
        ))
    }

    /// 响应中介者转发的事件:确认交付条件就绪
    fn on_event(&self, event: BusinessEvent, _ctx: &CommandContext) -> Result<(), ProcessError> {
        match event {
            BusinessEvent::LogisticsCompleted => {
                self.logger()
                    .info(&format!("【业务销售】经中介者确认物流已发货,可安排尾款结清交付"));
            }
            BusinessEvent::FinanceCompleted => {
                self.logger()
                    .info(&format!("【业务销售】经中介者确认财务定价完成,可推进成交"));
            }
            BusinessEvent::MarketingCompleted => {
                self.logger()
                    .info(&format!("【业务销售】经中介者确认营销投放完成,可承接客户咨询"));
            }
            _ => {}
        }
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : design.rs
//! 设计制图同事(中介者模式 Colleague 子类)
//!
//! 封装设计部业务:根据原料进行款式设计与 CAD 制图。
//! 覆盖 `on_event`:收到「采购完成」事件时确认原料已就绪,体现经中介者协同。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 设计制图同事
pub struct DesignColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl DesignColleague {
    /// 创建设计制图同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for DesignColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "DESIGN"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "设计制图"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "设计部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:款式设计与 CAD 制图
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【设计制图】为 {} 设计 3D 款式并输出 CAD 图纸",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【设计制图】完成建模、排石方案与工艺说明"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "设计图完成并通过初稿,图纸编号已归档",
        ))
    }

    /// 响应中介者转发的事件:采购完成 → 确认原料就绪
    fn on_event(&self, event: BusinessEvent, _ctx: &CommandContext) -> Result<(), ProcessError> {
        if event == BusinessEvent::ProcurementCompleted {
            // 经中介者查询采购部门产出(体现同事经中介者间接通信)
            let procurement = self
                .mediator()
                .and_then(|m| m.query("PROCUREMENT"));
            self.logger().info(&format!(
                "【设计制图】经中介者确认采购完成,原料产出:{}",
                procurement
                    .map(|o| o.summary)
                    .unwrap_or_else(|| "(暂无产出记录)".to_string())
            ));
        }
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : finance.rs
//! 财务同事(中介者模式 Colleague 子类)
//!
//! 封装财务部业务:成本归集、税费核算与凭证入账。
//! 覆盖 `on_event`:收到「采购完成」/「物流完成」事件时确认成本与回款依据。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 财务同事
pub struct FinanceColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl FinanceColleague {
    /// 创建财务同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for FinanceColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "FINANCE"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "财务"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "财务部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:成本归集与凭证入账
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        let cost = jewelry.weight_grams * 480.0; // 模拟按克重折算采购成本
        self.logger().info(&format!(
            "【财务】核算 {} 采购成本:{:.2} 元,加工费 1200 元,税费 13%",
            jewelry.name, cost
        ));
        self.logger()
            .info(&format!("【财务】生成成本核算单并完成记账凭证入账"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "财务核算完成,成本与税负已入账,凭证归档",
        ))
    }

    /// 响应中介者转发的事件:采购完成 → 确认成本依据
    fn on_event(&self, event: BusinessEvent, _ctx: &CommandContext) -> Result<(), ProcessError> {
        if event == BusinessEvent::ProcurementCompleted {
            let procurement = self.mediator().and_then(|m| m.query("PROCUREMENT"));
            self.logger().info(&format!(
                "【财务】经中介者确认采购完成,成本依据:{}",
                procurement
                    .map(|o| o.summary)
                    .unwrap_or_else(|| "(暂无产出记录)".to_string())
            ));
        }
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : hr_admin.rs
//! 人事行政同事(中介者模式 Colleague 子类)
//!
//! 封装人事行政部业务:人员排班、考勤与行政资源保障。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 人事行政同事
pub struct HrAdminColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl HrAdminColleague {
    /// 创建人事行政同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for HrAdminColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "HR_ADMIN"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "人事行政"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "人事行政部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:排班与行政保障
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【人事行政】为 {} 生产项目排班技师与质检人员,并保障工位与物料行政资源",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【人事行政】考勤与加班工时已登记,行政资源调配完成"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "人员排班与行政保障完成,项目人力齐备",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : inspection.rs
//! 质检同事(中介者模式 Colleague 子类)
//!
//! 封装质检部业务:对成品进行重量、成色、工艺、镶嵌牢固度检验。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 质检同事
pub struct InspectionColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl InspectionColleague {
    /// 创建质检同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for InspectionColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "INSPECTION"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "质检"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "质检部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:成品质量检验
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【质检】对 {} 进行重量复称、成色检测、工艺与镶嵌牢固度检验",
            jewelry.name
        ));
        if jewelry.weight_grams <= 0.0 {
            return Err(ProcessError::new(
                "WEIGHT_INVALID",
                "质检发现成品克重异常,判定不合格",
            ));
        }
        self.logger().info(&format!(
            "【质检】克重 {} 克复核通过,出具质检合格证书",
            jewelry.weight_grams
        ));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "质检合格,出具鉴定证书,可进入包装",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : it.rs
//! IT 同事(中介者模式 Colleague 子类)
//!
//! 封装 IT 部业务:珠宝 ERP/进销存系统数据同步与系统保障。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// IT 同事
pub struct ItColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl ItColleague {
    /// 创建 IT 同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for ItColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "IT"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "IT"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "IT部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:系统数据同步与运行保障
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【IT】为 {} 在 ERP 系统同步订单、库存与物流状态,并监控系统可用性",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【IT】数据库事务提交成功,系统健康检查通过"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "系统数据同步完成,业务运行保障正常",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : logistics.rs
//! 物流发货同事(中介者模式 Colleague 子类)
//!
//! 封装物流部业务:出库、配送单生成与快递发出。
//! 该同事 `perform` 首次调用会瞬时失败(模拟外部物流系统不可用),
//! 经中介者的「重试 + 熔断」适配器自动重试后成功,演示弹性保护实际效果。

use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 外部物流系统调用计数(模拟前两次瞬时失败,第三次成功)
static LOGISTICS_CALL_COUNT: AtomicU32 = AtomicU32::new(0);

/// 物流发货同事
pub struct LogisticsColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl LogisticsColleague {
    /// 创建物流发货同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for LogisticsColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "LOGISTICS"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "物流"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "物流部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:物流发货(模拟外部系统瞬时失败 → 触发重试)
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        // 模拟外部物流系统:前两次调用瞬时不可用(触发重试),第三次成功
        let call = LOGISTICS_CALL_COUNT.fetch_add(1, Ordering::SeqCst);
        if call < 2 {
            self.logger().warn(&format!(
                "【物流】外部物流系统暂时不可用(第 {} 次尝试)",
                call + 1
            ));
            return Err(ProcessError::new(
                "LOGISTICS_TEMP_UNAVAILABLE",
                "物流接口超时,等待重试",
            ));
        }
        self.logger().info(&format!(
            "【物流】为 {} 生成配送单并安排顺丰/京东发货,运单已创建",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【物流】出库完成,物流节点进入在途状态"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "已发货,运单号生成,商品进入在途运输",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : marketing.rs
//! 营销推广同事(中介者模式 Colleague 子类)
//!
//! 封装营销部业务:制定并投放新品推广方案。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 营销推广同事
pub struct MarketingColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl MarketingColleague {
    /// 创建营销推广同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for MarketingColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "MARKETING"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "营销推广"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "营销部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:制定并投放推广方案
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【营销推广】为 {} 制定新品推广方案:小红书种草 + 抖音直播 + 门店陈列",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【营销推广】推广素材已投放,曝光与转化数据开始回收"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "营销推广方案已投放,进入数据观测期",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : packaging.rs
//! 包装同事(中介者模式 Colleague 子类)
//!
//! 封装包装部业务:礼盒包装、贴标、防伪封装。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 包装同事
pub struct PackagingColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl PackagingColleague {
    /// 创建包装同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for PackagingColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "PACKAGING"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "包装"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "包装部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:礼盒包装与防伪封装
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【包装】对 {} 进行礼盒包装、吊牌与防伪标签封装",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【包装】生成唯一防伪码并录入系统"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "包装完成,防伪码已生成,可交付物流发货",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : procurement.rs
//! 原料采购核验同事(中介者模式 Colleague 子类)
//!
//! 封装采购部业务:核验材质并采购原料入库。
//! 覆盖 `on_event`:无额外协同响应(保持默认)。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;

/// 原料采购核验同事
pub struct ProcurementColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl ProcurementColleague {
    /// 创建原料采购核验同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for ProcurementColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "PROCUREMENT"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "原料采购核验"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "采购部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:原料采购与第三方核验
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        let supported = matches!(
            jewelry.material.as_str(),
            "黄金" | "铂金" | "钻石" | "K金" | "银"
        );
        if !supported {
            return Err(ProcessError::new(
                "INVALID_MATERIAL",
                &format!("原料材质 {} 不在采购目录中", jewelry.material),
            ));
        }
        self.logger().info(&format!(
            "【原料采购核验】向供应商采购原料:{},材质 {},重量 {} 克",
            jewelry.name, jewelry.material, jewelry.weight_grams
        ));
        self.logger()
            .info(&format!("【原料采购核验】第三方质检机构核验通过(成色/克重)"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "原料采购完成,成色与克重符合标准,已入库待设计",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : production.rs
//! 加工生产同事(中介者模式 Colleague 子类)
//!
//! 封装生产部业务:依据设计图进行浇铸、镶嵌、打磨。
//! 覆盖 `on_event`:收到「设计完成」事件时确认图纸就绪,体现经中介者协同。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 加工生产同事
pub struct ProductionColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl ProductionColleague {
    /// 创建加工生产同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for ProductionColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "PRODUCTION"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "加工生产"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "生产部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:加工生产
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        if ctx.jewelry().name.trim().is_empty() {
            return Err(ProcessError::new(
                "PRODUCT_NAME_EMPTY",
                "珠宝品名为空,无法进入加工生产",
            ));
        }
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【加工生产】对 {} 执行浇铸 → 镶嵌 → 打磨工序",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【加工生产】成品初步成形,待质检部门检验"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "加工完成,成品初检合格,等待质检",
        ))
    }

    /// 响应中介者转发的事件:设计完成 → 确认图纸就绪
    fn on_event(&self, event: BusinessEvent, _ctx: &CommandContext) -> Result<(), ProcessError> {
        if event == BusinessEvent::DesignCompleted {
            let design = self.mediator().and_then(|m| m.query("DESIGN"));
            self.logger().info(&format!(
                "【加工生产】经中介者确认设计完成,图纸产出:{}",
                design
                    .map(|o| o.summary)
                    .unwrap_or_else(|| "(暂无产出记录)".to_string())
            ));
        }
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : training.rs
//! 培训同事(中介者模式 Colleague 子类)
//!
//! 封装培训部业务:珠宝知识、工艺与销售话术培训及考核。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::{Colleague, ColleagueSupport};
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::BusinessMediator;
/// 培训同事
pub struct TrainingColleague {
    /// 同事共享支持(日志 + 中介者引用)
    support: ColleagueSupport,
}

impl TrainingColleague {
    /// 创建培训同事
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    ///
    /// # 返回
    /// 同事实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self {
            support: ColleagueSupport::new(logger),
        }
    }
}

impl Colleague for TrainingColleague {
    /// 同事标识
    fn colleague_id(&self) -> &'static str {
        "TRAINING"
    }

    /// 同事名称
    fn colleague_name(&self) -> &'static str {
        "培训"
    }

    /// 所属部门
    fn department(&self) -> &'static str {
        "培训部"
    }

    /// 获取统一日志对象
    fn logger(&self) -> &Arc<dyn Logger> {
        self.support.logger()
    }

    /// 注入中介者
    fn set_mediator(&self, mediator: Arc<dyn BusinessMediator>) {
        self.support.set_mediator(mediator);
    }

    /// 获取注入的中介者
    fn mediator(&self) -> Option<Arc<dyn BusinessMediator>> {
        self.support.mediator()
    }

    /// 执行业务:组织培训与考核
    fn perform(&self, ctx: &CommandContext) -> Result<ProcessOutcome, ProcessError> {
        let jewelry = ctx.jewelry();
        self.logger().info(&format!(
            "【培训】针对 {} 开展材质工艺、质检标准与销售话术专项培训",
            jewelry.name
        ));
        self.logger()
            .info(&format!("【培训】完成培训考核,学员成绩合格并归档"));
        Ok(ProcessOutcome::success(
            &ctx.instance_id,
            "培训完成,人员能力达标,考核记录已归档",
        ))
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : concrete_mediator.rs
//! 具体中介者实现(ConcreteMediator)
//!
//! 实现 `BusinessMediator` 契约,集中管理:
//! - 同事注册表(`Mutex<Vec<Arc<dyn Colleague>>>`,线程安全)
//! - 部门产出登记表(`Mutex<HashMap<colleague_id, ProcessOutcome>>`)
//! - 业务事件路由(dispatch:把某部门完成的事件转发给相关部门)
//! - 协调执行入口 `coordinate`:按珠宝业务链依次协调各部门,经「重试 + 熔断」保护
//! - 并发调度入口 `coordinate_concurrent`:多线程高并发执行全部同事
//!
//! 中介者是部门间交互的唯一通道,体现「同事不直接引用、经中介者集中解耦」。

use std::collections::HashMap;
use std::sync::Arc;
use std::sync::Mutex;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::common::resilience::retry_circuit_breaker::RetryCircuitBreaker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::{next_sequence, ProcessOutcome};
use crate::domain::mediator::colleague::Colleague;
use crate::domain::mediator::command_ctx::CommandContext;
use crate::domain::mediator::mediator::{BusinessEvent, BusinessMediator};

/// 业务事件 → 接收部门映射(中介者决定事件路由)
fn receivers_for(event: BusinessEvent) -> &'static [&'static str] {
    match event {
        // 采购完成 → 通知 设计 / 财务 / 人事
        BusinessEvent::ProcurementCompleted => &["DESIGN", "FINANCE", "HR_ADMIN"],
        // 设计完成 → 通知 生产 / 营销
        BusinessEvent::DesignCompleted => &["PRODUCTION", "MARKETING"],
        // 生产完成 → 通知 质检
        BusinessEvent::ProductionCompleted => &["INSPECTION"],
        // 质检完成 → 通知 包装 / 财务
        BusinessEvent::InspectionCompleted => &["PACKAGING", "FINANCE"],
        // 包装完成 → 通知 物流
        BusinessEvent::PackagingCompleted => &["LOGISTICS"],
        // 物流完成 → 通知 财务 / IT / 业务
        BusinessEvent::LogisticsCompleted => &["FINANCE", "IT", "SALES"],
        // 财务完成 → 通知 业务
        BusinessEvent::FinanceCompleted => &["SALES"],
        // 营销完成 → 通知 业务
        BusinessEvent::MarketingCompleted => &["SALES"],
        // 业务完成 → 通知 人事
        BusinessEvent::SalesCompleted => &["HR_ADMIN"],
        // 人事完成 → 通知 培训
        BusinessEvent::HrAdminCompleted => &["TRAINING"],
        // IT / 培训 完成 → 无后续依赖
        BusinessEvent::ItCompleted | BusinessEvent::TrainingCompleted => &[],
    }
}

/// 具体中介者(线程安全)
pub struct ConcreteMediator {
    /// 统一日志对象(依赖注入)
    logger: Arc<dyn Logger>,
    /// 重试 + 熔断适配器(依赖注入)
    resilience: Arc<RetryCircuitBreaker>,
    /// 同事注册表(受互斥锁保护)
    colleagues: Mutex<Vec<Arc<dyn Colleague>>>,
    /// 部门产出登记表(受互斥锁保护)
    outputs: Mutex<HashMap<String, ProcessOutcome>>,
}

impl ConcreteMediator {
    /// 创建具体中介者
    ///
    /// # 参数
    /// - `logger`:统一日志对象
    /// - `resilience`:重试 + 熔断适配器
    ///
    /// # 返回
    /// 中介者实例
    pub fn new(logger: Arc<dyn Logger>, resilience: Arc<RetryCircuitBreaker>) -> Self {
        Self {
            logger,
            resilience,
            colleagues: Mutex::new(Vec::new()),
            outputs: Mutex::new(HashMap::new()),
        }
    }

    /// 按珠宝业务链协调全部部门(体现中介者集中管理流程顺序与事件路由)
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各部门执行响应集合
    pub fn coordinate(&self, request: ProcessRequestDto) -> Vec<ProcessResponseDto> {
        self.logger.info("========== 中介者开始顺序协调珠宝全流程 ==========");
        // 珠宝业务链顺序
        let order = [
            "PROCUREMENT",
            "DESIGN",
            "PRODUCTION",
            "INSPECTION",
            "PACKAGING",
            "LOGISTICS",
            "FINANCE",
            "MARKETING",
            "SALES",
            "HR_ADMIN",
            "IT",
            "TRAINING",
        ];
        let mut responses = Vec::new();
        for colleague_id in order {
            if let Some(colleague) = self.colleague(colleague_id) {
                let instance_id = format!("{}-{:06}", colleague_id, next_sequence());
                let ctx = CommandContext::new(&instance_id, request.clone());
                responses.push(self.execute_colleague(&colleague, &ctx));
            }
        }
        self.logger.info("========== 中介者顺序协调完成 ==========");
        responses
    }

    /// 并发调度全部同事(多线程高并发演示,每个同事独立线程)
    ///
    /// 通过 `self: &Arc<Self>` 在闭包中克隆共享同一中介者实例,
    /// 保证同事注册表与产出登记表在多线程下一致。
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各部门执行响应集合
    pub fn coordinate_concurrent(
        self: &Arc<Self>,
        request: ProcessRequestDto,
    ) -> Vec<ProcessResponseDto> {
        self.logger.info("========== 中介者开始并发调度全部同事 ==========");
        let mut handles = Vec::new();
        for colleague in self.colleagues() {
            let mediator = self.clone();
            let request = request.clone();
            let handle = std::thread::spawn(move || {
                let instance_id = format!("{}-{:06}", colleague.colleague_id(), next_sequence());
                let ctx = CommandContext::new(&instance_id, request);
                mediator.execute_colleague(&colleague, &ctx)
            });
            handles.push(handle);
        }
        let mut responses = Vec::new();
        for handle in handles {
            responses.push(handle.join().unwrap());
        }
        self.logger.info("========== 中介者并发调度完成 ==========");
        responses
    }

    /// 经「重试 + 熔断」执行单个同事业务,并登记产出、广播完成事件
    ///
    /// # 参数
    /// - `colleague`:同事
    /// - `ctx`:命令上下文
    ///
    /// # 返回
    /// 执行响应 DTO
    pub fn execute_colleague(
        &self,
        colleague: &Arc<dyn Colleague>,
        ctx: &CommandContext,
    ) -> ProcessResponseDto {
        self.logger.info(&format!(
            "中介者协调执行部门「{}」实例={}",
            colleague.colleague_name(),
            ctx.instance_id
        ));
        match self.resilience.execute(|| colleague.perform(ctx)) {
            Ok(outcome) => {
                // 登记部门产出(供其他部门经中介者查询)
                self.record(colleague.colleague_id(), outcome.clone());
                // 广播完成事件 → 中介者路由给相关部门
                let event = BusinessEvent::from_colleague(colleague.colleague_id());
                if let Err(err) = self.dispatch(colleague.colleague_id(), event, ctx) {
                    self.logger.warn(&format!(
                        "事件分发失败:事件={} 原因={}",
                        event.tag(),
                        err
                    ));
                }
                ProcessResponseDto::new(
                    &ctx.instance_id,
                    colleague.colleague_name(),
                    true,
                    &outcome.summary,
                )
            }
            Err(err) => {
                self.logger.error(&format!(
                    "部门「{}」执行失败:{}(熔断状态={:?})",
                    colleague.colleague_name(),
                    err,
                    self.resilience.state()
                ));
                ProcessResponseDto::new(
                    &ctx.instance_id,
                    colleague.colleague_name(),
                    false,
                    &format!("部门执行失败:{}", err),
                )
            }
        }
    }
}

impl BusinessMediator for ConcreteMediator {
    /// 注册同事
    fn register(&self, colleague: Arc<dyn Colleague>) {
        self.colleagues.lock().unwrap().push(colleague);
    }

    /// 按标识查找同事
    fn colleague(&self, colleague_id: &str) -> Option<Arc<dyn Colleague>> {
        self.colleagues
            .lock()
            .unwrap()
            .iter()
            .find(|c| c.colleague_id() == colleague_id)
            .cloned()
    }

    /// 获取全部已注册同事
    fn colleagues(&self) -> Vec<Arc<dyn Colleague>> {
        self.colleagues.lock().unwrap().clone()
    }

    /// 记录某部门的业务产出
    fn record(&self, colleague_id: &str, outcome: ProcessOutcome) {
        self.outputs
            .lock()
            .unwrap()
            .insert(colleague_id.to_string(), outcome);
    }

    /// 查询某部门的业务产出(同事经中介者间接获取其他部门产出)
    fn query(&self, colleague_id: &str) -> Option<ProcessOutcome> {
        self.outputs.lock().unwrap().get(colleague_id).cloned()
    }

    /// 分发业务事件给相关部门(中介者集中管理部门间交互)
    fn dispatch(
        &self,
        sender_id: &str,
        event: BusinessEvent,
        ctx: &CommandContext,
    ) -> Result<(), ProcessError> {
        let receivers = receivers_for(event);
        for receiver_id in receivers {
            if *receiver_id == sender_id {
                continue;
            }
            if let Some(colleague) = self.colleague(receiver_id) {
                self.logger.debug(&format!(
                    "中介者将事件【{}】从 {} 路由给 {}",
                    event.tag(),
                    sender_id,
                    colleague.colleague_name()
                ));
                // 调用接收部门的 on_event(同事经中介者间接协同)
                if let Err(err) = colleague.on_event(event, ctx) {
                    self.logger.warn(&format!(
                        "部门「{}」响应事件失败:{}",
                        colleague.colleague_name(),
                        err
                    ));
                }
            }
        }
        Ok(())
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : process_service.rs
//! 业务流程应用服务
//!
//! 职责:
//! - 持有具体中介者(`Arc<ConcreteMediator>`)
//! 
//! 与仓储(构造器注入)
//! - 委托中介者执行顺序协调 / 并发调度
//! - 调用仓储保存执行记录
//! - 提供统计、记录查询、同事清单能力
//!
//! 全部日志通过统一日志对象(`Arc<dyn Logger>`)输出,控制台与文件一致。

use std::sync::Arc;

use crate::application::mediator::concrete_mediator::ConcreteMediator;
use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::mediator::colleague::Colleague;
use crate::domain::mediator::mediator::BusinessMediator;
use crate::domain::repository::process_repository::{ProcessRecord, ProcessRepository};

/// 业务流程应用服务
pub struct ProcessService {
    /// 具体中介者(依赖注入)
    mediator: Arc<ConcreteMediator>,
    /// 流程仓储(依赖注入)
    repository: Arc<dyn ProcessRepository>,
    /// 统一日志(依赖注入)
    logger: Arc<dyn Logger>,
}

impl ProcessService {
    /// 创建业务流程应用服务
    ///
    /// # 参数
    /// - `mediator`:具体中介者
    /// - `repository`:流程仓储
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 应用服务实例
    pub fn new(
        mediator: Arc<ConcreteMediator>,
        repository: Arc<dyn ProcessRepository>,
        logger: Arc<dyn Logger>,
    ) -> Self {
        Self {
            mediator,
            repository,
            logger,
        }
    }

    /// 中介者顺序协调全部部门,并保存执行记录
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各部门执行响应集合
    pub fn coordinate(&self, request: ProcessRequestDto) -> Vec<ProcessResponseDto> {
        let responses = self.mediator.coordinate(request);
        self.save_responses(&responses);
        responses
    }

    /// 中介者并发调度全部部门(高并发演示),并保存执行记录
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各部门执行响应集合
    pub fn coordinate_concurrent(&self, request: ProcessRequestDto) -> Vec<ProcessResponseDto> {
        let responses = self.mediator.coordinate_concurrent(request);
        self.save_responses(&responses);
        responses
    }

    /// 保存一批执行记录(内部辅助)
    ///
    /// # 参数
    /// - `responses`:执行响应集合
    fn save_responses(&self, responses: &[ProcessResponseDto]) {
        for resp in responses {
            let outcome = if resp.success {
                ProcessOutcome::success(&resp.instance_id, &resp.message)
            } else {
                ProcessOutcome::failure(&resp.instance_id, &resp.message)
            };
            let record = ProcessRecord {
                instance_id: resp.instance_id.clone(),
                process_name: resp.process_name.clone(),
                outcome,
                executed_at: chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
            };
            if let Err(err) = self.repository.save(record) {
                self.logger.error(&format!("保存业务执行记录失败:{}", err));
            }
        }
    }

    /// 获取已注册同事清单(经中介者)
    ///
    /// # 返回
    /// 全部同事实例
    pub fn colleagues(&self) -> Vec<Arc<dyn Colleague>> {
        self.mediator.colleagues()
    }

    /// 获取业务执行统计(成功数量,失败数量)
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    pub fn statistics(&self) -> (usize, usize) {
        self.repository.count()
    }

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    ///
    /// # 返回
    /// 全部执行记录
    pub fn records(&self) -> Vec<ProcessRecord> {
        self.repository.find_all()
    }

    /// 执行单个同事(供端口契约使用;经中介者重试熔断保护)
    ///
    /// # 参数
    /// - `colleague_id`:同事标识
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:执行响应(成败见 `success` 字段)
    /// - `Err(ProcessError)`:未找到同事
    pub fn execute_one(
        &self,
        colleague_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError> {
        let colleague = self.mediator.colleague(colleague_id).ok_or_else(|| {
            ProcessError::new("NOT_FOUND", &format!("未找到同事:{}", colleague_id))
        })?;
        let instance_id = format!(
            "{}-{:06}",
            colleague_id,
            crate::domain::entities::jewelry::next_sequence()
        );
        let ctx = crate::domain::mediator::command_ctx::CommandContext::new(&instance_id, request);
        let response = self.mediator.execute_colleague(&colleague, &ctx);
        Ok(response)
    }
}
rust 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : retry_circuit_breaker.rs
//! 重试 + 熔断适配器(Resilience Adapter)
//!
//! 作用:在中介者协调同事执行依赖外部系统(如质检系统、物流接口、财务网关)时,
//! 提供「自动重试 + 熔断保护」:
//! - **重试**:瞬时失败时按指数退避重试,直至达到最大重试次数。
//! - **熔断**:连续失败达到阈值后打开熔断器,快速失败(不再重试),
//!   经冷却时间后进入半开状态,试探恢复。
//!
//! 线程安全:内部状态使用 `Mutex` 保护,可被 `Arc` 共享到多个线程高并发使用。

use std::sync::Mutex;
use std::time::{Duration, Instant};

use crate::common::error::ProcessError;

/// 熔断器打开错误码
const ERROR_CIRCUIT_OPEN: &str = "CIRCUIT_OPEN";

/// 熔断器状态
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CircuitState {
    /// 关闭(正常运行,允许调用)
    Closed,
    /// 打开(熔断,快速失败)
    Open,
    /// 半开(冷却结束,试探性放行一次)
    HalfOpen,
}

/// 熔断器内部状态(受互斥锁保护)
struct CircuitInner {
    /// 当前熔断状态
    state: CircuitState,
    /// 连续失败次数
    consecutive_failures: u32,
    /// 熔断打开时刻(用于计算冷却时间)
    opened_at: Option<Instant>,
}

/// 重试 + 熔断适配器(线程安全、可共享)
pub struct RetryCircuitBreaker {
    /// 最大重试次数(成功之前最多额外尝试的次数)
    max_retries: u32,
    /// 熔断失败阈值(连续失败达到该次数即打开熔断器)
    failure_threshold: u32,
    /// 熔断冷却时间(打开后等待该时长才允许半开试探)
    cooldown: Duration,
    /// 内部熔断状态
    inner: Mutex<CircuitInner>,
}

impl RetryCircuitBreaker {
    /// 创建重试 + 熔断适配器
    ///
    /// # 参数
    /// - `max_retries`:最大重试次数
    /// - `failure_threshold`:熔断失败阈值
    /// - `cooldown`:熔断冷却时长
    ///
    /// # 返回
    /// 适配器实例
    pub fn new(max_retries: u32, failure_threshold: u32, cooldown: Duration) -> Self {
        Self {
            max_retries,
            failure_threshold,
            cooldown,
            inner: Mutex::new(CircuitInner {
                state: CircuitState::Closed,
                consecutive_failures: 0,
                opened_at: None,
            }),
        }
    }

    /// 获取当前熔断状态(用于日志输出)
    ///
    /// # 返回
    /// 当前 `CircuitState`
    pub fn state(&self) -> CircuitState {
        self.inner
            .lock()
            .map(|g| g.state)
            .unwrap_or(CircuitState::Closed)
    }

    /// 执行受保护的操作:带「重试 + 熔断」
    ///
    /// # 泛型参数
    /// - `F`:操作闭包类型
    /// - `O`:成功返回值类型
    ///
    /// # 参数
    /// - `operation`:返回 `Result<O, ProcessError>` 的操作闭包
    ///
    /// # 返回
    /// - `Ok(O)`:操作最终成功
    /// - `Err(ProcessError)`:重试耗尽或熔断快速失败
    pub fn execute<F, O>(&self, operation: F) -> Result<O, ProcessError>
    where
        F: Fn() -> Result<O, ProcessError>,
    {
        // 步骤一:熔断前置检查(快速失败)
        {
            let mut guard = self.inner.lock().unwrap();
            if guard.state == CircuitState::Open {
                if let Some(opened_at) = guard.opened_at {
                    // 冷却时间未过 → 直接快速失败
                    if opened_at.elapsed() < self.cooldown {
                        return Err(ProcessError::new(
                            ERROR_CIRCUIT_OPEN,
                            "熔断器已打开,请求快速失败,请稍后重试",
                        ));
                    }
                }
                // 冷却时间已过 → 转为半开状态,允许一次试探
                guard.state = CircuitState::HalfOpen;
            }
        }

        // 步骤二:带重试地执行操作
        let mut attempt = 0u32;
        loop {
            match operation() {
                Ok(value) => {
                    // 成功:重置失败计数,恢复关闭状态
                    let mut guard = self.inner.lock().unwrap();
                    guard.consecutive_failures = 0;
                    guard.state = CircuitState::Closed;
                    guard.opened_at = None;
                    return Ok(value);
                }
                Err(err) => {
                    attempt += 1;
                    {
                        let mut guard = self.inner.lock().unwrap();
                        guard.consecutive_failures += 1;
                        // 连续失败达到阈值 → 打开熔断器
                        if guard.consecutive_failures >= self.failure_threshold {
                            guard.state = CircuitState::Open;
                            guard.opened_at = Some(Instant::now());
                            return Err(err);
                        }
                    }
                    // 未熔断但重试次数已耗尽 → 返回错误
                    if attempt > self.max_retries {
                        return Err(err);
                    }
                    // 指数退避等待后重试
                    std::thread::sleep(Duration::from_millis(100 * attempt as u64));
                }
            }
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : error.rs
//! 统一错误类型定义
//!
//! 全项目统一使用 `ProcessError` 作为业务错误载体,携带错误码与消息,
//! 便于上层(应用层/接口层/表现层)统一捕获与日志输出。

/// 业务流程错误(统一错误载体)
#[derive(Debug, Clone)]
pub struct ProcessError {
    /// 错误码(如 EXECUTION_FAILED / CIRCUIT_OPEN 等)
    pub code: String,
    /// 错误消息(中文,可直接输出到日志与界面)
    pub message: String,
}

impl ProcessError {
    /// 创建业务流程错误
    ///
    /// # 参数
    /// - `code`:错误码
    /// - `message`:错误消息
    ///
    /// # 返回
    /// 构造好的 `ProcessError` 实例
    pub fn new(code: &str, message: &str) -> Self {
        Self {
            code: code.to_string(),
            message: message.to_string(),
        }
    }
}

/// 格式化输出(支持 `{}` 直接打印)
impl std::fmt::Display for ProcessError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "[{}] {}", self.code, self.message)
    }
}

/// 实现标准 Error trait,可向上转换为 `Box<dyn Error>`
impl std::error::Error for ProcessError {}

/// 预留的标准错误码字典(供上层业务模块调用,作为统一错误码契约预留给扩展)
#[allow(dead_code)]
pub mod error_code {
    /// 前置校验失败
    pub const VALIDATE_FAILED: &str = "VALIDATE_FAILED";
    /// 业务执行失败
    pub const EXECUTION_FAILED: &str = "EXECUTION_FAILED";
    /// 熔断器打开(快速失败)
    pub const CIRCUIT_OPEN: &str = "CIRCUIT_OPEN";
    /// 资源未找到
    pub const NOT_FOUND: &str = "NOT_FOUND";
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : logging.rs
//! 统一日志抽象接口(对应 C# 中的 `ILogger<T>`)
//!
//! 所有组件(调度器、中介者、同事、入口)仅依赖该接口输出日志,
//! 具体实现(文件日志)由基础设施层通过 DI 注入。
//! 保证控制台输出与日志文件输出格式完全一致。
//!
//! 日志文件规约:
//! ```text
//! Logs/
//!   2026-07-06/
//!     app-info.log
//!     app-error.log
//!     app-debug.log
//!     app-warn.log
//! ```

/// 日志等级
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
    /// 调试(用于输出详细执行过程)
    Debug,
    /// 信息(用于输出常规流程状态)
    Info,
    /// 警告(用于输出可恢复异常)
    Warn,
    /// 错误(用于输出失败/异常)
    Error,
}

impl LogLevel {
    /// 获取日志等级标签(用于日志前缀,控制台与文件一致)
    ///
    /// # 返回
    /// 等级标签字符串
    pub fn tag(&self) -> &'static str {
        match self {
            LogLevel::Debug => "DEBUG",
            LogLevel::Info => "INFO",
            LogLevel::Warn => "WARN",
            LogLevel::Error => "ERROR",
        }
    }

    /// 获取日志等级对应的文件名(按等级分文件)
    ///
    /// # 返回
    /// 文件名(如 `app-info.log`)
    pub fn file_name(&self) -> &'static str {
        match self {
            LogLevel::Debug => "app-debug.log",
            LogLevel::Info => "app-info.log",
            LogLevel::Warn => "app-warn.log",
            LogLevel::Error => "app-error.log",
        }
    }
}

/// 统一日志接口(线程安全、可对象化注入使用)
///
/// 设计要点:
/// - `Send + Sync` 保证可在多线程/高并发环境下共享(`Arc<dyn Logger>`)
/// - 方法非泛型,保持对象安全(object-safe),可向上转型为 trait 对象注入
pub trait Logger: Send + Sync {
    /// 输出调试日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn debug(&self, message: &str);

    /// 输出信息日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn info(&self, message: &str);

    /// 输出警告日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn warn(&self, message: &str);

    /// 输出错误日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn error(&self, message: &str);
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : result.rs
//! 统一结果返回类型
//!
//! 用于表现层/接口层向调用方返回统一结构的操作结果,保证输出格式一致。

/// 通用操作结果(泛型,表现层返回载体)
///
/// 预留给需要结构化返回(成功/失败 + 业务数据)的调用方使用;
/// 当前控制台演示直接输出日志,未构造该结果,属预留 API。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ApiResult<T> {
    /// 是否成功
    pub success: bool,
    /// 结果消息
    pub message: String,
    /// 业务数据(可选)
    pub data: Option<T>,
}

impl<T> ApiResult<T> {
    /// 创建成功结果
    ///
    /// # 参数
    /// - `data`:业务数据
    ///
    /// # 返回
    /// 成功结果
    #[allow(dead_code)]
    pub fn ok(data: T) -> Self {
        Self {
            success: true,
            message: "操作成功".to_string(),
            data: Some(data),
        }
    }

    /// 创建失败结果
    ///
    /// # 参数
    /// - `message`:失败消息
    ///
    /// # 返回
    /// 失败结果
    #[allow(dead_code)]
    pub fn err(message: &str) -> Self {
        Self {
            success: false,
            message: message.to_string(),
            data: None,
        }
    }
}

调用:

rust 复制代码
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:中介者模式Mediator Pattern  行为模式 Behavioral Patterns
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/21 21:39 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : MediatorPattern
//!# File      : main.rs
//! 中介者模式(Mediator Pattern)--- 珠宝行业企业级全程业务流程
//!
//! 业务范围:原料采购核验、设计制图、加工生产、质检、包装、物流、财务、
//!           营销推广、业务销售、人事行政、IT、培训。
//!
//! 中介者模式核心思想:
//! - **Colleague(同事)**:12 个业务部门各自封装业务动作,同事之间**不直接
//!   相互引用**,而是通过中介者通信。
//! - **Mediator(中介者)**:集中管理同事注册与事件路由,负责部门间的交互
//!   协调(如 采购完成 → 通知设计/财务;质检完成 → 通知包装/财务 等)。
//! - 通过中介者,部门间耦合被集中解耦,新增/替换部门不影响其他部门。
//!
//! 工程化特性:
//! - 日志按日期分文件夹、按日志等级分文件(Logs/2026-07-06/app-*.log)
//! - 注入统一日志对象 `Arc<dyn Logger>`(对应 C# 的 `ILogger<T>`)
//! - DTO 业务传输对象、适配器「重试 + 熔断」
//! - 兼容依赖注入(DI)、线程安全、高并发写入
//! - 调度器 / 同事 / 入口全部使用统一标准日志,控制台与文件输出完全一致
//!
//! DDD 严格分层(依赖方向:presentation → interface → application → domain → common;
//! infrastructure 实现 domain/interface 定义的接口):
//! - domain          领域层(实体、DTO、中介者/同事抽象、仓储接口)
//! - common          通用层(错误、结果、日志接口、重试熔断)
//! - application     应用层(具体中介者、12 个同事、应用服务)
//! - infrastructure  基础设施层(文件日志、DI 容器、内存仓储)
//! - interface       接口层(对外端口契约、命令信封契约)
//! - presentation    表现层(控制台入口 / 组合根装配 / 端口实现)

// 声明顶层模块(对应六个文件夹)
mod application;
mod common;
mod domain;
mod infrastructure;
mod interface;
mod presentation;

use std::sync::Arc;

use infrastructure::di::container::ServiceContainer;
use presentation::console::controller::ApplicationController;

/// 程序入口(组合根:装配依赖注入容器 → 创建应用控制器 → 启动中介者协调演示)
fn main() {
    // 1. 构建依赖注入容器(组合根,统一装配全部服务与同事)
    let container = Arc::new(ServiceContainer::new());

    // 2. 创建应用控制器(表现层,实现 interface 定义的对外端口契约)
    let controller = ApplicationController::new(container);

    // 3. 启动珠宝行业全程业务流程(中介者模式)演示
    controller.run();
}

输出:

相关推荐
传奇开心果编程1 小时前
【Rust入门练中学】第8课:错误处理
开发语言·rust·错误处理·编程语言理论·通用编程语言
Doker 多克1 小时前
Spring Integration AMQP 和 Spring AMQP详解
java·后端·spring
韩振方1 小时前
Kubernetes Ingress 用 TLS Secret 给预览域名接上 HTTPS
后端
郑同学的笔记1 小时前
【c++随笔30】C++ 注册回调函数
开发语言·c++
用户1494484813201 小时前
为什么大厂很少直接用 2PC/TCC?聊聊分布式事务在真实业务里的落地套路
分布式·后端
Thneonl1 小时前
采样采错地方,trace 全断链:OTel 尾部采样的代价账
后端·架构
匆匆那年随风1 小时前
零依赖 C# Office 库到底怎么用——四个场景讲透 Wisdom.Office
后端
今天早睡1 小时前
用子图封装流程,设计清晰的父子状态接口
后端
Lyy1 小时前
DevOps平台 — 第十七篇:测试管理的设计与实现
后端·devops