This commit is contained in:
tanglong 2026-08-21 09:29:20 +08:00
parent 07c5933b06
commit 78ac4ae259
2 changed files with 221 additions and 0 deletions

View File

@ -0,0 +1,32 @@
using System.Collections.Generic;
namespace YD_YiLu.Commons.Dto.Running
{
/// <summary>
/// 阳光跑跑道人员状态上报。
/// </summary>
public class RunningStageRequestDto
{
public string DeviceSerial { get; set; }
public List<RunUserRecognizeDto> RunUserList { get; set; } = new List<RunUserRecognizeDto>();
}
/// <summary>
/// 阳光跑跑道识别人员。
/// </summary>
public class RunUserRecognizeDto
{
public string UserSerial { get; set; }
public string Nickname { get; set; }
public string Base64face { get; set; }
public int Status { get; set; }
public int TrackIndex { get; set; }
public int Result { get; set; }
public int Medal { get; set; }
public int GroupId { get; set; }
public int Uid { get; set; }
public int QuizId { get; set; }
public string DeviceSerial { get; set; }
public int ErrorStatus { get; set; }
}
}

View File

@ -0,0 +1,189 @@
using System.Net.WebSockets;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using YD_YiLu.Api.WebSockets;
using YD_YiLu.Commons.Dto.Running;
namespace YD_YiLu.Api.Controllers
{
/// <summary>
/// 阳光跑接口。
/// </summary>
[AllowAnonymous]
public class RunningController : ControllerBase
{
private readonly ICameraDeviceSocketRegistry _registry;
private readonly ILogger<RunningController> _logger;
public RunningController(ICameraDeviceSocketRegistry registry, ILogger<RunningController> logger)
{
_registry = registry;
_logger = logger;
}
/// <summary>
/// 跑道人员变更状态。
/// </summary>
[HttpPost]
[Route("/running/result/stage")]
public object ResultStage([FromBody] RunningStageRequestDto dto)
{
_logger.LogInformation(
"Running stage changed. DeviceSerial: {DeviceSerial}, UserCount: {UserCount}",
dto?.DeviceSerial,
dto?.RunUserList?.Count ?? 0);
return new { };
}
/// <summary>
/// 平台指定用户下发人脸通知(旧)。
/// </summary>
[HttpPost]
[Route("/station:user:push")]
public async Task<object> StationUserPush([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("station:user:push", body, deviceSerial);
}
/// <summary>
/// 平台下发人脸通知。
/// </summary>
[HttpPost]
[Route("/station:remind")]
public async Task<object> StationRemind([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("station:remind", body, deviceSerial);
}
/// <summary>
/// 跑步小组重启。
/// </summary>
[HttpPost]
[Route("/running:group:restart")]
public async Task<object> RunningGroupRestart([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("running:group:restart", body, deviceSerial);
}
/// <summary>
/// 跑步小组推送。
/// </summary>
[HttpPost]
[Route("/running:group:push")]
public async Task<object> RunningGroupPush([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("running:group:push", body, deviceSerial);
}
/// <summary>
/// 跑步小组自动分组。
/// </summary>
[HttpPost]
[Route("/running:group:auto")]
public async Task<object> RunningGroupAuto([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("running:group:auto", body, deviceSerial);
}
/// <summary>
/// 设备指令。
/// </summary>
[HttpPost]
[Route("/device:instruct")]
public async Task<object> DeviceInstruct([FromBody] JObject body, [FromQuery] string deviceSerial = "")
{
return await SendSocketMessageAsync("device:instruct", body, deviceSerial);
}
private async Task<object> SendSocketMessageAsync(string request, JObject body, string deviceSerial)
{
body ??= new JObject();
var serial = FirstNotEmpty(deviceSerial, FindString(body, "serialNumber"), FindString(body, "deviceSerial"));
if (string.IsNullOrWhiteSpace(serial))
{
return new
{
success = false,
message = "deviceSerial不能为空"
};
}
if (!_registry.TryGet(serial, out var socket) || socket.State != WebSocketState.Open)
{
return new
{
success = false,
serialNumber = serial,
message = "设备不在线"
};
}
var message = NormalizeSocketMessage(request, body);
await CameraDeviceWebSocketHandler.SendAsync(
socket,
message.ToString(Formatting.None),
HttpContext.RequestAborted);
_logger.LogInformation("Running socket message sent. Request: {Request}, SerialNumber: {SerialNumber}", request, serial);
return new
{
success = true,
serialNumber = serial
};
}
private static JObject NormalizeSocketMessage(string request, JObject body)
{
var message = (JObject)body.DeepClone();
if (string.IsNullOrWhiteSpace(message["msgId"]?.ToString()))
message["msgId"] = Guid.NewGuid().ToString("N");
message["request"] = request;
message["code"] ??= 0;
message["msg"] ??= "";
message["data"] ??= new JObject();
return message;
}
private static string FirstNotEmpty(params string[] values)
{
return values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x)) ?? "";
}
private static string FindString(JToken token, string name)
{
if (token == null)
return "";
if (token.Type == JTokenType.Object)
{
var obj = (JObject)token;
foreach (var property in obj.Properties())
{
if (string.Equals(property.Name, name, StringComparison.OrdinalIgnoreCase))
{
var value = property.Value?.ToString();
if (!string.IsNullOrWhiteSpace(value))
return value;
}
}
}
foreach (var child in token.Children())
{
var value = FindString(child, name);
if (!string.IsNullOrWhiteSpace(value))
return value;
}
return "";
}
}
}