1092 lines
38 KiB
C#
1092 lines
38 KiB
C#
using DocumentFormat.OpenXml.EMMA;
|
||
using DocumentFormat.OpenXml.Math;
|
||
using DocumentFormat.OpenXml.Office2010.Excel;
|
||
using DocumentFormat.OpenXml.Spreadsheet;
|
||
using HidSharp;
|
||
using Infrastructure;
|
||
using Infrastructure.Cache;
|
||
using Infrastructure.CloudSdk.minio;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Minio;
|
||
using MQTTnet;
|
||
using OpenAuth.App.ServiceApp;
|
||
using OpenAuth.App.ServiceApp.Response;
|
||
using OpenAuth.Repository.Domain;
|
||
using SixLabors.ImageSharp;
|
||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||
using SixLabors.ImageSharp.PixelFormats;
|
||
using SixLabors.ImageSharp.Processing;
|
||
using StackExchange.Redis;
|
||
using System.Text;
|
||
using System.Text.Json;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace OpenAuth.WebApi.Controllers.ServiceControllers
|
||
{
|
||
/// <summary>
|
||
/// 机场运维
|
||
/// </summary>
|
||
[Route("api/[controller]/[action]")]
|
||
[ApiController]
|
||
public class AirportMaintenanceController : ControllerBase
|
||
{
|
||
private readonly AirportMaintenanceApp _app;
|
||
private readonly MqttClientManager _mqttClientManager;
|
||
private readonly MqttMessageCenter _mqttCenter;
|
||
private readonly RedisCacheContext _cache;
|
||
private readonly HttpClient _httpClient;
|
||
private readonly MinioService _minioService;
|
||
|
||
public AirportMaintenanceController(AirportMaintenanceApp app, MqttClientManager mqttClientManager,
|
||
MqttMessageCenter mqttCenter, RedisCacheContext cache, HttpClient httpClient, MinioService minioService)
|
||
{
|
||
_app = app;
|
||
_mqttClientManager = mqttClientManager;
|
||
_mqttCenter = mqttCenter;
|
||
_cache = cache;
|
||
_httpClient = httpClient;
|
||
_minioService = minioService;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 机场注册 注册码生成
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[Obsolete]
|
||
public async Task<Response<LasaDeviceBindingCode>> GetDeviceBindingCode()
|
||
{
|
||
var result = new Response<LasaDeviceBindingCode>();
|
||
try
|
||
{
|
||
result = await _app.GetDeviceBindingCode();
|
||
//发送MQTT消息
|
||
if (result.Code == 200 && result.Result != null)
|
||
{
|
||
var topicRequest = $"thing/product/{result.Result.DeviceBindingCode}/requests";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "airport_organization_bind",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
bind_devices = new[]
|
||
{
|
||
new
|
||
{
|
||
device_binding_code = result.Result.DeviceBindingCode,
|
||
organization_id = result.Result.OrgId
|
||
}
|
||
}
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
//在这个地方在接收一下?
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 机场注册 注册码生成
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<LasaGateway>> GetGateway()
|
||
{
|
||
var result = new Response<LasaGateway>();
|
||
try
|
||
{
|
||
result = await _app.GetGateway();
|
||
//自动更新主题
|
||
string sn = result.Result.GatewaySn;
|
||
var topics = new List<string>();
|
||
topics.AddRange(new[]
|
||
{
|
||
$"thing/product/{sn}/osd",
|
||
$"thing/product/{sn}/events",
|
||
$"thing/product/{sn}/requests",
|
||
$"thing/product/{sn}/services"
|
||
});
|
||
await _mqttCenter.SubscribeAsync(topics.ToArray());
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取网关列表
|
||
/// </summary>
|
||
/// <param name="page"></param>
|
||
/// <param name="limit"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
public async Task<Response<PageInfo<List<LasaGateway>>>> GetGatewayList(int page, int limit)
|
||
{
|
||
var result = new Response<PageInfo<List<LasaGateway>>>();
|
||
try
|
||
{
|
||
result = await _app.GetPageList(page, limit);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
#region 固件版本管理
|
||
|
||
/// <summary>
|
||
/// 添加固件版本
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[AllowAnonymous]
|
||
public async Task<Response<bool>> AddFirmware(LasaFirmware info)
|
||
{
|
||
var result = new Response<bool>();
|
||
try
|
||
{
|
||
result = await _app.AddFirmware(info);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改无人机或机场版本
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[AllowAnonymous]
|
||
public async Task<Response<bool>> UpdateFirmware(string id, string version, int type)
|
||
{
|
||
var result = new Response<bool>();
|
||
try
|
||
{
|
||
result = await _app.UpdateFirmware(id, version, type);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传固件文件
|
||
/// </summary>
|
||
/// <param name="xmlFile"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("upload")]
|
||
[AllowAnonymous]
|
||
public async Task<IActionResult> UploadFirmwareFile(IFormFile xmlFile)
|
||
{
|
||
if (xmlFile == null || xmlFile.Length == 0)
|
||
return BadRequest("文件为空");
|
||
var path = await _app.UploadFile(xmlFile);
|
||
return Ok(new { message = "上传成功", path });
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 切换相机
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> ExchangeCamera(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/services";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "live_camera_change",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
camera_position = zhiboReq.position,
|
||
video_id = zhiboReq.videoId
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
|
||
var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
|
||
|
||
await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
|
||
{
|
||
var payload = args.ApplicationMessage.Payload;
|
||
var message = Encoding.UTF8.GetString(payload);
|
||
Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
|
||
await Task.CompletedTask;
|
||
});
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 设置直播镜头
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> SetCamera(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/services";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "live_lens_change",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
video_type = zhiboReq.cameraType,
|
||
video_id = zhiboReq.videoId
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
|
||
var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
|
||
|
||
await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
|
||
{
|
||
var payload = args.ApplicationMessage.Payload;
|
||
var message = Encoding.UTF8.GetString(payload);
|
||
Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
|
||
await Task.CompletedTask;
|
||
});
|
||
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 设置直播清晰度
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> SetCameraVideo(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/services";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "live_set_quality",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
video_quality = zhiboReq.videoQuality,
|
||
video_id = zhiboReq.videoId
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
|
||
var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
|
||
|
||
await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
|
||
{
|
||
var payload = args.ApplicationMessage.Payload;
|
||
var message = Encoding.UTF8.GetString(payload);
|
||
Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
|
||
await Task.CompletedTask;
|
||
});
|
||
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 停止直播
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> EndLive(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/services";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "live_stop_push",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
video_id = zhiboReq.videoId
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
|
||
var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
|
||
|
||
await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
|
||
{
|
||
var payload = args.ApplicationMessage.Payload;
|
||
var message = Encoding.UTF8.GetString(payload);
|
||
Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
|
||
await Task.CompletedTask;
|
||
});
|
||
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 关联minio
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> RefMinio(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/requests_reply";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "storage_config_get",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
output = new
|
||
{
|
||
bucket = "test",
|
||
credentials = new
|
||
{
|
||
access_key_id = "minioadmin",
|
||
access_key_secret = "minioadmin",
|
||
expire = 3600,
|
||
security_token = "security_token"
|
||
},
|
||
endpoint = "175.27.168.120:6013",
|
||
object_key_prefix = "",
|
||
provider = "ali",
|
||
region = "hz"
|
||
},
|
||
result = 0
|
||
}
|
||
};
|
||
|
||
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 开始直播
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<Response<int>> StartLive(Zhibo zhiboReq)
|
||
{
|
||
Response<int> response = new Response<int>();
|
||
try
|
||
{
|
||
var videoids = zhiboReq.videoId.Split("/");
|
||
var topicRequest = $"thing/product/" + videoids[0] + "/services";
|
||
var requestData = new
|
||
{
|
||
bid = Guid.NewGuid().ToString(),
|
||
method = "live_start_push",
|
||
tid = Guid.NewGuid().ToString(),
|
||
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||
data = new
|
||
{
|
||
url_type = zhiboReq.urlType,
|
||
url = zhiboReq.url,
|
||
video_quality = zhiboReq.videoQuality,
|
||
video_id = zhiboReq.videoId
|
||
}
|
||
};
|
||
string payload = JsonSerializer.Serialize(requestData);
|
||
await _mqttClientManager.PublishAsync(topicRequest, payload);
|
||
|
||
var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
|
||
await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
|
||
{
|
||
var payload1 = args.ApplicationMessage.Payload;
|
||
var message = Encoding.UTF8.GetString(payload1);
|
||
Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
|
||
await Task.CompletedTask;
|
||
});
|
||
|
||
response.Result = 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
response.Code = 500;
|
||
response.Message = ex.Message;
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
|
||
#region redis 多用户控制
|
||
|
||
/// <summary>
|
||
/// 添加修改mqtt客户端信息
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[AllowAnonymous]
|
||
public async Task<Response<bool>> AddOrUpdateRedisUser(MqttClientResp info)
|
||
{
|
||
var result = new Response<bool>();
|
||
try
|
||
{
|
||
var clientKey = $"client:{info.UserId}";
|
||
string lockSetKey = "locked_users";
|
||
|
||
// 查询所有锁定用户
|
||
var existingLocked = await _cache.SetMembersAsync(lockSetKey);
|
||
|
||
// 如果有锁定用户,并且锁定的用户不是当前用户,则拒绝
|
||
if (existingLocked.Length > 0 && info.IsLock == true)
|
||
{
|
||
bool isCurrentUserLocked = existingLocked.Any(u => u == info.UserId);
|
||
if (!isCurrentUserLocked)
|
||
{
|
||
result.Code = 400;
|
||
result.Message = "已有其他用户处于锁定状态,不能添加新的锁定用户。";
|
||
result.Result = false;
|
||
return result;
|
||
}
|
||
}
|
||
|
||
// 存客户端信息
|
||
_cache.HashSetAsync(clientKey, new HashEntry[]
|
||
{
|
||
new("ClientId", info.ClientId),
|
||
new("UserId", info.UserId),
|
||
new("UserName", info.UserName),
|
||
new("ConnectTime", info.ConnectTime.ToString("O")),
|
||
new("IsLock", info.IsLock ? "true" : "false")
|
||
});
|
||
|
||
if (info.IsLock)
|
||
{
|
||
await _cache.SetAddAsync(lockSetKey, info.UserId);
|
||
}
|
||
else
|
||
{
|
||
await _cache.SetRemoveAsync(lockSetKey, info.UserId);
|
||
}
|
||
|
||
result.Result = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前用户mqtt客户端信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<MqttClientResp>> GetRedisUser(string id)
|
||
{
|
||
var result = new Response<MqttClientResp>();
|
||
try
|
||
{
|
||
result.Result = ParseClient(await _cache.HashGetAllAsync($"client:{id}"));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
/// <summary>
|
||
/// 获取当前用户mqtt客户端信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<MqttClientResp>> GetRedisUser11(string id)
|
||
{
|
||
var result = new Response<MqttClientResp>();
|
||
try
|
||
{
|
||
var keys = await _cache.ScanKeysAsync("client:*");
|
||
foreach (var key in keys)
|
||
{
|
||
// 2. 获取 hash 全部字段
|
||
var hashEntries = await _cache.HashGetAllAsync(key);
|
||
|
||
if (hashEntries == null || hashEntries.Length == 0)
|
||
continue;
|
||
|
||
// 3. 取 UserId 字段
|
||
var userIdEntry = hashEntries.FirstOrDefault(x => x.Name == "UserId");
|
||
|
||
if (userIdEntry.Value == RedisValue.Null)
|
||
continue;
|
||
|
||
// 4. 判断是否等于目标 UserId
|
||
if (userIdEntry.Value.ToString() == id)
|
||
{
|
||
// 将 HashEntry[] 转成字典
|
||
var dict = hashEntries.ToDictionary(
|
||
x => x.Name.ToString(),
|
||
x => x.Value.ToString()
|
||
);
|
||
dict.TryGetValue("ClientId", out var clientId);
|
||
dict.TryGetValue("UserId", out var userId);
|
||
dict.TryGetValue("UserName", out var userName);
|
||
dict.TryGetValue("ConnectTime", out var connectTimeStr);
|
||
dict.TryGetValue("DeviceSn", out var deviceSn);
|
||
dict.TryGetValue("IsLock", out var isLockStr);
|
||
MqttClientResp mqttClientResp = new MqttClientResp
|
||
{
|
||
ClientId = clientId ?? "",
|
||
UserId = userId ?? "",
|
||
UserName = userName ?? "",
|
||
DeviceSn = deviceSn ?? "",
|
||
ConnectTime = DateTime.TryParse(connectTimeStr, out var ct) ? ct : DateTime.MinValue,
|
||
IsLock = bool.TryParse(isLockStr, out var lk) && lk
|
||
};
|
||
|
||
//mqttClientResp.ClientId = dict["ClientId"];
|
||
//mqttClientResp.UserId = dict["UserId"];
|
||
//mqttClientResp.UserName = dict["UserName"];
|
||
//mqttClientResp.ConnectTime = DateTime.Parse(dict["ConnectTime"]);
|
||
//mqttClientResp.DeviceSn = dict["DeviceSn"];
|
||
//mqttClientResp.IsLock = bool.Parse(dict["IsLock"]);
|
||
result.Result = mqttClientResp;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private MqttClientResp ParseClient(HashEntry[] entries)
|
||
{
|
||
if (entries == null || entries.Length == 0)
|
||
return null;
|
||
var dict = entries.ToDictionary(e => e.Name.ToString(), e => e.Value.ToString());
|
||
dict.TryGetValue("ClientId", out var clientId);
|
||
dict.TryGetValue("UserId", out var userId);
|
||
dict.TryGetValue("UserName", out var userName);
|
||
dict.TryGetValue("ConnectTime", out var connectTimeStr);
|
||
dict.TryGetValue("DeviceSn", out var deviceSn);
|
||
dict.TryGetValue("IsLock", out var isLockStr);
|
||
return new MqttClientResp
|
||
{
|
||
//ClientId = dict["ClientId"],
|
||
//UserId = dict["UserId"],
|
||
//UserName = dict["UserName"],
|
||
//ConnectTime = DateTime.Parse(dict["ConnectTime"]),
|
||
//DeviceSn = dict["DeviceSn"],
|
||
//IsLock = bool.Parse(dict["IsLock"])
|
||
ClientId = clientId ?? "",
|
||
UserId = userId ?? "",
|
||
UserName = userName ?? "",
|
||
DeviceSn = deviceSn ?? "",
|
||
ConnectTime = DateTime.TryParse(connectTimeStr, out var ct) ? ct : DateTime.MinValue,
|
||
IsLock = bool.TryParse(isLockStr, out var lk) && lk
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有锁定的用户客户端信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
public async Task<List<MqttClientResp>> GetLockedClients()
|
||
{
|
||
var userIds = await _cache.SetMembersAsync("locked_users");
|
||
|
||
var result = new List<MqttClientResp>();
|
||
|
||
foreach (var userId in userIds)
|
||
{
|
||
var entries = await _cache.HashGetAllAsync($"client:{userId}");
|
||
if (entries.Length > 0)
|
||
result.Add(ParseClient(entries));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 添加修改mqtt客户端信息 设备为主
|
||
/// </summary>
|
||
/// <param name="info"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[AllowAnonymous]
|
||
public async Task<Response<bool>> AddOrUpdateRedisDevice(MqttClientResp info)
|
||
{
|
||
var result = new Response<bool>();
|
||
try
|
||
{
|
||
var clientKey = $"client:{info.DeviceSn}";
|
||
string lockSetKey = "locked_devices";
|
||
|
||
// 查询所有锁定用户
|
||
//var existingLocked = await _cache.SetMembersAsync(lockSetKey);
|
||
|
||
//// 如果设备锁定,并且锁定的用户不是当前用户,则拒绝
|
||
//if (existingLocked.Length > 0 && info.IsLock == true)
|
||
//{
|
||
// bool isCurrentUserLocked = existingLocked.Any(u => u == info.DeviceSn);
|
||
// if (isCurrentUserLocked)
|
||
// {
|
||
// result.Code = 400;
|
||
// result.Message = "已有用户处于锁定状态,不能添加新的锁定用户。";
|
||
// result.Result = false;
|
||
// return result;
|
||
// }
|
||
//}
|
||
var hashEntries = await _cache.HashGetAllAsync($"client:{info.DeviceSn}");
|
||
if (hashEntries.Length > 0)
|
||
{
|
||
var existingLocked = ParseClient(hashEntries);
|
||
if (existingLocked.DeviceSn == info.DeviceSn && existingLocked.UserId != info.UserId && existingLocked.IsLock)
|
||
{
|
||
result.Code = 400;
|
||
result.Message = "已有用户处于锁定状态,不能添加新的锁定用户。";
|
||
result.Result = false;
|
||
return result;
|
||
}
|
||
}
|
||
|
||
// 存客户端信息
|
||
_cache.HashSetAsync(clientKey, new HashEntry[]
|
||
{
|
||
new("ClientId", info.ClientId),
|
||
new("UserId", info.UserId),
|
||
new("UserName", info.UserName),
|
||
new("DeviceSn", info.DeviceSn),
|
||
new("ConnectTime", info.ConnectTime.ToString("O")),
|
||
new("IsLock", info.IsLock ? "true" : "false")
|
||
});
|
||
|
||
if (info.IsLock)
|
||
{
|
||
await _cache.SetAddAsync(lockSetKey, info.DeviceSn);
|
||
}
|
||
else
|
||
{
|
||
await _cache.SetRemoveAsync(lockSetKey, info.DeviceSn);
|
||
}
|
||
|
||
result.Result = true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
/// <summary>
|
||
/// 获取当前用户mqtt客户端信息
|
||
/// </summary>
|
||
/// <param name="id">设备sn</param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<MqttClientResp>> GetRedisDevice(string id)
|
||
{
|
||
var result = new Response<MqttClientResp>();
|
||
try
|
||
{
|
||
result.Result = ParseClient(await _cache.HashGetAllAsync($"client:{id}"));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
/// <summary>
|
||
/// 获取所有锁定的用户客户端信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<List<MqttClientResp>>> GetLockedDeviceClients()
|
||
{
|
||
var deviceSns = await _cache.SetMembersAsync("locked_devices");
|
||
|
||
var result = new List<MqttClientResp>();
|
||
|
||
foreach (var deviceSn in deviceSns)
|
||
{
|
||
var entries = await _cache.HashGetAllAsync($"client:{deviceSn}");
|
||
if (entries.Length > 0)
|
||
result.Add(ParseClient(entries));
|
||
}
|
||
return new Response<List<MqttClientResp>>
|
||
{
|
||
Result = result
|
||
};
|
||
}
|
||
/// <summary>
|
||
/// 天气阻飞
|
||
/// </summary>
|
||
/// <param name="address">机场所在的地址,比如兰山</param>
|
||
/// <param name="sn">机场sn</param>
|
||
/// <param name="dock">机场类型,Dock 1,Dock 2,Dock 3</param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<dynamic>> IsCanFly(string userid, string address, string sn, string dock)
|
||
{
|
||
var result = new Response<dynamic>();
|
||
try
|
||
{
|
||
result = await _app.IsCanFly(userid, sn, dock, address);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
return result;
|
||
}
|
||
#endregion
|
||
|
||
#region 获取告警信息
|
||
|
||
/// <summary>
|
||
/// 获取告警信息
|
||
/// </summary>
|
||
/// <param name="level">告警等级,0-全部,1-注意,2-告警</param>
|
||
/// <param name="model">设备,0-全部,1-设备管理,2-媒体管理,3-HMS告警</param>
|
||
/// <param name="startTime"></param>
|
||
/// <param name="endTime"></param>
|
||
/// <param name="page"></param>
|
||
/// <param name="limit"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
public async Task<Response<PageInfo<List<LasaManageDeviceHms>>>> GetManageDeviceHmsList(int level, int model,
|
||
DateTime startTime, DateTime endTime, int page, int limit, string message, string getway)
|
||
{
|
||
var result = new Response<PageInfo<List<LasaManageDeviceHms>>>();
|
||
try
|
||
{
|
||
result = await _app.GetManageDeviceHmsList(level, model, startTime, endTime, page, limit, message,
|
||
getway);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 日志信息
|
||
|
||
/// <summary>
|
||
/// 根据设备sn读取实时数据
|
||
/// </summary>
|
||
/// <param name="sn">设备sn</param>
|
||
/// <param name="startTime"></param>
|
||
/// <param name="endTime"></param>
|
||
/// <param name="page"></param>
|
||
/// <param name="limit"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
public async Task<Response<PageInfo<List<LasaLog>>>> GetLogList(string sn, DateTime startTime, DateTime endTime,
|
||
int page, int limit)
|
||
{
|
||
var result = new Response<PageInfo<List<LasaLog>>>();
|
||
try
|
||
{
|
||
result = await _app.GetLogList(sn, startTime, endTime, page, limit);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
/// <summary>
|
||
/// 根据任务获取无人机操作日志
|
||
/// </summary>
|
||
/// <param name="taskid">任务id</param>
|
||
/// <param name="page"></param>
|
||
/// <param name="limit"></param>
|
||
/// <returns></returns>
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<PageInfo<List<LasaControlOperation>>>> GetOperationLogList(string taskid, int page, int limit)
|
||
{
|
||
var result = new Response<PageInfo<List<LasaControlOperation>>>();
|
||
try
|
||
{
|
||
result = await _app.GetOperationLogList(taskid, page, limit);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
#endregion
|
||
|
||
|
||
[HttpGet]
|
||
public async Task<Response<PageInfo<List<LasaMediaFile>>>> GetMediaFile(string flightId, string taskId, string airId,
|
||
string device, int? type, string picname, DateTime startTime, DateTime endTime, int page, int limit,
|
||
string parentKey, int? objectKeyExist)
|
||
{
|
||
var result = new Response<PageInfo<List<LasaMediaFile>>>();
|
||
try
|
||
{
|
||
result = await _app.GetMediaFile(flightId, taskId, airId, device, type, picname, startTime, endTime, page, limit,
|
||
parentKey, objectKeyExist);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<string>> UpdatePicStatus(string id, int showOnMap, int display, string fileTags,
|
||
string graffitiJson)
|
||
{
|
||
var result = new Response<string>();
|
||
try
|
||
{
|
||
result = await _app.UpdatePicStatus(id, showOnMap, display, fileTags, graffitiJson);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<string>> deletepic(string ids)
|
||
{
|
||
var result = new Response<string>();
|
||
try
|
||
{
|
||
result = await _app.deletepic(ids);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<string>> UpdatePicName(string id, string name)
|
||
{
|
||
var result = new Response<string>();
|
||
try
|
||
{
|
||
result = await _app.UpdatePicName(id, name);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<string>> UpdatePicParentKey(string id, string ParentKey)
|
||
{
|
||
var result = new Response<string>();
|
||
try
|
||
{
|
||
result = await _app.UpdatePicParentKey(id, ParentKey);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public async Task<Response<string>> getMiniPic()
|
||
{
|
||
var result = new Response<string>();
|
||
try
|
||
{
|
||
// string presignedUrl = "http://175.27.168.120:6014/test/44fc8b4b-9448-4e79-a71d-536d094b8598/ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_202507231000_002_ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_20250723100110_0001_V.jpeg";
|
||
var imageStream = _minioService.GetObjectAsStream("test",
|
||
"44fc8b4b-9448-4e79-a71d-536d094b8598/ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_202507231000_002_ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_20250723100110_0001_V.jpeg");
|
||
// var imageStream = await _httpClient.GetStreamAsync(presignedUrl);
|
||
|
||
using (var image = Image.Load(imageStream.Result))
|
||
{
|
||
var width = image.Width;
|
||
var height = image.Height;
|
||
var thumbnailSize = 100; // 缩略图大小,可以根据需要调整
|
||
var thumbnail = image.Clone(ctx => ctx.Resize(new ResizeOptions
|
||
{
|
||
Size = new Size(thumbnailSize, thumbnailSize),
|
||
Mode = ResizeMode.Crop // 根据需要选择裁剪或填充模式
|
||
}));
|
||
|
||
// 将缩略图保存到内存流中(为了上传)
|
||
using (var memoryStream = new MemoryStream())
|
||
{
|
||
thumbnail.SaveAsJpeg(memoryStream); // 可以根据需要选择不同的格式,如Png, Bmp等。
|
||
memoryStream.Position = 0; // 重置流的位置到开始处
|
||
|
||
// 上传缩略图到MinIO
|
||
await _minioService.PutObjectAsync("test", "suolue_DJI_20250723100110_0001_V.jpeg",
|
||
"abc/suolue_DJI_20250723100110_0001_V.jpeg", memoryStream); // 根据实际格式修改Content-Type
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
result.Code = 500;
|
||
result.Message = ex.Message;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
}
|
||
} |