moklgy's blog moklgy's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 后端文章

    • 技术题
  • .netcore

    • 《asp.netcore》笔记
    • 《设计模式》
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

moklgy docs

全栈初级开发工程师
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 后端文章

    • 技术题
  • .netcore

    • 《asp.netcore》笔记
    • 《设计模式》
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 对象之间的关系
  • SOLID原则
  • 创建型
  • 结构型
  • 行为型一
  • 行为型二
    • 行为型模式二
      • 18. 观察者模式
      • 19. 状态模式
      • 20. 策略模式
      • 19. 状态模式
      • 20. 策略模式
  • 其他模式与组合使用
  • 《设计模式》
moklgydocs
2025-10-12
目录

行为型二

# C#设计模式全面指南

# 行为型模式二

# 18. 观察者模式

原理:
观察者模式定义了对象之间的一对多依赖关系,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。

思路:

  1. 定义主题(被观察者)接口,包含添加、删除和通知观察者的方法
  2. 定义观察者接口,包含更新方法,当收到通知时被调用
  3. 实现具体主题类,管理观察者并在状态变化时通知它们
  4. 实现具体观察者类,处理从主题发来的更新

前辈经验:

  • 当一个对象的变化需要通知其他对象,但不知道有多少对象需要通知时,使用观察者模式
  • 观察者模式可实现松耦合,主题不需要知道观察者的具体类
  • 观察者可以随时加入或退出,不影响其他观察者
  • 注意避免循环通知和多余的通知,以防性能问题
  • .NET中有内置的实现:事件和委托,以及IObservable和IObserver接口

业务场景:
股票市场系统,股票价格变动时通知所有关注该股票的投资者。

简单实现:

// 观察者接口
public interface IInvestor
{
    void Update(Stock stock);
}

// 主题类(被观察者)
public class Stock
{
    private string _symbol;
    private decimal _price;
    private readonly List<IInvestor> _investors = new List<IInvestor>();
    
    public Stock(string symbol, decimal price)
    {
        _symbol = symbol;
        _price = price;
    }
    
    public string Symbol
    {
        get { return _symbol; }
    }
    
    public decimal Price
    {
        get { return _price; }
        set
        {
            if (_price != value)
            {
                decimal oldPrice = _price;
                _price = value;
                Notify(oldPrice);
            }
        }
    }
    
    public void Attach(IInvestor investor)
    {
        if (!_investors.Contains(investor))
        {
            _investors.Add(investor);
            Console.WriteLine($"通知: {((Investor)investor).Name} 已开始关注 {Symbol}");
        }
    }
    
    public void Detach(IInvestor investor)
    {
        if (_investors.Contains(investor))
        {
            _investors.Remove(investor);
            Console.WriteLine($"通知: {((Investor)investor).Name} 已取消关注 {Symbol}");
        }
    }
    
    private void Notify(decimal oldPrice)
    {
        foreach (IInvestor investor in _investors)
        {
            investor.Update(this);
        }
        
        Console.WriteLine($"股票 {Symbol} 价格从 {oldPrice:C} 变为 {Price:C}");
    }
}

// 具体观察者
public class Investor : IInvestor
{
    public string Name { get; }
    private Dictionary<string, decimal> _portfolio = new Dictionary<string, decimal>();
    
    public Investor(string name)
    {
        Name = name;
    }
    
    public void Update(Stock stock)
    {
        decimal changePercent = (stock.Price - GetPurchasePrice(stock.Symbol)) / GetPurchasePrice(stock.Symbol) * 100;
        string changeDirection = stock.Price > GetPurchasePrice(stock.Symbol) ? "上涨" : "下跌";
        
        Console.WriteLine($"通知 {Name}: {stock.Symbol} 的价格已{changeDirection}到 {stock.Price:C}, 收益率: {changePercent:F2}%");
    }
    
    public void PurchaseStock(Stock stock, decimal purchasePrice)
    {
        _portfolio[stock.Symbol] = purchasePrice;
        Console.WriteLine($"{Name} 以 {purchasePrice:C} 购买了 {stock.Symbol}");
        
        stock.Attach(this);
    }
    
    public void SellStock(Stock stock)
    {
        if (_portfolio.ContainsKey(stock.Symbol))
        {
            decimal purchasePrice = _portfolio[stock.Symbol];
            _portfolio.Remove(stock.Symbol);
            
            decimal profit = stock.Price - purchasePrice;
            Console.WriteLine($"{Name} 以 {stock.Price:C} 卖出了 {stock.Symbol}, 盈亏: {profit:C}");
            
            stock.Detach(this);
        }
    }
    
    private decimal GetPurchasePrice(string symbol)
    {
        if (_portfolio.ContainsKey(symbol))
        {
            return _portfolio[symbol];
        }
        
        return 0;
    }
}

// 股票市场 - 管理多个股票
public class StockMarket
{
    private Dictionary<string, Stock> _stocks = new Dictionary<string, Stock>();
    
    public void AddStock(Stock stock)
    {
        _stocks[stock.Symbol] = stock;
    }
    
    public Stock GetStock(string symbol)
    {
        if (_stocks.ContainsKey(symbol))
        {
            return _stocks[symbol];
        }
        
        return null;
    }
    
    public void UpdateStockPrice(string symbol, decimal newPrice)
    {
        if (_stocks.ContainsKey(symbol))
        {
            _stocks[symbol].Price = newPrice;
        }
    }
    
    public void DisplayStocks()
    {
        Console.WriteLine("\n当前股票价格:");
        foreach (var stock in _stocks.Values)
        {
            Console.WriteLine($"{stock.Symbol}: {stock.Price:C}");
        }
        Console.WriteLine();
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建股票市场
        StockMarket market = new StockMarket();
        
        // 创建股票
        Stock msft = new Stock("MSFT", 235.77m);
        Stock aapl = new Stock("AAPL", 147.92m);
        Stock goog = new Stock("GOOG", 2732.42m);
        
        // 添加到市场
        market.AddStock(msft);
        market.AddStock(aapl);
        market.AddStock(goog);
        
        // 显示初始股票价格
        market.DisplayStocks();
        
        // 创建投资者
        Investor investor1 = new Investor("张三");
        Investor investor2 = new Investor("李四");
        Investor investor3 = new Investor("王五");
        
        // 投资者购买股票
        investor1.PurchaseStock(msft, 232.25m);
        investor1.PurchaseStock(aapl, 145.50m);
        
        investor2.PurchaseStock(aapl, 146.75m);
        investor2.PurchaseStock(goog, 2710.65m);
        
        investor3.PurchaseStock(msft, 234.50m);
        investor3.PurchaseStock(goog, 2725.30m);
        
        // 股票价格变动
        Console.WriteLine("\n股票价格变动:");
        market.UpdateStockPrice("MSFT", 240.25m);
        market.UpdateStockPrice("AAPL", 145.30m);
        market.UpdateStockPrice("GOOG", 2750.80m);
        
        // 显示更新后的股票价格
        market.DisplayStocks();
        
        // 投资者卖出股票
        Console.WriteLine("\n投资者卖出股票:");
        investor1.SellStock(aapl);
        investor3.SellStock(msft);
        
        // 再次更新股票价格
        Console.WriteLine("\n股票价格再次变动:");
        market.UpdateStockPrice("MSFT", 237.50m);
        market.UpdateStockPrice("AAPL", 148.25m);
        market.UpdateStockPrice("GOOG", 2722.75m);
        
        // 显示最终股票价格
        market.DisplayStocks();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

复杂实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;

// 1. 事件参数基类
public class StockEventArgs : EventArgs
{
    public string Symbol { get; }
    public DateTime Timestamp { get; }
    
    public StockEventArgs(string symbol)
    {
        Symbol = symbol;
        Timestamp = DateTime.Now;
    }
}

// 2. 价格变动事件参数
public class PriceChangedEventArgs : StockEventArgs
{
    public decimal OldPrice { get; }
    public decimal NewPrice { get; }
    public decimal ChangePercent { get; }
    
    public PriceChangedEventArgs(string symbol, decimal oldPrice, decimal newPrice) 
        : base(symbol)
    {
        OldPrice = oldPrice;
        NewPrice = newPrice;
        
        if (oldPrice != 0)
        {
            ChangePercent = (newPrice - oldPrice) / oldPrice * 100;
        }
        else
        {
            ChangePercent = 0;
        }
    }
}

// 3. 交易量变动事件参数
public class VolumeChangedEventArgs : StockEventArgs
{
    public long OldVolume { get; }
    public long NewVolume { get; }
    public long VolumeChange { get; }
    
    public VolumeChangedEventArgs(string symbol, long oldVolume, long newVolume) 
        : base(symbol)
    {
        OldVolume = oldVolume;
        NewVolume = newVolume;
        VolumeChange = newVolume - oldVolume;
    }
}

// 4. 市场状态变动事件参数
public class MarketStatusChangedEventArgs : EventArgs
{
    public MarketStatus OldStatus { get; }
    public MarketStatus NewStatus { get; }
    public DateTime Timestamp { get; }
    
    public MarketStatusChangedEventArgs(MarketStatus oldStatus, MarketStatus newStatus)
    {
        OldStatus = oldStatus;
        NewStatus = newStatus;
        Timestamp = DateTime.Now;
    }
}

// 5. 股票交易事件参数
public class StockTradeEventArgs : StockEventArgs
{
    public TradeType TradeType { get; }
    public decimal Price { get; }
    public int Quantity { get; }
    public string BuyerId { get; }
    public string SellerId { get; }
    public decimal TotalValue => Price * Quantity;
    
    public StockTradeEventArgs(string symbol, TradeType tradeType, decimal price, int quantity, 
                              string buyerId, string sellerId) 
        : base(symbol)
    {
        TradeType = tradeType;
        Price = price;
        Quantity = quantity;
        BuyerId = buyerId;
        SellerId = sellerId;
    }
}

// 6. 枚举类型
public enum MarketStatus
{
    BeforeMarket,
    Open,
    Closed,
    Halted
}

public enum TradeType
{
    Buy,
    Sell,
    ShortSell,
    Cover
}

// 7. 观察者接口
public interface IStockObserver
{
    string ObserverId { get; }
    int Priority { get; }
    void OnPriceChanged(object sender, PriceChangedEventArgs e);
    void OnVolumeChanged(object sender, VolumeChangedEventArgs e);
    void OnStockTrade(object sender, StockTradeEventArgs e);
}

// 8. 市场观察者接口
public interface IMarketObserver
{
    string ObserverId { get; }
    int Priority { get; }
    void OnMarketStatusChanged(object sender, MarketStatusChangedEventArgs e);
}

// 9. 观察者基类
public abstract class StockObserverBase : IStockObserver
{
    public string ObserverId { get; }
    public virtual int Priority => 0;
    
    protected StockObserverBase(string observerId)
    {
        ObserverId = observerId;
    }
    
    public abstract void OnPriceChanged(object sender, PriceChangedEventArgs e);
    public abstract void OnVolumeChanged(object sender, VolumeChangedEventArgs e);
    public abstract void OnStockTrade(object sender, StockTradeEventArgs e);
}

// 10. 股票类 - 被观察者
public class Stock
{
    private readonly List<WeakReference<IStockObserver>> _observers = new List<WeakReference<IStockObserver>>();
    private readonly ReaderWriterLockSlim _observersLock = new ReaderWriterLockSlim();
    private readonly object _dataLock = new object();
    
    public string Symbol { get; }
    
    private decimal _price;
    public decimal Price
    {
        get { return _price; }
        set
        {
            decimal oldPrice;
            lock (_dataLock)
            {
                oldPrice = _price;
                if (oldPrice == value) return;
                _price = value;
            }
            
            NotifyPriceChanged(oldPrice, value);
        }
    }
    
    private long _volume;
    public long Volume
    {
        get { return _volume; }
        set
        {
            long oldVolume;
            lock (_dataLock)
            {
                oldVolume = _volume;
                if (oldVolume == value) return;
                _volume = value;
            }
            
            NotifyVolumeChanged(oldVolume, value);
        }
    }
    
    public decimal Open { get; set; }
    public decimal Close { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal PreviousClose { get; set; }
    public DateTime LastUpdateTime { get; private set; }
    
    public Stock(string symbol, decimal initialPrice, long initialVolume = 0)
    {
        Symbol = symbol;
        _price = initialPrice;
        _volume = initialVolume;
        Open = initialPrice;
        Close = initialPrice;
        High = initialPrice;
        Low = initialPrice;
        PreviousClose = initialPrice;
        LastUpdateTime = DateTime.Now;
    }
    
    // 添加观察者
    public void AddObserver(IStockObserver observer)
    {
        _observersLock.EnterWriteLock();
        try
        {
            // 检查是否已经存在
            bool exists = false;
            foreach (var weakRef in _observers)
            {
                if (weakRef.TryGetTarget(out var existingObserver) && 
                    existingObserver.ObserverId == observer.ObserverId)
                {
                    exists = true;
                    break;
                }
            }
            
            if (!exists)
            {
                _observers.Add(new WeakReference<IStockObserver>(observer));
                Console.WriteLine($"已添加观察者 {observer.ObserverId} 到股票 {Symbol}");
            }
        }
        finally
        {
            _observersLock.ExitWriteLock();
        }
    }
    
    // 移除观察者
    public void RemoveObserver(IStockObserver observer)
    {
        _observersLock.EnterWriteLock();
        try
        {
            int index = -1;
            for (int i = 0; i < _observers.Count; i++)
            {
                if (_observers[i].TryGetTarget(out var target) && 
                    target.ObserverId == observer.ObserverId)
                {
                    index = i;
                    break;
                }
            }
            
            if (index >= 0)
            {
                _observers.RemoveAt(index);
                Console.WriteLine($"已移除观察者 {observer.ObserverId} 从股票 {Symbol}");
            }
        }
        finally
        {
            _observersLock.ExitWriteLock();
        }
    }
    
    // 清理失效的观察者引用
    private void CleanupObservers()
    {
        _observersLock.EnterWriteLock();
        try
        {
            int count = _observers.Count;
            _observers.RemoveAll(weakRef => !weakRef.TryGetTarget(out _));
            
            int removed = count - _observers.Count;
            if (removed > 0)
            {
                Console.WriteLine($"已清理 {removed} 个失效的观察者引用");
            }
        }
        finally
        {
            _observersLock.ExitWriteLock();
        }
    }
    
    // 执行交易并通知
    public void ExecuteTrade(TradeType tradeType, decimal tradePrice, int quantity, 
                            string buyerId, string sellerId)
    {
        // 更新价格和交易量
        decimal oldPrice;
        long oldVolume;
        
        lock (_dataLock)
        {
            oldPrice = _price;
            oldVolume = _volume;
            
            _price = tradePrice;
            _volume += quantity;
            
            // 更新高低价
            if (tradePrice > High) High = tradePrice;
            if (tradePrice < Low || Low == 0) Low = tradePrice;
            
            LastUpdateTime = DateTime.Now;
        }
        
        // 创建交易事件参数
        var tradeArgs = new StockTradeEventArgs(
            Symbol, tradeType, tradePrice, quantity, buyerId, sellerId);
        
        // 通知价格变动
        if (oldPrice != tradePrice)
        {
            NotifyPriceChanged(oldPrice, tradePrice);
        }
        
        // 通知交易量变动
        NotifyVolumeChanged(oldVolume, _volume);
        
        // 通知交易发生
        NotifyTrade(tradeArgs);
    }
    
    // 通知价格变动
    private void NotifyPriceChanged(decimal oldPrice, decimal newPrice)
    {
        // 准备事件参数
        var args = new PriceChangedEventArgs(Symbol, oldPrice, newPrice);
        
        // 创建观察者的本地副本以避免锁争用
        List<IStockObserver> observers = GetObserversOrderedByPriority();
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnPriceChanged(this, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"通知观察者 {observer.ObserverId} 价格变动时出错: {ex.Message}");
                }
            }
        });
        
        LastUpdateTime = DateTime.Now;
    }
    
    // 通知交易量变动
    private void NotifyVolumeChanged(long oldVolume, long newVolume)
    {
        // 准备事件参数
        var args = new VolumeChangedEventArgs(Symbol, oldVolume, newVolume);
        
        // 创建观察者的本地副本以避免锁争用
        List<IStockObserver> observers = GetObserversOrderedByPriority();
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnVolumeChanged(this, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"通知观察者 {observer.ObserverId} 交易量变动时出错: {ex.Message}");
                }
            }
        });
        
        LastUpdateTime = DateTime.Now;
    }
    
    // 通知交易发生
    private void NotifyTrade(StockTradeEventArgs args)
    {
        // 创建观察者的本地副本以避免锁争用
        List<IStockObserver> observers = GetObserversOrderedByPriority();
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnStockTrade(this, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"通知观察者 {observer.ObserverId} 交易发生时出错: {ex.Message}");
                }
            }
        });
    }
    
    // 获取按优先级排序的观察者列表
    private List<IStockObserver> GetObserversOrderedByPriority()
    {
        var result = new List<IStockObserver>();
        
        _observersLock.EnterReadLock();
        try
        {
            foreach (var weakRef in _observers)
            {
                if (weakRef.TryGetTarget(out var observer))
                {
                    result.Add(observer);
                }
            }
        }
        finally
        {
            _observersLock.ExitReadLock();
        }
        
        // 按优先级排序,高优先级在前
        return result.OrderByDescending(o => o.Priority).ToList();
    }
    
    // 获取统计信息
    public StockStatistics GetStatistics()
    {
        lock (_dataLock)
        {
            return new StockStatistics
            {
                Symbol = Symbol,
                CurrentPrice = _price,
                Volume = _volume,
                Open = Open,
                High = High,
                Low = Low,
                PreviousClose = PreviousClose,
                Change = _price - PreviousClose,
                ChangePercent = PreviousClose != 0 ? (_price - PreviousClose) / PreviousClose * 100 : 0,
                LastUpdateTime = LastUpdateTime
            };
        }
    }
    
    // 更新收盘价
    public void SetClose(decimal closePrice)
    {
        lock (_dataLock)
        {
            Close = closePrice;
            _price = closePrice;
            LastUpdateTime = DateTime.Now;
        }
    }
    
    // 设置新交易日的开盘价
    public void SetNewDay(decimal openPrice)
    {
        lock (_dataLock)
        {
            PreviousClose = Close;
            Open = openPrice;
            High = openPrice;
            Low = openPrice;
            _price = openPrice;
            _volume = 0;
            LastUpdateTime = DateTime.Now;
        }
    }
}

// 11. 股票统计信息
public class StockStatistics
{
    public string Symbol { get; set; }
    public decimal CurrentPrice { get; set; }
    public long Volume { get; set; }
    public decimal Open { get; set; }
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal PreviousClose { get; set; }
    public decimal Change { get; set; }
    public decimal ChangePercent { get; set; }
    public DateTime LastUpdateTime { get; set; }
    
    public override string ToString()
    {
        string changeDirection = Change >= 0 ? "+" : "";
        return $"{Symbol} - {CurrentPrice:C} ({changeDirection}{Change:F2} {changeDirection}{ChangePercent:F2}%) " +
               $"成交量: {Volume:N0} 最高: {High:C} 最低: {Low:C} 开盘: {Open:C}";
    }
}

// 12. 股票市场类 - 另一个被观察者
public class StockMarket
{
    private readonly Dictionary<string, Stock> _stocks = new Dictionary<string, Stock>();
    private readonly List<WeakReference<IMarketObserver>> _observers = new List<WeakReference<IMarketObserver>>();
    private readonly ReaderWriterLockSlim _observersLock = new ReaderWriterLockSlim();
    private readonly ReaderWriterLockSlim _stocksLock = new ReaderWriterLockSlim();
    
    private MarketStatus _status = MarketStatus.Closed;
    public MarketStatus Status
    {
        get { return _status; }
        set
        {
            MarketStatus oldStatus = _status;
            if (oldStatus == value) return;
            
            _status = value;
            NotifyMarketStatusChanged(oldStatus, value);
        }
    }
    
    public string MarketName { get; set; }
    public DateTime MarketOpenTime { get; set; }
    public DateTime MarketCloseTime { get; set; }
    
    public StockMarket(string marketName)
    {
        MarketName = marketName;
    }
    
    // 添加观察者
    public void AddObserver(IMarketObserver observer)
    {
        _observersLock.EnterWriteLock();
        try
        {
            // 检查是否已经存在
            bool exists = false;
            foreach (var weakRef in _observers)
            {
                if (weakRef.TryGetTarget(out var existingObserver) && 
                    existingObserver.ObserverId == observer.ObserverId)
                {
                    exists = true;
                    break;
                }
            }
            
            if (!exists)
            {
                _observers.Add(new WeakReference<IMarketObserver>(observer));
                Console.WriteLine($"已添加市场观察者 {observer.ObserverId} 到市场 {MarketName}");
            }
        }
        finally
        {
            _observersLock.ExitWriteLock();
        }
    }
    
    // 移除观察者
    public void RemoveObserver(IMarketObserver observer)
    {
        _observersLock.EnterWriteLock();
        try
        {
            int index = -1;
            for (int i = 0; i < _observers.Count; i++)
            {
                if (_observers[i].TryGetTarget(out var target) && 
                    target.ObserverId == observer.ObserverId)
                {
                    index = i;
                    break;
                }
            }
            
            if (index >= 0)
            {
                _observers.RemoveAt(index);
                Console.WriteLine($"已移除市场观察者 {observer.ObserverId} 从市场 {MarketName}");
            }
        }
        finally
        {
            _observersLock.ExitWriteLock();
        }
    }
    
    // 通知市场状态变化
    private void NotifyMarketStatusChanged(MarketStatus oldStatus, MarketStatus newStatus)
    {
        // 准备事件参数
        var args = new MarketStatusChangedEventArgs(oldStatus, newStatus);
        
        // 创建观察者的本地副本以避免锁争用
        List<IMarketObserver> observers = GetObserversOrderedByPriority();
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnMarketStatusChanged(this, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"通知市场观察者 {observer.ObserverId} 状态变动时出错: {ex.Message}");
                }
            }
        });
    }
    
    // 获取按优先级排序的观察者列表
    private List<IMarketObserver> GetObserversOrderedByPriority()
    {
        var result = new List<IMarketObserver>();
        
        _observersLock.EnterReadLock();
        try
        {
            foreach (var weakRef in _observers)
            {
                if (weakRef.TryGetTarget(out var observer))
                {
                    result.Add(observer);
                }
            }
        }
        finally
        {
            _observersLock.ExitReadLock();
        }
        
        // 按优先级排序,高优先级在前
        return result.OrderByDescending(o => o.Priority).ToList();
    }
    
    // 添加股票
    public void AddStock(Stock stock)
    {
        _stocksLock.EnterWriteLock();
        try
        {
            if (!_stocks.ContainsKey(stock.Symbol))
            {
                _stocks.Add(stock.Symbol, stock);
                Console.WriteLine($"已添加股票 {stock.Symbol} 到市场 {MarketName}");
            }
        }
        finally
        {
            _stocksLock.ExitWriteLock();
        }
    }
    
    // 获取股票
    public Stock GetStock(string symbol)
    {
        _stocksLock.EnterReadLock();
        try
        {
            if (_stocks.TryGetValue(symbol, out var stock))
            {
                return stock;
            }
            
            return null;
        }
        finally
        {
            _stocksLock.ExitReadLock();
        }
    }
    
    // 更新股票价格
    public void UpdateStockPrice(string symbol, decimal newPrice)
    {
        Stock stock = GetStock(symbol);
        if (stock != null)
        {
            stock.Price = newPrice;
        }
    }
    
    // 更新股票交易量
    public void UpdateStockVolume(string symbol, long volumeChange)
    {
        Stock stock = GetStock(symbol);
        if (stock != null)
        {
            stock.Volume += volumeChange;
        }
    }
    
    // 执行交易
    public void ExecuteTrade(string symbol, TradeType tradeType, decimal price, 
                           int quantity, string buyerId, string sellerId)
    {
        Stock stock = GetStock(symbol);
        if (stock != null)
        {
            stock.ExecuteTrade(tradeType, price, quantity, buyerId, sellerId);
        }
    }
    
    // 打开市场
    public void OpenMarket()
    {
        if (Status != MarketStatus.Open)
        {
            Console.WriteLine($"市场 {MarketName} 开盘");
            Status = MarketStatus.Open;
            MarketOpenTime = DateTime.Now;
        }
    }
    
    // 关闭市场
    public void CloseMarket()
    {
        if (Status != MarketStatus.Closed)
        {
            Console.WriteLine($"市场 {MarketName} 收盘");
            Status = MarketStatus.Closed;
            MarketCloseTime = DateTime.Now;
            
            // 更新所有股票的收盘价
            _stocksLock.EnterReadLock();
            try
            {
                foreach (var stock in _stocks.Values)
                {
                    stock.SetClose(stock.Price);
                }
            }
            finally
            {
                _stocksLock.ExitReadLock();
            }
        }
    }
    
    // 开始新的交易日
    public void StartNewTradingDay()
    {
        Console.WriteLine($"市场 {MarketName} 开始新的交易日");
        
        _stocksLock.EnterReadLock();
        try
        {
            foreach (var stock in _stocks.Values)
            {
                // 假设新一天的开盘价为前一天收盘价的随机波动
                Random random = new Random();
                decimal variation = (decimal)(random.NextDouble() * 0.02 - 0.01); // -1% 到 +1% 的波动
                decimal openPrice = stock.Close * (1 + variation);
                openPrice = Math.Round(openPrice, 2);
                
                stock.SetNewDay(openPrice);
            }
        }
        finally
        {
            _stocksLock.ExitReadLock();
        }
    }
    
    // 显示市场状态
    public void DisplayMarketStatus()
    {
        Console.WriteLine($"\n=== {MarketName} 市场状态 ===");
        Console.WriteLine($"状态: {Status}");
        
        if (Status == MarketStatus.Open)
        {
            Console.WriteLine($"开盘时间: {MarketOpenTime:yyyy-MM-dd HH:mm:ss}");
            TimeSpan duration = DateTime.Now - MarketOpenTime;
            Console.WriteLine($"已开盘: {duration.Hours}小时 {duration.Minutes}分钟");
        }
        else if (Status == MarketStatus.Closed && MarketCloseTime != default)
        {
            Console.WriteLine($"收盘时间: {MarketCloseTime:yyyy-MM-dd HH:mm:ss}");
        }
        
        Console.WriteLine($"股票数量: {_stocks.Count}");
        
        _stocksLock.EnterReadLock();
        try
        {
            int gainers = 0;
            int losers = 0;
            int unchanged = 0;
            
            foreach (var stock in _stocks.Values)
            {
                decimal change = stock.Price - stock.PreviousClose;
                if (change > 0) gainers++;
                else if (change < 0) losers++;
                else unchanged++;
            }
            
            Console.WriteLine($"上涨: {gainers}, 下跌: {losers}, 持平: {unchanged}");
            
            // 显示表现最好和最差的股票
            if (_stocks.Count > 0)
            {
                var sortedStocks = _stocks.Values.OrderByDescending(s => 
                    (s.Price - s.PreviousClose) / (s.PreviousClose == 0 ? 1 : s.PreviousClose) * 100).ToList();
                
                if (sortedStocks.Count > 0)
                {
                    var bestStock = sortedStocks.First();
                    var worstStock = sortedStocks.Last();
                    
                    decimal bestChangePercent = bestStock.PreviousClose == 0 ? 0 : 
                        (bestStock.Price - bestStock.PreviousClose) / bestStock.PreviousClose * 100;
                    
                    decimal worstChangePercent = worstStock.PreviousClose == 0 ? 0 : 
                        (worstStock.Price - worstStock.PreviousClose) / worstStock.PreviousClose * 100;
                    
                    Console.WriteLine($"表现最佳: {bestStock.Symbol} {bestChangePercent:+0.00;-0.00}%");
                    Console.WriteLine($"表现最差: {worstStock.Symbol} {worstChangePercent:+0.00;-0.00}%");
                }
            }
        }
        finally
        {
            _stocksLock.ExitReadLock();
        }
    }
    
    // 显示所有股票
    public void DisplayAllStocks()
    {
        Console.WriteLine($"\n=== {MarketName} 所有股票 ===");
        
        _stocksLock.EnterReadLock();
        try
        {
            var sortedStocks = _stocks.Values.OrderByDescending(s => 
                (s.Price - s.PreviousClose) / (s.PreviousClose == 0 ? 1 : s.PreviousClose) * 100).ToList();
                
            foreach (var stock in sortedStocks)
            {
                var stats = stock.GetStatistics();
                Console.WriteLine(stats);
            }
        }
        finally
        {
            _stocksLock.ExitReadLock();
        }
    }
}

// 13. 投资者类 - 具体观察者
public class Investor : StockObserverBase, IMarketObserver
{
    public string Name { get; }
    public override int Priority => _priority;
    
    private int _priority;
    private readonly Dictionary<string, InvestorPosition> _portfolio = new Dictionary<string, InvestorPosition>();
    private readonly Dictionary<string, decimal> _alertThresholds = new Dictionary<string, decimal>();
    private readonly List<string> _watchlist = new List<string>();
    private decimal _cash;
    
    public Investor(string name, int priority, decimal initialCash) 
        : base("INV_" + name)
    {
        Name = name;
        _priority = priority;
        _cash = initialCash;
    }
    
    public void AddToWatchlist(string symbol)
    {
        if (!_watchlist.Contains(symbol))
        {
            _watchlist.Add(symbol);
            Console.WriteLine($"投资者 {Name} 添加 {symbol} 到观察列表");
        }
    }
    
    public void RemoveFromWatchlist(string symbol)
    {
        if (_watchlist.Contains(symbol))
        {
            _watchlist.Remove(symbol);
            Console.WriteLine($"投资者 {Name} 从观察列表移除 {symbol}");
        }
    }
    
    // 设置价格警报
    public void SetPriceAlert(string symbol, decimal threshold)
    {
        _alertThresholds[symbol] = threshold;
        Console.WriteLine($"投资者 {Name} 为 {symbol} 设置价格警报: {threshold:C}");
    }
    
    // 购买股票
    public void BuyStock(Stock stock, int quantity, decimal price)
    {
        decimal totalCost = price * quantity;
        
        if (_cash < totalCost)
        {
            Console.WriteLine($"投资者 {Name} 资金不足,无法购买 {quantity} 股 {stock.Symbol}");
            return;
        }
        
        // 更新资金
        _cash -= totalCost;
        
        // 更新持仓
        if (!_portfolio.TryGetValue(stock.Symbol, out var position))
        {
            position = new InvestorPosition(stock.Symbol);
            _portfolio[stock.Symbol] = position;
        }
        
        position.Buy(quantity, price);
        
        // 添加观察
        stock.AddObserver(this);
        
        Console.WriteLine($"投资者 {Name} 以 {price:C} 购买了 {quantity} 股 {stock.Symbol}, 总成本: {totalCost:C}, 剩余资金: {_cash:C}");
    }
    
    // 卖出股票
    public void SellStock(Stock stock, int quantity, decimal price)
    {
        if (!_portfolio.TryGetValue(stock.Symbol, out var position) || position.Quantity < quantity)
        {
            Console.WriteLine($"投资者 {Name} 持仓不足,无法卖出 {quantity} 股 {stock.Symbol}");
            return;
        }
        
        decimal totalProceeds = price * quantity;
        
        // 更新资金
        _cash += totalProceeds;
        
        // 更新持仓
        position.Sell(quantity, price);
        
        // 如果已经没有持仓,可以考虑移除观察者
        if (position.Quantity == 0)
        {
            stock.RemoveObserver(this);
            _portfolio.Remove(stock.Symbol);
        }
        
        Console.WriteLine($"投资者 {Name} 以 {price:C} 卖出了 {quantity} 股 {stock.Symbol}, 总收入: {totalProceeds:C}, 剩余资金: {_cash:C}");
    }
    
    // 观察者方法:处理价格变动
    public override void OnPriceChanged(object sender, PriceChangedEventArgs e)
    {
        if (sender is Stock stock)
        {
            // 检查是否在投资组合中
            bool isInPortfolio = _portfolio.ContainsKey(e.Symbol);
            
            // 检查是否在观察列表中
            bool isInWatchlist = _watchlist.Contains(e.Symbol);
            
            // 对于投资组合中的股票,计算收益
            if (isInPortfolio)
            {
                var position = _portfolio[e.Symbol];
                decimal oldValue = position.Quantity * e.OldPrice;
                decimal newValue = position.Quantity * e.NewPrice;
                decimal valueChange = newValue - oldValue;
                
                decimal totalCost = position.GetTotalCost();
                decimal currentValue = position.Quantity * e.NewPrice;
                decimal totalProfit = currentValue - totalCost;
                decimal totalProfitPercent = totalCost != 0 ? totalProfit / totalCost * 100 : 0;
                
                string changeDirection = e.ChangePercent >= 0 ? "上涨" : "下跌";
                
                // 只有当价格变动超过一定阈值时才打印消息
                if (Math.Abs(e.ChangePercent) >= 0.5m)
                {
                    Console.WriteLine($"投资者 {Name}: {e.Symbol} 价格{changeDirection}到 {e.NewPrice:C} ({e.ChangePercent:+0.00;-0.00}%), " +
                                  $"持有 {position.Quantity} 股, 持仓价值变动: {valueChange:+0.00;-0.00}, " +
                                  $"总成本: {totalCost:C}, 当前价值: {currentValue:C}, 总收益: {totalProfit:C} ({totalProfitPercent:+0.00;-0.00}%)");
                }
            }
            
            // 检查是否触发价格警报
            if (_alertThresholds.TryGetValue(e.Symbol, out decimal threshold))
            {
                if ((e.OldPrice < threshold && e.NewPrice >= threshold) || 
                    (e.OldPrice > threshold && e.NewPrice <= threshold))
                {
                    Console.WriteLine($"⚠️ 价格警报! 投资者 {Name}: {e.Symbol} 价格 {e.NewPrice:C} 已{(e.NewPrice >= threshold ? "超过" : "低于")}警报阈值 {threshold:C}");
                }
            }
            
            // 对于观察列表中的股票,考虑买入或卖出的时机
            if (isInWatchlist && !isInPortfolio)
            {
                // 示例:如果价格下跌超过3%,考虑买入
                if (e.ChangePercent <= -3.0m)
                {
                    Console.WriteLine($"提示: 投资者 {Name} 可能需要考虑买入 {e.Symbol} (价格下跌 {e.ChangePercent:0.00}%)");
                }
            }
        }
    }
    
    // 观察者方法:处理交易量变动
    public override void OnVolumeChanged(object sender, VolumeChangedEventArgs e)
    {
        // 示例:只关注大量交易
        if (e.VolumeChange > 1000000)
        {
            Console.WriteLine($"投资者 {Name} 注意到 {e.Symbol} 出现大量交易: {e.VolumeChange:N0} 股");
        }
    }
    
    // 观察者方法:处理交易事件
    public override void OnStockTrade(object sender, StockTradeEventArgs e)
    {
        // 只关注大笔交易
        if (e.TotalValue > 1000000)
        {
            Console.WriteLine($"投资者 {Name} 注意到 {e.Symbol} 发生大笔交易: {e.Quantity:N0} 股 @ {e.Price:C}, 总值: {e.TotalValue:C}");
        }
    }
    
    // 市场观察者方法:处理市场状态变化
    public void OnMarketStatusChanged(object sender, MarketStatusChangedEventArgs e)
    {
        if (sender is StockMarket market)
        {
            Console.WriteLine($"投资者 {Name} 注意到市场 {market.MarketName} 状态从 {e.OldStatus} 变为 {e.NewStatus}");
            
            switch (e.NewStatus)
            {
                case MarketStatus.Open:
                    Console.WriteLine($"投资者 {Name} 准备开始交易");
                    break;
                case MarketStatus.Closed:
                    // 计算当日收益
                    CalculateDailyPerformance();
                    break;
            }
        }
    }
    
    // 计算当日表现
    private void CalculateDailyPerformance()
    {
        decimal totalPortfolioValue = 0;
        decimal totalCost = 0;
        
        foreach (var position in _portfolio.Values)
        {
            totalPortfolioValue += position.CurrentValue;
            totalCost += position.GetTotalCost();
        }
        
        decimal totalEquity = totalPortfolioValue + _cash;
        decimal totalProfit = totalPortfolioValue - totalCost;
        decimal returnPercent = totalCost != 0 ? totalProfit / totalCost * 100 : 0;
        
        Console.WriteLine($"\n=== 投资者 {Name} 当日表现 ===");
        Console.WriteLine($"投资组合价值: {totalPortfolioValue:C}");
        Console.WriteLine($"现金: {_cash:C}");
        Console.WriteLine($"总资产: {totalEquity:C}");
        Console.WriteLine($"总成本: {totalCost:C}");
        Console.WriteLine($"总收益: {totalProfit:C} ({returnPercent:+0.00;-0.00}%)");
        
        if (_portfolio.Count > 0)
        {
            Console.WriteLine("\n持仓明细:");
            foreach (var entry in _portfolio)
            {
                var position = entry.Value;
                decimal positionProfit = position.CurrentValue - position.GetTotalCost();
                decimal positionReturnPercent = position.GetTotalCost() != 0 ? positionProfit / position.GetTotalCost() * 100 : 0;
                
                Console.WriteLine($"  {entry.Key}: {position.Quantity} 股 @ 均价 {position.AverageCost:C}, " +
                               $"当前价值: {position.CurrentValue:C}, 收益: {positionProfit:C} ({positionReturnPercent:+0.00;-0.00}%)");
            }
        }
    }
    
    // 显示投资者信息
    public void DisplayInvestorInfo()
    {
        Console.WriteLine($"\n=== 投资者 {Name} 信息 ===");
        Console.WriteLine($"现金: {_cash:C}");
        Console.WriteLine($"优先级: {Priority}");
        
        if (_portfolio.Count > 0)
        {
            decimal totalValue = 0;
            
            Console.WriteLine("\n持仓:");
            foreach (var entry in _portfolio)
            {
                var position = entry.Value;
                totalValue += position.CurrentValue;
                
                Console.WriteLine($"  {entry.Key}: {position.Quantity} 股 @ 均价 {position.AverageCost:C}, 当前价值: {position.CurrentValue:C}");
            }
            
            decimal totalEquity = totalValue + _cash;
            Console.WriteLine($"\n总资产: {totalEquity:C} (现金: {_cash:C}, 持仓: {totalValue:C})");
        }
        else
        {
            Console.WriteLine("持仓: 无");
            Console.WriteLine($"总资产: {_cash:C}");
        }
        
        if (_watchlist.Count > 0)
        {
            Console.WriteLine("\n观察列表:");
            foreach (var symbol in _watchlist)
            {
                Console.WriteLine($"  {symbol}");
            }
        }
        
        if (_alertThresholds.Count > 0)
        {
            Console.WriteLine("\n价格警报:");
            foreach (var alert in _alertThresholds)
            {
                Console.WriteLine($"  {alert.Key}: {alert.Value:C}");
            }
        }
    }
}

// 14. 投资者持仓类
public class InvestorPosition
{
    public string Symbol { get; }
    public int Quantity { get; private set; }
    public decimal AverageCost { get; private set; }
    public decimal CurrentValue { get; private set; }
    
    private decimal _totalCost;
    
    public InvestorPosition(string symbol)
    {
        Symbol = symbol;
        Quantity = 0;
        AverageCost = 0;
        _totalCost = 0;
    }
    
    public void Buy(int quantity, decimal price)
    {
        decimal newCost = quantity * price;
        _totalCost += newCost;
        Quantity += quantity;
        AverageCost = _totalCost / Quantity;
        
        // 更新当前价值
        CurrentValue = Quantity * price;
    }
    
    public void Sell(int quantity, decimal price)
    {
        if (quantity > Quantity)
        {
            throw new ArgumentException("卖出数量不能大于持仓数量");
        }
        
        decimal soldCost = quantity * AverageCost;
        _totalCost -= soldCost;
        Quantity -= quantity;
        
        // 如果全部卖出,重置平均成本
        if (Quantity == 0)
        {
            AverageCost = 0;
        }
        
        // 更新当前价值
        CurrentValue = Quantity * price;
    }
    
    public void UpdateValue(decimal price)
    {
        CurrentValue = Quantity * price;
    }
    
    public decimal GetTotalCost()
    {
        return _totalCost;
    }
}

// 15. 市场分析师 - 另一个具体观察者
public class MarketAnalyst : StockObserverBase, IMarketObserver
{
    public string AnalystName { get; }
    public override int Priority => 10; // 分析师有更高的优先级
    
    private readonly Dictionary<string, List<decimal>> _priceHistory = new Dictionary<string, List<decimal>>();
    private readonly Dictionary<string, MovingAverage> _movingAverages = new Dictionary<string, MovingAverage>();
    private readonly Dictionary<string, StockRecommendation> _recommendations = new Dictionary<string, StockRecommendation>();
    
    public MarketAnalyst(string name) : base("ANALYST_" + name)
    {
        AnalystName = name;
    }
    
    // 观察者方法:处理价格变动
    public override void OnPriceChanged(object sender, PriceChangedEventArgs e)
    {
        // 记录价格历史
        if (!_priceHistory.ContainsKey(e.Symbol))
        {
            _priceHistory[e.Symbol] = new List<decimal>();
            _movingAverages[e.Symbol] = new MovingAverage(20); // 20天移动平均
        }
        
        _priceHistory[e.Symbol].Add(e.NewPrice);
        _movingAverages[e.Symbol].AddPrice(e.NewPrice);
        
        // 分析价格并生成建议
        AnalyzePrice(e.Symbol, e.NewPrice);
    }
    
    // 分析价格
    private void AnalyzePrice(string symbol, decimal currentPrice)
    {
        var ma = _movingAverages[symbol];
        decimal maValue = ma.GetAverage();
        
        if (ma.IsReady) // 确保有足够的数据点
        {
            StockRecommendation recommendation;
            
            if (!_recommendations.TryGetValue(symbol, out recommendation))
            {
                recommendation = new StockRecommendation { Symbol = symbol };
                _recommendations[symbol] = recommendation;
            }
            
            // 更新建议
            StockRecommendation.Action oldAction = recommendation.RecommendedAction;
            
            // 简单的交叉策略:当价格上穿均线,生成买入信号;当价格下穿均线,生成卖出信号
            if (currentPrice > maValue && recommendation.LastPrice <= maValue)
            {
                recommendation.RecommendedAction = StockRecommendation.Action.Buy;
                recommendation.Reason = $"价格 ({currentPrice:C}) 上穿 {ma.Period} 日均线 ({maValue:C})";
                recommendation.Price = currentPrice;
                recommendation.Date = DateTime.Now;
                
                if (oldAction != StockRecommendation.Action.Buy)
                {
                    Console.WriteLine($"分析师 {AnalystName} 建议: 买入 {symbol} @ {currentPrice:C} - {recommendation.Reason}");
                }
            }
            else if (currentPrice < maValue && recommendation.LastPrice >= maValue)
            {
                recommendation.RecommendedAction = StockRecommendation.Action.Sell;
                recommendation.Reason = $"价格 ({currentPrice:C}) 下穿 {ma.Period} 日均线 ({maValue:C})";
                recommendation.Price = currentPrice;
                recommendation.Date = DateTime.Now;
                
                if (oldAction != StockRecommendation.Action.Sell)
                {
                    Console.WriteLine($"分析师 {AnalystName} 建议: 卖出 {symbol} @ {currentPrice:C} - {recommendation.Reason}");
                }
            }
            else if (Math.Abs(currentPrice - maValue) / maValue < 0.01m)
            {
                recommendation.RecommendedAction = StockRecommendation.Action.Hold;
                recommendation.Reason = $"价格 ({currentPrice:C}) 接近 {ma.Period} 日均线 ({maValue:C})";
                recommendation.Price = currentPrice;
                recommendation.Date = DateTime.Now;
            }
            
            recommendation.LastPrice = currentPrice;
        }
    }
    
    // 观察者方法:处理交易量变动
    public override void OnVolumeChanged(object sender, VolumeChangedEventArgs e)
    {
        // 分析师对异常交易量感兴趣
        if (e.VolumeChange > 500000)
        {
            Console.WriteLine($"分析师 {AnalystName} 注意到 {e.Symbol} 交易量突然增加 {e.VolumeChange:N0} 股,可能表明有重要消息");
        }
    }
    
    // 观察者方法:处理交易事件
    public override void OnStockTrade(object sender, StockTradeEventArgs e)
    {
        // 分析师对大宗交易特别感兴趣
        if (e.TotalValue > 5000000)
        {
            Console.WriteLine($"分析师 {AnalystName} 注意到 {e.Symbol} 发生大宗交易: {e.Quantity:N0} 股 @ {e.Price:C} (总值: {e.TotalValue:C})");
        }
    }
    
    // 市场观察者方法:处理市场状态变化
    public void OnMarketStatusChanged(object sender, MarketStatusChangedEventArgs e)
    {
        if (sender is StockMarket market)
        {
            Console.WriteLine($"分析师 {AnalystName} 注意到市场 {market.MarketName} 状态从 {e.OldStatus} 变为 {e.NewStatus}");
            
            switch (e.NewStatus)
            {
                case MarketStatus.Open:
                    Console.WriteLine($"分析师 {AnalystName} 准备开始新的交易日分析");
                    break;
                case MarketStatus.Closed:
                    // 生成每日市场报告
                    GenerateMarketReport(market);
                    break;
            }
        }
    }
    
    // 生成市场报告
    private void GenerateMarketReport(StockMarket market)
    {
        Console.WriteLine($"\n=== 分析师 {AnalystName} 的市场日报 ===");
        Console.WriteLine($"日期: {DateTime.Now:yyyy-MM-dd}");
        
        Console.WriteLine("\n最新投资建议:");
        foreach (var recommendation in _recommendations.Values)
        {
            string actionText = recommendation.RecommendedAction switch
            {
                StockRecommendation.Action.Buy => "买入",
                StockRecommendation.Action.Sell => "卖出",
                StockRecommendation.Action.Hold => "持有",
                _ => "观望"
            };
            
            Console.WriteLine($"  {recommendation.Symbol}: {actionText} @ {recommendation.Price:C} - {recommendation.Reason}");
        }
    }
    
    // 获取特定股票的建议
    public StockRecommendation GetRecommendation(string symbol)
    {
        if (_recommendations.TryGetValue(symbol, out var recommendation))
        {
            return recommendation;
        }
        
        return new StockRecommendation 
        { 
            Symbol = symbol, 
            RecommendedAction = StockRecommendation.Action.Hold,
            Reason = "暂无足够数据进行分析"
        };
    }
    
    // 显示分析师信息
    public void DisplayAnalystInfo()
    {
        Console.WriteLine($"\n=== 分析师 {AnalystName} 信息 ===");
        Console.WriteLine($"跟踪的股票数量: {_priceHistory.Count}");
        
        if (_recommendations.Count > 0)
        {
            Console.WriteLine("\n当前投资建议:");
            foreach (var recommendation in _recommendations.Values)
            {
                string actionText = recommendation.RecommendedAction switch
                {
                    StockRecommendation.Action.Buy => "买入",
                    StockRecommendation.Action.Sell => "卖出",
                    StockRecommendation.Action.Hold => "持有",
                    _ => "观望"
                };
                
                Console.WriteLine($"  {recommendation.Symbol}: {actionText} @ {recommendation.Price:C} - {recommendation.Reason}");
            }
        }
    }
}

// 16. 移动平均线
public class MovingAverage
{
    private readonly Queue<decimal> _prices = new Queue<decimal>();
    private decimal _sum = 0;
    public int Period { get; }
    public bool IsReady => _prices.Count >= Period;
    
    public MovingAverage(int period)
    {
        Period = period;
    }
    
    public void AddPrice(decimal price)
    {
        _prices.Enqueue(price);
        _sum += price;
        
        if (_prices.Count > Period)
        {
            _sum -= _prices.Dequeue();
        }
    }
    
    public decimal GetAverage()
    {
        if (_prices.Count == 0) return 0;
        return _sum / _prices.Count;
    }
}

// 17. 股票推荐
public class StockRecommendation
{
    public enum Action
    {
        Buy,
        Sell,
        Hold,
        Watch
    }
    
    public string Symbol { get; set; }
    public Action RecommendedAction { get; set; } = Action.Watch;
    public string Reason { get; set; }
    public decimal Price { get; set; }
    public DateTime Date { get; set; }
    public decimal LastPrice { get; set; }
}

// 18. 市场新闻服务 - 另一个具体观察者
public class MarketNewsService : IMarketObserver
{
    public string ObserverId => "NEWS_SERVICE";
    public int Priority => 5;
    
    private readonly List<StockNewsItem> _newsItems = new List<StockNewsItem>();
    private readonly Random _random = new Random();
    
    // 市场状态变化处理
    public void OnMarketStatusChanged(object sender, MarketStatusChangedEventArgs e)
    {
        if (sender is StockMarket market)
        {
            GenerateMarketStatusNews(market, e.OldStatus, e.NewStatus);
        }
    }
    
    // 生成市场状态新闻
    private void GenerateMarketStatusNews(StockMarket market, MarketStatus oldStatus, MarketStatus newStatus)
    {
        string newsTitle = "";
        string newsContent = "";
        
        switch (newStatus)
        {
            case MarketStatus.Open:
                newsTitle = $"{market.MarketName} 开盘";
                newsContent = $"{market.MarketName} 已于今日 {DateTime.Now:HH:mm} 开盘。市场预期今日将继续关注宏观经济数据和企业财报。";
                break;
            case MarketStatus.Closed:
                newsTitle = $"{market.MarketName} 收盘";
                newsContent = $"{market.MarketName} 已于今日 {DateTime.Now:HH:mm} 收盘。";
                break;
            case MarketStatus.Halted:
                newsTitle = $"{market.MarketName} 交易暂停";
                newsContent = $"{market.MarketName} 交易已暂停。监管机构正在调查可能的异常交易行为。";
                break;
        }
        
        if (!string.IsNullOrEmpty(newsTitle))
        {
            var newsItem = new StockNewsItem
            {
                Title = newsTitle,
                Content = newsContent,
                PublishTime = DateTime.Now,
                RelatedSymbols = new List<string>(),
                Category = "市场动态"
            };
            
            _newsItems.Add(newsItem);
            PublishNews(newsItem);
        }
    }
    
    // 生成股票相关新闻
    public void GenerateStockNews(Stock stock, string newsType)
    {
        string newsTitle = "";
        string newsContent = "";
        
        switch (newsType)
        {
            case "earnings":
                bool isPositive = _random.Next(2) == 0;
                newsTitle = $"{stock.Symbol} 公布{(isPositive ? "优于" : "低于")}预期的季度财报";
                newsContent = $"{stock.Symbol} 今日公布了最新季度财报,每股收益{(isPositive ? "超过" : "未达到")}分析师预期。";
                break;
            case "upgrade":
                newsTitle = $"分析师上调 {stock.Symbol} 评级";
                newsContent = $"多家投行分析师上调了对 {stock.Symbol} 的投资评级,目标价上调至 {stock.Price * 1.2m:C}。";
                break;
            case "downgrade":
                newsTitle = $"分析师下调 {stock.Symbol} 评级";
                newsContent = $"部分分析师下调了对 {stock.Symbol} 的投资评级,担忧其业绩增长放缓。";
                break;
            case "merger":
                newsTitle = $"{stock.Symbol} 宣布并购计划";
                newsContent = $"{stock.Symbol} 今日宣布计划收购竞争对手,交易价值预计超过10亿美元。";
                break;
        }
        
        if (!string.IsNullOrEmpty(newsTitle))
        {
            var newsItem = new StockNewsItem
            {
                Title = newsTitle,
                Content = newsContent,
                PublishTime = DateTime.Now,
                RelatedSymbols = new List<string> { stock.Symbol },
                Category = "公司新闻"
            };
            
            _newsItems.Add(newsItem);
            PublishNews(newsItem);
        }
    }
    
    // 发布新闻
    private void PublishNews(StockNewsItem newsItem)
    {
        Console.WriteLine($"\n📰 {newsItem.Category} | {newsItem.PublishTime:HH:mm:ss}");
        Console.WriteLine($"标题: {newsItem.Title}");
        Console.WriteLine($"内容: {newsItem.Content}");
        
        if (newsItem.RelatedSymbols.Count > 0)
        {
            Console.WriteLine($"相关股票: {string.Join(", ", newsItem.RelatedSymbols)}");
        }
    }
    
    // 获取最近新闻
    public List<StockNewsItem> GetRecentNews(int count = 5)
    {
        return _newsItems.OrderByDescending(n => n.PublishTime).Take(count).ToList();
    }
    
    // 获取特定股票的新闻
    public List<StockNewsItem> GetNewsForStock(string symbol, int count = 5)
    {
        return _newsItems
            .Where(n => n.RelatedSymbols.Contains(symbol))
            .OrderByDescending(n => n.PublishTime)
            .Take(count)
            .ToList();
    }
}

// 19. 股票新闻项
public class StockNewsItem
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishTime { get; set; }
    public List<string> RelatedSymbols { get; set; } = new List<string>();
    public string Category { get; set; }
}

// 20. 模拟交易引擎
public class TradingEngine : IMarketObserver
{
    public string ObserverId => "TRADING_ENGINE";
    public int Priority => 100; // 交易引擎需要最高优先级
    
    private readonly StockMarket _market;
    private readonly ConcurrentQueue<TradeOrder> _orderQueue = new ConcurrentQueue<TradeOrder>();
    private readonly List<TradeOrder> _executedOrders = new List<TradeOrder>();
    private readonly List<TradeOrder> _pendingOrders = new List<TradeOrder>();
    private readonly Random _random = new Random();
    private bool _isProcessing;
    private readonly object _processingLock = new object();
    
    public TradingEngine(StockMarket market)
    {
        _market = market;
        _market.AddObserver(this);
    }
    
    // 提交订单
    public void SubmitOrder(TradeOrder order)
    {
        if (_market.Status != MarketStatus.Open)
        {
            Console.WriteLine($"无法提交订单:市场已关闭");
            return;
        }
        
        _orderQueue.Enqueue(order);
        Console.WriteLine($"订单已提交: {order}");
        
        // 启动处理队列
        ProcessOrdersAsync();
    }
    
    // 异步处理订单队列
    private async void ProcessOrdersAsync()
    {
        bool lockTaken = false;
        try
        {
            Monitor.TryEnter(_processingLock, ref lockTaken);
            
            if (!lockTaken || _isProcessing)
                return;
                
            _isProcessing = true;
            
            while (_orderQueue.TryDequeue(out var order))
            {
                // 模拟处理时间
                await Task.Delay(100 + _random.Next(200));
                
                bool executed = false;
                
                try
                {
                    executed = ExecuteOrder(order);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"处理订单时出错: {ex.Message}");
                }
                
                if (executed)
                {
                    _executedOrders.Add(order);
                }
                else
                {
                    _pendingOrders.Add(order);
                }
            }
        }
        finally
        {
            _isProcessing = false;
            
            if (lockTaken)
            {
                Monitor.Exit(_processingLock);
            }
        }
    }
    
    // 执行订单
    private bool ExecuteOrder(TradeOrder order)
    {
        // 获取当前股票
        Stock stock = _market.GetStock(order.Symbol);
        
        if (stock == null)
        {
            Console.WriteLine($"无法执行订单:找不到股票 {order.Symbol}");
            return false;
        }
        
        // 根据订单类型执行
        switch (order.OrderType)
        {
            case OrderType.Market:
                // 市价单直接执行
                decimal executionPrice = stock.Price;
                
                // 模拟轻微的滑点
                double slippage = _random.NextDouble() * 0.01 - 0.005; // -0.5% 到 +0.5%
                executionPrice *= 1 + (decimal)slippage;
                executionPrice = Math.Round(executionPrice, 2);
                
                _market.ExecuteTrade(
                    order.Symbol, 
                    order.Side == OrderSide.Buy ? TradeType.Buy : TradeType.Sell, 
                    executionPrice, 
                    order.Quantity, 
                    order.Side == OrderSide.Buy ? order.AccountId : "MARKET",
                    order.Side == OrderSide.Sell ? order.AccountId : "MARKET");
                
                order.ExecutionPrice = executionPrice;
                order.ExecutionTime = DateTime.Now;
                order.Status = OrderStatus.Executed;
                
                Console.WriteLine($"订单已执行: {order}");
                return true;
                
            case OrderType.Limit:
                // 限价单
                bool canExecute = false;
                
                if (order.Side == OrderSide.Buy && stock.Price <= order.LimitPrice)
                {
                    canExecute = true;
                }
                else if (order.Side == OrderSide.Sell && stock.Price >= order.LimitPrice)
                {
                    canExecute = true;
                }
                
                if (canExecute)
                {
                    _market.ExecuteTrade(
                        order.Symbol, 
                        order.Side == OrderSide.Buy ? TradeType.Buy : TradeType.Sell, 
                        order.LimitPrice, 
                        order.Quantity, 
                        order.Side == OrderSide.Buy ? order.AccountId : "MARKET",
                        order.Side == OrderSide.Sell ? order.AccountId : "MARKET");
                    
                    order.ExecutionPrice = order.LimitPrice;
                    order.ExecutionTime = DateTime.Now;
                    order.Status = OrderStatus.Executed;
                    
                    Console.WriteLine($"限价单已执行: {order}");
                    return true;
                }
                else
                {
                    order.Status = OrderStatus.Pending;
                    Console.WriteLine($"限价单未达成条件,等待中: {order}");
                    return false;
                }
                
            default:
                Console.WriteLine($"不支持的订单类型: {order.OrderType}");
                return false;
        }
    }
    
    // 处理市场状态变化
    public void OnMarketStatusChanged(object sender, MarketStatusChangedEventArgs e)
    {
        if (e.NewStatus == MarketStatus.Closed)
        {
            // 市场关闭时,取消所有待处理订单
            foreach (var order in _pendingOrders)
            {
                order.Status = OrderStatus.Canceled;
                Console.WriteLine($"市场关闭,订单已取消: {order}");
            }
            
            _pendingOrders.Clear();
            
            // 清空队列
            while (_orderQueue.TryDequeue(out _)) { }
            
            // 生成交易报告
            GenerateTradingReport();
        }
    }
    
    // 生成交易报告
    private void GenerateTradingReport()
    {
        Console.WriteLine("\n=== 交易引擎日报 ===");
        Console.WriteLine($"已执行订单数: {_executedOrders.Count}");
        
        int buyOrders = _executedOrders.Count(o => o.Side == OrderSide.Buy);
        int sellOrders = _executedOrders.Count(o => o.Side == OrderSide.Sell);
        
        Console.WriteLine($"买入订单: {buyOrders}, 卖出订单: {sellOrders}");
        
        if (_executedOrders.Count > 0)
        {
            decimal totalValue = _executedOrders.Sum(o => o.ExecutionPrice * o.Quantity);
            Console.WriteLine($"总交易额: {totalValue:C}");
            
            var topSymbols = _executedOrders
                .GroupBy(o => o.Symbol)
                .Select(g => new 
                { 
                    Symbol = g.Key, 
                    Count = g.Count(),
                    Volume = g.Sum(o => o.Quantity),
                    Value = g.Sum(o => o.ExecutionPrice * o.Quantity)
                })
                .OrderByDescending(x => x.Value)
                .Take(5);
                
            Console.WriteLine("\n交易量最大的股票:");
            foreach (var symbol in topSymbols)
            {
                Console.WriteLine($"  {symbol.Symbol}: {symbol.Count} 笔订单, {symbol.Volume} 股, 总额 {symbol.Value:C}");
            }
        }
        
        // 清除已执行订单
        _executedOrders.Clear();
    }
}

// 21. 交易订单
public class TradeOrder
{
    public string OrderId { get; } = Guid.NewGuid().ToString().Substring(0, 8);
    public string AccountId { get; set; }
    public string Symbol { get; set; }
    public OrderSide Side { get; set; }
    public OrderType OrderType { get; set; }
    public int Quantity { get; set; }
    public decimal LimitPrice { get; set; }
    public OrderStatus Status { get; set; } = OrderStatus.Created;
    public DateTime CreationTime { get; } = DateTime.Now;
    public DateTime? ExecutionTime { get; set; }
    public decimal? ExecutionPrice { get; set; }
    
    public override string ToString()
    {
        string sideText = Side == OrderSide.Buy ? "买入" : "卖出";
        string typeText = OrderType == OrderType.Market ? "市价" : $"限价 ({LimitPrice:C})";
        string statusText = Status.ToString();
        string executionInfo = ExecutionPrice.HasValue ? $", 成交价: {ExecutionPrice:C}" : "";
        
        return $"订单 {OrderId}: {sideText} {Quantity} 股 {Symbol}, {typeText}, 状态: {statusText}{executionInfo}";
    }
}

// 22. 订单相关枚举
public enum OrderSide
{
    Buy,
    Sell
}

public enum OrderType
{
    Market,
    Limit,
    Stop,
    StopLimit
}

public enum OrderStatus
{
    Created,
    Pending,
    PartiallyExecuted,
    Executed,
    Canceled,
    Rejected
}

// 23. 客户端代码
public class Client
{
    public static async Task Main()
    {
        // 创建股票市场
        StockMarket market = new StockMarket("纳斯达克");
        
        // 创建交易引擎
        TradingEngine tradingEngine = new TradingEngine(market);
        
        // 创建新闻服务
        MarketNewsService newsService = new MarketNewsService();
        market.AddObserver(newsService);
        
        // 创建股票
        var stocks = new List<Stock>
        {
            new Stock("MSFT", 239.82m, 5000000),
            new Stock("AAPL", 145.43m, 8000000),
            new Stock("GOOG", 2850.41m, 2000000),
            new Stock("AMZN", 3347.15m, 3000000),
            new Stock("FB", 335.45m, 4000000),
            new Stock("TSLA", 752.92m, 7000000),
            new Stock("NVDA", 225.36m, 6000000),
            new Stock("PYPL", 272.90m, 2500000),
            new Stock("NFLX", 625.14m, 1500000),
            new Stock("ADBE", 673.66m, 1200000),
        };
        
        // 添加股票到市场
        foreach (var stock in stocks)
        {
            market.AddStock(stock);
        }
        
        // 创建分析师
        MarketAnalyst analyst = new MarketAnalyst("王分析");
        
        // 让分析师关注所有股票
        foreach (var stock in stocks)
        {
            stock.AddObserver(analyst);
        }
        
        // 分析师也观察市场
        market.AddObserver(analyst);
        
        // 创建投资者
        List<Investor> investors = new List<Investor>
        {
            new Investor("张大户", 3, 1000000m),
            new Investor("李小散", 1, 50000m),
            new Investor("王专业", 5, 500000m)
        };
        
        // 投资者关注市场
        foreach (var investor in investors)
        {
            market.AddObserver(investor);
        }
        
        // 投资者购买股票
        investors[0].BuyStock(market.GetStock("MSFT"), 500, 240.50m);
        investors[0].BuyStock(market.GetStock("AAPL"), 800, 146.25m);
        investors[0].BuyStock(market.GetStock("TSLA"), 200, 755.40m);
        
        investors[1].BuyStock(market.GetStock("MSFT"), 20, 240.75m);
        investors[1].BuyStock(market.GetStock("NFLX"), 15, 626.50m);
        
        investors[2].BuyStock(market.GetStock("GOOG"), 30, 2855.25m);
        investors[2].BuyStock(market.GetStock("AMZN"), 40, 3350.80m);
        investors[2].BuyStock(market.GetStock("NVDA"), 100, 226.50m);
        
        // 设置价格警报
        investors[0].SetPriceAlert("MSFT", 245.00m);
        investors[1].SetPriceAlert("NFLX", 630.00m);
        investors[2].SetPriceAlert("NVDA", 230.00m);
        
        // 添加观察列表
        investors[0].AddToWatchlist("NVDA");
        investors[0].AddToWatchlist("FB");
        
        investors[1].AddToWatchlist("AMZN");
        investors[1].AddToWatchlist("PYPL");
        
        investors[2].AddToWatchlist("TSLA");
        investors[2].AddToWatchlist("AAPL");
        
        // 开始交易日
        Console.WriteLine("\n=== 开始交易日 ===");
        market.OpenMarket();
        
        // 模拟交易日活动
        await SimulateTradingDay(market, tradingEngine, newsService, investors);
        
        // 显示交易日结束时的市场状态
        market.DisplayMarketStatus();
        market.DisplayAllStocks();
        
        // 显示投资者信息
        foreach (var investor in investors)
        {
            investor.DisplayInvestorInfo();
        }
        
        // 显示分析师信息
        analyst.DisplayAnalystInfo();
        
        // 关闭市场
        market.CloseMarket();
    }
    
    // 模拟交易日活动
    private static async Task SimulateTradingDay(
        StockMarket market, 
        TradingEngine tradingEngine, 
        MarketNewsService newsService,
        List<Investor> investors)
    {
        Random random = new Random();
        
        // 模拟10个交易时段
        for (int period = 1; period <= 10; period++)
        {
            Console.WriteLine($"\n=== 交易时段 {period} ===");
            
            // 更新所有股票价格
            foreach (var symbol in new[] { "MSFT", "AAPL", "GOOG", "AMZN", "FB", "TSLA", "NVDA", "PYPL", "NFLX", "ADBE" })
            {
                var stock = market.GetStock(symbol);
                if (stock != null)
                {
                    // 随机价格波动,-2%到+2%
                    decimal change = (decimal)(random.NextDouble() * 0.04 - 0.02);
                    decimal newPrice = stock.Price * (1 + change);
                    newPrice = Math.Round(newPrice, 2); // 四舍五入到分
                    
                    market.UpdateStockPrice(symbol, newPrice);
                    
                    // 随机交易量
                    long volumeChange = random.Next(50000, 500000);
                    market.UpdateStockVolume(symbol, volumeChange);
                }
            }
            
            // 随机生成一些新闻
            if (random.Next(10) < 3) // 30%的概率
            {
                string symbol = new[] { "MSFT", "AAPL", "GOOG", "AMZN", "FB", "TSLA", "NVDA", "PYPL", "NFLX", "ADBE" }[random.Next(10)];
                string newsType = new[] { "earnings", "upgrade", "downgrade", "merger" }[random.Next(4)];
                
                newsService.GenerateStockNews(market.GetStock(symbol), newsType);
            }
            
            // 随机生成一些交易订单
            int orderCount = random.Next(1, 5);
            for (int i = 0; i < orderCount; i++)
            {
                string symbol = new[] { "MSFT", "AAPL", "GOOG", "AMZN", "FB", "TSLA", "NVDA", "PYPL", "NFLX", "ADBE" }[random.Next(10)];
                var stock = market.GetStock(symbol);
                
                if (stock != null)
                {
                    // 创建订单
                    var order = new TradeOrder
                    {
                        AccountId = $"ACC{random.Next(1000, 9999)}",
                        Symbol = symbol,
                        Side = (OrderSide)random.Next(2),
                        OrderType = (OrderType)random.Next(2),
                        Quantity = random.Next(10, 1000)
                    };
                    
                    if (order.OrderType == OrderType.Limit)
                    {
                        // 限价单的价格设为当前价格的随机波动
                        decimal limitPriceChange = (decimal)(random.NextDouble() * 0.04 - 0.02);
                        order.LimitPrice = Math.Round(stock.Price * (1 + limitPriceChange), 2);
                    }
                    
                    tradingEngine.SubmitOrder(order);
                }
            }
            
            // 随机让投资者做一些操作
            if (random.Next(10) < 7) // 70%的概率
            {
                var investor = investors[random.Next(investors.Count)];
                string symbol = new[] { "MSFT", "AAPL", "GOOG", "AMZN", "FB", "TSLA", "NVDA", "PYPL", "NFLX", "ADBE" }[random.Next(10)];
                var stock = market.GetStock(symbol);
                
                if (stock != null)
                {
                    int action = random.Next(3);
                    
                    switch (action)
                    {
                        case 0: // 买入
                            int buyQuantity = random.Next(10, 50);
                            investor.BuyStock(stock, buyQuantity, stock.Price);
                            break;
                        case 1: // 卖出
                            // 检查是否持有该股票
                            if (investor.GetInvestorInfo().portfolio.TryGetValue(symbol, out var position) && position.Quantity > 0)
                            {
                                int sellQuantity = random.Next(1, position.Quantity + 1);
                                investor.SellStock(stock, sellQuantity, stock.Price);
                            }
                            break;
                        case 2: // 设置警报或添加到观察列表
                            if (random.Next(2) == 0)
                            {
                                decimal alertPrice = stock.Price * (1 + (decimal)(random.NextDouble() * 0.1 - 0.05));
                                investor.SetPriceAlert(symbol, alertPrice);
                            }
                            else
                            {
                                investor.AddToWatchlist(symbol);
                            }
                            break;
                    }
                }
            }
            
            // 等待一段时间
            await Task.Delay(1000);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101

业务场景结合:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;

// 企业系统监控平台 - 基于观察者模式的应用

// 1. 系统指标类
public class SystemMetric
{
    public string MetricId { get; }
    public string Name { get; }
    public MetricType Type { get; }
    public string SystemComponent { get; }
    public DateTime Timestamp { get; set; }
    public double Value { get; set; }
    public string Unit { get; set; }
    public Dictionary<string, string> Tags { get; } = new Dictionary<string, string>();
    
    public SystemMetric(string metricId, string name, MetricType type, string systemComponent)
    {
        MetricId = metricId;
        Name = name;
        Type = type;
        SystemComponent = systemComponent;
        Timestamp = DateTime.UtcNow;
    }
    
    public override string ToString()
    {
        string tagString = Tags.Count > 0 
            ? $", Tags: {string.Join(", ", Tags.Select(t => $"{t.Key}={t.Value}"))}"
            : "";
            
        return $"{Name} [{SystemComponent}]: {Value} {Unit} ({Timestamp:yyyy-MM-dd HH:mm:ss}){tagString}";
    }
}

// 2. 指标类型枚举
public enum MetricType
{
    Counter,     // 持续增加的值(如请求总数)
    Gauge,       // 可增可减的值(如CPU使用率)
    Histogram,   // 数值分布(如响应时间分布)
    Summary      // 统计摘要(如95%响应时间)
}

// 3. 告警级别枚举
public enum AlertLevel
{
    Info,
    Warning,
    Error,
    Critical
}

// 4. 告警状态枚举
public enum AlertState
{
    Active,
    Acknowledged,
    Resolved,
    Closed
}

// 5. 告警类
public class Alert
{
    public string AlertId { get; } = Guid.NewGuid().ToString();
    public string Name { get; set; }
    public string Description { get; set; }
    public AlertLevel Level { get; set; }
    public AlertState State { get; set; } = AlertState.Active;
    public DateTime CreatedTime { get; } = DateTime.UtcNow;
    public DateTime? UpdatedTime { get; set; }
    public DateTime? ResolvedTime { get; set; }
    public string SystemComponent { get; set; }
    public string Source { get; set; }
    public SystemMetric TriggerMetric { get; set; }
    public double Threshold { get; set; }
    public string AcknowledgedBy { get; set; }
    public string ResolvedBy { get; set; }
    public List<string> RelatedAlerts { get; } = new List<string>();
    public Dictionary<string, string> Context { get; } = new Dictionary<string, string>();
    
    public TimeSpan GetDuration()
    {
        DateTime endTime = ResolvedTime ?? DateTime.UtcNow;
        return endTime - CreatedTime;
    }
    
    public string GetAlertLevelEmoji()
    {
        return Level switch
        {
            AlertLevel.Info => "ℹ️",
            AlertLevel.Warning => "⚠️",
            AlertLevel.Error => "❌",
            AlertLevel.Critical => "🚨",
            _ => ""
        };
    }
    
    public string GetStateEmoji()
    {
        return State switch
        {
            AlertState.Active => "🔴",
            AlertState.Acknowledged => "🟠",
            AlertState.Resolved => "🟢",
            AlertState.Closed => "⚪",
            _ => ""
        };
    }
    
    public override string ToString()
    {
        string alertEmoji = GetAlertLevelEmoji();
        string stateEmoji = GetStateEmoji();
        string duration = GetDuration().ToString(@"hh\:mm\:ss");
        
        return $"{alertEmoji} {stateEmoji} {Name} - {Description} [{Level}] - {Source} - {duration}";
    }
}

// 6. 指标更新事件参数
public class MetricUpdateEventArgs : EventArgs
{
    public SystemMetric Metric { get; }
    public double PreviousValue { get; }
    public double Change { get; }
    public double PercentChange { get; }
    
    public MetricUpdateEventArgs(SystemMetric metric, double previousValue)
    {
        Metric = metric;
        PreviousValue = previousValue;
        Change = metric.Value - previousValue;
        
        if (previousValue != 0)
            PercentChange = (metric.Value - previousValue) / previousValue * 100;
        else
            PercentChange = 0;
    }
}

// 7. 告警事件参数
public class AlertEventArgs : EventArgs
{
    public Alert Alert { get; }
    public AlertAction Action { get; }
    
    public AlertEventArgs(Alert alert, AlertAction action)
    {
        Alert = alert;
        Action = action;
    }
}

// 8. 告警动作枚举
public enum AlertAction
{
    Created,
    Updated,
    Acknowledged,
    Resolved,
    Closed
}

// 9. 指标观察者接口
public interface IMetricObserver
{
    string ObserverId { get; }
    void OnMetricUpdated(object sender, MetricUpdateEventArgs e);
}

// 10. 告警观察者接口
public interface IAlertObserver
{
    string ObserverId { get; }
    void OnAlertTriggered(object sender, AlertEventArgs e);
}

// 11. 指标管理器 - 被观察者
public class MetricManager
{
    private readonly Dictionary<string, SystemMetric> _metrics = new Dictionary<string, SystemMetric>();
    private readonly List<IMetricObserver> _observers = new List<IMetricObserver>();
    private readonly object _metricsLock = new object();
    private readonly object _observersLock = new object();
    private readonly ILogger<MetricManager> _logger;
    
    public MetricManager(ILogger<MetricManager> logger)
    {
        _logger = logger;
    }
    
    // 注册指标
    public SystemMetric RegisterMetric(string name, MetricType type, string systemComponent, string unit = "")
    {
        string metricId = $"{systemComponent}:{name}".ToLower();
        
        lock (_metricsLock)
        {
            if (_metrics.TryGetValue(metricId, out var existingMetric))
            {
                return existingMetric;
            }
            
            var metric = new SystemMetric(metricId, name, type, systemComponent) { Unit = unit };
            _metrics[metricId] = metric;
            
            _logger.LogInformation("已注册指标: {MetricId}", metricId);
            return metric;
        }
    }
    
    // 更新指标值
    public void UpdateMetric(string metricId, double value)
    {
        lock (_metricsLock)
        {
            if (_metrics.TryGetValue(metricId, out var metric))
            {
                double oldValue = metric.Value;
                metric.Value = value;
                metric.Timestamp = DateTime.UtcNow;
                
                _logger.LogDebug("已更新指标 {MetricId}: {OldValue} -> {NewValue}", 
                    metricId, oldValue, value);
                
                // 通知观察者
                NotifyMetricUpdated(metric, oldValue);
            }
            else
            {
                _logger.LogWarning("尝试更新未注册的指标: {MetricId}", metricId);
            }
        }
    }
    
    // 增加计数器指标
    public void IncrementCounter(string metricId, double amount = 1)
    {
        lock (_metricsLock)
        {
            if (_metrics.TryGetValue(metricId, out var metric))
            {
                if (metric.Type != MetricType.Counter)
                {
                    _logger.LogWarning("尝试递增非计数器类型的指标: {MetricId}", metricId);
                    return;
                }
                
                double oldValue = metric.Value;
                metric.Value += amount;
                metric.Timestamp = DateTime.UtcNow;
                
                _logger.LogDebug("已递增指标 {MetricId}: {OldValue} -> {NewValue}", 
                    metricId, oldValue, metric.Value);
                
                // 通知观察者
                NotifyMetricUpdated(metric, oldValue);
            }
            else
            {
                _logger.LogWarning("尝试递增未注册的指标: {MetricId}", metricId);
            }
        }
    }
    
    // 获取指标
    public SystemMetric GetMetric(string metricId)
    {
        lock (_metricsLock)
        {
            if (_metrics.TryGetValue(metricId, out var metric))
            {
                return metric;
            }
            
            return null;
        }
    }
    
    // 获取所有指标
    public List<SystemMetric> GetAllMetrics()
    {
        lock (_metricsLock)
        {
            return _metrics.Values.ToList();
        }
    }
    
    // 添加观察者
    public void AddObserver(IMetricObserver observer)
    {
        lock (_observersLock)
        {
            if (!_observers.Any(o => o.ObserverId == observer.ObserverId))
            {
                _observers.Add(observer);
                _logger.LogInformation("已添加指标观察者: {ObserverId}", observer.ObserverId);
            }
        }
    }
    
    // 移除观察者
    public void RemoveObserver(IMetricObserver observer)
    {
        lock (_observersLock)
        {
            _observers.RemoveAll(o => o.ObserverId == observer.ObserverId);
            _logger.LogInformation("已移除指标观察者: {ObserverId}", observer.ObserverId);
        }
    }
    
    // 通知指标更新
    private void NotifyMetricUpdated(SystemMetric metric, double oldValue)
    {
        var args = new MetricUpdateEventArgs(metric, oldValue);
        
        // 创建观察者的副本,避免锁定期间的修改
        List<IMetricObserver> observers;
        lock (_observersLock)
        {
            observers = new List<IMetricObserver>(_observers);
        }
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnMetricUpdated(this, args);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "通知指标观察者 {ObserverId} 时出错", observer.ObserverId);
                }
            }
        });
    }
}

// 12. 告警管理器 - 被观察者
public class AlertManager
{
    private readonly List<Alert> _activeAlerts = new List<Alert>();
    private readonly List<Alert> _historicalAlerts = new List<Alert>();
    private readonly List<IAlertObserver> _observers = new List<IAlertObserver>();
    private readonly object _alertsLock = new object();
    private readonly object _observersLock = new object();
    private readonly ILogger<AlertManager> _logger;
    
    public AlertManager(ILogger<AlertManager> logger)
    {
        _logger = logger;
    }
    
    // 创建告警
    public Alert CreateAlert(string name, string description, AlertLevel level, 
                           string systemComponent, string source, SystemMetric triggerMetric, 
                           double threshold)
    {
        var alert = new Alert
        {
            Name = name,
            Description = description,
            Level = level,
            SystemComponent = systemComponent,
            Source = source,
            TriggerMetric = triggerMetric,
            Threshold = threshold
        };
        
        lock (_alertsLock)
        {
            _activeAlerts.Add(alert);
        }
        
        _logger.LogInformation("已创建告警: {AlertName} [{AlertLevel}] - {AlertDescription}", 
            name, level, description);
            
        // 通知观察者
        NotifyAlertAction(alert, AlertAction.Created);
        
        return alert;
    }
    
    // 确认告警
    public void AcknowledgeAlert(string alertId, string acknowledgedBy)
    {
        Alert alert = null;
        
        lock (_alertsLock)
        {
            alert = _activeAlerts.FirstOrDefault(a => a.AlertId == alertId);
            
            if (alert != null && alert.State == AlertState.Active)
            {
                alert.State = AlertState.Acknowledged;
                alert.AcknowledgedBy = acknowledgedBy;
                alert.UpdatedTime = DateTime.UtcNow;
                
                _logger.LogInformation("告警已确认: {AlertId} 由 {AcknowledgedBy}", 
                    alertId, acknowledgedBy);
                    
                // 通知观察者
                NotifyAlertAction(alert, AlertAction.Acknowledged);
            }
            else
            {
                _logger.LogWarning("尝试确认不存在或已处理的告警: {AlertId}", alertId);
            }
        }
    }
    
    // 解决告警
    public void ResolveAlert(string alertId, string resolvedBy)
    {
        Alert alert = null;
        
        lock (_alertsLock)
        {
            alert = _activeAlerts.FirstOrDefault(a => a.AlertId == alertId);
            
            if (alert != null && (alert.State == AlertState.Active || alert.State == AlertState.Acknowledged))
            {
                alert.State = AlertState.Resolved;
                alert.ResolvedBy = resolvedBy;
                alert.ResolvedTime = DateTime.UtcNow;
                alert.UpdatedTime = DateTime.UtcNow;
                
                // 将告警从活动列表移动到历史列表
                _activeAlerts.Remove(alert);
                _historicalAlerts.Add(alert);
                
                _logger.LogInformation("告警已解决: {AlertId} 由 {ResolvedBy}", 
                    alertId, resolvedBy);
                    
                // 通知观察者
                NotifyAlertAction(alert, AlertAction.Resolved);
            }
            else
            {
                _logger.LogWarning("尝试解决不存在或已解决的告警: {AlertId}", alertId);
            }
        }
    }
    
    // 关闭告警
    public void CloseAlert(string alertId)
    {
        Alert alert = null;
        
        lock (_alertsLock)
        {
            // 先在活动告警中查找
            alert = _activeAlerts.FirstOrDefault(a => a.AlertId == alertId);
            
            if (alert != null)
            {
                alert.State = AlertState.Closed;
                alert.UpdatedTime = DateTime.UtcNow;
                
                // 将告警从活动列表移动到历史列表
                _activeAlerts.Remove(alert);
                _historicalAlerts.Add(alert);
            }
            else
            {
                // 在历史告警中查找
                alert = _historicalAlerts.FirstOrDefault(a => a.AlertId == alertId);
                
                if (alert != null)
                {
                    alert.State = AlertState.Closed;
                    alert.UpdatedTime = DateTime.UtcNow;
                }
            }
            
            if (alert != null)
            {
                _logger.LogInformation("告警已关闭: {AlertId}", alertId);
                
                // 通知观察者
                NotifyAlertAction(alert, AlertAction.Closed);
            }
            else
            {
                _logger.LogWarning("尝试关闭不存在的告警: {AlertId}", alertId);
            }
        }
    }
    
    // 获取活动告警
    public List<Alert> GetActiveAlerts()
    {
        lock (_alertsLock)
        {
            return new List<Alert>(_activeAlerts);
        }
    }
    
    // 获取历史告警
    public List<Alert> GetHistoricalAlerts(int count = 100)
    {
        lock (_alertsLock)
        {
            return _historicalAlerts
                .OrderByDescending(a => a.CreatedTime)
                .Take(count)
                .ToList();
        }
    }
    
    // 获取特定组件的告警
    public List<Alert> GetAlertsForComponent(string systemComponent)
    {
        lock (_alertsLock)
        {
            var alerts = _activeAlerts
                .Where(a => a.SystemComponent == systemComponent)
                .ToList();
                
            return alerts;
        }
    }
    
    // 添加观察者
    public void AddObserver(IAlertObserver observer)
    {
        lock (_observersLock)
        {
            if (!_observers.Any(o => o.ObserverId == observer.ObserverId))
            {
                _observers.Add(observer);
                _logger.LogInformation("已添加告警观察者: {ObserverId}", observer.ObserverId);
            }
        }
    }
    
    // 移除观察者
    public void RemoveObserver(IAlertObserver observer)
    {
        lock (_observersLock)
        {
            _observers.RemoveAll(o => o.ObserverId == observer.ObserverId);
            _logger.LogInformation("已移除告警观察者: {ObserverId}", observer.ObserverId);
        }
    }
    
    // 通知告警动作
    private void NotifyAlertAction(Alert alert, AlertAction action)
    {
        var args = new AlertEventArgs(alert, action);
        
        // 创建观察者的副本,避免锁定期间的修改
        List<IAlertObserver> observers;
        lock (_observersLock)
        {
            observers = new List<IAlertObserver>(_observers);
        }
        
        // 异步通知所有观察者
        Task.Run(() => 
        {
            foreach (var observer in observers)
            {
                try
                {
                    observer.OnAlertTriggered(this, args);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "通知告警观察者 {ObserverId} 时出错", observer.ObserverId);
                }
            }
        });
    }
}

// 13. 告警规则类
public class AlertRule
{
    public string RuleId { get; } = Guid.NewGuid().ToString();
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsEnabled { get; set; } = true;
    public string MetricId { get; set; }
    public RuleCondition Condition { get; set; }
    public double Threshold { get; set; }
    public TimeSpan Duration { get; set; } = TimeSpan.Zero; // 持续时间,零表示立即触发
    public AlertLevel Level { get; set; }
    public Dictionary<string, string> Context { get; } = new Dictionary<string, string>();
    
    // 检查是否满足告警条件
    public bool IsConditionMet(double metricValue)
    {
        return Condition switch
        {
            RuleCondition.GreaterThan => metricValue > Threshold,
            RuleCondition.GreaterThanOrEqual => metricValue >= Threshold,
            RuleCondition.LessThan => metricValue < Threshold,
            RuleCondition.LessThanOrEqual => metricValue <= Threshold,
            RuleCondition.Equal => Math.Abs(metricValue - Threshold) < 0.0001,
            RuleCondition.NotEqual => Math.Abs(metricValue - Threshold) >= 0.0001,
            _ => false
        };
    }
    
    public override string ToString()
    {
        string condition = Condition switch
        {
            RuleCondition.GreaterThan => ">",
            RuleCondition.GreaterThanOrEqual => ">=",
            RuleCondition.LessThan => "<",
            RuleCondition.LessThanOrEqual => "<=",
            RuleCondition.Equal => "==",
            RuleCondition.NotEqual => "!=",
            _ => "?"
        };
        
        string durationText = Duration > TimeSpan.Zero ? $" for {Duration.TotalSeconds}s" : "";
        
        return $"{Name}: {MetricId} {condition} {Threshold}{durationText} -> {Level}";
    }
}

// 14. 规则条件枚举
public enum RuleCondition
{
    GreaterThan,
    GreaterThanOrEqual,
    LessThan,
    LessThanOrEqual,
    Equal,
    NotEqual
}

// 15. 告警规则引擎 - 同时是指标观察者
public class AlertRuleEngine : IMetricObserver
{
    public string ObserverId => "ALERT_RULE_ENGINE";
    
    private readonly List<AlertRule> _rules = new List<AlertRule>();
    private readonly Dictionary<string, RuleState> _ruleStates = new Dictionary<string, RuleState>();
    private readonly object _rulesLock = new object();
    private readonly AlertManager _alertManager;
    private readonly MetricManager _metricManager;
    private readonly ILogger<AlertRuleEngine> _logger;
    
    // 规则状态跟踪
    private class RuleState
    {
        public DateTime FirstViolationTime { get; set; }
        public bool IsInViolation { get; set; }
        public string ActiveAlertId { get; set; }
    }
    
    public AlertRuleEngine(AlertManager alertManager, MetricManager metricManager, ILogger<AlertRuleEngine> logger)
    {
        _alertManager = alertManager;
        _metricManager = metricManager;
        _logger = logger;
    }
    
    // 添加规则
    public void AddRule(AlertRule rule)
    {
        lock (_rulesLock)
        {
            if (!_rules.Any(r => r.RuleId == rule.RuleId))
            {
                _rules.Add(rule);
                _ruleStates[rule.RuleId] = new RuleState();
                _logger.LogInformation("已添加告警规则: {RuleName}", rule.Name);
            }
        }
    }
    
    // 移除规则
    public void RemoveRule(string ruleId)
    {
        lock (_rulesLock)
        {
            _rules.RemoveAll(r => r.RuleId == ruleId);
            _ruleStates.Remove(ruleId);
            _logger.LogInformation("已移除告警规则: {RuleId}", ruleId);
        }
    }
    
    // 启用规则
    public void EnableRule(string ruleId)
    {
        lock (_rulesLock)
        {
            var rule = _rules.FirstOrDefault(r => r.RuleId == ruleId);
            if (rule != null)
            {
                rule.IsEnabled = true;
                _logger.LogInformation("已启用告警规则: {RuleName}", rule.Name);
            }
        }
    }
    
    // 禁用规则
    public void DisableRule(string ruleId)
    {
        lock (_rulesLock)
        {
            var rule = _rules.FirstOrDefault(r => r.RuleId == ruleId);
            if (rule != null)
            {
                rule.IsEnabled = false;
                _logger.LogInformation("已禁用告警规则: {RuleName}", rule.Name);
                
                // 如果有活动告警,关闭它
                var state = _ruleStates[ruleId];
                if (state.IsInViolation && !string.IsNullOrEmpty(state.ActiveAlertId))
                {
                    _alertManager.ResolveAlert(state.ActiveAlertId, "System (Rule Disabled)");
                    state.IsInViolation = false;
                    state.ActiveAlertId = null;
                }
            }
        }
    }
    
    // 获取所有规则
    public List<AlertRule> GetAllRules()
    {
        lock (_rulesLock)
        {
            return new List<AlertRule>(_rules);
        }
    }
    
    // 指标观察者方法
    public void OnMetricUpdated(object sender, MetricUpdateEventArgs e)
    {
        ProcessMetric(e.Metric);
    }
    
    // 处理指标更新
    private void ProcessMetric(SystemMetric metric)
    {
        List<AlertRule> matchingRules;
        
        // 找到适用于该指标的规则
        lock (_rulesLock)
        {
            matchingRules = _rules
                .Where(r => r.IsEnabled && r.MetricId == metric.MetricId)
                .ToList();
        }
        
        foreach (var rule in matchingRules)
        {
            ProcessRule(rule, metric);
        }
    }
    
    // 处理规则
    private void ProcessRule(AlertRule rule, SystemMetric metric)
    {
        var state = _ruleStates[rule.RuleId];
        bool conditionMet = rule.IsConditionMet(metric.Value);
        
        if (conditionMet)
        {
            // 条件满足
            if (!state.IsInViolation)
            {
                // 首次违反规则
                state.FirstViolationTime = DateTime.UtcNow;
                state.IsInViolation = true;
                
                _logger.LogDebug("告警规则 {RuleName} 首次违反,指标值: {MetricValue}, 阈值: {Threshold}", 
                    rule.Name, metric.Value, rule.Threshold);
                    
                // 如果没有持续时间要求,立即触发告警
                if (rule.Duration == TimeSpan.Zero)
                {
                    TriggerAlert(rule, metric);
                }
            }
            else if (string.IsNullOrEmpty(state.ActiveAlertId) && rule.Duration > TimeSpan.Zero)
            {
                // 检查持续时间是否已满足
                TimeSpan violationDuration = DateTime.UtcNow - state.FirstViolationTime;
                
                if (violationDuration >= rule.Duration)
                {
                    _logger.LogDebug("告警规则 {RuleName} 违反持续时间已满足: {Duration}", 
                        rule.Name, violationDuration);
                        
                    // 触发告警
                    TriggerAlert(rule, metric);
                }
            }
        }
        else
        {
            // 条件不满足
            if (state.IsInViolation)
            {
                // 规则不再违反
                state.IsInViolation = false;
                
                // 如果有活动告警,解决它
                if (!string.IsNullOrEmpty(state.ActiveAlertId))
                {
                    _logger.LogInformation("告警规则 {RuleName} 条件已恢复正常,解决告警", rule.Name);
                    
                    _alertManager.ResolveAlert(state.ActiveAlertId, "System (Auto-Resolved)");
                    state.ActiveAlertId = null;
                }
            }
        }
    }
    
    // 触发告警
    private void TriggerAlert(AlertRule rule, SystemMetric metric)
    {
        var state = _ruleStates[rule.RuleId];
        
        if (string.IsNullOrEmpty(state.ActiveAlertId))
        {
            string description = GenerateAlertDescription(rule, metric);
            
            // 创建告警
            var alert = _alertManager.CreateAlert(
                rule.Name,
                description,
                rule.Level,
                metric.SystemComponent,
                "AlertRuleEngine",
                metric,
                rule.Threshold
            );
            
            // 添加上下文信息
            foreach (var ctx in rule.Context)
            {
                alert.Context[ctx.Key] = ctx.Value;
            }
            
            // 记录活动告警ID
            state.ActiveAlertId = alert.AlertId;
            
            _logger.LogInformation("已触发告警 {AlertId}: {AlertName} [{AlertLevel}]", 
                alert.AlertId, alert.Name, alert.Level);
        }
    }
    
    // 生成告警描述
    private string GenerateAlertDescription(AlertRule rule, SystemMetric metric)
    {
        string condition = rule.Condition switch
        {
            RuleCondition.GreaterThan => "大于",
            RuleCondition.GreaterThanOrEqual => "大于或等于",
            RuleCondition.LessThan => "小于",
            RuleCondition.LessThanOrEqual => "小于或等于",
            RuleCondition.Equal => "等于",
            RuleCondition.NotEqual => "不等于",
            _ => "?"
        };
        
        return $"指标 {metric.Name} ({metric.MetricId}) 当前值 {metric.Value} {metric.Unit} {condition} 阈值 {rule.Threshold} {metric.Unit}";
    }
}

// 16. 邮件通知观察者
public class EmailNotifier : IAlertObserver
{
    public string ObserverId => "EMAIL_NOTIFIER";
    
    private readonly ILogger<EmailNotifier> _logger;
    private readonly HashSet<AlertLevel> _notificationLevels = new HashSet<AlertLevel>();
    private readonly List<string> _recipients = new List<string>();
    
    public EmailNotifier(ILogger<EmailNotifier> logger)
    {
        _logger = logger;
        
        // 默认通知级别
        _notificationLevels.Add(AlertLevel.Error);
        _notificationLevels.Add(AlertLevel.Critical);
    }
    
    // 添加通知级别
    public void AddNotificationLevel(AlertLevel level)
    {
        _notificationLevels.Add(level);
    }
    
    // 移除通知级别
    public void RemoveNotificationLevel(AlertLevel level)
    {
        _notificationLevels.Remove(level);
    }
    
    // 添加邮件接收者
    public void AddRecipient(string email)
    {
        if (!_recipients.Contains(email))
        {
            _recipients.Add(email);
            _logger.LogInformation("已添加邮件通知接收者: {Email}", email);
        }
    }
    
    // 告警观察者方法
    public void OnAlertTriggered(object sender, AlertEventArgs e)
    {
        // 检查是否需要通知
        if (!_notificationLevels.Contains(e.Alert.Level))
            return;
            
        if (e.Action == AlertAction.Created)
        {
            SendAlertEmail(e.Alert);
        }
        else if (e.Action == AlertAction.Resolved)
        {
            SendResolvedEmail(e.Alert);
        }
    }
    
    // 发送告警邮件
    private void SendAlertEmail(Alert alert)
    {
        if (_recipients.Count == 0)
        {
            _logger.LogWarning("无法发送告警邮件: 没有接收者");
            return;
        }
        
        string levelText = alert.Level.ToString().ToUpper();
        string subject = $"[{levelText}] 系统告警: {alert.Name}";
        
        StringBuilder body = new StringBuilder();
        body.AppendLine($"告警ID: {alert.AlertId}");
        body.AppendLine($"名称: {alert.Name}");
        body.AppendLine($"描述: {alert.Description}");
        body.AppendLine($"级别: {alert.Level}");
        body.AppendLine($"组件: {alert.SystemComponent}");
        body.AppendLine($"时间: {alert.CreatedTime:yyyy-MM-dd HH:mm:ss}");
        body.AppendLine($"阈值: {alert.Threshold}");
        
        if (alert.TriggerMetric != null)
        {
            body.AppendLine($"触发指标: {alert.TriggerMetric.Name} = {alert.TriggerMetric.Value} {alert.TriggerMetric.Unit}");
        }
        
        string recipients = string.Join(", ", _recipients);
        
        // 模拟邮件发送
        _logger.LogInformation("发送告警邮件 - 主题: {Subject}, 接收者: {Recipients}", subject, recipients);
        _logger.LogDebug("邮件内容:\n{Body}", body.ToString());
        
        // 在实际应用中,这里会调用邮件发送API
    }
    
    // 发送告警解决邮件
    private void SendResolvedEmail(Alert alert)
    {
        if (_recipients.Count == 0)
        {
            _logger.LogWarning("无法发送告警解决邮件: 没有接收者");
            return;
        }
        
        string subject = $"[已解决] 系统告警: {alert.Name}";
        
        StringBuilder body = new StringBuilder();
        body.AppendLine($"告警ID: {alert.AlertId}");
        body.AppendLine($"名称: {alert.Name}");
        body.AppendLine($"描述: {alert.Description}");
        body.AppendLine($"级别: {alert.Level}");
        body.AppendLine($"组件: {alert.SystemComponent}");
        body.AppendLine($"创建时间: {alert.CreatedTime:yyyy-MM-dd HH:mm:ss}");
        body.AppendLine($"解决时间: {alert.ResolvedTime:yyyy-MM-dd HH:mm:ss}");
        body.AppendLine($"持续时间: {alert.GetDuration().ToString(@"hh\:mm\:ss")}");
        body.AppendLine($"解决者: {alert.ResolvedBy}");
        
        string recipients = string.Join(", ", _recipients);
        
        // 模拟邮件发送
        _logger.LogInformation("发送告警解决邮件 - 主题: {Subject}, 接收者: {Recipients}", subject, recipients);
        _logger.LogDebug("邮件内容:\n{Body}", body.ToString());
        
        // 在实际应用中,这里会调用邮件发送API
    }
}

// 17. 短信通知观察者
public class SmsNotifier : IAlertObserver
{
    public string ObserverId => "SMS_NOTIFIER";
    
    private readonly ILogger<SmsNotifier> _logger;
    private readonly HashSet<AlertLevel> _notificationLevels = new HashSet<AlertLevel>();
    private readonly List<string> _phoneNumbers = new List<string>();
    
    public SmsNotifier(ILogger<SmsNotifier> logger)
    {
        _logger = logger;
        
        // 默认只有严重级别才发送短信
        _notificationLevels.Add(AlertLevel.Critical);
    }
    
    // 添加通知级别
    public void AddNotificationLevel(AlertLevel level)
    {
        _notificationLevels.Add(level);
    }
    
    // 添加手机号码
    public void AddPhoneNumber(string phoneNumber)
    {
        if (!_phoneNumbers.Contains(phoneNumber))
        {
            _phoneNumbers.Add(phoneNumber);
            _logger.LogInformation("已添加短信通知号码: {Phone}", phoneNumber);
        }
    }
    
    // 告警观察者方法
    public void OnAlertTriggered(object sender, AlertEventArgs e)
    {
        // 检查是否需要通知
        if (!_notificationLevels.Contains(e.Alert.Level))
            return;
            
        if (e.Action == AlertAction.Created)
        {
            SendAlertSms(e.Alert);
        }
        else if (e.Action == AlertAction.Resolved)
        {
            SendResolvedSms(e.Alert);
        }
    }
    
    // 发送告警短信
    private void SendAlertSms(Alert alert)
    {
        if (_phoneNumbers.Count == 0)
        {
            _logger.LogWarning("无法发送告警短信: 没有接收者");
            return;
        }
        
        string levelText = alert.Level.ToString().ToUpper();
        string message = $"[{levelText}] {alert.Name}: {alert.Description}";
        
        // 限制短信长度
        if (message.Length > 70)
        {
            message = message.Substring(0, 67) + "...";
        }
        
        string recipients = string.Join(", ", _phoneNumbers);
        
        // 模拟短信发送
        _logger.LogInformation("发送告警短信 - 接收者: {Recipients}, 内容: {Message}", recipients, message);
        
        // 在实际应用中,这里会调用短信发送API
    }
    
    // 发送告警解决短信
    private void SendResolvedSms(Alert alert)
    {
        if (_phoneNumbers.Count == 0)
        {
            _logger.LogWarning("无法发送告警解决短信: 没有接收者");
            return;
        }
        
        string message = $"[已解决] {alert.Name}";
        
        string recipients = string.Join(", ", _phoneNumbers);
        
        // 模拟短信发送
        _logger.LogInformation("发送告警解决短信 - 接收者: {Recipients}, 内容: {Message}", recipients, message);
        
        // 在实际应用中,这里会调用短信发送API
    }
}

// 18. 日志记录观察者
public class LoggingObserver : IAlertObserver, IMetricObserver
{
    public string ObserverId => "LOGGING_OBSERVER";
    
    private readonly ILogger<LoggingObserver> _logger;
    private readonly Dictionary<string, SystemMetric> _lastMetricValues = new Dictionary<string, SystemMetric>();
    private readonly object _metricsLock = new object();
    
    public LoggingObserver(ILogger<LoggingObserver> logger)
    {
        _logger = logger;
    }
    
    // 指标观察者方法
    public void OnMetricUpdated(object sender, MetricUpdateEventArgs e)
    {
        // 只记录重大变化以避免日志爆炸
        if (Math.Abs(e.PercentChange) >= 10 || IsFirstUpdate(e.Metric.MetricId))
        {
            _logger.LogInformation("指标 {MetricName} ({MetricId}) 变化: {OldValue} -> {NewValue} ({PercentChange:+0.00;-0.00}%)",
                e.Metric.Name, e.Metric.MetricId, e.PreviousValue, e.Metric.Value, e.PercentChange);
        }
        
        // 更新最后的指标值
        lock (_metricsLock)
        {
            _lastMetricValues[e.Metric.MetricId] = e.Metric;
        }
    }
    
    // 检查是否是首次更新
    private bool IsFirstUpdate(string metricId)
    {
        lock (_metricsLock)
        {
            return !_lastMetricValues.ContainsKey(metricId);
        }
    }
    
    // 告警观察者方法
    public void OnAlertTriggered(object sender, AlertEventArgs e)
    {
        switch (e.Action)
        {
            case AlertAction.Created:
                LogAlertCreated(e.Alert);
                break;
            case AlertAction.Acknowledged:
                LogAlertAcknowledged(e.Alert);
                break;
            case AlertAction.Resolved:
                LogAlertResolved(e.Alert);
                break;
            case AlertAction.Closed:
                LogAlertClosed(e.Alert);
                break;
        }
    }
    
    // 记录告警创建
    private void LogAlertCreated(Alert alert)
    {
        var logLevel = alert.Level switch
        {
            AlertLevel.Info => Microsoft.Extensions.Logging.LogLevel.Information,
            AlertLevel.Warning => Microsoft.Extensions.Logging.LogLevel.Warning,
            AlertLevel.Error => Microsoft.Extensions.Logging.LogLevel.Error,
            AlertLevel.Critical => Microsoft.Extensions.Logging.LogLevel.Critical,
            _ => Microsoft.Extensions.Logging.LogLevel.Information
        };
        
        _logger.Log(logLevel, "告警触发: [{AlertLevel}] {AlertName} - {AlertDescription} - 组件: {Component}",
            alert.Level, alert.Name, alert.Description, alert.SystemComponent);
    }
    
    // 记录告警确认
    private void LogAlertAcknowledged(Alert alert)
    {
        _logger.LogInformation("告警已确认: [{AlertLevel}] {AlertName} - 由 {AcknowledgedBy}",
            alert.Level, alert.Name, alert.AcknowledgedBy);
    }
    
    // 记录告警解决
    private void LogAlertResolved(Alert alert)
    {
        _logger.LogInformation("告警已解决: [{AlertLevel}] {AlertName} - 由 {ResolvedBy} - 持续时间: {Duration}",
            alert.Level, alert.Name, alert.ResolvedBy, alert.GetDuration().ToString(@"hh\:mm\:ss"));
    }
    
    // 记录告警关闭
    private void LogAlertClosed(Alert alert)
    {
        _logger.LogInformation("告警已关闭: [{AlertLevel}] {AlertName}",
            alert.Level, alert.Name);
    }
}

// 19. 告警聚合观察者
public class AlertAggregator : IAlertObserver
{
    public string ObserverId => "ALERT_AGGREGATOR";
    
    private readonly ILogger<AlertAggregator> _logger;
    private readonly AlertManager _alertManager;
    private readonly Dictionary<string, List<string>> _componentGroups = new Dictionary<string, List<string>>();
    private readonly Dictionary<string, Alert> _aggregatedAlerts = new Dictionary<string, Alert>();
    private readonly object _groupsLock = new object();
    private readonly object _aggregatedLock = new object();
    
    public AlertAggregator(AlertManager alertManager, ILogger<AlertAggregator> logger)
    {
        _alertManager = alertManager;
        _logger = logger;
    }
    
    // 定义组件组
    public void DefineComponentGroup(string groupName, List<string> componentNames)
    {
        lock (_groupsLock)
        {
            _componentGroups[groupName] = new List<string>(componentNames);
            _logger.LogInformation("已定义组件组 {GroupName} 包含 {ComponentCount} 个组件", 
                groupName, componentNames.Count);
        }
    }
    
    // 获取组件所属的组
    private List<string> GetGroupsForComponent(string componentName)
    {
        lock (_groupsLock)
        {
            return _componentGroups
                .Where(g => g.Value.Contains(componentName))
                .Select(g => g.Key)
                .ToList();
        }
    }
    
    // 告警观察者方法
    public void OnAlertTriggered(object sender, AlertEventArgs e)
    {
        if (e.Action == AlertAction.Created)
        {
            ProcessNewAlert(e.Alert);
        }
        else if (e.Action == AlertAction.Resolved || e.Action == AlertAction.Closed)
        {
            ProcessResolvedAlert(e.Alert);
        }
    }
    
    // 处理新告警
    private void ProcessNewAlert(Alert alert)
    {
        var groups = GetGroupsForComponent(alert.SystemComponent);
        
        if (groups.Count == 0)
            return; // 不属于任何组
            
        foreach (var group in groups)
        {
            UpdateGroupAlert(group, alert, true);
        }
    }
    
    // 处理已解决告警
    private void ProcessResolvedAlert(Alert alert)
    {
        var groups = GetGroupsForComponent(alert.SystemComponent);
        
        if (groups.Count == 0)
            return; // 不属于任何组
            
        foreach (var group in groups)
        {
            UpdateGroupAlert(group, alert, false);
        }
    }
    
    // 更新组告警
    private void UpdateGroupAlert(string groupName, Alert componentAlert, bool isNew)
    {
        lock (_aggregatedLock)
        {
            string aggregateKey = $"GROUP:{groupName}";
            
            if (isNew)
            {
                // 新告警 - 检查是否需要创建或更新聚合告警
                List<Alert> activeAlerts = GetActiveAlertsForGroup(groupName);
                
                if (!_aggregatedAlerts.ContainsKey(aggregateKey) && activeAlerts.Count >= 3)
                {
                    // 创建聚合告警
                    CreateAggregatedAlert(groupName, activeAlerts);
                }
                else if (_aggregatedAlerts.ContainsKey(aggregateKey))
                {
                    // 更新现有聚合告警
                    UpdateExistingAggregatedAlert(groupName, componentAlert);
                }
            }
            else
            {
                // 解决告警 - 检查是否需要更新或解决聚合告警
                if (_aggregatedAlerts.ContainsKey(aggregateKey))
                {
                    List<Alert> remainingAlerts = GetActiveAlertsForGroup(groupName);
                    
                    if (remainingAlerts.Count < 3)
                    {
                        // 解决聚合告警
                        ResolveAggregatedAlert(groupName);
                    }
                    else
                    {
                        // 更新聚合告警描述
                        var aggregatedAlert = _aggregatedAlerts[aggregateKey];
                        aggregatedAlert.Description = $"组 '{groupName}' 中有 {remainingAlerts.Count} 个活动告警";
                    }
                }
            }
        }
    }
    
    // 获取组的活动告警
    private List<Alert> GetActiveAlertsForGroup(string groupName)
    {
        List<string> components;
        
        lock (_groupsLock)
        {
            if (!_componentGroups.TryGetValue(groupName, out components))
                return new List<Alert>();
        }
        
        List<Alert> activeAlerts = new List<Alert>();
        
        foreach (var component in components)
        {
            activeAlerts.AddRange(_alertManager.GetAlertsForComponent(component));
        }
        
        return activeAlerts;
    }
    
    // 创建聚合告警
    private void CreateAggregatedAlert(string groupName, List<Alert> componentAlerts)
    {
        string aggregateKey = $"GROUP:{groupName}";
        
        // 确定最高告警级别
        var highestLevel = componentAlerts.Max(a => a.Level);
        
        // 创建聚合告警
        var aggregatedAlert = _alertManager.CreateAlert(
            $"多个 {groupName} 组件告警",
            $"组 '{groupName}' 中有 {componentAlerts.Count} 个活动告警",
            highestLevel,
            groupName,
            "AlertAggregator",
            null,
            componentAlerts.Count
        );
        
        // 添加相关告警
        foreach (var alert in componentAlerts)
        {
            aggregatedAlert.RelatedAlerts.Add(alert.AlertId);
        }
        
        // 记录聚合告警
        _aggregatedAlerts[aggregateKey] = aggregatedAlert;
        
        _logger.LogInformation("已创建聚合告警 {AlertId} 用于组 {GroupName} ({AlertCount} 个告警)",
            aggregatedAlert.AlertId, groupName, componentAlerts.Count);
    }
    
    // 更新现有聚合告警
    private void UpdateExistingAggregatedAlert(string groupName, Alert newAlert)
    {
        string aggregateKey = $"GROUP:{groupName}";
        var aggregatedAlert = _aggregatedAlerts[aggregateKey];
        
        // 添加新告警到相关告警列表
        if (!aggregatedAlert.RelatedAlerts.Contains(newAlert.AlertId))
        {
            aggregatedAlert.RelatedAlerts.Add(newAlert.AlertId);
        }
        
        // 更新描述
        aggregatedAlert.Description = $"组 '{groupName}' 中有 {aggregatedAlert.RelatedAlerts.Count} 个活动告警";
        
        // 如果新告警级别更高,更新聚合告警级别
        if (newAlert.Level > aggregatedAlert.Level)
        {
            aggregatedAlert.Level = newAlert.Level;
        }
        
        _logger.LogDebug("已更新聚合告警 {AlertId} 用于组 {GroupName} ({AlertCount} 个告警)",
            aggregatedAlert.AlertId, groupName, aggregatedAlert.RelatedAlerts.Count);
    }
    
    // 解决聚合告警
    private void ResolveAggregatedAlert(string groupName)
    {
        string aggregateKey = $"GROUP:{groupName}";
        
        if (_aggregatedAlerts.TryGetValue(aggregateKey, out var aggregatedAlert))
        {
            _alertManager.ResolveAlert(aggregatedAlert.AlertId, "AlertAggregator");
            _aggregatedAlerts.Remove(aggregateKey);
            
            _logger.LogInformation("已解决聚合告警 {AlertId} 用于组 {GroupName}",
                aggregatedAlert.AlertId, groupName);
        }
    }
}

// 20. 系统监控组件 - 模拟系统指标收集
public class SystemMonitor
{
    private readonly MetricManager _metricManager;
    private readonly ILogger<SystemMonitor> _logger;
    private readonly Random _random = new Random();
    private readonly Dictionary<string, SystemMetric> _registeredMetrics = new Dictionary<string, SystemMetric>();
    private readonly CancellationTokenSource _cts = new CancellationTokenSource();
    private readonly List<Task> _monitoringTasks = new List<Task>();
    
    public SystemMonitor(MetricManager metricManager, ILogger<SystemMonitor> logger)
    {
        _metricManager = metricManager;
        _logger = logger;
    }
    
    // 初始化监控
    public void Initialize()
    {
        // 注册CPU指标
        RegisterMetric("cpu_usage", "CPU Usage", MetricType.Gauge, "System", "%");
        RegisterMetric("cpu_temperature", "CPU Temperature", MetricType.Gauge, "System", "°C");
        
        // 注册内存指标
        RegisterMetric("memory_usage", "Memory Usage", MetricType.Gauge, "System", "%");
        RegisterMetric("memory_available", "Available Memory", MetricType.Gauge, "System", "MB");
        
        // 注册磁盘指标
        RegisterMetric("disk_usage", "Disk Usage", MetricType.Gauge, "Storage", "%");
        RegisterMetric("disk_io", "Disk I/O", MetricType.Gauge, "Storage", "MB/s");
        
        // 注册网络指标
        RegisterMetric("network_in", "Network Inbound", MetricType.Gauge, "Network", "Mbps");
        RegisterMetric("network_out", "Network Outbound", MetricType.Gauge, "Network", "Mbps");
        RegisterMetric("active_connections", "Active Connections", MetricType.Gauge, "Network", "conn");
        
        // 注册应用指标
        RegisterMetric("app_requests", "Application Requests", MetricType.Counter, "Application", "req");
        RegisterMetric("app_errors", "Application Errors", MetricType.Counter, "Application", "err");
        RegisterMetric("app_response_time", "Response Time", MetricType.Gauge, "Application", "ms");
        
        // 注册数据库指标
        RegisterMetric("db_connections", "Database Connections", MetricType.Gauge, "Database", "conn");
        RegisterMetric("db_queries", "Database Queries", MetricType.Counter, "Database", "qry");
        RegisterMetric("db_latency", "Database Latency", MetricType.Gauge, "Database", "ms");
        
        _logger.LogInformation("系统监控初始化完成,已注册 {MetricCount} 个指标", _registeredMetrics.Count);
    }
    
    // 注册指标
    private void RegisterMetric(string name, string displayName, MetricType type, string component, string unit)
    {
        string metricId = $"{component.ToLower()}:{name}";
        var metric = _metricManager.RegisterMetric(displayName, type, component, unit);
        _registeredMetrics[metricId] = metric;
    }
    
    // 启动监控
    public void StartMonitoring()
    {
        _logger.LogInformation("开始系统监控");
        
        // 启动CPU监控
        _monitoringTasks.Add(Task.Run(() => MonitorCpu(_cts.Token)));
        
        // 启动内存监控
        _monitoringTasks.Add(Task.Run(() => MonitorMemory(_cts.Token)));
        
        // 启动磁盘监控
        _monitoringTasks.Add(Task.Run(() => MonitorDisk(_cts.Token)));
        
        // 启动网络监控
        _monitoringTasks.Add(Task.Run(() => MonitorNetwork(_cts.Token)));
        
        // 启动应用监控
        _monitoringTasks.Add(Task.Run(() => MonitorApplication(_cts.Token)));
        
        // 启动数据库监控
        _monitoringTasks.Add(Task.Run(() => MonitorDatabase(_cts.Token)));
    }
    
    // 停止监控
    public async Task StopMonitoring()
    {
        _logger.LogInformation("停止系统监控");
        _cts.Cancel();
        
        await Task.WhenAll(_monitoringTasks);
    }
    
    // 监控CPU
    private async Task MonitorCpu(CancellationToken cancellationToken)
    {
        _logger.LogDebug("CPU监控启动");
        
        string usageMetricId = "system:cpu_usage";
        string tempMetricId = "system:cpu_temperature";
        
        double baseUsage = 30.0; // 基准CPU使用率
        double baseTemp = 40.0;  // 基准CPU温度
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟CPU使用率波动
                double usageVariation = _random.NextDouble() * 20 - 5; // -5到+15的变化
                double newUsage = Math.Min(100, Math.Max(0, baseUsage + usageVariation));
                
                // 模拟温度波动 (与CPU使用率相关)
                double tempVariation = (usageVariation / 10.0) + (_random.NextDouble() * 2 - 1);
                double newTemp = Math.Max(30, baseTemp + tempVariation);
                
                // 更新指标
                _metricManager.UpdateMetric(usageMetricId, newUsage);
                _metricManager.UpdateMetric(tempMetricId, newTemp);
                
                // 每5秒采样一次
                await Task.Delay(5000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "CPU监控发生错误");
                await Task.Delay(10000, cancellationToken); // 错误后等待较长时间
            }
        }
        
        _logger.LogDebug("CPU监控停止");
    }
    
    // 监控内存
    private async Task MonitorMemory(CancellationToken cancellationToken)
    {
        _logger.LogDebug("内存监控启动");
        
        string usageMetricId = "system:memory_usage";
        string availableMetricId = "system:memory_available";
        
        double baseUsage = 45.0;     // 基准内存使用率
        double totalMemory = 16384;  // 总内存 (MB)
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟内存使用率波动
                double usageVariation = _random.NextDouble() * 10 - 3; // -3到+7的变化
                double newUsage = Math.Min(95, Math.Max(10, baseUsage + usageVariation));
                
                // 计算可用内存
                double availableMemory = totalMemory * (1 - newUsage / 100);
                
                // 更新指标
                _metricManager.UpdateMetric(usageMetricId, newUsage);
                _metricManager.UpdateMetric(availableMetricId, availableMemory);
                
                // 每8秒采样一次
                await Task.Delay(8000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "内存监控发生错误");
                await Task.Delay(10000, cancellationToken);
            }
        }
        
        _logger.LogDebug("内存监控停止");
    }
    
    // 监控磁盘
    private async Task MonitorDisk(CancellationToken cancellationToken)
    {
        _logger.LogDebug("磁盘监控启动");
        
        string usageMetricId = "storage:disk_usage";
        string ioMetricId = "storage:disk_io";
        
        double baseUsage = 68.0;  // 基准磁盘使用率
        double baseIo = 5.0;      // 基准磁盘IO (MB/s)
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟磁盘使用率缓慢增长
                double usageVariation = _random.NextDouble() * 0.2 - 0.05; // 非常小的变化
                double newUsage = Math.Min(100, Math.Max(0, baseUsage + usageVariation));
                baseUsage = newUsage; // 保持缓慢变化
                
                // 模拟IO波动
                double ioSpike = _random.NextDouble() < 0.1 ? _random.NextDouble() * 50 : 0; // 10%概率有IO峰值
                double newIo = baseIo + ioSpike + (_random.NextDouble() * 3 - 1);
                newIo = Math.Max(0, newIo);
                
                // 更新指标
                _metricManager.UpdateMetric(usageMetricId, newUsage);
                _metricManager.UpdateMetric(ioMetricId, newIo);
                
                // 每10秒采样一次
                await Task.Delay(10000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "磁盘监控发生错误");
                await Task.Delay(10000, cancellationToken);
            }
        }
        
        _logger.LogDebug("磁盘监控停止");
    }
    
    // 监控网络
    private async Task MonitorNetwork(CancellationToken cancellationToken)
    {
        _logger.LogDebug("网络监控启动");
        
        string inboundMetricId = "network:network_in";
        string outboundMetricId = "network:network_out";
        string connectionsMetricId = "network:active_connections";
        
        double baseInbound = 25.0;  // 基准入站流量 (Mbps)
        double baseOutbound = 10.0; // 基准出站流量 (Mbps)
        int baseConnections = 150;  // 基准连接数
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟网络流量波动
                double inVariation = _random.NextDouble() * 20 - 5;
                double outVariation = _random.NextDouble() * 8 - 2;
                
                double newInbound = Math.Max(0, baseInbound + inVariation);
                double newOutbound = Math.Max(0, baseOutbound + outVariation);
                
                // 模拟连接数波动
                int connVariation = _random.Next(-10, 11);
                int newConnections = Math.Max(0, baseConnections + connVariation);
                
                // 模拟网络突发流量
                if (_random.NextDouble() < 0.05) // 5%概率
                {
                    newInbound *= 1.5;
                    newOutbound *= 1.3;
                    newConnections += 50;
                }
                
                // 更新指标
                _metricManager.UpdateMetric(inboundMetricId, newInbound);
                _metricManager.UpdateMetric(outboundMetricId, newOutbound);
                _metricManager.UpdateMetric(connectionsMetricId, newConnections);
                
                // 每3秒采样一次
                await Task.Delay(3000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "网络监控发生错误");
                await Task.Delay(10000, cancellationToken);
            }
        }
        
        _logger.LogDebug("网络监控停止");
    }
    
    // 监控应用
    private async Task MonitorApplication(CancellationToken cancellationToken)
    {
        _logger.LogDebug("应用监控启动");
        
        string requestsMetricId = "application:app_requests";
        string errorsMetricId = "application:app_errors";
        string responseTimeMetricId = "application:app_response_time";
        
        double baseResponseTime = 75.0;  // 基准响应时间 (ms)
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟请求计数器增加
                int newRequests = _random.Next(10, 50);
                
                // 模拟错误计数器增加
                int newErrors = _random.Next(100) < 5 ? _random.Next(1, 5) : 0; // 5%概率出现错误
                
                // 模拟响应时间波动
                double rtVariation = _random.NextDouble() * 30 - 10;
                double newResponseTime = Math.Max(10, baseResponseTime + rtVariation);
                
                // 模拟应用偶尔变慢
                if (_random.NextDouble() < 0.03) // 3%概率
                {
                    newResponseTime *= 2.5;
                    newErrors += _random.Next(3, 8);
                }
                
                // 更新指标
                _metricManager.IncrementCounter(requestsMetricId, newRequests);
                _metricManager.IncrementCounter(errorsMetricId, newErrors);
                _metricManager.UpdateMetric(responseTimeMetricId, newResponseTime);
                
                // 每2秒采样一次
                await Task.Delay(2000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "应用监控发生错误");
                await Task.Delay(10000, cancellationToken);
            }
        }
        
        _logger.LogDebug("应用监控停止");
    }
    
    // 监控数据库
    private async Task MonitorDatabase(CancellationToken cancellationToken)
    {
        _logger.LogDebug("数据库监控启动");
        
        string connectionsMetricId = "database:db_connections";
        string queriesMetricId = "database:db_queries";
        string latencyMetricId = "database:db_latency";
        
        int baseConnections = 25;      // 基准数据库连接数
        double baseLatency = 15.0;     // 基准数据库延迟 (ms)
        
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                // 模拟数据库连接波动
                int connVariation = _random.Next(-3, 4);
                int newConnections = Math.Max(1, baseConnections + connVariation);
                
                // 模拟查询计数器增加
                int newQueries = _random.Next(50, 200);
                
                // 模拟延迟波动
                double latencyVariation = _random.NextDouble() * 10 - 3;
                double newLatency = Math.Max(1, baseLatency + latencyVariation);
                
                // 模拟数据库偶尔变慢
                if (_random.NextDouble() < 0.02) // 2%概率
                {
                    newLatency *= 3;
                    newConnections = Math.Min(50, newConnections + 10);
                }
                
                // 更新指标
                _metricManager.UpdateMetric(connectionsMetricId, newConnections);
                _metricManager.IncrementCounter(queriesMetricId, newQueries);
                _metricManager.UpdateMetric(latencyMetricId, newLatency);
                
                // 每4秒采样一次
                await Task.Delay(4000, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "数据库监控发生错误");
                await Task.Delay(10000, cancellationToken);
            }
        }
        
        _logger.LogDebug("数据库监控停止");
    }
}

// 21. 仪表盘观察者
public class DashboardObserver : IMetricObserver, IAlertObserver
{
    public string ObserverId => "DASHBOARD";
    
    private readonly Dictionary<string, SystemMetric> _latestMetrics = new Dictionary<string, SystemMetric>();
    private readonly List<Alert> _activeAlerts = new List<Alert>();
    private readonly object _metricsLock = new object();
    private readonly object _alertsLock = new object();
    private readonly ILogger<DashboardObserver> _logger;
    
    public DashboardObserver(ILogger<DashboardObserver> logger)
    {
        _logger = logger;
    }
    
    // 指标观察者方法
    public void OnMetricUpdated(object sender, MetricUpdateEventArgs e)
    {
        lock (_metricsLock)
        {
            _latestMetrics[e.Metric.MetricId] = e.Metric;
        }
    }
    
    // 告警观察者方法
    public void OnAlertTriggered(object sender, AlertEventArgs e)
    {
        lock (_alertsLock)
        {
            if (e.Action == AlertAction.Created)
            {
                _activeAlerts.Add(e.Alert);
            }
            else if (e.Action == AlertAction.Resolved || e.Action == AlertAction.Closed)
            {
                _activeAlerts.RemoveAll(a => a.AlertId == e.Alert.AlertId);
            }
        }
    }
    
    // 显示仪表盘
    public void DisplayDashboard()
    {
        Console.Clear();
        Console.WriteLine("=== 系统监控仪表盘 ===");
        Console.WriteLine($"时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
        
        // 显示活动告警
        DisplayActiveAlerts();
        
        // 显示系统指标
        DisplaySystemMetrics();
        
        // 显示应用指标
        DisplayApplicationMetrics();
        
        // 显示数据库指标
        DisplayDatabaseMetrics();
        
        Console.WriteLine("\n按 'q' 退出,按其他键刷新...");
    }
    
    // 显示活动告警
    private void DisplayActiveAlerts()
    {
        List<Alert> alerts;
        
        lock (_alertsLock)
        {
            alerts = new List<Alert>(_activeAlerts);
        }
        
        if (alerts.Count > 0)
        {
            Console.WriteLine("\n活动告警:");
            
            var sortedAlerts = alerts
                .OrderByDescending(a => a.Level)
                .ThenBy(a => a.CreatedTime)
                .ToList();
                
            foreach (var alert in sortedAlerts.Take(5))
            {
                string alertEmoji = alert.GetAlertLevelEmoji();
                string stateEmoji = alert.GetStateEmoji();
                TimeSpan duration = alert.GetDuration();
                
                Console.WriteLine($"{alertEmoji} {stateEmoji} [{alert.Level}] {alert.Name} - {duration:hh\\:mm\\:ss}");
                Console.WriteLine($"    {alert.Description}");
            }
            
            if (sortedAlerts.Count > 5)
            {
                Console.WriteLine($"    ... 还有 {sortedAlerts.Count - 5} 个告警未显示");
            }
        }
        else
        {
            Console.WriteLine("\n没有活动告警");
        }
    }
    
    // 显示系统指标
    private void DisplaySystemMetrics()
    {
        Console.WriteLine("\n系统状态:");
        
        Dictionary<string, SystemMetric> metrics;
        lock (_metricsLock)
        {
            metrics = new Dictionary<string, SystemMetric>(_latestMetrics);
        }
        
        // CPU 指标
        if (metrics.TryGetValue("system:cpu_usage", out var cpuUsage))
        {
            string cpuStatusBar = GenerateStatusBar(cpuUsage.Value, 100, 20);
            Console.WriteLine($"CPU 使用率: {cpuStatusBar} {cpuUsage.Value:F1}%");
        }
        
        // 内存指标
        if (metrics.TryGetValue("system:memory_usage", out var memUsage))
        {
            string memStatusBar = GenerateStatusBar(memUsage.Value, 100, 20);
            Console.WriteLine($"内存使用率: {memStatusBar} {memUsage.Value:F1}%");
        }
        
        // 磁盘指标
        if (metrics.TryGetValue("storage:disk_usage", out var diskUsage))
        {
            string diskStatusBar = GenerateStatusBar(diskUsage.Value, 100, 20);
            Console.WriteLine($"磁盘使用率: {diskStatusBar} {diskUsage.Value:F1}%");
        }
        
        // 网络指标
        if (metrics.TryGetValue("network:network_in", out var netIn) && 
            metrics.TryGetValue("network:network_out", out var netOut))
        {
            Console.WriteLine($"网络流量: ↓ {netIn.Value:F1} {netIn.Unit} | ↑ {netOut.Value:F1} {netOut.Unit}");
        }
    }
    
    // 显示应用指标
    private void DisplayApplicationMetrics()
    {
        Console.WriteLine("\n应用状态:");
        
        Dictionary<string, SystemMetric> metrics;
        lock (_metricsLock)
        {
            metrics = new Dictionary<string, SystemMetric>(_latestMetrics);
        }
        
        // 响应时间
        if (metrics.TryGetValue("application:app_response_time", out var respTime))
        {
            string rtStatus = respTime.Value < 100 ? "良好" : (respTime.Value < 300 ? "一般" : "较慢");
            Console.WriteLine($"响应时间: {respTime.Value:F1} {respTime.Unit} ({rtStatus})");
        }
        
        // 请求和错误
        if (metrics.TryGetValue("application:app_requests", out var requests) &&
            metrics.TryGetValue("application:app_errors", out var errors))
        {
            double errorRate = requests.Value > 0 ? (errors.Value / requests.Value * 100) : 0;
            Console.WriteLine($"请求: {requests.Value:F0} | 错误: {errors.Value:F0} | 错误率: {errorRate:F2}%");
        }
        
        // 连接数
        if (metrics.TryGetValue("network:active_connections", out var connections))
        {
            Console.WriteLine($"活动连接: {connections.Value:F0}");
        }
    }
    
    // 显示数据库指标
    private void DisplayDatabaseMetrics()
    {
        Console.WriteLine("\n数据库状态:");
        
        Dictionary<string, SystemMetric> metrics;
        lock (_metricsLock)
        {
            metrics = new Dictionary<string, SystemMetric>(_latestMetrics);
        }
        
        // 数据库延迟
        if (metrics.TryGetValue("database:db_latency", out var dbLatency))
        {
            string latencyStatus = dbLatency.Value < 20 ? "良好" : (dbLatency.Value < 50 ? "一般" : "较慢");
            Console.WriteLine($"查询延迟: {dbLatency.Value:F1} {dbLatency.Unit} ({latencyStatus})");
        }
        
        // 数据库连接
        if (metrics.TryGetValue("database:db_connections", out var dbConn))
        {
            Console.WriteLine($"活动连接: {dbConn.Value:F0}");
        }
        
        // 查询计数
        if (metrics.TryGetValue("database:db_queries", out var dbQueries))
        {
            Console.WriteLine($"总查询数: {dbQueries.Value:F0}");
        }
    }
    
    // 生成状态条
    private string GenerateStatusBar(double value, double max, int length)
    {
        int filledLength = (int)Math.Round(value / max * length);
        filledLength = Math.Min(length, Math.Max(0, filledLength));
        
        string color;
        if (value < max * 0.7)
            color = "绿";
        else if (value < max * 0.9)
            color = "黄";
        else
            color = "红";
            
        return $"[{new string('■', filledLength)}{new string('□', length - filledLength)}] ({color})";
    }
}

// 22. 客户端代码
public class Program
{
    public static async Task Main()
    {
        // 设置依赖注入
        var services = new ServiceCollection();
        
        // 添加日志
        services.AddLogging(builder =>
        {
            builder.AddConsole();
            builder.SetMinimumLevel(LogLevel.Information);
        });
        
        // 注册服务
        services.AddSingleton<MetricManager>();
        services.AddSingleton<AlertManager>();
        services.AddSingleton<AlertRuleEngine>();
        services.AddSingleton<SystemMonitor>();
        services.AddSingleton<DashboardObserver>();
        services.AddSingleton<EmailNotifier>();
        services.AddSingleton<SmsNotifier>();
        services.AddSingleton<LoggingObserver>();
        services.AddSingleton<AlertAggregator>();
        
        var serviceProvider = services.BuildServiceProvider();
        
        // 获取服务
        var metricManager = serviceProvider.GetRequiredService<MetricManager>();
        var alertManager = serviceProvider.GetRequiredService<AlertManager>();
        var alertRuleEngine = serviceProvider.GetRequiredService<AlertRuleEngine>();
        var systemMonitor = serviceProvider.GetRequiredService<SystemMonitor>();
        var dashboard = serviceProvider.GetRequiredService<DashboardObserver>();
        var emailNotifier = serviceProvider.GetRequiredService<EmailNotifier>();
        var smsNotifier = serviceProvider.GetRequiredService<SmsNotifier>();
        var loggingObserver = serviceProvider.GetRequiredService<LoggingObserver>();
        var alertAggregator = serviceProvider.GetRequiredService<AlertAggregator>();
        
        // 注册观察者
        metricManager.AddObserver(alertRuleEngine);
        metricManager.AddObserver(dashboard);
        metricManager.AddObserver(loggingObserver);
        
        alertManager.AddObserver(dashboard);
        alertManager.AddObserver(emailNotifier);
        alertManager.AddObserver(smsNotifier);
        alertManager.AddObserver(loggingObserver);
        alertManager.AddObserver(alertAggregator);
        
        // 配置通知
        emailNotifier.AddRecipient("admin@example.com");
        emailNotifier.AddRecipient("ops@example.com");
        
        smsNotifier.AddPhoneNumber("+1234567890");
        
        // 定义组件组
        alertAggregator.DefineComponentGroup("Database System", new List<string> { "Database", "Storage" });
        alertAggregator.DefineComponentGroup("Web Platform", new List<string> { "Application", "Network" });
        
        // 添加告警规则
        // CPU规则
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "CPU使用率过高",
            Description = "CPU使用率超过阈值",
            MetricId = "system:cpu_usage",
            Condition = RuleCondition.GreaterThan,
            Threshold = 85,
            Duration = TimeSpan.FromSeconds(30),
            Level = AlertLevel.Warning
        });
        
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "CPU使用率严重过高",
            Description = "CPU使用率严重超过阈值",
            MetricId = "system:cpu_usage",
            Condition = RuleCondition.GreaterThan,
            Threshold = 95,
            Duration = TimeSpan.FromSeconds(15),
            Level = AlertLevel.Error
        });
        
        // 内存规则
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "内存使用率过高",
            Description = "内存使用率超过阈值",
            MetricId = "system:memory_usage",
            Condition = RuleCondition.GreaterThan,
            Threshold = 80,
            Duration = TimeSpan.FromSeconds(60),
            Level = AlertLevel.Warning
        });
        
        // 磁盘规则
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "磁盘空间不足",
            Description = "磁盘使用率超过阈值",
            MetricId = "storage:disk_usage",
            Condition = RuleCondition.GreaterThan,
            Threshold = 90,
            Duration = TimeSpan.Zero,
            Level = AlertLevel.Warning
        });
        
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "磁盘空间严重不足",
            Description = "磁盘使用率严重超过阈值",
            MetricId = "storage:disk_usage",
            Condition = RuleCondition.GreaterThan,
            Threshold = 95,
            Duration = TimeSpan.Zero,
            Level = AlertLevel.Error
        });
        
        // 应用规则
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "应用响应时间过长",
            Description = "应用响应时间超过阈值",
            MetricId = "application:app_response_time",
            Condition = RuleCondition.GreaterThan,
            Threshold = 200,
            Duration = TimeSpan.FromSeconds(45),
            Level = AlertLevel.Warning
        });
        
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "应用错误率过高",
            Description = "应用错误率超过阈值",
            MetricId = "application:app_errors",
            Condition = RuleCondition.GreaterThan,
            Threshold = 50,
            Duration = TimeSpan.Zero,
            Level = AlertLevel.Warning
        });
        
        // 数据库规则
        alertRuleEngine.AddRule(new AlertRule
        {
            Name = "数据库延迟过高",
            Description = "数据库查询延迟超过阈值",
            MetricId = "database:db_latency",
            Condition = RuleCondition.GreaterThan,
            Threshold = 50,
            Duration = TimeSpan.FromSeconds(30),
            Level = AlertLevel.Warning
        });
        
        // 初始化系统监控
        systemMonitor.Initialize();
        
        // 启动监控
        systemMonitor.StartMonitoring();
        
        // 仪表盘刷新循环
        bool running = true;
        
        while (running)
        {
            dashboard.DisplayDashboard();
            
            // 等待用户输入
            if (Console.KeyAvailable)
            {
                var key = Console.ReadKey(true);
                if (key.KeyChar == 'q' || key.KeyChar == 'Q')
                {
                    running = false;
                }
            }
            
            await Task.Delay(1000); // 每秒刷新一次
        }
        
        // 停止监控
        await systemMonitor.StopMonitoring();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222

# 19. 状态模式

原理:
状态模式允许对象在内部状态改变时改变它的行为,使对象看起来好像修改了它的类。状态模式将状态相关的行为封装在独立的状态类中,并将行为委托给当前状态对象,从而消除了大量的条件判断语句。

思路:

  1. 定义状态接口,声明与特定状态相关的方法
  2. 实现具体状态类,处理上下文对象的状态转换
  3. 定义上下文类,维护当前状态对象的引用
  4. 上下文将状态相关的请求委托给当前状态对象处理

前辈经验:

  • 当对象的行为取决于其状态,且必须在运行时根据状态改变行为时,使用状态模式
  • 状态模式将状态相关的行为分散到各个状态类中,消除了复杂的条件判断语句
  • 状态之间的转换逻辑可以放在状态类中或上下文类中,各有优缺点
  • 注意避免状态类之间的循环依赖,可能导致难以维护的代码
  • 在具体状态类中重用共同的功能可以使用继承或组合

业务场景:
订单处理系统,订单根据其当前状态(创建、支付、发货、完成、取消)有不同的处理方式。

简单实现:

// 订单状态接口
public interface IOrderState
{
    void ProcessOrder(Order order);
    void CancelOrder(Order order);
    void PayOrder(Order order);
    void ShipOrder(Order order);
    void DeliverOrder(Order order);
    string GetStateName();
}

// 已创建状态
public class CreatedState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单正在处理中...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("订单已取消。");
        order.SetState(new CanceledState());
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("订单已支付。");
        order.SetState(new PaidState());
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:未支付的订单不能发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:未发货的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已创建";
    }
}

// 已支付状态
public class PaidState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已支付,准备发货...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("已支付订单已取消,将安排退款。");
        order.SetState(new CanceledState());
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("订单已发货。");
        order.SetState(new ShippedState());
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:未发货的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已支付";
    }
}

// 已发货状态
public class ShippedState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已发货,正在运输中...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:已发货的订单不能取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:订单已发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("订单已交付。");
        order.SetState(new DeliveredState());
    }
    
    public string GetStateName()
    {
        return "已发货";
    }
}

// 已交付状态
public class DeliveredState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已完成。");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:已交付的订单不能取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:订单已发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:订单已交付。");
    }
    
    public string GetStateName()
    {
        return "已交付";
    }
}

// 已取消状态
public class CanceledState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能处理。");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:订单已取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已取消";
    }
}

// 订单类(上下文)
public class Order
{
    private IOrderState _state;
    public string OrderNumber { get; }
    public DateTime CreatedDate { get; }
    
    public Order(string orderNumber)
    {
        OrderNumber = orderNumber;
        CreatedDate = DateTime.Now;
        _state = new CreatedState(); // 初始状态为已创建
    }
    
    public void SetState(IOrderState state)
    {
        _state = state;
    }
    
    public void ProcessOrder()
    {
        _state.ProcessOrder(this);
    }
    
    public void CancelOrder()
    {
        _state.CancelOrder(this);
    }
    
    public void PayOrder()
    {
        _state.PayOrder(this);
    }
    
    public void ShipOrder()
    {
        _state.ShipOrder(this);
    }
    
    public void DeliverOrder()
    {
        _state.DeliverOrder(this);
    }
    
    public string GetOrderStatus()
    {
        return _state.GetStateName();
    }
    
    public void DisplayOrder()
    {
        Console.WriteLine($"订单号: {OrderNumber}");
        Console.WriteLine($"创建时间: {CreatedDate}");
        Console.WriteLine($"当前状态: {GetOrderStatus()}");
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建新订单
        Order order = new Order("ORD-2023-001");
        
        // 显示订单状态
        order.DisplayOrder();
        Console.WriteLine();
        
        // 处理订单
        Console.WriteLine("操作: 处理订单");
        order.ProcessOrder();
        Console.WriteLine();
        
        // 支付订单
        Console.WriteLine("操作: 支付订单");
        order.PayOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 再次支付
        Console.WriteLine("操作: 再次支付订单");
        order.PayOrder();
        Console.WriteLine();
        
        // 发货订单
        Console.WriteLine("操作: 发货订单");
        order.ShipOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 尝试取消
        Console.WriteLine("操作: 取消订单");
        order.CancelOrder();
        Console.WriteLine();
        
        // 交付订单
        Console.WriteLine("操作: 交付订单");
        order.DeliverOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 创建另一个订单并取消
        Order order2 = new Order("ORD-2023-002");
        Console.WriteLine($"创建新订单: {order2.OrderNumber}");
        order2.DisplayOrder();
        Console.WriteLine();
        
        Console.WriteLine("操作: 取消订单");
        order2.CancelOrder();
        order2.DisplayOrder();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

复杂实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// 1. 订单状态接口
public interface IOrderState
{
    bool CanTransitionTo(IOrderState nextState);
    void EnterState(Order order);
    void ExitState(Order order);
    
    Task<bool> ProcessOrder(Order order);
    Task<bool> PayOrder(Order order, PaymentInfo paymentInfo);
    Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo);
    Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo);
    Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo);
    Task<bool> RefundOrder(Order order, RefundInfo refundInfo);
    Task<bool> CancelOrder(Order order, string reason);
    
    Task<bool> AddItem(Order order, OrderItem item);
    Task<bool> RemoveItem(Order order, string itemId);
    Task<bool> UpdateQuantity(Order order, string itemId, int quantity);
    
    Task<bool> ApplyDiscount(Order order, Discount discount);
    Task<bool> UpdateShippingAddress(Order order, Address address);
    Task<bool> UpdateBillingAddress(Order order, Address address);
    
    string GetStateName();
    OrderStateEnum GetStateEnum();
    List<OrderStateTransition> GetAllowedTransitions();
}

// 2. 订单状态枚举
public enum OrderStateEnum
{
    Created,
    Processing,
    AwaitingPayment,
    PaymentFailed,
    Paid,
    ReadyForShipment,
    Shipped,
    Delivered,
    Returned,
    PartiallyReturned,
    Refunded,
    PartiallyRefunded,
    Canceled,
    Completed
}

// 3. 状态转换类
public class OrderStateTransition
{
    public OrderStateEnum FromState { get; }
    public OrderStateEnum ToState { get; }
    public string TransitionName { get; }
    public string Description { get; }
    
    public OrderStateTransition(OrderStateEnum fromState, OrderStateEnum toState, string transitionName, string description)
    {
        FromState = fromState;
        ToState = toState;
        TransitionName = transitionName;
        Description = description;
    }
}

// 4. 支付信息类
public class PaymentInfo
{
    public string PaymentId { get; set; }
    public decimal Amount { get; set; }
    public string PaymentMethod { get; set; }
    public DateTime PaymentDate { get; set; }
    public string TransactionId { get; set; }
    public PaymentStatus Status { get; set; }
    public Dictionary<string, string> AdditionalInfo { get; set; } = new Dictionary<string, string>();
    
    public enum PaymentStatus
    {
        Pending,
        Successful,
        Failed,
        Refunded,
        PartiallyRefunded
    }
}

// 5. 配送信息类
public class ShipmentInfo
{
    public string ShipmentId { get; set; }
    public string Carrier { get; set; }
    public string TrackingNumber { get; set; }
    public DateTime ShipmentDate { get; set; }
    public decimal ShippingCost { get; set; }
    public List<OrderItem> ShippedItems { get; set; } = new List<OrderItem>();
    public ShipmentStatus Status { get; set; }
    
    public enum ShipmentStatus
    {
        Processing,
        Shipped,
        InTransit,
        Delivered,
        Failed,
        Returned
    }
}

// 6. 交付信息类
public class DeliveryInfo
{
    public string DeliveryId { get; set; }
    public DateTime DeliveryDate { get; set; }
    public string ReceivedBy { get; set; }
    public string DeliveryNotes { get; set; }
    public DeliveryStatus Status { get; set; }
    public string ProofOfDeliveryUrl { get; set; }
    
    public enum DeliveryStatus
    {
        Pending,
        InTransit,
        AttemptedDelivery,
        Delivered,
        Failed
    }
}

// 7. 退货信息类
public class ReturnInfo
{
    public string ReturnId { get; set; }
    public string Reason { get; set; }
    public DateTime ReturnRequestDate { get; set; }
    public DateTime? ReturnReceivedDate { get; set; }
    public List<OrderItem> ReturnedItems { get; set; } = new List<OrderItem>();
    public ReturnStatus Status { get; set; }
    public string ReturnShippingLabel { get; set; }
    
    public enum ReturnStatus
    {
        Requested,
        Approved,
        Rejected,
        InTransit,
        Received,
        Inspected,
        Completed
    }
}

// 8. 退款信息类
public class RefundInfo
{
    public string RefundId { get; set; }
    public decimal Amount { get; set; }
    public string Reason { get; set; }
    public DateTime RefundRequestDate { get; set; }
    public DateTime? RefundProcessedDate { get; set; }
    public RefundStatus Status { get; set; }
    public string RefundMethod { get; set; }
    public string TransactionId { get; set; }
    
    public enum RefundStatus
    {
        Requested,
        Approved,
        Rejected,
        Processing,
        Completed,
        Failed
    }
}

// 9. 地址类
public class Address
{
    public string FullName { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
    public string PhoneNumber { get; set; }
    
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(FullName);
        sb.AppendLine(AddressLine1);
        
        if (!string.IsNullOrWhiteSpace(AddressLine2))
            sb.AppendLine(AddressLine2);
            
        sb.AppendLine($"{City}, {State} {ZipCode}");
        sb.AppendLine(Country);
        sb.AppendLine(PhoneNumber);
        
        return sb.ToString();
    }
}

// 10. 折扣类
public class Discount
{
    public string DiscountId { get; set; }
    public string Code { get; set; }
    public string Description { get; set; }
    public DiscountType Type { get; set; }
    public decimal Value { get; set; }
    public DateTime? ExpirationDate { get; set; }
    public int? MaxUsage { get; set; }
    public int CurrentUsage { get; set; }
    
    public enum DiscountType
    {
        Percentage,
        FixedAmount,
        FreeShipping,
        BuyXGetY
    }
    
    public decimal CalculateDiscount(decimal originalPrice)
    {
        return Type switch
        {
            DiscountType.Percentage => originalPrice * (Value / 100),
            DiscountType.FixedAmount => Math.Min(Value, originalPrice),
            DiscountType.FreeShipping => 0, // 处理在其他地方
            DiscountType.BuyXGetY => 0, // 处理在其他地方
            _ => 0
        };
    }
    
    public bool IsValid()
    {
        if (ExpirationDate.HasValue && ExpirationDate.Value < DateTime.Now)
            return false;
            
        if (MaxUsage.HasValue && CurrentUsage >= MaxUsage.Value)
            return false;
            
        return true;
    }
}

// 11. 订单项类
public class OrderItem
{
    public string ItemId { get; set; }
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal TotalPrice => UnitPrice * Quantity;
    public List<Discount> AppliedDiscounts { get; set; } = new List<Discount>();
    public decimal DiscountAmount => AppliedDiscounts.Sum(d => d.CalculateDiscount(TotalPrice));
    public decimal FinalPrice => TotalPrice - DiscountAmount;
    
    public OrderItem Clone()
    {
        return new OrderItem
        {
            ItemId = ItemId,
            ProductId = ProductId,
            ProductName = ProductName,
            Quantity = Quantity,
            UnitPrice = UnitPrice,
            AppliedDiscounts = new List<Discount>(AppliedDiscounts)
        };
    }
}

// 12. 订单事件参数
public class OrderStateChangedEventArgs : EventArgs
{
    public OrderStateEnum OldState { get; }
    public OrderStateEnum NewState { get; }
    public string OrderNumber { get; }
    public DateTime Timestamp { get; }
    
    public OrderStateChangedEventArgs(OrderStateEnum oldState, OrderStateEnum newState, string orderNumber)
    {
        OldState = oldState;
        NewState = newState;
        OrderNumber = orderNumber;
        Timestamp = DateTime.Now;
    }
}

// 13. 订单事件日志
public class OrderEventLog
{
    public Guid LogId { get; } = Guid.NewGuid();
    public string OrderNumber { get; set; }
    public DateTime Timestamp { get; set; }
    public string EventType { get; set; }
    public string Description { get; set; }
    public string PerformedBy { get; set; }
    public Dictionary<string, string> AdditionalData { get; set; } = new Dictionary<string, string>();
    
    public override string ToString()
    {
        return $"[{Timestamp:yyyy-MM-dd HH:mm:ss}] {EventType}: {Description}";
    }
}

// 14. 订单类(上下文)
public class Order
{
    // 订单基本信息
    public string OrderNumber { get; }
    public DateTime CreatedDate { get; }
    public string CustomerId { get; set; }
    public string CustomerName { get; set; }
    
    // 订单状态
    private IOrderState _currentState;
    public OrderStateEnum CurrentStateEnum => _currentState.GetStateEnum();
    public string CurrentStateName => _currentState.GetStateName();
    
    // 订单项
    public List<OrderItem> Items { get; } = new List<OrderItem>();
    
    // 地址信息
    public Address ShippingAddress { get; set; }
    public Address BillingAddress { get; set; }
    
    // 付款信息
    public List<PaymentInfo> Payments { get; } = new List<PaymentInfo>();
    
    // 配送信息
    public List<ShipmentInfo> Shipments { get; } = new List<ShipmentInfo>();
    
    // 交付信息
    public List<DeliveryInfo> Deliveries { get; } = new List<DeliveryInfo>();
    
    // 退货信息
    public List<ReturnInfo> Returns { get; } = new List<ReturnInfo>();
    
    // 退款信息
    public List<RefundInfo> Refunds { get; } = new List<RefundInfo>();
    
    // 折扣信息
    public List<Discount> AppliedDiscounts { get; } = new List<Discount>();
    
    // 订单取消原因
    public string CancellationReason { get; set; }
    
    // 历史状态
    public List<OrderEventLog> EventHistory { get; } = new List<OrderEventLog>();
    
    // 事件
    public event EventHandler<OrderStateChangedEventArgs> StateChanged;
    
    // 计算订单总金额
    public decimal SubTotal => Items.Sum(item => item.TotalPrice);
    public decimal DiscountAmount => Items.Sum(item => item.DiscountAmount) + AppliedDiscounts.Sum(d => d.CalculateDiscount(SubTotal));
    public decimal ShippingCost => Shipments.Sum(s => s.ShippingCost);
    public decimal TaxAmount { get; set; }
    public decimal GrandTotal => SubTotal - DiscountAmount + ShippingCost + TaxAmount;
    public decimal PaidAmount => Payments.Where(p => p.Status == PaymentInfo.PaymentStatus.Successful).Sum(p => p.Amount);
    public decimal RefundedAmount => Refunds.Where(r => r.Status == RefundInfo.RefundStatus.Completed).Sum(r => r.Amount);
    public decimal BalanceDue => GrandTotal - PaidAmount + RefundedAmount;
    
    // 构造函数
    public Order(string orderNumber, string customerId, string customerName)
    {
        OrderNumber = orderNumber;
        CreatedDate = DateTime.Now;
        CustomerId = customerId;
        CustomerName = customerName;
        
        // 设置初始状态
        _currentState = new CreatedState();
        
        // 记录创建事件
        LogEvent("OrderCreated", $"订单 {OrderNumber} 已创建", "System");
    }
    
    // 设置状态
    public async Task<bool> SetState(IOrderState newState)
    {
        if (!_currentState.CanTransitionTo(newState))
        {
            LogEvent("InvalidStateTransition", 
                $"无效的状态转换: 从 {_currentState.GetStateName()} 到 {newState.GetStateName()}", 
                "System");
            return false;
        }
        
        var oldState = _currentState;
        
        // 退出当前状态
        await Task.Run(() => oldState.ExitState(this));
        
        // 切换状态
        _currentState = newState;
        
        // 进入新状态
        await Task.Run(() => _currentState.EnterState(this));
        
        // 记录状态变更事件
        LogEvent("StateChanged", 
            $"订单状态从 {oldState.GetStateName()} 变更为 {newState.GetStateName()}", 
            "System");
            
        // 触发状态变更事件
        OnStateChanged(new OrderStateChangedEventArgs(
            oldState.GetStateEnum(),
            newState.GetStateEnum(),
            OrderNumber));
            
        return true;
    }
    
    // 记录事件
    public void LogEvent(string eventType, string description, string performedBy, Dictionary<string, string> additionalData = null)
    {
        var eventLog = new OrderEventLog
        {
            OrderNumber = OrderNumber,
            Timestamp = DateTime.Now,
            EventType = eventType,
            Description = description,
            PerformedBy = performedBy
        };
        
        if (additionalData != null)
        {
            foreach (var kvp in additionalData)
            {
                eventLog.AdditionalData[kvp.Key] = kvp.Value;
            }
        }
        
        EventHistory.Add(eventLog);
    }
    
    // 处理订单
    public async Task<bool> ProcessOrder()
    {
        return await _currentState.ProcessOrder(this);
    }
    
    // 支付订单
    public async Task<bool> PayOrder(PaymentInfo paymentInfo)
    {
        return await _currentState.PayOrder(this, paymentInfo);
    }
    
    // 发货订单
    public async Task<bool> ShipOrder(ShipmentInfo shipmentInfo)
    {
        return await _currentState.ShipOrder(this, shipmentInfo);
    }
    
    // 交付订单
    public async Task<bool> DeliverOrder(DeliveryInfo deliveryInfo)
    {
        return await _currentState.DeliverOrder(this, deliveryInfo);
    }
    
    // 退货订单
    public async Task<bool> ReturnOrder(ReturnInfo returnInfo)
    {
        return await _currentState.ReturnOrder(this, returnInfo);
    }
    
    // 退款订单
    public async Task<bool> RefundOrder(RefundInfo refundInfo)
    {
        return await _currentState.RefundOrder(this, refundInfo);
    }
    
    // 取消订单
    public async Task<bool> CancelOrder(string reason)
    {
        return await _currentState.CancelOrder(this, reason);
    }
    
    // 添加商品
    public async Task<bool> AddItem(OrderItem item)
    {
        return await _currentState.AddItem(this, item);
    }
    
    // 移除商品
    public async Task<bool> RemoveItem(string itemId)
    {
        return await _currentState.RemoveItem(this, itemId);
    }
    
    // 更新数量
    public async Task<bool> UpdateQuantity(string itemId, int quantity)
    {
        return await _currentState.UpdateQuantity(this, itemId, quantity);
    }
    
    // 应用折扣
    public async Task<bool> ApplyDiscount(Discount discount)
    {
        return await _currentState.ApplyDiscount(this, discount);
    }
    
    // 更新配送地址
    public async Task<bool> UpdateShippingAddress(Address address)
    {
        return await _currentState.UpdateShippingAddress(this, address);
    }
    
    // 更新账单地址
    public async Task<bool> UpdateBillingAddress(Address address)
    {
        return await _currentState.UpdateBillingAddress(this, address);
    }
    
    // 获取允许的状态转换
    public List<OrderStateTransition> GetAllowedTransitions()
    {
        return _currentState.GetAllowedTransitions();
    }
    
    // 状态变更事件触发方法
    protected virtual void OnStateChanged(OrderStateChangedEventArgs e)
    {
        StateChanged?.Invoke(this, e);
    }
    
    // 显示订单信息
    public void DisplayOrder()
    {
        Console.WriteLine($"=== 订单信息 ===");
        Console.WriteLine($"订单号: {OrderNumber}");
        Console.WriteLine($"客户: {CustomerName} (ID: {CustomerId})");
        Console.WriteLine($"创建时间: {CreatedDate:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine($"当前状态: {CurrentStateName}");
        
        if (Items.Count > 0)
        {
            Console.WriteLine("\n商品列表:");
            foreach (var item in Items)
            {
                Console.WriteLine($"- {item.ProductName} x {item.Quantity} @ {item.UnitPrice:C} = {item.TotalPrice:C}");
                if (item.AppliedDiscounts.Count > 0)
                {
                    Console.WriteLine($"  折扣: {item.DiscountAmount:C}");
                }
            }
        }
        
        Console.WriteLine($"\n小计: {SubTotal:C}");
        if (DiscountAmount > 0)
        {
            Console.WriteLine($"折扣: -{DiscountAmount:C}");
        }
        Console.WriteLine($"运费: {ShippingCost:C}");
        Console.WriteLine($"税费: {TaxAmount:C}");
        Console.WriteLine($"总计: {GrandTotal:C}");
        Console.WriteLine($"已支付: {PaidAmount:C}");
        
        if (RefundedAmount > 0)
        {
            Console.WriteLine($"已退款: {RefundedAmount:C}");
        }
        
        if (BalanceDue > 0)
        {
            Console.WriteLine($"待支付: {BalanceDue:C}");
        }
        
        if (ShippingAddress != null)
        {
            Console.WriteLine("\n配送地址:");
            Console.WriteLine(ShippingAddress.ToString());
        }
        
        if (Payments.Count > 0)
        {
            Console.WriteLine("\n支付记录:");
            foreach (var payment in Payments)
            {
                Console.WriteLine($"- {payment.PaymentDate:yyyy-MM-dd HH:mm:ss} | {payment.PaymentMethod} | {payment.Amount:C} | {payment.Status}");
            }
        }
        
        if (Shipments.Count > 0)
        {
            Console.WriteLine("\n配送记录:");
            foreach (var shipment in Shipments)
            {
                Console.WriteLine($"- {shipment.ShipmentDate:yyyy-MM-dd} | {shipment.Carrier} | 跟踪号: {shipment.TrackingNumber} | {shipment.Status}");
            }
        }
        
        if (EventHistory.Count > 0)
        {
            Console.WriteLine("\n订单历史:");
            foreach (var log in EventHistory.OrderByDescending(e => e.Timestamp).Take(5))
            {
                Console.WriteLine($"- {log}");
            }
            
            if (EventHistory.Count > 5)
            {
                Console.WriteLine($"...(还有 {EventHistory.Count - 5} 条记录)");
            }
        }
    }
}

// 15. 基础状态类 - 实现通用的逻辑和默认行为
public abstract class OrderStateBase : IOrderState
{
    // 状态转换检查
    public virtual bool CanTransitionTo(IOrderState nextState)
    {
        var allowedTransitions = GetAllowedTransitions();
        return allowedTransitions.Any(t => t.ToState == nextState.GetStateEnum());
    }
    
    // 进入状态
    public virtual void EnterState(Order order)
    {
        // 默认实现,可由子类重写
    }
    
    // 退出状态
    public virtual void ExitState(Order order)
    {
        // 默认实现,可由子类重写
    }
    
    // 默认的操作实现 - 大多数操作在大多数状态下是不允许的
    public virtual Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine($"无法处理订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"无法支付订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo)
    {
        Console.WriteLine($"无法发货订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo)
    {
        Console.WriteLine($"无法交付订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"无法退货订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"无法退款订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"无法取消订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    // 在大多数状态下修改订单都是不允许的
    public virtual Task<bool> AddItem(Order order, OrderItem item)
    {
        Console.WriteLine($"无法添加商品: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> RemoveItem(Order order, string itemId)
    {
        Console.WriteLine($"无法移除商品: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateQuantity(Order order, string itemId, int quantity)
    {
        Console.WriteLine($"无法更新数量: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ApplyDiscount(Order order, Discount discount)
    {
        Console.WriteLine($"无法应用折扣: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        Console.WriteLine($"无法更新配送地址: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateBillingAddress(Order order, Address address)
    {
        Console.WriteLine($"无法更新账单地址: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    // 子类必须实现的方法
    public abstract string GetStateName();
    public abstract OrderStateEnum GetStateEnum();
    public abstract List<OrderStateTransition> GetAllowedTransitions();
}

// 16. 已创建状态
public class CreatedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已进入已创建状态");
    }
    
    public override string GetStateName()
    {
        return "已创建";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Created;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.Processing, "处理", "开始处理订单"),
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.AwaitingPayment, "等待支付", "订单已准备好等待支付"),
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    // 在已创建状态下允许的操作
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine($"开始处理订单 {order.OrderNumber}");
        
        // 异步转换到处理中状态
        return order.SetState(new ProcessingState());
    }
    
    public override async Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"为订单 {order.OrderNumber} 处理支付");
        
        // 添加支付记录
        order.Payments.Add(paymentInfo);
        
        // 根据支付状态设置订单状态
        if (paymentInfo.Status == PaymentInfo.PaymentStatus.Successful)
        {
            // 支付成功,转到已支付状态
            order.LogEvent("PaymentReceived", $"收到支付 {paymentInfo.Amount:C}", "System", 
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "TransactionId", paymentInfo.TransactionId }
                });
                
            return await order.SetState(new PaidState());
        }
        else if (paymentInfo.Status == PaymentInfo.PaymentStatus.Failed)
        {
            // 支付失败,转到支付失败状态
            order.LogEvent("PaymentFailed", $"支付失败 {paymentInfo.Amount:C}", "System",
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "Reason", "Payment processor declined" }
                });
                
            return await order.SetState(new PaymentFailedState());
        }
        else
        {
            // 其他状态,转到等待支付状态
            order.LogEvent("PaymentPending", $"等待支付确认 {paymentInfo.Amount:C}", "System");
            return await order.SetState(new AwaitingPaymentState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "Customer");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
    
    // 允许在已创建状态修改订单
    public override Task<bool> AddItem(Order order, OrderItem item)
    {
        // 检查是否已存在相同商品
        var existingItem = order.Items.FirstOrDefault(i => i.ProductId == item.ProductId);
        
        if (existingItem != null)
        {
            // 如果已存在,增加数量
            existingItem.Quantity += item.Quantity;
            Console.WriteLine($"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}");
            
            order.LogEvent("ItemUpdated", $"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}", "System");
        }
        else
        {
            // 添加新商品
            order.Items.Add(item);
            Console.WriteLine($"添加商品: {item.ProductName} x {item.Quantity}");
            
            order.LogEvent("ItemAdded", $"添加商品: {item.ProductName} x {item.Quantity}", "System");
        }
        
        return Task.FromResult(true);
    }
    
    public override Task<bool> RemoveItem(Order order, string itemId)
    {
        var item = order.Items.FirstOrDefault(i => i.ItemId == itemId);
        
        if (item != null)
        {
            order.Items.Remove(item);
            Console.WriteLine($"移除商品: {item.ProductName}");
            
            order.LogEvent("ItemRemoved", $"移除商品: {item.ProductName}", "System");
            return Task.FromResult(true);
        }
        
        Console.WriteLine($"商品不存在: {itemId}");
        return Task.FromResult(false);
    }
    
    public override Task<bool> UpdateQuantity(Order order, string itemId, int quantity)
    {
        var item = order.Items.FirstOrDefault(i => i.ItemId == itemId);
        
        if (item != null)
        {
            if (quantity <= 0)
            {
                // 如果数量为0或负数,移除商品
                return RemoveItem(order, itemId);
            }
            
            int oldQuantity = item.Quantity;
            item.Quantity = quantity;
            
            Console.WriteLine($"更新商品 {item.ProductName} 数量: {oldQuantity} -> {quantity}");
            
            order.LogEvent("QuantityUpdated", 
                $"更新商品 {item.ProductName} 数量: {oldQuantity} -> {quantity}", 
                "System");
                
            return Task.FromResult(true);
        }
        
        Console.WriteLine($"商品不存在: {itemId}");
        return Task.FromResult(false);
    }
    
    public override Task<bool> ApplyDiscount(Order order, Discount discount)
    {
        // 验证折扣是否有效
        if (!discount.IsValid())
        {
            Console.WriteLine($"折扣无效: {discount.Code}");
            return Task.FromResult(false);
        }
        
        // 检查是否已应用相同折扣
        if (order.AppliedDiscounts.Any(d => d.Code == discount.Code))
        {
            Console.WriteLine($"折扣已应用: {discount.Code}");
            return Task.FromResult(false);
        }
        
        // 应用折扣
        order.AppliedDiscounts.Add(discount);
        
        Console.WriteLine($"应用折扣: {discount.Code}, 折扣金额: {discount.CalculateDiscount(order.SubTotal):C}");
        
        order.LogEvent("DiscountApplied", 
            $"应用折扣: {discount.Code}, 折扣金额: {discount.CalculateDiscount(order.SubTotal):C}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        order.ShippingAddress = address;
        
        Console.WriteLine("更新配送地址");
        
        order.LogEvent("ShippingAddressUpdated", 
            $"更新配送地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateBillingAddress(Order order, Address address)
    {
        order.BillingAddress = address;
        
        Console.WriteLine("更新账单地址");
        
        order.LogEvent("BillingAddressUpdated", 
            $"更新账单地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
}

// 17. 处理中状态
public class ProcessingState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 正在处理中");
        
        // 验证订单是否可以处理
        if (order.Items.Count == 0)
        {
            Console.WriteLine("警告: 订单中没有商品");
        }
        
        if (order.ShippingAddress == null)
        {
            Console.WriteLine("警告: 缺少配送地址");
        }
    }
    
    public override string GetStateName()
    {
        return "处理中";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Processing;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Processing, OrderStateEnum.AwaitingPayment, "等待支付", "处理完成,等待支付"),
            new OrderStateTransition(OrderStateEnum.Processing, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    // 在处理中状态下允许的操作
    public override async Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("完成订单处理");
        
        // 生成税费
        decimal taxRate = 0.08m; // 示例税率
        order.TaxAmount = order.SubTotal * taxRate;
        
        order.LogEvent("TaxCalculated", $"计算税费: {order.TaxAmount:C}", "System");
        
        // 验证订单所需信息
        bool isValid = ValidateOrder(order);
        
        if (!isValid)
        {
            return false;
        }
        
        // 处理完成,转到等待支付状态
        order.LogEvent("ProcessingCompleted", "订单处理完成", "System");
        return await order.SetState(new AwaitingPaymentState());
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
    
    // 在处理中状态仍然可以修改订单
    public override Task<bool> AddItem(Order order, OrderItem item)
    {
        // 检查是否已存在相同商品
        var existingItem = order.Items.FirstOrDefault(i => i.ProductId == item.ProductId);
        
        if (existingItem != null)
        {
            // 如果已存在,增加数量
            existingItem.Quantity += item.Quantity;
            Console.WriteLine($"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}");
            
            order.LogEvent("ItemUpdated", $"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}", "System");
        }
        else
        {
            // 添加新商品
            order.Items.Add(item);
            Console.WriteLine($"添加商品: {item.ProductName} x {item.Quantity}");
            
            order.LogEvent("ItemAdded", $"添加商品: {item.ProductName} x {item.Quantity}", "System");
        }
        
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        order.ShippingAddress = address;
        
        Console.WriteLine("更新配送地址");
        
        order.LogEvent("ShippingAddressUpdated", 
            $"更新配送地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    // 订单验证
    private bool ValidateOrder(Order order)
    {
        bool isValid = true;
        
        if (order.Items.Count == 0)
        {
            Console.WriteLine("错误: 订单中没有商品");
            isValid = false;
        }
        
        if (order.ShippingAddress == null)
        {
            Console.WriteLine("错误: 缺少配送地址");
            isValid = false;
        }
        
        return isValid;
    }
}

// 18. 等待支付状态
public class AwaitingPaymentState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 等待支付,应付金额: {order.BalanceDue:C}");
    }
    
    public override string GetStateName()
    {
        return "等待支付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.AwaitingPayment;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.Paid, "支付完成", "订单已支付"),
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.PaymentFailed, "支付失败", "订单支付失败"),
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    public override async Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"为订单 {order.OrderNumber} 处理支付 {paymentInfo.Amount:C}");
        
        // 添加支付记录
        order.Payments.Add(paymentInfo);
        
        // 根据支付状态设置订单状态
        if (paymentInfo.Status == PaymentInfo.PaymentStatus.Successful)
        {
            // 检查支付金额是否足够
            if (order.PaidAmount >= order.GrandTotal)
            {
                // 支付足够,转到已支付状态
                order.LogEvent("PaymentReceived", $"收到支付 {paymentInfo.Amount:C}", "System", 
                    new Dictionary<string, string> {
                        { "PaymentMethod", paymentInfo.PaymentMethod },
                        { "TransactionId", paymentInfo.TransactionId }
                    });
                    
                return await order.SetState(new PaidState());
            }
            else
            {
                // 支付不足,保持等待支付状态
                order.LogEvent("PartialPaymentReceived", 
                    $"收到部分支付 {paymentInfo.Amount:C}, 剩余 {order.BalanceDue:C}", 
                    "System");
                    
                Console.WriteLine($"部分支付已收到,剩余应付金额: {order.BalanceDue:C}");
                return true;
            }
        }
        else if (paymentInfo.Status == PaymentInfo.PaymentStatus.Failed)
        {
            // 支付失败,转到支付失败状态
            order.LogEvent("PaymentFailed", $"支付失败 {paymentInfo.Amount:C}", "System",
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "Reason", "Payment processor declined" }
                });
                
            return await order.SetState(new PaymentFailedState());
        }
        else
        {
            // 其他状态,保持等待支付状态
            order.LogEvent("PaymentPending", $"等待支付确认 {paymentInfo.Amount:C}", "System");
            Console.WriteLine("支付处理中,等待确认");
            return true;
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 19. 支付失败状态
public class PaymentFailedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 支付失败");
    }
    
    public override string GetStateName()
    {
        return "支付失败";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PaymentFailed;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PaymentFailed, OrderStateEnum.AwaitingPayment, "重新支付", "尝试重新支付"),
            new OrderStateTransition(OrderStateEnum.PaymentFailed, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("重新尝试支付订单");
        return order.SetState(new AwaitingPaymentState());
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 20. 已支付状态
public class PaidState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已支付完成,准备发货");
    }
    
    public override string GetStateName()
    {
        return "已支付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Paid;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.ReadyForShipment, "准备发货", "订单已准备好发货"),
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.Refunded, "退款", "订单已退款"),
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.Canceled, "取消", "取消订单并退款")
        };
    }
    
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("订单已支付,准备发货");
        return order.SetState(new ReadyForShipmentState());
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 如果退款金额等于已支付金额,转到已退款状态
        if (order.RefundedAmount >= order.PaidAmount)
        {
            return await order.SetState(new RefundedState());
        }
        else
        {
            // 部分退款,转到部分退款状态
            return await order.SetState(new PartiallyRefundedState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消已支付订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 自动创建退款信息
        var refundInfo = new RefundInfo
        {
            RefundId = Guid.NewGuid().ToString(),
            Amount = order.PaidAmount,
            Reason = "订单取消: " + reason,
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Processing,
            RefundMethod = "原付款方式"
        };
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录取消事件
        order.LogEvent("OrderCanceledWithRefund", 
            $"订单已取消并退款 {refundInfo.Amount:C}: {reason}", 
            "System");
            
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 21. 准备发货状态
public class ReadyForShipmentState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已准备好发货");
    }
    
    public override string GetStateName()
    {
        return "准备发货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.ReadyForShipment;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Shipped, "已发货", "订单已发货"),
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Refunded, "退款", "订单已退款"),
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Canceled, "取消", "取消订单并退款")
        };
    }
    
    public override async Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 发货中");
        
        // 添加配送信息
        order.Shipments.Add(shipmentInfo);
        
        // 记录发货事件
        order.LogEvent("OrderShipped", 
            $"订单已发货: {shipmentInfo.Carrier} {shipmentInfo.TrackingNumber}", 
            "System", 
            new Dictionary<string, string> {
                { "Carrier", shipmentInfo.Carrier },
                { "TrackingNumber", shipmentInfo.TrackingNumber }
            });
            
        // 转换到已发货状态
        return await order.SetState(new ShippedState());
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 如果退款金额等于已支付金额,转到已退款状态
        if (order.RefundedAmount >= order.PaidAmount)
        {
            return await order.SetState(new RefundedState());
        }
        else
        {
            // 部分退款,转到部分退款状态
            return await order.SetState(new PartiallyRefundedState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消准备发货订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 自动创建退款信息
        var refundInfo = new RefundInfo
        {
            RefundId = Guid.NewGuid().ToString(),
            Amount = order.PaidAmount,
            Reason = "订单取消: " + reason,
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Processing,
            RefundMethod = "原付款方式"
        };
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录取消事件
        order.LogEvent("OrderCanceledWithRefund", 
            $"订单已取消并退款 {refundInfo.Amount:C}: {reason}", 
            "System");
            
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 22. 已发货状态
public class ShippedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已发货");
    }
    
    public override string GetStateName()
    {
        return "已发货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Shipped;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Shipped, OrderStateEnum.Delivered, "已交付", "订单已交付"),
            new OrderStateTransition(OrderStateEnum.Shipped, OrderStateEnum.Returned, "已退货", "订单已退货")
        };
    }
    
    public override async Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已交付");
        
        // 添加交付信息
        order.Deliveries.Add(deliveryInfo);
        
        // 记录交付事件
        order.LogEvent("OrderDelivered", 
            $"订单已交付: 接收人 {deliveryInfo.ReceivedBy}", 
            "System");
            
        // 转换到已交付状态
        return await order.SetState(new DeliveredState());
    }
}

// 23. 已交付状态
public class DeliveredState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已交付,交付时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
        
        // 检查是否所有项目都已交付
        bool allItemsDelivered = true;
        
        // 在实际应用中,这里会检查每个订单项的交付状态
        
        if (allItemsDelivered)
        {
            // 如果一切正常,自动转换到已完成状态
            Task.Run(async () => {
                // 延迟一些时间后自动完成订单
                await Task.Delay(5000); // 5秒后自动完成
                await order.SetState(new CompletedState());
            });
        }
    }
    
    public override string GetStateName()
    {
        return "已交付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Delivered;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.Completed, "已完成", "订单已完成"),
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.Returned, "已退货", "订单已退货"),
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.PartiallyReturned, "部分退货", "订单部分退货")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("ReturnRequested", 
            $"退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            bool itemReturned = returnInfo.ReturnedItems.Any(ri => ri.ItemId == item.ItemId && ri.Quantity == item.Quantity);
            if (!itemReturned)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        else
        {
            // 部分退货,转到部分退货状态
            return await order.SetState(new PartiallyReturnedState());
        }
    }
}

// 24. 已完成状态
public class CompletedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已完成");
        
        // 记录完成事件
        order.LogEvent("OrderCompleted", "订单已完成", "System");
    }
    
    public override string GetStateName()
    {
        return "已完成";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Completed;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Completed, OrderStateEnum.Returned, "已退货", "订单已退货"),
            new OrderStateTransition(OrderStateEnum.Completed, OrderStateEnum.PartiallyReturned, "部分退货", "订单部分退货")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理已完成订单 {order.OrderNumber} 的退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("ReturnRequested", 
            $"退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            bool itemReturned = returnInfo.ReturnedItems.Any(ri => ri.ItemId == item.ItemId && ri.Quantity == item.Quantity);
            if (!itemReturned)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        else
        {
            // 部分退货,转到部分退货状态
            return await order.SetState(new PartiallyReturnedState());
        }
    }
}

// 25. 已退货状态
public class ReturnedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已退货");
        
        // 在这里可以自动触发退款流程
        Task.Run(async () => {
            // 创建退款信息
            var refundInfo = new RefundInfo
            {
                RefundId = Guid.NewGuid().ToString(),
                Amount = order.PaidAmount,
                Reason = "订单退货",
                RefundRequestDate = DateTime.Now,
                Status = RefundInfo.RefundStatus.Processing,
                RefundMethod = "原付款方式"
            };
            
            // 处理退款
            await order.RefundOrder(refundInfo);
        });
    }
    
    public override string GetStateName()
    {
        return "已退货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Returned;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Returned, OrderStateEnum.Refunded, "已退款", "订单已退款")
        };
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理退货订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 转换到已退款状态
        return await order.SetState(new RefundedState());
    }
}

// 26. 部分退货状态
public class PartiallyReturnedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已部分退货");
    }
    
    public override string GetStateName()
    {
        return "部分退货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PartiallyReturned;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PartiallyReturned, OrderStateEnum.Returned, "全部退货", "订单已全部退货"),
            new OrderStateTransition(OrderStateEnum.PartiallyReturned, OrderStateEnum.PartiallyRefunded, "部分退款", "订单已部分退款")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理部分退货订单 {order.OrderNumber} 的额外退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("AdditionalReturnRequested", 
            $"额外退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否现在是全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            // 从所有退货记录中检查该商品的退货数量
            int returnedQuantity = 0;
            foreach (var returnRecord in order.Returns)
            {
                returnedQuantity += returnRecord.ReturnedItems
                    .Where(ri => ri.ItemId == item.ItemId)
                    .Sum(ri => ri.Quantity);
            }
            
            if (returnedQuantity < item.Quantity)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        
        return true;
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理部分退货订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("PartialRefundProcessed", 
            $"处理部分退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 转换到部分退款状态
        return await order.SetState(new PartiallyRefundedState());
    }
}

// 27. 已退款状态
public class RefundedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已退款");
        
        // 记录退款完成事件
        order.LogEvent("RefundCompleted", $"退款完成: {order.RefundedAmount:C}", "System");
    }
    
    public override string GetStateName()
    {
        return "已退款";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Refunded;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        // 已退款是终态,没有后续转换
        return new List<OrderStateTransition>();
    }
}

// 28. 部分退款状态
public class PartiallyRefundedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已部分退款: {order.RefundedAmount:C}");
    }
    
    public override string GetStateName()
    {
        return "部分退款";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PartiallyRefunded;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PartiallyRefunded, OrderStateEnum.Refunded, "全部退款", "订单已全部退款")
        };
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理部分退款订单 {order.OrderNumber} 的额外退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("AdditionalRefundProcessed", 
            $"处理额外退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 检查退款金额是否等于已支付金额
        if (order.RefundedAmount >= order.PaidAmount)
        {
            // 全部退款,转到已退款状态
            return await order.SetState(new RefundedState());
        }
        
        return true;
    }
}

// 29. 已取消状态
public class CanceledState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已取消,原因: {order.CancellationReason}");
    }
    
    public override string GetStateName()
    {
        return "已取消";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Canceled;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        // 已取消是终态,没有后续转换
        return new List<OrderStateTransition>();
    }
}

// 30. 订单状态工厂
public static class OrderStateFactory
{
    public static IOrderState CreateState(OrderStateEnum stateEnum)
    {
        return stateEnum switch
        {
            OrderStateEnum.Created => new CreatedState(),
            OrderStateEnum.Processing => new ProcessingState(),
            OrderStateEnum.AwaitingPayment => new AwaitingPaymentState(),
            OrderStateEnum.PaymentFailed => new PaymentFailedState(),
            OrderStateEnum.Paid => new PaidState(),
            OrderStateEnum.ReadyForShipment => new ReadyForShipmentState(),
            OrderStateEnum.Shipped => new ShippedState(),
            OrderStateEnum.Delivered => new DeliveredState(),
            OrderStateEnum.Returned => new ReturnedState(),
            OrderStateEnum.PartiallyReturned => new PartiallyReturnedState(),
            OrderStateEnum.Refunded => new RefundedState(),
            OrderStateEnum.PartiallyRefunded => new PartiallyRefundedState(),
            OrderStateEnum.Canceled => new CanceledState(),
            OrderStateEnum.Completed => new CompletedState(),
            _ => throw new ArgumentException($"未知的订单状态: {stateEnum}")
        };
    }
}

// 31. 订单处理示例
public class OrderProcessingDemo
{
    public static async Task RunDemoAsync()
    {
        // 创建订单
        var order = new Order("ORD-2023-001", "CUST-001", "张三");
        
        // 显示订单状态
        order.DisplayOrder();
        Console.WriteLine();
        
        // 添加商品
        await order.AddItem(new OrderItem
        {
            ItemId = "ITEM-001",
            ProductId = "PROD-001",
            ProductName = "iPhone 15 Pro",
            Quantity = 1,
            UnitPrice = 8999.00m
        });
        
        await order.AddItem(new OrderItem
        {
            ItemId = "ITEM-002",
            ProductId = "PROD-002",
            ProductName = "AirPods Pro",
            Quantity = 1,
            UnitPrice = 1999.00m
        });
        
        // 应用折扣
        await order.ApplyDiscount(new Discount
        {
            DiscountId = "DISC-001",
            Code = "WELCOME10",
            Description = "新用户折扣10%",
            Type = Discount.DiscountType.Percentage,
            Value = 10
        });
        
        // 设置地址
        await order.UpdateShippingAddress(new Address
        {
            FullName = "张三",
            AddressLine1 = "科技路123号",
            City = "北京",
            State = "北京",
            ZipCode = "100000",
            Country = "中国",
            PhoneNumber = "13800138000"
        });
        
        await order.UpdateBillingAddress(new Address
        {
            FullName = "张三",
            AddressLine1 = "科技路123号",
            City = "北京",
            State = "北京",
            ZipCode = "100000",
            Country = "中国",
            PhoneNumber = "13800138000"
        });
        
        // 处理订单
        Console.WriteLine("\n处理订单...");
        await order.ProcessOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 支付订单
        Console.WriteLine("\n支付订单...");
        await order.PayOrder(new PaymentInfo
        {
            PaymentId = "PAY-001",
            Amount = order.GrandTotal,
            PaymentMethod = "信用卡",
            PaymentDate = DateTime.Now,
            TransactionId = "TRANS-001",
            Status = PaymentInfo.PaymentStatus.Successful
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 准备发货
        Console.WriteLine("\n准备发货...");
        await order.ProcessOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 发货
        Console.WriteLine("\n发货...");
        await order.ShipOrder(new ShipmentInfo
        {
            ShipmentId = "SHIP-001",
            Carrier = "顺丰快递",
            TrackingNumber = "SF1234567890",
            ShipmentDate = DateTime.Now,
            ShippingCost = 20.00m,
            Status = ShipmentInfo.ShipmentStatus.Shipped
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 交付
        Console.WriteLine("\n交付...");
        await order.DeliverOrder(new DeliveryInfo
        {
            DeliveryId = "DEL-001",
            DeliveryDate = DateTime.Now,
            ReceivedBy = "张三",
            Status = DeliveryInfo.DeliveryStatus.Delivered
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 等待订单自动完成
        Console.WriteLine("\n等待订单自动完成...");
        await Task.Delay(6000);
        order.DisplayOrder();
        Console.WriteLine();
        
        // 创建第二个订单并取消
        var order2 = new Order("ORD-2023-002", "CUST-002", "李四");
        Console.WriteLine($"\n创建第二个订单: {order2.OrderNumber}");
        
        // 添加商品
        await order2.AddItem(new OrderItem
        {
            ItemId = "ITEM-003",
            ProductId = "PROD-003",
            ProductName = "MacBook Air",
            Quantity = 1,
            UnitPrice = 7999.00m
        });
        
        // 设置地址
        await order2.UpdateShippingAddress(new Address
        {
            FullName = "李四",
            AddressLine1 = "创新路456号",
            City = "上海",
            State = "上海",
            ZipCode = "200000",
            Country = "中国",
            PhoneNumber = "13900139000"
        });
        
        // 处理订单
        Console.WriteLine("\n处理订单...");
        await order2.ProcessOrder();
        
        // 取消订单
        Console.WriteLine("\n取消订单...");
        await order2.CancelOrder("客户要求取消");
        order2.DisplayOrder();
        
        // 创建第三个订单并处理退货
        var order3 = new Order("ORD-2023-003", "CUST-003", "王五");
        Console.WriteLine($"\n创建第三个订单: {order3.OrderNumber}");
        
        // 添加商品
        await order3.AddItem(new OrderItem
        {
            ItemId = "ITEM-004",
            ProductId = "PROD-004",
            ProductName = "iPad Pro",
            Quantity = 1,
            UnitPrice = 6999.00m
        });
        
        await order3.AddItem(new OrderItem
        {
            ItemId = "ITEM-005",
            ProductId = "PROD-005",
            ProductName = "Apple Pencil",
            Quantity = 1,
            UnitPrice = 899.00m
        });
        
        // 设置地址
        await order3.UpdateShippingAddress(new Address
        {
            FullName = "王五",
            AddressLine1 = "发展大道789号",
            City = "广州",
            State = "广东",
            ZipCode = "510000",
            Country = "中国",
            PhoneNumber = "13600136000"
        });
        
        // 处理并支付订单
        await order3.ProcessOrder();
        await order3.PayOrder(new PaymentInfo
        {
            PaymentId = "PAY-003",
            Amount = order3.GrandTotal,
            PaymentMethod = "支付宝",
            PaymentDate = DateTime.Now,
            TransactionId = "TRANS-003",
            Status = PaymentInfo.PaymentStatus.Successful
        });
        
        // 发货和交付
        await order3.ProcessOrder();
        await order3.ShipOrder(new ShipmentInfo
        {
            ShipmentId = "SHIP-003",
            Carrier = "中通快递",
            TrackingNumber = "ZT9876543210",
            ShipmentDate = DateTime.Now,
            ShippingCost = 15.00m,
            Status = ShipmentInfo.ShipmentStatus.Shipped
        });
        
        await order3.DeliverOrder(new DeliveryInfo
        {
            DeliveryId = "DEL-003",
            DeliveryDate = DateTime.Now,
            ReceivedBy = "王五",
            Status = DeliveryInfo.DeliveryStatus.Delivered
        });
        
        // 完成订单
        await Task.Delay(6000);
        
        // 处理部分退货
        Console.WriteLine("\n处理部分退货...");
        var item = order3.Items.First(i => i.ProductId == "PROD-005"); // Apple Pencil
        var returnedItem = item.Clone();
        
        await order3.ReturnOrder(new ReturnInfo
        {
            ReturnId = "RET-001",
            Reason = "不满意产品",
            ReturnRequestDate = DateTime.Now,
            ReturnedItems = new List<OrderItem> { returnedItem },
            Status = ReturnInfo.ReturnStatus.Received
        });
        
        // 处理退款
        Console.WriteLine("\n处理退款...");
        await order3.RefundOrder(new RefundInfo
        {
            RefundId = "REF-001",
            Amount = returnedItem.FinalPrice,
            Reason = "退货退款",
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Completed,
            RefundMethod = "原付款方式"
        });
        
        order3.DisplayOrder();
    }
}

// 32. 客户端代码
public class Client
{
    public static async Task Main()
    {
        Console.WriteLine("===== 订单状态管理演示 =====\n");
        
        await OrderProcessingDemo.RunDemoAsync();
        
        Console.WriteLine("\n===== 演示完成 =====");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151

业务场景结合:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;

// 工单处理系统 - 使用状态模式实现工单流转

// 1. 工单优先级枚举
public enum TicketPriority
{
    Low,
    Normal,
    High,
    Critical
}

// 2. 工单类型枚举
public enum TicketType
{
    Bug,
    Feature,
    Support,
    Inquiry,
    Complaint,
    Maintenance,
    Security,
    Other
}

// 3. 工单状态枚举
public enum TicketStateEnum
{
    New,
    Triaged,
    Assigned,
    InProgress,
    Waiting,
    Resolved,
    Verified,
    Reopened,
    Closed,
    Cancelled
}

// 4. 用户角色枚举
public enum UserRole
{
    Customer,
    Agent,
    Supervisor,
    Developer,
    Manager,
    Administrator
}

// 5. 用户类
public class User
{
    public string UserId { get; }
    public string Username { get; set; }
    public string Email { get; set; }
    public string Department { get; set; }
    public UserRole Role { get; set; }
    public bool IsActive { get; set; } = true;
    
    public User(string userId, string username, string email, UserRole role)
    {
        UserId = userId;
        Username = username;
        Email = email;
        Role = role;
    }
    
    // 检查用户是否有特定权限
    public bool HasPermission(string permissionName)
    {
        // 简化的权限检查,基于角色
        return Role switch
        {
            UserRole.Administrator => true, // 管理员有所有权限
            UserRole.Manager => permissionName != "system_config",
            UserRole.Supervisor => new[] { "assign_ticket", "resolve_ticket", "close_ticket", "reopen_ticket" }.Contains(permissionName),
            UserRole.Developer => new[] { "update_ticket", "resolve_ticket" }.Contains(permissionName),
            UserRole.Agent => new[] { "update_ticket", "assign_ticket", "resolve_ticket" }.Contains(permissionName),
            UserRole.Customer => new[] { "create_ticket", "update_ticket", "close_ticket" }.Contains(permissionName),
            _ => false
        };
    }
}

// 6. 工单评论类
public class TicketComment
{
    public string CommentId { get; } = Guid.NewGuid().ToString();
    public string Content { get; set; }
    public string AuthorId { get; set; }
    public string AuthorName { get; set; }
    public DateTime CreatedTime { get; }
    public bool IsInternal { get; set; } // 是否仅内部可见
    
    public TicketComment(string content, string authorId, string authorName, bool isInternal = false)
    {
        Content = content;
        AuthorId = authorId;
        AuthorName = authorName;
        CreatedTime = DateTime.Now;
        IsInternal = isInternal;
    }
    
    public override string ToString()
    {
        string internalMark = IsInternal ? " [内部]" : "";
        return $"{CreatedTime:yyyy-MM-dd HH:mm:ss} - {AuthorName}{internalMark}: {Content}";
    }
}

// 7. 工单附件类
public class TicketAttachment
{
    public string AttachmentId { get; } = Guid.NewGuid().ToString();
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public long FileSize { get; set; }
    public string UploadedBy { get; set; }
    public DateTime UploadTime { get; }
    public string FileUrl { get; set; }
    
    public TicketAttachment(string fileName, string contentType, long fileSize, string uploadedBy)
    {
        FileName = fileName;
        ContentType = contentType;
        FileSize = fileSize;
        UploadedBy = uploadedBy;
        UploadTime = DateTime.Now;
        FileUrl = $"/attachments/{AttachmentId}/{fileName}"; // 示例URL
    }
    
    public string GetFormattedSize()
    {
        string[] sizes = { "B", "KB", "MB", "GB" };
        double len = FileSize;
        int order = 0;
        
        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len /= 1024;
        }
        
        return $"{len:0.##} {sizes[order]}";
    }
}

// 8. 工单事件日志
public class TicketEvent
{
    public string EventId { get; } = Guid.NewGuid().ToString();
    public string TicketId { get; set; }
    public string EventType { get; set; }
    public string Description { get; set; }
    public string UserId { get; set; }
    public string Username { get; set; }
    public DateTime Timestamp { get; }
    public Dictionary<string, string> EventData { get; } = new Dictionary<string, string>();
    
    public TicketEvent(string ticketId, string eventType, string description, string userId, string username)
    {
        TicketId = ticketId;
        EventType = eventType;
        Description = description;
        UserId = userId;
        Username = username;
        Timestamp = DateTime.Now;
    }
    
    public override string ToString()
    {
        return $"{Timestamp:yyyy-MM-dd HH:mm:ss} - {EventType}: {Description} (by {Username})";
    }
}

// 9. 工单状态接口
public interface ITicketState
{
    TicketStateEnum StateEnum { get; }
    string StateName { get; }
    
    // 状态转换
    bool CanTransitionTo(ITicketState nextState);
    void EnterState(SupportTicket ticket, string userId, string comments);
    void ExitState(SupportTicket ticket, string userId);
    List<TicketStateEnum> GetAllowedNextStates(SupportTicket ticket, User currentUser);
    
    // 工单操作
    Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments);
    Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments);
    Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal);
    Task<bool> AddAttachment(SupportTicket ticket, TicketAttachment attachment, string userId, string comments);
    Task<bool> SetPriority(SupportTicket ticket, TicketPriority priority, string userId, string comments);
    Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments);
    Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments);
    Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason);
    Task<bool> CancelTicket(SupportTicket ticket, string userId, string reason);
    Task<bool> EscalateTicket(SupportTicket ticket, string userId, string reason);
}

// 10. 抽象工单状态类 - 提供默认实现
public abstract class TicketStateBase : ITicketState
{
    public abstract TicketStateEnum StateEnum { get; }
    public abstract string StateName { get; }
    
    // 状态转换
    public virtual bool CanTransitionTo(ITicketState nextState)
    {
        var allowedStates = GetAllowedTransitions();
        return allowedStates.Contains(nextState.StateEnum);
    }
    
    public virtual void EnterState(SupportTicket ticket, string userId, string comments)
    {
        // 记录状态变更事件
        ticket.LogEvent(
            "state_changed", 
            $"工单状态变更为 {StateName}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 如果有评论,添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            ticket.AddCommentInternal(comments, userId, false);
        }
    }
    
    public virtual void ExitState(SupportTicket ticket, string userId)
    {
        // 默认无操作
    }
    
    public virtual List<TicketStateEnum> GetAllowedNextStates(SupportTicket ticket, User currentUser)
    {
        var allowedStates = GetAllowedTransitions();
        
        // 根据用户角色过滤允许的状态
        // 这里简化处理,仅考虑一些基本规则
        if (currentUser.Role == UserRole.Customer)
        {
            // 客户通常只能关闭工单
            return allowedStates.Intersect(new[] { TicketStateEnum.Closed }).ToList();
        }
        else if (currentUser.Role == UserRole.Agent || currentUser.Role == UserRole.Developer)
        {
            // 代理和开发人员不能取消工单
            return allowedStates.Except(new[] { TicketStateEnum.Cancelled }).ToList();
        }
        
        return allowedStates;
    }
    
    // 默认操作实现 - 大多数操作在大多数状态下是允许的
    public virtual async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "assign_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有分配工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 更新分配信息
        var oldAssigneeId = ticket.AssigneeId;
        ticket.AssigneeId = assigneeId;
        
        // 记录事件
        ticket.LogEvent(
            "ticket_assigned", 
            $"工单分配给 {ticket.GetUsername(assigneeId)}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 如果当前状态是新建或分类后,自动转换为已分配状态
        if (ticket.CurrentStateEnum == TicketStateEnum.New || ticket.CurrentStateEnum == TicketStateEnum.Triaged)
        {
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return true;
    }
    
    public virtual async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "update_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有更新工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 应用更新
        foreach (var update in updates)
        {
            ApplyUpdate(ticket, update.Key, update.Value);
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_updated", 
            $"工单已更新", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    private void ApplyUpdate(SupportTicket ticket, string field, object value)
    {
        switch (field)
        {
            case "subject":
                ticket.Subject = value.ToString();
                break;
            case "description":
                ticket.Description = value.ToString();
                break;
            case "type":
                if (Enum.TryParse<TicketType>(value.ToString(), out var ticketType))
                    ticket.Type = ticketType;
                break;
            case "tags":
                if (value is List<string> tags)
                    ticket.Tags = tags;
                break;
            // 其他字段...
        }
    }
    
    public virtual async Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal)
    {
        // 所有状态都允许添加评论
        ticket.AddCommentInternal(content, userId, isInternal);
        return await Task.FromResult(true);
    }
    
    public virtual async Task<bool> AddAttachment(SupportTicket ticket, TicketAttachment attachment, string userId, string comments)
    {
        // 所有状态都允许添加附件
        ticket.Attachments.Add(attachment);
        
        // 记录事件
        ticket.LogEvent(
            "attachment_added", 
            $"添加附件: {attachment.FileName} ({attachment.GetFormattedSize()})", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    public virtual async Task<bool> SetPriority(SupportTicket ticket, TicketPriority priority, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "update_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有更新工单优先级的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 更新优先级
        var oldPriority = ticket.Priority;
        ticket.Priority = priority;
        
        // 记录事件
        ticket.LogEvent(
            "priority_changed", 
            $"优先级从 {oldPriority} 变更为 {priority}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    public virtual async Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments)
    {
        // 默认情况下,不允许解决工单
        Console.WriteLine($"无法在 {StateName} 状态下解决工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 默认情况下,不允许关闭工单
        Console.WriteLine($"无法在 {StateName} 状态下关闭工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 默认情况下,不允许重新打开工单
        Console.WriteLine($"无法在 {StateName} 状态下重新打开工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> CancelTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool isAdmin = ticket.UserHasPermission(userId, "cancel_ticket");
        
        if (!isCreator && !isAdmin)
        {
            ticket.LogEvent("permission_denied", "没有取消工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 添加取消原因评论
        await ticket.AddComment($"取消原因: {reason}", userId, false);
        
        // 转换状态为已取消
        await ticket.SetState(new CancelledState(), userId, reason);
        
        return true;
    }
    
    public virtual async Task<bool> EscalateTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "escalate_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有升级工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 升级工单优先级
        TicketPriority newPriority = ticket.Priority == TicketPriority.Critical 
            ? TicketPriority.Critical 
            : (TicketPriority)((int)ticket.Priority + 1);
            
        await SetPriority(ticket, newPriority, userId, $"工单已升级: {reason}");
        
        // 记录升级事件
        ticket.LogEvent(
            "ticket_escalated", 
            $"工单已升级: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        return true;
    }
    
    // 获取允许的下一个状态列表
    protected abstract List<TicketStateEnum> GetAllowedTransitions();
}

// 11. 新建状态
public class NewState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.New;
    public override string StateName => "新建";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 新建工单设置创建时间
        ticket.CreatedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Triaged,
            TicketStateEnum.Assigned,
            TicketStateEnum.Cancelled
        };
    }
    
    // 新建状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result && ticket.CurrentStateEnum == TicketStateEnum.New)
        {
            // 自动转换到已分配状态
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return result;
    }
}

// 12. 分类状态
public class TriagedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Triaged;
    public override string StateName => "已分类";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 分类时设置分类时间
        ticket.TriagedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Assigned,
            TicketStateEnum.Cancelled
        };
    }
    
    // 分类状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result)
        {
            // 自动转换到已分配状态
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return result;
    }
}

// 13. 已分配状态
public class AssignedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Assigned;
    public override string StateName => "已分配";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置分配时间
        ticket.AssignedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Waiting,
            TicketStateEnum.Cancelled
        };
    }
    
    // 已分配状态下的特定行为
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        bool result = await base.UpdateTicket(ticket, updates, userId, comments);
        
        if (result && userId == ticket.AssigneeId)
        {
            // 受理人更新工单,自动转为处理中
            await ticket.SetState(new InProgressState(), userId, "工单处理中");
        }
        
        return result;
    }
}

// 14. 处理中状态
public class InProgressState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.InProgress;
    public override string StateName => "处理中";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置开始处理时间
        if (!ticket.StartProgressTime.HasValue)
        {
            ticket.StartProgressTime = DateTime.Now;
        }
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Waiting,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 处理中状态下的特定行为
    public override async Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "resolve_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有解决工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 设置解决方案
        ticket.Resolution = resolution;
        
        // 记录事件
        ticket.LogEvent(
            "ticket_resolved", 
            $"工单已解决", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        string resolveComment = string.IsNullOrEmpty(comments) 
            ? $"工单已解决: {resolution}" 
            : comments;
            
        await ticket.AddComment(resolveComment, userId, false);
        
        // 转换状态为已解决
        await ticket.SetState(new ResolvedState(), userId, resolveComment);
        
        return true;
    }
}

// 15. 等待中状态
public class WaitingState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Waiting;
    public override string StateName => "等待中";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置等待开始时间
        ticket.WaitingStartTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    public override void ExitState(SupportTicket ticket, string userId)
    {
        // 计算等待时间
        if (ticket.WaitingStartTime.HasValue)
        {
            TimeSpan waitingTime = DateTime.Now - ticket.WaitingStartTime.Value;
            ticket.TotalWaitingTime += waitingTime;
            ticket.WaitingStartTime = null;
        }
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 等待中状态下的特定行为
    public override async Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal)
    {
        await base.AddComment(ticket, content, userId, isInternal);
        
        // 如果是客户回复,自动转为处理中
        if (userId == ticket.CreatedBy)
        {
            await ticket.SetState(new InProgressState(), userId, "客户已回复");
        }
        
        return true;
    }
}

// 16. 已解决状态
public class ResolvedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Resolved;
    public override string StateName => "已解决";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置解决时间
        ticket.ResolvedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Verified,
            TicketStateEnum.Reopened,
            TicketStateEnum.Closed
        };
    }
    
    // 已解决状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    public override async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "close_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有关闭工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_closed", 
            "工单已关闭", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 转换状态为已关闭
        await ticket.SetState(new ClosedState(), userId, "工单已关闭");
        
        return true;
    }
}

// 17. 已验证状态
public class VerifiedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Verified;
    public override string StateName => "已验证";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置验证时间
        ticket.VerifiedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Closed,
            TicketStateEnum.Reopened
        };
    }
    
    // 已验证状态下的特定行为
    public override async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "close_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有关闭工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_closed", 
            "工单已关闭", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 转换状态为已关闭
        await ticket.SetState(new ClosedState(), userId, "工单已关闭");
        
        return true;
    }
    
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
}

// 18. 重新打开状态
public class ReopenedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Reopened;
    public override string StateName => "重新打开";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 重新打开时间
        ticket.ReopenedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Assigned,
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 重新打开状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result)
        {
            // 自动转换到已分配或处理中状态
            if (assigneeId == ticket.PreviousAssigneeId)
            {
                await ticket.SetState(new InProgressState(), userId, "工单已分配给之前的处理人");
            }
            else
            {
                await ticket.SetState(new AssignedState(), userId, "工单已重新分配");
            }
        }
        
        return result;
    }
}

// 19. 已关闭状态
public class ClosedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Closed;
    public override string StateName => "已关闭";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置关闭时间
        ticket.ClosedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
        
        // 计算解决时间
        if (ticket.CreatedTime.HasValue && ticket.ResolvedTime.HasValue)
        {
            ticket.ResolutionTime = ticket.ResolvedTime.Value - ticket.CreatedTime.Value;
        }
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Reopened
        };
    }
    
    // 已关闭状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    // 在已关闭状态下限制一些操作
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        Console.WriteLine("无法更新已关闭的工单");
        return await Task.FromResult(false);
    }
}

// 20. 已取消状态
public class CancelledState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Cancelled;
    public override string StateName => "已取消";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置取消时间
        ticket.CancelledTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Reopened
        };
    }
    
    // 已取消状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    // 在已取消状态下限制一些操作
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        Console.WriteLine("无法更新已取消的工单");
        return await Task.FromResult(false);
    }
    
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        Console.WriteLine("无法分配已取消的工单");
        return await Task.FromResult(false);
    }
}

// 21. 工单状态工厂
public static class TicketStateFactory
{
    public static ITicketState GetState(TicketStateEnum stateEnum)
    {
        return stateEnum switch
        {
            TicketStateEnum.New => new NewState(),
            TicketStateEnum.Triaged => new TriagedState(),
            TicketStateEnum.Assigned => new AssignedState(),
            TicketStateEnum.InProgress => new InProgressState(),
            TicketStateEnum.Waiting => new WaitingState(),
            TicketStateEnum.Resolved => new ResolvedState(),
            TicketStateEnum.Verified => new VerifiedState(),
            TicketStateEnum.Reopened => new ReopenedState(),
            TicketStateEnum.Closed => new ClosedState(),
            TicketStateEnum.Cancelled => new CancelledState(),
            _ => throw new ArgumentException($"未知的工单状态: {stateEnum}")
        };
    }
}

// 22. 工单类
public class SupportTicket
{
    // 基本信息
    public string TicketId { get; }
    public string Subject { get; set; }
    public string Description { get; set; }
    public TicketType Type { get; set; }
    public TicketPriority Priority { get; set; }
    
    // 状态信息
    private ITicketState _currentState;
    public TicketStateEnum CurrentStateEnum => _currentState.StateEnum;
    public string CurrentStateName => _currentState.StateName;
    
    // 参与者信息
    public string CreatedBy { get; set; }
    public string AssigneeId { get; set; }
    public string PreviousAssigneeId { get; set; }
    
    // 时间信息
    public DateTime? CreatedTime { get; set; }
    public DateTime? UpdatedTime { get; set; }
    public DateTime? AssignedTime { get; set; }
    public DateTime? TriagedTime { get; set; }
    public DateTime? StartProgressTime { get; set; }
    public DateTime? WaitingStartTime { get; set; }
    public TimeSpan TotalWaitingTime { get; set; } = TimeSpan.Zero;
    public DateTime? ResolvedTime { get; set; }
    public DateTime? VerifiedTime { get; set; }
    public DateTime? ClosedTime { get; set; }
    public DateTime? ReopenedTime { get; set; }
    public DateTime? CancelledTime { get; set; }
    public TimeSpan? ResolutionTime { get; set; }
    
    // 解决方案
    public string Resolution { get; set; }
    
    // 附加信息
    public List<string> Tags { get; set; } = new List<string>();
    public List<TicketComment> Comments { get; } = new List<TicketComment>();
    public List<TicketAttachment> Attachments { get; } = new List<TicketAttachment>();
    public List<TicketEvent> EventHistory { get; } = new List<TicketEvent>();
    
    // SLA相关
    public DateTime? DueDate { get; set; }
    public DateTime? EscalatedTime { get; set; }
    public int EscalationLevel { get; set; } = 0;
    
    // 依赖关系
    private readonly Dictionary<string, User> _userCache = new Dictionary<string, User>();
    private readonly IUserService _userService;
    private readonly ILogger<SupportTicket> _logger;
    
    public SupportTicket(string ticketId, string subject, string description, 
                        TicketType type, string createdBy, IUserService userService,
                        ILogger<SupportTicket> logger)
    {
        TicketId = ticketId;
        Subject = subject;
        Description = description;
        Type = type;
        Priority = TicketPriority.Normal; // 默认优先级
        CreatedBy = createdBy;
        
        _userService = userService;
        _logger = logger;
        
        // 设置初始状态
        _currentState = new NewState();
        _currentState.EnterState(this, createdBy, "工单创建");
    }
    
    // 状态转换
    public async Task<bool> SetState(ITicketState newState, string userId, string comments)
    {
        if (!_currentState.CanTransitionTo(newState))
        {
            _logger.LogWarning("不允许从 {CurrentState} 转换到 {NewState}", 
                _currentState.StateName, newState.StateName);
            return false;
        }
        
        _currentState.ExitState(this, userId);
        ITicketState oldState = _currentState;
        _currentState = newState;
        _currentState.EnterState(this, userId, comments);
        
        _logger.LogInformation("工单 {TicketId} 状态从 {OldState} 变更为 {NewState}", 
            TicketId, oldState.StateName, newState.StateName);
            
        return true;
    }
    
    // 工单操作方法
    public async Task<bool> AssignTicket(string assigneeId, string userId, string comments)
    {
        return await _currentState.AssignTicket(this, assigneeId, userId, comments);
    }
    
    public async Task<bool> UpdateTicket(Dictionary<string, object> updates, string userId, string comments)
    {
        return await _currentState.UpdateTicket(this, updates, userId, comments);
    }
    
    public async Task<bool> AddComment(string content, string userId, bool isInternal)
    {
        return await _currentState.AddComment(this, content, userId, isInternal);
    }
    
    public void AddCommentInternal(string content, string userId, bool isInternal)
    {
        User user = GetUser(userId);
        
        var comment = new TicketComment(
            content,
            userId,
            user?.Username ?? userId,
            isInternal
        );
        
        Comments.Add(comment);
        UpdatedTime = DateTime.Now;
        
        LogEvent("comment_added", 
            $"添加评论" + (isInternal ? " (内部)" : ""), 
            userId, 
            user?.Username ?? userId);
    }
    
    public async Task<bool> AddAttachment(TicketAttachment attachment, string userId, string comments)
    {
        return await _currentState.AddAttachment(this, attachment, userId, comments);
    }
    
    public async Task<bool> SetPriority(TicketPriority priority, string userId, string comments)
    {
        return await _currentState.SetPriority(this, priority, userId, comments);
    }
    
    public async Task<bool> ResolveTicket(string resolution, string userId, string comments)
    {
        return await _currentState.ResolveTicket(this, resolution, userId, comments);
    }
    
    public async Task<bool> CloseTicket(string userId, string comments)
    {
        return await _currentState.CloseTicket(this, userId, comments);
    }
    
    public async Task<bool> ReopenTicket(string userId, string reason)
    {
        return await _currentState.ReopenTicket(this, userId, reason);
    }
    
    public async Task<bool> CancelTicket(string userId, string reason)
    {
        return await _currentState.CancelTicket(this, userId, reason);
    }
    
    public async Task<bool> EscalateTicket(string userId, string reason)
    {
        return await _currentState.EscalateTicket(this, userId, reason);
    }
    
    // 获取下一个可能的状态
    public List<TicketStateEnum> GetAllowedNextStates(string userId)
    {
        User user = GetUser(userId);
        if (user == null) return new List<TicketStateEnum>();
        
        return _currentState.GetAllowedNextStates(this, user);
    }
    
    // 事件记录
    public void LogEvent(string eventType, string description, string userId, string username)
    {
        var ticketEvent = new TicketEvent(
            TicketId,
            eventType,
            description,
            userId,
            username
        );
        
        EventHistory.Add(ticketEvent);
        _logger.LogInformation("工单 {TicketId} 事件: {EventType} - {Description}", 
            TicketId, eventType, description);
    }
    
    // 缓存用户信息
    public User GetUser(string userId)
    {
        if (_userCache.ContainsKey(userId))
        {
            return _userCache[userId];
        }
        
        var user = _userService.GetUser(userId);
        if (user != null)
        {
            _userCache[userId] = user;
        }
        
        return user;
    }
    
    // 获取用户名
    public string GetUsername(string userId)
    {
        var user = GetUser(userId);
        return user?.Username ?? userId;
    }
    
    // 检查用户权限
    public bool UserHasPermission(string userId, string permission)
    {
        var user = GetUser(userId);
        if (user == null) return false;
        
        return user.HasPermission(permission);
    }
    
    // 显示工单信息
    public void DisplayTicket()
    {
        Console.WriteLine($"=== 工单 {TicketId} ===");
        Console.WriteLine($"主题: {Subject}");
        Console.WriteLine($"类型: {Type}");
        Console.WriteLine($"优先级: {Priority}");
        Console.WriteLine($"状态: {CurrentStateName}");
        Console.WriteLine($"创建者: {GetUsername(CreatedBy)}");
        Console.WriteLine($"受理人: {(AssigneeId != null ? GetUsername(AssigneeId) : "未分配")}");
        
        if (CreatedTime.HasValue)
            Console.WriteLine($"创建时间: {CreatedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (UpdatedTime.HasValue)
            Console.WriteLine($"更新时间: {UpdatedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ResolvedTime.HasValue)
            Console.WriteLine($"解决时间: {ResolvedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ClosedTime.HasValue)
            Console.WriteLine($"关闭时间: {ClosedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ResolutionTime.HasValue)
            Console.WriteLine($"解决用时: {ResolutionTime.Value.TotalHours:F1}小时");
        
        Console.WriteLine("\n描述:");
        Console.WriteLine(Description);
        
        if (!string.IsNullOrEmpty(Resolution))
        {
            Console.WriteLine("\n解决方案:");
            Console.WriteLine(Resolution);
        }
        
        if (Tags.Count > 0)
        {
            Console.WriteLine($"\n标签: {string.Join(", ", Tags)}");
        }
        
        if (Comments.Count > 0)
        {
            Console.WriteLine("\n评论:");
            foreach (var comment in Comments)
            {
                Console.WriteLine(comment);
            }
        }
        
        if (Attachments.Count > 0)
        {
            Console.WriteLine("\n附件:");
            foreach (var attachment in Attachments)
            {
                Console.WriteLine($"- {attachment.FileName} ({attachment.GetFormattedSize()})");
            }
        }
        
        Console.WriteLine("\n工单历史:");
        foreach (var evt in EventHistory.OrderByDescending(e => e.Timestamp).Take(5))
        {
            Console.WriteLine($"- {evt}");
        }
        
        if (EventHistory.Count > 5)
        {
            Console.WriteLine($"...(还有 {EventHistory.Count - 5} 条记录)");
        }
    }
}

// 23. 用户服务接口
public interface IUserService
{
    User GetUser(string userId);
    List<User> GetUsersByRole(UserRole role);
    List<User> GetUsersByDepartment(string department);
}

// 24. 简单用户服务实现
public class SimpleUserService : IUserService
{
    private readonly Dictionary<string, User> _users = new Dictionary<string, User>();
    private readonly ILogger<SimpleUserService> _logger;
    
    public SimpleUserService(ILogger<SimpleUserService> logger)
    {
        _logger = logger;
        
        // 添加一些示例用户
        AddUser(new User("user1", "张三", "zhangsan@example.com", UserRole.Customer));
        AddUser(new User("user2", "李四", "lisi@example.com", UserRole.Agent) { Department = "技术支持" });
        AddUser(new User("user3", "王五", "wangwu@example.com", UserRole.Developer) { Department = "研发" });
        AddUser(new User("user4", "赵六", "zhaoliu@example.com", UserRole.Supervisor) { Department = "技术支持" });
        AddUser(new User("user5", "钱七", "qianqi@example.com", UserRole.Manager) { Department = "产品" });
        AddUser(new User("admin", "管理员", "admin@example.com", UserRole.Administrator));
    }
    
    private void AddUser(User user)
    {
        _users[user.UserId] = user;
    }
    
    public User GetUser(string userId)
    {
        if (_users.TryGetValue(userId, out var user))
        {
            return user;
        }
        
        _logger.LogWarning("找不到用户 {UserId}", userId);
        return null;
    }
    
    public List<User> GetUsersByRole(UserRole role)
    {
        return _users.Values.Where(u => u.Role == role && u.IsActive).ToList();
    }
    
    public List<User> GetUsersByDepartment(string department)
    {
        return _users.Values.Where(u => u.Department == department && u.IsActive).ToList();
    }
}

// 25. 工单服务接口
public interface ITicketService
{
    Task<SupportTicket> CreateTicket(string subject, string description, TicketType type, 
                                  string createdBy, TicketPriority priority = TicketPriority.Normal);
    Task<SupportTicket> GetTicket(string ticketId);
    Task<List<SupportTicket>> GetTicketsByStatus(TicketStateEnum state);
    Task<List<SupportTicket>> GetTicketsByAssignee(string assigneeId);
    Task<List<SupportTicket>> GetTicketsByCreator(string creatorId);
    
    Task<bool> AssignTicket(string ticketId, string assigneeId, string userId, string comments = "");
    Task<bool> UpdateTicket(string ticketId, Dictionary<string, object> updates, string userId, string comments = "");
    Task<bool> AddComment(string ticketId, string content, string userId, bool isInternal = false);
    Task<bool> ResolveTicket(string ticketId, string resolution, string userId, string comments = "");
    Task<bool> CloseTicket(string ticketId, string userId, string comments = "");
    Task<bool> ReopenTicket(string ticketId, string userId, string reason);
}

// 26. 工单服务实现
public class TicketService : ITicketService
{
    private readonly Dictionary<string, SupportTicket> _tickets = new Dictionary<string, SupportTicket>();
    private readonly IUserService _userService;
    private readonly ILogger<TicketService> _logger;
    private readonly ILogger<SupportTicket> _ticketLogger;
    private int _nextTicketNumber = 1;
    
    public TicketService(IUserService userService, ILogger<TicketService> logger, ILogger<SupportTicket> ticketLogger)
    {
        _userService = userService;
        _logger = logger;
        _ticketLogger = ticketLogger;
    }
    
    public async Task<SupportTicket> CreateTicket(string subject, string description, TicketType type, 
                                              string createdBy, TicketPriority priority = TicketPriority.Normal)
    {
        // 生成工单ID
        string ticketId = $"TICKET-{_nextTicketNumber++:D6}";
        
        // 创建工单
        var ticket = new SupportTicket(
            ticketId,
            subject,
            description,
            type,
            createdBy,
            _userService,
            _ticketLogger
        );
        
        // 设置优先级
        await ticket.SetPriority(priority, createdBy, "初始优先级设置");
        
        // 存储工单
        _tickets[ticketId] = ticket;
        
        _logger.LogInformation("创建工单 {TicketId}: {Subject}", ticketId, subject);
        
        return ticket;
    }
    
    public Task<SupportTicket> GetTicket(string ticketId)
    {
        if (_tickets.TryGetValue(ticketId, out var ticket))
        {
            return Task.FromResult(ticket);
        }
        
        _logger.LogWarning("找不到工单 {TicketId}", ticketId);
        return Task.FromResult<SupportTicket>(null);
    }
    
    public Task<List<SupportTicket>> GetTicketsByStatus(TicketStateEnum state)
    {
        var tickets = _tickets.Values
            .Where(t => t.CurrentStateEnum == state)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public Task<List<SupportTicket>> GetTicketsByAssignee(string assigneeId)
    {
        var tickets = _tickets.Values
            .Where(t => t.AssigneeId == assigneeId)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public Task<List<SupportTicket>> GetTicketsByCreator(string creatorId)
    {
        var tickets = _tickets.Values
            .Where(t => t.CreatedBy == creatorId)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public async Task<bool> AssignTicket(string ticketId, string assigneeId, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.AssignTicket(assigneeId, userId, comments);
    }
    
    public async Task<bool> UpdateTicket(string ticketId, Dictionary<string, object> updates, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.UpdateTicket(updates, userId, comments);
    }
    
    public async Task<bool> AddComment(string ticketId, string content, string userId, bool isInternal = false)
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.AddComment(content, userId, isInternal);
    }
    
    public async Task<bool> ResolveTicket(string ticketId, string resolution, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.ResolveTicket(resolution, userId, comments);
    }
    
    public async Task<bool> CloseTicket(string ticketId, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.CloseTicket(userId, comments);
    }
    
    public async Task<bool> ReopenTicket(string ticketId, string userId, string reason)
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.ReopenTicket(userId, reason);
    }
}

// 27. 工单流程演示
public class TicketWorkflowDemo
{
    private readonly ITicketService _ticketService;
    private readonly IUserService _userService;
    private readonly ILogger<TicketWorkflowDemo> _logger;
    
    public TicketWorkflowDemo(ITicketService ticketService, IUserService userService, ILogger<TicketWorkflowDemo> logger)
    {
        _ticketService = ticketService;
        _userService = userService;
        _logger = logger;
    }
    
    public async Task RunDemoAsync()
    {
        Console.WriteLine("===== 工单处理流程演示 =====\n");
        
        // 1. 客户创建工单
        _logger.LogInformation("1. 客户创建工单");
        var ticket = await _ticketService.CreateTicket(
            "登录功能异常",
            "我无法登录系统,提示'用户名或密码错误',但我确认输入是正确的。",
            TicketType.Bug,
            "user1",
            TicketPriority.High
        );
        
        Console.WriteLine($"工单已创建: {ticket.TicketId}");
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 2. 添加附件
        _logger.LogInformation("2. 客户添加附件");
        await ticket.AddAttachment(
            new TicketAttachment("error_screenshot.png", "image/png", 258000, "user1"),
            "user1", 
            "添加错误截图"
        );
        
        // 3. 支持人员分配工单
        _logger.LogInformation("3. 支持人员分配工单");
        await _ticketService.AssignTicket(
            ticket.TicketId,
            "user2",
            "user4",
            "请尽快处理这个登录问题"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 4. 支持人员添加内部评论
        _logger.LogInformation("4. 支持人员添加内部评论");
        await _ticketService.AddComment(
            ticket.TicketId,
            "经检查可能是用户账号被锁定,需要重置密码。",
            "user2",
            true // 内部评论
        );
        
        // 5. 支持人员回复客户
        _logger.LogInformation("5. 支持人员回复客户");
        await _ticketService.AddComment(
            ticket.TicketId,
            "您好,经检查您的账号可能被临时锁定。请问您最近是否多次输入错误密码?",
            "user2"
        );
        
        // 6. 客户回复
        _logger.LogInformation("6. 客户回复");
        await _ticketService.AddComment(
            ticket.TicketId,
            "是的,我尝试了几次不同的密码,因为我不太记得了。",
            "user1"
        );
        
        // 7. 工单转给开发人员
        _logger.LogInformation("7. 工单转给开发人员");
        await _ticketService.AssignTicket(
            ticket.TicketId,
            "user3",
            "user2",
            "这需要重置用户密码,请协助处理"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 8. 开发人员处理问题
        _logger.LogInformation("8. 开发人员处理问题");
        await _ticketService.AddComment(
            ticket.TicketId,
            "已重置用户密码,并发送临时密码到用户邮箱。同时,我们应该改进错误提示,明确告知用户账号被锁定的情况。",
            "user3"
        );
        
        // 9. 开发人员解决工单
        _logger.LogInformation("9. 开发人员解决工单");
        await _ticketService.ResolveTicket(
            ticket.TicketId,
            "已重置用户密码并发送临时密码到邮箱。同时计划改进错误提示。",
            "user3",
            "问题已解决,请用户确认"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 10. 客户验证并关闭工单
        _logger.LogInformation("10. 客户验证并关闭工单");
        await _ticketService.AddComment(
            ticket.TicketId,
            "我收到了临时密码邮件,已成功登录系统。谢谢!",
            "user1"
        );
        
        await _ticketService.CloseTicket(
            ticket.TicketId,
            "user1",
            "问题已解决,谢谢支持"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 11. 创建第二个工单 - 演示重新打开流程
        _logger.LogInformation("11. 创建第二个工单");
        var ticket2 = await _ticketService.CreateTicket(
            "系统响应缓慢",
            "过去几天系统响应越来越慢,特别是在生成报表时几乎无法使用。",
            TicketType.Performance,
            "user1",
            TicketPriority.Normal
        );
        
        // 12. 分配并解决第二个工单
        _logger.LogInformation("12. 分配并解决第二个工单");
        await _ticketService.AssignTicket(ticket2.TicketId, "user2", "user4", "请检查性能问题");
        await _ticketService.AddComment(ticket2.TicketId, "正在检查性能问题...", "user2");
        await _ticketService.ResolveTicket(
            ticket2.TicketId,
            "已优化数据库查询,清理了临时文件,系统性能应该已经恢复。",
            "user2",
            "性能问题已解决"
        );
        
        await _ticketService.CloseTicket(ticket2.TicketId, "user1", "谢谢,问题已解决");
        
        // 13. 客户重新打开工单
        _logger.LogInformation("13. 客户重新打开工单");
        await _ticketService.ReopenTicket(
            ticket2.TicketId,
            "user1",
            "问题仍然存在,生成大型报表时仍然非常慢"
        );
        
        ticket2.DisplayTicket();
        Console.WriteLine();
        
        // 14. 升级工单优先级
        _logger.LogInformation("14. 升级工单优先级");
        await ticket2.EscalateTicket(
            "user4", // 主管
            "客户反馈问题持续存在,且影响业务运营"
        );
        
        // 15. 重新分配给开发人员
        _logger.LogInformation("15. 重新分配给开发人员");
        await _ticketService.AssignTicket(
            ticket2.TicketId,
            "user3",
            "user4",
            "这个性能问题需要更深入的分析,请优先处理"
        );
        
        ticket2.DisplayTicket();
        Console.WriteLine();
        
        Console.WriteLine("===== 工单处理流程演示完成 =====");
    }
}

// 28. 客户端代码
public class Program
{
    public static async Task Main()
    {
        // 设置依赖注入
        var services = new ServiceCollection();
        
        // 添加日志
        services.AddLogging(builder =>
        {
            builder.AddConsole();
            builder.SetMinimumLevel(LogLevel.Information);
        });
        
        // 注册服务
        services.AddSingleton<IUserService, SimpleUserService>();
        services.AddSingleton<ITicketService, TicketService>();
        services.AddTransient<TicketWorkflowDemo>();
        
        var serviceProvider = services.BuildServiceProvider();
        
        // 运行演示
        var demo = serviceProvider.GetRequiredService<TicketWorkflowDemo>();
        await demo.RunDemoAsync();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

# 20. 策略模式

原理:
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,算法的变化不会影响使用算法的客户。

思路:

  1. 定义策略接口,声明算法的方法
  2. 实现具体策略类,封装不同的算法
  3. 创建上下文类,维护对策略对象的引用
  4. 客户端通过上下文类使用策略

前辈经验:

  • 当有多种相关算法可供选择时,使用策略模式
  • 策略模式可以避免使用多重条件语句来选择不同的行为
  • 策略可以在运行时动态切换,提供了更高的灵活性
  • 选择策略的逻辑可以放在客户端或上下文类中
  • 经常与工厂模式结合使用,以便动态选择合适的策略

业务场景:
支付系统,需要支持多种支付方式(信用卡、支付宝、微信支付等),每种支付方式有不同的处理逻辑。

简单实现:

// 支付上下文信息
public class PaymentContext
{
    public decimal Amount { get; set; }
    public string Currency { get; set; }
    public string OrderId { get; set; }
    public Dictionary<string, string> AdditionalInfo { get; set; } = new Dictionary<string, string>();
}

// 支付结果
public class PaymentResult
{
    public bool Success { get; set; }
    public string TransactionId { get; set; }
    public string Message { get; set; }
    public DateTime Timestamp { get; set; } = DateTime.Now;
}

// 支付策略接口
public interface IPaymentStrategy
{
    string Name { get; }
    bool SupportsRefund { get; }
    Task<PaymentResult> ProcessPayment(PaymentContext context);
    Task<PaymentResult> RefundPayment(string transactionId, decimal amount);
}

// 信用卡支付策略
public class CreditCardPaymentStrategy : IPaymentStrategy
{
    public string Name => "信用卡支付";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用信用卡支付网关API
        Console.WriteLine($"使用信用卡支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"信用卡号: {context.AdditionalInfo["CardNumber"]}");
        
        // 模拟网络延迟
        await Task.Delay(1000);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"CC-{Guid.NewGuid():N}",
            Message = "信用卡支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款信用卡支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(1000);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "信用卡退款成功"
        };
    }
}

// 支付宝支付策略
public class AlipayPaymentStrategy : IPaymentStrategy
{
    public string Name => "支付宝";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用支付宝API
        Console.WriteLine($"使用支付宝支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"支付宝账号: {context.AdditionalInfo["AlipayAccount"]}");
        
        // 模拟网络延迟
        await Task.Delay(800);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"ALI-{Guid.NewGuid():N}",
            Message = "支付宝支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款支付宝支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(800);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "支付宝退款成功"
        };
    }
}

// 微信支付策略
public class WeChatPayStrategy : IPaymentStrategy
{
    public string Name => "微信支付";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用微信支付API
        Console.WriteLine($"使用微信支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"微信OpenID: {context.AdditionalInfo["WeChatOpenId"]}");
        
        // 模拟网络延迟
        await Task.Delay(1200);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"WX-{Guid.NewGuid():N}",
            Message = "微信支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款微信支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(1200);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "微信支付退款成功"
        };
    }
}

// 银行转账支付策略
public class BankTransferPaymentStrategy : IPaymentStrategy
{
    public string Name => "银行转账";
    public bool SupportsRefund => false;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        Console.WriteLine($"使用银行转账支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"银行账号: {context.AdditionalInfo["BankAccount"]}");
        Console.WriteLine($"银行名称: {context.AdditionalInfo["BankName"]}");
        
        // 模拟网络延迟
        await Task.Delay(1500);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"BT-{Guid.NewGuid():N}",
            Message = "银行转账已处理,等待确认"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"银行转账不支持自动退款,交易ID: {transactionId}");
        
        return new PaymentResult
        {
            Success = false,
            Message = "银行转账不支持自动退款,请手动处理"
        };
    }
}

// 支付处理器 - 上下文
public class PaymentProcessor
{
    private IPaymentStrategy _strategy;
    
    public PaymentProcessor(IPaymentStrategy strategy)
    {
        _strategy = strategy;
    }
    
    public void SetStrategy(IPaymentStrategy strategy)
    {
        _strategy = strategy;
    }
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 验证输入
        if (context.Amount <= 0)
        {
            return new PaymentResult
            {
                Success = false,
                Message = "支付金额必须大于0"
            };
        }
        
        if (string.IsNullOrEmpty(context.OrderId))
        {
            return new PaymentResult
            {
                Success = false,
                Message = "订单ID不能为空"
            };
        }
        
        Console.WriteLine($"使用 {_strategy.Name} 处理订单 {context.OrderId} 的支付");
        
        // 调用选定的支付策略
        return await _strategy.ProcessPayment(context);
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        if (!_strategy.SupportsRefund)
        {
            return new PaymentResult
            {
                Success = false,
                Message = $"{_strategy.Name} 不支持自动退款"
            };
        }
        
        Console.WriteLine($"使用 {_strategy.Name} 处理退款");
        
        return await _strategy.RefundPayment(transactionId, amount);
    }
}

// 客户端代码
public class Client
{
    public static async Task Main()
    {
        // 创建各种支付策略
        IPaymentStrategy creditCardStrategy = new CreditCardPaymentStrategy();
        IPaymentStrategy alipayStrategy = new AlipayPaymentStrategy();
        IPaymentStrategy weChatPayStrategy = new WeChatPayStrategy();
        IPaymentStrategy bankTransferStrategy = new BankTransferPaymentStrategy();
        
        // 创建支付处理器并设置初始策略
        PaymentProcessor processor = new PaymentProcessor(creditCardStrategy);
        
        // 信用卡支付
        var ccContext = new PaymentContext
        {
            Amount = 100.50m,
            Currency = "CNY",
            OrderId = "ORD-12345",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "CardNumber", "4111********1111" },
                { "ExpiryDate", "12/25" },
                { "CVV", "123" }
            }
        };
        
        var ccResult = await processor.ProcessPayment(ccContext);
        Console.WriteLine($"支付结果: {(ccResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {ccResult.TransactionId}");
        Console.WriteLine($"消息: {ccResult.Message}");
        Console.WriteLine();
        
        // 支付宝支付
        processor.SetStrategy(alipayStrategy);
        
        var alipayContext = new PaymentContext
        {
            Amount = 200.75m,
            Currency = "CNY",
            OrderId = "ORD-23456",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "AlipayAccount", "user@example.com" }
            }
        };
        
        var alipayResult = await processor.ProcessPayment(alipayContext);
        Console.WriteLine($"支付结果: {(alipayResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {alipayResult.TransactionId}");
        Console.WriteLine($"消息: {alipayResult.Message}");
        Console.WriteLine();
        
        // 微信支付
        processor.SetStrategy(weChatPayStrategy);
        
        var weChatContext = new PaymentContext
        {
            Amount = 50.25m,
            Currency = "CNY",
            OrderId = "ORD-34567",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "WeChatOpenId", "wx_12345678" }
            }
        };
        
        var weChatResult = await processor.ProcessPayment(weChatContext);
        Console.WriteLine($"支付结果: {(weChatResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {weChatResult.TransactionId}");
        Console.WriteLine($"消息: {weChatResult.Message}");
        Console.WriteLine();
        
        // 测试退款功能
        var refundResult = await processor.RefundPayment(weChatResult.TransactionId, 20.00m);
        Console.WriteLine($"退款结果: {(refundResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"退款交易ID: {refundResult.TransactionId}");
        Console.WriteLine($"退款消息: {refundResult.Message}");
        Console.WriteLine();
        
        // 银行转账支付
        processor.SetStrategy(bankTransferStrategy);
        
        var bankContext = new PaymentContext
        {
            Amount = 1000.00m,
            Currency = "CNY",
            OrderId = "ORD-45678",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "BankAccount", "1234567890" },
                { "BankName", "中国银行" },
                { "AccountName", "张三" }
            }
        };
        
        var bankResult = await processor.ProcessPayment(bankContext);
        Console.WriteLine($"支付结果: {(bankResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {bankResult.TransactionId}");
        Console.WriteLine($"消息: {bankResult.Message}");
        Console.WriteLine();
        
        // 测试银行转账退款(应该不支持)
        var bankRefundResult = await processor.RefundPayment(bankResult.TransactionId, 500.00m);
        Console.WriteLine($"退款结果: {(bankRefundResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"退款消息: {bankRefundResult.Message}");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

# 19. 状态模式

原理:
状态模式允许对象在内部状态改变时改变它的行为,使对象看起来好像修改了它的类。状态模式将状态相关的行为封装在独立的状态类中,并将行为委托给当前状态对象,从而消除了大量的条件判断语句。

思路:

  1. 定义状态接口,声明与特定状态相关的方法
  2. 实现具体状态类,处理上下文对象的状态转换
  3. 定义上下文类,维护当前状态对象的引用
  4. 上下文将状态相关的请求委托给当前状态对象处理

前辈经验:

  • 当对象的行为取决于其状态,且必须在运行时根据状态改变行为时,使用状态模式
  • 状态模式将状态相关的行为分散到各个状态类中,消除了复杂的条件判断语句
  • 状态之间的转换逻辑可以放在状态类中或上下文类中,各有优缺点
  • 注意避免状态类之间的循环依赖,可能导致难以维护的代码
  • 在具体状态类中重用共同的功能可以使用继承或组合

业务场景:
订单处理系统,订单根据其当前状态(创建、支付、发货、完成、取消)有不同的处理方式。

简单实现:

// 订单状态接口
public interface IOrderState
{
    void ProcessOrder(Order order);
    void CancelOrder(Order order);
    void PayOrder(Order order);
    void ShipOrder(Order order);
    void DeliverOrder(Order order);
    string GetStateName();
}

// 已创建状态
public class CreatedState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单正在处理中...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("订单已取消。");
        order.SetState(new CanceledState());
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("订单已支付。");
        order.SetState(new PaidState());
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:未支付的订单不能发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:未发货的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已创建";
    }
}

// 已支付状态
public class PaidState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已支付,准备发货...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("已支付订单已取消,将安排退款。");
        order.SetState(new CanceledState());
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("订单已发货。");
        order.SetState(new ShippedState());
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:未发货的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已支付";
    }
}

// 已发货状态
public class ShippedState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已发货,正在运输中...");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:已发货的订单不能取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:订单已发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("订单已交付。");
        order.SetState(new DeliveredState());
    }
    
    public string GetStateName()
    {
        return "已发货";
    }
}

// 已交付状态
public class DeliveredState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("订单已完成。");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:已交付的订单不能取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:订单已支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:订单已发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:订单已交付。");
    }
    
    public string GetStateName()
    {
        return "已交付";
    }
}

// 已取消状态
public class CanceledState : IOrderState
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能处理。");
    }
    
    public void CancelOrder(Order order)
    {
        Console.WriteLine("错误:订单已取消。");
    }
    
    public void PayOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能支付。");
    }
    
    public void ShipOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能发货。");
    }
    
    public void DeliverOrder(Order order)
    {
        Console.WriteLine("错误:已取消的订单不能交付。");
    }
    
    public string GetStateName()
    {
        return "已取消";
    }
}

// 订单类(上下文)
public class Order
{
    private IOrderState _state;
    public string OrderNumber { get; }
    public DateTime CreatedDate { get; }
    
    public Order(string orderNumber)
    {
        OrderNumber = orderNumber;
        CreatedDate = DateTime.Now;
        _state = new CreatedState(); // 初始状态为已创建
    }
    
    public void SetState(IOrderState state)
    {
        _state = state;
    }
    
    public void ProcessOrder()
    {
        _state.ProcessOrder(this);
    }
    
    public void CancelOrder()
    {
        _state.CancelOrder(this);
    }
    
    public void PayOrder()
    {
        _state.PayOrder(this);
    }
    
    public void ShipOrder()
    {
        _state.ShipOrder(this);
    }
    
    public void DeliverOrder()
    {
        _state.DeliverOrder(this);
    }
    
    public string GetOrderStatus()
    {
        return _state.GetStateName();
    }
    
    public void DisplayOrder()
    {
        Console.WriteLine($"订单号: {OrderNumber}");
        Console.WriteLine($"创建时间: {CreatedDate}");
        Console.WriteLine($"当前状态: {GetOrderStatus()}");
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建新订单
        Order order = new Order("ORD-2023-001");
        
        // 显示订单状态
        order.DisplayOrder();
        Console.WriteLine();
        
        // 处理订单
        Console.WriteLine("操作: 处理订单");
        order.ProcessOrder();
        Console.WriteLine();
        
        // 支付订单
        Console.WriteLine("操作: 支付订单");
        order.PayOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 再次支付
        Console.WriteLine("操作: 再次支付订单");
        order.PayOrder();
        Console.WriteLine();
        
        // 发货订单
        Console.WriteLine("操作: 发货订单");
        order.ShipOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 尝试取消
        Console.WriteLine("操作: 取消订单");
        order.CancelOrder();
        Console.WriteLine();
        
        // 交付订单
        Console.WriteLine("操作: 交付订单");
        order.DeliverOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 创建另一个订单并取消
        Order order2 = new Order("ORD-2023-002");
        Console.WriteLine($"创建新订单: {order2.OrderNumber}");
        order2.DisplayOrder();
        Console.WriteLine();
        
        Console.WriteLine("操作: 取消订单");
        order2.CancelOrder();
        order2.DisplayOrder();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

复杂实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// 1. 订单状态接口
public interface IOrderState
{
    bool CanTransitionTo(IOrderState nextState);
    void EnterState(Order order);
    void ExitState(Order order);
    
    Task<bool> ProcessOrder(Order order);
    Task<bool> PayOrder(Order order, PaymentInfo paymentInfo);
    Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo);
    Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo);
    Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo);
    Task<bool> RefundOrder(Order order, RefundInfo refundInfo);
    Task<bool> CancelOrder(Order order, string reason);
    
    Task<bool> AddItem(Order order, OrderItem item);
    Task<bool> RemoveItem(Order order, string itemId);
    Task<bool> UpdateQuantity(Order order, string itemId, int quantity);
    
    Task<bool> ApplyDiscount(Order order, Discount discount);
    Task<bool> UpdateShippingAddress(Order order, Address address);
    Task<bool> UpdateBillingAddress(Order order, Address address);
    
    string GetStateName();
    OrderStateEnum GetStateEnum();
    List<OrderStateTransition> GetAllowedTransitions();
}

// 2. 订单状态枚举
public enum OrderStateEnum
{
    Created,
    Processing,
    AwaitingPayment,
    PaymentFailed,
    Paid,
    ReadyForShipment,
    Shipped,
    Delivered,
    Returned,
    PartiallyReturned,
    Refunded,
    PartiallyRefunded,
    Canceled,
    Completed
}

// 3. 状态转换类
public class OrderStateTransition
{
    public OrderStateEnum FromState { get; }
    public OrderStateEnum ToState { get; }
    public string TransitionName { get; }
    public string Description { get; }
    
    public OrderStateTransition(OrderStateEnum fromState, OrderStateEnum toState, string transitionName, string description)
    {
        FromState = fromState;
        ToState = toState;
        TransitionName = transitionName;
        Description = description;
    }
}

// 4. 支付信息类
public class PaymentInfo
{
    public string PaymentId { get; set; }
    public decimal Amount { get; set; }
    public string PaymentMethod { get; set; }
    public DateTime PaymentDate { get; set; }
    public string TransactionId { get; set; }
    public PaymentStatus Status { get; set; }
    public Dictionary<string, string> AdditionalInfo { get; set; } = new Dictionary<string, string>();
    
    public enum PaymentStatus
    {
        Pending,
        Successful,
        Failed,
        Refunded,
        PartiallyRefunded
    }
}

// 5. 配送信息类
public class ShipmentInfo
{
    public string ShipmentId { get; set; }
    public string Carrier { get; set; }
    public string TrackingNumber { get; set; }
    public DateTime ShipmentDate { get; set; }
    public decimal ShippingCost { get; set; }
    public List<OrderItem> ShippedItems { get; set; } = new List<OrderItem>();
    public ShipmentStatus Status { get; set; }
    
    public enum ShipmentStatus
    {
        Processing,
        Shipped,
        InTransit,
        Delivered,
        Failed,
        Returned
    }
}

// 6. 交付信息类
public class DeliveryInfo
{
    public string DeliveryId { get; set; }
    public DateTime DeliveryDate { get; set; }
    public string ReceivedBy { get; set; }
    public string DeliveryNotes { get; set; }
    public DeliveryStatus Status { get; set; }
    public string ProofOfDeliveryUrl { get; set; }
    
    public enum DeliveryStatus
    {
        Pending,
        InTransit,
        AttemptedDelivery,
        Delivered,
        Failed
    }
}

// 7. 退货信息类
public class ReturnInfo
{
    public string ReturnId { get; set; }
    public string Reason { get; set; }
    public DateTime ReturnRequestDate { get; set; }
    public DateTime? ReturnReceivedDate { get; set; }
    public List<OrderItem> ReturnedItems { get; set; } = new List<OrderItem>();
    public ReturnStatus Status { get; set; }
    public string ReturnShippingLabel { get; set; }
    
    public enum ReturnStatus
    {
        Requested,
        Approved,
        Rejected,
        InTransit,
        Received,
        Inspected,
        Completed
    }
}

// 8. 退款信息类
public class RefundInfo
{
    public string RefundId { get; set; }
    public decimal Amount { get; set; }
    public string Reason { get; set; }
    public DateTime RefundRequestDate { get; set; }
    public DateTime? RefundProcessedDate { get; set; }
    public RefundStatus Status { get; set; }
    public string RefundMethod { get; set; }
    public string TransactionId { get; set; }
    
    public enum RefundStatus
    {
        Requested,
        Approved,
        Rejected,
        Processing,
        Completed,
        Failed
    }
}

// 9. 地址类
public class Address
{
    public string FullName { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
    public string PhoneNumber { get; set; }
    
    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(FullName);
        sb.AppendLine(AddressLine1);
        
        if (!string.IsNullOrWhiteSpace(AddressLine2))
            sb.AppendLine(AddressLine2);
            
        sb.AppendLine($"{City}, {State} {ZipCode}");
        sb.AppendLine(Country);
        sb.AppendLine(PhoneNumber);
        
        return sb.ToString();
    }
}

// 10. 折扣类
public class Discount
{
    public string DiscountId { get; set; }
    public string Code { get; set; }
    public string Description { get; set; }
    public DiscountType Type { get; set; }
    public decimal Value { get; set; }
    public DateTime? ExpirationDate { get; set; }
    public int? MaxUsage { get; set; }
    public int CurrentUsage { get; set; }
    
    public enum DiscountType
    {
        Percentage,
        FixedAmount,
        FreeShipping,
        BuyXGetY
    }
    
    public decimal CalculateDiscount(decimal originalPrice)
    {
        return Type switch
        {
            DiscountType.Percentage => originalPrice * (Value / 100),
            DiscountType.FixedAmount => Math.Min(Value, originalPrice),
            DiscountType.FreeShipping => 0, // 处理在其他地方
            DiscountType.BuyXGetY => 0, // 处理在其他地方
            _ => 0
        };
    }
    
    public bool IsValid()
    {
        if (ExpirationDate.HasValue && ExpirationDate.Value < DateTime.Now)
            return false;
            
        if (MaxUsage.HasValue && CurrentUsage >= MaxUsage.Value)
            return false;
            
        return true;
    }
}

// 11. 订单项类
public class OrderItem
{
    public string ItemId { get; set; }
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal TotalPrice => UnitPrice * Quantity;
    public List<Discount> AppliedDiscounts { get; set; } = new List<Discount>();
    public decimal DiscountAmount => AppliedDiscounts.Sum(d => d.CalculateDiscount(TotalPrice));
    public decimal FinalPrice => TotalPrice - DiscountAmount;
    
    public OrderItem Clone()
    {
        return new OrderItem
        {
            ItemId = ItemId,
            ProductId = ProductId,
            ProductName = ProductName,
            Quantity = Quantity,
            UnitPrice = UnitPrice,
            AppliedDiscounts = new List<Discount>(AppliedDiscounts)
        };
    }
}

// 12. 订单事件参数
public class OrderStateChangedEventArgs : EventArgs
{
    public OrderStateEnum OldState { get; }
    public OrderStateEnum NewState { get; }
    public string OrderNumber { get; }
    public DateTime Timestamp { get; }
    
    public OrderStateChangedEventArgs(OrderStateEnum oldState, OrderStateEnum newState, string orderNumber)
    {
        OldState = oldState;
        NewState = newState;
        OrderNumber = orderNumber;
        Timestamp = DateTime.Now;
    }
}

// 13. 订单事件日志
public class OrderEventLog
{
    public Guid LogId { get; } = Guid.NewGuid();
    public string OrderNumber { get; set; }
    public DateTime Timestamp { get; set; }
    public string EventType { get; set; }
    public string Description { get; set; }
    public string PerformedBy { get; set; }
    public Dictionary<string, string> AdditionalData { get; set; } = new Dictionary<string, string>();
    
    public override string ToString()
    {
        return $"[{Timestamp:yyyy-MM-dd HH:mm:ss}] {EventType}: {Description}";
    }
}

// 14. 订单类(上下文)
public class Order
{
    // 订单基本信息
    public string OrderNumber { get; }
    public DateTime CreatedDate { get; }
    public string CustomerId { get; set; }
    public string CustomerName { get; set; }
    
    // 订单状态
    private IOrderState _currentState;
    public OrderStateEnum CurrentStateEnum => _currentState.GetStateEnum();
    public string CurrentStateName => _currentState.GetStateName();
    
    // 订单项
    public List<OrderItem> Items { get; } = new List<OrderItem>();
    
    // 地址信息
    public Address ShippingAddress { get; set; }
    public Address BillingAddress { get; set; }
    
    // 付款信息
    public List<PaymentInfo> Payments { get; } = new List<PaymentInfo>();
    
    // 配送信息
    public List<ShipmentInfo> Shipments { get; } = new List<ShipmentInfo>();
    
    // 交付信息
    public List<DeliveryInfo> Deliveries { get; } = new List<DeliveryInfo>();
    
    // 退货信息
    public List<ReturnInfo> Returns { get; } = new List<ReturnInfo>();
    
    // 退款信息
    public List<RefundInfo> Refunds { get; } = new List<RefundInfo>();
    
    // 折扣信息
    public List<Discount> AppliedDiscounts { get; } = new List<Discount>();
    
    // 订单取消原因
    public string CancellationReason { get; set; }
    
    // 历史状态
    public List<OrderEventLog> EventHistory { get; } = new List<OrderEventLog>();
    
    // 事件
    public event EventHandler<OrderStateChangedEventArgs> StateChanged;
    
    // 计算订单总金额
    public decimal SubTotal => Items.Sum(item => item.TotalPrice);
    public decimal DiscountAmount => Items.Sum(item => item.DiscountAmount) + AppliedDiscounts.Sum(d => d.CalculateDiscount(SubTotal));
    public decimal ShippingCost => Shipments.Sum(s => s.ShippingCost);
    public decimal TaxAmount { get; set; }
    public decimal GrandTotal => SubTotal - DiscountAmount + ShippingCost + TaxAmount;
    public decimal PaidAmount => Payments.Where(p => p.Status == PaymentInfo.PaymentStatus.Successful).Sum(p => p.Amount);
    public decimal RefundedAmount => Refunds.Where(r => r.Status == RefundInfo.RefundStatus.Completed).Sum(r => r.Amount);
    public decimal BalanceDue => GrandTotal - PaidAmount + RefundedAmount;
    
    // 构造函数
    public Order(string orderNumber, string customerId, string customerName)
    {
        OrderNumber = orderNumber;
        CreatedDate = DateTime.Now;
        CustomerId = customerId;
        CustomerName = customerName;
        
        // 设置初始状态
        _currentState = new CreatedState();
        
        // 记录创建事件
        LogEvent("OrderCreated", $"订单 {OrderNumber} 已创建", "System");
    }
    
    // 设置状态
    public async Task<bool> SetState(IOrderState newState)
    {
        if (!_currentState.CanTransitionTo(newState))
        {
            LogEvent("InvalidStateTransition", 
                $"无效的状态转换: 从 {_currentState.GetStateName()} 到 {newState.GetStateName()}", 
                "System");
            return false;
        }
        
        var oldState = _currentState;
        
        // 退出当前状态
        await Task.Run(() => oldState.ExitState(this));
        
        // 切换状态
        _currentState = newState;
        
        // 进入新状态
        await Task.Run(() => _currentState.EnterState(this));
        
        // 记录状态变更事件
        LogEvent("StateChanged", 
            $"订单状态从 {oldState.GetStateName()} 变更为 {newState.GetStateName()}", 
            "System");
            
        // 触发状态变更事件
        OnStateChanged(new OrderStateChangedEventArgs(
            oldState.GetStateEnum(),
            newState.GetStateEnum(),
            OrderNumber));
            
        return true;
    }
    
    // 记录事件
    public void LogEvent(string eventType, string description, string performedBy, Dictionary<string, string> additionalData = null)
    {
        var eventLog = new OrderEventLog
        {
            OrderNumber = OrderNumber,
            Timestamp = DateTime.Now,
            EventType = eventType,
            Description = description,
            PerformedBy = performedBy
        };
        
        if (additionalData != null)
        {
            foreach (var kvp in additionalData)
            {
                eventLog.AdditionalData[kvp.Key] = kvp.Value;
            }
        }
        
        EventHistory.Add(eventLog);
    }
    
    // 处理订单
    public async Task<bool> ProcessOrder()
    {
        return await _currentState.ProcessOrder(this);
    }
    
    // 支付订单
    public async Task<bool> PayOrder(PaymentInfo paymentInfo)
    {
        return await _currentState.PayOrder(this, paymentInfo);
    }
    
    // 发货订单
    public async Task<bool> ShipOrder(ShipmentInfo shipmentInfo)
    {
        return await _currentState.ShipOrder(this, shipmentInfo);
    }
    
    // 交付订单
    public async Task<bool> DeliverOrder(DeliveryInfo deliveryInfo)
    {
        return await _currentState.DeliverOrder(this, deliveryInfo);
    }
    
    // 退货订单
    public async Task<bool> ReturnOrder(ReturnInfo returnInfo)
    {
        return await _currentState.ReturnOrder(this, returnInfo);
    }
    
    // 退款订单
    public async Task<bool> RefundOrder(RefundInfo refundInfo)
    {
        return await _currentState.RefundOrder(this, refundInfo);
    }
    
    // 取消订单
    public async Task<bool> CancelOrder(string reason)
    {
        return await _currentState.CancelOrder(this, reason);
    }
    
    // 添加商品
    public async Task<bool> AddItem(OrderItem item)
    {
        return await _currentState.AddItem(this, item);
    }
    
    // 移除商品
    public async Task<bool> RemoveItem(string itemId)
    {
        return await _currentState.RemoveItem(this, itemId);
    }
    
    // 更新数量
    public async Task<bool> UpdateQuantity(string itemId, int quantity)
    {
        return await _currentState.UpdateQuantity(this, itemId, quantity);
    }
    
    // 应用折扣
    public async Task<bool> ApplyDiscount(Discount discount)
    {
        return await _currentState.ApplyDiscount(this, discount);
    }
    
    // 更新配送地址
    public async Task<bool> UpdateShippingAddress(Address address)
    {
        return await _currentState.UpdateShippingAddress(this, address);
    }
    
    // 更新账单地址
    public async Task<bool> UpdateBillingAddress(Address address)
    {
        return await _currentState.UpdateBillingAddress(this, address);
    }
    
    // 获取允许的状态转换
    public List<OrderStateTransition> GetAllowedTransitions()
    {
        return _currentState.GetAllowedTransitions();
    }
    
    // 状态变更事件触发方法
    protected virtual void OnStateChanged(OrderStateChangedEventArgs e)
    {
        StateChanged?.Invoke(this, e);
    }
    
    // 显示订单信息
    public void DisplayOrder()
    {
        Console.WriteLine($"=== 订单信息 ===");
        Console.WriteLine($"订单号: {OrderNumber}");
        Console.WriteLine($"客户: {CustomerName} (ID: {CustomerId})");
        Console.WriteLine($"创建时间: {CreatedDate:yyyy-MM-dd HH:mm:ss}");
        Console.WriteLine($"当前状态: {CurrentStateName}");
        
        if (Items.Count > 0)
        {
            Console.WriteLine("\n商品列表:");
            foreach (var item in Items)
            {
                Console.WriteLine($"- {item.ProductName} x {item.Quantity} @ {item.UnitPrice:C} = {item.TotalPrice:C}");
                if (item.AppliedDiscounts.Count > 0)
                {
                    Console.WriteLine($"  折扣: {item.DiscountAmount:C}");
                }
            }
        }
        
        Console.WriteLine($"\n小计: {SubTotal:C}");
        if (DiscountAmount > 0)
        {
            Console.WriteLine($"折扣: -{DiscountAmount:C}");
        }
        Console.WriteLine($"运费: {ShippingCost:C}");
        Console.WriteLine($"税费: {TaxAmount:C}");
        Console.WriteLine($"总计: {GrandTotal:C}");
        Console.WriteLine($"已支付: {PaidAmount:C}");
        
        if (RefundedAmount > 0)
        {
            Console.WriteLine($"已退款: {RefundedAmount:C}");
        }
        
        if (BalanceDue > 0)
        {
            Console.WriteLine($"待支付: {BalanceDue:C}");
        }
        
        if (ShippingAddress != null)
        {
            Console.WriteLine("\n配送地址:");
            Console.WriteLine(ShippingAddress.ToString());
        }
        
        if (Payments.Count > 0)
        {
            Console.WriteLine("\n支付记录:");
            foreach (var payment in Payments)
            {
                Console.WriteLine($"- {payment.PaymentDate:yyyy-MM-dd HH:mm:ss} | {payment.PaymentMethod} | {payment.Amount:C} | {payment.Status}");
            }
        }
        
        if (Shipments.Count > 0)
        {
            Console.WriteLine("\n配送记录:");
            foreach (var shipment in Shipments)
            {
                Console.WriteLine($"- {shipment.ShipmentDate:yyyy-MM-dd} | {shipment.Carrier} | 跟踪号: {shipment.TrackingNumber} | {shipment.Status}");
            }
        }
        
        if (EventHistory.Count > 0)
        {
            Console.WriteLine("\n订单历史:");
            foreach (var log in EventHistory.OrderByDescending(e => e.Timestamp).Take(5))
            {
                Console.WriteLine($"- {log}");
            }
            
            if (EventHistory.Count > 5)
            {
                Console.WriteLine($"...(还有 {EventHistory.Count - 5} 条记录)");
            }
        }
    }
}

// 15. 基础状态类 - 实现通用的逻辑和默认行为
public abstract class OrderStateBase : IOrderState
{
    // 状态转换检查
    public virtual bool CanTransitionTo(IOrderState nextState)
    {
        var allowedTransitions = GetAllowedTransitions();
        return allowedTransitions.Any(t => t.ToState == nextState.GetStateEnum());
    }
    
    // 进入状态
    public virtual void EnterState(Order order)
    {
        // 默认实现,可由子类重写
    }
    
    // 退出状态
    public virtual void ExitState(Order order)
    {
        // 默认实现,可由子类重写
    }
    
    // 默认的操作实现 - 大多数操作在大多数状态下是不允许的
    public virtual Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine($"无法处理订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"无法支付订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo)
    {
        Console.WriteLine($"无法发货订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo)
    {
        Console.WriteLine($"无法交付订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"无法退货订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"无法退款订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"无法取消订单: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    // 在大多数状态下修改订单都是不允许的
    public virtual Task<bool> AddItem(Order order, OrderItem item)
    {
        Console.WriteLine($"无法添加商品: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> RemoveItem(Order order, string itemId)
    {
        Console.WriteLine($"无法移除商品: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateQuantity(Order order, string itemId, int quantity)
    {
        Console.WriteLine($"无法更新数量: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> ApplyDiscount(Order order, Discount discount)
    {
        Console.WriteLine($"无法应用折扣: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        Console.WriteLine($"无法更新配送地址: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    public virtual Task<bool> UpdateBillingAddress(Order order, Address address)
    {
        Console.WriteLine($"无法更新账单地址: 订单状态为 {GetStateName()}");
        return Task.FromResult(false);
    }
    
    // 子类必须实现的方法
    public abstract string GetStateName();
    public abstract OrderStateEnum GetStateEnum();
    public abstract List<OrderStateTransition> GetAllowedTransitions();
}

// 16. 已创建状态
public class CreatedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已进入已创建状态");
    }
    
    public override string GetStateName()
    {
        return "已创建";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Created;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.Processing, "处理", "开始处理订单"),
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.AwaitingPayment, "等待支付", "订单已准备好等待支付"),
            new OrderStateTransition(OrderStateEnum.Created, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    // 在已创建状态下允许的操作
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine($"开始处理订单 {order.OrderNumber}");
        
        // 异步转换到处理中状态
        return order.SetState(new ProcessingState());
    }
    
    public override async Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"为订单 {order.OrderNumber} 处理支付");
        
        // 添加支付记录
        order.Payments.Add(paymentInfo);
        
        // 根据支付状态设置订单状态
        if (paymentInfo.Status == PaymentInfo.PaymentStatus.Successful)
        {
            // 支付成功,转到已支付状态
            order.LogEvent("PaymentReceived", $"收到支付 {paymentInfo.Amount:C}", "System", 
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "TransactionId", paymentInfo.TransactionId }
                });
                
            return await order.SetState(new PaidState());
        }
        else if (paymentInfo.Status == PaymentInfo.PaymentStatus.Failed)
        {
            // 支付失败,转到支付失败状态
            order.LogEvent("PaymentFailed", $"支付失败 {paymentInfo.Amount:C}", "System",
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "Reason", "Payment processor declined" }
                });
                
            return await order.SetState(new PaymentFailedState());
        }
        else
        {
            // 其他状态,转到等待支付状态
            order.LogEvent("PaymentPending", $"等待支付确认 {paymentInfo.Amount:C}", "System");
            return await order.SetState(new AwaitingPaymentState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "Customer");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
    
    // 允许在已创建状态修改订单
    public override Task<bool> AddItem(Order order, OrderItem item)
    {
        // 检查是否已存在相同商品
        var existingItem = order.Items.FirstOrDefault(i => i.ProductId == item.ProductId);
        
        if (existingItem != null)
        {
            // 如果已存在,增加数量
            existingItem.Quantity += item.Quantity;
            Console.WriteLine($"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}");
            
            order.LogEvent("ItemUpdated", $"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}", "System");
        }
        else
        {
            // 添加新商品
            order.Items.Add(item);
            Console.WriteLine($"添加商品: {item.ProductName} x {item.Quantity}");
            
            order.LogEvent("ItemAdded", $"添加商品: {item.ProductName} x {item.Quantity}", "System");
        }
        
        return Task.FromResult(true);
    }
    
    public override Task<bool> RemoveItem(Order order, string itemId)
    {
        var item = order.Items.FirstOrDefault(i => i.ItemId == itemId);
        
        if (item != null)
        {
            order.Items.Remove(item);
            Console.WriteLine($"移除商品: {item.ProductName}");
            
            order.LogEvent("ItemRemoved", $"移除商品: {item.ProductName}", "System");
            return Task.FromResult(true);
        }
        
        Console.WriteLine($"商品不存在: {itemId}");
        return Task.FromResult(false);
    }
    
    public override Task<bool> UpdateQuantity(Order order, string itemId, int quantity)
    {
        var item = order.Items.FirstOrDefault(i => i.ItemId == itemId);
        
        if (item != null)
        {
            if (quantity <= 0)
            {
                // 如果数量为0或负数,移除商品
                return RemoveItem(order, itemId);
            }
            
            int oldQuantity = item.Quantity;
            item.Quantity = quantity;
            
            Console.WriteLine($"更新商品 {item.ProductName} 数量: {oldQuantity} -> {quantity}");
            
            order.LogEvent("QuantityUpdated", 
                $"更新商品 {item.ProductName} 数量: {oldQuantity} -> {quantity}", 
                "System");
                
            return Task.FromResult(true);
        }
        
        Console.WriteLine($"商品不存在: {itemId}");
        return Task.FromResult(false);
    }
    
    public override Task<bool> ApplyDiscount(Order order, Discount discount)
    {
        // 验证折扣是否有效
        if (!discount.IsValid())
        {
            Console.WriteLine($"折扣无效: {discount.Code}");
            return Task.FromResult(false);
        }
        
        // 检查是否已应用相同折扣
        if (order.AppliedDiscounts.Any(d => d.Code == discount.Code))
        {
            Console.WriteLine($"折扣已应用: {discount.Code}");
            return Task.FromResult(false);
        }
        
        // 应用折扣
        order.AppliedDiscounts.Add(discount);
        
        Console.WriteLine($"应用折扣: {discount.Code}, 折扣金额: {discount.CalculateDiscount(order.SubTotal):C}");
        
        order.LogEvent("DiscountApplied", 
            $"应用折扣: {discount.Code}, 折扣金额: {discount.CalculateDiscount(order.SubTotal):C}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        order.ShippingAddress = address;
        
        Console.WriteLine("更新配送地址");
        
        order.LogEvent("ShippingAddressUpdated", 
            $"更新配送地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateBillingAddress(Order order, Address address)
    {
        order.BillingAddress = address;
        
        Console.WriteLine("更新账单地址");
        
        order.LogEvent("BillingAddressUpdated", 
            $"更新账单地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
}

// 17. 处理中状态
public class ProcessingState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 正在处理中");
        
        // 验证订单是否可以处理
        if (order.Items.Count == 0)
        {
            Console.WriteLine("警告: 订单中没有商品");
        }
        
        if (order.ShippingAddress == null)
        {
            Console.WriteLine("警告: 缺少配送地址");
        }
    }
    
    public override string GetStateName()
    {
        return "处理中";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Processing;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Processing, OrderStateEnum.AwaitingPayment, "等待支付", "处理完成,等待支付"),
            new OrderStateTransition(OrderStateEnum.Processing, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    // 在处理中状态下允许的操作
    public override async Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("完成订单处理");
        
        // 生成税费
        decimal taxRate = 0.08m; // 示例税率
        order.TaxAmount = order.SubTotal * taxRate;
        
        order.LogEvent("TaxCalculated", $"计算税费: {order.TaxAmount:C}", "System");
        
        // 验证订单所需信息
        bool isValid = ValidateOrder(order);
        
        if (!isValid)
        {
            return false;
        }
        
        // 处理完成,转到等待支付状态
        order.LogEvent("ProcessingCompleted", "订单处理完成", "System");
        return await order.SetState(new AwaitingPaymentState());
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
    
    // 在处理中状态仍然可以修改订单
    public override Task<bool> AddItem(Order order, OrderItem item)
    {
        // 检查是否已存在相同商品
        var existingItem = order.Items.FirstOrDefault(i => i.ProductId == item.ProductId);
        
        if (existingItem != null)
        {
            // 如果已存在,增加数量
            existingItem.Quantity += item.Quantity;
            Console.WriteLine($"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}");
            
            order.LogEvent("ItemUpdated", $"更新商品 {item.ProductName} 数量为 {existingItem.Quantity}", "System");
        }
        else
        {
            // 添加新商品
            order.Items.Add(item);
            Console.WriteLine($"添加商品: {item.ProductName} x {item.Quantity}");
            
            order.LogEvent("ItemAdded", $"添加商品: {item.ProductName} x {item.Quantity}", "System");
        }
        
        return Task.FromResult(true);
    }
    
    public override Task<bool> UpdateShippingAddress(Order order, Address address)
    {
        order.ShippingAddress = address;
        
        Console.WriteLine("更新配送地址");
        
        order.LogEvent("ShippingAddressUpdated", 
            $"更新配送地址: {address.City}, {address.State}", 
            "System");
            
        return Task.FromResult(true);
    }
    
    // 订单验证
    private bool ValidateOrder(Order order)
    {
        bool isValid = true;
        
        if (order.Items.Count == 0)
        {
            Console.WriteLine("错误: 订单中没有商品");
            isValid = false;
        }
        
        if (order.ShippingAddress == null)
        {
            Console.WriteLine("错误: 缺少配送地址");
            isValid = false;
        }
        
        return isValid;
    }
}

// 18. 等待支付状态
public class AwaitingPaymentState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 等待支付,应付金额: {order.BalanceDue:C}");
    }
    
    public override string GetStateName()
    {
        return "等待支付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.AwaitingPayment;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.Paid, "支付完成", "订单已支付"),
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.PaymentFailed, "支付失败", "订单支付失败"),
            new OrderStateTransition(OrderStateEnum.AwaitingPayment, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    public override async Task<bool> PayOrder(Order order, PaymentInfo paymentInfo)
    {
        Console.WriteLine($"为订单 {order.OrderNumber} 处理支付 {paymentInfo.Amount:C}");
        
        // 添加支付记录
        order.Payments.Add(paymentInfo);
        
        // 根据支付状态设置订单状态
        if (paymentInfo.Status == PaymentInfo.PaymentStatus.Successful)
        {
            // 检查支付金额是否足够
            if (order.PaidAmount >= order.GrandTotal)
            {
                // 支付足够,转到已支付状态
                order.LogEvent("PaymentReceived", $"收到支付 {paymentInfo.Amount:C}", "System", 
                    new Dictionary<string, string> {
                        { "PaymentMethod", paymentInfo.PaymentMethod },
                        { "TransactionId", paymentInfo.TransactionId }
                    });
                    
                return await order.SetState(new PaidState());
            }
            else
            {
                // 支付不足,保持等待支付状态
                order.LogEvent("PartialPaymentReceived", 
                    $"收到部分支付 {paymentInfo.Amount:C}, 剩余 {order.BalanceDue:C}", 
                    "System");
                    
                Console.WriteLine($"部分支付已收到,剩余应付金额: {order.BalanceDue:C}");
                return true;
            }
        }
        else if (paymentInfo.Status == PaymentInfo.PaymentStatus.Failed)
        {
            // 支付失败,转到支付失败状态
            order.LogEvent("PaymentFailed", $"支付失败 {paymentInfo.Amount:C}", "System",
                new Dictionary<string, string> {
                    { "PaymentMethod", paymentInfo.PaymentMethod },
                    { "Reason", "Payment processor declined" }
                });
                
            return await order.SetState(new PaymentFailedState());
        }
        else
        {
            // 其他状态,保持等待支付状态
            order.LogEvent("PaymentPending", $"等待支付确认 {paymentInfo.Amount:C}", "System");
            Console.WriteLine("支付处理中,等待确认");
            return true;
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 19. 支付失败状态
public class PaymentFailedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 支付失败");
    }
    
    public override string GetStateName()
    {
        return "支付失败";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PaymentFailed;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PaymentFailed, OrderStateEnum.AwaitingPayment, "重新支付", "尝试重新支付"),
            new OrderStateTransition(OrderStateEnum.PaymentFailed, OrderStateEnum.Canceled, "取消", "取消订单")
        };
    }
    
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("重新尝试支付订单");
        return order.SetState(new AwaitingPaymentState());
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 记录取消事件
        order.LogEvent("OrderCanceled", $"订单已取消: {reason}", "System");
        
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 20. 已支付状态
public class PaidState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已支付完成,准备发货");
    }
    
    public override string GetStateName()
    {
        return "已支付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Paid;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.ReadyForShipment, "准备发货", "订单已准备好发货"),
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.Refunded, "退款", "订单已退款"),
            new OrderStateTransition(OrderStateEnum.Paid, OrderStateEnum.Canceled, "取消", "取消订单并退款")
        };
    }
    
    public override Task<bool> ProcessOrder(Order order)
    {
        Console.WriteLine("订单已支付,准备发货");
        return order.SetState(new ReadyForShipmentState());
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 如果退款金额等于已支付金额,转到已退款状态
        if (order.RefundedAmount >= order.PaidAmount)
        {
            return await order.SetState(new RefundedState());
        }
        else
        {
            // 部分退款,转到部分退款状态
            return await order.SetState(new PartiallyRefundedState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消已支付订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 自动创建退款信息
        var refundInfo = new RefundInfo
        {
            RefundId = Guid.NewGuid().ToString(),
            Amount = order.PaidAmount,
            Reason = "订单取消: " + reason,
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Processing,
            RefundMethod = "原付款方式"
        };
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录取消事件
        order.LogEvent("OrderCanceledWithRefund", 
            $"订单已取消并退款 {refundInfo.Amount:C}: {reason}", 
            "System");
            
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 21. 准备发货状态
public class ReadyForShipmentState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已准备好发货");
    }
    
    public override string GetStateName()
    {
        return "准备发货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.ReadyForShipment;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Shipped, "已发货", "订单已发货"),
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Refunded, "退款", "订单已退款"),
            new OrderStateTransition(OrderStateEnum.ReadyForShipment, OrderStateEnum.Canceled, "取消", "取消订单并退款")
        };
    }
    
    public override async Task<bool> ShipOrder(Order order, ShipmentInfo shipmentInfo)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 发货中");
        
        // 添加配送信息
        order.Shipments.Add(shipmentInfo);
        
        // 记录发货事件
        order.LogEvent("OrderShipped", 
            $"订单已发货: {shipmentInfo.Carrier} {shipmentInfo.TrackingNumber}", 
            "System", 
            new Dictionary<string, string> {
                { "Carrier", shipmentInfo.Carrier },
                { "TrackingNumber", shipmentInfo.TrackingNumber }
            });
            
        // 转换到已发货状态
        return await order.SetState(new ShippedState());
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 如果退款金额等于已支付金额,转到已退款状态
        if (order.RefundedAmount >= order.PaidAmount)
        {
            return await order.SetState(new RefundedState());
        }
        else
        {
            // 部分退款,转到部分退款状态
            return await order.SetState(new PartiallyRefundedState());
        }
    }
    
    public override Task<bool> CancelOrder(Order order, string reason)
    {
        Console.WriteLine($"取消准备发货订单 {order.OrderNumber}: {reason}");
        
        // 设置取消原因
        order.CancellationReason = reason;
        
        // 自动创建退款信息
        var refundInfo = new RefundInfo
        {
            RefundId = Guid.NewGuid().ToString(),
            Amount = order.PaidAmount,
            Reason = "订单取消: " + reason,
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Processing,
            RefundMethod = "原付款方式"
        };
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录取消事件
        order.LogEvent("OrderCanceledWithRefund", 
            $"订单已取消并退款 {refundInfo.Amount:C}: {reason}", 
            "System");
            
        // 转换到取消状态
        return order.SetState(new CanceledState());
    }
}

// 22. 已发货状态
public class ShippedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已发货");
    }
    
    public override string GetStateName()
    {
        return "已发货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Shipped;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Shipped, OrderStateEnum.Delivered, "已交付", "订单已交付"),
            new OrderStateTransition(OrderStateEnum.Shipped, OrderStateEnum.Returned, "已退货", "订单已退货")
        };
    }
    
    public override async Task<bool> DeliverOrder(Order order, DeliveryInfo deliveryInfo)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已交付");
        
        // 添加交付信息
        order.Deliveries.Add(deliveryInfo);
        
        // 记录交付事件
        order.LogEvent("OrderDelivered", 
            $"订单已交付: 接收人 {deliveryInfo.ReceivedBy}", 
            "System");
            
        // 转换到已交付状态
        return await order.SetState(new DeliveredState());
    }
}

// 23. 已交付状态
public class DeliveredState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已交付,交付时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
        
        // 检查是否所有项目都已交付
        bool allItemsDelivered = true;
        
        // 在实际应用中,这里会检查每个订单项的交付状态
        
        if (allItemsDelivered)
        {
            // 如果一切正常,自动转换到已完成状态
            Task.Run(async () => {
                // 延迟一些时间后自动完成订单
                await Task.Delay(5000); // 5秒后自动完成
                await order.SetState(new CompletedState());
            });
        }
    }
    
    public override string GetStateName()
    {
        return "已交付";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Delivered;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.Completed, "已完成", "订单已完成"),
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.Returned, "已退货", "订单已退货"),
            new OrderStateTransition(OrderStateEnum.Delivered, OrderStateEnum.PartiallyReturned, "部分退货", "订单部分退货")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理订单 {order.OrderNumber} 的退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("ReturnRequested", 
            $"退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            bool itemReturned = returnInfo.ReturnedItems.Any(ri => ri.ItemId == item.ItemId && ri.Quantity == item.Quantity);
            if (!itemReturned)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        else
        {
            // 部分退货,转到部分退货状态
            return await order.SetState(new PartiallyReturnedState());
        }
    }
}

// 24. 已完成状态
public class CompletedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已完成");
        
        // 记录完成事件
        order.LogEvent("OrderCompleted", "订单已完成", "System");
    }
    
    public override string GetStateName()
    {
        return "已完成";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Completed;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Completed, OrderStateEnum.Returned, "已退货", "订单已退货"),
            new OrderStateTransition(OrderStateEnum.Completed, OrderStateEnum.PartiallyReturned, "部分退货", "订单部分退货")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理已完成订单 {order.OrderNumber} 的退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("ReturnRequested", 
            $"退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            bool itemReturned = returnInfo.ReturnedItems.Any(ri => ri.ItemId == item.ItemId && ri.Quantity == item.Quantity);
            if (!itemReturned)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        else
        {
            // 部分退货,转到部分退货状态
            return await order.SetState(new PartiallyReturnedState());
        }
    }
}

// 25. 已退货状态
public class ReturnedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已退货");
        
        // 在这里可以自动触发退款流程
        Task.Run(async () => {
            // 创建退款信息
            var refundInfo = new RefundInfo
            {
                RefundId = Guid.NewGuid().ToString(),
                Amount = order.PaidAmount,
                Reason = "订单退货",
                RefundRequestDate = DateTime.Now,
                Status = RefundInfo.RefundStatus.Processing,
                RefundMethod = "原付款方式"
            };
            
            // 处理退款
            await order.RefundOrder(refundInfo);
        });
    }
    
    public override string GetStateName()
    {
        return "已退货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Returned;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.Returned, OrderStateEnum.Refunded, "已退款", "订单已退款")
        };
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理退货订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("RefundProcessed", 
            $"处理退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 转换到已退款状态
        return await order.SetState(new RefundedState());
    }
}

// 26. 部分退货状态
public class PartiallyReturnedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已部分退货");
    }
    
    public override string GetStateName()
    {
        return "部分退货";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PartiallyReturned;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PartiallyReturned, OrderStateEnum.Returned, "全部退货", "订单已全部退货"),
            new OrderStateTransition(OrderStateEnum.PartiallyReturned, OrderStateEnum.PartiallyRefunded, "部分退款", "订单已部分退款")
        };
    }
    
    public override async Task<bool> ReturnOrder(Order order, ReturnInfo returnInfo)
    {
        Console.WriteLine($"处理部分退货订单 {order.OrderNumber} 的额外退货");
        
        // 添加退货记录
        order.Returns.Add(returnInfo);
        
        // 记录退货事件
        order.LogEvent("AdditionalReturnRequested", 
            $"额外退货请求: {returnInfo.ReturnedItems.Count} 件商品, 原因: {returnInfo.Reason}", 
            "Customer");
            
        // 检查是否现在是全部退货
        bool isFullReturn = true;
        
        // 在实际应用中,这里会检查是否所有订单项都退货了
        foreach (var item in order.Items)
        {
            // 从所有退货记录中检查该商品的退货数量
            int returnedQuantity = 0;
            foreach (var returnRecord in order.Returns)
            {
                returnedQuantity += returnRecord.ReturnedItems
                    .Where(ri => ri.ItemId == item.ItemId)
                    .Sum(ri => ri.Quantity);
            }
            
            if (returnedQuantity < item.Quantity)
            {
                isFullReturn = false;
                break;
            }
        }
        
        if (isFullReturn)
        {
            // 全部退货,转到已退货状态
            return await order.SetState(new ReturnedState());
        }
        
        return true;
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理部分退货订单 {order.OrderNumber} 的退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("PartialRefundProcessed", 
            $"处理部分退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 转换到部分退款状态
        return await order.SetState(new PartiallyRefundedState());
    }
}

// 27. 已退款状态
public class RefundedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已退款");
        
        // 记录退款完成事件
        order.LogEvent("RefundCompleted", $"退款完成: {order.RefundedAmount:C}", "System");
    }
    
    public override string GetStateName()
    {
        return "已退款";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Refunded;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        // 已退款是终态,没有后续转换
        return new List<OrderStateTransition>();
    }
}

// 28. 部分退款状态
public class PartiallyRefundedState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已部分退款: {order.RefundedAmount:C}");
    }
    
    public override string GetStateName()
    {
        return "部分退款";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.PartiallyRefunded;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        return new List<OrderStateTransition>
        {
            new OrderStateTransition(OrderStateEnum.PartiallyRefunded, OrderStateEnum.Refunded, "全部退款", "订单已全部退款")
        };
    }
    
    public override async Task<bool> RefundOrder(Order order, RefundInfo refundInfo)
    {
        Console.WriteLine($"处理部分退款订单 {order.OrderNumber} 的额外退款: {refundInfo.Amount:C}");
        
        // 添加退款记录
        order.Refunds.Add(refundInfo);
        
        // 记录退款事件
        order.LogEvent("AdditionalRefundProcessed", 
            $"处理额外退款: {refundInfo.Amount:C}, 原因: {refundInfo.Reason}", 
            "System");
            
        // 检查退款金额是否等于已支付金额
        if (order.RefundedAmount >= order.PaidAmount)
        {
            // 全部退款,转到已退款状态
            return await order.SetState(new RefundedState());
        }
        
        return true;
    }
}

// 29. 已取消状态
public class CanceledState : OrderStateBase
{
    public override void EnterState(Order order)
    {
        Console.WriteLine($"订单 {order.OrderNumber} 已取消,原因: {order.CancellationReason}");
    }
    
    public override string GetStateName()
    {
        return "已取消";
    }
    
    public override OrderStateEnum GetStateEnum()
    {
        return OrderStateEnum.Canceled;
    }
    
    public override List<OrderStateTransition> GetAllowedTransitions()
    {
        // 已取消是终态,没有后续转换
        return new List<OrderStateTransition>();
    }
}

// 30. 订单状态工厂
public static class OrderStateFactory
{
    public static IOrderState CreateState(OrderStateEnum stateEnum)
    {
        return stateEnum switch
        {
            OrderStateEnum.Created => new CreatedState(),
            OrderStateEnum.Processing => new ProcessingState(),
            OrderStateEnum.AwaitingPayment => new AwaitingPaymentState(),
            OrderStateEnum.PaymentFailed => new PaymentFailedState(),
            OrderStateEnum.Paid => new PaidState(),
            OrderStateEnum.ReadyForShipment => new ReadyForShipmentState(),
            OrderStateEnum.Shipped => new ShippedState(),
            OrderStateEnum.Delivered => new DeliveredState(),
            OrderStateEnum.Returned => new ReturnedState(),
            OrderStateEnum.PartiallyReturned => new PartiallyReturnedState(),
            OrderStateEnum.Refunded => new RefundedState(),
            OrderStateEnum.PartiallyRefunded => new PartiallyRefundedState(),
            OrderStateEnum.Canceled => new CanceledState(),
            OrderStateEnum.Completed => new CompletedState(),
            _ => throw new ArgumentException($"未知的订单状态: {stateEnum}")
        };
    }
}

// 31. 订单处理示例
public class OrderProcessingDemo
{
    public static async Task RunDemoAsync()
    {
        // 创建订单
        var order = new Order("ORD-2023-001", "CUST-001", "张三");
        
        // 显示订单状态
        order.DisplayOrder();
        Console.WriteLine();
        
        // 添加商品
        await order.AddItem(new OrderItem
        {
            ItemId = "ITEM-001",
            ProductId = "PROD-001",
            ProductName = "iPhone 15 Pro",
            Quantity = 1,
            UnitPrice = 8999.00m
        });
        
        await order.AddItem(new OrderItem
        {
            ItemId = "ITEM-002",
            ProductId = "PROD-002",
            ProductName = "AirPods Pro",
            Quantity = 1,
            UnitPrice = 1999.00m
        });
        
        // 应用折扣
        await order.ApplyDiscount(new Discount
        {
            DiscountId = "DISC-001",
            Code = "WELCOME10",
            Description = "新用户折扣10%",
            Type = Discount.DiscountType.Percentage,
            Value = 10
        });
        
        // 设置地址
        await order.UpdateShippingAddress(new Address
        {
            FullName = "张三",
            AddressLine1 = "科技路123号",
            City = "北京",
            State = "北京",
            ZipCode = "100000",
            Country = "中国",
            PhoneNumber = "13800138000"
        });
        
        await order.UpdateBillingAddress(new Address
        {
            FullName = "张三",
            AddressLine1 = "科技路123号",
            City = "北京",
            State = "北京",
            ZipCode = "100000",
            Country = "中国",
            PhoneNumber = "13800138000"
        });
        
        // 处理订单
        Console.WriteLine("\n处理订单...");
        await order.ProcessOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 支付订单
        Console.WriteLine("\n支付订单...");
        await order.PayOrder(new PaymentInfo
        {
            PaymentId = "PAY-001",
            Amount = order.GrandTotal,
            PaymentMethod = "信用卡",
            PaymentDate = DateTime.Now,
            TransactionId = "TRANS-001",
            Status = PaymentInfo.PaymentStatus.Successful
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 准备发货
        Console.WriteLine("\n准备发货...");
        await order.ProcessOrder();
        order.DisplayOrder();
        Console.WriteLine();
        
        // 发货
        Console.WriteLine("\n发货...");
        await order.ShipOrder(new ShipmentInfo
        {
            ShipmentId = "SHIP-001",
            Carrier = "顺丰快递",
            TrackingNumber = "SF1234567890",
            ShipmentDate = DateTime.Now,
            ShippingCost = 20.00m,
            Status = ShipmentInfo.ShipmentStatus.Shipped
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 交付
        Console.WriteLine("\n交付...");
        await order.DeliverOrder(new DeliveryInfo
        {
            DeliveryId = "DEL-001",
            DeliveryDate = DateTime.Now,
            ReceivedBy = "张三",
            Status = DeliveryInfo.DeliveryStatus.Delivered
        });
        order.DisplayOrder();
        Console.WriteLine();
        
        // 等待订单自动完成
        Console.WriteLine("\n等待订单自动完成...");
        await Task.Delay(6000);
        order.DisplayOrder();
        Console.WriteLine();
        
        // 创建第二个订单并取消
        var order2 = new Order("ORD-2023-002", "CUST-002", "李四");
        Console.WriteLine($"\n创建第二个订单: {order2.OrderNumber}");
        
        // 添加商品
        await order2.AddItem(new OrderItem
        {
            ItemId = "ITEM-003",
            ProductId = "PROD-003",
            ProductName = "MacBook Air",
            Quantity = 1,
            UnitPrice = 7999.00m
        });
        
        // 设置地址
        await order2.UpdateShippingAddress(new Address
        {
            FullName = "李四",
            AddressLine1 = "创新路456号",
            City = "上海",
            State = "上海",
            ZipCode = "200000",
            Country = "中国",
            PhoneNumber = "13900139000"
        });
        
        // 处理订单
        Console.WriteLine("\n处理订单...");
        await order2.ProcessOrder();
        
        // 取消订单
        Console.WriteLine("\n取消订单...");
        await order2.CancelOrder("客户要求取消");
        order2.DisplayOrder();
        
        // 创建第三个订单并处理退货
        var order3 = new Order("ORD-2023-003", "CUST-003", "王五");
        Console.WriteLine($"\n创建第三个订单: {order3.OrderNumber}");
        
        // 添加商品
        await order3.AddItem(new OrderItem
        {
            ItemId = "ITEM-004",
            ProductId = "PROD-004",
            ProductName = "iPad Pro",
            Quantity = 1,
            UnitPrice = 6999.00m
        });
        
        await order3.AddItem(new OrderItem
        {
            ItemId = "ITEM-005",
            ProductId = "PROD-005",
            ProductName = "Apple Pencil",
            Quantity = 1,
            UnitPrice = 899.00m
        });
        
        // 设置地址
        await order3.UpdateShippingAddress(new Address
        {
            FullName = "王五",
            AddressLine1 = "发展大道789号",
            City = "广州",
            State = "广东",
            ZipCode = "510000",
            Country = "中国",
            PhoneNumber = "13600136000"
        });
        
        // 处理并支付订单
        await order3.ProcessOrder();
        await order3.PayOrder(new PaymentInfo
        {
            PaymentId = "PAY-003",
            Amount = order3.GrandTotal,
            PaymentMethod = "支付宝",
            PaymentDate = DateTime.Now,
            TransactionId = "TRANS-003",
            Status = PaymentInfo.PaymentStatus.Successful
        });
        
        // 发货和交付
        await order3.ProcessOrder();
        await order3.ShipOrder(new ShipmentInfo
        {
            ShipmentId = "SHIP-003",
            Carrier = "中通快递",
            TrackingNumber = "ZT9876543210",
            ShipmentDate = DateTime.Now,
            ShippingCost = 15.00m,
            Status = ShipmentInfo.ShipmentStatus.Shipped
        });
        
        await order3.DeliverOrder(new DeliveryInfo
        {
            DeliveryId = "DEL-003",
            DeliveryDate = DateTime.Now,
            ReceivedBy = "王五",
            Status = DeliveryInfo.DeliveryStatus.Delivered
        });
        
        // 完成订单
        await Task.Delay(6000);
        
        // 处理部分退货
        Console.WriteLine("\n处理部分退货...");
        var item = order3.Items.First(i => i.ProductId == "PROD-005"); // Apple Pencil
        var returnedItem = item.Clone();
        
        await order3.ReturnOrder(new ReturnInfo
        {
            ReturnId = "RET-001",
            Reason = "不满意产品",
            ReturnRequestDate = DateTime.Now,
            ReturnedItems = new List<OrderItem> { returnedItem },
            Status = ReturnInfo.ReturnStatus.Received
        });
        
        // 处理退款
        Console.WriteLine("\n处理退款...");
        await order3.RefundOrder(new RefundInfo
        {
            RefundId = "REF-001",
            Amount = returnedItem.FinalPrice,
            Reason = "退货退款",
            RefundRequestDate = DateTime.Now,
            Status = RefundInfo.RefundStatus.Completed,
            RefundMethod = "原付款方式"
        });
        
        order3.DisplayOrder();
    }
}

// 32. 客户端代码
public class Client
{
    public static async Task Main()
    {
        Console.WriteLine("===== 订单状态管理演示 =====\n");
        
        await OrderProcessingDemo.RunDemoAsync();
        
        Console.WriteLine("\n===== 演示完成 =====");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151

业务场景结合:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;

// 工单处理系统 - 使用状态模式实现工单流转

// 1. 工单优先级枚举
public enum TicketPriority
{
    Low,
    Normal,
    High,
    Critical
}

// 2. 工单类型枚举
public enum TicketType
{
    Bug,
    Feature,
    Support,
    Inquiry,
    Complaint,
    Maintenance,
    Security,
    Other
}

// 3. 工单状态枚举
public enum TicketStateEnum
{
    New,
    Triaged,
    Assigned,
    InProgress,
    Waiting,
    Resolved,
    Verified,
    Reopened,
    Closed,
    Cancelled
}

// 4. 用户角色枚举
public enum UserRole
{
    Customer,
    Agent,
    Supervisor,
    Developer,
    Manager,
    Administrator
}

// 5. 用户类
public class User
{
    public string UserId { get; }
    public string Username { get; set; }
    public string Email { get; set; }
    public string Department { get; set; }
    public UserRole Role { get; set; }
    public bool IsActive { get; set; } = true;
    
    public User(string userId, string username, string email, UserRole role)
    {
        UserId = userId;
        Username = username;
        Email = email;
        Role = role;
    }
    
    // 检查用户是否有特定权限
    public bool HasPermission(string permissionName)
    {
        // 简化的权限检查,基于角色
        return Role switch
        {
            UserRole.Administrator => true, // 管理员有所有权限
            UserRole.Manager => permissionName != "system_config",
            UserRole.Supervisor => new[] { "assign_ticket", "resolve_ticket", "close_ticket", "reopen_ticket" }.Contains(permissionName),
            UserRole.Developer => new[] { "update_ticket", "resolve_ticket" }.Contains(permissionName),
            UserRole.Agent => new[] { "update_ticket", "assign_ticket", "resolve_ticket" }.Contains(permissionName),
            UserRole.Customer => new[] { "create_ticket", "update_ticket", "close_ticket" }.Contains(permissionName),
            _ => false
        };
    }
}

// 6. 工单评论类
public class TicketComment
{
    public string CommentId { get; } = Guid.NewGuid().ToString();
    public string Content { get; set; }
    public string AuthorId { get; set; }
    public string AuthorName { get; set; }
    public DateTime CreatedTime { get; }
    public bool IsInternal { get; set; } // 是否仅内部可见
    
    public TicketComment(string content, string authorId, string authorName, bool isInternal = false)
    {
        Content = content;
        AuthorId = authorId;
        AuthorName = authorName;
        CreatedTime = DateTime.Now;
        IsInternal = isInternal;
    }
    
    public override string ToString()
    {
        string internalMark = IsInternal ? " [内部]" : "";
        return $"{CreatedTime:yyyy-MM-dd HH:mm:ss} - {AuthorName}{internalMark}: {Content}";
    }
}

// 7. 工单附件类
public class TicketAttachment
{
    public string AttachmentId { get; } = Guid.NewGuid().ToString();
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public long FileSize { get; set; }
    public string UploadedBy { get; set; }
    public DateTime UploadTime { get; }
    public string FileUrl { get; set; }
    
    public TicketAttachment(string fileName, string contentType, long fileSize, string uploadedBy)
    {
        FileName = fileName;
        ContentType = contentType;
        FileSize = fileSize;
        UploadedBy = uploadedBy;
        UploadTime = DateTime.Now;
        FileUrl = $"/attachments/{AttachmentId}/{fileName}"; // 示例URL
    }
    
    public string GetFormattedSize()
    {
        string[] sizes = { "B", "KB", "MB", "GB" };
        double len = FileSize;
        int order = 0;
        
        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len /= 1024;
        }
        
        return $"{len:0.##} {sizes[order]}";
    }
}

// 8. 工单事件日志
public class TicketEvent
{
    public string EventId { get; } = Guid.NewGuid().ToString();
    public string TicketId { get; set; }
    public string EventType { get; set; }
    public string Description { get; set; }
    public string UserId { get; set; }
    public string Username { get; set; }
    public DateTime Timestamp { get; }
    public Dictionary<string, string> EventData { get; } = new Dictionary<string, string>();
    
    public TicketEvent(string ticketId, string eventType, string description, string userId, string username)
    {
        TicketId = ticketId;
        EventType = eventType;
        Description = description;
        UserId = userId;
        Username = username;
        Timestamp = DateTime.Now;
    }
    
    public override string ToString()
    {
        return $"{Timestamp:yyyy-MM-dd HH:mm:ss} - {EventType}: {Description} (by {Username})";
    }
}

// 9. 工单状态接口
public interface ITicketState
{
    TicketStateEnum StateEnum { get; }
    string StateName { get; }
    
    // 状态转换
    bool CanTransitionTo(ITicketState nextState);
    void EnterState(SupportTicket ticket, string userId, string comments);
    void ExitState(SupportTicket ticket, string userId);
    List<TicketStateEnum> GetAllowedNextStates(SupportTicket ticket, User currentUser);
    
    // 工单操作
    Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments);
    Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments);
    Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal);
    Task<bool> AddAttachment(SupportTicket ticket, TicketAttachment attachment, string userId, string comments);
    Task<bool> SetPriority(SupportTicket ticket, TicketPriority priority, string userId, string comments);
    Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments);
    Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments);
    Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason);
    Task<bool> CancelTicket(SupportTicket ticket, string userId, string reason);
    Task<bool> EscalateTicket(SupportTicket ticket, string userId, string reason);
}

// 10. 抽象工单状态类 - 提供默认实现
public abstract class TicketStateBase : ITicketState
{
    public abstract TicketStateEnum StateEnum { get; }
    public abstract string StateName { get; }
    
    // 状态转换
    public virtual bool CanTransitionTo(ITicketState nextState)
    {
        var allowedStates = GetAllowedTransitions();
        return allowedStates.Contains(nextState.StateEnum);
    }
    
    public virtual void EnterState(SupportTicket ticket, string userId, string comments)
    {
        // 记录状态变更事件
        ticket.LogEvent(
            "state_changed", 
            $"工单状态变更为 {StateName}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 如果有评论,添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            ticket.AddCommentInternal(comments, userId, false);
        }
    }
    
    public virtual void ExitState(SupportTicket ticket, string userId)
    {
        // 默认无操作
    }
    
    public virtual List<TicketStateEnum> GetAllowedNextStates(SupportTicket ticket, User currentUser)
    {
        var allowedStates = GetAllowedTransitions();
        
        // 根据用户角色过滤允许的状态
        // 这里简化处理,仅考虑一些基本规则
        if (currentUser.Role == UserRole.Customer)
        {
            // 客户通常只能关闭工单
            return allowedStates.Intersect(new[] { TicketStateEnum.Closed }).ToList();
        }
        else if (currentUser.Role == UserRole.Agent || currentUser.Role == UserRole.Developer)
        {
            // 代理和开发人员不能取消工单
            return allowedStates.Except(new[] { TicketStateEnum.Cancelled }).ToList();
        }
        
        return allowedStates;
    }
    
    // 默认操作实现 - 大多数操作在大多数状态下是允许的
    public virtual async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "assign_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有分配工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 更新分配信息
        var oldAssigneeId = ticket.AssigneeId;
        ticket.AssigneeId = assigneeId;
        
        // 记录事件
        ticket.LogEvent(
            "ticket_assigned", 
            $"工单分配给 {ticket.GetUsername(assigneeId)}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 如果当前状态是新建或分类后,自动转换为已分配状态
        if (ticket.CurrentStateEnum == TicketStateEnum.New || ticket.CurrentStateEnum == TicketStateEnum.Triaged)
        {
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return true;
    }
    
    public virtual async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "update_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有更新工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 应用更新
        foreach (var update in updates)
        {
            ApplyUpdate(ticket, update.Key, update.Value);
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_updated", 
            $"工单已更新", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    private void ApplyUpdate(SupportTicket ticket, string field, object value)
    {
        switch (field)
        {
            case "subject":
                ticket.Subject = value.ToString();
                break;
            case "description":
                ticket.Description = value.ToString();
                break;
            case "type":
                if (Enum.TryParse<TicketType>(value.ToString(), out var ticketType))
                    ticket.Type = ticketType;
                break;
            case "tags":
                if (value is List<string> tags)
                    ticket.Tags = tags;
                break;
            // 其他字段...
        }
    }
    
    public virtual async Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal)
    {
        // 所有状态都允许添加评论
        ticket.AddCommentInternal(content, userId, isInternal);
        return await Task.FromResult(true);
    }
    
    public virtual async Task<bool> AddAttachment(SupportTicket ticket, TicketAttachment attachment, string userId, string comments)
    {
        // 所有状态都允许添加附件
        ticket.Attachments.Add(attachment);
        
        // 记录事件
        ticket.LogEvent(
            "attachment_added", 
            $"添加附件: {attachment.FileName} ({attachment.GetFormattedSize()})", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    public virtual async Task<bool> SetPriority(SupportTicket ticket, TicketPriority priority, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "update_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有更新工单优先级的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 更新优先级
        var oldPriority = ticket.Priority;
        ticket.Priority = priority;
        
        // 记录事件
        ticket.LogEvent(
            "priority_changed", 
            $"优先级从 {oldPriority} 变更为 {priority}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        return true;
    }
    
    public virtual async Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments)
    {
        // 默认情况下,不允许解决工单
        Console.WriteLine($"无法在 {StateName} 状态下解决工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 默认情况下,不允许关闭工单
        Console.WriteLine($"无法在 {StateName} 状态下关闭工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 默认情况下,不允许重新打开工单
        Console.WriteLine($"无法在 {StateName} 状态下重新打开工单");
        return await Task.FromResult(false);
    }
    
    public virtual async Task<bool> CancelTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool isAdmin = ticket.UserHasPermission(userId, "cancel_ticket");
        
        if (!isCreator && !isAdmin)
        {
            ticket.LogEvent("permission_denied", "没有取消工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 添加取消原因评论
        await ticket.AddComment($"取消原因: {reason}", userId, false);
        
        // 转换状态为已取消
        await ticket.SetState(new CancelledState(), userId, reason);
        
        return true;
    }
    
    public virtual async Task<bool> EscalateTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "escalate_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有升级工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 升级工单优先级
        TicketPriority newPriority = ticket.Priority == TicketPriority.Critical 
            ? TicketPriority.Critical 
            : (TicketPriority)((int)ticket.Priority + 1);
            
        await SetPriority(ticket, newPriority, userId, $"工单已升级: {reason}");
        
        // 记录升级事件
        ticket.LogEvent(
            "ticket_escalated", 
            $"工单已升级: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        return true;
    }
    
    // 获取允许的下一个状态列表
    protected abstract List<TicketStateEnum> GetAllowedTransitions();
}

// 11. 新建状态
public class NewState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.New;
    public override string StateName => "新建";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 新建工单设置创建时间
        ticket.CreatedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Triaged,
            TicketStateEnum.Assigned,
            TicketStateEnum.Cancelled
        };
    }
    
    // 新建状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result && ticket.CurrentStateEnum == TicketStateEnum.New)
        {
            // 自动转换到已分配状态
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return result;
    }
}

// 12. 分类状态
public class TriagedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Triaged;
    public override string StateName => "已分类";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 分类时设置分类时间
        ticket.TriagedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Assigned,
            TicketStateEnum.Cancelled
        };
    }
    
    // 分类状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result)
        {
            // 自动转换到已分配状态
            await ticket.SetState(new AssignedState(), userId, "工单已分配");
        }
        
        return result;
    }
}

// 13. 已分配状态
public class AssignedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Assigned;
    public override string StateName => "已分配";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置分配时间
        ticket.AssignedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Waiting,
            TicketStateEnum.Cancelled
        };
    }
    
    // 已分配状态下的特定行为
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        bool result = await base.UpdateTicket(ticket, updates, userId, comments);
        
        if (result && userId == ticket.AssigneeId)
        {
            // 受理人更新工单,自动转为处理中
            await ticket.SetState(new InProgressState(), userId, "工单处理中");
        }
        
        return result;
    }
}

// 14. 处理中状态
public class InProgressState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.InProgress;
    public override string StateName => "处理中";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置开始处理时间
        if (!ticket.StartProgressTime.HasValue)
        {
            ticket.StartProgressTime = DateTime.Now;
        }
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Waiting,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 处理中状态下的特定行为
    public override async Task<bool> ResolveTicket(SupportTicket ticket, string resolution, string userId, string comments)
    {
        // 检查用户权限
        if (!ticket.UserHasPermission(userId, "resolve_ticket"))
        {
            ticket.LogEvent("permission_denied", "没有解决工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 设置解决方案
        ticket.Resolution = resolution;
        
        // 记录事件
        ticket.LogEvent(
            "ticket_resolved", 
            $"工单已解决", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        string resolveComment = string.IsNullOrEmpty(comments) 
            ? $"工单已解决: {resolution}" 
            : comments;
            
        await ticket.AddComment(resolveComment, userId, false);
        
        // 转换状态为已解决
        await ticket.SetState(new ResolvedState(), userId, resolveComment);
        
        return true;
    }
}

// 15. 等待中状态
public class WaitingState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Waiting;
    public override string StateName => "等待中";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置等待开始时间
        ticket.WaitingStartTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    public override void ExitState(SupportTicket ticket, string userId)
    {
        // 计算等待时间
        if (ticket.WaitingStartTime.HasValue)
        {
            TimeSpan waitingTime = DateTime.Now - ticket.WaitingStartTime.Value;
            ticket.TotalWaitingTime += waitingTime;
            ticket.WaitingStartTime = null;
        }
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 等待中状态下的特定行为
    public override async Task<bool> AddComment(SupportTicket ticket, string content, string userId, bool isInternal)
    {
        await base.AddComment(ticket, content, userId, isInternal);
        
        // 如果是客户回复,自动转为处理中
        if (userId == ticket.CreatedBy)
        {
            await ticket.SetState(new InProgressState(), userId, "客户已回复");
        }
        
        return true;
    }
}

// 16. 已解决状态
public class ResolvedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Resolved;
    public override string StateName => "已解决";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置解决时间
        ticket.ResolvedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Verified,
            TicketStateEnum.Reopened,
            TicketStateEnum.Closed
        };
    }
    
    // 已解决状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    public override async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "close_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有关闭工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_closed", 
            "工单已关闭", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 转换状态为已关闭
        await ticket.SetState(new ClosedState(), userId, "工单已关闭");
        
        return true;
    }
}

// 17. 已验证状态
public class VerifiedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Verified;
    public override string StateName => "已验证";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置验证时间
        ticket.VerifiedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Closed,
            TicketStateEnum.Reopened
        };
    }
    
    // 已验证状态下的特定行为
    public override async Task<bool> CloseTicket(SupportTicket ticket, string userId, string comments)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "close_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有关闭工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_closed", 
            "工单已关闭", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        if (!string.IsNullOrEmpty(comments))
        {
            await ticket.AddComment(comments, userId, false);
        }
        
        // 转换状态为已关闭
        await ticket.SetState(new ClosedState(), userId, "工单已关闭");
        
        return true;
    }
    
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
}

// 18. 重新打开状态
public class ReopenedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Reopened;
    public override string StateName => "重新打开";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 重新打开时间
        ticket.ReopenedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Assigned,
            TicketStateEnum.InProgress,
            TicketStateEnum.Resolved,
            TicketStateEnum.Cancelled
        };
    }
    
    // 重新打开状态下的特定行为
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        bool result = await base.AssignTicket(ticket, assigneeId, userId, comments);
        
        if (result)
        {
            // 自动转换到已分配或处理中状态
            if (assigneeId == ticket.PreviousAssigneeId)
            {
                await ticket.SetState(new InProgressState(), userId, "工单已分配给之前的处理人");
            }
            else
            {
                await ticket.SetState(new AssignedState(), userId, "工单已重新分配");
            }
        }
        
        return result;
    }
}

// 19. 已关闭状态
public class ClosedState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Closed;
    public override string StateName => "已关闭";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置关闭时间
        ticket.ClosedTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
        
        // 计算解决时间
        if (ticket.CreatedTime.HasValue && ticket.ResolvedTime.HasValue)
        {
            ticket.ResolutionTime = ticket.ResolvedTime.Value - ticket.CreatedTime.Value;
        }
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Reopened
        };
    }
    
    // 已关闭状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    // 在已关闭状态下限制一些操作
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        Console.WriteLine("无法更新已关闭的工单");
        return await Task.FromResult(false);
    }
}

// 20. 已取消状态
public class CancelledState : TicketStateBase
{
    public override TicketStateEnum StateEnum => TicketStateEnum.Cancelled;
    public override string StateName => "已取消";
    
    public override void EnterState(SupportTicket ticket, string userId, string comments)
    {
        base.EnterState(ticket, userId, comments);
        
        // 设置取消时间
        ticket.CancelledTime = DateTime.Now;
        ticket.UpdatedTime = DateTime.Now;
    }
    
    protected override List<TicketStateEnum> GetAllowedTransitions()
    {
        return new List<TicketStateEnum>
        {
            TicketStateEnum.Reopened
        };
    }
    
    // 已取消状态下的特定行为
    public override async Task<bool> ReopenTicket(SupportTicket ticket, string userId, string reason)
    {
        // 检查用户权限
        bool isCreator = userId == ticket.CreatedBy;
        bool hasPermission = ticket.UserHasPermission(userId, "reopen_ticket");
        
        if (!isCreator && !hasPermission)
        {
            ticket.LogEvent("permission_denied", "没有重新打开工单的权限", userId, ticket.GetUsername(userId));
            return false;
        }
        
        // 记录事件
        ticket.LogEvent(
            "ticket_reopened", 
            $"工单已重新打开: {reason}", 
            userId, 
            ticket.GetUsername(userId)
        );
        
        // 添加评论
        await ticket.AddComment($"工单已重新打开: {reason}", userId, false);
        
        // 转换状态为重新打开
        await ticket.SetState(new ReopenedState(), userId, reason);
        
        return true;
    }
    
    // 在已取消状态下限制一些操作
    public override async Task<bool> UpdateTicket(SupportTicket ticket, Dictionary<string, object> updates, string userId, string comments)
    {
        Console.WriteLine("无法更新已取消的工单");
        return await Task.FromResult(false);
    }
    
    public override async Task<bool> AssignTicket(SupportTicket ticket, string assigneeId, string userId, string comments)
    {
        Console.WriteLine("无法分配已取消的工单");
        return await Task.FromResult(false);
    }
}

// 21. 工单状态工厂
public static class TicketStateFactory
{
    public static ITicketState GetState(TicketStateEnum stateEnum)
    {
        return stateEnum switch
        {
            TicketStateEnum.New => new NewState(),
            TicketStateEnum.Triaged => new TriagedState(),
            TicketStateEnum.Assigned => new AssignedState(),
            TicketStateEnum.InProgress => new InProgressState(),
            TicketStateEnum.Waiting => new WaitingState(),
            TicketStateEnum.Resolved => new ResolvedState(),
            TicketStateEnum.Verified => new VerifiedState(),
            TicketStateEnum.Reopened => new ReopenedState(),
            TicketStateEnum.Closed => new ClosedState(),
            TicketStateEnum.Cancelled => new CancelledState(),
            _ => throw new ArgumentException($"未知的工单状态: {stateEnum}")
        };
    }
}

// 22. 工单类
public class SupportTicket
{
    // 基本信息
    public string TicketId { get; }
    public string Subject { get; set; }
    public string Description { get; set; }
    public TicketType Type { get; set; }
    public TicketPriority Priority { get; set; }
    
    // 状态信息
    private ITicketState _currentState;
    public TicketStateEnum CurrentStateEnum => _currentState.StateEnum;
    public string CurrentStateName => _currentState.StateName;
    
    // 参与者信息
    public string CreatedBy { get; set; }
    public string AssigneeId { get; set; }
    public string PreviousAssigneeId { get; set; }
    
    // 时间信息
    public DateTime? CreatedTime { get; set; }
    public DateTime? UpdatedTime { get; set; }
    public DateTime? AssignedTime { get; set; }
    public DateTime? TriagedTime { get; set; }
    public DateTime? StartProgressTime { get; set; }
    public DateTime? WaitingStartTime { get; set; }
    public TimeSpan TotalWaitingTime { get; set; } = TimeSpan.Zero;
    public DateTime? ResolvedTime { get; set; }
    public DateTime? VerifiedTime { get; set; }
    public DateTime? ClosedTime { get; set; }
    public DateTime? ReopenedTime { get; set; }
    public DateTime? CancelledTime { get; set; }
    public TimeSpan? ResolutionTime { get; set; }
    
    // 解决方案
    public string Resolution { get; set; }
    
    // 附加信息
    public List<string> Tags { get; set; } = new List<string>();
    public List<TicketComment> Comments { get; } = new List<TicketComment>();
    public List<TicketAttachment> Attachments { get; } = new List<TicketAttachment>();
    public List<TicketEvent> EventHistory { get; } = new List<TicketEvent>();
    
    // SLA相关
    public DateTime? DueDate { get; set; }
    public DateTime? EscalatedTime { get; set; }
    public int EscalationLevel { get; set; } = 0;
    
    // 依赖关系
    private readonly Dictionary<string, User> _userCache = new Dictionary<string, User>();
    private readonly IUserService _userService;
    private readonly ILogger<SupportTicket> _logger;
    
    public SupportTicket(string ticketId, string subject, string description, 
                        TicketType type, string createdBy, IUserService userService,
                        ILogger<SupportTicket> logger)
    {
        TicketId = ticketId;
        Subject = subject;
        Description = description;
        Type = type;
        Priority = TicketPriority.Normal; // 默认优先级
        CreatedBy = createdBy;
        
        _userService = userService;
        _logger = logger;
        
        // 设置初始状态
        _currentState = new NewState();
        _currentState.EnterState(this, createdBy, "工单创建");
    }
    
    // 状态转换
    public async Task<bool> SetState(ITicketState newState, string userId, string comments)
    {
        if (!_currentState.CanTransitionTo(newState))
        {
            _logger.LogWarning("不允许从 {CurrentState} 转换到 {NewState}", 
                _currentState.StateName, newState.StateName);
            return false;
        }
        
        _currentState.ExitState(this, userId);
        ITicketState oldState = _currentState;
        _currentState = newState;
        _currentState.EnterState(this, userId, comments);
        
        _logger.LogInformation("工单 {TicketId} 状态从 {OldState} 变更为 {NewState}", 
            TicketId, oldState.StateName, newState.StateName);
            
        return true;
    }
    
    // 工单操作方法
    public async Task<bool> AssignTicket(string assigneeId, string userId, string comments)
    {
        return await _currentState.AssignTicket(this, assigneeId, userId, comments);
    }
    
    public async Task<bool> UpdateTicket(Dictionary<string, object> updates, string userId, string comments)
    {
        return await _currentState.UpdateTicket(this, updates, userId, comments);
    }
    
    public async Task<bool> AddComment(string content, string userId, bool isInternal)
    {
        return await _currentState.AddComment(this, content, userId, isInternal);
    }
    
    public void AddCommentInternal(string content, string userId, bool isInternal)
    {
        User user = GetUser(userId);
        
        var comment = new TicketComment(
            content,
            userId,
            user?.Username ?? userId,
            isInternal
        );
        
        Comments.Add(comment);
        UpdatedTime = DateTime.Now;
        
        LogEvent("comment_added", 
            $"添加评论" + (isInternal ? " (内部)" : ""), 
            userId, 
            user?.Username ?? userId);
    }
    
    public async Task<bool> AddAttachment(TicketAttachment attachment, string userId, string comments)
    {
        return await _currentState.AddAttachment(this, attachment, userId, comments);
    }
    
    public async Task<bool> SetPriority(TicketPriority priority, string userId, string comments)
    {
        return await _currentState.SetPriority(this, priority, userId, comments);
    }
    
    public async Task<bool> ResolveTicket(string resolution, string userId, string comments)
    {
        return await _currentState.ResolveTicket(this, resolution, userId, comments);
    }
    
    public async Task<bool> CloseTicket(string userId, string comments)
    {
        return await _currentState.CloseTicket(this, userId, comments);
    }
    
    public async Task<bool> ReopenTicket(string userId, string reason)
    {
        return await _currentState.ReopenTicket(this, userId, reason);
    }
    
    public async Task<bool> CancelTicket(string userId, string reason)
    {
        return await _currentState.CancelTicket(this, userId, reason);
    }
    
    public async Task<bool> EscalateTicket(string userId, string reason)
    {
        return await _currentState.EscalateTicket(this, userId, reason);
    }
    
    // 获取下一个可能的状态
    public List<TicketStateEnum> GetAllowedNextStates(string userId)
    {
        User user = GetUser(userId);
        if (user == null) return new List<TicketStateEnum>();
        
        return _currentState.GetAllowedNextStates(this, user);
    }
    
    // 事件记录
    public void LogEvent(string eventType, string description, string userId, string username)
    {
        var ticketEvent = new TicketEvent(
            TicketId,
            eventType,
            description,
            userId,
            username
        );
        
        EventHistory.Add(ticketEvent);
        _logger.LogInformation("工单 {TicketId} 事件: {EventType} - {Description}", 
            TicketId, eventType, description);
    }
    
    // 缓存用户信息
    public User GetUser(string userId)
    {
        if (_userCache.ContainsKey(userId))
        {
            return _userCache[userId];
        }
        
        var user = _userService.GetUser(userId);
        if (user != null)
        {
            _userCache[userId] = user;
        }
        
        return user;
    }
    
    // 获取用户名
    public string GetUsername(string userId)
    {
        var user = GetUser(userId);
        return user?.Username ?? userId;
    }
    
    // 检查用户权限
    public bool UserHasPermission(string userId, string permission)
    {
        var user = GetUser(userId);
        if (user == null) return false;
        
        return user.HasPermission(permission);
    }
    
    // 显示工单信息
    public void DisplayTicket()
    {
        Console.WriteLine($"=== 工单 {TicketId} ===");
        Console.WriteLine($"主题: {Subject}");
        Console.WriteLine($"类型: {Type}");
        Console.WriteLine($"优先级: {Priority}");
        Console.WriteLine($"状态: {CurrentStateName}");
        Console.WriteLine($"创建者: {GetUsername(CreatedBy)}");
        Console.WriteLine($"受理人: {(AssigneeId != null ? GetUsername(AssigneeId) : "未分配")}");
        
        if (CreatedTime.HasValue)
            Console.WriteLine($"创建时间: {CreatedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (UpdatedTime.HasValue)
            Console.WriteLine($"更新时间: {UpdatedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ResolvedTime.HasValue)
            Console.WriteLine($"解决时间: {ResolvedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ClosedTime.HasValue)
            Console.WriteLine($"关闭时间: {ClosedTime:yyyy-MM-dd HH:mm:ss}");
            
        if (ResolutionTime.HasValue)
            Console.WriteLine($"解决用时: {ResolutionTime.Value.TotalHours:F1}小时");
        
        Console.WriteLine("\n描述:");
        Console.WriteLine(Description);
        
        if (!string.IsNullOrEmpty(Resolution))
        {
            Console.WriteLine("\n解决方案:");
            Console.WriteLine(Resolution);
        }
        
        if (Tags.Count > 0)
        {
            Console.WriteLine($"\n标签: {string.Join(", ", Tags)}");
        }
        
        if (Comments.Count > 0)
        {
            Console.WriteLine("\n评论:");
            foreach (var comment in Comments)
            {
                Console.WriteLine(comment);
            }
        }
        
        if (Attachments.Count > 0)
        {
            Console.WriteLine("\n附件:");
            foreach (var attachment in Attachments)
            {
                Console.WriteLine($"- {attachment.FileName} ({attachment.GetFormattedSize()})");
            }
        }
        
        Console.WriteLine("\n工单历史:");
        foreach (var evt in EventHistory.OrderByDescending(e => e.Timestamp).Take(5))
        {
            Console.WriteLine($"- {evt}");
        }
        
        if (EventHistory.Count > 5)
        {
            Console.WriteLine($"...(还有 {EventHistory.Count - 5} 条记录)");
        }
    }
}

// 23. 用户服务接口
public interface IUserService
{
    User GetUser(string userId);
    List<User> GetUsersByRole(UserRole role);
    List<User> GetUsersByDepartment(string department);
}

// 24. 简单用户服务实现
public class SimpleUserService : IUserService
{
    private readonly Dictionary<string, User> _users = new Dictionary<string, User>();
    private readonly ILogger<SimpleUserService> _logger;
    
    public SimpleUserService(ILogger<SimpleUserService> logger)
    {
        _logger = logger;
        
        // 添加一些示例用户
        AddUser(new User("user1", "张三", "zhangsan@example.com", UserRole.Customer));
        AddUser(new User("user2", "李四", "lisi@example.com", UserRole.Agent) { Department = "技术支持" });
        AddUser(new User("user3", "王五", "wangwu@example.com", UserRole.Developer) { Department = "研发" });
        AddUser(new User("user4", "赵六", "zhaoliu@example.com", UserRole.Supervisor) { Department = "技术支持" });
        AddUser(new User("user5", "钱七", "qianqi@example.com", UserRole.Manager) { Department = "产品" });
        AddUser(new User("admin", "管理员", "admin@example.com", UserRole.Administrator));
    }
    
    private void AddUser(User user)
    {
        _users[user.UserId] = user;
    }
    
    public User GetUser(string userId)
    {
        if (_users.TryGetValue(userId, out var user))
        {
            return user;
        }
        
        _logger.LogWarning("找不到用户 {UserId}", userId);
        return null;
    }
    
    public List<User> GetUsersByRole(UserRole role)
    {
        return _users.Values.Where(u => u.Role == role && u.IsActive).ToList();
    }
    
    public List<User> GetUsersByDepartment(string department)
    {
        return _users.Values.Where(u => u.Department == department && u.IsActive).ToList();
    }
}

// 25. 工单服务接口
public interface ITicketService
{
    Task<SupportTicket> CreateTicket(string subject, string description, TicketType type, 
                                  string createdBy, TicketPriority priority = TicketPriority.Normal);
    Task<SupportTicket> GetTicket(string ticketId);
    Task<List<SupportTicket>> GetTicketsByStatus(TicketStateEnum state);
    Task<List<SupportTicket>> GetTicketsByAssignee(string assigneeId);
    Task<List<SupportTicket>> GetTicketsByCreator(string creatorId);
    
    Task<bool> AssignTicket(string ticketId, string assigneeId, string userId, string comments = "");
    Task<bool> UpdateTicket(string ticketId, Dictionary<string, object> updates, string userId, string comments = "");
    Task<bool> AddComment(string ticketId, string content, string userId, bool isInternal = false);
    Task<bool> ResolveTicket(string ticketId, string resolution, string userId, string comments = "");
    Task<bool> CloseTicket(string ticketId, string userId, string comments = "");
    Task<bool> ReopenTicket(string ticketId, string userId, string reason);
}

// 26. 工单服务实现
public class TicketService : ITicketService
{
    private readonly Dictionary<string, SupportTicket> _tickets = new Dictionary<string, SupportTicket>();
    private readonly IUserService _userService;
    private readonly ILogger<TicketService> _logger;
    private readonly ILogger<SupportTicket> _ticketLogger;
    private int _nextTicketNumber = 1;
    
    public TicketService(IUserService userService, ILogger<TicketService> logger, ILogger<SupportTicket> ticketLogger)
    {
        _userService = userService;
        _logger = logger;
        _ticketLogger = ticketLogger;
    }
    
    public async Task<SupportTicket> CreateTicket(string subject, string description, TicketType type, 
                                              string createdBy, TicketPriority priority = TicketPriority.Normal)
    {
        // 生成工单ID
        string ticketId = $"TICKET-{_nextTicketNumber++:D6}";
        
        // 创建工单
        var ticket = new SupportTicket(
            ticketId,
            subject,
            description,
            type,
            createdBy,
            _userService,
            _ticketLogger
        );
        
        // 设置优先级
        await ticket.SetPriority(priority, createdBy, "初始优先级设置");
        
        // 存储工单
        _tickets[ticketId] = ticket;
        
        _logger.LogInformation("创建工单 {TicketId}: {Subject}", ticketId, subject);
        
        return ticket;
    }
    
    public Task<SupportTicket> GetTicket(string ticketId)
    {
        if (_tickets.TryGetValue(ticketId, out var ticket))
        {
            return Task.FromResult(ticket);
        }
        
        _logger.LogWarning("找不到工单 {TicketId}", ticketId);
        return Task.FromResult<SupportTicket>(null);
    }
    
    public Task<List<SupportTicket>> GetTicketsByStatus(TicketStateEnum state)
    {
        var tickets = _tickets.Values
            .Where(t => t.CurrentStateEnum == state)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public Task<List<SupportTicket>> GetTicketsByAssignee(string assigneeId)
    {
        var tickets = _tickets.Values
            .Where(t => t.AssigneeId == assigneeId)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public Task<List<SupportTicket>> GetTicketsByCreator(string creatorId)
    {
        var tickets = _tickets.Values
            .Where(t => t.CreatedBy == creatorId)
            .ToList();
            
        return Task.FromResult(tickets);
    }
    
    public async Task<bool> AssignTicket(string ticketId, string assigneeId, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.AssignTicket(assigneeId, userId, comments);
    }
    
    public async Task<bool> UpdateTicket(string ticketId, Dictionary<string, object> updates, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.UpdateTicket(updates, userId, comments);
    }
    
    public async Task<bool> AddComment(string ticketId, string content, string userId, bool isInternal = false)
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.AddComment(content, userId, isInternal);
    }
    
    public async Task<bool> ResolveTicket(string ticketId, string resolution, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.ResolveTicket(resolution, userId, comments);
    }
    
    public async Task<bool> CloseTicket(string ticketId, string userId, string comments = "")
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.CloseTicket(userId, comments);
    }
    
    public async Task<bool> ReopenTicket(string ticketId, string userId, string reason)
    {
        var ticket = await GetTicket(ticketId);
        if (ticket == null) return false;
        
        return await ticket.ReopenTicket(userId, reason);
    }
}

// 27. 工单流程演示
public class TicketWorkflowDemo
{
    private readonly ITicketService _ticketService;
    private readonly IUserService _userService;
    private readonly ILogger<TicketWorkflowDemo> _logger;
    
    public TicketWorkflowDemo(ITicketService ticketService, IUserService userService, ILogger<TicketWorkflowDemo> logger)
    {
        _ticketService = ticketService;
        _userService = userService;
        _logger = logger;
    }
    
    public async Task RunDemoAsync()
    {
        Console.WriteLine("===== 工单处理流程演示 =====\n");
        
        // 1. 客户创建工单
        _logger.LogInformation("1. 客户创建工单");
        var ticket = await _ticketService.CreateTicket(
            "登录功能异常",
            "我无法登录系统,提示'用户名或密码错误',但我确认输入是正确的。",
            TicketType.Bug,
            "user1",
            TicketPriority.High
        );
        
        Console.WriteLine($"工单已创建: {ticket.TicketId}");
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 2. 添加附件
        _logger.LogInformation("2. 客户添加附件");
        await ticket.AddAttachment(
            new TicketAttachment("error_screenshot.png", "image/png", 258000, "user1"),
            "user1", 
            "添加错误截图"
        );
        
        // 3. 支持人员分配工单
        _logger.LogInformation("3. 支持人员分配工单");
        await _ticketService.AssignTicket(
            ticket.TicketId,
            "user2",
            "user4",
            "请尽快处理这个登录问题"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 4. 支持人员添加内部评论
        _logger.LogInformation("4. 支持人员添加内部评论");
        await _ticketService.AddComment(
            ticket.TicketId,
            "经检查可能是用户账号被锁定,需要重置密码。",
            "user2",
            true // 内部评论
        );
        
        // 5. 支持人员回复客户
        _logger.LogInformation("5. 支持人员回复客户");
        await _ticketService.AddComment(
            ticket.TicketId,
            "您好,经检查您的账号可能被临时锁定。请问您最近是否多次输入错误密码?",
            "user2"
        );
        
        // 6. 客户回复
        _logger.LogInformation("6. 客户回复");
        await _ticketService.AddComment(
            ticket.TicketId,
            "是的,我尝试了几次不同的密码,因为我不太记得了。",
            "user1"
        );
        
        // 7. 工单转给开发人员
        _logger.LogInformation("7. 工单转给开发人员");
        await _ticketService.AssignTicket(
            ticket.TicketId,
            "user3",
            "user2",
            "这需要重置用户密码,请协助处理"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 8. 开发人员处理问题
        _logger.LogInformation("8. 开发人员处理问题");
        await _ticketService.AddComment(
            ticket.TicketId,
            "已重置用户密码,并发送临时密码到用户邮箱。同时,我们应该改进错误提示,明确告知用户账号被锁定的情况。",
            "user3"
        );
        
        // 9. 开发人员解决工单
        _logger.LogInformation("9. 开发人员解决工单");
        await _ticketService.ResolveTicket(
            ticket.TicketId,
            "已重置用户密码并发送临时密码到邮箱。同时计划改进错误提示。",
            "user3",
            "问题已解决,请用户确认"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 10. 客户验证并关闭工单
        _logger.LogInformation("10. 客户验证并关闭工单");
        await _ticketService.AddComment(
            ticket.TicketId,
            "我收到了临时密码邮件,已成功登录系统。谢谢!",
            "user1"
        );
        
        await _ticketService.CloseTicket(
            ticket.TicketId,
            "user1",
            "问题已解决,谢谢支持"
        );
        
        ticket.DisplayTicket();
        Console.WriteLine();
        
        // 11. 创建第二个工单 - 演示重新打开流程
        _logger.LogInformation("11. 创建第二个工单");
        var ticket2 = await _ticketService.CreateTicket(
            "系统响应缓慢",
            "过去几天系统响应越来越慢,特别是在生成报表时几乎无法使用。",
            TicketType.Performance,
            "user1",
            TicketPriority.Normal
        );
        
        // 12. 分配并解决第二个工单
        _logger.LogInformation("12. 分配并解决第二个工单");
        await _ticketService.AssignTicket(ticket2.TicketId, "user2", "user4", "请检查性能问题");
        await _ticketService.AddComment(ticket2.TicketId, "正在检查性能问题...", "user2");
        await _ticketService.ResolveTicket(
            ticket2.TicketId,
            "已优化数据库查询,清理了临时文件,系统性能应该已经恢复。",
            "user2",
            "性能问题已解决"
        );
        
        await _ticketService.CloseTicket(ticket2.TicketId, "user1", "谢谢,问题已解决");
        
        // 13. 客户重新打开工单
        _logger.LogInformation("13. 客户重新打开工单");
        await _ticketService.ReopenTicket(
            ticket2.TicketId,
            "user1",
            "问题仍然存在,生成大型报表时仍然非常慢"
        );
        
        ticket2.DisplayTicket();
        Console.WriteLine();
        
        // 14. 升级工单优先级
        _logger.LogInformation("14. 升级工单优先级");
        await ticket2.EscalateTicket(
            "user4", // 主管
            "客户反馈问题持续存在,且影响业务运营"
        );
        
        // 15. 重新分配给开发人员
        _logger.LogInformation("15. 重新分配给开发人员");
        await _ticketService.AssignTicket(
            ticket2.TicketId,
            "user3",
            "user4",
            "这个性能问题需要更深入的分析,请优先处理"
        );
        
        ticket2.DisplayTicket();
        Console.WriteLine();
        
        Console.WriteLine("===== 工单处理流程演示完成 =====");
    }
}

// 28. 客户端代码
public class Program
{
    public static async Task Main()
    {
        // 设置依赖注入
        var services = new ServiceCollection();
        
        // 添加日志
        services.AddLogging(builder =>
        {
            builder.AddConsole();
            builder.SetMinimumLevel(LogLevel.Information);
        });
        
        // 注册服务
        services.AddSingleton<IUserService, SimpleUserService>();
        services.AddSingleton<ITicketService, TicketService>();
        services.AddTransient<TicketWorkflowDemo>();
        
        var serviceProvider = services.BuildServiceProvider();
        
        // 运行演示
        var demo = serviceProvider.GetRequiredService<TicketWorkflowDemo>();
        await demo.RunDemoAsync();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

# 20. 策略模式

原理:
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,算法的变化不会影响使用算法的客户。

思路:

  1. 定义策略接口,声明算法的方法
  2. 实现具体策略类,封装不同的算法
  3. 创建上下文类,维护对策略对象的引用
  4. 客户端通过上下文类使用策略

前辈经验:

  • 当有多种相关算法可供选择时,使用策略模式
  • 策略模式可以避免使用多重条件语句来选择不同的行为
  • 策略可以在运行时动态切换,提供了更高的灵活性
  • 选择策略的逻辑可以放在客户端或上下文类中
  • 经常与工厂模式结合使用,以便动态选择合适的策略

业务场景:
支付系统,需要支持多种支付方式(信用卡、支付宝、微信支付等),每种支付方式有不同的处理逻辑。

简单实现:

// 支付上下文信息
public class PaymentContext
{
    public decimal Amount { get; set; }
    public string Currency { get; set; }
    public string OrderId { get; set; }
    public Dictionary<string, string> AdditionalInfo { get; set; } = new Dictionary<string, string>();
}

// 支付结果
public class PaymentResult
{
    public bool Success { get; set; }
    public string TransactionId { get; set; }
    public string Message { get; set; }
    public DateTime Timestamp { get; set; } = DateTime.Now;
}

// 支付策略接口
public interface IPaymentStrategy
{
    string Name { get; }
    bool SupportsRefund { get; }
    Task<PaymentResult> ProcessPayment(PaymentContext context);
    Task<PaymentResult> RefundPayment(string transactionId, decimal amount);
}

// 信用卡支付策略
public class CreditCardPaymentStrategy : IPaymentStrategy
{
    public string Name => "信用卡支付";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用信用卡支付网关API
        Console.WriteLine($"使用信用卡支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"信用卡号: {context.AdditionalInfo["CardNumber"]}");
        
        // 模拟网络延迟
        await Task.Delay(1000);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"CC-{Guid.NewGuid():N}",
            Message = "信用卡支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款信用卡支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(1000);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "信用卡退款成功"
        };
    }
}

// 支付宝支付策略
public class AlipayPaymentStrategy : IPaymentStrategy
{
    public string Name => "支付宝";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用支付宝API
        Console.WriteLine($"使用支付宝支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"支付宝账号: {context.AdditionalInfo["AlipayAccount"]}");
        
        // 模拟网络延迟
        await Task.Delay(800);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"ALI-{Guid.NewGuid():N}",
            Message = "支付宝支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款支付宝支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(800);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "支付宝退款成功"
        };
    }
}

// 微信支付策略
public class WeChatPayStrategy : IPaymentStrategy
{
    public string Name => "微信支付";
    public bool SupportsRefund => true;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 在实际应用中,这里会调用微信支付API
        Console.WriteLine($"使用微信支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"微信OpenID: {context.AdditionalInfo["WeChatOpenId"]}");
        
        // 模拟网络延迟
        await Task.Delay(1200);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"WX-{Guid.NewGuid():N}",
            Message = "微信支付成功"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"退款微信支付 {amount},交易ID: {transactionId}");
        
        // 模拟网络延迟
        await Task.Delay(1200);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"RF-{transactionId}",
            Message = "微信支付退款成功"
        };
    }
}

// 银行转账支付策略
public class BankTransferPaymentStrategy : IPaymentStrategy
{
    public string Name => "银行转账";
    public bool SupportsRefund => false;
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        Console.WriteLine($"使用银行转账支付 {context.Amount} {context.Currency}");
        Console.WriteLine($"银行账号: {context.AdditionalInfo["BankAccount"]}");
        Console.WriteLine($"银行名称: {context.AdditionalInfo["BankName"]}");
        
        // 模拟网络延迟
        await Task.Delay(1500);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = $"BT-{Guid.NewGuid():N}",
            Message = "银行转账已处理,等待确认"
        };
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        Console.WriteLine($"银行转账不支持自动退款,交易ID: {transactionId}");
        
        return new PaymentResult
        {
            Success = false,
            Message = "银行转账不支持自动退款,请手动处理"
        };
    }
}

// 支付处理器 - 上下文
public class PaymentProcessor
{
    private IPaymentStrategy _strategy;
    
    public PaymentProcessor(IPaymentStrategy strategy)
    {
        _strategy = strategy;
    }
    
    public void SetStrategy(IPaymentStrategy strategy)
    {
        _strategy = strategy;
    }
    
    public async Task<PaymentResult> ProcessPayment(PaymentContext context)
    {
        // 验证输入
        if (context.Amount <= 0)
        {
            return new PaymentResult
            {
                Success = false,
                Message = "支付金额必须大于0"
            };
        }
        
        if (string.IsNullOrEmpty(context.OrderId))
        {
            return new PaymentResult
            {
                Success = false,
                Message = "订单ID不能为空"
            };
        }
        
        Console.WriteLine($"使用 {_strategy.Name} 处理订单 {context.OrderId} 的支付");
        
        // 调用选定的支付策略
        return await _strategy.ProcessPayment(context);
    }
    
    public async Task<PaymentResult> RefundPayment(string transactionId, decimal amount)
    {
        if (!_strategy.SupportsRefund)
        {
            return new PaymentResult
            {
                Success = false,
                Message = $"{_strategy.Name} 不支持自动退款"
            };
        }
        
        Console.WriteLine($"使用 {_strategy.Name} 处理退款");
        
        return await _strategy.RefundPayment(transactionId, amount);
    }
}

// 客户端代码
public class Client
{
    public static async Task Main()
    {
        // 创建各种支付策略
        IPaymentStrategy creditCardStrategy = new CreditCardPaymentStrategy();
        IPaymentStrategy alipayStrategy = new AlipayPaymentStrategy();
        IPaymentStrategy weChatPayStrategy = new WeChatPayStrategy();
        IPaymentStrategy bankTransferStrategy = new BankTransferPaymentStrategy();
        
        // 创建支付处理器并设置初始策略
        PaymentProcessor processor = new PaymentProcessor(creditCardStrategy);
        
        // 信用卡支付
        var ccContext = new PaymentContext
        {
            Amount = 100.50m,
            Currency = "CNY",
            OrderId = "ORD-12345",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "CardNumber", "4111********1111" },
                { "ExpiryDate", "12/25" },
                { "CVV", "123" }
            }
        };
        
        var ccResult = await processor.ProcessPayment(ccContext);
        Console.WriteLine($"支付结果: {(ccResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {ccResult.TransactionId}");
        Console.WriteLine($"消息: {ccResult.Message}");
        Console.WriteLine();
        
        // 支付宝支付
        processor.SetStrategy(alipayStrategy);
        
        var alipayContext = new PaymentContext
        {
            Amount = 200.75m,
            Currency = "CNY",
            OrderId = "ORD-23456",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "AlipayAccount", "user@example.com" }
            }
        };
        
        var alipayResult = await processor.ProcessPayment(alipayContext);
        Console.WriteLine($"支付结果: {(alipayResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {alipayResult.TransactionId}");
        Console.WriteLine($"消息: {alipayResult.Message}");
        Console.WriteLine();
        
        // 微信支付
        processor.SetStrategy(weChatPayStrategy);
        
        var weChatContext = new PaymentContext
        {
            Amount = 50.25m,
            Currency = "CNY",
            OrderId = "ORD-34567",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "WeChatOpenId", "wx_12345678" }
            }
        };
        
        var weChatResult = await processor.ProcessPayment(weChatContext);
        Console.WriteLine($"支付结果: {(weChatResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {weChatResult.TransactionId}");
        Console.WriteLine($"消息: {weChatResult.Message}");
        Console.WriteLine();
        
        // 测试退款功能
        var refundResult = await processor.RefundPayment(weChatResult.TransactionId, 20.00m);
        Console.WriteLine($"退款结果: {(refundResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"退款交易ID: {refundResult.TransactionId}");
        Console.WriteLine($"退款消息: {refundResult.Message}");
        Console.WriteLine();
        
        // 银行转账支付
        processor.SetStrategy(bankTransferStrategy);
        
        var bankContext = new PaymentContext
        {
            Amount = 1000.00m,
            Currency = "CNY",
            OrderId = "ORD-45678",
            AdditionalInfo = new Dictionary<string, string>
            {
                { "BankAccount", "1234567890" },
                { "BankName", "中国银行" },
                { "AccountName", "张三" }
            }
        };
        
        var bankResult = await processor.ProcessPayment(bankContext);
        Console.WriteLine($"支付结果: {(bankResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"交易ID: {bankResult.TransactionId}");
        Console.WriteLine($"消息: {bankResult.Message}");
        Console.WriteLine();
        
        // 测试银行转账退款(应该不支持)
        var bankRefundResult = await processor.RefundPayment(bankResult.TransactionId, 500.00m);
        Console.WriteLine($"退款结果: {(bankRefundResult.Success ? "成功" : "失败")}");
        Console.WriteLine($"退款消息: {bankRefundResult.Message}");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
编辑 (opens new window)
#pattern
上次更新: 2026/03/11, 09:10:05
行为型一
其他模式与组合使用

← 行为型一 其他模式与组合使用→

最近更新
01
鉴权服务中心
03-11
02
聚合根
03-11
03
补充
02-06
更多文章>
Theme by Vdoing | Copyright © 2019-2026 moklgy's blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式