| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # èªå¨åºåºä»»å¡åå°æå¡å®ç°è®¡å |
| | | |
| | | > **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("æ£å¨åæ¢èªå¨åºåºä»»å¡åå°æå¡..."); |
| | | 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 |
| | | - ç±»åä¸å¹é
â æ£æ¥å±æ§åç§°åç±»åæ¯å¦æ£ç¡® |
| | | |
| | | --- |
| | | |
| | | ## 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 |
| | | |
| | | --- |
| | | |
| | | ## æ
éææ¥ |
| | | |
| | | ### ç¼è¯é误 |
| | | |
| | | **é®é¢**: æ¾ä¸å°ç±»åæå½åç©ºé´ |
| | | **è§£å³**: ç¡®ä¿å·²æ·»å æ£ç¡®ç using å¼ç¨ |
| | | |
| | | **é®é¢**: ä¾èµæ³¨å
¥å¤±è´¥ |
| | | **è§£å³**: æ£æ¥ Program.cs ä¸çæå¡æ³¨åé¡ºåº |
| | | |
| | | ### è¿è¡æ¶é误 |
| | | |
| | | **é®é¢**: å尿塿²¡æå¯å¨ |
| | | **è§£å³**: |
| | | 1. æ£æ¥ `appsettings.json` ä¸ `Enable` æ¯å¦ä¸º `true` |
| | | 2. æ¥çå¯å¨æ¥å¿ä¸çéè¯¯ä¿¡æ¯ |
| | | |
| | | **é®é¢**: 没æåå»ºä»»å¡ |
| | | **è§£å³**: |
| | | 1. 确认åºåè®°å½ç `OutboundDate` å·²è¿æ |
| | | 2. 确认åºåç¶æä¸º"å
¥åºå®æ" |
| | | 3. æ£æ¥æ¯å¦å·²åå¨ç¸åæççä»»å¡ |
| | | |
| | | **é®é¢**: WCS éç¥å¤±è´¥ |
| | | **è§£å³**: |
| | | 1. æ£æ¥ WCS æå¡æ¯å¦è¿è¡ |
| | | 2. éªè¯éç¥å°åæ¯å¦æ£ç¡® |
| | | 3. 注æ: WCS éç¥å¤±è´¥ä¸å½±åä»»å¡å建 |