10 KiB
10 KiB
网关 MC4 模块整改方案 v1.0
版本: 1.0 日期: 2026-06-03 基准:
doc/设计文档/网关MC4模块检查报告20260603.md
1. 整改总览
| 步骤 | 优先级 | 内容 | 文件 | 预计 |
|---|---|---|---|---|
| M1 | 🔴 P0 | Mc4AuthHelper 认证修复 | Mc4AuthHelper.cs + appsettings | 1h |
| M2 | 🟠 P1 | 批量点位查询 | Mc4Adapter.cs | 30min |
| M3 | 🟡 P2 | 历史告警查询 | Mc4Adapter.cs | 30min |
| M4 | 🟡 P2 | B4-batch 路由改用 native batch | Program.cs | 15min |
| M5 | 验证 | 编译 + 联调 | — | 30min |
| 合计 | — | — | 4 文件 | ~3h |
2. 步骤 M1: Mc4AuthHelper 认证修复(预计 1h)
2.1 问题
// 当前: 调 /conf/get (返回 { "encrypt": true }),误读为 Token
var resp = await _http.PostAsync($"{_baseUrl}/api/central/auth/conf/get", null);
var result = JsonSerializer.Deserialize<Mc4AuthResponse>(json);
_token = result?.Token ?? ""; // Token 始终为 null
2.2 MC4.0 实际认证流程
1. POST /api/central/auth/conf/get → { "encrypt": true/false }
2. 若 encrypt=true → 密码 MD5(原始密码)
3. POST /api/central/auth/login {
"account": "admin",
"password": "md5或原始密码"
}
→ { "token": "xxx", "id": 0, "account": "admin", "name": "管理员" }
2.3 修改后的 Mc4AuthHelper
public class Mc4AuthHelper
{
private readonly HttpClient _http;
private readonly string _baseUrl;
private readonly string _account;
private readonly string _password;
private string? _token;
private DateTime _tokenExpiry = DateTime.MinValue;
private bool? _needMd5;
public Mc4AuthHelper(HttpClient http, string baseUrl, string account, string password)
{
_http = http;
_baseUrl = baseUrl.TrimEnd('/');
_account = account;
_password = password;
}
public async Task<string> GetTokenAsync()
{
if (!string.IsNullOrEmpty(_token) && DateTime.UtcNow < _tokenExpiry)
return _token;
// 1. 获取加密配置
if (!_needMd5.HasValue)
{
var confResp = await _http.PostAsync($"{_baseUrl}/api/central/auth/conf/get", null);
if (confResp.IsSuccessStatusCode)
{
var confJson = await confResp.Content.ReadAsStringAsync();
var conf = JsonSerializer.Deserialize<Mc4ConfResponse>(confJson);
_needMd5 = conf?.Encrypt ?? false;
}
else
{
_needMd5 = false; // 失败时假定不需要加密
}
}
// 2. 登录获取 Token
var pwd = _needMd5 == true ? ComputeMd5(_password) : _password;
var loginBody = JsonSerializer.Serialize(new { account = _account, password = pwd });
var resp = await _http.PostAsync($"{_baseUrl}/api/central/auth/login",
new StringContent(loginBody, Encoding.UTF8, "application/json"));
resp.EnsureSuccessStatusCode();
var json = await resp.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<Mc4LoginResponse>(json)
?? throw new Exception("MC4 登录失败");
_token = result.Token ?? "";
_tokenExpiry = DateTime.UtcNow.AddHours(7); // 保守估计 8h
return _token;
}
public async Task<HttpClient> GetAuthenticatedClientAsync()
{
var token = await GetTokenAsync();
var client = new HttpClient { BaseAddress = new Uri(_baseUrl) };
if (!string.IsNullOrEmpty(token))
client.DefaultRequestHeaders.Add("token", token);
return client;
}
public void Invalidate() => _token = null;
private static string ComputeMd5(string input) { /* MD5 实现 or use System.Security.Cryptography */ }
private class Mc4ConfResponse { public bool? Encrypt { get; set; } }
private class Mc4LoginResponse { public string? Token { get; set; } public int Id { get; set; } public string? Account { get; set; } }
}
2.4 构造函数签名变更
// 旧: public Mc4AuthHelper(HttpClient http, string baseUrl)
// 新: public Mc4AuthHelper(HttpClient http, string baseUrl, string account, string password)
2.5 Mc4Adapter 构造函数变更
// 旧:
public Mc4Adapter(string adapterCode, HttpClient http, string baseUrl)
{
_auth = new Mc4AuthHelper(http, baseUrl);
}
// 新:
public Mc4Adapter(string adapterCode, HttpClient http, string baseUrl,
string account = "admin", string password = "admin")
{
_auth = new Mc4AuthHelper(http, baseUrl, account, password);
}
2.6 Program.cs 注册变更
// 旧: new Mc4Adapter(code, http, m.BaseUrl)
// 新: new Mc4Adapter(code, http, m.BaseUrl,
// m.Username ?? "admin", m.Password ?? "admin")
2.7 Mc4Config 增加字段
public class Mc4Config
{
public string? InstanceName { get; set; }
public string BaseUrl { get; set; } = "";
public string Username { get; set; } = "admin"; // 新增
public string Password { get; set; } = "admin"; // 新增
}
2.8 appsettings.json 更新
"MC4": [
{ "InstanceName": "31ku", "BaseUrl": "http://localhost:3000",
"Username": "admin", "Password": "your_mc4_password" }
]
2.9 编译验证
dotnet build gateway/IntegrationGateway.slnx → 0 错误。
M1 提交点:
Fix-M1: Mc4AuthHelper 认证修复 conf/get→login + account/password支持
3. 步骤 M2: 批量点位查询(预计 30min)
3.1 文件
gateway/src/IntegrationGateway.Adapters.MC4/Mc4Adapter.cs
3.2 新增方法
/// <summary>批量获取多个设备的实时点位值(MC4.0 原生 multi/value/get)</summary>
public async Task<Dictionary<int, List<Mc4PointValue>>> GetMultiRealtimeValuesAsync(List<int> deviceIds)
{
await _limiter.WaitAsync();
var client = await _auth.GetAuthenticatedClientAsync();
var body = JsonSerializer.Serialize(new { ids = deviceIds });
var resp = await client.PostAsync("/api/central/point/multi/value/get",
new StringContent(body, Encoding.UTF8, "application/json"));
resp.EnsureSuccessStatusCode();
var json = await resp.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<Dictionary<int, List<Mc4PointValue>>>(json)!;
return result;
}
3.3 编译验证
dotnet build → 0 错误。
M2 提交点:
Fix-M2: MC4 批量点位查询 GetMultiRealtimeValuesAsync
4. 步骤 M3: 历史告警查询(预计 30min)
4.1 新增 DTO
/// <summary>MC4.0 历史告警查询请求</summary>
public class Mc4HisAlarmQuery
{
public string From { get; set; } = "";
public string To { get; set; } = "";
public int Skip { get; set; }
public int Limit { get; set; }
public int Sort { get; set; } = 1;
}
4.2 新增方法
/// <summary>查询 MC4.0 历史告警(已恢复的告警)</summary>
public async Task<PagedResult<StandardAlarm>> GetHisAlarmsAsync(int page, int size, DateTime from, DateTime to)
{
await _limiter.WaitAsync();
var client = await _auth.GetAuthenticatedClientAsync();
var body = JsonSerializer.Serialize(new Mc4HisAlarmQuery
{
From = from.ToString("yyyy-MM-dd HH:mm:ss"),
To = to.ToString("yyyy-MM-dd HH:mm:ss"),
Skip = (page - 1) * size,
Limit = size,
Sort = 1
});
var resp = await client.PostAsync("/api/central/his_alarm/query",
new StringContent(body, Encoding.UTF8, "application/json"));
resp.EnsureSuccessStatusCode();
var json = await resp.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<Mc4AlarmQueryResult>(json)!;
return new PagedResult<StandardAlarm>
{
Items = (result.List ?? new()).Select(MapAlarmItem).ToList(),
Total = result.Total
};
}
private StandardAlarm MapAlarmItem(Mc4AlarmItem a) => new()
{
AlarmId = a.Id ?? "",
AdapterCode = AdapterCode,
Level = MapAlarmLevel(a.Level),
Title = a.Desc ?? "",
OccurTime = DateTime.TryParse(a.Stime, out var st) ? st : DateTime.MinValue,
Status = MapAlarmState(a.State),
ActualValue = a.Soption?.Value,
ThresholdValue = a.Eoption?.Value
};
4.3 编译验证
dotnet build → 0 错误。
M3 提交点:
Fix-M3: MC4 历史告警查询 GetHisAlarmsAsync
5. 步骤 M4: B4-batch 路由优化(预计 15min)
5.1 修改
gateway/src/IntegrationGateway.Host/Program.cs B4-batch 路由改用 MC4 原生批量接口:
// B4-batch 改用 MC4 原生 multi/value/get
app.MapPost("/api/gateway/realtime/{adapter}/batch", async (string adapter, BatchRealtimeRequest req) =>
{
var a = registry.FindByCode<IHasPoints>(adapter);
if (a == null) return Results.NotFound();
if (a is Mc4Adapter mc4 && req.DeviceIds?.Count > 0)
{
// MC4.0 原生批量接口
var intIds = req.DeviceIds.Select(int.Parse).ToList();
var multi = await mc4.GetMultiRealtimeValuesAsync(intIds);
return Results.Ok(multi);
}
// 其他适配器 fallback
var results = new Dictionary<string, List<PointValue>>();
foreach (var id in req.DeviceIds ?? new())
try { results[id] = await a.GetRealtimeValuesAsync(id); } catch { }
return Results.Ok(results);
});
5.2 编译验证
dotnet build → 0 错误。
M4 提交点:
Fix-M4: B4-batch 优化 MC4原生批量接口
6. 步骤 M5: 编译验证 + 联调
dotnet build gateway/IntegrationGateway.slnx→ 0 错误 0 警告- MC4 appsettings.json 填入真实
Username/Password - 网关启动 → A1 注册 → A3 同步 MC4 设备树
- B4-batch 调
multi/value/get返回批量值 - 告警查询
/alarms/MC4:31ku有数据 - Mc4AuthHelper Token 非空 → 登录流程正常
M5 提交点:
Fix-M5: MC4整改全量编译验证通过
7. 改动文件汇总
| 步骤 | 文件 | 改动 |
|---|---|---|
| M1 | Mc4AuthHelper.cs |
重写认证流程: conf/get → login |
| M1 | Mc4Adapter.cs |
构造函数加 account/password |
| M1 | Program.cs |
Mc4Adapter 构造传 Username/Password |
| M1 | appsettings.json |
MC4 数组加 Username/Password |
| M2 | Mc4Adapter.cs |
新增 GetMultiRealtimeValuesAsync |
| M3 | Mc4Adapter.cs |
新增 GetHisAlarmsAsync + DTO |
| M4 | Program.cs |
B4-batch 优化 MC4 原生批量 |