From c75f62bad64e5b03c9cda9ba97c68aba7f09dd3d Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 30 一月 2026 10:54:00 +0800
Subject: [PATCH] 添加化成分容堆垛机调度,优化路由查找

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneDBName.cs      |   84 ++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs |   97 ++
 项目资料/高常温堆垛机/模拟PLC程序.zip                                                                                  |    0 
 .gitignore                                                                                               |  106 ++
 Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json                                 |  120 ++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs            |  445 +++++++++++
 Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db             |    0 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/IRouterService.cs                                |   33 
 Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db        |    0 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/DispatchInfoService.cs                           |    2 
 /dev/null                                                                                                |  276 -------
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs                |   36 
 Code/WCS/WIDESEAWCS_Client/VITE_MIGRATION_SUMMARY.md                                                     |    2 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/FormationStackerCraneStatus.cs         |  171 ++++
 项目资料/高常温堆垛机/堆垛机通信协议.xlsx                                                                                 |    0 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json                                            |    4 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs                     |  329 ++++----
 项目资料/开发计划/副本陕煤项目开发计划260126.xlsx                                                                          |    0 
 Code/WCS/WIDESEAWCS_Client/package.json                                                                  |    2 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs                                 |  304 ++++++-
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationCommonStackerCraneJob.cs   |  308 +++++++
 21 files changed, 1,780 insertions(+), 539 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1cf1dd4..413dc58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -290,3 +290,109 @@
 Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
 Code/WMS/WIDESEA_WMSClient/yarn.lock
 Code/WMS/WIDESEA_WMSClient/package-lock.json
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/02CEDD732D62C94D758FE67FF83D72CF
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/12313E989BCBD9B17CB5E1F4659BB227
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/20D96583D4E59CBF251955AB3AEE224B
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/326CB4F0763C1328A2FE9B1DEAEEE459
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/41A179025C25D2BE7AF7B6AA41CD697F
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/43DB506154C7EA149D631F3446B3F79A
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/966BBA8CF0A87B2A233AEA0A2F0794E9
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/CE1DA310E2C206A7C790F1012746725B
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/06BDA642C34D304DA3CFBDE5A90B0214/EF8B82096B9438E8EF04EF866ACC6365
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/37BA68D3A4AFE9B4B3E8D1F219796E43
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/66639773C1563C8E4A66750CD9E91A42
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/74A5F8BAFAF84678F3DBAD19D2DCA4C4
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/0E757001EF822C40B0B7B32A7191F50B/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/24ED6D94AF6C551D6278FB0AF2C07239
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/4A7264DE6B88B1CE5DB63F2CF21810E0
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/4ACFB47A91BDB6CAF109C5CB5A821941
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/8E82010873955D36B8637A8AA7594D6D
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/AA217133559F0488EC77AF4AAD1A97D6
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/B2744ACFBBD6298BD34CEDA635CC7928
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/C3FEC06F7A6EB2FD6A2B504485FA7BE9
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/11C2B2745D388A49AA91E9482D590508/ECA5E1DC5AE3AF113B2740CF9FFEA730
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/1FFCC3BC333CC2F8F80C3FD42D9C35A7
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/4B405FB24AE2E7CDA196C2E13DCCD94D
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/6C7A603CDFCA37C8B230FBCE1A6EF3C9
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/723DEEBD0A5EE2AED06E8CCF18EDC349
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/A780863F90E89FAFD4F108245B9FC59C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/B6F47F9752892BB8AC3789633BF0B198
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/BC33C2D906CA58D53FBC0BD60B91818F
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/2D60A5D08D551142A9CDCC8410949C3F/ED961C09A796FFDF0F5BABA1939DA716
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/288D1FB098610EAA981381CF1D3425C1
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/74A5F8BAFAF84678F3DBAD19D2DCA4C4
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/40A6D24721279A47A0317205F33DE3FD/A592E03ACCDEC4FECC773C76FCACA72D
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/50FD06FB30A9DB2E369D237EB6D8D8F8
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/5CFB13DBA9FE67985336DC2F4C226534
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/74A5F8BAFAF84678F3DBAD19D2DCA4C4
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/7029E49609C0524D965C26823A27EEA1/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/55DE31DE47C1715E5B9151AE24AC74CC
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/F8448AD0D92C292C4B1EBD43C11F2870
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/80B3BD5CD7AB2A41AFD5BD70193EC06E/FD23F73719A7512E845F2F1D8B1BF111
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/40F7E57802DACE2B3BBB65B9A371BB17
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/74A5F8BAFAF84678F3DBAD19D2DCA4C4
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/7CA1586DEF629651EE20C80BA9F5498F
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/BAE14F88C2A85A4FA1EA674CFD09AB3E/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/464529942B4DF0909C04E15C72912D32
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/811D807D4744CFA93E159B8F74F0F8BC
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/EAC09E9546070C4397A0096536CDEAD9/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/6B3C476AA39528929C43BD504073D1A2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/6D201C9A521C3192EE982AA13020805C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/7A3359239D3444727928DAAA9D7F188C
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/8C3792853AD604BFAF1D21B2148608F2
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/C81B0E8985C68630D39D9C4831A88D3D
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/F3CC65965247224EAA3ECED76422C6C8/CE83D9037361C8282E2811065127E2F6
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/48A4EA5F3CA61E408736097ACF7047F6/state.mpack
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/copilot-chat/bef6627e/sessions/5feaa448-a63c-401e-8736-097acf7047f6
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db-shm
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db-wal
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db-shm
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db-wal
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
diff --git a/Code/WCS/WIDESEAWCS_Client/VITE_MIGRATION_SUMMARY.md b/Code/WCS/WIDESEAWCS_Client/VITE_MIGRATION_SUMMARY.md
index f8ca432..37b5ea6 100644
--- a/Code/WCS/WIDESEAWCS_Client/VITE_MIGRATION_SUMMARY.md
+++ b/Code/WCS/WIDESEAWCS_Client/VITE_MIGRATION_SUMMARY.md
@@ -89,7 +89,7 @@
 
 ### 寮�鍙戠幆澧�
 ```bash
-yarn dev
+yarn serve
 # Vite dev server 杩愯浜� http://localhost:8080/
 # 鏀寔 HMR (Hot Module Replacement)
 ```
diff --git a/Code/WCS/WIDESEAWCS_Client/package.json b/Code/WCS/WIDESEAWCS_Client/package.json
index aa5177b..1f17df7 100644
--- a/Code/WCS/WIDESEAWCS_Client/package.json
+++ b/Code/WCS/WIDESEAWCS_Client/package.json
@@ -3,7 +3,7 @@
   "version": "0.1.0",
   "private": true,
   "scripts": {
-    "dev": "vite",
+    "serve": "vite",
     "build": "vite build",
     "preview": "vite preview",
     "lint": "eslint --ext .js,.vue src"
diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
index 78459e9..d3ffae8 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
Binary files differ
diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
index 51ad928..5865a4f 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
Binary files differ
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 d98ad99..1fae43c 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
@@ -3,12 +3,28 @@
   "WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\stackercrane\\spec\\spestackercrane.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\stackercrane\\spec\\spestackercrane.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\stackercrane\\spec\\speformationstackercrane.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\stackercrane\\spec\\speformationstackercrane.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:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\stackercrane\\enum\\formationstackercranestatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\stackercrane\\enum\\formationstackercranestatus.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\\formationstackercranejob\\formationstackercranedbname.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationstackercranedbname.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\\formationstackercranejob\\formationstackercranetaskcommand.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationstackercranetaskcommand.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\\formationstackercranejob\\formationcommonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationcommonstackercranejob.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\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -18,7 +34,7 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 2,
+          "SelectedChildIndex": 6,
           "Children": [
             {
               "$type": "Bookmark",
@@ -29,33 +45,85 @@
               "Name": "ST:0:0:{40ea2e6b-2121-4bb8-a43e-c83c04b51041}"
             },
             {
-              "$type": "Document",
-              "DocumentIndex": 0,
-              "Title": "SpeStackerCrane.cs",
-              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeStackerCrane.cs",
-              "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeStackerCrane.cs",
-              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeStackerCrane.cs",
-              "RelativeToolTip": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeStackerCrane.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAJQAAAARAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2026-01-28T05:55:14.804Z",
-              "EditorCaption": ""
-            },
-            {
               "$type": "Bookmark",
               "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
             },
             {
               "$type": "Document",
+              "DocumentIndex": 3,
+              "Title": "FormationStackerCraneTaskCommand.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
+              "ViewState": "AgIAAEcAAAAAAAAAAAAiwDAAAAAVAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T09:17:51.622Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 2,
+              "Title": "FormationStackerCraneDBName.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAC4AAAAQAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T09:13:24.922Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
               "DocumentIndex": 1,
-              "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": "AgIAAAYAAAAAAAAAAAAAABQAAAAAAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
-              "WhenOpened": "2026-01-26T08:07:36.508Z",
+              "Title": "FormationStackerCraneStatus.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
+              "RelativeToolTip": "WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
+              "ViewState": "AgIAAEAAAAAAAAAAAAArwFQAAAAQAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T03:35:09.011Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 0,
+              "Title": "SpeFormationStackerCrane.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
+              "RelativeToolTip": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
+              "ViewState": "AgIAAN8AAAAAAAAAAAAnwPEAAAAUAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T03:12:53.832Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 4,
+              "Title": "FormationCommonStackerCraneJob.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
+              "ViewState": "AgIAAEEAAAAAAAAAAAAqwFQAAAAVAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T03:12:40.035Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 5,
+              "Title": "CommonStackerCraneJob.cs",
+              "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
+              "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
+              "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
+              "RelativeToolTip": "WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
+              "ViewState": "AgIAAJ4AAAAAAAAAAAAkwLQAAAATAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2026-01-29T02:59:35.12Z",
               "EditorCaption": ""
             }
           ]
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/DispatchInfoService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/DispatchInfoService.cs
index f40cc54..457a241 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/DispatchInfoService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/DispatchInfoService.cs
@@ -64,7 +64,7 @@
                 Creater = a.Creater,
                 CycleHasRunTimes = 0,
                 EndTime = a.EndTime,
-                Id = b.Id,
+                Id = a.Id,
                 IntervalSecond = a.IntervalSecond,
                 Modifier = a.Modifier,
                 ModifyDate = a.ModifyDate,
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/IRouterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/IRouterService.cs
index 67bc77e..36ebebe 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/IRouterService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/IRouterService.cs
@@ -33,6 +33,39 @@
         List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi, int routeType);
 
         /// <summary>
+        /// 鏍规嵁璧风偣鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi);
+
+        /// <summary>
+        /// 鏍规嵁璧风偣鍜岃矾鐢辩被鍨嬭幏鍙栦笅涓�涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, int routeType);
+
+        /// <summary>
+        /// 鏍规嵁璧风偣銆佺粓鐐规柟鍚戝拰璺敱绫诲瀷鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱锛堟櫤鑳介�夋嫨鏈濆悜缁堢偣鐨勮矾鐢憋級
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆锛堢敤浜庢柟鍚戝垽鏂級</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝浼樺厛杩斿洖鏈濆悜缁堢偣鐨勮矾鐢憋紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, string endPosi, int routeType);
+
+        /// <summary>
+        /// 鑾峰彇浠庤捣鐐瑰埌缁堢偣鐨勫畬鏁磋矾寰勶紙鎸夐『搴忚繑鍥炴瘡涓瓙鑺傜偣璺敱锛�
+        /// </summary>
+        /// <param name="startPosi">璧风偣浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖鏈夊簭鐨勮矾鐢卞垪琛紝濡傛灉鎵句笉鍒拌矾寰勫垯杩斿洖绌哄垪琛�</returns>
+        public List<Dt_Router> QueryRoutePath(string startPosi, string endPosi, int routeType);
+
+        /// <summary>
         /// 鏍规嵁璁惧缂栧彿鑾峰彇瀵瑰簲鐨勮矾鐢辩偣浣嶇紪鍙�(杈撻�佺嚎绔欏彴缂栧彿)淇℃伅
         /// </summary>
         /// <param name="deviceCode">璁惧缂栧彿</param>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
