From bfd4fd8e4a05a681ec10a47992294cf752a764c4 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期一, 02 三月 2026 15:10:58 +0800
Subject: [PATCH] 添加Redis服务与缓存增强

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBitmapService.cs                     |   46 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/IDistributedLockService.cs                  |   34 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/RedisCacheService.cs                       |  174 ++
 Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json                            |  191 ++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/RedisLeaderboardService.cs           |   75 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBloomFilterService.cs                |   96 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/ISessionStorage.cs                       |   12 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/RedisRateLimitingService.cs         |  113 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/RedisGeoLocationService.cs                   |   65 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/RedisConfigurationCenterService.cs |   65 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/IConfigurationCenterService.cs     |   30 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json                                       |   47 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/IRedisMonitorService.cs               |   39 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/NewtonsoftRedisSerializer.cs       |   31 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/RedisDelayQueueService.cs             |   60 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/IGeoLocationService.cs                       |   43 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/RedisSessionStorage.cs                   |   63 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/RedisMessageQueueService.cs               |   64 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/IRedisConnectionManager.cs            |   17 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs                                   |   39 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj                               |    5 
 Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.backup.json                     |  149 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs                 |   11 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/ICacheService.cs                                  |   49 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/RedisDistributedIdGenerator.cs       |   56 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/WIDESEAWCS_RedisService.csproj                   |   21 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLine/CheckPalletPosition.cs  |    9 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/MemoryCacheService.cs                             |   75 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs                                 |    7 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/RedisStreamProcessingService.cs           |   76 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/IDistributedIdGenerator.cs           |   25 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Extensions/RedisServiceSetup.cs                  |   77 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/IRedisSerializer.cs                |   11 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Http/HTTP/HttpClientHelper.cs                            |    6 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/IMessageQueueService.cs                   |   35 
 Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json                            |  134 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/RedisDistributedLockService.cs              |  112 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Options/RedisOptions.cs                          |   49 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/RedisConnectionManager.cs             |  111 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs          |   47 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/RedisCounterService.cs                   |   57 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/HybridCacheService.cs                      |  266 ++++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/ILeaderboardService.cs               |   52 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/ICounterService.cs                       |   30 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/IRateLimitingService.cs             |   25 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/IBitmapService.cs                         |   28 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/IDelayQueueService.cs                 |   25 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs                                             |   44 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs                                    |  149 +-
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/RedisObjectStorageService.cs             |   71 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/RedisMonitorService.cs                |   91 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/IObjectStorageService.cs                 |   40 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln                                                    |  178 ++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Redis使用案例.md                                           |  380 +++++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/IStreamProcessingService.cs               |   41 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs                              |    3 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs                            |   78 
 57 files changed, 3,668 insertions(+), 259 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
index e593f80..1b17578 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
@@ -5,6 +5,50 @@
     {
       "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\robotjob\\robotjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\robotjob\\robotjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\socketserver\\tcpsocketserver.clients.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\socketserver\\tcpsocketserver.clients.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_redisservice\\cache\\hybridcacheservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|solutionrelative:wideseawcs_redisservice\\cache\\hybridcacheservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_redisservice\\connection\\redisconnectionmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|solutionrelative:wideseawcs_redisservice\\connection\\redisconnectionmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_server\\appsettings.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}",
+      "RelativeMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|solutionrelative:wideseawcs_server\\appsettings.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_redisservice\\extensions\\redisservicesetup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|solutionrelative:wideseawcs_redisservice\\extensions\\redisservicesetup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_redisservice\\cache\\rediscacheservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{F9886971-C3B2-4334-B014-D5109F2041DE}|WIDESEAWCS_RedisService\\WIDESEAWCS_RedisService.csproj|solutionrelative:wideseawcs_redisservice\\cache\\rediscacheservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_server\\redis\u4F7F\u7528\u6848\u4F8B.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}",
+      "RelativeMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|solutionrelative:wideseawcs_server\\redis\u4F7F\u7528\u6848\u4F8B.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_server\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}|WIDESEAWCS_Server\\WIDESEAWCS_Server.csproj|solutionrelative:wideseawcs_server\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}|WIDESEAWCS_Core\\WIDESEAWCS_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_core\\http\\http\\httpclienthelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}|WIDESEAWCS_Core\\WIDESEAWCS_Core.csproj|solutionrelative:wideseawcs_core\\http\\http\\httpclienthelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\conveyorlinenewjob\\conveyorline\\checkpalletposition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\conveyorlinenewjob\\conveyorline\\checkpalletposition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\conveyorlinenewjob\\commonconveyorlinenewjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\conveyorlinenewjob\\commonconveyorlinenewjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -14,7 +58,7 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 3,
+          "SelectedChildIndex": 14,
           "Children": [
             {
               "$type": "Bookmark",
@@ -30,13 +74,156 @@
             },
             {
               "$type": "Document",
+              "DocumentIndex": 1,
+              "Title": "TcpSocketServer.Clients.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+              "ViewState": "AgIAAEkAAAAAAAAAAAAIwAkAAAAZAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T04:08:38.428Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 3,
+              "Title": "RedisConnectionManager.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Connection\\RedisConnectionManager.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_RedisService\\Connection\\RedisConnectionManager.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Connection\\RedisConnectionManager.cs",
+              "RelativeToolTip": "WIDESEAWCS_RedisService\\Connection\\RedisConnectionManager.cs",
+              "ViewState": "AgIAAD0AAAAAAAAAAAAuwE8AAAAIAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T03:52:53.567Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 2,
+              "Title": "HybridCacheService.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Cache\\HybridCacheService.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_RedisService\\Cache\\HybridCacheService.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Cache\\HybridCacheService.cs",
+              "RelativeToolTip": "WIDESEAWCS_RedisService\\Cache\\HybridCacheService.cs",
+              "ViewState": "AgIAAOkAAAAAAAAAAAAqwPoAAAAjAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T03:39:18.734Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 5,
+              "Title": "RedisServiceSetup.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Extensions\\RedisServiceSetup.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_RedisService\\Extensions\\RedisServiceSetup.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Extensions\\RedisServiceSetup.cs",
+              "RelativeToolTip": "WIDESEAWCS_RedisService\\Extensions\\RedisServiceSetup.cs",
+              "ViewState": "AgIAADgAAAAAAAAAAAAmwCIAAAAMAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T03:33:54.548Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 8,
+              "Title": "Program.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\Program.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Server\\Program.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\Program.cs",
+              "RelativeToolTip": "WIDESEAWCS_Server\\Program.cs",
+              "ViewState": "AgIAACQAAAAAAAAAAAAqwDYAAAAeAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T03:16:21.765Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 6,
+              "Title": "RedisCacheService.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Cache\\RedisCacheService.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_RedisService\\Cache\\RedisCacheService.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_RedisService\\Cache\\RedisCacheService.cs",
+              "RelativeToolTip": "WIDESEAWCS_RedisService\\Cache\\RedisCacheService.cs",
+              "ViewState": "AgIAABoAAAAAAAAAAAAmwCkAAAAoAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T03:06:06.952Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 7,
+              "Title": "Redis\u4F7F\u7528\u6848\u4F8B.md",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\Redis\u4F7F\u7528\u6848\u4F8B.md",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Server\\Redis\u4F7F\u7528\u6848\u4F8B.md",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\Redis\u4F7F\u7528\u6848\u4F8B.md",
+              "RelativeToolTip": "WIDESEAWCS_Server\\Redis\u4F7F\u7528\u6848\u4F8B.md",
+              "ViewState": "AgIAAAgBAAAAAAAAAAAAABcBAAAPAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|",
+              "WhenOpened": "2026-03-02T02:59:29.028Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 9,
+              "Title": "HttpClientHelper.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Core\\Http\\HTTP\\HttpClientHelper.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Core\\Http\\HTTP\\HttpClientHelper.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Core\\Http\\HTTP\\HttpClientHelper.cs",
+              "RelativeToolTip": "WIDESEAWCS_Core\\Http\\HTTP\\HttpClientHelper.cs",
+              "ViewState": "AgIAABQAAAAAAAAAAADwvygAAABLAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-03-02T02:58:50.075Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 10,
+              "Title": "CheckPalletPosition.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\ConveyorLineNewJob\\ConveyorLine\\CheckPalletPosition.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\ConveyorLineNewJob\\ConveyorLine\\CheckPalletPosition.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\ConveyorLineNewJob\\ConveyorLine\\CheckPalletPosition.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\ConveyorLineNewJob\\ConveyorLine\\CheckPalletPosition.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAeAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-02-28T08:42:47.236Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 4,
+              "Title": "appsettings.json",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\appsettings.json",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Server\\appsettings.json",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Server\\appsettings.json",
+              "RelativeToolTip": "WIDESEAWCS_Server\\appsettings.json",
+              "ViewState": "AgIAACUAAAAAAAAAAAAYwCsAAAAeAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
+              "WhenOpened": "2026-02-28T05:50:10.851Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 11,
+              "Title": "CommonConveyorLineNewJob.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\ConveyorLineNewJob\\CommonConveyorLineNewJob.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\ConveyorLineNewJob\\CommonConveyorLineNewJob.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\ConveyorLineNewJob\\CommonConveyorLineNewJob.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\ConveyorLineNewJob\\CommonConveyorLineNewJob.cs",
+              "ViewState": "AgIAAEoAAAAAAAAAAAAAwGAAAABTAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-02-28T05:48:06.526Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
               "DocumentIndex": 0,
               "Title": "RobotJob.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
               "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
               "RelativeToolTip": "WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
-              "ViewState": "AgIAAAEAAAAAAAAAAAAuwBoAAAAAAAAAAAAAAA==",
+              "ViewState": "AgIAADgAAAAAAAAAAAAtwEIAAAAPAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-05T05:38:04.031Z",
               "EditorCaption": ""
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/ICacheService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/ICacheService.cs
index 2c076d7..d733532 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/ICacheService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/ICacheService.cs
@@ -60,5 +60,54 @@
         /// <param name="key">缂撳瓨Key</param>
         /// <returns></returns>
         string? Get(string key);
+
+        #region ConcurrentDictionary椋庢牸鏂规硶
+
+        /// <summary>
+        /// 灏濊瘯娣诲姞锛屼粎褰揔ey涓嶅瓨鍦ㄦ椂娣诲姞鎴愬姛
+        /// </summary>
+        bool TryAdd(string key, string value, int expireSeconds = -1);
+
+        /// <summary>
+        /// 灏濊瘯娣诲姞瀵硅薄锛屼粎褰揔ey涓嶅瓨鍦ㄦ椂娣诲姞鎴愬姛
+        /// </summary>
+        bool TryAdd<T>(string key, T value, int expireSeconds = -1) where T : class;
+
+        /// <summary>
+        /// 灏濊瘯鑾峰彇鍊硷紝杩斿洖鏄惁瀛樺湪
+        /// </summary>
+        bool TryGetValue(string key, out string? value);
+
+        /// <summary>
+        /// 灏濊瘯鑾峰彇瀵硅薄锛岃繑鍥炴槸鍚﹀瓨鍦�
+        /// </summary>
+        bool TryGetValue<T>(string key, out T? value) where T : class;
+
+        /// <summary>
+        /// 灏濊瘯绉婚櫎骞惰繑鍥炶绉婚櫎鐨勫��
+        /// </summary>
+        bool TryRemove(string key, out string? value);
+
+        /// <summary>
+        /// 灏濊瘯鏇存柊锛屼粎褰揔ey瀛樺湪鏃舵洿鏂�
+        /// </summary>
+        bool TryUpdate(string key, string newValue, int expireSeconds = -1);
+
+        /// <summary>
+        /// 鑾峰彇鎴栨坊鍔狅細Key瀛樺湪鍒欒繑鍥炵幇鏈夊�硷紝涓嶅瓨鍦ㄥ垯娣诲姞骞惰繑鍥炴柊鍊�
+        /// </summary>
+        string GetOrAdd(string key, string value, int expireSeconds = -1);
+
+        /// <summary>
+        /// 鑾峰彇鎴栨坊鍔狅紙宸ュ巶鏂规硶锛夛細Key瀛樺湪鍒欒繑鍥炵幇鏈夊�硷紝涓嶅瓨鍦ㄥ垯閫氳繃宸ュ巶鏂规硶鐢熸垚鍊煎苟娣诲姞
+        /// </summary>
+        string GetOrAdd(string key, Func<string, string> valueFactory, int expireSeconds = -1);
+
+        /// <summary>
+        /// 鑾峰彇鎴栨坊鍔犲璞�
+        /// </summary>
+        T GetOrAdd<T>(string key, Func<string, T> valueFactory, int expireSeconds = -1) where T : class;
+
+        #endregion
     }
 }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/MemoryCacheService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/MemoryCacheService.cs
index ce7a585..5f6d4ef 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/MemoryCacheService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Caches/MemoryCacheService.cs
@@ -144,5 +144,80 @@
 
             keys.ToList().ForEach(item => _cache.Remove(item));
         }
+
+        public bool TryAdd(string key, string value, int expireSeconds = -1)
+        {
+            if (Exists(key)) return false;
+            return Add(key, value, expireSeconds);
+        }
+
+        public bool TryAdd<T>(string key, T value, int expireSeconds = -1) where T : class
+        {
+            if (Exists(key)) return false;
+            return AddObject(key, value, expireSeconds);
+        }
+
+        public bool TryGetValue(string key, out string? value)
+        {
+            value = _cache.Get(key)?.ToString();
+            return value != null;
+        }
+
+        public bool TryGetValue<T>(string key, out T? value) where T : class
+        {
+            if (_cache.TryGetValue(key, out object? obj) && obj != null)
+            {
+                value = obj as T ?? JsonConvert.DeserializeObject<T>(obj.ToString() ?? "");
+                return value != null;
+            }
+            value = default;
+            return false;
+        }
+
+        public bool TryRemove(string key, out string? value)
+        {
+            value = _cache.Get(key)?.ToString();
+            if (value == null) return false;
+            _cache.Remove(key);
+            return true;
+        }
+
+        public bool TryUpdate(string key, string newValue, int expireSeconds = -1)
+        {
+            if (!Exists(key)) return false;
+            Remove(key);
+            Add(key, newValue, expireSeconds);
+            return true;
+        }
+
+        public string GetOrAdd(string key, string value, int expireSeconds = -1)
+        {
+            var existing = _cache.Get(key)?.ToString();
+            if (existing != null) return existing;
+            Add(key, value, expireSeconds);
+            return value;
+        }
+
+        public string GetOrAdd(string key, Func<string, string> valueFactory, int expireSeconds = -1)
+        {
+            var existing = _cache.Get(key)?.ToString();
+            if (existing != null) return existing;
+            var value = valueFactory(key);
+            Add(key, value, expireSeconds);
+            return value;
+        }
+
+        public T GetOrAdd<T>(string key, Func<string, T> valueFactory, int expireSeconds = -1) where T : class
+        {
+            if (_cache.TryGetValue(key, out object? obj) && obj != null)
+            {
+                if (obj is T t) return t;
+                var deserialized = JsonConvert.DeserializeObject<T>(obj.ToString() ?? "");
+                if (deserialized != null) return deserialized;
+            }
+            var value = valueFactory(key);
+            AddObject(key, value, expireSeconds);
+            return value;
+        }
     }
 }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Http/HTTP/HttpClientHelper.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Http/HTTP/HttpClientHelper.cs
