From ff967e1e9fa01b5c499d87a9583daf28b89279da Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 06 三月 2026 17:10:18 +0800
Subject: [PATCH] 添加自动出库任务实现计划
---
Code/WMS/WIDESEA_WMSServer/docs/plans/2026-03-06-auto-outbound-task-implementation.md | 729 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 729 insertions(+), 0 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSServer/docs/plans/2026-03-06-auto-outbound-task-implementation.md b/Code/WMS/WIDESEA_WMSServer/docs/plans/2026-03-06-auto-outbound-task-implementation.md
new file mode 100644
index 0000000..e5cac54
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/docs/plans/2026-03-06-auto-outbound-task-implementation.md
@@ -0,0 +1,729 @@
+# 鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟瀹炵幇璁″垝
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**鐩爣:** 瀹炵幇涓�涓悗鍙版湇鍔★紝鑷姩妫�娴嬪埌鏈熷簱瀛樺苟鍒涘缓鍑哄簱浠诲姟閫氱煡 WCS 绯荤粺
+
+**鏋舵瀯:** 浣跨敤 BackgroundService 妯″紡瀹炵幇瀹氭椂浠诲姟锛岄�氳繃 ITaskService 鏌ヨ鍒版湡搴撳瓨銆佸垱寤轰换鍔″苟閫氱煡 WCS
+
+**鎶�鏈爤:** .NET 6, BackgroundService, SqlSugar, Autofac, appsettings.json 閰嶇疆
+
+---
+
+## 鍓嶇疆妫�鏌�
+
+鍦ㄥ紑濮嬪疄鐜板墠锛岃纭锛�
+- 椤圭洰浣嶄簬: `d:\Git\ShanMeiXinNengYuan\Code\WMS\WIDESEA_WMSServer`
+- 涓婚」鐩枃浠�: `WIDESEA_WMSServer\WIDESEA_WMSServer.csproj`
+- 宸查槄璇昏璁℃枃妗�: `docs/plans/2026-03-06-auto-outbound-task-design.md`
+
+---
+
+## Task 1: 鍒涘缓閰嶇疆妯″瀷绫�
+
+**Files:**
+- Create: `WIDESEA_Core/Core/AutoOutboundTaskOptions.cs`
+
+**Step 1: 鍒涘缓閰嶇疆妯″瀷绫�**
+
+鍒涘缓鏂囦欢 `WIDESEA_Core/Core/AutoOutboundTaskOptions.cs`:
+
+```csharp
+using System.Collections.Generic;
+
+namespace WIDESEA_Core.Core
+{
+ /// <summary>
+ /// 鑷姩鍑哄簱浠诲姟閰嶇疆閫夐」
+ /// </summary>
+ public class AutoOutboundTaskOptions
+ {
+ /// <summary>
+ /// 鏄惁鍚敤鑷姩鍑哄簱浠诲姟
+ /// </summary>
+ public bool Enable { get; set; } = true;
+
+ /// <summary>
+ /// 妫�鏌ラ棿闅旓紙绉掞級
+ /// </summary>
+ public int CheckIntervalSeconds { get; set; } = 300;
+
+ /// <summary>
+ /// 鎸夊贩閬撳墠缂�閰嶇疆鐩爣鍦板潃
+ /// </summary>
+ public Dictionary<string, string> TargetAddresses { get; set; }
+ = new()
+ {
+ { "GW", "10081" },
+ { "CW", "10080" }
+ };
+ }
+}
+```
+
+**Step 2: 鎻愪氦閰嶇疆妯″瀷绫�**
+
+```bash
+git add WIDESEA_Core/Core/AutoOutboundTaskOptions.cs
+git commit -m "feat: 娣诲姞鑷姩鍑哄簱浠诲姟閰嶇疆妯″瀷绫�"
+```
+
+---
+
+## Task 2: 鏇存柊 appsettings.json 閰嶇疆
+
+**Files:**
+- Modify: `WIDESEA_WMSServer/appsettings.json`
+
+**Step 1: 娣诲姞閰嶇疆鑺�**
+
+鍦� `appsettings.json` 涓坊鍔� `AutoOutboundTask` 閰嶇疆鑺傦紙鍦� `WebSocketPort` 鍚庨潰锛�:
+
+```json
+{
+ ...,
+ "WebSocketPort": 9296,
+ "AutoOutboundTask": {
+ "Enable": true,
+ "CheckIntervalSeconds": 300,
+ "TargetAddresses": {
+ "GW": "10081",
+ "CW": "10080"
+ }
+ }
+}
+```
+
+**Step 2: 鎻愪氦閰嶇疆鏇存柊**
+
+```bash
+git add WIDESEA_WMSServer/appsettings.json
+git commit -m "config: 娣诲姞鑷姩鍑哄簱浠诲姟閰嶇疆"
+```
+
+---
+
+## Task 3: 鍦� ITaskService 鎺ュ彛涓坊鍔犳柟娉曞畾涔�
+
+**Files:**
+- Modify: `WIDESEA_ITaskInfoService/ITaskService.cs`
+
+**Step 1: 娣诲姞鎺ュ彛鏂规硶**
+
+鍦� `ITaskService.cs` 涓坊鍔犳柟娉曞畾涔夛紙鍦ㄦ枃浠舵湯灏撅紝`}` 涔嬪墠锛�:
+
+```csharp
+/// <summary>
+/// 鑷姩鍒涘缓鍑哄簱浠诲姟 - 鏌ヨ鍒版湡搴撳瓨骞跺垱寤轰换鍔�
+/// </summary>
+/// <returns>鍖呭惈鍒涘缓缁撴灉鐨勫搷搴斿璞�</returns>
+Task<WebResponseContent> CreateAutoOutboundTasksAsync();
+```
+
+**Step 2: 鎻愪氦鎺ュ彛鏇存柊**
+
+```bash
+git add WIDESEA_ITaskInfoService/ITaskService.cs
+git commit -m "feat: 娣诲姞鑷姩鍑哄簱浠诲姟鍒涘缓鎺ュ彛鏂规硶"
+```
+
+---
+
+## Task 4: 鍦� TaskService 涓疄鐜版牳蹇冮�昏緫
+
+**Files:**
+- Modify: `WIDESEA_TaskInfoService/TaskService.cs`
+
+**Step 1: 娣诲姞渚濊禆娉ㄥ叆瀛楁**
+
+鍦� `TaskService` 绫荤殑绉佹湁瀛楁鍖哄煙锛堢 20-25 琛岄檮杩戯級娣诲姞:
+
+```csharp
+private readonly IConfiguration _configuration;
+```
+
+淇敼鏋勯�犲嚱鏁扮鍚嶏紙绗� 37-48 琛岋級锛屾坊鍔� `IConfiguration` 鍙傛暟:
+
+```csharp
+public TaskService(
+ IRepository<Dt_Task> BaseDal,
+ IMapper mapper,
+ IStockInfoService stockInfoService,
+ ILocationInfoService locationInfoService,
+ HttpClientHelper httpClientHelper,
+ IConfiguration configuration) : base(BaseDal)
+{
+ _mapper = mapper;
+ _stockInfoService = stockInfoService;
+ _locationInfoService = locationInfoService;
+ _httpClientHelper = httpClientHelper;
+ _configuration = configuration;
+}
+```
+
+**Step 2: 娣诲姞鍦板潃鏄犲皠杈呭姪鏂规硶**
+
+鍦� `TaskService` 绫讳腑娣诲姞绉佹湁鏂规硶锛堝湪 `GetTasksByPalletCodeAsync` 鏂规硶鍚庨潰锛宍#endregion` 涔嬪墠锛�:
+
+```csharp
+/// <summary>
+/// 鏍规嵁宸烽亾纭畾鐩爣鍦板潃
+/// </summary>
+private string DetermineTargetAddress(string roadway, Dictionary<string, string> addressMap)
+{
+ if (string.IsNullOrWhiteSpace(roadway))
+ return "10080"; // 榛樿鍦板潃
+
+ foreach (var kvp in addressMap)
+ {
+ if (roadway.Contains(kvp.Key))
+ return kvp.Value;
+ }
+
+ return "10080"; // 榛樿鍦板潃
+}
+```
+
+**Step 3: 瀹炵幇鑷姩鍑哄簱浠诲姟鍒涘缓鏂规硶**
+
+鍦� `TaskService` 绫荤殑 `#endregion WCS閫昏緫澶勭悊` 涔嬪墠娣诲姞瀹屾暣鏂规硶:
+
+```csharp
+/// <summary>
+/// 鑷姩鍒涘缓鍑哄簱浠诲姟 - 鏌ヨ鍒版湡搴撳瓨骞跺垱寤轰换鍔�
+/// </summary>
+public async Task<WebResponseContent> CreateAutoOutboundTasksAsync()
+{
+ try
+ {
+ // 1. 鏌ヨ鍒版湡搴撳瓨
+ var expiredStocks = await _stockInfoService.Repository
+ .QueryAsync(s => s.OutboundDate <= DateTime.Now
+ && s.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.GetHashCode());
+
+ if (expiredStocks == null || !expiredStocks.Any())
+ {
+ return WebResponseContent.Instance.OK("鏃犲埌鏈熷簱瀛橀渶瑕佸鐞�");
+ }
+
+ // 鍔犺浇浣嶇疆璇︽儏
+ foreach (var stock in expiredStocks)
+ {
+ if (stock.LocationId > 0)
+ {
+ stock.LocationDetails = await _locationInfoService.Repository
+ .GetFirstAsync(s => s.Id == stock.LocationId);
+ }
+ }
+
+ // 杩囨护鏈変綅缃笖浣嶇疆鏈夊簱瀛樼殑璁板綍
+ expiredStocks = expiredStocks
+ .Where(s => s.LocationDetails != null
+ && s.LocationDetails.LocationStatus == LocationStatusEnum.InStock.GetHashCode())
+ .ToList();
+
+ if (!expiredStocks.Any())
+ {
+ return WebResponseContent.Instance.OK("鏃犵鍚堟潯浠剁殑鍒版湡搴撳瓨");
+ }
+
+ // 2. 妫�鏌ュ凡瀛樺湪鐨勪换鍔�
+ var palletCodes = expiredStocks.Select(s => s.PalletCode).ToList();
+ var existingTasks = await Repository.QueryAsync(t =>
+ palletCodes.Contains(t.PalletCode)
+ && (t.TaskStatus == TaskStatusEnum.New.GetHashCode()
+ || t.TaskStatus == TaskStatusEnum.Executing.GetHashCode()
+ || t.TaskStatus == TaskInStatusEnum.InNew.GetHashCode()));
+
+ var processedPallets = existingTasks.Select(t => t.PalletCode).ToHashSet();
+
+ // 3. 绛涢�夐渶瑕佸鐞嗙殑搴撳瓨
+ var stocksToProcess = expiredStocks
+ .Where(s => !processedPallets.Contains(s.PalletCode))
+ .ToList();
+
+ if (!stocksToProcess.Any())
+ {
+ return WebResponseContent.Instance.OK("鎵�鏈夊埌鏈熷簱瀛樺凡瀛樺湪浠诲姟");
+ }
+
+ // 4. 鑾峰彇閰嶇疆鐨勭洰鏍囧湴鍧�鏄犲皠
+ var targetAddressMap = _configuration.GetSection("AutoOutboundTask:TargetAddresses")
+ .Get<Dictionary<string, string>>()
+ ?? new Dictionary<string, string>();
+
+ // 5. 鎵归噺鍒涘缓浠诲姟
+ var taskList = new List<Dt_Task>();
+ foreach (var stock in stocksToProcess)
+ {
+ // 鏍规嵁宸烽亾纭畾鐩爣鍦板潃
+ var targetAddress = DetermineTargetAddress(
+ stock.LocationDetails?.RoadwayNo ?? "",
+ targetAddressMap);
+
+ var task = new Dt_Task
+ {
+ WarehouseId = stock.WarehouseId,
+ PalletCode = stock.PalletCode,
+ PalletType = stock.PalletType,
+ SourceAddress = stock.LocationCode,
+ CurrentAddress = stock.LocationCode,
+ NextAddress = targetAddress,
+ TargetAddress = targetAddress,
+ Roadway = stock.LocationDetails?.RoadwayNo ?? "",
+ TaskType = TaskTypeEnum.Outbound.GetHashCode(),
+ TaskStatus = TaskStatusEnum.New.GetHashCode(),
+ Grade = 1,
+ TaskNum = await Repository.GetTaskNo(),
+ Creater = "system_auto"
+ };
+ taskList.Add(task);
+ }
+
+ var addResult = await BaseDal.AddDataAsync(taskList) > 0;
+ if (!addResult)
+ {
+ return WebResponseContent.Instance.Error($"鎵归噺鍒涘缓浠诲姟澶辫触锛屽叡 {taskList.Count} 涓换鍔�");
+ }
+
+ // 6. 閫氱煡 WCS锛堝紓姝ワ紝涓嶅奖鍝嶄富娴佺▼锛�
+ _ = Task.Run(async () =>
+ {
+ foreach (var task in taskList)
+ {
+ try
+ {
+ var wmstaskDto = _mapper.Map<WMSTaskDTO>(task);
+ await _httpClientHelper.Post<WebResponseContent>(
+ "http://logistics-service/api/logistics/notifyoutbound",
+ JsonSerializer.Serialize(wmstaskDto));
+ }
+ catch (Exception ex)
+ {
+ // WCS 閫氱煡澶辫触涓嶅奖鍝嶄换鍔″垱寤猴紝璁板綍鏃ュ織鍗冲彲
+ Console.WriteLine($"WCS 閫氱煡澶辫触锛屼换鍔$紪鍙�: {task.TaskNum}, 閿欒: {ex.Message}");
+ }
+ }
+ });
+
+ return WebResponseContent.Instance.OK($"鎴愬姛鍒涘缓 {taskList.Count} 涓嚭搴撲换鍔�", taskList.Count);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"鑷姩鍒涘缓鍑哄簱浠诲姟澶辫触: {ex.Message}");
+ }
+}
+```
+
+**Step 4: 鎻愪氦瀹炵幇**
+
+```bash
+git add WIDESEA_TaskInfoService/TaskService.cs
+git commit -m "feat: 瀹炵幇鑷姩鍑哄簱浠诲姟鍒涘缓鏂规硶"
+```
+
+---
+
+## Task 5: 鍒涘缓鍚庡彴鏈嶅姟绫�
+
+**Files:**
+- Create: `WIDESEA_WMSServer/BackgroundServices/AutoOutboundTaskBackgroundService.cs`
+
+**Step 1: 鍒涘缓 BackgroundServices 鐩綍**
+
+```bash
+mkdir -p WIDESEA_WMSServer/BackgroundServices
+```
+
+**Step 2: 鍒涘缓鍚庡彴鏈嶅姟绫�**
+
+鍒涘缓鏂囦欢 `WIDESEA_WMSServer/BackgroundServices/AutoOutboundTaskBackgroundService.cs`:
+
+```csharp
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using WIDESEA_Core.Core;
+using WIDESEA_ITaskInfoService;
+
+namespace WIDESEA_WMSServer.BackgroundServices
+{
+ /// <summary>
+ /// 鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟
+ /// 瀹氭湡妫�鏌ュ埌鏈熷簱瀛樺苟鍒涘缓鍑哄簱浠诲姟
+ /// </summary>
+ public class AutoOutboundTaskBackgroundService : BackgroundService
+ {
+ private readonly ILogger<AutoOutboundTaskBackgroundService> _logger;
+ private readonly ITaskService _taskService;
+ private readonly AutoOutboundTaskOptions _options;
+
+ public AutoOutboundTaskBackgroundService(
+ ILogger<AutoOutboundTaskBackgroundService> logger,
+ ITaskService taskService,
+ IOptions<AutoOutboundTaskOptions> options)
+ {
+ _logger = logger;
+ _taskService = taskService;
+ _options = options.Value;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ _logger.LogInformation("鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟宸插惎鍔�");
+
+ if (!_options.Enable)
+ {
+ _logger.LogInformation("鑷姩鍑哄簱浠诲姟鍔熻兘宸茬鐢紝鏈嶅姟閫�鍑�");
+ return;
+ }
+
+ _logger.LogInformation("鑷姩鍑哄簱浠诲姟妫�鏌ラ棿闅�: {Seconds} 绉�", _options.CheckIntervalSeconds);
+
+ while (!stoppingToken.IsCancellationRequested)
+ {
+ try
+ {
+ _logger.LogDebug("寮�濮嬫鏌ュ埌鏈熷簱瀛�...");
+ var result = await _taskService.CreateAutoOutboundTasksAsync();
+
+ if (result.Status)
+ {
+ _logger.LogInformation("鍒版湡搴撳瓨妫�鏌ュ畬鎴�: {Message}", result.Message);
+ }
+ else
+ {
+ _logger.LogWarning("鍒版湡搴撳瓨妫�鏌ュけ璐�: {Message}", result.Message);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "鑷姩鍑哄簱浠诲姟鍒涘缓杩囩▼涓彂鐢熷紓甯�");
+ }
+
+ var delay = TimeSpan.FromSeconds(_options.CheckIntervalSeconds);
+ _logger.LogDebug("绛夊緟 {Seconds} 绉掑悗杩涜涓嬫妫�鏌�", delay.TotalSeconds);
+ await Task.Delay(delay, stoppingToken);
+ }
+
+ _logger.LogInformation("鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟宸插仠姝�");
+ }
+
+ public override async Task StopAsync(CancellationToken cancellationToken)
+ {
+ _logger.LogInformation("姝e湪鍋滄鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟...");
+ await base.StopAsync(cancellationToken);
+ }
+ }
+}
+```
+
+**Step 3: 鎻愪氦鍚庡彴鏈嶅姟绫�**
+
+```bash
+git add WIDESEA_WMSServer/BackgroundServices/AutoOutboundTaskBackgroundService.cs
+git commit -m "feat: 娣诲姞鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟"
+```
+
+---
+
+## Task 6: 娉ㄥ唽鏈嶅姟鍜岄厤缃�
+
+**Files:**
+- Modify: `WIDESEA_WMSServer/Program.cs`
+
+**Step 1: 娣诲姞閰嶇疆娉ㄥ唽**
+
+鍦� `Program.cs` 涓殑 `builder.Services.AddAllOptionRegister();` 涔嬪悗娣诲姞:
+
+```csharp
+builder.Services.Configure<AutoOutboundTaskOptions>(
+ builder.Configuration.GetSection("AutoOutboundTask"));
+```
+
+**Step 2: 娣诲姞鍚庡彴鏈嶅姟娉ㄥ唽**
+
+鍦� `Program.cs` 涓殑 `builder.Services.AddInitializationHostServiceSetup();` 涔嬪悗娣诲姞:
+
+```csharp
+builder.Services.AddHostedService<AutoOutboundTaskBackgroundService>();
+```
+
+**Step 3: 娣诲姞鍛藉悕绌洪棿寮曠敤**
+
+鍦� `Program.cs` 鏂囦欢椤堕儴鐨� using 鍖哄煙娣诲姞:
+
+```csharp
+using WIDESEA_WMSServer.BackgroundServices;
+using WIDESEA_Core.Core;
+```
+
+**Step 4: 鎻愪氦 Program.cs 鏇存柊**
+
+```bash
+git add WIDESEA_WMSServer/Program.cs
+git commit -m "config: 娉ㄥ唽鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟鍜岄厤缃�"
+```
+
+---
+
+## Task 7: 缂栬瘧楠岃瘉
+
+**Step 1: 缂栬瘧椤圭洰**
+
+```bash
+cd WIDESEA_WMSServer
+dotnet build --configuration Release
+```
+
+棰勬湡杈撳嚭: 缂栬瘧鎴愬姛锛屾棤閿欒
+
+**Step 2: 妫�鏌ョ紪璇戣緭鍑�**
+
+纭杈撳嚭鍖呭惈:
+```
+Build succeeded.
+ 0 Warning(s)
+ 0 Error(s)
+```
+
+**Step 3: 濡傛灉鏈夐敊璇紝鏍规嵁閿欒淇℃伅淇**
+
+甯歌闂:
+- 缂哄皯 using 寮曠敤 鈫� 娣诲姞鐩稿簲鐨� namespace
+- 绫诲瀷涓嶅尮閰� 鈫� 妫�鏌ュ睘鎬у悕绉板拰绫诲瀷鏄惁姝g‘
+
+---
+
+## Task 8: 鎵嬪姩娴嬭瘯
+
+**Step 1: 鍑嗗娴嬭瘯鏁版嵁**
+
+鍦ㄦ暟鎹簱涓墽琛� SQL锛屽垱寤轰竴鏉℃祴璇曞簱瀛樿褰�:
+
+```sql
+-- 纭繚鏈変竴涓凡鍏ュ簱鐨勫簱瀛樿褰曪紝OutboundDate 璁剧疆涓鸿繃鍘绘椂闂�
+UPDATE Dt_StockInfo
+SET OutboundDate = DATEADD(MINUTE, -5, GETDATE())
+WHERE PalletCode = 'TEST001' AND StockStatus = 1; -- 1 = 鍏ュ簱瀹屾垚
+
+-- 濡傛灉娌℃湁娴嬭瘯璁板綍锛屾彃鍏ヤ竴鏉�
+INSERT INTO Dt_StockInfo (PalletCode, PalletType, LocationId, LocationCode, WarehouseId, StockStatus, OutboundDate, CreateDate)
+VALUES ('TEST001', 1, 1, '01-01-01', 1, 1, DATEADD(MINUTE, -5, GETDATE()), GETDATE())
+```
+
+**Step 2: 鍚姩搴旂敤绋嬪簭**
+
+```bash
+cd WIDESEA_WMSServer
+dotnet run
+```
+
+**Step 3: 瑙傚療鎺у埗鍙拌緭鍑�**
+
+棰勬湡鐪嬪埌绫讳技鏃ュ織:
+```
+info: WIDESEA_WMSServer.BackgroundServices.AutoOutboundTaskBackgroundService[0]
+ 鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟宸插惎鍔�
+info: WIDESEA_WMSServer.BackgroundServices.AutoOutboundTaskBackgroundService[0]
+ 鑷姩鍑哄簱浠诲姟妫�鏌ラ棿闅�: 300 绉�
+...
+info: WIDESEA_WMSServer.BackgroundServices.AutoOutboundTaskBackgroundService[0]
+ 鍒版湡搴撳瓨妫�鏌ュ畬鎴�: 鎴愬姛鍒涘缓 X 涓嚭搴撲换鍔�
+```
+
+**Step 4: 楠岃瘉鏁版嵁搴�**
+
+鏌ヨ浠诲姟琛ㄧ‘璁や换鍔″凡鍒涘缓:
+
+```sql
+SELECT * FROM Dt_Task WHERE PalletCode = 'TEST001' AND Creater = 'system_auto'
+```
+
+**Step 5: 娴嬭瘯瀹屾垚锛屾竻鐞嗘祴璇曟暟鎹�**
+
+```sql
+-- 鍒犻櫎娴嬭瘯浠诲姟
+DELETE FROM Dt_Task WHERE PalletCode = 'TEST001'
+-- 鍒犻櫎娴嬭瘯搴撳瓨
+DELETE FROM Dt_StockInfo WHERE PalletCode = 'TEST001'
+```
+
+---
+
+## Task 9: 閰嶇疆楠岃瘉娴嬭瘯
+
+**Step 1: 娴嬭瘯绂佺敤鍔熻兘**
+
+淇敼 `appsettings.json`:
+```json
+"AutoOutboundTask": {
+ "Enable": false,
+ ...
+}
+```
+
+**Step 2: 鍚姩搴旂敤楠岃瘉**
+
+```bash
+dotnet run
+```
+
+棰勬湡杈撳嚭搴斿寘鍚�: `鑷姩鍑哄簱浠诲姟鍔熻兘宸茬鐢紝鏈嶅姟閫�鍑篳
+
+**Step 3: 鎭㈠閰嶇疆**
+
+```json
+"AutoOutboundTask": {
+ "Enable": true,
+ ...
+}
+```
+
+**Step 4: 娴嬭瘯涓嶅悓鐨勬鏌ラ棿闅�**
+
+淇敼涓� 10 绉掓柟渚胯瀵�:
+```json
+"CheckIntervalSeconds": 10
+```
+
+鍚姩搴旂敤锛岃瀵熸鏌ユ槸鍚︽寜 10 绉掗棿闅旀墽琛�
+
+**Step 5: 鎻愪氦娴嬭瘯缁撹**
+
+鍒涘缓娴嬭瘯璇存槑鏂囦欢 `WIDESEA_WMSServer/BackgroundServices/README.md`:
+
+```markdown
+# 鑷姩鍑哄簱浠诲姟鍚庡彴鏈嶅姟
+
+## 鍔熻兘璇存槑
+鏈湇鍔¤嚜鍔ㄦ娴嬪埌鏈熷簱瀛樺苟鍒涘缓鍑哄簱浠诲姟銆�
+
+## 閰嶇疆
+鍦� `appsettings.json` 涓厤缃�:
+
+```json
+{
+ "AutoOutboundTask": {
+ "Enable": true,
+ "CheckIntervalSeconds": 300,
+ "TargetAddresses": {
+ "GW": "10081",
+ "CW": "10080"
+ }
+ }
+}
+```
+
+## 娴嬭瘯鏂规硶
+1. 璁剧疆搴撳瓨鐨� OutboundDate 涓鸿繃鍘绘椂闂�
+2. 鍚姩搴旂敤锛岃瀵熸棩蹇�
+3. 纭浠诲姟宸插垱寤哄埌鏁版嵁搴�
+```
+
+**Step 6: 鎻愪氦娴嬭瘯鏂囨。**
+
+```bash
+git add WIDESEA_WMSServer/BackgroundServices/README.md
+git commit -m "docs: 娣诲姞鍚庡彴鏈嶅姟娴嬭瘯璇存槑"
+```
+
+---
+
+## Task 10: 鏈�缁堥獙璇佸拰鏂囨。
+
+**Step 1: 杩愯瀹屾暣缂栬瘧**
+
+```bash
+cd ..
+dotnet build WIDESEA_WMSServer/WIDESEA_WMSServer.csproj --configuration Release
+```
+
+**Step 2: 纭鎵�鏈夋枃浠跺凡鎻愪氦**
+
+```bash
+git status
+```
+
+搴旇鐪嬪埌: `nothing to commit, working tree clean`
+
+**Step 3: 鏌ョ湅鎻愪氦鍘嗗彶**
+
+```bash
+git log --oneline -10
+```
+
+**Step 4: 鍒涘缓鍔熻兘鎬荤粨**
+
+鏇存柊璁捐鏂囨。锛屾坊鍔犲疄鏂界姸鎬�:
+
+鍦� `docs/plans/2026-03-06-auto-outbound-task-design.md` 鏈熬娣诲姞:
+
+```markdown
+## 瀹炴柦鐘舵��
+
+- [x] 璁捐瀹屾垚
+- [x] 閰嶇疆妯″瀷绫诲垱寤�
+- [x] TaskService 鏂规硶瀹炵幇
+- [x] 鍚庡彴鏈嶅姟绫诲垱寤�
+- [x] Program.cs 娉ㄥ唽瀹屾垚
+- [x] 缂栬瘧楠岃瘉閫氳繃
+- [x] 鎵嬪姩娴嬭瘯瀹屾垚
+
+**瀹炴柦鏃ユ湡**: 2026-03-06
+**瀹炴柦浜�**: Claude Code
+```
+
+**Step 5: 鎻愪氦鏂囨。鏇存柊**
+
+```bash
+git add docs/plans/2026-03-06-auto-outbound-task-design.md
+git commit -m "docs: 鏇存柊璁捐鏂囨。瀹炴柦鐘舵��"
+```
+
+---
+
+## 瀹屾垚妫�鏌ユ竻鍗�
+
+- [ ] 鎵�鏈変唬鐮佹枃浠跺凡鍒涘缓
+- [ ] 鎵�鏈変唬鐮佸凡缂栬瘧閫氳繃
+- [ ] 閰嶇疆鏂囦欢宸叉洿鏂�
+- [ ] 鎵嬪姩娴嬭瘯宸插畬鎴�
+- [ ] 鏃ュ織杈撳嚭绗﹀悎棰勬湡
+- [ ] 鏁版嵁搴撻獙璇侀�氳繃
+- [ ] 鏂囨。宸叉洿鏂�
+- [ ] 鎵�鏈夋洿鏀瑰凡鎻愪氦鍒� git
+
+---
+
+## 鏁呴殰鎺掓煡
+
+### 缂栬瘧閿欒
+
+**闂**: 鎵句笉鍒扮被鍨嬫垨鍛藉悕绌洪棿
+**瑙e喅**: 纭繚宸叉坊鍔犳纭殑 using 寮曠敤
+
+**闂**: 渚濊禆娉ㄥ叆澶辫触
+**瑙e喅**: 妫�鏌� Program.cs 涓殑鏈嶅姟娉ㄥ唽椤哄簭
+
+### 杩愯鏃堕敊璇�
+
+**闂**: 鍚庡彴鏈嶅姟娌℃湁鍚姩
+**瑙e喅**:
+1. 妫�鏌� `appsettings.json` 涓� `Enable` 鏄惁涓� `true`
+2. 鏌ョ湅鍚姩鏃ュ織涓殑閿欒淇℃伅
+
+**闂**: 娌℃湁鍒涘缓浠诲姟
+**瑙e喅**:
+1. 纭搴撳瓨璁板綍鐨� `OutboundDate` 宸茶繃鏈�
+2. 纭搴撳瓨鐘舵�佷负"鍏ュ簱瀹屾垚"
+3. 妫�鏌ユ槸鍚﹀凡瀛樺湪鐩稿悓鎵樼洏鐨勪换鍔�
+
+**闂**: WCS 閫氱煡澶辫触
+**瑙e喅**:
+1. 妫�鏌� WCS 鏈嶅姟鏄惁杩愯
+2. 楠岃瘉閫氱煡鍦板潃鏄惁姝g‘
+3. 娉ㄦ剰: WCS 閫氱煡澶辫触涓嶅奖鍝嶄换鍔″垱寤�
--
Gitblit v1.9.3