index 2feada3..4bf89ae 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
@@ -42,46 +42,23 @@
         /// <returns>杩斿洖璺敱瀹炰綋闆嗗悎銆�</returns>
         public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi)
         {
-            //todo 鏂规硶闇�浼樺寲
             List<Dt_Router> routers = new List<Dt_Router>();
             try
             {
-                //鏌ヨ涓嬩竴涓矾鐢变俊鎭�
-                List<Dt_Router> dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi), new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                if (dt_Routers.Count > 0)
+                // 涓�娆℃�ф煡璇㈡墍鏈夎矾鐢辨暟鎹埌鍐呭瓨
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
+                
+                // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
+                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
+                
+                if (routers.Count == 0)
                 {
-                    foreach (var item in dt_Routers)
-                    {
-                        //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                        if (item.StartPosi == startPosi && !routers.Any(x => x.Id == item.Id))
-                        {
-                            routers.Add(item);
-                        }
-                        else
-                        {
-                            //鍚﹀垯锛岄�掑綊鏌ヨ涓嬩竴涓矾鐢辩殑璧风偣
-                            List<Dt_Router> tempRouters = QueryNextRoutes(startPosi, item.StartPosi);
-                            foreach (var router in tempRouters)
-                            {
-                                //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                                if (router.StartPosi == startPosi && !routers.Any(x => x.Id == router.Id))
-                                {
-                                    routers.Add(router);
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    //濡傛灉鏌ヨ涓嶅埌涓嬩竴涓矾鐢变俊鎭紝鍒欐姏鍑哄紓甯�
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
                 }
             }
             catch (Exception ex)
             {
-                //throw new Exception(ex.Message);
-                //璁板綍閿欒淇℃伅
+                // 璁板綍閿欒淇℃伅
             }
             return routers;
         }
@@ -95,48 +72,250 @@
         /// <returns>杩斿洖璺敱瀹炰綋闆嗗悎銆�</returns>
         public List<Dt_Router> QueryNextRoutes(string startPosi, string endPosi, int routeType)
         {
-            //todo 鏂规硶闇�浼樺寲
             List<Dt_Router> routers = new List<Dt_Router>();
             try
             {
-                //鏌ヨ涓嬩竴涓矾鐢变俊鎭�
-                List<Dt_Router> dt_Routers = BaseDal.QueryData(x => (x.NextPosi == endPosi || x.ChildPosi == endPosi) && x.InOutType == routeType, new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
-                if (dt_Routers.Count > 0)
+                // 涓�娆℃�ф煡璇㈡寚瀹氱被鍨嬬殑鎵�鏈夎矾鐢辨暟鎹埌鍐呭瓨
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+                
+                // 鍦ㄥ唴瀛樹腑杩涜璺緞鎼滅储
+                routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
+                
+                if (routers.Count == 0)
                 {
-                    foreach (var item in dt_Routers)
-                    {
-                        //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                        if (item.StartPosi == startPosi && !routers.Any(x => x.Id == item.Id))
-                        {
-                            routers.Add(item);
-                        }
-                        else
-                        {
-                            //鍚﹀垯锛岄�掑綊鏌ヨ涓嬩竴涓矾鐢辩殑璧风偣
-                            List<Dt_Router> tempRouters = QueryNextRoutes(startPosi, item.StartPosi, routeType);
-                            foreach (var router in tempRouters)
-                            {
-                                //濡傛灉涓嬩竴涓矾鐢辩殑璧风偣鍜岀粓鐐归兘鍖归厤锛屽垯娣诲姞鍒拌矾鐢卞垪琛ㄤ腑
-                                if (router.StartPosi == startPosi && !routers.Any(x => x.Id == router.Id))
-                                {
-                                    routers.Add(router);
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    //濡傛灉鏌ヨ涓嶅埌涓嬩竴涓矾鐢变俊鎭紝鍒欐姏鍑哄紓甯�
                     throw new Exception($"璇ヨ矾寰勬湭閰嶇疆鎴栭厤缃敊璇�,璇锋鏌ヨ澶囪矾鐢变俊鎭�,璧风偣:銆恵startPosi}銆�,缁堢偣:銆恵endPosi}銆�");
                 }
             }
             catch (Exception ex)
             {
-                //throw new Exception(ex.Message);
-                //璁板綍閿欒淇℃伅
+                // 璁板綍閿欒淇℃伅
             }
             return routers;
+        }
+
+        /// <summary>
+        /// 鍦ㄥ唴瀛樹腑鏌ユ壘浠庤捣鐐瑰埌缁堢偣鐨勬墍鏈夎矾鐢�
+        /// </summary>
+        /// <param name="startPosi">璧风偣浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆</param>
+        /// <param name="allRouters">鎵�鏈夎矾鐢辨暟鎹�</param>
+        /// <param name="routeType">璺敱绫诲瀷锛堝彲閫夛級</param>
+        /// <returns>绗﹀悎鏉′欢鐨勮矾鐢卞垪琛�</returns>
+        private List<Dt_Router> FindRoutesInMemory(string startPosi, string endPosi, List<Dt_Router> allRouters, int? routeType)
+        {
+            List<Dt_Router> result = new List<Dt_Router>();
+            HashSet<int> addedIds = new HashSet<int>();
+
+            // 鏋勫缓绱㈠紩锛氫互 NextPosi 鍜� ChildPosi 涓洪敭鐨勫瓧鍏革紝鍔犻�熸煡鎵�
+            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());
+
+            // 鎵惧埌鎵�鏈夋寚鍚戠粓鐐圭殑璺敱锛堢粓鐐圭殑鐖惰妭鐐癸級
+            List<Dt_Router> endRouters = new List<Dt_Router>();
+            if (routersByNext.ContainsKey(endPosi))
+                endRouters.AddRange(routersByNext[endPosi]);
+            if (routersByChild.ContainsKey(endPosi))
+                endRouters.AddRange(routersByChild[endPosi].Where(r => !endRouters.Any(e => e.Id == r.Id)));
+
+            // 鎸� IsEnd 闄嶅簭鎺掑簭
+            endRouters = endRouters.OrderByDescending(r => r.IsEnd).ToList();
+
+            // 浣跨敤闃熷垪杩涜骞垮害浼樺厛鎼滅储
+            Queue<(Dt_Router router, List<Dt_Router> path)> queue = new Queue<(Dt_Router, List<Dt_Router>)>();
+            
+            // 灏嗘墍鏈夌粓鐐硅矾鐢卞姞鍏ラ槦鍒�
+            foreach (var endRouter in endRouters)
+            {
+                queue.Enqueue((endRouter, new List<Dt_Router> { endRouter }));
+            }
+
+            // 骞垮害浼樺厛鎼滅储
+            while (queue.Count > 0)
+            {
+                var (currentRouter, currentPath) = queue.Dequeue();
+
+                // 濡傛灉褰撳墠璺敱鐨勮捣鐐瑰氨鏄洰鏍囪捣鐐癸紝鎵惧埌瀹屾暣璺緞
+                if (currentRouter.StartPosi == startPosi)
+                {
+                    // 灏嗚矾寰勪腑鐨勬墍鏈夎矾鐢辨坊鍔犲埌缁撴灉涓紙鍘婚噸锛�
+                    foreach (var router in currentPath)
+                    {
+                        if (!addedIds.Contains(router.Id))
+                        {
+                            result.Add(router);
+                            addedIds.Add(router.Id);
+                        }
+                    }
+                    continue;
+                }
+
+                // 鏌ユ壘褰撳墠璺敱璧风偣鐨勭埗璺敱
+                List<Dt_Router> parentRouters = new List<Dt_Router>();
+                if (routersByNext.ContainsKey(currentRouter.StartPosi))
+                    parentRouters.AddRange(routersByNext[currentRouter.StartPosi]);
+                if (routersByChild.ContainsKey(currentRouter.StartPosi))
+                    parentRouters.AddRange(routersByChild[currentRouter.StartPosi].Where(r => !parentRouters.Any(p => p.Id == r.Id)));
+
+                // 灏嗙埗璺敱鍔犲叆闃熷垪
+                foreach (var parentRouter in parentRouters)
+                {
+                    // 閬垮厤寰幆寮曠敤
+                    if (!currentPath.Any(p => p.Id == parentRouter.Id))
+                    {
+                        var newPath = new List<Dt_Router>(currentPath) { parentRouter };
+                        queue.Enqueue((parentRouter, newPath));
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎵�鏈夎矾鐢�
+                List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi, 
+                    new Dictionary<string, OrderByType> { { nameof(Dt_Router.IsEnd), OrderByType.Desc } });
+                
+                // 杩斿洖绗竴涓矾鐢�
+                return routes.FirstOrDefault();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣鍜岃矾鐢辩被鍨嬭幏鍙栦笅涓�涓崟涓瓙鑺傜偣璺敱
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, int routeType)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
+                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();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁璧风偣銆佺粓鐐规柟鍚戝拰璺敱绫诲瀷鑾峰彇涓嬩竴涓崟涓瓙鑺傜偣璺敱锛堟櫤鑳介�夋嫨鏈濆悜缁堢偣鐨勮矾鐢憋級
+        /// </summary>
+        /// <param name="startPosi">璧风偣/褰撳墠浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆锛堢敤浜庢柟鍚戝垽鏂級</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖涓嬩竴涓矾鐢辫妭鐐癸紝浼樺厛杩斿洖鏈濆悜缁堢偣鐨勮矾鐢憋紝濡傛灉娌℃湁鍒欒繑鍥瀗ull</returns>
+        public Dt_Router QueryNextRoute(string startPosi, string endPosi, int routeType)
+        {
+            try
+            {
+                // 鏌ヨ浠庤捣鐐瑰嚭鍙戠殑鎸囧畾绫诲瀷璺敱
+                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;
+
+                // 浼樺厛閫夋嫨鐩存帴鎸囧悜缁堢偣鐨勮矾鐢�
+                Dt_Router directRoute = routes.FirstOrDefault(x => x.NextPosi == endPosi || x.ChildPosi == endPosi);
+                if (directRoute != null)
+                    return directRoute;
+
+                // 濡傛灉娌℃湁鐩存帴璺敱锛屼娇鐢ㄦ煡鎵剧畻娉曟壘鍒版湞鍚戠粓鐐圭殑璺敱
+                List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+                foreach (var route in routes)
+                {
+                    // 妫�鏌ヤ粠杩欎釜璺敱鐨勪笅涓�涓綅缃槸鍚﹁兘鍒拌揪缁堢偣
+                    var pathToEnd = FindRoutesInMemory(route.NextPosi, endPosi, allRouters, routeType);
+                    if (pathToEnd.Count > 0)
+                        return route;
+                }
+
+                // 濡傛灉閮戒笉鑳藉埌杈剧粓鐐癸紝杩斿洖绗竴涓矾鐢�
+                return routes.FirstOrDefault();
+            }
+            catch (Exception ex)
+            {
+                // 璁板綍閿欒淇℃伅
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇浠庤捣鐐瑰埌缁堢偣鐨勫畬鏁磋矾寰勶紙鎸夐『搴忚繑鍥炴瘡涓瓙鑺傜偣璺敱锛�
+        /// </summary>
+        /// <param name="startPosi">璧风偣浣嶇疆</param>
+        /// <param name="endPosi">缁堢偣浣嶇疆</param>
+        /// <param name="routeType">璺敱绫诲瀷</param>
+        /// <returns>杩斿洖鏈夊簭鐨勮矾鐢卞垪琛紝濡傛灉鎵句笉鍒拌矾寰勫垯杩斿洖绌哄垪琛�</returns>
+        public List<Dt_Router> QueryRoutePath(string startPosi, string endPosi, int routeType)
+        {
+            List<Dt_Router> path = new List<Dt_Router>();
+            string currentPosi = startPosi;
+            HashSet<string> visitedPositions = new HashSet<string>();
+            
+            try
+            {
+                while (currentPosi != endPosi)
+                {
+                    if (visitedPositions.Contains(currentPosi))
+                    {
+                        break;
+                    }
+                    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>();
+                }
+            }
+            catch (Exception ex)
+            {
+                return new List<Dt_Router>();
+            }
+            
+            return path;
         }
 
         /// <summary>
@@ -144,7 +323,6 @@
         /// </summary>
         /// <param name="deviceCode">璁惧缂栧彿</param>
         /// <returns>杩斿洖璺敱鐐逛綅缂栧彿(杈撻�佺嚎绔欏彴缂栧彿)闆嗗悎</returns>
-        // 鏍规嵁璁惧缂栫爜鏌ヨ鎵�鏈変綅缃�
         public List<string> QueryAllPositions(string deviceCode)
         {
             // 鍒涘缓涓�涓瓧绗︿覆鍒楄〃锛岀敤浜庡瓨鍌ㄦ墍鏈変綅缃�
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
index 66e63ff..5e746e7 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
@@ -1,4 +1,5 @@
 锘�#region << 鐗� 鏈� 娉� 閲� >>
+
 /*----------------------------------------------------------------
  * 鍛藉悕绌洪棿锛歐IDESEAWCS_QuartzJob
  * 鍒涘缓鑰咃細鑳$搴�
@@ -11,21 +12,15 @@
  * 淇敼鏃堕棿锛�
  * 鐗堟湰锛歏1.0.1
  * 淇敼璇存槑锛�
- * 
+ *
  *----------------------------------------------------------------*/
+
 #endregion << 鐗� 鏈� 娉� 閲� >>
 
 using HslCommunication;
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
 using System.ComponentModel;
-using System.Linq;
 using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
 using WIDESEAWCS_Communicator;
-using WIDESEAWCS_Core.Enums;
 using WIDESEAWCS_QuartzJob.DeviceBase;
 using WIDESEAWCS_QuartzJob.DTO;
 using WIDESEAWCS_QuartzJob.StackerCrane;
@@ -40,26 +35,32 @@
     public class CommonStackerCrane : IStackerCrane
     {
         #region Private Member
+
         /// <summary>
         /// 鍫嗗灈鏈洪�氳瀵硅薄
         /// </summary>
         private BaseCommunicator _communicator;
+
         /// <summary>
         /// 鍫嗗灈鏈哄崗璁俊鎭�
         /// </summary>
         private readonly List<DeviceProDTO> _deviceProDTOs;
+
         /// <summary>
         /// 鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�
         /// </summary>
         private readonly List<DeviceProtocolDetailDTO> _deviceProtocolDetailDTOs;
+
         /// <summary>
         /// 璁惧缂栧彿
         /// </summary>
         public readonly string _deviceCode;
+
         /// <summary>
         /// 璁惧鍚嶇О
         /// </summary>
         public readonly string _deviceName;
+
         /// <summary>
         /// 涓婁竴娆′换鍔″彿
         /// </summary>
@@ -70,9 +71,11 @@
         private bool _heartStatr = true;
 
         private bool _isConnected = true;
+
         #endregion Private Member
 
         #region Public Member
+
         /// <summary>
         /// 鍫嗗灈鏈洪�氳瀵硅薄
         /// </summary>
@@ -176,6 +179,7 @@
         #endregion
 
         #region Constructor Function
+
         /// <summary>
         /// 鏋勯�犲嚱鏁�
         /// </summary>
@@ -193,9 +197,11 @@
             _deviceName = deviceName;
             CheckConnect();
         }
+
         #endregion
 
         #region Private Method
+
         /// <summary>
         /// 鏍规嵁鍗忚璇诲彇鍫嗗灈鏈虹姸鎬�
         /// </summary>
@@ -306,7 +312,6 @@
                     return StackerCraneStatus.Unkonw.ToString();
                 }
             }
-            //todo 閫氳鏈繛鎺ユ椂鎶涘嚭寮傚父
             return StackerCraneStatus.Unkonw.ToString();
         }
 
@@ -333,9 +338,11 @@
                 }
             });
         }
+
         #endregion
 
         #region Public Method
+
         /// <summary>
         /// 鍙戦�佷换鍔″懡浠�
         /// </summary>
@@ -391,21 +398,27 @@
                                 case TypeCode.Boolean:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Byte:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Int16:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.Int32:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.UInt16:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 case TypeCode.UInt32:
                                     operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
+
                                 default:
                                     break;
                             }
@@ -421,7 +434,6 @@
                 }
                 catch (Exception ex)
                 {
-
                 }
                 finally
                 {
@@ -450,7 +462,6 @@
         /// </summary>
         public void Heartbeat()
         {
-
         }
 
         /// <summary>
@@ -483,6 +494,7 @@
             // 鍛婅瘔鍨冨溇鍥炴敹鍣ㄤ笉鍐嶈皟鐢ㄦ瀵硅薄鐨勭粓缁撳櫒
             GC.SuppressFinalize(this);
         }
+
         #endregion
     }
-}
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/FormationStackerCraneStatus.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/FormationStackerCraneStatus.cs
new file mode 100644
index 0000000..8da3632
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/FormationStackerCraneStatus.cs
@@ -0,0 +1,171 @@
+锘�#region << 鐗� 鏈� 娉� 閲� >>
+/*----------------------------------------------------------------
+ * 鍛藉悕绌洪棿锛歐IDESEAWCS_QuartzJob
+ * 鍒涘缓鑰咃細鑳$搴�
+ * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36
+ * 鐗堟湰锛歏1.0.0
+ * 鎻忚堪锛氬爢鍨涙満鐘舵�佹灇涓�
+ *
+ * ----------------------------------------------------------------
+ * 淇敼浜猴細
+ * 淇敼鏃堕棿锛�
+ * 鐗堟湰锛歏1.0.1
+ * 淇敼璇存槑锛�
+ * 
+ *----------------------------------------------------------------*/
+#endregion << 鐗� 鏈� 娉� 閲� >>
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WIDESEAWCS_QuartzJob.StackerCrane.Enum
+{
+
+    /// <summary>
+    /// 鍫嗗灈鏈鸿繍琛岀姸鎬佹灇涓�
+    /// </summary>
+    public enum FormationStackerCraneRunStatus
+    {
+        /// <summary>
+        /// OFF
+        /// </summary>
+        [Description("OFF")]
+        Off,
+
+        /// <summary>
+        /// 寰呮満涓�
+        /// </summary>
+        [Description("寰呮満涓�")]
+        Standby,
+
+        /// <summary>
+        /// 鎵嬪姩妯″紡
+        /// </summary>
+        [Description("鎵嬪姩妯″紡")]
+        ManualMode,
+
+        /// <summary>
+        /// 鍘熺偣鍥炲綊涓�
+        /// </summary>
+        [Description("鍘熺偣鍥炲綊涓�")]
+        ReturningToOrigin,
+
+        /// <summary>
+        /// 鑷姩杩愯浆涓�
+        /// </summary>
+        [Description("鑷姩杩愯浆涓�")]
+        AutoRunning,
+
+        /// <summary>
+        /// 寮傚父涓�
+        /// </summary>
+        [Description("寮傚父涓�")]
+        Abnormal,
+
+        /// <summary>
+        /// 闈炲父鍋滄涓�
+        /// </summary>
+        [Description("闈炲父鍋滄涓�")]
+        EmergencyStopping,
+
+        /// <summary>
+        /// 鏈煡
+        /// </summary>
+        [Description("鏈煡")]
+        Unkonw
+    }
+
+    /// <summary>
+    /// 鍫嗗灈鏈哄伐浣滅姸鎬佹灇涓�
+    /// </summary>
+    public enum FormationStackerCraneOperationStatus
+    {
+        /// <summary>
+        /// 鏃�
+        /// </summary>
+        [Description("鏃�")]
+        None,
+
+        /// <summary>
+        /// 绌洪棽涓�
+        /// </summary>
+        [Description("绌洪棽涓�")]
+        Idle,
+
+        /// <summary>
+        /// 绉诲姩涓�
+        /// </summary>
+        [Description("绉诲姩涓�")]
+        Moving,
+
+        /// <summary>
+        /// 鍙栬揣涓�
+        /// </summary>
+        [Description("鍙栬揣涓�")]
+        PickingUp,
+
+        /// <summary>
+        /// 鏀捐揣涓�
+        /// </summary>
+        [Description("鏀捐揣涓�")]
+        PuttingDown,
+
+        /// <summary>
+        /// 澶勭悊涓�
+        /// </summary>
+        [Description("澶勭悊涓�")]
+        Processing,
+
+        /// <summary>
+        /// 寮傚父涓�
+        /// </summary>
+        [Description("寮傚父涓�")]
+        Abnormal,
+
+        /// <summary>
+        /// 闈炲父鍋滄涓�
+        /// </summary>
+        [Description("闈炲父鍋滄涓�")]
+        EmergencyStopping,
+
+        /// <summary>
+        /// 鏈煡
+        /// </summary>
+        [Description("鏈煡")]
+        Unkonw
+    }
+
+    /// <summary>
+    /// 鍫嗗灈鏈轰换鍔″畬鎴愮姸鎬佹灇涓�
+    /// </summary>
+    public enum FormationStackerCraneTaskCompletionStatus
+    {
+        /// <summary>
+        /// 鏃�
+        /// </summary>
+        [Description("鏃�")]
+        None,
+
+        /// <summary>
+        /// 姝e父瀹屾垚
+        /// </summary>
+        [Description("姝e父瀹屾垚")]
+        NormalCompleted,
+
+        /// <summary>
+        /// 寮傚父瀹屾垚
+        /// </summary>
+        [Description("寮傚父瀹屾垚")]
+        AbnormalCompleted,
+
+        /// <summary>
+        /// 鏈煡
+        /// </summary>
+        [Description("鏈煡")]
+        Unkonw
+    }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs
new file mode 100644
index 0000000..7c56dab
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs
@@ -0,0 +1,445 @@
+锘縰sing HslCommunication;
+using System.ComponentModel;
+using System.Reflection;
+using WIDESEAWCS_Communicator;
+using WIDESEAWCS_QuartzJob.DeviceBase;
+using WIDESEAWCS_QuartzJob.DTO;
+using WIDESEAWCS_QuartzJob.StackerCrane;
+using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
+
+namespace WIDESEAWCS_QuartzJob
+{
+    /// <summary>
+    /// 鑷畾涔夊爢鍨涙満
+    /// </summary>
+    [Description("鍖栨垚鍒嗗鍫嗗灈鏈�")]
+    public class SpeFormationStackerCrane : IStackerCrane
+    {
+        #region Private Member
+
+        /// <summary>
+        /// 鍫嗗灈鏈洪�氳瀵硅薄
+        /// </summary>
+        private BaseCommunicator _communicator;
+
+        /// <summary>
+        /// 鍫嗗灈鏈哄崗璁俊鎭�
+        /// </summary>
+        private readonly List<DeviceProDTO> _deviceProDTOs;
+
+        /// <summary>
+        /// 鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�
+        /// </summary>
+        private readonly List<DeviceProtocolDetailDTO> _deviceProtocolDetailDTOs;
+
+        /// <summary>
+        /// 璁惧缂栧彿
+        /// </summary>
+        public readonly string _deviceCode;
+
+        /// <summary>
+        /// 璁惧鍚嶇О
+        /// </summary>
+        public readonly string _deviceName;
+
+        /// <summary>
+        /// 涓婁竴娆′换鍔″彿
+        /// </summary>
+        private int _lastTaskNum;
+
+        private bool _isChecked = false;
+
+        private bool _heartStart = true;
+
+        private bool _isConnected = true;
+
+        #endregion Private Member
+
+        #region Public Member
+
+        /// <summary>
+        /// 閫氳瀵硅薄
+        /// </summary>
+        public BaseCommunicator Communicator => _communicator;
+
+        /// <summary>
+        /// 閫氳鍗忚淇℃伅
+        /// </summary>
+        public List<DeviceProDTO> DeviceProDTOs => _deviceProDTOs;
+
+        /// <summary>
+        /// 閫氳鍗忚鏄庣粏淇℃伅
+        /// </summary>
+        public List<DeviceProtocolDetailDTO> DeviceProtocolDetailDTOs => _deviceProtocolDetailDTOs;
+
+        public FormationStackerCraneTaskCompletionStatus StackerCraneCompletionValue => GetStackerCraneCompletionStatus();
+
+        /// <summary>
+        /// 鍫嗗灈鏈虹姸鎬�
+        /// </summary>
+        public FormationStackerCraneRunStatus StackerCraneStatusValue => GetStackerCraneStatus();
+
+        /// <summary>
+        /// 鍫嗗灈鏈虹姸鎬佷腑鏂囪鏄�
+        /// </summary>
+        public string StackerCraneStatusDes => GetEnumDes(StackerCraneStatusValue);
+
+        /// <summary>
+        /// 浣滀笟鐘舵��
+        /// </summary>
+        public FormationStackerCraneOperationStatus StackerCraneWorkStatusValue => GetStackerCraneWorkStatus();
+
+        /// <summary>
+        /// 浣滀笟鐘舵�佷腑鏂囪鏄�
+        /// </summary>
+        public string StackerCraneWorkStatusDes => GetEnumDes(StackerCraneWorkStatusValue);
+
+        /// <summary>
+        /// 涓婁竴娆℃墽琛岀殑浠诲姟鍙�
+        /// </summary>
+        public int LastTaskNum => _lastTaskNum;
+
+        /// <summary>
+        /// 褰撳墠姝e湪鎵ц鐨勪换鍔″彿
+        /// </summary>
+        public int CurrentTaskNum => GetCurrentTaskNum();
+
+        /// <summary>
+        /// 涓婁竴娆℃墽琛岀殑浠诲姟绫诲瀷
+        /// </summary>
+        public int? LastTaskType { get; set; } = null;
+
+        /// <summary>
+        /// 璁惧缂栧彿
+        /// </summary>
+        public string DeviceCode => _deviceCode;
+
+        /// <summary>
+        /// 璁惧鍚嶇О
+        /// </summary>
+        public string DeviceName => _deviceName;
+
+        /// <summary>
+        /// 璁惧鏄惁宸茶繛鎺�
+        /// </summary>
+        public bool IsConnected => Communicator.IsConnected && _isConnected;
+
+        /// <summary>
+        /// 鍫嗗灈鏈轰换鍔″懡浠�
+        /// </summary>
+        public object StackerCraneTaskCommand { get; set; }
+
+        /// <summary>
+        /// 鍫嗗灈鏈轰换鍔″畬鎴愪簨浠�
+        /// </summary>
+        public event EventHandler<StackerCraneTaskCompletedEventArgs> StackerCraneTaskCompletedEventHandler;
+
+        /// <summary>
+        /// 鍫嗗灈鏈哄畬鎴愪簨浠舵槸鍚﹀凡璁㈤槄
+        /// </summary>
+        public bool IsEventSubscribed => StackerCraneTaskCompletedEventHandler != null;
+
+        #endregion Public Member
+
+        #region Constructor Function
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        /// <param name="communicator">鍫嗗灈鏈洪�氳瀵硅薄</param>
+        /// <param name="deviceProDTOs">鍫嗗灈鏈哄崗璁俊鎭�</param>
+        /// <param name="deviceProtocolDetailDTOs">鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�</param>
+        /// <param name="deviceCode">璁惧缂栧彿</param>
+        /// <param name="deviceName">璁惧鍚嶇О</param>
+        public SpeFormationStackerCrane(BaseCommunicator communicator, List<DeviceProDTO> deviceProDTOs, List<DeviceProtocolDetailDTO> deviceProtocolDetailDTOs, string deviceCode, string deviceName)
+        {
+            _communicator = communicator;
+            _deviceProDTOs = deviceProDTOs;
+            _deviceProtocolDetailDTOs = deviceProtocolDetailDTOs;
+            _deviceCode = deviceCode;
+            _deviceName = deviceName;
+            CheckConnect();
+        }
+
+        #endregion Constructor Function
+
+        #region Private Method
+
+        private object GetStatus(string protocolParamType)
+        {
+            if (!Communicator.IsConnected)
+            {
+                return StackerCraneStatus.Unkonw.ToString();
+            }
+
+            List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == protocolParamType).ToList();
+            if (devicePros.Count == 0)
+            {
+                throw new Exception($"鏈幏鍙栧埌鍗忚淇℃伅锛屽崗璁弬鏁扮被鍨嬶細{protocolParamType}");
+            }
+
+            foreach (var devicePro in devicePros)
+            {
+                object readStatus = Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+
+                DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(
+                    x => x.DeviceProParamName == devicePro.DeviceProParamType
+                    && x.ProtocalDetailValue.Equals(readStatus.ToString()));
+
+                if (deviceProtocolDetail != null)
+                {
+                    return Convert.ToInt32(readStatus);
+                }
+            }
+
+            return StackerCraneStatus.Unkonw.ToString();
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍫嗗灈鏈鸿澶囩姸鎬�
+        /// </summary>
+        /// <returns></returns>
+        private FormationStackerCraneRunStatus GetStackerCraneStatus()
+        {
+            return (FormationStackerCraneRunStatus)GetStatus(nameof(FormationStackerCraneRunStatus));
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍫嗗灈鏈哄伐浣滅姸鎬�
+        /// </summary>
+        /// <returns></returns>
+        private FormationStackerCraneOperationStatus GetStackerCraneWorkStatus()
+        {
+            return (FormationStackerCraneOperationStatus)GetStatus(nameof(FormationStackerCraneOperationStatus));
+        }
+
+        private FormationStackerCraneTaskCompletionStatus GetStackerCraneCompletionStatus()
+        {
+            return (FormationStackerCraneTaskCompletionStatus)GetStatus(nameof(FormationStackerCraneTaskCompletionStatus));
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏋氫妇璇存槑
+        /// </summary>
+        /// <typeparam name="T">鏋氫妇娉涘瀷</typeparam>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        private string GetEnumDes<T>(T value) where T : Enum
+        {
+            FieldInfo? fieldInfo = typeof(T).GetField(value.ToString());
+            if (fieldInfo != null)
+            {
+                DescriptionAttribute? descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
+                if (descriptionAttribute != null)
+                {
+                    return descriptionAttribute.Description;
+                }
+                return "鏈畾涔�";
+            }
+            return "鏈煡";
+        }
+
+        private int GetCurrentTaskNum()
+        {
+            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(CurrentTaskNum));
+            return devicePro == null ? throw new Exception($"璇诲彇褰撳墠浠诲姟鍙烽敊璇�,鏈幏鍙栧埌鍗忚淇℃伅,璇锋鏌ラ厤缃弬鏁板悕绉版槸鍚﹂厤缃�,涓旈厤缃负{nameof(CurrentTaskNum)}") : (int)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+        }
+
+        private void CheckConnect()
+        {
+            Task.Run(() =>
+            {
+                while (_heartStart)
+                {
+                    try
+                    {
+                        DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault();
+                        if (devicePro == null)
+                        {
+                            _isConnected = false;
+                        }
+                        else
+                        {
+                            Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+                            _isConnected = true;
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        _isConnected = false;
+                    }
+                    Thread.Sleep(500);
+                }
+            });
+        }
+
+        #endregion Private Method
+
+        #region Public Method
+
+        /// <summary>
+        /// 鑾峰彇鍫嗗灈鏈虹姸鎬�
+        /// </summary>
+        public T GetStackerCraneStatus<T>() where T : notnull, Enum
+        {
+            return (T)GetStatus(typeof(T).Name);
+        }
+
+        /// <summary>
+        /// 閲婃斁瀵硅薄
+        /// </summary>
+        public void Dispose()
+        {
+            _heartStart = false;
+            _communicator.Dispose();
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// 鏍规嵁鍙傛暟鍚嶇О璇诲彇鍫嗗灈鏈哄搴旂殑鏁版嵁銆�
+        /// </summary>
+        /// <typeparam name="TEnum">鍙傛暟鍚嶇О鏋氫妇绫诲瀷銆�</typeparam>
+        /// <typeparam name="TResult">璇诲彇缁撴灉鐨勮繑鍥炲�肩被鍨嬨��</typeparam>
+        /// <param name="value">鍙傛暟鍚嶇О銆�</param>
+        /// <returns>杩斿洖璇诲彇鍒扮殑鏁版嵁銆�</returns>
+        /// <exception cref="Exception"></exception>
+        public TResult GetValue<TEnum, TResult>(TEnum value) where TEnum : Enum
+        {
+            if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
+            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == value.ToString());
+            return devicePro == null ? throw new Exception($"璇诲彇鏁版嵁閿欒,鏈湪鍗忚淇℃伅閲岄潰鎵惧埌鍙傛暟{value.ToString()}") : (TResult)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
+        }
+
+        /// <summary>
+        /// 蹇冭烦
+        /// </summary>
+        public void Heartbeat()
+        {
+        }
+
+        /// <summary>
+        /// 鍙戦�佷换鍔″懡浠�
+        /// </summary>
+        /// <param name="command">浠诲姟鍛戒护</param>
+        /// <returns></returns>
+        public bool SendCommand<T>(T command) where T : IDataTransfer, new()
+        {
+            if (Communicator is SiemensS7)
+            {
+                if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
+                DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand)).OrderBy(x => x.DeviceProOffset).FirstOrDefault();
+                if (devicePro == null)
+                {
+                    return false;
+                }
+                if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command))
+                {
+                    StackerCraneTaskCommand = command;
+                    //CheckStackerCraneTaskCompleted();
+                    return true;
+                }
+                return false;
+            }
+            else
+            {
+                throw new Exception("鏆備笉鏀寔闄よタ闂ㄥ瓙涔嬪鐨凱LC");
+            }
+        }
+
+        /// <summary>
+        /// 鐩戞祴鍫嗗灈鏈轰换鍔℃槸鍚﹀畬鎴�(闃叉浠诲姟瀹屾垚浜嬩欢鐩戞祴瓒呮椂锛屽畾涔夋墜鍔ㄨЕ鍙戝姛鑳�)
+        /// </summary>
+        public void CheckStackerCraneTaskCompleted()
+        {
+            if (_isChecked)
+                return;
+
+            Task.Run(() =>
+            {
+                _isChecked = true;
+                try
+                {
+                    DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(FormationStackerCraneTaskCompletionStatus));
+                    if (devicePro == null)
+                        return;
+
+                    DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(
+                        x => x.DeviceProParamName == devicePro.DeviceProParamName
+                        && x.ProtocolDetailType == FormationStackerCraneTaskCompletionStatus.NormalCompleted.ToString());
+
+                    if (deviceProtocolDetail == null)
+                        return;
+
+                    OperateResult<TimeSpan> operateResult = WaitForCompletion(devicePro, deviceProtocolDetail);
+
+                    if (operateResult.IsSuccess)
+                    {
+                        int taskNum = CurrentTaskNum;
+                        StackerCraneTaskCompletedEventArgs args = new(taskNum);
+                        StackerCraneTaskCompletedEventHandler?.Invoke(this, args);
+                        _lastTaskNum = taskNum;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    // TODO: 娣诲姞鏃ュ織璁板綍
+                }
+                finally
+                {
+                    _isChecked = false;
+                }
+            });
+        }
+
+        /// <summary>
+        /// 绛夊緟浠诲姟瀹屾垚淇″彿
+        /// </summary>
+        private OperateResult<TimeSpan> WaitForCompletion(DeviceProDTO devicePro, DeviceProtocolDetailDTO deviceProtocolDetail)
+        {
+            TypeCode typeCode = SiemensDBDataType.GetTypeCode(devicePro.DeviceDataType);
+
+            return typeCode switch
+            {
+                TypeCode.Boolean => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue)),
+
+                TypeCode.Byte => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue)),
+
+                TypeCode.Int16 => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue)),
+
+                TypeCode.Int32 => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue)),
+
+                TypeCode.UInt16 => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue)),
+
+                TypeCode.UInt32 => Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000,
+                    Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue)),
+
+                _ => new OperateResult<TimeSpan>()
+            };
+        }
+
+        /// <summary>
+        /// 鏍规嵁鍙傛暟鍚嶇О鍐欏叆鍫嗗灈鏈哄搴旂殑鏁版嵁銆�
+        /// </summary>
+        /// <typeparam name="TEnum">鍙傛暟鍚嶇О鏋氫妇绫诲瀷銆�</typeparam>
+        /// <typeparam name="TValue">瑕佸啓鍏ョ殑鏁版嵁绫诲瀷銆�</typeparam>
+        /// <param name="enum">鍙傛暟鍚嶇О銆�</param>
+        /// <param name="value">瑕佸啓鍏ョ殑鏁版嵁銆�</param>
+        /// <returns>杩斿洖鍐欏叆鎴愬姛鎴栧け璐�</returns>
+        /// <exception cref="Exception"></exception>
+        public bool SetValue<TEnum, TValue>(TEnum @enum, TValue value)
+            where TEnum : Enum
+            where TValue : notnull
+        {
+            if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
+            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == @enum.ToString());
+            return devicePro == null ? throw new Exception($"鍐欏叆鏁版嵁閿欒,鏈湪鍗忚淇℃伅閲岄潰鎵惧埌鍙傛暟{value.ToString()}") : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value);
+        }
+
+        #endregion Public Method
+    }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeStackerCrane.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeStackerCrane.cs
deleted file mode 100644
index 6d19535..0000000
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeStackerCrane.cs
+++ /dev/null
@@ -1,276 +0,0 @@
-锘縰sing HslCommunication;
-using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using WIDESEAWCS_Communicator;
-using WIDESEAWCS_QuartzJob.DeviceBase;
-using WIDESEAWCS_QuartzJob.DTO;
-using WIDESEAWCS_QuartzJob.StackerCrane;
-using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
-
-namespace WIDESEAWCS_QuartzJob
-{
-    /// <summary>
-    /// 鑷畾涔夊爢鍨涙満
-    /// </summary>
-    [Description("鍫嗗灈鏈�2")]
-    public class SpeStackerCrane : IStackerCrane
-    {
-        #region Private Member
-        /// <summary>
-        /// 鍫嗗灈鏈洪�氳瀵硅薄
-        /// </summary>
-        private BaseCommunicator _communicator;
-        /// <summary>
-        /// 鍫嗗灈鏈哄崗璁俊鎭�
-        /// </summary>
-        private readonly List<DeviceProDTO> _deviceProDTOs;
-        /// <summary>
-        /// 鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�
-        /// </summary>
-        private readonly List<DeviceProtocolDetailDTO> _deviceProtocolDetailDTOs;
-        /// <summary>
-        /// 璁惧缂栧彿
-        /// </summary>
-        public readonly string _deviceCode;
-        /// <summary>
-        /// 璁惧鍚嶇О
-        /// </summary>
-        public readonly string _deviceName;
-        /// <summary>
-        /// 涓婁竴娆′换鍔″彿
-        /// </summary>
-        private int _lastTaskNum;
-
-        private bool _isChecked = false;
-
-        private bool _heartStatr = true;
-
-        private bool _isConnected = true;
-        #endregion Private Member
-
-        #region Public Member
-        /// <summary>
-        /// 閫氳瀵硅薄
-        /// </summary>
-        public BaseCommunicator Communicator => _communicator;
-
-        /// <summary>
-        /// 閫氳鍗忚淇℃伅
-        /// </summary>
-        public List<DeviceProDTO> DeviceProDTOs => _deviceProDTOs;
-
-        /// <summary>
-        /// 閫氳鍗忚鏄庣粏淇℃伅
-        /// </summary>
-        public List<DeviceProtocolDetailDTO> DeviceProtocolDetailDTOs => _deviceProtocolDetailDTOs;
-
-        /// <summary>
-        /// 涓婁竴娆℃墽琛岀殑浠诲姟鍙�
-        /// </summary>
-        public int LastTaskNum => _lastTaskNum;
-
-        /// <summary>
-        /// 褰撳墠姝e湪鎵ц鐨勪换鍔″彿
-        /// </summary>
-        public int CurrentTaskNum => GetCurrentTaskNum();
-
-        /// <summary>
-        /// 涓婁竴娆℃墽琛岀殑浠诲姟绫诲瀷
-        /// </summary>
-        public int? LastTaskType { get; set; } = null;
-
-        /// <summary>
-        /// 璁惧缂栧彿
-        /// </summary>
-        public string DeviceCode => _deviceCode;
-
-        /// <summary>
-        /// 璁惧鍚嶇О
-        /// </summary>
-        public string DeviceName => _deviceName;
-
-        /// <summary>
-        /// 璁惧鏄惁宸茶繛鎺�
-        /// </summary>
-        public bool IsConnected => Communicator.IsConnected && _isConnected;
-
-        /// <summary>
-        /// 鍫嗗灈鏈轰换鍔″懡浠�
-        /// </summary>
-        public object StackerCraneTaskCommand { get; set; }
-        #endregion
-
-        #region Constructor Function
-        /// <summary>
-        /// 鏋勯�犲嚱鏁�
-        /// </summary>
-        /// <param name="communicator">鍫嗗灈鏈洪�氳瀵硅薄</param>
-        /// <param name="deviceProDTOs">鍫嗗灈鏈哄崗璁俊鎭�</param>
-        /// <param name="deviceProtocolDetailDTOs">鍫嗗灈鏈哄崗璁槑缁嗕俊鎭�</param>
-        /// <param name="deviceCode">璁惧缂栧彿</param>
-        /// <param name="deviceName">璁惧鍚嶇О</param>
-        public SpeStackerCrane(BaseCommunicator communicator, List<DeviceProDTO> deviceProDTOs, List<DeviceProtocolDetailDTO> deviceProtocolDetailDTOs, string deviceCode, string deviceName)
-        {
-            _communicator = communicator;
-            _deviceProDTOs = deviceProDTOs;
-            _deviceProtocolDetailDTOs = deviceProtocolDetailDTOs;
-            _deviceCode = deviceCode;
-            _deviceName = deviceName;
-            CheckConnect();
-        }
-        #endregion
-
-        #region Private Method
-        private object GetStatus(string protocolParamType)
-        {
-            if (Communicator.IsConnected)
-            {
-                List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == protocolParamType).ToList();
-                if (devicePros.Count == 0)
-                {
-                    throw new Exception("鏈幏鍙栧埌鍗忚淇℃伅");
-                }
-                for (int i = 0; i < devicePros.Count; i++)
-                {
-                    object readStatus = Communicator.ReadAsObj(devicePros[i].DeviceProAddress, devicePros[i].DeviceDataType);
-                    //todo 鍗忚鏄庣粏淇℃伅鏈幏鍙栧埌鏃舵姏鍑哄紓甯�
-                    DeviceProtocolDetailDTO? deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePros[i].DeviceProParamName) ?? throw new Exception();
-                    deviceProtocolDetail = _deviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == devicePros[i].DeviceProParamType && x.ProtocalDetailValue.Equals(readStatus.ToString()));
-                    if (deviceProtocolDetail != null)
-                    {
-                        return Convert.ToInt32(readStatus);
-                    }
-                    return -1;
-                }
-            }
-            //todo 閫氳鏈繛鎺ユ椂鎶涘嚭寮傚父
-            return -1;
-        }
-
-        private int GetCurrentTaskNum()
-        {
-            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(CurrentTaskNum));
-            return devicePro == null ? throw new Exception($"璇诲彇褰撳墠浠诲姟鍙烽敊璇�,鏈幏鍙栧埌鍗忚淇℃伅,璇锋鏌ラ厤缃弬鏁板悕绉版槸鍚﹂厤缃�,涓旈厤缃负{nameof(CurrentTaskNum)}") : (int)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
-        }
-
-        private void CheckConnect()
-        {
-            Task.Run(() =>
-            {
-                while (_heartStatr)
-                {
-                    try
-                    {
-                        DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault();
-                        if (devicePro == null)
-                            _isConnected = false;
-                        else
-                            Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
-                        _isConnected = true;
-                    }
-                    catch (Exception ex)
-                    {
-                        _isConnected = false;
-                    }
-                    Thread.Sleep(500);
-                }
-            });
-        }
-        #endregion
-
-        #region Public Method
-        /// <summary>
-        /// 鑾峰彇鍫嗗灈鏈虹姸鎬�
-        /// </summary>
-        public T GetStackerCraneStatus<T>() where T : notnull, Enum
-        {
-            return (T)GetStatus(typeof(T).Name);
-        }
-
-        /// <summary>
-        /// 閲婃斁瀵硅薄
-        /// </summary>
-        public void Dispose()
-        {
-            _heartStatr = false;
-            _communicator.Dispose();
-            GC.SuppressFinalize(this);
-        }
-
-        /// <summary>
-        /// 鏍规嵁鍙傛暟鍚嶇О璇诲彇鍫嗗灈鏈哄搴旂殑鏁版嵁銆�
-        /// </summary>
-        /// <typeparam name="TEnum">鍙傛暟鍚嶇О鏋氫妇绫诲瀷銆�</typeparam>
-        /// <typeparam name="TResult">璇诲彇缁撴灉鐨勮繑鍥炲�肩被鍨嬨��</typeparam>
-        /// <param name="value">鍙傛暟鍚嶇О銆�</param>
-        /// <returns>杩斿洖璇诲彇鍒扮殑鏁版嵁銆�</returns>
-        /// <exception cref="Exception"></exception>
-        public TResult GetValue<TEnum, TResult>(TEnum value) where TEnum : Enum
-        {
-            if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
-            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == value.ToString());
-            return devicePro == null ? throw new Exception($"璇诲彇鏁版嵁閿欒,鏈湪鍗忚淇℃伅閲岄潰鎵惧埌鍙傛暟{value.ToString()}") : (TResult)Communicator.ReadAsObj(devicePro.DeviceProAddress, devicePro.DeviceDataType);
-        }
-
-        /// <summary>
-        /// 蹇冭烦
-        /// </summary>
-        public void Heartbeat()
-        {
-
-        }
-
-        /// <summary>
-        /// 鍙戦�佷换鍔″懡浠�
-        /// </summary>
-        /// <param name="command">浠诲姟鍛戒护</param>
-        /// <returns></returns>
-        public bool SendCommand<T>(T command) where T : IDataTransfer, new()
-        {
-            if (Communicator is SiemensS7)
-            {
-                if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
-                DeviceProDTO? devicePro = _deviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand)).OrderBy(x => x.DeviceProOffset).FirstOrDefault();
-                if (devicePro == null)
-                {
-                    return false;
-                }
-                if (Communicator.WriteCustomer(devicePro.DeviceProAddress, command))
-                {
-                    StackerCraneTaskCommand = command;
-                    //CheckStackerCraneTaskCompleted();
-                    return true;
-                }
-                return false;
-            }
-            else
-            {
-                throw new Exception("鏆備笉鏀寔闄よタ闂ㄥ瓙涔嬪鐨凱LC");
-            }
-        }
-
-        /// <summary>
-        /// 鏍规嵁鍙傛暟鍚嶇О鍐欏叆鍫嗗灈鏈哄搴旂殑鏁版嵁銆�
-        /// </summary>
-        /// <typeparam name="TEnum">鍙傛暟鍚嶇О鏋氫妇绫诲瀷銆�</typeparam>
-        /// <typeparam name="TValue">瑕佸啓鍏ョ殑鏁版嵁绫诲瀷銆�</typeparam>
-        /// <param name="enum">鍙傛暟鍚嶇О銆�</param>
-        /// <param name="value">瑕佸啓鍏ョ殑鏁版嵁銆�</param>
-        /// <returns>杩斿洖鍐欏叆鎴愬姛鎴栧け璐�</returns>
-        /// <exception cref="Exception"></exception>
-        public bool SetValue<TEnum, TValue>(TEnum @enum, TValue value)
-            where TEnum : Enum
-            where TValue : notnull
-        {
-            if (!IsConnected) throw new Exception($"閫氳杩炴帴閿欒锛岃妫�鏌ョ綉缁�");
-            DeviceProDTO? devicePro = _deviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == @enum.ToString());
-            return devicePro == null ? throw new Exception($"鍐欏叆鏁版嵁閿欒,鏈湪鍗忚淇℃伅閲岄潰鎵惧埌鍙傛暟{value.ToString()}") : Communicator.WriteObj(devicePro.DeviceProAddress, devicePro.DeviceDataType, value);
-        }
-        #endregion
-    }
-}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index 7dd819a..fe6dfbb 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -38,8 +38,8 @@
   "ApiName": "WIDESEAWCS",
   "ExpMinutes": 120,
   "QuartzJobAutoStart": true,
