1111
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
using Evergreen.Health.Application.Health.Entities;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Evergreen.Health.Application.Health.Integrations.Ib43;
|
||||
|
||||
// 仅由本地维护程序调用;不是 Controller,也不注册 HTTP 路由。
|
||||
public sealed class Ib43LocalBinding(ISqlSugarClient db, TimeProvider clock)
|
||||
{
|
||||
public async Task<HealthIb43Binding> Run(string phone, Ib43Options options, string actor, bool apply)
|
||||
{
|
||||
var device = options.Devices.SingleOrDefault(d => d.ProductKey == "evergreen-test" && d.SerialNumber == "IB43SIM001");
|
||||
if (device?.Simulation != true) throw new InvalidOperationException("模拟设备白名单不匹配,已停止。");
|
||||
var users = await db.Queryable<HealthUser>().Where(u => u.Phone == phone && !u.IsDelete &&
|
||||
u.Status == HealthUserStatus.Enabled).Select(u => new { u.Id }).ToListAsync();
|
||||
if (users.Count != 1) throw new InvalidOperationException("未找到唯一且已启用的健康账号,已停止。");
|
||||
var key = Ib43DataRepository.DeviceKey(device.ProductKey, device.SerialNumber);
|
||||
var slot = key + ".left";
|
||||
var existing = await db.Queryable<HealthIb43Binding>().Where(b => b.ActiveSlot == slot).FirstAsync();
|
||||
if (existing != null)
|
||||
{
|
||||
if (existing.UserId != users[0].Id || !existing.Simulation || existing.EndedAtMs != null)
|
||||
throw new InvalidOperationException("左侧已被其他用户或非模拟绑定占用,未覆盖或解绑。");
|
||||
return existing;
|
||||
}
|
||||
var binding = new HealthIb43Binding
|
||||
{
|
||||
DeviceKey = key, ProductKey = device.ProductKey, SerialNumber = device.SerialNumber,
|
||||
Side = "left", ActiveSlot = slot, UserId = users[0].Id, BedName = "IB43模拟床垫左侧",
|
||||
Simulation = true, StartedAtMs = clock.GetUtcNow().ToUnixTimeMilliseconds(), AssignedBy = 0
|
||||
};
|
||||
if (!apply) return binding;
|
||||
if (string.IsNullOrWhiteSpace(actor) || actor.Length > 200) throw new InvalidOperationException("维护操作者信息不合法。");
|
||||
var stage = "binding";
|
||||
await db.Ado.BeginTranAsync();
|
||||
try
|
||||
{
|
||||
await db.Insertable(binding).ExecuteCommandAsync();
|
||||
stage = "audit";
|
||||
await db.Insertable(new HealthIb43MaintenanceAudit
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N"), BindingId = binding.Id, UserId = binding.UserId,
|
||||
Actor = actor, OccurredAtMs = binding.StartedAtMs, Operation = "local-bind-simulator-left"
|
||||
}).ExecuteCommandAsync();
|
||||
stage = "commit";
|
||||
await db.Ado.CommitTranAsync();
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
await db.Ado.RollbackTranAsync();
|
||||
var code = error is MySqlConnector.MySqlException mysql ? $" MySQL {mysql.Number}" : "";
|
||||
throw new InvalidOperationException($"绑定事务失败 ({stage}, {error.GetType().Name}{code}),请重新预检确认数据库状态。", error);
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user