编辑 | blame | 历史 | 原始文档

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行

同时在接口末尾新增以下方法签名:

/// <summary>
/// 清除路由缓存
/// </summary>
void ClearRouterCache();

/// <summary>
/// 根据设备编号查询经过该设备的所有路由
/// </summary>
List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode);

/// <summary>
/// 判断两点之间是否存在路由(全类型)
/// </summary>
bool ExistsRouter(string startPosi, string endPosi);

/// <summary>
/// 判断两点之间是否存在指定类型的路由
/// </summary>
bool ExistsRouter(string startPosi, string endPosi, int routeType);

/// <summary>
/// 获取全量路由数量(合并入口+出口)
/// </summary>
int GetRouterCount();

/// <summary>
/// 获取指定类型路由数量
/// </summary>
int GetRouterCount(int routeType);

/// <summary>
/// 批量删除路由
/// </summary>
WebResponseContent DeleteRouters(List<long> routerIds);

Task 4: 实现 ClearRouterCache()

文件:
- Modify: WIDESEAWCS_QuartzJob/Service/RouterService.cs

GetAllRoutersFromCache 方法之后新增:

/// <summary>
/// 清除所有路由缓存(入口和出口类型)
/// </summary>
public void ClearRouterCache()
{
    _cacheService.Remove("Router:AllRouters:In");
    _cacheService.Remove("Router:AllRouters:Out");
}

Task 5: 实现 QueryRoutersByDeviceCode

文件:
- Modify: WIDESEAWCS_QuartzJob/Service/RouterService.cs

ClearRouterCache 之后新增:

/// <summary>
/// 根据设备编号查询经过该设备的所有路由(合并入口+出口类型)
/// </summary>
/// <param name="deviceCode">设备编号</param>
/// <returns>经过该设备的路由列表</returns>
public List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode)
{
    List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
    List<Dt_Router> 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 之后新增:

/// <summary>
/// 判断两点之间是否存在路由(全类型)
/// </summary>
public bool ExistsRouter(string startPosi, string endPosi)
{
    List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
    List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
    var allRouters = inRouters.Concat(outRouters).ToList();
    var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
    return routes.Count > 0;
}

/// <summary>
/// 判断两点之间是否存在指定类型的路由
/// </summary>
public bool ExistsRouter(string startPosi, string endPosi, int routeType)
{
    List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
    var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
    return routes.Count > 0;
}

Task 7: 实现 GetRouterCount(两个重载)

文件:
- Modify: WIDESEAWCS_QuartzJob/Service/RouterService.cs

ExistsRouter 之后新增:

/// <summary>
/// 获取全量路由数量(入口+出口合计)
/// </summary>
public int GetRouterCount()
{
    int inCount = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()).Count;
    int outCount = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()).Count;
    return inCount + outCount;
}

/// <summary>
/// 获取指定类型路由数量
/// </summary>
public int GetRouterCount(int routeType)
{
    return GetAllRoutersFromCache(routeType).Count;
}

Task 8: 实现 DeleteRouters

文件:
- Modify: WIDESEAWCS_QuartzJob/Service/RouterService.cs

AddRouters 方法之后新增:

/// <summary>
/// 批量删除指定ID的路由,删除后同步清除对应类型的缓存
/// </summary>
/// <param name="routerIds">待删除的路由ID列表</param>
/// <returns>返回处理结果</returns>
public WebResponseContent DeleteRouters(List<long> 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 — 编译验证