-  "DBSeedEnable": true,
-  "QuartzDBSeedEnable": true,
+  "DBSeedEnable": false,
+  "QuartzDBSeedEnable": false,
   "LogDeubgEnable": false, //鏄惁璁板綍璋冭瘯鏃ュ織
   "PrintSql": true, //鎵撳嵃SQL璇彞
   "LogAOPEnable": true, //鏄惁璁板綍AOP鏃ュ織
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationCommonStackerCraneJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationCommonStackerCraneJob.cs
new file mode 100644
index 0000000..a006e83
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationCommonStackerCraneJob.cs
@@ -0,0 +1,308 @@
+锘縰sing Quartz;
+using System.Diagnostics.CodeAnalysis;
+using WIDESEAWCS_Common.TaskEnum;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_QuartzJob.Models;
+using WIDESEAWCS_QuartzJob.Service;
+using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
+using WIDESEAWCS_Tasks.StackerCraneJob;
+
+namespace WIDESEAWCS_Tasks
+{
+    [DisallowConcurrentExecution]
+    public class FormationCommonStackerCraneJob : IJob
+    {
+        private readonly ITaskService _taskService;
+        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
+        private readonly ITaskRepository _taskRepository;
+        private readonly IRouterService _routerService;
+
+        public FormationCommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService)
+        {
+            _taskService = taskService;
+            _taskExecuteDetailService = taskExecuteDetailService;
+            _taskRepository = taskRepository;
+            _routerService = routerService;
+        }
+
+        public Task Execute(IJobExecutionContext context)
+        {
+            try
+            {
+                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " FormationCommonStackerCraneJob Start");
+
+                bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
+                if (!flag || value is not SpeFormationStackerCrane commonStackerCrane)
+                {
+                    return Task.CompletedTask;
+                }
+
+                if (!commonStackerCrane.IsEventSubscribed)
+                {
+                    commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;
+                }
+
+                if (commonStackerCrane.StackerCraneStatusValue != FormationStackerCraneRunStatus.Standby)
+                {
+                    return Task.CompletedTask;
+                }
+
+                commonStackerCrane.CheckStackerCraneTaskCompleted();
+
+                if (commonStackerCrane.StackerCraneWorkStatusValue == FormationStackerCraneOperationStatus.Idle)
+                {
+                    Dt_Task? task = GetTask(commonStackerCrane);
+                    if (task != null)
+                    {
+                        FormationStackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
+                        if (stackerCraneTaskCommand != null)
+                        {
+                            bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
+                            if (sendFlag)
+                            {
+                                commonStackerCrane.LastTaskType = task.TaskType;
+                                _taskService.UpdateTaskStatusToNext(task.TaskNum);
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"FormationCommonStackerCraneJob Error: {ex.Message}");
+            }
+            return Task.CompletedTask;
+        }
+
+        /// <summary>
+        /// 浠诲姟瀹屾垚浜嬩欢璁㈤槄鐨勬柟娉�
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, WIDESEAWCS_QuartzJob.StackerCrane.StackerCraneTaskCompletedEventArgs e)
+        {
+            SpeFormationStackerCrane? commonStackerCrane = sender as SpeFormationStackerCrane;
+            if (commonStackerCrane != null)
+            {
+                if (commonStackerCrane.GetValue<FormationStackerCraneDBName, short>(FormationStackerCraneDBName.WorkType) != 7)
+                {
+                    Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
+                    _taskService.StackCraneTaskCompleted(e.TaskNum);
+                    commonStackerCrane.SetValue(FormationStackerCraneDBName.WorkType, 4);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇浠诲姟
+        /// </summary>
+        /// <param name="commonStackerCrane">鍫嗗灈鏈哄璞�</param>
+        /// <returns></returns>
+        private Dt_Task? GetTask(SpeFormationStackerCrane commonStackerCrane)
+        {
+            Dt_Task? task = null;
+
+            if (commonStackerCrane.LastTaskType == null)
+            {
+                task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
+            }
+            else
+            {
+                if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
+                {
+                    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
+                    task ??= _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
+                }
+                else
+                {
+                    task = _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
+                }
+            }
+
+            if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
+            {
+                if (IsOutTaskStationAvailable(task))
+                {
+                    return task;
+                }
+
+                List<string> otherOutStationCodes = _routerService.QueryNextRoutes(commonStackerCrane.DeviceCode, task.NextAddress, task.TaskType)
+                    .Select(x => x.ChildPosi).ToList();
+
+                List<Dt_Task> tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode, otherOutStationCodes);
+
+                foreach (var alternativeTask in tasks)
+                {
+                    if (IsOutTaskStationAvailable(alternativeTask))
+                    {
+                        return alternativeTask;
+                    }
+                }
+
+                task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
+            }
+
+            return task;
+        }
+
+        /// <summary>
+        /// 妫�鏌ュ嚭搴撲换鍔$殑鍑哄簱绔欏彴鏄惁鍙敤
+        /// </summary>
+        /// <param name="task">浠诲姟瀹炰綋</param>
+        /// <returns>濡傛灉绔欏彴鍙敤杩斿洖true锛屽惁鍒欒繑鍥瀎alse</returns>
+        private bool IsOutTaskStationAvailable([NotNull] Dt_Task task)
+        {
+            Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.NextAddress, task.TaskType);
+            if (router == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.NextAddress}銆戜俊鎭紝鏃犳硶鏍¢獙绔欏彴");
+                return false;
+            }
+
+            IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
+            if (device == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒板嚭搴撶珯鍙般�恵router.ChildPosiDeviceCode}銆戝搴旂殑閫氳瀵硅薄锛屾棤娉曞垽鏂嚭搴撶珯鍙版槸鍚﹁鍗犵敤");
+                return false;
+            }
+
+            CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
+            return conveyorLine.IsOccupied(router.ChildPosi);
+        }
+
+        /// <summary>
+        /// 浠诲姟瀹炰綋杞崲鎴愬懡浠odel
+        /// </summary>
+        /// <param name="task">浠诲姟瀹炰綋</param>
+        /// <returns></returns>
+        public FormationStackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task)
+        {
+            FormationStackerCraneTaskCommand stackerCraneTaskCommand = new FormationStackerCraneTaskCommand
+            {
+                Barcode = task.PalletCode,
+                TaskNum = task.TaskNum,
+                WorkType = 4,
+                WorkAction = 1,
+                FireAlarm = 0,
+                FieldName = ""
+            };
+
+            TaskTypeGroup taskTypeGroup = task.TaskType.GetTaskTypeGroup();
+
+            return taskTypeGroup switch
+            {
+                TaskTypeGroup.InboundGroup => BuildInboundCommand(task, stackerCraneTaskCommand),
+                TaskTypeGroup.OutbondGroup => BuildOutboundCommand(task, stackerCraneTaskCommand),
+                TaskTypeGroup.RelocationGroup => BuildRelocationCommand(task, stackerCraneTaskCommand),
+                _ => stackerCraneTaskCommand
+            };
+        }
+
+        /// <summary>
+        /// 鏋勫缓鍏ュ簱鍛戒护
+        /// </summary>
+        private FormationStackerCraneTaskCommand? BuildInboundCommand(Dt_Task task, FormationStackerCraneTaskCommand command)
+        {
+            Dt_Router? router = _routerService.QueryNextRoute(task.CurrentAddress, task.Roadway, task.TaskType);
+            if (router == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.CurrentAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鍙栬揣绔欏彴淇℃伅");
+                return null;
+            }
+
+            command.StartRow = Convert.ToInt16(router.SrmRow);
+            command.StartColumn = Convert.ToInt16(router.SrmColumn);
+            command.StartLayer = Convert.ToInt16(router.SrmLayer);
+
+            if (!TryParseAddress(task.NextAddress, out short endRow, out short endColumn, out short endLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍏ュ簱浠诲姟缁堢偣閿欒锛岀粓鐐癸細銆恵task.NextAddress}銆�");
+                return null;
+            }
+
+            command.EndRow = endRow;
+            command.EndColumn = endColumn;
+            command.EndLayer = endLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 鏋勫缓鍑哄簱鍛戒护
+        /// </summary>
+        private FormationStackerCraneTaskCommand? BuildOutboundCommand(Dt_Task task, FormationStackerCraneTaskCommand command)
+        {
+            Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.TargetAddress, task.TaskType);
+            if (router == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.TargetAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鏀捐揣绔欏彴淇℃伅");
+                return null;
+            }
+
+            command.EndRow = Convert.ToInt16(router.SrmRow);
+            command.EndColumn = Convert.ToInt16(router.SrmColumn);
+            command.EndLayer = Convert.ToInt16(router.SrmLayer);
+
+            if (!TryParseAddress(task.CurrentAddress, out short startRow, out short startColumn, out short startLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍑哄簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
+                return null;
+            }
+
+            command.StartRow = startRow;
+            command.StartColumn = startColumn;
+            command.StartLayer = startLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 鏋勫缓绉诲簱鍛戒护
+        /// </summary>
+        private FormationStackerCraneTaskCommand? BuildRelocationCommand(Dt_Task task, FormationStackerCraneTaskCommand command)
+        {
+            if (!TryParseAddress(task.NextAddress, out short endRow, out short endColumn, out short endLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟缁堢偣閿欒锛岀粓鐐癸細銆恵task.NextAddress}銆�");
+                return null;
+            }
+
+            command.EndRow = endRow;
+            command.EndColumn = endColumn;
+            command.EndLayer = endLayer;
+
+            if (!TryParseAddress(task.CurrentAddress, out short startRow, out short startColumn, out short startLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
+                return null;
+            }
+
+            command.StartRow = startRow;
+            command.StartColumn = startColumn;
+            command.StartLayer = startLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 瑙f瀽鍦板潃瀛楃涓诧紙鏍煎紡锛氳-鍒�-灞傦級
+        /// </summary>
+        private bool TryParseAddress(string address, out short row, out short column, out short layer)
+        {
+            row = column = layer = 0;
+
+            string[] parts = address.Split("-");
+            if (parts.Length != 3)
+            {
+                return false;
+            }
+
+            return short.TryParse(parts[0], out row)
+                && short.TryParse(parts[1], out column)
+                && short.TryParse(parts[2], out layer);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneDBName.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneDBName.cs
new file mode 100644
index 0000000..3c6b6ba
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneDBName.cs
@@ -0,0 +1,84 @@
+锘�#region << 鐗� 鏈� 娉� 閲� >>
+
+/*----------------------------------------------------------------
+ * 鍛藉悕绌洪棿锛歐IDESEAWCS_Tasks.StackerCraneJob
+ * 鍒涘缓鑰咃細鑳$搴�
+ * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36
+ * 鐗堟湰锛歏1.0.0
+ * 鎻忚堪锛�
+ *
+ * ----------------------------------------------------------------
+ * 淇敼浜猴細
+ * 淇敼鏃堕棿锛�
+ * 鐗堟湰锛歏1.0.1
+ * 淇敼璇存槑锛�
+ *
+ *----------------------------------------------------------------*/
+
+#endregion << 鐗� 鏈� 娉� 閲� >>
+
+namespace WIDESEAWCS_Tasks.StackerCraneJob
+{
+    public enum FormationStackerCraneDBName
+    {
+        /// <summary>
+        /// 蹇冭烦
+        /// </summary>
+        HeartBeat,
+
+        /// <summary>
+        /// 浠诲姟鍙�
+        /// </summary>
+        TaskNum,
+
+        /// <summary>
+        /// 浣滀笟鎸囦护
+        /// </summary>
+        WorkAction,
+
+        /// <summary>
+        /// 娑堥槻鎸囦护
+        /// </summary>
+        FireAlarm,
+
+        /// <summary>
+        /// 浣滀笟绫诲瀷
+        /// </summary>
+        WorkType,
+
+        /// <summary>
+        /// 璧峰琛�
+        /// </summary>
+        StartRow,
+
+        /// <summary>
+        /// 璧峰鍒�
+        /// </summary>
+        StartColumn,
+
+        /// <summary>
+        /// 璧峰灞�
+        /// </summary>
+        StartLayer,
+
+        /// <summary>
+        /// 鐩爣琛�
+        /// </summary>
+        EndRow,
+
+        /// <summary>
+        /// 鐩爣鍒�
+        /// </summary>
+        EndColumn,
+
+        /// <summary>
+        /// 鐩爣灞�
+        /// </summary>
+        EndLayer,
+
+        /// <summary>
+        /// 鎵樼洏鍙�
+        /// </summary>
+        Barcode,
+    }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs
new file mode 100644
index 0000000..1c368a5
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs
@@ -0,0 +1,97 @@
+锘�#region << 鐗� 鏈� 娉� 閲� >>
+
+/*----------------------------------------------------------------
+ * 鍛藉悕绌洪棿锛歐IDESEAWCS_Tasks.StackerCraneJob
+ * 鍒涘缓鑰咃細鑳$搴�
+ * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36
+ * 鐗堟湰锛歏1.0.0
+ * 鎻忚堪锛�
+ *
+ * ----------------------------------------------------------------
+ * 淇敼浜猴細
+ * 淇敼鏃堕棿锛�
+ * 鐗堟湰锛歏1.0.1
+ * 淇敼璇存槑锛�
+ *
+ *----------------------------------------------------------------*/
+
+#endregion << 鐗� 鏈� 娉� 閲� >>
+
+using WIDESEAWCS_QuartzJob.DeviceBase;
+
+namespace WIDESEAWCS_Tasks.StackerCraneJob
+{
+    public class FormationStackerCraneTaskCommand : DeviceCommand
+    {
+        #region <Public Menber>
+
+        /// <summary>
+        /// 蹇冭烦
+        /// </summary>
+        public short HeartBeat { get; set; }
+
+        /// <summary>
+        /// 浠诲姟鍙�
+        /// </summary>
+        public int TaskNum { get; set; }
+
+        /// <summary>
+        /// 鏃犳晥瀛楁
+        /// </summary>
+        [DataLength(32)]
+        public string FieldName { get; set; }
+
+        /// <summary>
+        /// 浣滀笟鎸囦护
+        /// </summary>
+        public short WorkAction { get; set; }
+
+        /// <summary>
+        /// 娑堥槻鎸囦护
+        /// </summary>
+        public short FireAlarm { get; set; }
+
+        /// <summary>
+        /// 浣滀笟绫诲瀷
+        /// </summary>
+        public short WorkType { get; set; }
+
+        /// <summary>
+        /// 璧峰琛�
+        /// </summary>
+        public short StartRow { get; set; }
+
+        /// <summary>
+        /// 璧峰鍒�
+        /// </summary>
+        public short StartColumn { get; set; }
+
+        /// <summary>
+        /// 璧峰灞�
+        /// </summary>
+        public short StartLayer { get; set; }
+
+        /// <summary>
+        /// 鐩爣琛�
+        /// </summary>
+        public short EndRow { get; set; }
+
+        /// <summary>
+        /// 鐩爣鍒�
+        /// </summary>
+        public short EndColumn { get; set; }
+
+        /// <summary>
+        /// 鐩爣灞�
+        /// </summary>
+        public short EndLayer { get; set; }
+
+        /// <summary>
+        /// 鎵樼洏鍙�
+        /// </summary>
+        [DataLength(26)]
+        public string Barcode { get; set; }
+
+        #endregion <Public Menber>
+    }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
index 6ed2eb2..ee38b1e 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -43,40 +43,40 @@
         {
             try
             {
-                List<Dt_Task> tasks = _taskService.Repository.QueryData();
-
                 Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " CommonStackerCraneJob Start");
-                bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
-                if (flag && value != null && value is CommonStackerCrane commonStackerCrane)
-                {
-                    if (!commonStackerCrane.IsEventSubscribed)
-                    {
-                        commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//璁㈤槄浠诲姟瀹屾垚浜嬩欢
-                    }
-                    if (commonStackerCrane.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && commonStackerCrane.StackerCraneStatusValue == StackerCraneStatus.Normal)
-                    {
-                        commonStackerCrane.CheckStackerCraneTaskCompleted();//闃叉浠诲姟瀹屾垚浜嬩欢鐩戞祴瓒呮椂锛屽啀鎵嬪姩瑙﹀彂涓�娆�
 
-                        if (commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
+                bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
+                if (!flag || value is not CommonStackerCrane commonStackerCrane)
+                {
+                    return Task.CompletedTask;
+                }
+
+                if (!commonStackerCrane.IsEventSubscribed)
+                {
+                    commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;
+                }
+
+                if (commonStackerCrane.StackerCraneAutoStatusValue != StackerCraneAutoStatus.Automatic
+                    || commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal)
+                {
+                    return Task.CompletedTask;
+                }
+
+                commonStackerCrane.CheckStackerCraneTaskCompleted();
+
+                if (commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
+                {
+                    Dt_Task? task = GetTask(commonStackerCrane);
+                    if (task != null)
+                    {
+                        StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
+                        if (stackerCraneTaskCommand != null)
                         {
-                            Dt_Task? task = GetTask(commonStackerCrane);
-                            if (task != null)
+                            bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
+                            if (sendFlag)
                             {
-                                int num = new Random().Next(1, 100);
-                                if (num < 30)
-                                {
-                                    throw new CommunicationException("閿欒娴嬭瘯", CommunicationErrorType.Unknown);
-                                }
-                                StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
-                                if (stackerCraneTaskCommand != null)
-                                {
-                                    bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
-                                    if (sendFlag)
-                                    {
-                                        commonStackerCrane.LastTaskType = task.TaskType;
-                                        _taskService.UpdateTaskStatusToNext(task.TaskNum);
-                                    }
-                                }
+                                commonStackerCrane.LastTaskType = task.TaskType;
+                                _taskService.UpdateTaskStatusToNext(task.TaskNum);
                             }
                         }
                     }
@@ -84,6 +84,7 @@
             }
             catch (Exception ex)
             {
+                Console.WriteLine($"CommonStackerCraneJob Error: {ex.Message}");
             }
             return Task.CompletedTask;
         }
@@ -114,7 +115,7 @@
         /// <returns></returns>
         private Dt_Task? GetTask(CommonStackerCrane commonStackerCrane)
         {
-            Dt_Task task;
+            Dt_Task? task = null;
             if (commonStackerCrane.LastTaskType == null)
             {
                 task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
@@ -124,10 +125,7 @@
                 if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
                 {
                     task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
-                    if (task == null)
-                    {
-                        task = _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
-                    }
+                    task ??= _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
                 }
                 else
                 {
@@ -137,58 +135,50 @@
 
             if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
             {
-                if (OutTaskStationIsOccupied(task) != null)
+                if (IsOutTaskStationAvailable(task))
                 {
                     return task;
                 }
-                else
+
+                List<string> otherOutStationCodes = _routerService.QueryNextRoutes(commonStackerCrane.DeviceCode, task.NextAddress, task.TaskType)
+                    .Select(x => x.ChildPosi).ToList();
+                List<Dt_Task> tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode, otherOutStationCodes);
+                foreach (var alternativeTask in tasks)
                 {
-                    List<string> otherOutStaionCodes = _routerService.QueryNextRoutes(commonStackerCrane.DeviceCode, task.NextAddress).Select(x => x.ChildPosi).ToList();
-                    List<Dt_Task> tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode, otherOutStaionCodes);
-                    foreach (var item in tasks)
+                    if (IsOutTaskStationAvailable(alternativeTask))
                     {
-                        if (OutTaskStationIsOccupied(task) != null)
-                        {
-                            return task;
-                        }
+                        return alternativeTask;
                     }
-                    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
                 }
+                task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
             }
 
             return task;
         }
 
         /// <summary>
-        /// 鍑哄簱浠诲姟鍒ゆ柇鍑哄簱绔欏彴鏄惁琚崰鐢�
+        /// 鍑哄簱浠诲姟鍒ゆ柇鍑哄簱绔欏彴鏄惁鍙敤
         /// </summary>
         /// <param name="task">浠诲姟瀹炰綋</param>
-        /// <returns>濡傛灉鏈鍗犵敤锛岃繑鍥炰紶鍏ョ殑浠诲姟淇℃伅锛屽惁鍒欙紝杩斿洖null</returns>
-        private Dt_Task? OutTaskStationIsOccupied([NotNull] Dt_Task task)
+        /// <returns>濡傛灉绔欏彴鍙敤杩斿洖true锛屽惁鍒欒繑鍥瀎alse</returns>
+        private bool IsOutTaskStationAvailable([NotNull] Dt_Task task)
         {
-
-            Dt_Router? router = _routerService.QueryNextRoutes(task.Roadway, task.NextAddress).FirstOrDefault();
-            if (router != null)
-            {
-                IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
-                if (device != null)
-                {
-                    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
-                    if (conveyorLine.IsOccupied(router.ChildPosi))//鍑哄簱绔欏彴鏈鍗犵敤
-                    {
-                        return task;
-                    }
-                }
-                else
-                {
-                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒板嚭搴撶珯鍙般�恵router.ChildPosiDeviceCode}銆戝搴旂殑閫氳瀵硅薄锛屾棤娉曞垽鏂嚭搴撶珯鍙版槸鍚﹁鍗犵敤");
-                }
-            }
-            else
+            Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.NextAddress, task.TaskType);
+            if (router == null)
             {
                 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.NextAddress}銆戜俊鎭紝鏃犳硶鏍¢獙绔欏彴");
+                return false;
             }
-            return null;
+
+            IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
+            if (device == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒板嚭搴撶珯鍙般�恵router.ChildPosiDeviceCode}銆戝搴旂殑閫氳瀵硅薄锛屾棤娉曞垽鏂嚭搴撶珯鍙版槸鍚﹁鍗犵敤");
+                return false;
+            }
+
+            CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
+            return conveyorLine.IsOccupied(router.ChildPosi);
         }
 
         /// <summary>
@@ -196,103 +186,128 @@
         /// </summary>
         /// <param name="task">浠诲姟瀹炰綋</param>
         /// <returns></returns>
-        /// <exception cref="Exception"></exception>
         public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task)
         {
-            StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand();
-
-            stackerCraneTaskCommand.Barcode = task.PalletCode;
-            stackerCraneTaskCommand.TaskNum = task.TaskNum;
-            stackerCraneTaskCommand.WorkType = 1;
-            stackerCraneTaskCommand.TrayType = 0;
-            if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//鍒ゆ柇鏄惁鏄叆搴撲换鍔�
+            StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand
             {
-                List<Dt_Router> routers = _routerService.QueryNextRoutes(task.CurrentAddress, task.Roadway);
-                if (routers.Count > 0)
-                {
-                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
-                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
-                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
+                Barcode = task.PalletCode,
+                TaskNum = task.TaskNum,
+                WorkType = 1,
+                TrayType = 0
+            };
 
-                    string[] targetCodes = task.NextAddress.Split("-");
-                    if (targetCodes.Length == 3)
-                    {
-                        stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]);
-                        stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]);
-                        stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]);
-                    }
-                    else
-                    {
-                        //鏁版嵁閰嶇疆閿欒
-                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍏ュ簱浠诲姟缁堢偣閿欒锛岃捣鐐癸細銆恵task.NextAddress}銆�");
-                        return null;
-                    }
-                }
-                else
-                {
-                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.NextAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鍙栬揣绔欏彴淇℃伅");
-                    return null;
-                }
-            }
-            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
+            TaskTypeGroup taskTypeGroup = task.TaskType.GetTaskTypeGroup();
+            return taskTypeGroup switch
             {
-                List<Dt_Router> routers = _routerService.QueryNextRoutes(task.Roadway, task.TargetAddress);
-                if (routers.Count > 0)
-                {
-                    stackerCraneTaskCommand.EndRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
-                    stackerCraneTaskCommand.EndColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
-                    stackerCraneTaskCommand.EndLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
+                TaskTypeGroup.InboundGroup => BuildInboundCommand(task, stackerCraneTaskCommand),
+                TaskTypeGroup.OutbondGroup => BuildOutboundCommand(task, stackerCraneTaskCommand),
+                TaskTypeGroup.RelocationGroup => BuildRelocationCommand(task, stackerCraneTaskCommand),
+                _ => stackerCraneTaskCommand
+            };
+        }
 
