# RouterService 逻辑修复与新方法实现计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 修复 RouterService 中的 3 个逻辑问题,新增 7 个路由查询/管理方法,并更新接口层。 **Architecture:** 在现有 RouterService 基础上新增缓存管理方法和路由查询增强方法,保持现有 HybridCacheService 缓存架构不变。 **Tech Stack:** ASP.NET Core 6.0, HybridCacheService, SqlSugar ORM --- ## 文件变更概览 **修改文件:** - `WIDESEAWCS_QuartzJob/Service/RouterService.cs` — 逻辑修复 + 新增方法实现 - `WIDESEAWCS_QuartzJob/Service/IRouterService.cs` — 接口新增方法签名 + 去掉多余 `public` 修饰符 --- ## Task 1: 修复 AddRouters 缓存一致性问题 **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:605-613` **原代码:** ```csharp BaseDal.AddData(routers); List updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType); string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}"; _cacheService.AddOrUpdate(cacheKey, updatedRouters); content = WebResponseContent.Instance.OK(); ``` **改为:** ```csharp // 添加新的路由信息 BaseDal.AddData(routers); // 重新查询全量路由(此时才包含新增的路由),再写入缓存 List updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType); string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}"; try { _cacheService.AddOrUpdate(cacheKey, updatedRouters); } catch { // 缓存更新失败时静默忽略,下次查询会从DB自动重建缓存 } content = WebResponseContent.Instance.OK(); ``` **说明**:用 try-catch 包裹缓存更新操作,防止缓存写入失败时异常逃逸到外层被当作错误返回。DB 已写入成功,缓存失败不影响业务正确性。 --- ## Task 2: 修复 QueryAllPositions 空 catch 块 **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:412-415` **原代码:** ```csharp catch { } ``` **改为:** ```csharp catch (Exception ex) { ConsoleHelper.WriteErrorLine($"RouterService.QueryAllPositions 查询失败: {ex.Message}"); } ``` **说明**:增加错误日志记录,便于排查问题。返回值仍为空列表,调用方行为不变。 --- ## Task 3: 修复 IRouterService 接口 public 修饰符 + 新增方法签名 **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/IRouterService.cs` 去掉以下行的 `public` 修饰符: - 第40行:`public Dt_Router QueryNextRoute(string startPosi);` → `Dt_Router QueryNextRoute(string startPosi);` - 第48行 - 第57行 - 第65行 - 第74行 同时在接口末尾新增以下方法签名: ```csharp /// /// 清除路由缓存 /// void ClearRouterCache(); /// /// 根据设备编号查询经过该设备的所有路由 /// List QueryRoutersByDeviceCode(string deviceCode); /// /// 判断两点之间是否存在路由(全类型) /// bool ExistsRouter(string startPosi, string endPosi); /// /// 判断两点之间是否存在指定类型的路由 /// bool ExistsRouter(string startPosi, string endPosi, int routeType); /// /// 获取全量路由数量(合并入口+出口) /// int GetRouterCount(); /// /// 获取指定类型路由数量 /// int GetRouterCount(int routeType); /// /// 批量删除路由 /// WebResponseContent DeleteRouters(List routerIds); ``` --- ## Task 4: 实现 ClearRouterCache() **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 在 `GetAllRoutersFromCache` 方法之后新增: ```csharp /// /// 清除所有路由缓存(入口和出口类型) /// public void ClearRouterCache() { _cacheService.Remove("Router:AllRouters:In"); _cacheService.Remove("Router:AllRouters:Out"); } ``` --- ## Task 5: 实现 QueryRoutersByDeviceCode **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 在 `ClearRouterCache` 之后新增: ```csharp /// /// 根据设备编号查询经过该设备的所有路由(合并入口+出口类型) /// /// 设备编号 /// 经过该设备的路由列表 public List QueryRoutersByDeviceCode(string deviceCode) { List inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()); List outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()); return inRouters.Concat(outRouters) .Where(x => x.ChildPosiDeviceCode == deviceCode) .ToList(); } ``` --- ## Task 6: 实现 ExistsRouter(两个重载) **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 在 `QueryRoutersByDeviceCode` 之后新增: ```csharp /// /// 判断两点之间是否存在路由(全类型) /// public bool ExistsRouter(string startPosi, string endPosi) { List inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()); List outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()); var allRouters = inRouters.Concat(outRouters).ToList(); var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, null); return routes.Count > 0; } /// /// 判断两点之间是否存在指定类型的路由 /// public bool ExistsRouter(string startPosi, string endPosi, int routeType) { List allRouters = GetAllRoutersFromCache(routeType); var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType); return routes.Count > 0; } ``` --- ## Task 7: 实现 GetRouterCount(两个重载) **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 在 `ExistsRouter` 之后新增: ```csharp /// /// 获取全量路由数量(入口+出口合计) /// public int GetRouterCount() { int inCount = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()).Count; int outCount = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()).Count; return inCount + outCount; } /// /// 获取指定类型路由数量 /// public int GetRouterCount(int routeType) { return GetAllRoutersFromCache(routeType).Count; } ``` --- ## Task 8: 实现 DeleteRouters **文件:** - Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 在 `AddRouters` 方法之后新增: ```csharp /// /// 批量删除指定ID的路由,删除后同步清除对应类型的缓存 /// /// 待删除的路由ID列表 /// 返回处理结果 public WebResponseContent DeleteRouters(List routerIds) { WebResponseContent content = new WebResponseContent(); try { if (routerIds == null || routerIds.Count == 0) { return content = WebResponseContent.Instance.Error("待删除的路由ID列表不能为空"); } // 查询待删除路由的类型(用于后续清除缓存) var routersToDelete = BaseDal.QueryData(x => routerIds.Contains(x.Id)); if (routersToDelete.Count == 0) { return content = WebResponseContent.Instance.Error("未找到待删除的路由"); } // 记录涉及的类型(去重) var affectedTypes = routersToDelete.Select(x => x.InOutType).Distinct().ToList(); // 执行批量删除 BaseDal.DeleteData(routersToDelete); // 清除受影响类型的缓存 foreach (var routeType in affectedTypes) { string cacheKey = $"Router:AllRouters:{(routeType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}"; _cacheService.Remove(cacheKey); } content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } ``` --- ## Task 9: 编译验证 **验证命令:** ```bash dotnet build WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj ``` 预期:0 errors --- ## 实施顺序 1. Task 1 — 修复 AddRouters 缓存一致性 2. Task 2 — 修复 QueryAllPositions 空 catch 块 3. Task 3 — 修复 IRouterService 接口(去掉 public + 新增签名) 4. Task 4 — 实现 ClearRouterCache 5. Task 5 — 实现 QueryRoutersByDeviceCode 6. Task 6 — 实现 ExistsRouter 两个重载 7. Task 7 — 实现 GetRouterCount 两个重载 8. Task 8 — 实现 DeleteRouters 9. Task 9 — 编译验证