wanshenmean
2026-03-27 4b22bcec7226c8a05c27f3c839630a31e1f38ef8
docs: 添加 RouterService 逻辑修复与新方法设计文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
已添加1个文件
104 ■■■■■ 文件已修改
Code/WCS/WIDESEAWCS_Server/docs/superpowers/specs/2026-03-27-router-service-audit-design.md 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/docs/superpowers/specs/2026-03-27-router-service-audit-design.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,104 @@
# RouterService é€»è¾‘修复与新方法设计
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:writing-plans to create implementation plan.
**Goal:** ä¿®å¤ `RouterService` ä¸­å·²å‘现的逻辑错误,新增 5 ä¸ªè·¯ç”±æŸ¥è¯¢/管理方法,并更新接口层。
**Architecture:** åœ¨çŽ°æœ‰ `RouterService` åŸºç¡€ä¸Šæ–°å¢žç¼“存管理方法和路由查询增强方法,保持现有缓存架构不变。
**Tech Stack:** ASP.NET Core 6.0, HybridCacheService, SqlSugar ORM
---
## ä¸€ã€çŽ°æœ‰é€»è¾‘é—®é¢˜ä¿®å¤
### 1.1 AddRouters ç¼“存一致性
**问题**:`BaseDal.AddData` å’Œ `_cacheService.AddOrUpdate` ä¹‹é—´æ— ä¿æŠ¤ã€‚如果 `AddOrUpdate` æŠ›å¼‚常,DB å·²å†™å…¥ä½†ç¼“存未更新,下次查询读到旧数据。
**修复**:使用 try-finally é€»è¾‘,保证 DB å†™å…¥åŽå†æ›´æ–°ç¼“存。如果缓存更新失败,下次查询会从 DB è‡ªåŠ¨é‡å»ºç¼“å­˜ï¼ˆ`GetOrAdd` æ‡’加载保证)。
### 1.2 QueryAllPositions ç©º catch å—
**问题**:catch å—仅有注释,无实际日志记录。异常被静默吞掉,调用方无法区分"没有数据"和"查询失败"。
**修复**:增加 `ConsoleHelper.WriteErrorLine` è®°å½•错误。
### 1.3 æŽ¥å£å±‚ public ä¿®é¥°ç¬¦
**问题**:`IRouterService` ä¸­çš„æ–¹æ³•签名有多余的 `public` ä¿®é¥°ç¬¦ã€‚
**修复**:移除接口方法上的 `public` ä¿®é¥°ç¬¦ã€‚
---
## äºŒã€æ–°å¢žæ–¹æ³•设计
### 2.1 ClearRouterCache()
清除 `Router:AllRouters:In` å’Œ `Router:AllRouters:Out` ä¸¤ä¸ªç¼“存键。
**签名**:`void ClearRouterCache()`
**实现**:
```csharp
_cacheService.Remove("Router:AllRouters:In");
_cacheService.Remove("Router:AllRouters:Out");
```
### 2.2 QueryRoutersByDeviceCode(string deviceCode)
查询经过指定设备的所有路由(合并入口/出口类型)。
**签名**:`List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode)`
**逻辑**:从缓存加载 In + Out è·¯ç”±ï¼Œç­›é€‰ `ChildPosiDeviceCode == deviceCode` çš„路由。
**缓存**:不独占缓存,直接使用现有 `GetAllRoutersFromCache` èŽ·å–æ•°æ®ã€‚
### 2.3 ExistsRouter(两个重载)
判断两点之间是否存在路由。
**签名**:
- `bool ExistsRouter(string startPosi, string endPosi)` â€” å…¨ç±»åž‹
- `bool ExistsRouter(string startPosi, string endPosi, int routeType)` â€” æŒ‡å®šç±»åž‹
**逻辑**:调用 `FindRoutesInMemory`,返回 `routers.Count > 0`。
### 2.4 GetRouterCount(两个重载)
返回路由数量。
**签名**:
- `int GetRouterCount()` â€” åˆå¹¶ In + Out æ€»æ•°
- `int GetRouterCount(int routeType)` â€” æŒ‡å®šç±»åž‹æ•°é‡
**实现**:从缓存获取后 `.Count`。
### 2.5 DeleteRouters(List<long> routerIds)
批量删除指定 ID çš„路由,删除后同步清除对应类型缓存。
**签名**:`WebResponseContent DeleteRouters(List<long> routerIds)`
**逻辑**:
1. æŸ¥å‡ºå¾…删除路由各自的 `InOutType`
2. `BaseDal.DeleteData` æ‰¹é‡åˆ é™¤
3. æ ¹æ®æ¶‰åŠçš„ `InOutType` æ¸…除对应缓存键
4. è¿”回 `WebResponseContent`
---
## ä¸‰ã€æ¶‰åŠæ–‡ä»¶
| æ–‡ä»¶ | æ”¹åЍ |
|------|------|
| `WIDESEAWCS_QuartzJob/Service/RouterService.cs` | ä¿®å¤é€»è¾‘ + æ–°å¢žæ–¹æ³•实现 |
| `WIDESEAWCS_QuartzJob/Service/IRouterService.cs` | æŽ¥å£æ–°å¢žæ–¹æ³•签名,去掉多余 `public` |
---
## å››ã€ç¼“存键汇总
| é”® | ç”¨é€” |
|----|------|
| `Router:AllRouters:In` | å…¥å£ç±»åž‹å…¨é‡è·¯ç”± |
| `Router:AllRouters:Out` | å‡ºå£ç±»åž‹å…¨é‡è·¯ç”± |
| `System:DevicePositions:{deviceCode}` | `QueryAllPositions` å·²æœ‰ç¼“存,不在本方案范围内 |