-                    string[] sourceCodes = task.CurrentAddress.Split("-");
-                    if (sourceCodes.Length == 3)
-                    {
-                        stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]);
-                        stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
-                        stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
-                    }
-                    else
-                    {
-                        //鏁版嵁閰嶇疆閿欒
-                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍑哄簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
-                        return null;
-                    }
-                }
-                else
-                {
-                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.NextAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鏀捐揣绔欏彴淇℃伅");
-                    return null;
-                }
-            }
-            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup)
+        /// <summary>
+        /// 鏋勫缓鍏ュ簱鍛戒护
+        /// </summary>
+        private StackerCraneTaskCommand? BuildInboundCommand(Dt_Task task, StackerCraneTaskCommand command)
+        {
+            Dt_Router? router = _routerService.QueryNextRoute(task.CurrentAddress, task.Roadway, task.TaskType);
+            if (router == null)
             {
-                string[] targetCodes = task.NextAddress.Split("-");
-                if (targetCodes.Length == 3)
-                {
-                    stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]);
-                    stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]);
-                    stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]);
-                }
-                else
-                {
-                    //鏁版嵁閰嶇疆閿欒
-                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟缁堢偣閿欒锛岃捣鐐癸細銆恵task.NextAddress}銆�");
-                    return null;
-                }
-                string[] sourceCodes = task.CurrentAddress.Split("-");
-                if (sourceCodes.Length == 3)
-                {
-                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]);
-                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
-                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
-                }
-                else
-                {
-                    //鏁版嵁閰嶇疆閿欒
-                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
-                    return null;
-                }
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.CurrentAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鍙栬揣绔欏彴淇℃伅");
+                return null;
             }