index fc0cd5b..4b08204 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Http/HTTP/HttpClientHelper.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Http/HTTP/HttpClientHelper.cs
@@ -10,16 +10,19 @@
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 using Newtonsoft.Json;
+using WIDESEAWCS_Core.Caches;
 
 namespace WIDESEA_Core
 {
     public class HttpClientHelper
     {
         private readonly IHttpClientFactory _httpClientFactory;
+        private readonly ICacheService _cache;
 
-        public HttpClientHelper(IHttpClientFactory httpClientFactory, IConfiguration configuration = null)
+        public HttpClientHelper(IHttpClientFactory httpClientFactory, ICacheService cache, IConfiguration configuration = null)
         {
             _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
+            _cache = cache ?? throw new ArgumentNullException(nameof(cache));
         }
 
         /// <summary>
@@ -32,6 +35,7 @@
         /// <returns></returns>
         public HttpResponseResult Post(string url, string content, string contentType = "application/json", HttpRequestConfig? config = null)
         {
+            url = _cache.Get(url);
             HttpResponseResult httpResponseResult = ExecuteAsync(async (client) =>
             {
                 var request = new HttpRequestMessage(HttpMethod.Post, url);
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
index 3cdd283..c63f06e 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
@@ -11,6 +11,7 @@
 using WIDESEAWCS_DTO.BasicInfo;
 using WIDESEAWCS_QuartzJob.Models;
 using WIDESEAWCS_QuartzJob.Repository;
+using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
 
 namespace WIDESEAWCS_QuartzJob.Service
 {
@@ -21,6 +22,7 @@
     {
         private readonly IDeviceProtocolRepository _deviceProtocolRepository;
         private readonly IDeviceInfoRepository _deviceInfoRepository;
+        private readonly ICacheService _cacheService;
 
         /// <summary>
         /// 璺敱閰嶇疆涓氬姟灞�
@@ -28,10 +30,11 @@
         /// <param name="BaseDal"></param>
         /// <param name="deviceProtocolRepository"></param>
         /// <param name="deviceInfoRepository"></param>
-        public RouterService(IRouterRepository BaseDal, IDeviceProtocolRepository deviceProtocolRepository, IDeviceInfoRepository deviceInfoRepository) : base(BaseDal)
+        public RouterService(IRouterRepository BaseDal, IDeviceProtocolRepository deviceProtocolRepository, IDeviceInfoRepository deviceInfoRepository, ICacheService cacheService) : base(BaseDal)
         {
             _deviceProtocolRepository = deviceProtocolRepository;
             _deviceInfoRepository = deviceInfoRepository;
+            _cacheService = cacheService;
         }
 
         /// <summary>
@@ -47,10 +50,10 @@
             {
                 // 涓�娆℃�ф煡璇㈡墍鏈夎矾鐢辨暟鎹埌鍐呭瓨
                 List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
-                
+
                 // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
                 routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
-                
+
                 if (routers.Count == 0)
                 {
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
@@ -77,10 +80,10 @@
             {
                 // 涓�娆℃�ф煡璇㈡寚瀹氱被鍨嬬殑鎵�鏈夎矾鐢辨暟鎹埌鍐呭瓨
                 List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
-                
+
                 // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
                 routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
-                
+
                 if (routers.Count == 0)
                 {
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
@@ -110,7 +113,7 @@
             var routersByNext = allRouters
                 .GroupBy(r => r.NextPosi)
                 .ToDictionary(g => g.Key, g => g.ToList());
-            
+
             var routersByChild = allRouters
                 .GroupBy(r => r.ChildPosi)
                 .ToDictionary(g => g.Key, g => g.ToList());
@@ -127,7 +130,7 @@
 
             // 浣跨敤闃熷垪杩涜骞垮害浼樺厛鎼滅储
             Queue<(Dt_Router router, List<Dt_Router> path)> queue = new Queue<(Dt_Router, List<Dt_Router>)>();
-            
+
             // 灏嗘墍鏈夌粓鐐硅矾鐢卞姞鍏ラ槦鍒�
             foreach (var endRouter in endRouters)
             {
@@ -186,9 +189,9 @@
             try
             {
                 // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎵�鏈夎矾鐢�
-                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi, 
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi,
                     new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                
+
                 // 杩斿洖绗竴涓矾鐢�
                 return routes.FirstOrDefault();
             }
@@ -210,9 +213,9 @@
             try
             {
                 // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
-                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType, 
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType,
                     new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                
+
                 // 杩斿洖绗竴涓矾鐢�
                 return routes.FirstOrDefault();
             }
@@ -235,9 +238,9 @@
             try
             {
                 // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
-                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType, 
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType,
                     new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                
+
                 if (routes.Count == 0)
                     return null;
 
@@ -278,7 +281,7 @@
             List<Dt_Router> path = new List<Dt_Router>();
             string currentPosi = startPosi;
             HashSet<string> visitedPositions = new HashSet<string>();
-            
+
             try
             {
                 while (currentPosi != endPosi)
@@ -290,21 +293,21 @@
                     visitedPositions.Add(currentPosi);
 
                     Dt_Router nextRoute = QueryNextRoute(currentPosi, endPosi, routeType);
-                    
+
                     if (nextRoute == null)
                     {
                         break;
                     }
-                    
+
                     path.Add(nextRoute);
                     currentPosi = nextRoute.NextPosi;
-                    
+
                     if (path.Count > 1000)
                     {
                         break;
                     }
                 }
-                
+
                 if (currentPosi != endPosi)
                 {
                     return new List<Dt_Router>();
@@ -314,7 +317,7 @@
             {
                 return new List<Dt_Router>();
             }
-            
+
             return path;
         }
 
@@ -327,24 +330,31 @@
         {
             // 鍒涘缓涓�涓瓧绗︿覆鍒楄〃锛岀敤浜庡瓨鍌ㄦ墍鏈変綅缃�
             List<string> positions = new List<string>();
-            try
-            {
-                // 鏌ヨ鎵�鏈夎繘鍏ヨ矾鐢卞櫒鐨勪綅缃�
-                List<string> inRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.In.ObjToInt()).GroupBy(x => x.StartPosi).Select(x => x.Key).ToList();
-
-                // 鏌ヨ鎵�鏈夌寮�璺敱鍣ㄧ殑浣嶇疆
-                List<string> outRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.Out.ObjToInt()).GroupBy(x => x.ChildPosi).Select(x => x.Key).ToList();
-
-                // 灏嗚繘鍏ュ拰绂诲紑璺敱鍣ㄧ殑浣嶇疆娣诲姞鍒板垪琛ㄤ腑
-                positions.AddRange(inRouterPositions);
-                positions.AddRange(outRouterPositions);
-                // 杩斿洖鍘婚噸鍚庣殑浣嶇疆鍒楄〃
-                return positions.GroupBy(x => x).Select(x => x.Key).ToList();
-            }
-            catch
+            var device = _cacheService.Get<List<string>>($"DevicePositions:{deviceCode}");
+            if (device.IsNullOrEmpty())
             {
 
+                try
+                {
+                    // 鏌ヨ鎵�鏈夎繘鍏ヨ矾鐢卞櫒鐨勪綅缃�
+                    List<string> inRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.In.ObjToInt()).GroupBy(x => x.StartPosi).Select(x => x.Key).ToList();
+
+                    // 鏌ヨ鎵�鏈夌寮�璺敱鍣ㄧ殑浣嶇疆
+                    List<string> outRouterPositions = BaseDal.QueryData(x => x.ChildPosiDeviceCode == deviceCode && x.InOutType == RouterInOutType.Out.ObjToInt()).GroupBy(x => x.ChildPosi).Select(x => x.Key).ToList();
+
+                    // 灏嗚繘鍏ュ拰绂诲紑璺敱鍣ㄧ殑浣嶇疆娣诲姞鍒板垪琛ㄤ腑
+                    positions.AddRange(inRouterPositions);
+                    positions.AddRange(outRouterPositions);
+                    // 杩斿洖鍘婚噸鍚庣殑浣嶇疆鍒楄〃
+                    return positions.GroupBy(x => x).Select(x => x.Key).ToList();
+                }
+                catch
+                {
+
+                }
             }
+            else 
+                positions = device;
             // 杩斿洖浣嶇疆鍒楄〃
             return positions;
         }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/IBitmapService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/IBitmapService.cs
new file mode 100644
index 0000000..9351b73
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/IBitmapService.cs
@@ -0,0 +1,28 @@
+namespace WIDESEAWCS_RedisService.Bitmap
+{
+    public interface IBitmapService
+    {
+        bool SetBit(string key, long offset, bool value);
+        bool GetBit(string key, long offset);
+        long BitCount(string key);
+        long BitCount(string key, long start, long end);
+    }
+
+    public interface IBloomFilterService
+    {
+        /// <summary>
+        /// 娣诲姞鍏冪礌鍒板竷闅嗚繃婊ゅ櫒
+        /// </summary>
+        void Add(string filterName, string value);
+
+        /// <summary>
+        /// 妫�鏌ュ厓绱犳槸鍚﹀彲鑳藉瓨鍦�
+        /// </summary>
+        bool MayExist(string filterName, string value);
+
+        /// <summary>
+        /// 鎵归噺娣诲姞
+        /// </summary>
+        void AddRange(string filterName, IEnumerable<string> values);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBitmapService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBitmapService.cs
new file mode 100644
index 0000000..b0b5d73
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBitmapService.cs
@@ -0,0 +1,46 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Bitmap
+{
+    public class RedisBitmapService : IBitmapService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisBitmapService> _logger;
+
+        public RedisBitmapService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisBitmapService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}bitmap:{key}";
+
+        public bool SetBit(string key, long offset, bool value)
+        {
+            return _connectionManager.GetDatabase().StringSetBit(BuildKey(key), offset, value);
+        }
+
+        public bool GetBit(string key, long offset)
+        {
+            return _connectionManager.GetDatabase().StringGetBit(BuildKey(key), offset);
+        }
+
+        public long BitCount(string key)
+        {
+            return _connectionManager.GetDatabase().StringBitCount(BuildKey(key));
+        }
+
+        public long BitCount(string key, long start, long end)
+        {
+            return _connectionManager.GetDatabase().StringBitCount(BuildKey(key), start, end);
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBloomFilterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBloomFilterService.cs
new file mode 100644
index 0000000..b329731
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Bitmap/RedisBloomFilterService.cs
@@ -0,0 +1,96 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+using System.Text;
+
+namespace WIDESEAWCS_RedisService.Bitmap
+{
+    public class RedisBloomFilterService : IBloomFilterService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisBloomFilterService> _logger;
+        private const int HashCount = 5;
+        private const long BitSize = 1_000_000;
+
+        public RedisBloomFilterService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisBloomFilterService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}bloom:{key}";
+
+        public void Add(string filterName, string value)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(filterName);
+            var offsets = GetHashOffsets(value);
+            foreach (var offset in offsets)
+                db.StringSetBit(fullKey, offset, true);
+        }
+
+        public bool MayExist(string filterName, string value)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(filterName);
+            var offsets = GetHashOffsets(value);
+            return offsets.All(offset => db.StringGetBit(fullKey, offset));
+        }
+
+        public void AddRange(string filterName, IEnumerable<string> values)
+        {
+            foreach (var value in values) Add(filterName, value);
+        }
+
+        private long[] GetHashOffsets(string value)
+        {
+            var offsets = new long[HashCount];
+            var bytes = Encoding.UTF8.GetBytes(value);
+            for (int i = 0; i < HashCount; i++)
+            {
+                uint hash = MurmurHash(bytes, (uint)i);
+                offsets[i] = hash % BitSize;
+            }
+            return offsets;
+        }
+
+        private static uint MurmurHash(byte[] data, uint seed)
+        {
+            const uint c1 = 0xcc9e2d51;
+            const uint c2 = 0x1b873593;
+            uint h1 = seed;
+            int len = data.Length;
+            int blocks = len / 4;
+
+            for (int i = 0; i < blocks; i++)
+            {
+                uint k1 = BitConverter.ToUInt32(data, i * 4);
+                k1 *= c1; k1 = RotateLeft(k1, 15); k1 *= c2;
+                h1 ^= k1; h1 = RotateLeft(h1, 13); h1 = h1 * 5 + 0xe6546b64;
+            }
+
+            uint tail = 0;
+            int tailIdx = blocks * 4;
+            switch (len & 3)
+            {
+                case 3: tail ^= (uint)data[tailIdx + 2] << 16; goto case 2;
+                case 2: tail ^= (uint)data[tailIdx + 1] << 8; goto case 1;
+                case 1: tail ^= data[tailIdx]; tail *= c1; tail = RotateLeft(tail, 15); tail *= c2; h1 ^= tail; break;
+            }
+
+            h1 ^= (uint)len;
+            h1 ^= h1 >> 16; h1 *= 0x85ebca6b;
+            h1 ^= h1 >> 13; h1 *= 0xc2b2ae35;
+            h1 ^= h1 >> 16;
+            return h1;
+        }
+
+        private static uint RotateLeft(uint x, byte r) => (x << r) | (x >> (32 - r));
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/HybridCacheService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/HybridCacheService.cs
new file mode 100644
index 0000000..55c3c22
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/HybridCacheService.cs
@@ -0,0 +1,266 @@
+using Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_Core.Caches;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+using WIDESEAWCS_RedisService.Serialization;
+
+namespace WIDESEAWCS_RedisService.Cache
+{
+    public class HybridCacheService : ICacheService
+    {
+        private readonly IMemoryCache _memoryCache;
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly IRedisSerializer _serializer;
+        private readonly RedisOptions _options;
+        private readonly ILogger<HybridCacheService> _logger;
+        private bool _disposed;
+
+        private bool RedisAvailable => _connectionManager.IsConnected;
+
+        public HybridCacheService(
+            IMemoryCache memoryCache,
+            IRedisConnectionManager connectionManager,
+            IRedisSerializer serializer,
+            IOptions<RedisOptions> options,
+            ILogger<HybridCacheService> logger)
+        {
+            _memoryCache = memoryCache;
+            _connectionManager = connectionManager;
+            _serializer = serializer;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}{key}";
+
+        public bool Exists(string key)
+        {
+            if (_memoryCache.TryGetValue(BuildKey(key), out _)) return true;
+            if (!RedisAvailable) return false;
+            try
+            {
+                return _connectionManager.GetDatabase().KeyExists(BuildKey(key));
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Exists澶辫触, key={Key}", key);
+                return false;
+            }
+        }
+
+        public bool Add(string key, string value, int expireSeconds = -1, bool isSliding = false)
+        {
+            var fullKey = BuildKey(key);
+            SetMemoryCache(fullKey, value, expireSeconds, isSliding);
+            if (!RedisAvailable)
+            {
+                _logger.LogWarning("Redis涓嶅彲鐢紝浠呬娇鐢ㄥ唴瀛樼紦瀛�, key={Key}", key);
+                return true;
+            }
+            try
+            {
+                var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+                var result = _connectionManager.GetDatabase().StringSet(fullKey, value, expiry);
+                _logger.LogInformation("Redis鍐欏叆鎴愬姛: key={Key}, result={Result}", fullKey, result);
+                return result;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Add澶辫触, key={Key}", key);
+                return _options.FallbackToMemory;
+            }
+        }
+
+        public bool AddObject(string key, object value, int expireSeconds = -1, bool isSliding = false)
+        {
+            return Add(key, _serializer.Serialize(value), expireSeconds, isSliding);
+        }
+
+        public void AddOrUpdate(string key, string value, int expireSeconds = -1, bool isSliding = false)
+        {
+            Add(key, value, expireSeconds, isSliding);
+        }
+
+        public void AddOrUpdate(string key, object value, int expireSeconds = -1, bool isSliding = false)
+        {
+            AddObject(key, value, expireSeconds, isSliding);
+        }
+
+        public bool Remove(string key)
+        {
+            var fullKey = BuildKey(key);
+            _memoryCache.Remove(fullKey);
+            if (!RedisAvailable) return true;
+            try
+            {
+                return _connectionManager.GetDatabase().KeyDelete(fullKey);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Remove澶辫触, key={Key}", key);
+                return true;
+            }
+        }
+
+        public void Remove(IEnumerable<string> keys)
+        {
+            foreach (var key in keys) Remove(key);
+        }
+
+        public T? Get<T>(string key) where T : class
+        {
+            var fullKey = BuildKey(key);
+            if (_memoryCache.TryGetValue(fullKey, out string? cached) && cached != null)
+                return _serializer.Deserialize<T>(cached);
+
+            if (!RedisAvailable) return default;
+            try
+            {
+                var value = _connectionManager.GetDatabase().StringGet(fullKey);
+                if (value.IsNullOrEmpty) return default;
+                var str = value.ToString();
+                SetMemoryCache(fullKey, str, 300, false);
+                return _serializer.Deserialize<T>(str);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Get<T>澶辫触, key={Key}", key);
+                return default;
+            }
+        }
+
+        public object? Get(Type type, string key)
+        {
+            var fullKey = BuildKey(key);
+            if (_memoryCache.TryGetValue(fullKey, out string? cached) && cached != null)
+                return _serializer.Deserialize(cached, type);
+
+            if (!RedisAvailable) return null;
+            try
+            {
+                var value = _connectionManager.GetDatabase().StringGet(fullKey);
+                if (value.IsNullOrEmpty) return null;
+                var str = value.ToString();
+                SetMemoryCache(fullKey, str, 300, false);
+                return _serializer.Deserialize(str, type);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Get(Type)澶辫触, key={Key}", key);
+                return null;
+            }
+        }
+
+        public string? Get(string key)
+        {
+            var fullKey = BuildKey(key);
+            if (_memoryCache.TryGetValue(fullKey, out string? cached))
+                return cached;
+
+            if (!RedisAvailable) return null;
+            try
+            {
+                var value = _connectionManager.GetDatabase().StringGet(fullKey);
+                if (value.IsNullOrEmpty) return null;
+                var str = value.ToString();
+                SetMemoryCache(fullKey, str, 300, false);
+                return str;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "Redis Get澶辫触, key={Key}", key);
+                return null;
+            }
+        }
+
+        private void SetMemoryCache(string fullKey, string value, int expireSeconds, bool isSliding)
+        {
+            var entryOptions = new MemoryCacheEntryOptions();
+            if (expireSeconds > 0)
+            {
+                if (isSliding)
+                    entryOptions.SetSlidingExpiration(TimeSpan.FromSeconds(expireSeconds));
+                else
+                    entryOptions.SetAbsoluteExpiration(TimeSpan.FromSeconds(expireSeconds));
+            }
+            _memoryCache.Set(fullKey, value, entryOptions);
+        }
+
+        #region ConcurrentDictionary椋庢牸鏂规硶
+
+        public bool TryAdd(string key, string value, int expireSeconds = -1)
+        {
+            if (Exists(key)) return false;
+            return Add(key, value, expireSeconds);
+        }
+
+        public bool TryAdd<T>(string key, T value, int expireSeconds = -1) where T : class
+        {
+            if (Exists(key)) return false;
+            return AddObject(key, value, expireSeconds);
+        }
+
+        public bool TryGetValue(string key, out string? value)
+        {
+            value = Get(key);
+            return value != null;
+        }
+
+        public bool TryGetValue<T>(string key, out T? value) where T : class
+        {
+            value = Get<T>(key);
+            return value != null;
+        }
+
+        public bool TryRemove(string key, out string? value)
+        {
+            value = Get(key);
+            if (value == null) return false;
+            Remove(key);
+            return true;
+        }
+
+        public bool TryUpdate(string key, string newValue, int expireSeconds = -1)
+        {
+            if (!Exists(key)) return false;
+            Add(key, newValue, expireSeconds);
+            return true;
+        }
+
+        public string GetOrAdd(string key, string value, int expireSeconds = -1)
+        {
+            var existing = Get(key);
+            if (existing != null) return existing;
+            Add(key, value, expireSeconds);
+            return value;
+        }
+
+        public string GetOrAdd(string key, Func<string, string> valueFactory, int expireSeconds = -1)
+        {
+            var existing = Get(key);
+            if (existing != null) return existing;
+            var value = valueFactory(key);
+            Add(key, value, expireSeconds);
+            return value;
+        }
+
+        public T GetOrAdd<T>(string key, Func<string, T> valueFactory, int expireSeconds = -1) where T : class
+        {
+            var existing = Get<T>(key);
+            if (existing != null) return existing;
+            var value = valueFactory(key);
+            AddObject(key, value, expireSeconds);
+            return value;
+        }
+
+        #endregion
+
+        public void Dispose()
+        {
+            if (_disposed) return;
+            _disposed = true;
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/RedisCacheService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/RedisCacheService.cs
new file mode 100644
index 0000000..fe19c5f
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Cache/RedisCacheService.cs
@@ -0,0 +1,174 @@
+using Microsoft.Extensions.Logging;
+using StackExchange.Redis;
+using WIDESEAWCS_Core.Caches;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+using WIDESEAWCS_RedisService.Serialization;
+using Microsoft.Extensions.Options;
+
+namespace WIDESEAWCS_RedisService.Cache
+{
+    public class RedisCacheService : ICacheService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly IRedisSerializer _serializer;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisCacheService> _logger;
+        private bool _disposed;
+
+        public RedisCacheService(
+            IRedisConnectionManager connectionManager,
+            IRedisSerializer serializer,
+            IOptions<RedisOptions> options,
+            ILogger<RedisCacheService> logger)
+        {
+            _connectionManager = connectionManager;
+            _serializer = serializer;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}{key}";
+
+        private IDatabase Db => _connectionManager.GetDatabase();
+
+        public bool Exists(string key)
+        {
+            return Db.KeyExists(BuildKey(key));
+        }
+
+        public bool Add(string key, string value, int expireSeconds = -1, bool isSliding = false)
+        {
+            var fullKey = BuildKey(key);
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            return Db.StringSet(fullKey, value, expiry);
+        }
+
+        public bool AddObject(string key, object value, int expireSeconds = -1, bool isSliding = false)
+        {
+            return Add(key, _serializer.Serialize(value), expireSeconds, isSliding);
+        }
+
+        public void AddOrUpdate(string key, string value, int expireSeconds = -1, bool isSliding = false)
+        {
+            Add(key, value, expireSeconds, isSliding);
+        }
+
+        public void AddOrUpdate(string key, object value, int expireSeconds = -1, bool isSliding = false)
+        {
+            AddObject(key, value, expireSeconds, isSliding);
+        }
+
+        public bool Remove(string key)
+        {
+            return Db.KeyDelete(BuildKey(key));
+        }
+
+        public void Remove(IEnumerable<string> keys)
+        {
+            var redisKeys = keys.Select(k => (RedisKey)BuildKey(k)).ToArray();
+            Db.KeyDelete(redisKeys);
+        }
+
+        public T? Get<T>(string key) where T : class
+        {
+            var value = Db.StringGet(BuildKey(key));
+            if (value.IsNullOrEmpty) return default;
+            return _serializer.Deserialize<T>(value!);
+        }
+
+        public object? Get(Type type, string key)
+        {
+            var value = Db.StringGet(BuildKey(key));
+            if (value.IsNullOrEmpty) return null;
+            return _serializer.Deserialize(value!, type);
+        }
+
+        public string? Get(string key)
+        {
+            var value = Db.StringGet(BuildKey(key));
+            return value.IsNullOrEmpty ? null : value.ToString();
+        }
+
+        public void Dispose()
+        {
+            if (_disposed) return;
+            _disposed = true;
+        }
+
+        public bool TryAdd(string key, string value, int expireSeconds = -1)
+        {
+            var fullKey = BuildKey(key);
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            return Db.StringSet(fullKey, value, expiry, When.NotExists);
+        }
+
+        public bool TryAdd<T>(string key, T value, int expireSeconds = -1) where T : class
+        {
+            return TryAdd(key, _serializer.Serialize(value), expireSeconds);
+        }
+
+        public bool TryGetValue(string key, out string? value)
+        {
+            var val = Db.StringGet(BuildKey(key));
+            value = val.IsNullOrEmpty ? null : val.ToString();
+            return !val.IsNullOrEmpty;
+        }
+
+        public bool TryGetValue<T>(string key, out T? value) where T : class
+        {
+            var val = Db.StringGet(BuildKey(key));
+            if (val.IsNullOrEmpty) { value = default; return false; }
+            value = _serializer.Deserialize<T>(val!);
+            return value != null;
+        }
+
+        public bool TryRemove(string key, out string? value)
+        {
+            var fullKey = BuildKey(key);
+            value = Db.StringGet(fullKey).ToString();
+            if (value == null) return false;
+            return Db.KeyDelete(fullKey);
+        }
+
+        public bool TryUpdate(string key, string newValue, int expireSeconds = -1)
+        {
+            var fullKey = BuildKey(key);
+            if (!Db.KeyExists(fullKey)) return false;
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            return Db.StringSet(fullKey, newValue, expiry, When.Exists);
+        }
+
+        public string GetOrAdd(string key, string value, int expireSeconds = -1)
+        {
+            var fullKey = BuildKey(key);
+            var existing = Db.StringGet(fullKey);
+            if (!existing.IsNullOrEmpty) return existing.ToString();
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            Db.StringSet(fullKey, value, expiry, When.NotExists);
+            return Db.StringGet(fullKey).ToString();
+        }
+
+        public string GetOrAdd(string key, Func<string, string> valueFactory, int expireSeconds = -1)
+        {
+            var fullKey = BuildKey(key);
+            var existing = Db.StringGet(fullKey);
+            if (!existing.IsNullOrEmpty) return existing.ToString();
+            var value = valueFactory(key);
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            Db.StringSet(fullKey, value, expiry, When.NotExists);
+            return Db.StringGet(fullKey).ToString();
+        }
+
+        public T GetOrAdd<T>(string key, Func<string, T> valueFactory, int expireSeconds = -1) where T : class
+        {
+            var fullKey = BuildKey(key);
+            var existing = Db.StringGet(fullKey);
+            if (!existing.IsNullOrEmpty) return _serializer.Deserialize<T>(existing!)!;
+            var value = valueFactory(key);
+            var expiry = expireSeconds > 0 ? TimeSpan.FromSeconds(expireSeconds) : (TimeSpan?)null;
+            Db.StringSet(fullKey, _serializer.Serialize(value), expiry, When.NotExists);
+            return value;
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/IConfigurationCenterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/IConfigurationCenterService.cs
new file mode 100644
index 0000000..8d9eab3
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/IConfigurationCenterService.cs
@@ -0,0 +1,30 @@
+namespace WIDESEAWCS_RedisService.Configuration
+{
+    public interface IConfigurationCenterService
+    {
+        /// <summary>
+        /// 璁剧疆閰嶇疆椤�
+        /// </summary>
+        bool Set(string section, string key, string value);
+
+        /// <summary>
+        /// 鑾峰彇閰嶇疆椤�
+        /// </summary>
+        string? Get(string section, string key);
+
+        /// <summary>
+        /// 鑾峰彇鏁翠釜閰嶇疆鑺�
+        /// </summary>
+        Dictionary<string, string> GetSection(string section);
+
+        /// <summary>
+        /// 鍒犻櫎閰嶇疆椤�
+        /// </summary>
+        bool Delete(string section, string key);
+
+        /// <summary>
+        /// 璁㈤槄閰嶇疆鍙樻洿
+        /// </summary>
+        void Subscribe(string section, Action<string, string> onChange);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/RedisConfigurationCenterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/RedisConfigurationCenterService.cs
new file mode 100644
index 0000000..2eeb049
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Configuration/RedisConfigurationCenterService.cs
@@ -0,0 +1,65 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Configuration
+{
+    public class RedisConfigurationCenterService : IConfigurationCenterService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisConfigurationCenterService> _logger;
+
+        public RedisConfigurationCenterService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisConfigurationCenterService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string section) => $"{_options.KeyPrefix}config:{section}";
+
+        public bool Set(string section, string key, string value)
+        {
+            var db = _connectionManager.GetDatabase();
+            var result = db.HashSet(BuildKey(section), key, value);
+            // 鍙戝竷鍙樻洿閫氱煡
+            _connectionManager.GetSubscriber()
+                .Publish(RedisChannel.Literal($"{_options.KeyPrefix}config:change:{section}"), key);
+            return result;
+        }
+
+        public string? Get(string section, string key)
+        {
+            var val = _connectionManager.GetDatabase().HashGet(BuildKey(section), key);
+            return val.IsNullOrEmpty ? null : val.ToString();
+        }
+
+        public Dictionary<string, string> GetSection(string section)
+        {
+            var entries = _connectionManager.GetDatabase().HashGetAll(BuildKey(section));
+            return entries.ToDictionary(e => e.Name.ToString(), e => e.Value.ToString());
+        }
+
+        public bool Delete(string section, string key)
+        {
+            return _connectionManager.GetDatabase().HashDelete(BuildKey(section), key);
+        }
+
+        public void Subscribe(string section, Action<string, string> onChange)
+        {
+            _connectionManager.GetSubscriber()
+                .Subscribe(RedisChannel.Literal($"{_options.KeyPrefix}config:change:{section}"), (_, msg) =>
+                {
+                    var changedKey = msg.ToString();
+                    var value = Get(section, changedKey) ?? string.Empty;
+                    onChange(changedKey, value);
+                });
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/IRedisConnectionManager.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/IRedisConnectionManager.cs
new file mode 100644
index 0000000..04be0f3
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/IRedisConnectionManager.cs
@@ -0,0 +1,17 @@
+using StackExchange.Redis;
+
+namespace WIDESEAWCS_RedisService.Connection
+{
+    public interface IRedisConnectionManager : IDisposable
+    {
+        IDatabase GetDatabase(int db = -1);
+
+        IServer GetServer();
+
+        ISubscriber GetSubscriber();
+
+        ConnectionMultiplexer GetConnection();
+
+        bool IsConnected { get; }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/RedisConnectionManager.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/RedisConnectionManager.cs
new file mode 100644
index 0000000..bc37709
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Connection/RedisConnectionManager.cs
@@ -0,0 +1,111 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using System.Linq;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Connection
+{
+    public class RedisConnectionManager : IRedisConnectionManager
+    {
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisConnectionManager> _logger;
+        private readonly Lazy<ConnectionMultiplexer> _connection;
+        private bool _disposed;
+
+        public bool IsConnected
+        {
+            get
+            {
+                try
+                {
+                    // 寮哄埗璁块棶Value鏉ヨЕ鍙戣繛鎺ュ垱寤�
+                    var connected = _connection.Value.IsConnected;
+                    _logger.LogDebug("IsConnected妫�鏌�: IsValueCreated={IsValueCreated}, IsConnected={Connected}",
+                        _connection.IsValueCreated, connected);
+                    return connected;
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogWarning(ex, "IsConnected妫�鏌ュけ璐�");
+                    return false;
+                }
+            }
+        }
+
+        public RedisConnectionManager(IOptions<RedisOptions> options, ILogger<RedisConnectionManager> logger)
+        {
+            _options = options.Value;
+            _logger = logger;
+            _logger.LogInformation("RedisConnectionManager鏋勯�犲紑濮�, ConnectionString={ConnectionString}, Enabled={Enabled}",
+                _options.ConnectionString, _options.Enabled);
+            _connection = new Lazy<ConnectionMultiplexer>(CreateConnection);
+            _logger.LogInformation("RedisConnectionManager鏋勯�犲畬鎴�, Lazy宸插垱寤�");
+        }
+
+        private ConnectionMultiplexer CreateConnection()
+        {
+            try
+            {
+                _logger.LogInformation("寮�濮嬪垱寤篟edis杩炴帴, ConnectionString={ConnectionString}", _options.ConnectionString);
+                var configOptions = ConfigurationOptions.Parse(_options.ConnectionString);
+                configOptions.AbortOnConnectFail = false;
+                configOptions.ConnectRetry = _options.ConnectRetry;
+                configOptions.DefaultDatabase = _options.DefaultDatabase;
+                _logger.LogInformation("ConfigurationOptions瑙f瀽瀹屾垚, EndPoints={EndPoints}", string.Join(",", configOptions.EndPoints.Select(e => e.ToString())));
+
+                if (_options.EnableSentinel && _options.SentinelEndpoints.Count > 0)
+                {
+                    configOptions.ServiceName = _options.SentinelMasterName;
+                    foreach (var endpoint in _options.SentinelEndpoints)
+                    {
+                        configOptions.EndPoints.Add(endpoint);
+                    }
+                }
+
+                var connection = ConnectionMultiplexer.Connect(configOptions);
+                connection.ConnectionFailed += (_, e) =>
+                    _logger.LogError("Redis杩炴帴澶辫触: {FailureType}", e.FailureType);
+                connection.ConnectionRestored += (_, e) =>
+                    _logger.LogInformation("Redis杩炴帴鎭㈠: {EndPoint}", e.EndPoint);
+
+                _logger.LogInformation("Redis杩炴帴鎴愬姛: {EndPoints}", string.Join(",", configOptions.EndPoints));
+                return connection;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Redis杩炴帴鍒涘缓澶辫触");
+                throw;
+            }
+        }
+
+        public IDatabase GetDatabase(int db = -1)
+        {
+            return _connection.Value.GetDatabase(db == -1 ? _options.DefaultDatabase : db);
+        }
+
+        public IServer GetServer()
+        {
+            var endpoints = _connection.Value.GetEndPoints();
+            return _connection.Value.GetServer(endpoints[0]);
+        }
+
+        public ISubscriber GetSubscriber()
+        {
+            return _connection.Value.GetSubscriber();
+        }
+
+        public ConnectionMultiplexer GetConnection()
+        {
+            return _connection.Value;
+        }
+
+        public void Dispose()
+        {
+            if (_disposed) return;
+            _disposed = true;
+            if (_connection.IsValueCreated)
+                _connection.Value.Dispose();
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/ICounterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/ICounterService.cs
new file mode 100644
index 0000000..60939c3
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/ICounterService.cs
@@ -0,0 +1,30 @@
+namespace WIDESEAWCS_RedisService.Counter
+{
+    public interface ICounterService
+    {
+        /// <summary>
+        /// 閫掑
+        /// </summary>
+        long Increment(string key, long value = 1);
+
+        /// <summary>
+        /// 閫掑噺
+        /// </summary>
+        long Decrement(string key, long value = 1);
+
+        /// <summary>
+        /// 鑾峰彇褰撳墠鍊�
+        /// </summary>
+        long GetCount(string key);
+
+        /// <summary>
+        /// 閲嶇疆璁℃暟鍣�
+        /// </summary>
+        bool Reset(string key);
+
+        /// <summary>
+        /// 璁剧疆甯﹁繃鏈熸椂闂寸殑璁℃暟鍣�
+        /// </summary>
+        long IncrementWithExpiry(string key, TimeSpan expiry, long value = 1);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/RedisCounterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/RedisCounterService.cs
new file mode 100644
index 0000000..dc17483
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Counter/RedisCounterService.cs
@@ -0,0 +1,57 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Counter
+{
+    public class RedisCounterService : ICounterService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisCounterService> _logger;
+
+        public RedisCounterService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisCounterService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}counter:{key}";
+
+        public long Increment(string key, long value = 1)
+        {
+            return _connectionManager.GetDatabase().StringIncrement(BuildKey(key), value);
+        }
+
+        public long Decrement(string key, long value = 1)
+        {
+            return _connectionManager.GetDatabase().StringDecrement(BuildKey(key), value);
+        }
+
+        public long GetCount(string key)
+        {
+            var val = _connectionManager.GetDatabase().StringGet(BuildKey(key));
+            return val.IsNullOrEmpty ? 0 : (long)val;
+        }
+
+        public bool Reset(string key)
+        {
+            return _connectionManager.GetDatabase().KeyDelete(BuildKey(key));
+        }
+
+        public long IncrementWithExpiry(string key, TimeSpan expiry, long value = 1)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(key);
+            var result = db.StringIncrement(fullKey, value);
+            if (result == value)
+                db.KeyExpire(fullKey, expiry);
+            return result;
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/IDelayQueueService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/IDelayQueueService.cs
new file mode 100644
index 0000000..b220290
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/IDelayQueueService.cs
@@ -0,0 +1,25 @@
+namespace WIDESEAWCS_RedisService.DelayQueue
+{
+    public interface IDelayQueueService
+    {
+        /// <summary>
+        /// 娣诲姞寤惰繜浠诲姟
+        /// </summary>
+        bool Enqueue(string queueName, string message, TimeSpan delay);
+
+        /// <summary>
+        /// 鑾峰彇鍒版湡鐨勪换鍔�
+        /// </summary>
+        List<string> DequeueDue(string queueName, int count = 10);
+
+        /// <summary>
+        /// 绉婚櫎浠诲姟
+        /// </summary>
+        bool Remove(string queueName, string message);
+
+        /// <summary>
+        /// 鑾峰彇闃熷垪闀垮害
+        /// </summary>
+        long GetQueueLength(string queueName);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/RedisDelayQueueService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/RedisDelayQueueService.cs
new file mode 100644
index 0000000..5d12390
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/DelayQueue/RedisDelayQueueService.cs
@@ -0,0 +1,60 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.DelayQueue
+{
+    public class RedisDelayQueueService : IDelayQueueService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisDelayQueueService> _logger;
+
+        public RedisDelayQueueService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisDelayQueueService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}delay:{key}";
+
+        public bool Enqueue(string queueName, string message, TimeSpan delay)
+        {
+            var score = DateTimeOffset.UtcNow.Add(delay).ToUnixTimeMilliseconds();
+            return _connectionManager.GetDatabase().SortedSetAdd(BuildKey(queueName), message, score);
+        }
+
+        public List<string> DequeueDue(string queueName, int count = 10)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(queueName);
+            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+            var entries = db.SortedSetRangeByScore(fullKey, 0, now, take: count);
+            var result = new List<string>();
+
+            foreach (var entry in entries)
+            {
+                if (db.SortedSetRemove(fullKey, entry))
+                    result.Add(entry.ToString());
+            }
+            return result;
+        }
+
+        public bool Remove(string queueName, string message)
+        {
+            return _connectionManager.GetDatabase().SortedSetRemove(BuildKey(queueName), message);
+        }
+
+        public long GetQueueLength(string queueName)
+        {
+            return _connectionManager.GetDatabase().SortedSetLength(BuildKey(queueName));
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Extensions/RedisServiceSetup.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Extensions/RedisServiceSetup.cs
new file mode 100644
index 0000000..bd5d40a
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Extensions/RedisServiceSetup.cs
@@ -0,0 +1,77 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using System.Linq;
+using WIDESEAWCS_Core.Caches;
+using WIDESEAWCS_RedisService.Bitmap;
+using WIDESEAWCS_RedisService.Cache;
+using WIDESEAWCS_RedisService.Configuration;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Counter;
+using WIDESEAWCS_RedisService.DelayQueue;
+using WIDESEAWCS_RedisService.IdGenerator;
+using WIDESEAWCS_RedisService.Leaderboard;
+using WIDESEAWCS_RedisService.Geo;
+using WIDESEAWCS_RedisService.Lock;
+using WIDESEAWCS_RedisService.Monitoring;
+using WIDESEAWCS_RedisService.Options;
+using WIDESEAWCS_RedisService.PubSub;
+using WIDESEAWCS_RedisService.RateLimiting;
+using WIDESEAWCS_RedisService.Serialization;
+using WIDESEAWCS_RedisService.Session;
+using WIDESEAWCS_RedisService.Storage;
+using WIDESEAWCS_RedisService.Stream;
+
+namespace WIDESEAWCS_RedisService.Extensions
+{
+    public static class RedisServiceSetup
+    {
+        public static IServiceCollection AddRedisSetup(this IServiceCollection services, IConfiguration configuration)
+        {
+            var section = configuration.GetSection("RedisConfig");
+            services.Configure<RedisOptions>(section);
+
+            var options = section.Get<RedisOptions>() ?? new RedisOptions();
+
+            if (!options.Enabled)
+            {
+                // Redis鏈惎鐢紝浣跨敤鍐呭瓨缂撳瓨
+                services.AddMemoryCache();
+                return services;
+            }
+
+            // 绉婚櫎宸叉湁鐨処CacheService娉ㄥ唽锛圡emoryCacheService锛夛紝閬垮厤鍐茬獊
+            var existingDescriptor = services.FirstOrDefault(d => d.ServiceType == typeof(ICacheService));
+            if (existingDescriptor != null)
+            {
+                services.Remove(existingDescriptor);
+            }
+
+            // 鍩虹璁炬柦
+            services.AddMemoryCache();
+            services.AddSingleton<IRedisSerializer, NewtonsoftRedisSerializer>();
+            services.AddSingleton<IRedisConnectionManager, RedisConnectionManager>();
+
+            // 缂撳瓨锛堟浛鎹㈠師鏈塎emoryCacheService锛�
+            services.AddSingleton<ICacheService, HybridCacheService>();
+
+            // 鍔熻兘妯″潡
+            services.AddSingleton<IDistributedLockService, RedisDistributedLockService>();
+            services.AddSingleton<ICounterService, RedisCounterService>();
+            services.AddSingleton<IMessageQueueService, RedisMessageQueueService>();
+            services.AddSingleton<IDelayQueueService, RedisDelayQueueService>();
+            services.AddSingleton<IStreamProcessingService, RedisStreamProcessingService>();
+            services.AddSingleton<ILeaderboardService, RedisLeaderboardService>();
+            services.AddSingleton<IGeoLocationService, RedisGeoLocationService>();
+            services.AddSingleton<IBitmapService, RedisBitmapService>();
+            services.AddSingleton<IBloomFilterService, RedisBloomFilterService>();
+            services.AddSingleton<IObjectStorageService, RedisObjectStorageService>();
+            services.AddSingleton<IDistributedIdGenerator, RedisDistributedIdGenerator>();
+            services.AddSingleton<IRateLimitingService, RedisRateLimitingService>();
+            services.AddSingleton<IConfigurationCenterService, RedisConfigurationCenterService>();
+            services.AddSingleton<ISessionStorage, RedisSessionStorage>();
+            services.AddSingleton<IRedisMonitorService, RedisMonitorService>();
+
+            return services;
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/IGeoLocationService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/IGeoLocationService.cs
new file mode 100644
index 0000000..165a091
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/IGeoLocationService.cs
@@ -0,0 +1,43 @@
+namespace WIDESEAWCS_RedisService.Geo
+{
+    public interface IGeoLocationService
+    {
+        /// <summary>
+        /// 娣诲姞鍦扮悊浣嶇疆
+        /// </summary>
+        bool Add(string key, double longitude, double latitude, string member);
+
+        /// <summary>
+        /// 鑾峰彇鎴愬憳浣嶇疆
+        /// </summary>
+        GeoPosition? GetPosition(string key, string member);
+
+        /// <summary>
+        /// 璁$畻涓や釜鎴愬憳涔嬮棿鐨勮窛绂伙紙绫筹級
+        /// </summary>
+        double? GetDistance(string key, string member1, string member2);
+
+        /// <summary>
+        /// 鎼滅储鎸囧畾鍗婂緞鍐呯殑鎴愬憳
+        /// </summary>
+        List<GeoRadiusResult> SearchRadius(string key, double longitude, double latitude, double radiusMeters, int count = 10);
+
+        /// <summary>
+        /// 绉婚櫎鎴愬憳
+        /// </summary>
+        bool Remove(string key, string member);
+    }
+
+    public class GeoPosition
+    {
+        public double Longitude { get; set; }
+        public double Latitude { get; set; }
+    }
+
+    public class GeoRadiusResult
+    {
+        public string Member { get; set; } = string.Empty;
+        public double? Distance { get; set; }
+        public GeoPosition? Position { get; set; }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/RedisGeoLocationService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/RedisGeoLocationService.cs
new file mode 100644
index 0000000..45bd564
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Geo/RedisGeoLocationService.cs
@@ -0,0 +1,65 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Geo
+{
+    public class RedisGeoLocationService : IGeoLocationService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisGeoLocationService> _logger;
+
+        public RedisGeoLocationService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisGeoLocationService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}geo:{key}";
+
+        public bool Add(string key, double longitude, double latitude, string member)
+        {
+            return _connectionManager.GetDatabase().GeoAdd(BuildKey(key), longitude, latitude, member);
+        }
+
+        public GeoPosition? GetPosition(string key, string member)
+        {
+            var pos = _connectionManager.GetDatabase().GeoPosition(BuildKey(key), member);
+            if (pos == null) return null;
+            return new GeoPosition { Longitude = pos.Value.Longitude, Latitude = pos.Value.Latitude };
+        }
+
+        public double? GetDistance(string key, string member1, string member2)
+        {
+            return _connectionManager.GetDatabase().GeoDistance(BuildKey(key), member1, member2, GeoUnit.Meters);
+        }
+
+        public List<GeoRadiusResult> SearchRadius(string key, double longitude, double latitude, double radiusMeters, int count = 10)
+        {
+            var results = _connectionManager.GetDatabase()
+                .GeoRadius(BuildKey(key), longitude, latitude, radiusMeters, GeoUnit.Meters,
+                    count, Order.Ascending, GeoRadiusOptions.WithDistance | GeoRadiusOptions.WithCoordinates);
+
+            return results.Select(r => new GeoRadiusResult
+            {
+                Member = r.Member.ToString(),
+                Distance = r.Distance,
+                Position = r.Position.HasValue
+                    ? new GeoPosition { Longitude = r.Position.Value.Longitude, Latitude = r.Position.Value.Latitude }
+                    : null
+            }).ToList();
+        }
+
+        public bool Remove(string key, string member)
+        {
+            return _connectionManager.GetDatabase().SortedSetRemove(BuildKey(key), member);
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/IDistributedIdGenerator.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/IDistributedIdGenerator.cs
new file mode 100644
index 0000000..28c53b1
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/IDistributedIdGenerator.cs
@@ -0,0 +1,25 @@
+namespace WIDESEAWCS_RedisService.IdGenerator
+{
+    public interface IDistributedIdGenerator
+    {
+        /// <summary>
+        /// 鐢熸垚鑷ID
+        /// </summary>
+        long NextId(string sequenceName);
+
+        /// <summary>
+        /// 鐢熸垚甯︽棩鏈熷墠缂�鐨処D锛堝 20260228000001锛�
+        /// </summary>
+        string NextIdWithDate(string sequenceName);
+
+        /// <summary>
+        /// 鑾峰彇褰撳墠搴忓垪鍊�
+        /// </summary>
+        long GetCurrentId(string sequenceName);
+
+        /// <summary>
+        /// 閲嶇疆搴忓垪
+        /// </summary>
+        bool Reset(string sequenceName);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/RedisDistributedIdGenerator.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/RedisDistributedIdGenerator.cs
new file mode 100644
index 0000000..0897e73
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/IdGenerator/RedisDistributedIdGenerator.cs
@@ -0,0 +1,56 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.IdGenerator
+{
+    public class RedisDistributedIdGenerator : IDistributedIdGenerator
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisDistributedIdGenerator> _logger;
+
+        public RedisDistributedIdGenerator(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisDistributedIdGenerator> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string name) => $"{_options.KeyPrefix}id:{name}";
+
+        public long NextId(string sequenceName)
+        {
+            return _connectionManager.GetDatabase().StringIncrement(BuildKey(sequenceName));
+        }
+
+        public string NextIdWithDate(string sequenceName)
+        {
+            var datePrefix = DateTime.Now.ToString("yyyyMMdd");
+            var dailyKey = $"{BuildKey(sequenceName)}:{datePrefix}";
+            var db = _connectionManager.GetDatabase();
+            var seq = db.StringIncrement(dailyKey);
+
+            // 姣忔棩棣栨鐢熸垚鏃惰缃繃鏈熸椂闂达紙48灏忔椂锛岀暀浣欓噺锛�
+            if (seq == 1)
+                db.KeyExpire(dailyKey, TimeSpan.FromHours(48));
+
+            return $"{datePrefix}{seq:D6}";
+        }
+
+        public long GetCurrentId(string sequenceName)
+        {
+            var val = _connectionManager.GetDatabase().StringGet(BuildKey(sequenceName));
+            return val.IsNullOrEmpty ? 0 : (long)val;
+        }
+
+        public bool Reset(string sequenceName)
+        {
+            return _connectionManager.GetDatabase().KeyDelete(BuildKey(sequenceName));
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/ILeaderboardService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/ILeaderboardService.cs
new file mode 100644
index 0000000..4a3d93c
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/ILeaderboardService.cs
@@ -0,0 +1,52 @@
+namespace WIDESEAWCS_RedisService.Leaderboard
+{
+    public interface ILeaderboardService
+    {
+        /// <summary>
+        /// 娣诲姞鎴栨洿鏂版垚鍛樺垎鏁�
+        /// </summary>
+        bool AddOrUpdate(string boardName, string member, double score);
+
+        /// <summary>
+        /// 澧炲姞鎴愬憳鍒嗘暟
+        /// </summary>
+        double IncrementScore(string boardName, string member, double increment);
+
+        /// <summary>
+        /// 鑾峰彇鎺掑悕锛堜粠楂樺埌浣庯紝0寮�濮嬶級
+        /// </summary>
+        long? GetRank(string boardName, string member);
+
+        /// <summary>
+        /// 鑾峰彇鎴愬憳鍒嗘暟
+        /// </summary>
+        double? GetScore(string boardName, string member);
+
+        /// <summary>
+        /// 鑾峰彇鎺掕姒滐紙浠庨珮鍒颁綆锛�
+        /// </summary>
+        List<LeaderboardEntry> GetTopN(string boardName, int count);
+
+        /// <summary>
+        /// 鑾峰彇鎸囧畾鎺掑悕鑼冨洿
+        /// </summary>
+        List<LeaderboardEntry> GetRange(string boardName, long start, long stop);
+
+        /// <summary>
+        /// 绉婚櫎鎴愬憳
+        /// </summary>
+        bool Remove(string boardName, string member);
+
+        /// <summary>
+        /// 鑾峰彇鎺掕姒滄�讳汉鏁�
+        /// </summary>
+        long GetCount(string boardName);
+    }
+
+    public class LeaderboardEntry
+    {
+        public string Member { get; set; } = string.Empty;
+        public double Score { get; set; }
+        public long Rank { get; set; }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/RedisLeaderboardService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/RedisLeaderboardService.cs
new file mode 100644
index 0000000..00e5d1a
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Leaderboard/RedisLeaderboardService.cs
@@ -0,0 +1,75 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Leaderboard
+{
+    public class RedisLeaderboardService : ILeaderboardService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisLeaderboardService> _logger;
+
+        public RedisLeaderboardService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisLeaderboardService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}board:{key}";
+
+        public bool AddOrUpdate(string boardName, string member, double score)
+        {
+            return _connectionManager.GetDatabase().SortedSetAdd(BuildKey(boardName), member, score);
+        }
+
+        public double IncrementScore(string boardName, string member, double increment)
+        {
+            return _connectionManager.GetDatabase().SortedSetIncrement(BuildKey(boardName), member, increment);
+        }
+
+        public long? GetRank(string boardName, string member)
+        {
+            return _connectionManager.GetDatabase().SortedSetRank(BuildKey(boardName), member, Order.Descending);
+        }
+
+        public double? GetScore(string boardName, string member)
+        {
+            return _connectionManager.GetDatabase().SortedSetScore(BuildKey(boardName), member);
+        }
+
+        public List<LeaderboardEntry> GetTopN(string boardName, int count)
+        {
+            return GetRange(boardName, 0, count - 1);
+        }
+
+        public List<LeaderboardEntry> GetRange(string boardName, long start, long stop)
+        {
+            var entries = _connectionManager.GetDatabase()
+                .SortedSetRangeByRankWithScores(BuildKey(boardName), start, stop, Order.Descending);
+
+            return entries.Select((e, i) => new LeaderboardEntry
+            {
+                Member = e.Element.ToString(),
+                Score = e.Score,
+                Rank = start + i
+            }).ToList();
+        }
+
+        public bool Remove(string boardName, string member)
+        {
+            return _connectionManager.GetDatabase().SortedSetRemove(BuildKey(boardName), member);
+        }
+
+        public long GetCount(string boardName)
+        {
+            return _connectionManager.GetDatabase().SortedSetLength(BuildKey(boardName));
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/IDistributedLockService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/IDistributedLockService.cs
new file mode 100644
index 0000000..fdb24f2
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/IDistributedLockService.cs
@@ -0,0 +1,34 @@
+namespace WIDESEAWCS_RedisService.Lock
+{
+    public interface IDistributedLockService
+    {
+        /// <summary>
+        /// 鑾峰彇鍒嗗竷寮忛攣
+        /// </summary>
+        /// <param name="lockKey">閿佺殑Key</param>
+        /// <param name="expiry">閿佽繃鏈熸椂闂�</param>
+        /// <param name="waitTimeout">绛夊緟鑾峰彇閿佺殑瓒呮椂鏃堕棿</param>
+        /// <returns>閿乀oken锛岄噴鏀炬椂闇�瑕佷紶鍏ワ紱鑾峰彇澶辫触杩斿洖null</returns>
+        string? AcquireLock(string lockKey, TimeSpan expiry, TimeSpan? waitTimeout = null);
+
+        /// <summary>
+        /// 閲婃斁鍒嗗竷寮忛攣
+        /// </summary>
+        bool ReleaseLock(string lockKey, string lockToken);
+
+        /// <summary>
+        /// 缁湡閿�
+        /// </summary>
+        bool RenewLock(string lockKey, string lockToken, TimeSpan expiry);
+
+        /// <summary>
+        /// 浣跨敤閿佹墽琛屾搷浣�
+        /// </summary>
+        T? ExecuteWithLock<T>(string lockKey, TimeSpan expiry, Func<T> action, TimeSpan? waitTimeout = null);
+
+        /// <summary>
+        /// 浣跨敤閿佹墽琛屾搷浣滐紙鏃犺繑鍥炲�硷級
+        /// </summary>
+        bool ExecuteWithLock(string lockKey, TimeSpan expiry, Action action, TimeSpan? waitTimeout = null);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/RedisDistributedLockService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/RedisDistributedLockService.cs
new file mode 100644
index 0000000..7b4fbbe
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Lock/RedisDistributedLockService.cs
@@ -0,0 +1,112 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Lock
+{
+    public class RedisDistributedLockService : IDistributedLockService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisDistributedLockService> _logger;
+
+        // Lua鑴氭湰锛氬畨鍏ㄩ噴鏀鹃攣锛堝彧鏈夋寔鏈夎�呮墠鑳介噴鏀撅級
+        private const string ReleaseLockScript = @"
+            if redis.call('get', KEYS[1]) == ARGV[1] then
+                return redis.call('del', KEYS[1])
+            else
+                return 0
+            end";
+
+        // Lua鑴氭湰锛氬畨鍏ㄧ画鏈熼攣
+        private const string RenewLockScript = @"
+            if redis.call('get', KEYS[1]) == ARGV[1] then
+                return redis.call('pexpire', KEYS[1], ARGV[2])
+            else
+                return 0
+            end";
+
+        public RedisDistributedLockService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisDistributedLockService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}lock:{key}";
+
+        public string? AcquireLock(string lockKey, TimeSpan expiry, TimeSpan? waitTimeout = null)
+        {
+            var fullKey = BuildKey(lockKey);
+            var token = Guid.NewGuid().ToString("N");
+            var db = _connectionManager.GetDatabase();
+            var deadline = DateTime.UtcNow + (waitTimeout ?? TimeSpan.Zero);
+
+            do
+            {
+                if (db.StringSet(fullKey, token, expiry, When.NotExists))
+                    return token;
+
+                if (waitTimeout == null) return null;
+                Thread.Sleep(50);
+            }
+            while (DateTime.UtcNow < deadline);
+
+            return null;
+        }
+
+        public bool ReleaseLock(string lockKey, string lockToken)
+        {
+            var db = _connectionManager.GetDatabase();
+            var result = db.ScriptEvaluate(
+                ReleaseLockScript,
+                new RedisKey[] { BuildKey(lockKey) },
+                new RedisValue[] { lockToken });
+            return (long)result == 1;
+        }
+
+        public bool RenewLock(string lockKey, string lockToken, TimeSpan expiry)
+        {
+            var db = _connectionManager.GetDatabase();
+            var result = db.ScriptEvaluate(
+                RenewLockScript,
+                new RedisKey[] { BuildKey(lockKey) },
+                new RedisValue[] { lockToken, (long)expiry.TotalMilliseconds });
+            return (long)result == 1;
+        }
+
+        public T? ExecuteWithLock<T>(string lockKey, TimeSpan expiry, Func<T> action, TimeSpan? waitTimeout = null)
+        {
+            var token = AcquireLock(lockKey, expiry, waitTimeout);
+            if (token == null) return default;
+            try
+            {
+                return action();
+            }
+            finally
+            {
+                ReleaseLock(lockKey, token);
+            }
+        }
+
+        public bool ExecuteWithLock(string lockKey, TimeSpan expiry, Action action, TimeSpan? waitTimeout = null)
+        {
+            var token = AcquireLock(lockKey, expiry, waitTimeout);
+            if (token == null) return false;
+            try
+            {
+                action();
+                return true;
+            }
+            finally
+            {
+                ReleaseLock(lockKey, token);
+            }
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/IRedisMonitorService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/IRedisMonitorService.cs
new file mode 100644
index 0000000..c7ba7d5
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/IRedisMonitorService.cs
@@ -0,0 +1,39 @@
+namespace WIDESEAWCS_RedisService.Monitoring
+{
+    public interface IRedisMonitorService
+    {
+        /// <summary>
+        /// 鑾峰彇Redis鏈嶅姟鍣ㄤ俊鎭�
+        /// </summary>
+        Dictionary<string, string> GetServerInfo();
+
+        /// <summary>
+        /// 鑾峰彇鍐呭瓨浣跨敤淇℃伅
+        /// </summary>
+        RedisMemoryInfo GetMemoryInfo();
+
+        /// <summary>
+        /// 鍋ュ悍妫�鏌�
+        /// </summary>
+        bool HealthCheck();
+
+        /// <summary>
+        /// 鑾峰彇鏁版嵁搴揔ey鏁伴噺
+        /// </summary>
+        long GetDbSize();
+
+        /// <summary>
+        /// 鑾峰彇瀹㈡埛绔繛鎺ユ暟
+        /// </summary>
+        long GetClientCount();
+    }
+
+    public class RedisMemoryInfo
+    {
+        public long UsedMemory { get; set; }
+        public string UsedMemoryHuman { get; set; } = string.Empty;
+        public long MaxMemory { get; set; }
+        public string MaxMemoryHuman { get; set; } = string.Empty;
+        public double UsagePercent { get; set; }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/RedisMonitorService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/RedisMonitorService.cs
new file mode 100644
index 0000000..55bb693
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Monitoring/RedisMonitorService.cs
@@ -0,0 +1,91 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Monitoring
+{
+    public class RedisMonitorService : IRedisMonitorService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisMonitorService> _logger;
+
+        public RedisMonitorService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisMonitorService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        public Dictionary<string, string> GetServerInfo()
+        {
+            var server = _connectionManager.GetServer();
+            var info = server.Info();
+            var result = new Dictionary<string, string>();
+            foreach (var group in info)
+            {
+                foreach (var item in group)
+                    result[$"{group.Key}:{item.Key}"] = item.Value;
+            }
+            return result;
+        }
+
+        public RedisMemoryInfo GetMemoryInfo()
+        {
+            var server = _connectionManager.GetServer();
+            var info = server.Info("memory");
+            var memorySection = info.FirstOrDefault();
+
+            var memInfo = new RedisMemoryInfo();
+            if (memorySection == null) return memInfo;
+
+            var dict = memorySection.ToDictionary(x => x.Key, x => x.Value);
+            if (dict.TryGetValue("used_memory", out var used))
+                memInfo.UsedMemory = long.Parse(used);
+            if (dict.TryGetValue("used_memory_human", out var usedH))
+                memInfo.UsedMemoryHuman = usedH;
+            if (dict.TryGetValue("maxmemory", out var max))
+                memInfo.MaxMemory = long.Parse(max);
+            if (dict.TryGetValue("maxmemory_human", out var maxH))
+                memInfo.MaxMemoryHuman = maxH;
+
+            if (memInfo.MaxMemory > 0)
+                memInfo.UsagePercent = Math.Round((double)memInfo.UsedMemory / memInfo.MaxMemory * 100, 2);
+
+            return memInfo;
+        }
+
+        public bool HealthCheck()
+        {
+            try
+            {
+                var db = _connectionManager.GetDatabase();
+                var pong = db.Ping();
+                return pong.TotalMilliseconds < 5000;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Redis鍋ュ悍妫�鏌ュけ璐�");
+                return false;
+            }
+        }
+
+        public long GetDbSize()
+        {
+            return _connectionManager.GetServer().DatabaseSize();
+        }
+
+        public long GetClientCount()
+        {
+            var info = _connectionManager.GetServer().Info("clients");
+            var section = info.FirstOrDefault();
+            if (section == null) return 0;
+            var dict = section.ToDictionary(x => x.Key, x => x.Value);
+            return dict.TryGetValue("connected_clients", out var count) ? long.Parse(count) : 0;
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Options/RedisOptions.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Options/RedisOptions.cs
new file mode 100644
index 0000000..8b8a824
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Options/RedisOptions.cs
@@ -0,0 +1,49 @@
+namespace WIDESEAWCS_RedisService.Options
+{
+    public class RedisOptions
+    {
+        public bool Enabled { get; set; } = true;
+
+        public string ConnectionString { get; set; } = "127.0.0.1:6379,defaultDatabase=0,connectTimeout=5000,abortConnect=false";
+
+        public string InstanceName { get; set; } = "WIDESEAWCS:";
+
+        public int DefaultDatabase { get; set; } = 0;
+
+        public bool EnableSentinel { get; set; } = false;
+
+        public string SentinelMasterName { get; set; } = "mymaster";
+
+        public List<string> SentinelEndpoints { get; set; } = new();
+
+        public int PoolSize { get; set; } = 10;
+
+        public int ConnectRetry { get; set; } = 3;
+
+        public string SerializerType { get; set; } = "Newtonsoft";
+
+        public bool FallbackToMemory { get; set; } = true;
+
+        public string KeyPrefix { get; set; } = "wcs:";
+
+        public MonitoringOptions Monitoring { get; set; } = new();
+
+        public EvictionOptions Eviction { get; set; } = new();
+    }
+
+    public class MonitoringOptions
+    {
+        public bool Enabled { get; set; } = false;
+
+        public int SlowLogThresholdMs { get; set; } = 100;
+
+        public int HealthCheckIntervalSeconds { get; set; } = 30;
+    }
+
+    public class EvictionOptions
+    {
+        public int DefaultExpirationSeconds { get; set; } = 3600;
+
+        public string MaxMemoryPolicy { get; set; } = "allkeys-lru";
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/IMessageQueueService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/IMessageQueueService.cs
new file mode 100644
index 0000000..0f33418
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/IMessageQueueService.cs
@@ -0,0 +1,35 @@
+namespace WIDESEAWCS_RedisService.PubSub
+{
+    public interface IMessageQueueService
+    {
+        /// <summary>
+        /// 鍙戝竷娑堟伅
+        /// </summary>
+        long Publish(string channel, string message);
+
+        /// <summary>
+        /// 璁㈤槄棰戦亾
+        /// </summary>
+        void Subscribe(string channel, Action<string, string> handler);
+
+        /// <summary>
+        /// 鍙栨秷璁㈤槄
+        /// </summary>
+        void Unsubscribe(string channel);
+
+        /// <summary>
+        /// 鎺ㄩ�佹秷鎭埌鍙潬闃熷垪锛圠ist锛�
+        /// </summary>
+        long Enqueue(string queueName, string message);
+
+        /// <summary>
+        /// 浠庡彲闈犻槦鍒楀脊鍑烘秷鎭�
+        /// </summary>
+        string? Dequeue(string queueName, TimeSpan? timeout = null);
+
+        /// <summary>
+        /// 鑾峰彇闃熷垪闀垮害
+        /// </summary>
+        long GetQueueLength(string queueName);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/RedisMessageQueueService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/RedisMessageQueueService.cs
new file mode 100644
index 0000000..9d1076a
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/PubSub/RedisMessageQueueService.cs
@@ -0,0 +1,64 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.PubSub
+{
+    public class RedisMessageQueueService : IMessageQueueService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisMessageQueueService> _logger;
+
+        public RedisMessageQueueService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisMessageQueueService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}queue:{key}";
+
+        public long Publish(string channel, string message)
+        {
+            var sub = _connectionManager.GetSubscriber();
+            return sub.Publish(RedisChannel.Literal($"{_options.KeyPrefix}{channel}"), message);
+        }
+
+        public void Subscribe(string channel, Action<string, string> handler)
+        {
+            var sub = _connectionManager.GetSubscriber();
+            sub.Subscribe(RedisChannel.Literal($"{_options.KeyPrefix}{channel}"), (ch, msg) =>
+            {
+                handler(ch!, msg!);
+            });
+        }
+
+        public void Unsubscribe(string channel)
+        {
+            var sub = _connectionManager.GetSubscriber();
+            sub.Unsubscribe(RedisChannel.Literal($"{_options.KeyPrefix}{channel}"));
+        }
+
+        public long Enqueue(string queueName, string message)
+        {
+            return _connectionManager.GetDatabase().ListLeftPush(BuildKey(queueName), message);
+        }
+
+        public string? Dequeue(string queueName, TimeSpan? timeout = null)
+        {
+            var val = _connectionManager.GetDatabase().ListRightPop(BuildKey(queueName));
+            return val.IsNullOrEmpty ? null : val.ToString();
+        }
+
+        public long GetQueueLength(string queueName)
+        {
+            return _connectionManager.GetDatabase().ListLength(BuildKey(queueName));
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/IRateLimitingService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/IRateLimitingService.cs
new file mode 100644
index 0000000..ff0d52c
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/IRateLimitingService.cs
@@ -0,0 +1,25 @@
+namespace WIDESEAWCS_RedisService.RateLimiting
+{
+    public interface IRateLimitingService
+    {
+        /// <summary>
+        /// 鍥哄畾绐楀彛闄愭祦
+        /// </summary>
+        bool IsAllowed(string key, int maxRequests, TimeSpan window);
+
+        /// <summary>
+        /// 婊戝姩绐楀彛闄愭祦
+        /// </summary>
+        bool IsAllowedSliding(string key, int maxRequests, TimeSpan window);
+
+        /// <summary>
+        /// 浠ょ墝妗堕檺娴�
+        /// </summary>
+        bool TryAcquireToken(string key, int maxTokens, int refillRate, TimeSpan refillInterval);
+
+        /// <summary>
+        /// 鑾峰彇鍓╀綑璇锋眰鏁�
+        /// </summary>
+        long GetRemainingRequests(string key, int maxRequests, TimeSpan window);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/RedisRateLimitingService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/RedisRateLimitingService.cs
new file mode 100644
index 0000000..ec3c47f
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/RateLimiting/RedisRateLimitingService.cs
@@ -0,0 +1,113 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.RateLimiting
+{
+    public class RedisRateLimitingService : IRateLimitingService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisRateLimitingService> _logger;
+
+        private const string FixedWindowScript = @"
+            local key = KEYS[1]
+            local limit = tonumber(ARGV[1])
+            local window = tonumber(ARGV[2])
+            local current = tonumber(redis.call('GET', key) or '0')
+            if current < limit then
+                redis.call('INCR', key)
+                if current == 0 then
+                    redis.call('PEXPIRE', key, window)
+                end
+                return 1
+            end
+            return 0";
+
+        public RedisRateLimitingService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisRateLimitingService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}rate:{key}";
+
+        public bool IsAllowed(string key, int maxRequests, TimeSpan window)
+        {
+            var db = _connectionManager.GetDatabase();
+            var result = db.ScriptEvaluate(
+                FixedWindowScript,
+                new RedisKey[] { BuildKey(key) },
+                new RedisValue[] { maxRequests, (long)window.TotalMilliseconds });
+            return (long)result == 1;
+        }
+
+        public bool IsAllowedSliding(string key, int maxRequests, TimeSpan window)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(key);
+            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            var windowMs = (long)window.TotalMilliseconds;
+
+            var tran = db.CreateTransaction();
+            tran.SortedSetRemoveRangeByScoreAsync(fullKey, 0, now - windowMs);
+            tran.SortedSetAddAsync(fullKey, now.ToString(), now);
+            tran.KeyExpireAsync(fullKey, window.Add(TimeSpan.FromSeconds(1)));
+            tran.Execute();
+
+            var count = db.SortedSetLength(fullKey);
+            if (count > maxRequests)
+            {
+                db.SortedSetRemove(fullKey, now.ToString());
+                return false;
+            }
+            return true;
+        }
+
+        public bool TryAcquireToken(string key, int maxTokens, int refillRate, TimeSpan refillInterval)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey($"token:{key}");
+            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+            var script = @"
+                local key = KEYS[1]
+                local max = tonumber(ARGV[1])
+                local rate = tonumber(ARGV[2])
+                local interval = tonumber(ARGV[3])
+                local now = tonumber(ARGV[4])
+                local info = redis.call('HMGET', key, 'tokens', 'last')
+                local tokens = tonumber(info[1]) or max
+                local last = tonumber(info[2]) or now
+                local elapsed = now - last
+                local refill = math.floor(elapsed / interval) * rate
+                tokens = math.min(max, tokens + refill)
+                if tokens > 0 then
+                    tokens = tokens - 1
+                    redis.call('HMSET', key, 'tokens', tokens, 'last', now)
+                    redis.call('PEXPIRE', key, interval * max / rate * 2)
+                    return 1
+                end
+                return 0";
+
+            var result = db.ScriptEvaluate(script,
+                new RedisKey[] { fullKey },
+                new RedisValue[] { maxTokens, refillRate, (long)refillInterval.TotalMilliseconds, now });
+            return (long)result == 1;
+        }
+
+        public long GetRemainingRequests(string key, int maxRequests, TimeSpan window)
+        {
+            var db = _connectionManager.GetDatabase();
+            var val = db.StringGet(BuildKey(key));
+            if (val.IsNullOrEmpty) return maxRequests;
+            return Math.Max(0, maxRequests - (long)val);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/IRedisSerializer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/IRedisSerializer.cs
new file mode 100644
index 0000000..d93ef7e
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/IRedisSerializer.cs
@@ -0,0 +1,11 @@
+namespace WIDESEAWCS_RedisService.Serialization
+{
+    public interface IRedisSerializer
+    {
+        string Serialize<T>(T value);
+
+        T? Deserialize<T>(string value);
+
+        object? Deserialize(string value, Type type);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/NewtonsoftRedisSerializer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/NewtonsoftRedisSerializer.cs
new file mode 100644
index 0000000..c2a11ff
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Serialization/NewtonsoftRedisSerializer.cs
@@ -0,0 +1,31 @@
+using Newtonsoft.Json;
+
+namespace WIDESEAWCS_RedisService.Serialization
+{
+    public class NewtonsoftRedisSerializer : IRedisSerializer
+    {
+        private static readonly JsonSerializerSettings _settings = new()
+        {
+            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+            NullValueHandling = NullValueHandling.Ignore,
+            DateFormatString = "yyyy-MM-dd HH:mm:ss"
+        };
+
+        public string Serialize<T>(T value)
+        {
+            return JsonConvert.SerializeObject(value, _settings);
+        }
+
+        public T? Deserialize<T>(string value)
+        {
+            if (string.IsNullOrEmpty(value)) return default;
+            return JsonConvert.DeserializeObject<T>(value, _settings);
+        }
+
+        public object? Deserialize(string value, Type type)
+        {
+            if (string.IsNullOrEmpty(value)) return null;
+            return JsonConvert.DeserializeObject(value, type, _settings);
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/ISessionStorage.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/ISessionStorage.cs
new file mode 100644
index 0000000..82e2c73
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/ISessionStorage.cs
@@ -0,0 +1,12 @@
+namespace WIDESEAWCS_RedisService.Session
+{
+    public interface ISessionStorage
+    {
+        bool Set(string sessionId, string key, string value, TimeSpan? expiry = null);
+        string? Get(string sessionId, string key);
+        bool Remove(string sessionId, string key);
+        bool DestroySession(string sessionId);
+        bool SessionExists(string sessionId);
+        bool RefreshSession(string sessionId, TimeSpan expiry);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/RedisSessionStorage.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/RedisSessionStorage.cs
new file mode 100644
index 0000000..953ddb7
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Session/RedisSessionStorage.cs
@@ -0,0 +1,63 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Session
+{
+    public class RedisSessionStorage : ISessionStorage
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisSessionStorage> _logger;
+
+        public RedisSessionStorage(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisSessionStorage> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string sessionId) => $"{_options.KeyPrefix}session:{sessionId}";
+
+        public bool Set(string sessionId, string key, string value, TimeSpan? expiry = null)
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(sessionId);
+            db.HashSet(fullKey, key, value);
+            if (expiry.HasValue)
+                db.KeyExpire(fullKey, expiry);
+            return true;
+        }
+
+        public string? Get(string sessionId, string key)
+        {
+            var val = _connectionManager.GetDatabase().HashGet(BuildKey(sessionId), key);
+            return val.IsNullOrEmpty ? null : val.ToString();
+        }
+
+        public bool Remove(string sessionId, string key)
+        {
+            return _connectionManager.GetDatabase().HashDelete(BuildKey(sessionId), key);
+        }
+
+        public bool DestroySession(string sessionId)
+        {
+            return _connectionManager.GetDatabase().KeyDelete(BuildKey(sessionId));
+        }
+
+        public bool SessionExists(string sessionId)
+        {
+            return _connectionManager.GetDatabase().KeyExists(BuildKey(sessionId));
+        }
+
+        public bool RefreshSession(string sessionId, TimeSpan expiry)
+        {
+            return _connectionManager.GetDatabase().KeyExpire(BuildKey(sessionId), expiry);
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/IObjectStorageService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/IObjectStorageService.cs
new file mode 100644
index 0000000..b5db548
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/IObjectStorageService.cs
@@ -0,0 +1,40 @@
+namespace WIDESEAWCS_RedisService.Storage
+{
+    public interface IObjectStorageService
+    {
+        /// <summary>
+        /// 瀛樺偍瀵硅薄锛圚ash缁撴瀯锛�
+        /// </summary>
+        bool SetObject<T>(string key, T value, TimeSpan? expiry = null) where T : class;
+
+        /// <summary>
+        /// 鑾峰彇瀵硅薄
+        /// </summary>
+        T? GetObject<T>(string key) where T : class;
+
+        /// <summary>
+        /// 璁剧疆瀵硅薄鐨勬煇涓瓧娈�
+        /// </summary>
+        bool SetField(string key, string field, string value);
+
+        /// <summary>
+        /// 鑾峰彇瀵硅薄鐨勬煇涓瓧娈�
+        /// </summary>
+        string? GetField(string key, string field);
+
+        /// <summary>
+        /// 鍒犻櫎瀵硅薄
+        /// </summary>
+        bool Delete(string key);
+
+        /// <summary>
+        /// 鍒犻櫎瀵硅薄鐨勬煇涓瓧娈�
+        /// </summary>
+        bool DeleteField(string key, string field);
+
+        /// <summary>
+        /// 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        /// </summary>
+        bool Exists(string key);
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/RedisObjectStorageService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/RedisObjectStorageService.cs
new file mode 100644
index 0000000..fb176d9
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Storage/RedisObjectStorageService.cs
@@ -0,0 +1,71 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+using WIDESEAWCS_RedisService.Serialization;
+
+namespace WIDESEAWCS_RedisService.Storage
+{
+    public class RedisObjectStorageService : IObjectStorageService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly IRedisSerializer _serializer;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisObjectStorageService> _logger;
+
+        public RedisObjectStorageService(
+            IRedisConnectionManager connectionManager,
+            IRedisSerializer serializer,
+            IOptions<RedisOptions> options,
+            ILogger<RedisObjectStorageService> logger)
+        {
+            _connectionManager = connectionManager;
+            _serializer = serializer;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}obj:{key}";
+
+        public bool SetObject<T>(string key, T value, TimeSpan? expiry = null) where T : class
+        {
+            var db = _connectionManager.GetDatabase();
+            var fullKey = BuildKey(key);
+            var json = _serializer.Serialize(value);
+            return db.StringSet(fullKey, json, expiry);
+        }
+
+        public T? GetObject<T>(string key) where T : class
+        {
+            var val = _connectionManager.GetDatabase().StringGet(BuildKey(key));
+            return val.IsNullOrEmpty ? default : _serializer.Deserialize<T>(val!);
+        }
+
+        public bool SetField(string key, string field, string value)
+        {
+            return _connectionManager.GetDatabase().HashSet(BuildKey(key), field, value);
+        }
+
+        public string? GetField(string key, string field)
+        {
+            var val = _connectionManager.GetDatabase().HashGet(BuildKey(key), field);
+            return val.IsNullOrEmpty ? null : val.ToString();
+        }
+
+        public bool Delete(string key)
+        {
+            return _connectionManager.GetDatabase().KeyDelete(BuildKey(key));
+        }
+
+        public bool DeleteField(string key, string field)
+        {
+            return _connectionManager.GetDatabase().HashDelete(BuildKey(key), field);
+        }
+
+        public bool Exists(string key)
+        {
+            return _connectionManager.GetDatabase().KeyExists(BuildKey(key));
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/IStreamProcessingService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/IStreamProcessingService.cs
new file mode 100644
index 0000000..c938546
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/IStreamProcessingService.cs
@@ -0,0 +1,41 @@
+namespace WIDESEAWCS_RedisService.Stream
+{
+    public interface IStreamProcessingService
+    {
+        /// <summary>
+        /// 鍙戦�佹秷鎭埌Stream
+        /// </summary>
+        string AddMessage(string streamKey, Dictionary<string, string> fields);
+
+        /// <summary>
+        /// 鍒涘缓娑堣垂鑰呯粍
+        /// </summary>
+        bool CreateConsumerGroup(string streamKey, string groupName, string startId = "$");
+
+        /// <summary>
+        /// 璇诲彇娑堟伅锛堟秷璐硅�呯粍妯″紡锛�
+        /// </summary>
+        List<StreamEntry> ReadGroup(string streamKey, string groupName, string consumerName, int count = 10);
+
+        /// <summary>
+        /// 纭娑堟伅
+        /// </summary>
+        long Acknowledge(string streamKey, string groupName, params string[] messageIds);
+
+        /// <summary>
+        /// 鑾峰彇Stream闀垮害
+        /// </summary>
+        long GetStreamLength(string streamKey);
+
+        /// <summary>
+        /// 瑁佸壀Stream
+        /// </summary>
+        long TrimStream(string streamKey, int maxLength);
+    }
+
+    public class StreamEntry
+    {
+        public string Id { get; set; } = string.Empty;
+        public Dictionary<string, string> Fields { get; set; } = new();
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/RedisStreamProcessingService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/RedisStreamProcessingService.cs
new file mode 100644
index 0000000..a10c568
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/Stream/RedisStreamProcessingService.cs
@@ -0,0 +1,76 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using StackExchange.Redis;
+using WIDESEAWCS_RedisService.Connection;
+using WIDESEAWCS_RedisService.Options;
+
+namespace WIDESEAWCS_RedisService.Stream
+{
+    public class RedisStreamProcessingService : IStreamProcessingService
+    {
+        private readonly IRedisConnectionManager _connectionManager;
+        private readonly RedisOptions _options;
+        private readonly ILogger<RedisStreamProcessingService> _logger;
+
+        public RedisStreamProcessingService(
+            IRedisConnectionManager connectionManager,
+            IOptions<RedisOptions> options,
+            ILogger<RedisStreamProcessingService> logger)
+        {
+            _connectionManager = connectionManager;
+            _options = options.Value;
+            _logger = logger;
+        }
+
+        private string BuildKey(string key) => $"{_options.KeyPrefix}stream:{key}";
+
+        public string AddMessage(string streamKey, Dictionary<string, string> fields)
+        {
+            var entries = fields.Select(f => new NameValueEntry(f.Key, f.Value)).ToArray();
+            var id = _connectionManager.GetDatabase().StreamAdd(BuildKey(streamKey), entries);
+            return id.ToString();
+        }
+
+        public bool CreateConsumerGroup(string streamKey, string groupName, string startId = "$")
+        {
+            try
+            {
+                return _connectionManager.GetDatabase()
+                    .StreamCreateConsumerGroup(BuildKey(streamKey), groupName, startId, true);
+            }
+            catch (RedisServerException ex) when (ex.Message.Contains("BUSYGROUP"))
+            {
+                _logger.LogWarning("娑堣垂鑰呯粍 {Group} 宸插瓨鍦�", groupName);
+                return true;
+            }
+        }
+
+        public List<StreamEntry> ReadGroup(string streamKey, string groupName, string consumerName, int count = 10)
+        {
+            var entries = _connectionManager.GetDatabase()
+                .StreamReadGroup(BuildKey(streamKey), groupName, consumerName, ">", count);
+
+            return entries?.Select(e => new StreamEntry
+            {
+                Id = e.Id.ToString(),
+                Fields = e.Values.ToDictionary(v => v.Name.ToString(), v => v.Value.ToString())
+            }).ToList() ?? new List<StreamEntry>();
+        }
+
+        public long Acknowledge(string streamKey, string groupName, params string[] messageIds)
+        {
+            var ids = messageIds.Select(id => new RedisValue(id)).ToArray();
+            return _connectionManager.GetDatabase().StreamAcknowledge(BuildKey(streamKey), groupName, ids);
+        }
+
+        public long GetStreamLength(string streamKey)
+        {
+            return _connectionManager.GetDatabase().StreamLength(BuildKey(streamKey));
+        }
+
+        public long TrimStream(string streamKey, int maxLength)
+        {
+            return _connectionManager.GetDatabase().StreamTrim(BuildKey(streamKey), maxLength);
+        }
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/WIDESEAWCS_RedisService.csproj b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/WIDESEAWCS_RedisService.csproj
new file mode 100644
index 0000000..428d0ea
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_RedisService/WIDESEAWCS_RedisService.csproj
@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<TargetFramework>net6.0</TargetFramework>
+		<ImplicitUsings>enable</ImplicitUsings>
+		<Nullable>enable</Nullable>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="StackExchange.Redis" Version="2.7.33" />
+		<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+		<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
+		<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
+		<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
+	</ItemGroup>
+
+	<ItemGroup>
+		<ProjectReference Include="..\WIDESEAWCS_Core\WIDESEAWCS_Core.csproj" />
+	</ItemGroup>
+
+</Project>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln
index 476b4cd..795321d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln
@@ -64,92 +64,270 @@
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WIDESEAWCS_BasicInfoService", "WIDESEAWCS_BasicInfoService\WIDESEAWCS_BasicInfoService.csproj", "{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WIDESEAWCS_RedisService", "WIDESEAWCS_RedisService\WIDESEAWCS_RedisService.csproj", "{F9886971-C3B2-4334-B014-D5109F2041DE}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
 		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|x64.Build.0 = Debug|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Debug|x86.Build.0 = Debug|Any CPU
 		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|x64.ActiveCfg = Release|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|x64.Build.0 = Release|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|x86.ActiveCfg = Release|Any CPU
+		{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}.Release|x86.Build.0 = Release|Any CPU
 		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|x64.Build.0 = Debug|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Debug|x86.Build.0 = Debug|Any CPU
 		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|x64.ActiveCfg = Release|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|x64.Build.0 = Release|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|x86.ActiveCfg = Release|Any CPU
+		{294E4915-0241-4C8C-BA99-7588B945863A}.Release|x86.Build.0 = Release|Any CPU
 		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|x64.Build.0 = Debug|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Debug|x86.Build.0 = Debug|Any CPU
 		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|x64.ActiveCfg = Release|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|x64.Build.0 = Release|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|x86.ActiveCfg = Release|Any CPU
+		{6236BFFF-173D-44A8-9FC3-7C001EA30347}.Release|x86.Build.0 = Release|Any CPU
 		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|x64.Build.0 = Debug|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Debug|x86.Build.0 = Debug|Any CPU
 		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|x64.ActiveCfg = Release|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|x64.Build.0 = Release|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|x86.ActiveCfg = Release|Any CPU
+		{7F200FE8-CAF6-4131-BD25-8D438FE0ABAC}.Release|x86.Build.0 = Release|Any CPU
 		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|x64.Build.0 = Debug|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Debug|x86.Build.0 = Debug|Any CPU
 		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|x64.ActiveCfg = Release|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|x64.Build.0 = Release|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|x86.ActiveCfg = Release|Any CPU
+		{C2D3D138-9109-481B-8BEB-A27597890B2C}.Release|x86.Build.0 = Release|Any CPU
 		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|x64.Build.0 = Debug|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Debug|x86.Build.0 = Debug|Any CPU
 		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|x64.ActiveCfg = Release|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|x64.Build.0 = Release|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|x86.ActiveCfg = Release|Any CPU
+		{BFFDD936-2E61-4D3A-ABFE-7CF77FE0B184}.Release|x86.Build.0 = Release|Any CPU
 		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|x64.Build.0 = Debug|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Debug|x86.Build.0 = Debug|Any CPU
 		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|x64.ActiveCfg = Release|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|x64.Build.0 = Release|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|x86.ActiveCfg = Release|Any CPU
+		{861C4D0B-A478-48DB-A0FA-AE70F5BA210A}.Release|x86.Build.0 = Release|Any CPU
 		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|x64.Build.0 = Debug|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Debug|x86.Build.0 = Debug|Any CPU
 		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|x64.ActiveCfg = Release|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|x64.Build.0 = Release|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|x86.ActiveCfg = Release|Any CPU
+		{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}.Release|x86.Build.0 = Release|Any CPU
 		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|x64.Build.0 = Debug|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Debug|x86.Build.0 = Debug|Any CPU
 		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|x64.ActiveCfg = Release|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|x64.Build.0 = Release|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|x86.ActiveCfg = Release|Any CPU
+		{F302E6D6-5A95-4D22-8DC2-21BE2CB30275}.Release|x86.Build.0 = Release|Any CPU
 		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|x64.Build.0 = Debug|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Debug|x86.Build.0 = Debug|Any CPU
 		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|x64.ActiveCfg = Release|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|x64.Build.0 = Release|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|x86.ActiveCfg = Release|Any CPU
+		{5777BDEC-4726-4425-85F2-A090524F692D}.Release|x86.Build.0 = Release|Any CPU
 		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|x64.Build.0 = Debug|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Debug|x86.Build.0 = Debug|Any CPU
 		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|Any CPU.Build.0 = Release|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|x64.ActiveCfg = Release|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|x64.Build.0 = Release|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|x86.ActiveCfg = Release|Any CPU
+		{09D05F35-CEA2-48D9-86D0-FB95982BA511}.Release|x86.Build.0 = Release|Any CPU
 		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|x64.Build.0 = Debug|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Debug|x86.Build.0 = Debug|Any CPU
 		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|Any CPU.Build.0 = Release|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|x64.ActiveCfg = Release|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|x64.Build.0 = Release|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|x86.ActiveCfg = Release|Any CPU
+		{35054AA5-CF40-4F38-9414-C76742C29382}.Release|x86.Build.0 = Release|Any CPU
 		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|x64.Build.0 = Debug|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Debug|x86.Build.0 = Debug|Any CPU
 		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|x64.ActiveCfg = Release|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|x64.Build.0 = Release|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|x86.ActiveCfg = Release|Any CPU
+		{9E4BFF47-52BF-4FD8-9CC7-3763BF19D9E0}.Release|x86.Build.0 = Release|Any CPU
 		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|x64.Build.0 = Debug|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Debug|x86.Build.0 = Debug|Any CPU
 		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|x64.ActiveCfg = Release|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|x64.Build.0 = Release|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|x86.ActiveCfg = Release|Any CPU
+		{A14242DD-DA06-4DC3-8598-1761AA7C76D1}.Release|x86.Build.0 = Release|Any CPU
 		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|x64.Build.0 = Debug|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Debug|x86.Build.0 = Debug|Any CPU
 		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|x64.ActiveCfg = Release|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|x64.Build.0 = Release|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|x86.ActiveCfg = Release|Any CPU
+		{7279A2AE-8D1F-4E66-A73A-01AF7927A336}.Release|x86.Build.0 = Release|Any CPU
 		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|x64.Build.0 = Debug|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Debug|x86.Build.0 = Debug|Any CPU
 		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|x64.ActiveCfg = Release|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|x64.Build.0 = Release|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|x86.ActiveCfg = Release|Any CPU
+		{83F18A31-5983-4587-A0B2-414BF70E50B5}.Release|x86.Build.0 = Release|Any CPU
 		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|x64.Build.0 = Debug|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Debug|x86.Build.0 = Debug|Any CPU
 		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|Any CPU.Build.0 = Release|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|x64.ActiveCfg = Release|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|x64.Build.0 = Release|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|x86.ActiveCfg = Release|Any CPU
+		{266D07B7-3648-4F3D-818A-89EDA7D84C58}.Release|x86.Build.0 = Release|Any CPU
 		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|x64.Build.0 = Debug|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Debug|x86.Build.0 = Debug|Any CPU
 		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|Any CPU.Build.0 = Release|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|x64.ActiveCfg = Release|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|x64.Build.0 = Release|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|x86.ActiveCfg = Release|Any CPU
+		{206FDF79-9BF3-433A-B7FF-627287BBD760}.Release|x86.Build.0 = Release|Any CPU
 		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|x64.Build.0 = Debug|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Debug|x86.Build.0 = Debug|Any CPU
 		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|x64.ActiveCfg = Release|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|x64.Build.0 = Release|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|x86.ActiveCfg = Release|Any CPU
+		{8C2CC25B-DE5D-433E-A550-63864C7A716D}.Release|x86.Build.0 = Release|Any CPU
 		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|x64.Build.0 = Debug|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Debug|x86.Build.0 = Debug|Any CPU
 		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|x64.ActiveCfg = Release|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|x64.Build.0 = Release|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|x86.ActiveCfg = Release|Any CPU
+		{FFAB2C76-1C9E-4006-95C8-A0B2AA53139D}.Release|x86.Build.0 = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|x64.Build.0 = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Debug|x86.Build.0 = Debug|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|x64.ActiveCfg = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|x64.Build.0 = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|x86.ActiveCfg = Release|Any CPU
+		{F9886971-C3B2-4334-B014-D5109F2041DE}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
index 9e0ec7e..a33363b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
@@ -27,14 +27,15 @@
 using WIDESEAWCS_Server.Filter;
 using WIDESEAWCS_Server.HostedService;
 using WIDESEAWCS_Tasks.SocketServer;
+using WIDESEAWCS_RedisService.Extensions;
 using WIDESEAWCS_WCSServer.Filter;
 
 var builder = WebApplication.CreateBuilder(args);
-// 1、配置服务容器
+// 1锟斤拷锟斤拷锟矫凤拷锟斤拷锟斤拷锟斤拷
 
 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(builder =>
 {
-    builder.RegisterModule(new AutofacModuleRegister());//带有接口层的服务注入
+    builder.RegisterModule(new AutofacModuleRegister());//锟斤拷锟叫接口诧拷姆锟斤拷锟阶拷锟�
     builder.RegisterModule(new QuartzJobAutofacModuleRegister());
     builder.RegisterModule<AutofacPropertityModuleReg>();//
 }).ConfigureAppConfiguration((hostingContext, config) =>
@@ -45,20 +46,21 @@
 });
 builder.ConfigureApplication();
 
-// 2、配置服务
-builder.Services.AddSingleton(new AppSettings(builder.Configuration));//注册
-builder.Services.AddAllOptionRegister();//读取配置文件
+// 2锟斤拷锟斤拷锟矫凤拷锟斤拷
+builder.Services.AddSingleton(new AppSettings(builder.Configuration));//注锟斤拷
+builder.Services.AddAllOptionRegister();//锟斤拷取锟斤拷锟斤拷锟侥硷拷
 
 
-builder.Services.AddMemoryCacheSetup();//缓存
-builder.Services.AddSqlsugarSetup();//SqlSugar 启动服务
-builder.Services.AddInitializationHostServiceSetup();//应用初始化服务注入
-builder.Services.AddHostedService<SeedDataHostedService>();//初始化数据库
+builder.Services.AddMemoryCacheSetup();//锟斤拷锟斤拷
+builder.Services.AddRedisSetup(builder.Configuration);//Redis缂撳瓨
+builder.Services.AddSqlsugarSetup();//SqlSugar 锟斤拷锟斤拷锟斤拷锟斤拷
+builder.Services.AddInitializationHostServiceSetup();//应锟矫筹拷始锟斤拷锟斤拷锟斤拷注锟斤拷
+builder.Services.AddHostedService<SeedDataHostedService>();//锟斤拷始锟斤拷锟斤拷锟捷匡拷
 
-builder.Services.AddDbSetup();//Db 启动服务
+builder.Services.AddDbSetup();//Db 锟斤拷锟斤拷锟斤拷锟斤拷
 
-builder.Services.AddScoped<QuartzJobCreateDataTabel>();//任务调度 注入创建QuartzJob数据库表类
-builder.Services.AddHostedService<QuartzJobDataTableHostedService>();//任务调度 映射QuartzJob数据库表
+builder.Services.AddScoped<QuartzJobCreateDataTabel>();//锟斤拷锟斤拷锟斤拷锟� 注锟诫创锟斤拷QuartzJob锟斤拷锟捷匡拷锟斤拷锟�
+builder.Services.AddHostedService<QuartzJobDataTableHostedService>();//锟斤拷锟斤拷锟斤拷锟� 映锟斤拷QuartzJob锟斤拷锟捷匡拷锟�
 
 builder.Services.AddWebSocketSetup();
 
@@ -70,11 +72,11 @@
 
 builder.Services.AddSwaggerSetup();
 
-builder.Services.AddJobSetup();//任务调度 注入反射获取依赖对象
+builder.Services.AddJobSetup();//锟斤拷锟斤拷锟斤拷锟� 注锟诫反锟斤拷锟饺★拷锟斤拷锟斤拷锟斤拷锟�
 
 builder.Services.AddHttpContextSetup();
 
-builder.Services.AddHostedService<QuartzJobHostedService>();//任务调度 启动服务
+builder.Services.AddHostedService<QuartzJobHostedService>();//锟斤拷锟斤拷锟斤拷锟� 锟斤拷锟斤拷锟斤拷锟斤拷
 builder.Services.AddSingleton<TcpSocketServer>();
 builder.Services.AddHostedService<SocketServerHostedService>();
 
@@ -89,7 +91,7 @@
 
 builder.Services.AddAuthorizationSetup();
 
-builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration);//IPLimit限流 启动服务
+builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration);//IPLimit锟斤拷锟斤拷 锟斤拷锟斤拷锟斤拷锟斤拷
 
 builder.Services.AddScoped<UseServiceDIAttribute>();
 
@@ -99,7 +101,7 @@
 
 builder.Services.AddControllers(o =>
 {
-    o.Filters.Add(typeof(GlobalExceptionsFilter));//全局异常
+    o.Filters.Add(typeof(GlobalExceptionsFilter));//全锟斤拷锟届常
 })
 .AddNewtonsoftJson(options =>
 {
@@ -120,17 +122,17 @@
 
 var app = builder.Build();
 
-// 3、配置中间件
-app.UseMiniProfiler();//性能分析器
-app.ConfigureApplication();//配置文件
-app.UseApplicationSetup();//启动配置
+// 3锟斤拷锟斤拷锟斤拷锟叫硷拷锟�
+app.UseMiniProfiler();//锟斤拷锟杰凤拷锟斤拷锟斤拷
+app.ConfigureApplication();//锟斤拷锟斤拷锟侥硷拷
+app.UseApplicationSetup();//锟斤拷锟斤拷锟斤拷锟斤拷
 
 app.UseAllServicesMiddle(builder.Services);
 
 app.UseSession();
 
 app.UseSwaggerAuthorized();
-app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WIDESEAWCS_Server.index.html") ?? throw new Exception("未找到WIDESEAWCS_Server.index.html文件"));
+app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WIDESEAWCS_Server.index.html") ?? throw new Exception("未锟揭碉拷WIDESEAWCS_Server.index.html锟侥硷拷"));
 
 app.UseIpLimitMiddle();
 app.UseApiLogMiddleware();
diff --git "a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Redis\344\275\277\347\224\250\346\241\210\344\276\213.md" "b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Redis\344\275\277\347\224\250\346\241\210\344\276\213.md"
new file mode 100644
index 0000000..8f86a1b
--- /dev/null
+++ "b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Redis\344\275\277\347\224\250\346\241\210\344\276\213.md"
@@ -0,0 +1,380 @@
+# Redis 鏈嶅姟浣跨敤妗堜緥
+
+## 1. 缂撳瓨锛圛CacheService锛�
+
+閫氳繃鏋勯�犲嚱鏁版敞鍏� `ICacheService`锛孒ybridCacheService 鑷姩瀹炵幇 L1(鍐呭瓨) + L2(Redis) 鍙屽眰缂撳瓨銆�
+
+```csharp
+public class MyService
+{
+    private readonly ICacheService _cache;
+
+    public MyService(ICacheService cache)
+    {
+        _cache = cache;
+    }
+
+    // 缂撳瓨瀛楃涓诧紝60绉掕繃鏈�
+    public void CacheString()
+    {
+        _cache.Add("token:10001", "abc123", 60);
+        var token = _cache.Get("token:10001");
+    }
+
+    // 缂撳瓨瀵硅薄
+    public void CacheObject()
+    {
+        var user = new { Id = 1, Name = "寮犱笁" };
+        _cache.AddObject("user:1", user, 300);
+        var cached = _cache.Get<dynamic>("user:1");
+    }
+
+    // 鍒犻櫎缂撳瓨
+    public void RemoveCache()
+    {
+        _cache.Remove("user:1");
+        _cache.Remove(new[] { "token:10001", "token:10002" });
+    }
+}
+```
+
+## 2. 鍒嗗竷寮忛攣锛圛DistributedLockService锛�
+
+```csharp
+public class OrderService
+{
+    private readonly IDistributedLockService _lock;
+
+    public OrderService(IDistributedLockService lockService)
+    {
+        _lock = lockService;
+    }
+
+    // 鏂瑰紡涓�锛氭墜鍔ㄨ幏鍙栧拰閲婃斁閿�
+    public void ProcessOrder(string orderId)
+    {
+        var token = _lock.AcquireLock($"order:{orderId}", TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5));
+        if (token == null)
+        {
+            Console.WriteLine("鑾峰彇閿佸け璐ワ紝鍏朵粬杩涚▼姝e湪澶勭悊");
+            return;
+        }
+        try
+        {
+            // 涓氬姟閫昏緫...
+        }
+        finally
+        {
+            _lock.ReleaseLock($"order:{orderId}", token);
+        }
+    }
+
+    // 鏂瑰紡浜岋細鑷姩绠$悊閿佺殑鐢熷懡鍛ㄦ湡
+    public void ProcessOrderAuto(string orderId)
+    {
+        var success = _lock.ExecuteWithLock($"order:{orderId}", TimeSpan.FromSeconds(30), () =>
+        {
+            // 涓氬姟閫昏緫...
+        });
+    }
+}
+```
+
+## 3. 璁℃暟鍣紙ICounterService锛�
+
+```csharp
+public class StatisticsService
+{
+    private readonly ICounterService _counter;
+
+    public StatisticsService(ICounterService counter)
+    {
+        _counter = counter;
+    }
+
+    // 浠诲姟璁℃暟
+    public void OnTaskCompleted()
+    {
+        _counter.Increment("task:completed");
+        var total = _counter.GetCount("task:completed");
+    }
+
+    // 甯﹁繃鏈熸椂闂寸殑璁℃暟锛堝锛氭瘡灏忔椂璇锋眰鏁帮級
+    public void OnApiRequest()
+    {
+        var count = _counter.IncrementWithExpiry("api:hourly", TimeSpan.FromHours(1));
+    }
+}
+```
+
+## 4. 鍙戝竷/璁㈤槄锛圛MessageQueueService锛�
+
+```csharp
+public class NotificationService
+{
+    private readonly IMessageQueueService _mq;
+
+    public NotificationService(IMessageQueueService mq)
+    {
+        _mq = mq;
+    }
+
+    // 鍙戝竷娑堟伅
+    public void NotifyTaskComplete(int taskId)
+    {
+        _mq.Publish("task:complete", $"{{\"taskId\":{taskId}}}");
+    }
+
+    // 璁㈤槄娑堟伅
+    public void SubscribeTaskEvents()
+    {
+        _mq.Subscribe("task:complete", (channel, message) =>
+        {
+            Console.WriteLine($"鏀跺埌浠诲姟瀹屾垚閫氱煡: {message}");
+        });
+    }
+
+    // 绠�鍗曢槦鍒楋細鍏ラ槦/鍑洪槦
+    public void UseQueue()
+    {
+        _mq.Enqueue("pending-tasks", "task_001");
+        var task = _mq.Dequeue("pending-tasks");
+    }
+}
+```
+
+## 5. 闄愭祦锛圛RateLimitingService锛�
+
+```csharp
+public class ApiController
+{
+    private readonly IRateLimitingService _rateLimiter;
+
+    public ApiController(IRateLimitingService rateLimiter)
+    {
+        _rateLimiter = rateLimiter;
+    }
+
+    // 鍥哄畾绐楀彛闄愭祦锛氭瘡鍒嗛挓鏈�澶�100娆�
+    public bool CheckRateLimit(string clientIp)
+    {
+        return _rateLimiter.IsAllowed($"api:{clientIp}", 100, TimeSpan.FromMinutes(1));
+    }
+
+    // 婊戝姩绐楀彛闄愭祦
+    public bool CheckSlidingRateLimit(string clientIp)
+    {
+        return _rateLimiter.IsAllowedSliding($"api:{clientIp}", 100, TimeSpan.FromMinutes(1));
+    }
+
+    // 浠ょ墝妗堕檺娴侊細妗跺閲�50锛屾瘡绉掕ˉ鍏�10涓�
+    public bool CheckTokenBucket(string clientIp)
+    {
+        return _rateLimiter.TryAcquireToken($"api:{clientIp}", 50, 10, TimeSpan.FromSeconds(1));
+    }
+}
+```
+
+## 6. 鍒嗗竷寮廔D鐢熸垚鍣紙IDistributedIdGenerator锛�
+
+```csharp
+public class TaskService
+{
+    private readonly IDistributedIdGenerator _idGen;
+
+    public TaskService(IDistributedIdGenerator idGen)
+    {
+        _idGen = idGen;
+    }
+
+    // 鑷ID
+    public long CreateTask()
+    {
+        var id = _idGen.NextId("task");
+        return id; // 1, 2, 3...
+    }
+
+    // 甯︽棩鏈熷墠缂�鐨処D
+    public string CreateTaskCode()
+    {
+        var code = _idGen.NextIdWithDate("task");
+        return code; // 20260302000001
+    }
+}
+```
+
+## 7. 鎺掕姒滐紙ILeaderboardService锛�
+
+```csharp
+public class LeaderboardDemo
+{
+    private readonly ILeaderboardService _board;
+
+    public LeaderboardDemo(ILeaderboardService board)
+    {
+        _board = board;
+    }
+
+    public void Demo()
+    {
+        // 娣诲姞/鏇存柊鍒嗘暟
+        _board.AddOrUpdate("efficiency", "璁惧A", 95.5);
+        _board.AddOrUpdate("efficiency", "璁惧B", 88.0);
+
+        // 澧炲姞鍒嗘暟
+        _board.IncrementScore("efficiency", "璁惧A", 2.0);
+
+        // 鑾峰彇鎺掑悕鍜孴op N
+        var rank = _board.GetRank("efficiency", "璁惧A"); // 0 = 绗竴鍚�
+        var top10 = _board.GetTopN("efficiency", 10);
+    }
+}
+```
+
+## 8. 瀵硅薄瀛樺偍锛圛ObjectStorageService锛�
+
+```csharp
+public class DeviceService
+{
+    private readonly IObjectStorageService _storage;
+
+    public DeviceService(IObjectStorageService storage)
+    {
+        _storage = storage;
+    }
+
+    public void Demo()
+    {
+        // 瀛樺偍瀹屾暣瀵硅薄
+        var device = new { Id = 1, Name = "鍫嗗灈鏈�01", Status = "Running" };
+        _storage.SetObject("device:1", device, TimeSpan.FromMinutes(30));
+
+        // 璇诲彇瀵硅薄
+        var cached = _storage.GetObject<dynamic>("device:1");
+
+        // Hash瀛楁鎿嶄綔
+        _storage.SetField("device:1:props", "temperature", "36.5");
+        var temp = _storage.GetField("device:1:props", "temperature");
+    }
+}
+```
+
+## 9. 閰嶇疆涓績锛圛ConfigurationCenterService锛�
+
+```csharp
+public class ConfigDemo
+{
+    private readonly IConfigurationCenterService _config;
+
+    public ConfigDemo(IConfigurationCenterService config)
+    {
+        _config = config;
+    }
+
+    public void Demo()
+    {
+        // 璁剧疆閰嶇疆
+        _config.Set("system", "MaxTaskCount", "100");
+        _config.Set("system", "EnableAutoDispatch", "true");
+
+        // 璇诲彇閰嶇疆
+        var maxTask = _config.Get("system", "MaxTaskCount");
+        var allConfig = _config.GetSection("system");
+
+        // 鐩戝惉閰嶇疆鍙樻洿
+        _config.Subscribe("system", (key, value) =>
+        {
+            Console.WriteLine($"閰嶇疆鍙樻洿: {key} = {value}");
+        });
+    }
+}
+```
+
+## 10. 鐩戞帶锛圛RedisMonitorService锛�
+
+```csharp
+public class MonitorDemo
+{
+    private readonly IRedisMonitorService _monitor;
+
+    public MonitorDemo(IRedisMonitorService monitor)
+    {
+        _monitor = monitor;
+    }
+
+    public void Demo()
+    {
+        // 鍋ュ悍妫�鏌�
+        var healthy = _monitor.HealthCheck();
+
+        // 鍐呭瓨淇℃伅
+        var mem = _monitor.GetMemoryInfo();
+        Console.WriteLine($"鍐呭瓨浣跨敤: {mem.UsedMemoryHuman}, 浣跨敤鐜�: {mem.UsagePercent}%");
+
+        // 杩炴帴鏁板拰Key鏁伴噺
+        var clients = _monitor.GetClientCount();
+        var dbSize = _monitor.GetDbSize();
+    }
+}
+```
+
+## 11. Session瀛樺偍锛圛SessionStorage锛�
+
+```csharp
+public class SessionDemo
+{
+    private readonly ISessionStorage _session;
+
+    public SessionDemo(ISessionStorage session)
+    {
+        _session = session;
+    }
+
+    public void Demo()
+    {
+        var sid = Guid.NewGuid().ToString("N");
+
+        // 璁剧疆Session鏁版嵁锛�30鍒嗛挓杩囨湡
+        _session.Set(sid, "userId", "10001", TimeSpan.FromMinutes(30));
+        _session.Set(sid, "role", "admin");
+
+        // 璇诲彇
+        var userId = _session.Get(sid, "userId");
+
+        // 缁湡
+        _session.RefreshSession(sid, TimeSpan.FromMinutes(30));
+
+        // 閿�姣�
+        _session.DestroySession(sid);
+    }
+}
+```
+
+## 12. 甯冮殕杩囨护鍣紙IBloomFilterService锛�
+
+```csharp
+public class BloomFilterDemo
+{
+    private readonly IBloomFilterService _bloom;
+
+    public BloomFilterDemo(IBloomFilterService bloom)
+    {
+        _bloom = bloom;
+    }
+
+    // 闃叉缂撳瓨绌块��
+    public void Demo()
+    {
+        // 棰勭儹锛氬皢宸叉湁鏁版嵁鍔犲叆杩囨护鍣�
+        _bloom.AddRange("task:ids", new[] { "T001", "T002", "T003" });
+
+        // 鏌ヨ鍓嶅厛妫�鏌�
+        if (!_bloom.MayExist("task:ids", "T999"))
+        {
+            // 涓�瀹氫笉瀛樺湪锛岀洿鎺ヨ繑鍥烇紝閬垮厤鏌ヨ鏁版嵁搴�
+            return;
+        }
+        // 鍙兘瀛樺湪锛岀户缁煡璇㈡暟鎹簱...
+    }
+}
+```
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj
index 25ba69c..69ecb81 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server.csproj
@@ -73,6 +73,7 @@
 		<ProjectReference Include="..\WIDESEAWCS_SystemServices\WIDESEAWCS_SystemServices.csproj" />
 		<ProjectReference Include="..\WIDESEAWCs_TaskInfoService\WIDESEAWCs_TaskInfoService.csproj" />
 		<ProjectReference Include="..\WIDESEAWCS_Tasks\WIDESEAWCS_Tasks.csproj" />
+		<ProjectReference Include="..\WIDESEAWCS_RedisService\WIDESEAWCS_RedisService.csproj" />
 	</ItemGroup>
 
 	<ItemGroup>
@@ -105,4 +106,8 @@
 	  </EmbeddedResource>
 	</ItemGroup>
 
+	<ItemGroup>
+	  <Folder Include="Log\" />
+	</ItemGroup>
+
 </Project>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index 95b9cd2..d3da09b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -41,19 +41,48 @@
   "DBSeedEnable": false,
   "QuartzDBSeedEnable": false,
   "LogDeubgEnable": false, //鏄惁璁板綍璋冭瘯鏃ュ織
-  "PrintSql": true, //鎵撳嵃SQL璇彞
-  "LogAOPEnable": true, //鏄惁璁板綍AOP鏃ュ織
+  "PrintSql": false, //鎵撳嵃SQL璇彞
+  "LogAOPEnable": false, //鏄惁璁板綍AOP鏃ュ織
   "WebSocketEnable": true, //鏄惁寮�鍚疻ebSocket鏈嶅姟
   "WebSocketPort": 9296, //WebSocket鏈嶅姟绔彛
   "SocketServer": {
     "Enabled": true, //鏄惁鍚敤Socket鏈嶅姟鍣�
-    "Port": 2000,  //鐩戝惉绔彛
+    "Port": 2000, //鐩戝惉绔彛
     "IpAddress": "0.0.0.0", //鐩戝惉鍦板潃锛�
-    "Backlog": 1000,   //鏈�澶ц繛鎺ユ暟 
-    "EncodingName": "utf-8",  //缂栫爜鏂瑰紡
-    "AutoDetectEncoding": true,   //鏄惁鑷姩妫�娴嬬紪鐮�
-    "IdleTimeoutSeconds": 0,   //绌洪棽瓒呮椂鏃堕棿锛屽崟浣嶇锛�0琛ㄧず涓嶈秴鏃�
-    "EnableHeartbeat": true,   //鏄惁鍚敤蹇冭烦妫�娴�
-    "LogFilePath": "socketserver.log"  //鏃ュ織鏂囦欢璺緞
+    "Backlog": 1000, //鏈�澶ц繛鎺ユ暟 
+    "EncodingName": "utf-8", //缂栫爜鏂瑰紡
+    "AutoDetectEncoding": true, //鏄惁鑷姩妫�娴嬬紪鐮�
+    "IdleTimeoutSeconds": 0, //绌洪棽瓒呮椂鏃堕棿锛屽崟浣嶇锛�0琛ㄧず涓嶈秴鏃�
+    "EnableHeartbeat": true, //鏄惁鍚敤蹇冭烦妫�娴�
+    "LogFilePath": "socketserver.log" //鏃ュ織鏂囦欢璺緞
+  },
+  "CheckPalletPositions": [
+    {
+      "Code": "11068",
+      "WarehouseId": 1
+    }
+  ],
+  "RedisConfig": {
+    "Enabled": true, //鏄惁鍚敤Redis锛宖alse鏃朵粎浣跨敤鍐呭瓨缂撳瓨
+    "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,defaultDatabase=0,connectTimeout=5000,abortConnect=false", //Redis杩炴帴瀛楃涓�
+    "InstanceName": "WIDESEAWCS:", //瀹炰緥鍚嶇О锛岀敤浜庡尯鍒嗕笉鍚屽簲鐢�
+    "DefaultDatabase": 0, //榛樿鏁版嵁搴撶储寮曪紙0-15锛�
+    "EnableSentinel": false, //鏄惁鍚敤鍝ㄥ叺妯″紡
+    "SentinelMasterName": "mymaster", //鍝ㄥ叺涓昏妭鐐瑰悕绉�
+    "SentinelEndpoints": [], //鍝ㄥ叺鑺傜偣鍦板潃鍒楄〃锛屽 ["sentinel1:26379","sentinel2:26379"]
+    "PoolSize": 10, //杩炴帴姹犲ぇ灏�
+    "ConnectRetry": 3, //杩炴帴澶辫触閲嶈瘯娆℃暟
+    "SerializerType": "Newtonsoft", //搴忓垪鍖栨柟寮忥細Newtonsoft
+    "FallbackToMemory": true, //Redis涓嶅彲鐢ㄦ椂鏄惁闄嶇骇鍒板唴瀛樼紦瀛�
+    "KeyPrefix": "wcs:", //鍏ㄥ眬Key鍓嶇紑锛岀敤浜庨殧绂讳笉鍚岀郴缁熺殑鏁版嵁
+    "Monitoring": {
+      "Enabled": false, //鏄惁鍚敤鐩戞帶
+      "SlowLogThresholdMs": 100, //鎱㈡煡璇㈤槇鍊硷紙姣锛�
+      "HealthCheckIntervalSeconds": 30 //鍋ュ悍妫�鏌ラ棿闅旓紙绉掞級
+    },
+    "Eviction": {
+      "DefaultExpirationSeconds": 3600, //榛樿缂撳瓨杩囨湡鏃堕棿锛堢锛�
+      "MaxMemoryPolicy": "allkeys-lru" //鍐呭瓨娣樻卑绛栫暐锛歛llkeys-lru, volatile-lru, noeviction绛�
+    }
   }
 }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
index cb2da11..f8219c9 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
@@ -18,10 +18,15 @@
 #endregion << 鐗� 鏈� 娉� 閲� >>
 
 using AutoMapper;
+using Microsoft.Extensions.Configuration;
 using Quartz;
+using SqlSugar;
+using System.Text.Json;
+using WIDESEA_Core;
 using WIDESEAWCS_Common.TaskEnum;
 using WIDESEAWCS_Core;
 using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_DTO.TaskInfo;
 using WIDESEAWCS_ITaskInfoService;
 using WIDESEAWCS_Model.Models;
 using WIDESEAWCS_QuartzJob;
@@ -36,15 +41,17 @@
         private readonly ITaskExecuteDetailService _taskExecuteDetailService;
         private readonly IRouterService _routerService;
         private readonly IMapper _mapper;
-        ConveyorLineDispatchHandler _conveyorLineDispatch;
+        private ConveyorLineDispatchHandler _conveyorLineDispatch;
+        private readonly HttpClientHelper _httpClientHelper;
 
-        public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper)
+        public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, HttpClientHelper httpClientHelper)
         {
             _taskService = taskService;
             _taskExecuteDetailService = taskExecuteDetailService;
             _routerService = routerService;
             _mapper = mapper;
             _conveyorLineDispatch = new ConveyorLineDispatchHandler(_taskService, _taskExecuteDetailService, _routerService, _mapper);
+            _httpClientHelper = httpClientHelper;
         }
 
         public Task Execute(IJobExecutionContext context)
@@ -73,6 +80,38 @@
                         try
                         {
                             ConveyorLineTaskCommandNew command = conveyorLine.ReadCustomer<ConveyorLineTaskCommandNew>(childDeviceCode);
+
+                            #region 妫�鏌ョ壒瀹氫綅缃槸鍚︽湁鎵樼洏
+
+                            var checkPalletPositions = App.Configuration.GetSection("CheckPalletPositions")
+                                .Get<List<CheckPalletPosition>>() ?? new List<CheckPalletPosition>();
+
+                            if (checkPalletPositions.Any(x => x.Code == childDeviceCode))
+                            {
+                                if (command.CV_State.ObjToBool())
+                                {
+                                    var existingTask = _taskService.Repository.QueryFirst(x => x.TargetAddress == childDeviceCode);
+                                    if (existingTask.IsNullOrEmpty())
+                                    {
+                                        var position = checkPalletPositions.FirstOrDefault(x => x.Code == childDeviceCode);
+                                        var responseResult = _httpClientHelper.Post<WebResponseContent>("GetOutBoundTrayTaskAsync", new CreateTaskDto()
+                                        {
+                                            WarehouseId = position.WarehouseId,
+                                            TargetAddress = childDeviceCode
+                                        }.Serialize());
+
+                                        if (responseResult.IsSuccess && responseResult.Data.Status)
+                                        {
+                                            var wmsTask = JsonSerializer.Deserialize<List<WMSTaskDTO>>(responseResult.Data.Data.Serialize());
+                                            if (wmsTask != null)
+                                                _taskService.ReceiveWMSTask(wmsTask);
+                                        }
+                                    }
+                                }
+                            }
+
+                            #endregion
+
                             if (command == null || command.PLC_STB != 1)
                             {
                                 return;
@@ -97,7 +136,6 @@
                                 // 澶勭悊浠诲姟鐘舵��
                                 ProcessTaskState(conveyorLine, command, task, childDeviceCode);
                             }
-
                         }
                         catch (Exception innerEx)
                         {
@@ -112,7 +150,6 @@
             }
             return Task.CompletedTask;
         }
-
 
         /// <summary>
         /// 澶勭悊浠诲姟鐘舵��
@@ -158,7 +195,5 @@
                     break;
             }
         }
-
-
     }
 }
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLine/CheckPalletPosition.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLine/CheckPalletPosition.cs
new file mode 100644
index 0000000..85a4ade
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLine/CheckPalletPosition.cs
@@ -0,0 +1,9 @@
+namespace WIDESEAWCS_Tasks
+{
+    public class CheckPalletPosition
+    {
+        public string Code { get; set; } = string.Empty;
+
+        public int WarehouseId { get; set; } = 0;
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
index 7efce62..497a7ed 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
@@ -7,6 +7,7 @@
 using WIDESEAWCS_Common.HttpEnum;
 using WIDESEAWCS_Common.TaskEnum;
 using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.Caches;
 using WIDESEAWCS_Core.Helper;
 using WIDESEAWCS_Core.Http;
 using WIDESEAWCS_DTO.Stock;
@@ -26,20 +27,22 @@
         private const int MaxTaskTotalNum = 48;
 
         private readonly TcpSocketServer _TcpSocket;
-        private static readonly ConcurrentDictionary<string, RobotSocketState> _socketStates = new();
+        //private static readonly ConcurrentDictionary<string, RobotSocketState> _socketStates = new();
         private static int _eventSubscribedFlag;
 
         private readonly ITaskService _taskService;
         private readonly IRobotTaskService _robotTaskService;
+        private readonly ICacheService _cache;
 
         private static IRobotTaskService _latestRobotTaskService = null!;
         private static ITaskService _latestTaskService = null!;
 
-        public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService)
+        public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService, ICacheService cache)
         {
             _TcpSocket = TcpSocket;
             _robotTaskService = RobottaskService;
             _taskService = TaskService;
+            _cache = cache;
 
             _latestRobotTaskService = RobottaskService;
             _latestTaskService = TaskService;
@@ -57,7 +60,7 @@
             string ipAddress = robotCrane.IPAddress;
 
             // 鑾峰彇鎴栧垱寤虹姸鎬�
-            RobotSocketState state = _socketStates.GetOrAdd(ipAddress, _ => new RobotSocketState
+            RobotSocketState state = _cache.GetOrAdd(ipAddress, _ => new RobotSocketState
             {
                 IPAddress = ipAddress,
                 RobotCrane = robotCrane
@@ -66,87 +69,101 @@
             // 鏇存柊璁惧淇℃伅
             state.RobotCrane = robotCrane;
 
-            // 妫�鏌ユ槸鍚︽湁璇ュ鎴风杩炴帴
-            var clientIds = _TcpSocket.GetClientIds();
-            if (!clientIds.Contains(ipAddress))
+            try
             {
-                return;
-            }
 
-            // 璁㈤槄涓�娆� message 浜嬩欢锛堝叏灞�涓�娆★級
-            if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0)
-            {
-                _TcpSocket.MessageReceived += _TcpSocket_MessageReceived;
-                _TcpSocket.RobotReceived += _TcpSocket_RobotReceived;
-            }
-
-            if (!state.IsEventSubscribed)
-            {
-                if (_TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client))
+                // 妫�鏌ユ槸鍚︽湁璇ュ鎴风杩炴帴
+                var clientIds = _TcpSocket.GetClientIds();
+                if (!clientIds.Contains(ipAddress))
                 {
-                    _ = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state)
-                        .ContinueWith(t =>
-                        {
-                            if (t.IsFaulted)
-                                Console.WriteLine($"HandleClientAsync error: {t.Exception?.GetBaseException().Message}");
-                        }, TaskContinuationOptions.OnlyOnFaulted);
-                    state.IsEventSubscribed = true;
+                    return;
                 }
-            }
 
-            // 鑾峰彇浠诲姟骞剁紦瀛樺埌鐘舵�佷腑
-            Dt_RobotTask? task = GetTask(robotCrane);
-            if (task != null)
-            {
-                state.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode();
-                state.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() || task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode();
-                state.CurrentTask = task;
-                if (task.RobotTaskTotalNum <= MaxTaskTotalNum)
+                // 璁㈤槄涓�娆� message 浜嬩欢锛堝叏灞�涓�娆★級
+                if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0)
                 {
-                    // 澶勭悊姝e湪鎵ц鐨勪换鍔�
-                    if (state.RobotRunMode == 2 && state.RobotControlMode == 1 && state.OperStatus != "Running")
+                    _TcpSocket.MessageReceived += _TcpSocket_MessageReceived;
+                    _TcpSocket.RobotReceived += _TcpSocket_RobotReceived;
+                }
+
+                if (!state.IsEventSubscribed)
+                {
+                    if (_TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client))
                     {
-                        await Task.Delay(1000);
-                        if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
+                        _ = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state)
+                            .ContinueWith(t =>
+                            {
+                                if (t.IsFaulted)
+                                    Console.WriteLine($"HandleClientAsync error: {t.Exception?.GetBaseException().Message}");
+                            }, TaskContinuationOptions.OnlyOnFaulted);
+                        state.IsEventSubscribed = true;
+                    }
+                }
+
+                // 鑾峰彇浠诲姟骞剁紦瀛樺埌鐘舵�佷腑
+                Dt_RobotTask? task = GetTask(robotCrane);
+                if (task != null)
+                {
+                    state.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode();
+                    state.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() || task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode();
+                    state.CurrentTask = task;
+                    if (task.RobotTaskTotalNum <= MaxTaskTotalNum)
+                    {
+                        // 澶勭悊姝e湪鎵ц鐨勪换鍔�
+                        if (state.RobotRunMode == 2 && state.RobotControlMode == 1 && state.OperStatus != "Running")
                         {
-                            string taskString = $"Putbattery,{task.RobotTargetAddress}";
-                            bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
-                            if (result)
+                            await Task.Delay(1000);
+                            if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
+                            {
+                                string taskString = $"Putbattery,{task.RobotTargetAddress}";
+                                bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
+                                if (result)
+                                {
+                                    task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+                                    await _robotTaskService.UpdateRobotTaskAsync(task);
+                                }
+                            }
+                            else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
                             {
                                 task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                                 await _robotTaskService.UpdateRobotTaskAsync(task);
                             }
-                        }
-                        else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
-                        {
-                            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-                            await _robotTaskService.UpdateRobotTaskAsync(task);
-                        }
-                        else if (state.OperStatus == "Homed" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
-                        {
-                            // TODO 璇诲彇绾夸綋鐢垫睜鏉$爜锛屽彂閫佸彇鐢垫睜鎸囦护
-                            // 闅忔満鐢熸垚涓ゅぉ鎵樼洏鏉$爜瀛樻斁鍒颁袱涓彉閲忛噷闈�
-                            // 瀹氫箟鍓嶇紑锛堜緥濡傦細TRAY浠h〃鎵樼洏锛�
-                            string prefix = "TRAY";
-
-                            // 鐢熸垚涓や釜鎵樼洏鏉$爜
-                            string trayBarcode1 = GenerateTrayBarcode(state, prefix);
-                            string trayBarcode2 = GenerateTrayBarcode(state, prefix);
-                            if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty())
+                            else if (state.OperStatus == "Homed" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
                             {
-                                string taskString = $"Pickbattery,{task.RobotSourceAddress}";
-                                // 鍙戦�佷换鍔℃寚浠�
-                                bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
-                                if (result)
+                                // TODO 璇诲彇绾夸綋鐢垫睜鏉$爜锛屽彂閫佸彇鐢垫睜鎸囦护
+                                // 闅忔満鐢熸垚涓ゅぉ鎵樼洏鏉$爜瀛樻斁鍒颁袱涓彉閲忛噷闈�
+                                // 瀹氫箟鍓嶇紑锛堜緥濡傦細TRAY浠h〃鎵樼洏锛�
+                                string prefix = "TRAY";
+
+                                // 鐢熸垚涓や釜鎵樼洏鏉$爜
+                                string trayBarcode1 = GenerateTrayBarcode(state, prefix);
+                                string trayBarcode2 = GenerateTrayBarcode(state, prefix);
+                                if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty())
                                 {
-                                    // TODO 澶勭悊鎴愬姛鍙戦�佷换鍔℃寚浠ゅ悗鐨勯�昏緫
-                                    task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-                                    result = await _robotTaskService.UpdateRobotTaskAsync(task);
+                                    string taskString = $"Pickbattery,{task.RobotSourceAddress}";
+                                    // 鍙戦�佷换鍔℃寚浠�
+                                    bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
+                                    if (result)
+                                    {
+                                        // TODO 澶勭悊鎴愬姛鍙戦�佷换鍔℃寚浠ゅ悗鐨勯�昏緫
+                                        task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+                                        result = await _robotTaskService.UpdateRobotTaskAsync(task);
+                                    }
                                 }
                             }
                         }
                     }
                 }
+            }
+            catch (Exception)
+            {
+
+            }
+            finally
+            {
+                // 鍙�夛細鍦ㄨ繖閲屽鐞嗕换浣曢渶瑕佸湪浠诲姟瀹屾垚鍚庢墽琛岀殑娓呯悊宸ヤ綔
+                // 鏇存柊缂撳瓨涓殑鐘舵��
+                _cache.AddOrUpdate(ipAddress, state);
             }
         }
 
@@ -176,7 +193,7 @@
         /// <returns></returns>
         private Task<string?> _TcpSocket_RobotReceived(string clientId)
         {
-            _socketStates.TryRemove(clientId, out _);
+            _cache.TryRemove(clientId, out _);
             return Task.FromResult<string?>(null);
         }
 
diff --git a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.backup.json b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.backup.json
index 2f3b2b8..84b0fd5 100644
--- a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.backup.json
+++ b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.backup.json
@@ -3,24 +3,44 @@
   "WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
       "AbsoluteMoniker": "D:0:0:{7D7534D4-51D9-46DC-A6B7-6430042F4E12}|WIDESEA_TaskInfoService\\WIDESEA_TaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{7D7534D4-51D9-46DC-A6B7-6430042F4E12}|WIDESEA_TaskInfoService\\WIDESEA_TaskInfoService.csproj|solutionrelative:widesea_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|solutionrelative:widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{CE0DB91F-5A68-448E-A419-4C26B5039F51}|WIDESEA_ITaskInfoService\\WIDESEA_ITaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{CE0DB91F-5A68-448E-A419-4C26B5039F51}|WIDESEA_ITaskInfoService\\WIDESEA_ITaskInfoService.csproj|solutionrelative:widesea_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_common\\stockenum\\stockstatusemun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|solutionrelative:widesea_common\\stockenum\\stockstatusemun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|solutionrelative:widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|solutionrelative:widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_common\\locationenum\\locationstatusenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
@@ -43,10 +63,6 @@
       "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
       "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
@@ -61,14 +77,6 @@
     {
       "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\helper\\http\\httpresponseresult.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\helper\\http\\httpresponseresult.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|solutionrelative:widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{D11C804C-2FF4-4C18-A3EE-2F0574427BB3}|WIDESEA_BasicService\\WIDESEA_BasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_basicservice\\locationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
@@ -89,10 +97,6 @@
     {
       "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\gradingmachine\\outputdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\gradingmachine\\outputdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -105,6 +109,19 @@
           "SelectedChildIndex": 24,
           "Children": [
             {
+              "$type": "Document",
+              "DocumentIndex": 6,
+              "Title": "StockStatusEmun.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "RelativeDocumentMoniker": "WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "RelativeToolTip": "WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "ViewState": "AgIAACQAAAAAAAAAAAAgwDoAAAAeAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-02-28T06:15:43.313Z",
+              "EditorCaption": ""
+            },
+            {
               "$type": "Bookmark",
               "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
             },
@@ -113,8 +130,12 @@
               "Name": "ST:0:0:{40ea2e6b-2121-4bb8-a43e-c83c04b51041}"
             },
             {
+              "$type": "Bookmark",
+              "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
+            },
+            {
               "$type": "Document",
-              "DocumentIndex": 5,
+              "DocumentIndex": 10,
               "Title": "LocationStatusEnum.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\LocationEnum\\LocationStatusEnum.cs",
               "RelativeDocumentMoniker": "WIDESEA_Common\\LocationEnum\\LocationStatusEnum.cs",
@@ -126,7 +147,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 8,
+              "DocumentIndex": 13,
               "Title": "IStockService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IStockService\\IStockService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IStockService\\IStockService.cs",
@@ -138,7 +159,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 7,
+              "DocumentIndex": 12,
               "Title": "StockController.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\Stock\\StockController.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Controllers\\Stock\\StockController.cs",
@@ -150,7 +171,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 11,
+              "DocumentIndex": 15,
               "Title": "Program.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Program.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Program.cs",
@@ -162,7 +183,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 14,
+              "DocumentIndex": 18,
               "Title": "HttpResponseResult.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpResponseResult.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpResponseResult.cs",
@@ -174,7 +195,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 13,
+              "DocumentIndex": 17,
               "Title": "HttpRequestConfig.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpRequestConfig.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpRequestConfig.cs",
@@ -186,7 +207,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 12,
+              "DocumentIndex": 16,
               "Title": "HttpClientHelper.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpClientHelper.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpClientHelper.cs",
@@ -198,7 +219,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 21,
+              "DocumentIndex": 23,
               "Title": "OutPutDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\GradingMachine\\OutPutDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\GradingMachine\\OutPutDto.cs",
@@ -210,7 +231,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 20,
+              "DocumentIndex": 22,
               "Title": "InputDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\GradingMachine\\InputDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\GradingMachine\\InputDto.cs",
@@ -222,19 +243,20 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 22,
+              "DocumentIndex": 5,
               "Title": "RepositoryBase.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "RelativeToolTip": "WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
-              "ViewState": "AgIAALgDAAAAAAAAAAAhwMsDAAAZAAAAAAAAAA==",
+              "ViewState": "AgIAALgDAAAAAAAAAAAawMsDAAAZAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-14T08:55:16.1Z"
+              "WhenOpened": "2026-02-14T08:55:16.1Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 19,
+              "DocumentIndex": 21,
               "Title": "IRepository.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\IRepository.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\BaseRepository\\IRepository.cs",
@@ -246,7 +268,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 18,
+              "DocumentIndex": 20,
               "Title": "StockViewService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockViewService.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockViewService.cs",
@@ -258,7 +280,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 2,
+              "DocumentIndex": 9,
               "Title": "ILocationInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IBasicService\\ILocationInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IBasicService\\ILocationInfoService.cs",
@@ -270,7 +292,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 17,
+              "DocumentIndex": 19,
               "Title": "LocationInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_BasicService\\LocationInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_BasicService\\LocationInfoService.cs",
@@ -282,19 +304,20 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 16,
+              "DocumentIndex": 7,
               "Title": "Dt_StockInfo.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "RelativeDocumentMoniker": "WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "RelativeToolTip": "WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
-              "ViewState": "AgIAAEAAAAAAAAAAAAAkwFIAAAAeAAAAAAAAAA==",
+              "ViewState": "AgIAAEAAAAAAAAAAAAAkwFIAAAAuAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-11T01:38:37.887Z"
+              "WhenOpened": "2026-02-11T01:38:37.887Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 9,
+              "DocumentIndex": 14,
               "Title": "StockInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockInfoService.cs",
@@ -306,7 +329,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 6,
+              "DocumentIndex": 11,
               "Title": "IStockInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IStockService\\IStockInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IStockService\\IStockInfoService.cs",
@@ -318,74 +341,78 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 4,
+              "DocumentIndex": 3,
               "Title": "TaskController.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "RelativeToolTip": "WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
-              "ViewState": "AgIAACcAAAAAAAAAAAAIwDcAAABAAAAAAAAAAA==",
+              "ViewState": "AgIAAD0AAAAAAAAAAAAUwFUAAABJAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-09T01:23:19.844Z"
+              "WhenOpened": "2026-02-09T01:23:19.844Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 15,
+              "DocumentIndex": 8,
               "Title": "CreateTaskDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "RelativeToolTip": "WIDESEA_DTO\\Task\\CreateTaskDto.cs",
-              "ViewState": "AgIAABEAAAAAAAAAAADwvw4AAAARAAAAAAAAAA==",
+              "ViewState": "AgIAABsAAAAAAAAAAAAywA4AAAARAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-06T07:58:13.932Z"
+              "WhenOpened": "2026-02-06T07:58:13.932Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 3,
+              "DocumentIndex": 4,
               "Title": "ITaskService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_ITaskInfoService\\ITaskService.cs",
               "RelativeDocumentMoniker": "WIDESEA_ITaskInfoService\\ITaskService.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_ITaskInfoService\\ITaskService.cs",
               "RelativeToolTip": "WIDESEA_ITaskInfoService\\ITaskService.cs",
-              "ViewState": "AgIAAC0AAAAAAAAAAAAAAEkAAAAIAAAAAAAAAA==",
+              "ViewState": "AgIAAEAAAAAAAAAAAAAUwFEAAAAVAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-06T07:00:19.697Z"
+              "WhenOpened": "2026-02-06T07:00:19.697Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 1,
+              "DocumentIndex": 0,
               "Title": "TaskService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_TaskInfoService\\TaskService.cs",
               "RelativeDocumentMoniker": "WIDESEA_TaskInfoService\\TaskService.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_TaskInfoService\\TaskService.cs",
               "RelativeToolTip": "WIDESEA_TaskInfoService\\TaskService.cs",
-              "ViewState": "AgIAADkAAAAAAAAAAAAUwEkAAAAoAAAAAAAAAA==",
+              "ViewState": "AgIAAAEBAAAAAAAAAAAxwPABAAAAAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-06T06:34:59.734Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 10,
+              "DocumentIndex": 1,
               "Title": "StockDTO.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Stock\\StockDTO.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\Stock\\StockDTO.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Stock\\StockDTO.cs",
               "RelativeToolTip": "WIDESEA_DTO\\Stock\\StockDTO.cs",
-              "ViewState": "AgIAACMAAAAAAAAAAAAAADoAAAASAAAAAAAAAA==",
+              "ViewState": "AgIAACMAAAAAAAAAAAAAADYAAAAuAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-06T02:56:51.397Z"
+              "WhenOpened": "2026-02-06T02:56:51.397Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 0,
+              "DocumentIndex": 2,
               "Title": "StockSerivce.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockSerivce.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockSerivce.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockSerivce.cs",
               "RelativeToolTip": "WIDESEA_StockService\\StockSerivce.cs",
-              "ViewState": "AgIAACQAAAAAAAAAAAAYwIgAAAAdAAAAAAAAAA==",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAD8AAAApAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-06T01:53:49.077Z",
               "EditorCaption": ""
diff --git a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
index ded488e..7935bb9 100644
--- a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
+++ b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
@@ -3,24 +3,44 @@
   "WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
       "AbsoluteMoniker": "D:0:0:{7D7534D4-51D9-46DC-A6B7-6430042F4E12}|WIDESEA_TaskInfoService\\WIDESEA_TaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{7D7534D4-51D9-46DC-A6B7-6430042F4E12}|WIDESEA_TaskInfoService\\WIDESEA_TaskInfoService.csproj|solutionrelative:widesea_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|solutionrelative:widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockserivce.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{CE0DB91F-5A68-448E-A419-4C26B5039F51}|WIDESEA_ITaskInfoService\\WIDESEA_ITaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{CE0DB91F-5A68-448E-A419-4C26B5039F51}|WIDESEA_ITaskInfoService\\WIDESEA_ITaskInfoService.csproj|solutionrelative:widesea_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\controllers\\taskinfo\\taskcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_common\\stockenum\\stockstatusemun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|solutionrelative:widesea_common\\stockenum\\stockstatusemun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|solutionrelative:widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+    },
+    {
+      "AbsoluteMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{5F260E03-095A-4870-8419-5B72CB62929E}|WIDESEA_IBasicService\\WIDESEA_IBasicService.csproj|solutionrelative:widesea_ibasicservice\\ilocationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{AF8F3D65-1D75-4B8F-AFD9-4150E591C44D}|WIDESEA_Common\\WIDESEA_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_common\\locationenum\\locationstatusenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
@@ -43,10 +63,6 @@
       "RelativeMoniker": "D:0:0:{7DC26D42-D8EE-46F0-BA66-A13457086885}|WIDESEA_StockService\\WIDESEA_StockService.csproj|solutionrelative:widesea_stockservice\\stockinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\stock\\stockdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
       "AbsoluteMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_wmsserver\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{D81A65B5-47D1-40C1-8FDE-7D24FF003F51}|WIDESEA_WMSServer\\WIDESEA_WMSServer.csproj|solutionrelative:widesea_wmsserver\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
@@ -61,14 +77,6 @@
     {
       "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\helper\\http\\httpresponseresult.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\helper\\http\\httpresponseresult.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\task\\createtaskdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{00CE9885-9F24-4B6C-A7E8-0DE8C9ED7128}|WIDESEA_Model\\WIDESEA_Model.csproj|solutionrelative:widesea_model\\models\\stock\\dt_stockinfo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
       "AbsoluteMoniker": "D:0:0:{D11C804C-2FF4-4C18-A3EE-2F0574427BB3}|WIDESEA_BasicService\\WIDESEA_BasicService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_basicservice\\locationinfoservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
@@ -89,10 +97,6 @@
     {
       "AbsoluteMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_dto\\gradingmachine\\outputdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
       "RelativeMoniker": "D:0:0:{929DF936-042C-4EEC-8722-A831FC2F0AEA}|WIDESEA_DTO\\WIDESEA_DTO.csproj|solutionrelative:widesea_dto\\gradingmachine\\outputdto.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|d:\\git\\shanmeixinnengyuan\\code\\wms\\widesea_wmsserver\\widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{111BD7AA-9749-4506-9772-79F9EF14754C}|WIDESEA_Core\\WIDESEA_Core.csproj|solutionrelative:widesea_core\\baserepository\\repositorybase.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -102,7 +106,7 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 25,
+          "SelectedChildIndex": 24,
           "Children": [
             {
               "$type": "Bookmark",
@@ -118,7 +122,19 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 5,
+              "DocumentIndex": 6,
+              "Title": "StockStatusEmun.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "RelativeDocumentMoniker": "WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "RelativeToolTip": "WIDESEA_Common\\StockEnum\\StockStatusEmun.cs",
+              "ViewState": "AgIAACQAAAAAAAAAAAAgwDoAAAAeAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-02-28T06:15:43.313Z"
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 10,
               "Title": "LocationStatusEnum.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Common\\LocationEnum\\LocationStatusEnum.cs",
               "RelativeDocumentMoniker": "WIDESEA_Common\\LocationEnum\\LocationStatusEnum.cs",
@@ -130,7 +146,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 8,
+              "DocumentIndex": 13,
               "Title": "IStockService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IStockService\\IStockService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IStockService\\IStockService.cs",
@@ -142,7 +158,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 7,
+              "DocumentIndex": 12,
               "Title": "StockController.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\Stock\\StockController.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Controllers\\Stock\\StockController.cs",
@@ -154,7 +170,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 11,
+              "DocumentIndex": 15,
               "Title": "Program.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Program.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Program.cs",
@@ -166,7 +182,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 14,
+              "DocumentIndex": 18,
               "Title": "HttpResponseResult.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpResponseResult.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpResponseResult.cs",
@@ -178,7 +194,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 13,
+              "DocumentIndex": 17,
               "Title": "HttpRequestConfig.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpRequestConfig.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpRequestConfig.cs",
@@ -190,7 +206,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 12,
+              "DocumentIndex": 16,
               "Title": "HttpClientHelper.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Helper\\HTTP\\HttpClientHelper.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\Helper\\HTTP\\HttpClientHelper.cs",
@@ -202,7 +218,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 21,
+              "DocumentIndex": 23,
               "Title": "OutPutDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\GradingMachine\\OutPutDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\GradingMachine\\OutPutDto.cs",
@@ -214,7 +230,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 20,
+              "DocumentIndex": 22,
               "Title": "InputDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\GradingMachine\\InputDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\GradingMachine\\InputDto.cs",
@@ -226,19 +242,19 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 22,
+              "DocumentIndex": 5,
               "Title": "RepositoryBase.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
               "RelativeToolTip": "WIDESEA_Core\\BaseRepository\\RepositoryBase.cs",
-              "ViewState": "AgIAALgDAAAAAAAAAAAhwMsDAAAZAAAAAAAAAA==",
+              "ViewState": "AgIAALgDAAAAAAAAAAAawMsDAAAZAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-14T08:55:16.1Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 19,
+              "DocumentIndex": 21,
               "Title": "IRepository.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\BaseRepository\\IRepository.cs",
               "RelativeDocumentMoniker": "WIDESEA_Core\\BaseRepository\\IRepository.cs",
@@ -250,7 +266,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 18,
+              "DocumentIndex": 20,
               "Title": "StockViewService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockViewService.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockViewService.cs",
@@ -262,7 +278,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 2,
+              "DocumentIndex": 9,
               "Title": "ILocationInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IBasicService\\ILocationInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IBasicService\\ILocationInfoService.cs",
@@ -274,7 +290,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 17,
+              "DocumentIndex": 19,
               "Title": "LocationInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_BasicService\\LocationInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_BasicService\\LocationInfoService.cs",
@@ -286,19 +302,19 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 16,
+              "DocumentIndex": 7,
               "Title": "Dt_StockInfo.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "RelativeDocumentMoniker": "WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
               "RelativeToolTip": "WIDESEA_Model\\Models\\Stock\\Dt_StockInfo.cs",
-              "ViewState": "AgIAAEAAAAAAAAAAAAAkwFIAAAAeAAAAAAAAAA==",
+              "ViewState": "AgIAAEAAAAAAAAAAAAAkwFIAAAAuAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-11T01:38:37.887Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 9,
+              "DocumentIndex": 14,
               "Title": "StockInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockInfoService.cs",
@@ -310,7 +326,7 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 6,
+              "DocumentIndex": 11,
               "Title": "IStockInfoService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_IStockService\\IStockInfoService.cs",
               "RelativeDocumentMoniker": "WIDESEA_IStockService\\IStockInfoService.cs",
@@ -322,76 +338,76 @@
             },
             {
               "$type": "Document",
-              "DocumentIndex": 4,
+              "DocumentIndex": 3,
               "Title": "TaskController.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "RelativeDocumentMoniker": "WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
               "RelativeToolTip": "WIDESEA_WMSServer\\Controllers\\TaskInfo\\TaskController.cs",
-              "ViewState": "AgIAACcAAAAAAAAAAAAIwDcAAABAAAAAAAAAAA==",
+              "ViewState": "AgIAAD0AAAAAAAAAAAAUwFUAAABJAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-09T01:23:19.844Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 15,
+              "DocumentIndex": 8,
               "Title": "CreateTaskDto.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Task\\CreateTaskDto.cs",
               "RelativeToolTip": "WIDESEA_DTO\\Task\\CreateTaskDto.cs",
-              "ViewState": "AgIAABEAAAAAAAAAAADwvw4AAAARAAAAAAAAAA==",
+              "ViewState": "AgIAABsAAAAAAAAAAAAywA4AAAARAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-06T07:58:13.932Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 3,
+              "DocumentIndex": 4,
               "Title": "ITaskService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_ITaskInfoService\\ITaskService.cs",
               "RelativeDocumentMoniker": "WIDESEA_ITaskInfoService\\ITaskService.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_ITaskInfoService\\ITaskService.cs",
               "RelativeToolTip": "WIDESEA_ITaskInfoService\\ITaskService.cs",
-              "ViewState": "AgIAAC0AAAAAAAAAAAAAAEkAAAAIAAAAAAAAAA==",
+              "ViewState": "AgIAAEAAAAAAAAAAAAAUwFEAAAAVAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-06T07:00:19.697Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 1,
+              "DocumentIndex": 0,
               "Title": "TaskService.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_TaskInfoService\\TaskService.cs",
               "RelativeDocumentMoniker": "WIDESEA_TaskInfoService\\TaskService.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_TaskInfoService\\TaskService.cs",
               "RelativeToolTip": "WIDESEA_TaskInfoService\\TaskService.cs",
-              "ViewState": "AgIAADkAAAAAAAAAAAAUwEkAAAAoAAAAAAAAAA==",
+              "ViewState": "AgIAANcAAAAAAAAAAAAgwBYBAABGAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-06T06:34:59.734Z"
+              "WhenOpened": "2026-02-06T06:34:59.734Z",
+              "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 10,
+              "DocumentIndex": 1,
               "Title": "StockDTO.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Stock\\StockDTO.cs",
               "RelativeDocumentMoniker": "WIDESEA_DTO\\Stock\\StockDTO.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_DTO\\Stock\\StockDTO.cs",
               "RelativeToolTip": "WIDESEA_DTO\\Stock\\StockDTO.cs",
-              "ViewState": "AgIAACMAAAAAAAAAAAAAADoAAAASAAAAAAAAAA==",
+              "ViewState": "AgIAACMAAAAAAAAAAAAAADYAAAAuAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
               "WhenOpened": "2026-02-06T02:56:51.397Z"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 0,
+              "DocumentIndex": 2,
               "Title": "StockSerivce.cs",
               "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockSerivce.cs",
               "RelativeDocumentMoniker": "WIDESEA_StockService\\StockSerivce.cs",
               "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_StockService\\StockSerivce.cs",
               "RelativeToolTip": "WIDESEA_StockService\\StockSerivce.cs",
-              "ViewState": "AgIAACUAAAAAAAAAAAAowD8AAAApAAAAAAAAAA==",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAD8AAAApAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-02-06T01:53:49.077Z",
-              "EditorCaption": ""
+              "WhenOpened": "2026-02-06T01:53:49.077Z"
             }
           ]
         }
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs
index 65ea267..d8b39a4 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs
@@ -56,6 +56,9 @@
         [Description("閫�搴�")]
         MES閫�搴� = 21,
 
+        [Description("绌烘墭鐩樺簱瀛�")]
+        绌烘墭鐩樺簱瀛� = 22,
+
         [Description("缁勭洏鎾ら攢")]
         缁勭洏鎾ら攢 = 99,
 
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
index d7b3fa3..4dfe3a3 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
@@ -79,6 +79,13 @@
         Task<WebResponseContent> CreateTaskInboundTrayAsync(CreateTaskDto taskDto);
 
         /// <summary>
+        /// 鍒涘缓绌烘墭鐩樺嚭搴撲换鍔�
+        /// </summary>
+        /// <param name="taskDto"></param>
+        /// <returns></returns>
+        Task<WebResponseContent> GetOutBoundTrayTaskAsync(CreateTaskDto taskDto);
+
+        /// <summary>
         /// 鍫嗗灈鏈哄彇鏀捐揣瀹屾垚鍚庣墿娴侀�氱煡鍖栨垚鍒嗗鏌滃畬鎴愪俊鍙�
         /// </summary>
         /// <param name="input"></param>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
index 797986d..2a799c9 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -3,6 +3,7 @@
 using SqlSugar;
 using System.Text.Json;
 using WIDESEA_Common.LocationEnum;
+using WIDESEA_Common.StockEnum;
 using WIDESEA_Common.TaskEnum;
 using WIDESEA_Core;
 using WIDESEA_Core.BaseRepository;
@@ -270,6 +271,44 @@
             }
         }
 
+        /// <summary>
+        /// 鍒涘缓绌烘墭鐩樺嚭搴撲换鍔�
+        /// </summary>
+        /// <param name="taskDto"></param>
+        /// <returns></returns>
+        public async Task<WebResponseContent> GetOutBoundTrayTaskAsync(CreateTaskDto taskDto)
+        {
+            try
+            {
+                var stockInfo = await _stockInfoService.Repository.QueryFirstAsync(x => x.LocationDetails.WarehouseId == taskDto.WarehouseId && x.LocationDetails.LocationStatus == LocationStatusEnum.InStock.GetHashCode() && x.StockStatus == StockStatusEmun.绌烘墭鐩樺簱瀛�.GetHashCode());
+                if(stockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑搴撳瓨淇℃伅");
+
+                var task = new Dt_Task()
+                {
+                    WarehouseId = stockInfo.LocationDetails.WarehouseId,
+                    PalletCode = stockInfo.PalletCode,
+                    PalletType = stockInfo.PalletType,
+                    SourceAddress = stockInfo.LocationCode,
+                    CurrentAddress = stockInfo.LocationCode,
+                    NextAddress = taskDto.TargetAddress,
+                    TargetAddress = taskDto.TargetAddress,
+                    Roadway = stockInfo.LocationDetails.RoadwayNo,
+                    TaskType = TaskTypeEnum.OutEmpty.GetHashCode(),
+                    TaskStatus = TaskStatusEnum.New.GetHashCode(),
+                    Grade = 1,
+                    TaskNum = await BaseDal.GetTaskNo(),
+                    Creater = "system",
+                };
+                 var taskDtos = _mapper.Map<List<WMSTaskDTO>>(task);
+                return WebResponseContent.Instance.OK("鏌ヨ鎴愬姛", taskDtos);
+            }
+            catch (Exception ex)
+            {
+                return WebResponseContent.Instance.Error($"鏌ヨ浠诲姟澶辫触: {ex.Message}");
+            }
+        }
+
         #region 鍒嗗鏌滄帴鍙�
 
         /// <summary>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
index 8df930c..5f0f297 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
@@ -79,6 +79,17 @@
         }
 
         /// <summary>
+        /// 鍒涘缓绌烘墭鐩樺嚭搴撲换鍔�
+        /// </summary>
+        /// <param name="taskDto"></param>
+        /// <returns></returns>
+        [HttpGet, HttpPost, Route("GetOutBoundTrayTask"), AllowAnonymous]
+        public async Task<WebResponseContent?> GetOutBoundTrayTaskAsync([FromBody] CreateTaskDto taskDto)
+        {
+            return await Service.GetOutBoundTrayTaskAsync(taskDto);
+        }
+
+        /// <summary>
         /// 鍫嗗灈鏈哄彇鏀捐揣瀹屾垚鍚庣墿娴侀�氱煡鍖栨垚鍒嗗鏌滃畬鎴愪俊鍙�
         /// </summary>
         /// <param name="input"></param>

--
Gitblit v1.9.3