-            return stackerCraneTaskCommand;
+
+            command.StartRow = Convert.ToInt16(router.SrmRow);
+            command.StartColumn = Convert.ToInt16(router.SrmColumn);
+            command.StartLayer = Convert.ToInt16(router.SrmLayer);
+
+            if (!TryParseAddress(task.NextAddress, out short endRow, out short endColumn, out short endLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍏ュ簱浠诲姟缁堢偣閿欒锛岀粓鐐癸細銆恵task.NextAddress}銆�");
+                return null;
+            }
+
+            command.EndRow = endRow;
+            command.EndColumn = endColumn;
+            command.EndLayer = endLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 鏋勫缓鍑哄簱鍛戒护
+        /// </summary>
+        private StackerCraneTaskCommand? BuildOutboundCommand(Dt_Task task, StackerCraneTaskCommand command)
+        {
+            Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.TargetAddress, task.TaskType);
+            if (router == null)
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.TargetAddress}銆戜俊鎭紝鏃犳硶鑾峰彇瀵瑰簲鐨勫爢鍨涙満鏀捐揣绔欏彴淇℃伅");
+                return null;
+            }
+
+            command.EndRow = Convert.ToInt16(router.SrmRow);
+            command.EndColumn = Convert.ToInt16(router.SrmColumn);
+            command.EndLayer = Convert.ToInt16(router.SrmLayer);
+
+            if (!TryParseAddress(task.CurrentAddress, out short startRow, out short startColumn, out short startLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鍑哄簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
+                return null;
+            }
+
+            command.StartRow = startRow;
+            command.StartColumn = startColumn;
+            command.StartLayer = startLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 鏋勫缓绉诲簱鍛戒护
+        /// </summary>
+        private StackerCraneTaskCommand? BuildRelocationCommand(Dt_Task task, StackerCraneTaskCommand command)
+        {
+            if (!TryParseAddress(task.NextAddress, out short endRow, out short endColumn, out short endLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟缁堢偣閿欒锛岀粓鐐癸細銆恵task.NextAddress}銆�");
+                return null;
+            }
+
+            command.EndRow = endRow;
+            command.EndColumn = endColumn;
+            command.EndLayer = endLayer;
+
+            if (!TryParseAddress(task.CurrentAddress, out short startRow, out short startColumn, out short startLayer))
+            {
+                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"绉诲簱浠诲姟璧风偣閿欒锛岃捣鐐癸細銆恵task.CurrentAddress}銆�");
+                return null;
+            }
+
+            command.StartRow = startRow;
+            command.StartColumn = startColumn;
+            command.StartLayer = startLayer;
+
+            return command;
+        }
+
+        /// <summary>
+        /// 瑙f瀽鍦板潃瀛楃涓诧紙鏍煎紡锛氳-鍒�-灞傦級
+        /// </summary>
+        private bool TryParseAddress(string address, out short row, out short column, out short layer)
+        {
+            row = column = layer = 0;
+
+            string[] parts = address.Split("-");
+            if (parts.Length != 3)
+            {
+                return false;
+            }
+
+            return short.TryParse(parts[0], out row)
+                && short.TryParse(parts[1], out column)
+                && short.TryParse(parts[2], out layer);
         }
     }
 }
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\345\274\200\345\217\221\350\256\241\345\210\222/\345\211\257\346\234\254\351\231\225\347\205\244\351\241\271\347\233\256\345\274\200\345\217\221\350\256\241\345\210\222260126.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\345\274\200\345\217\221\350\256\241\345\210\222/\345\211\257\346\234\254\351\231\225\347\205\244\351\241\271\347\233\256\345\274\200\345\217\221\350\256\241\345\210\222260126.xlsx"
new file mode 100644
index 0000000..1657f7d
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\345\274\200\345\217\221\350\256\241\345\210\222/\345\211\257\346\234\254\351\231\225\347\205\244\351\241\271\347\233\256\345\274\200\345\217\221\350\256\241\345\210\222260126.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx"
new file mode 100644
index 0000000..9e4ea08
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip"
new file mode 100644
index 0000000..a06de9c
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip"
Binary files differ

--
Gitblit v1.9.3