using DocumentFormat.OpenXml.EMMA; using DocumentFormat.OpenXml.Math; using DocumentFormat.OpenXml.Spreadsheet; using Infrastructure; using Infrastructure.Cache; using Infrastructure.CloudSdk.minio; using Infrastructure.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPOI.SS.Formula.Functions; using OpenAuth.App.BaseApp.Base; using OpenAuth.App.Interface; using OpenAuth.App.ServiceApp.Response; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using SqlSugar; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; namespace OpenAuth.App.ServiceApp { public class AirportMaintenanceApp : SqlSugarBaseApp { private readonly IConfiguration _configuration; private readonly ISqlSugarClient _client; private readonly MinioService _minioService; private readonly RedisCacheContext _redisCacheContext; public AirportMaintenanceApp(MinioService minioService, ISqlSugarClient client, RedisCacheContext redisCacheContext, ISugarUnitOfWork unitWork, IConfiguration configuration, ISimpleClient repository, IAuth auth) : base(unitWork, repository, auth) { _configuration = configuration; _client = client; _minioService = minioService; _redisCacheContext = redisCacheContext; } //获取设备绑定码 public async Task> GetDeviceBindingCode() { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var info = await db.LasaDeviceBindingCode.AsQueryable().Where(r => r.BindStatus == 0).FirstAsync(); if (info != null) { return new Response { Code = 200, Message = "获取设备绑定码成功", Result = info }; } else { //如果设备绑定码不存在,则创建一个新的设备绑定码 var newBindingCode = new LasaDeviceBindingCode { Id = Guid.NewGuid().ToString(), DeviceBindingCode = Guid.NewGuid().ToString("N").Substring(0, 8), // 生成一个新的绑定码 OrgId = "371300", // 默认组织ID OrgName = "sdhc", // 默认组织名称 BindStatus = 0 // 未绑定状态 }; await db.LasaDeviceBindingCode.InsertAsync(newBindingCode); if (db.Commit()) { return new Response { Code = 200, Message = "获取设备绑定码成功", Result = newBindingCode }; } else { return new Response { Code = 500, Message = "获取设备绑定码失败", }; } } } } /// /// 修改注册码状态 /// /// /// public async Task UpdateCodeStatus(string DeviceBindingCode) { using (var db = UnitWork.CreateContext()) { var flag = await db.LasaDeviceBindingCode.UpdateAsync(it => new LasaDeviceBindingCode() { BindStatus = 1, }, it => it.DeviceBindingCode == DeviceBindingCode); if (db.Commit()) return true; else return false; } } //使用网关 public async Task> GetGateway() { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var info = await db.LasaGateway.AsQueryable().Where(r => r.BindStatus == 0).FirstAsync(); if (info != null) { return new Response { Code = 200, Message = "获取设备绑定码成功", Result = info }; } else { var serverIp = _configuration.GetSection("MQTT:Server").Value; var port = _configuration.GetSection("MQTT:Port").Value; var username = _configuration.GetSection("MQTT:UserName").Value; var password = _configuration.GetSection("MQTT:Password").Value; //如果网关不存在,则创建一个新的 var newGateway = new LasaGateway { Id = Guid.NewGuid().ToString(), CreateTime = DateTime.Now, GatewayAccount = username, GatewaySn = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(), // 生成一个新的 MqttGateway = serverIp + ":" + port, MqttPassword = password, OrgId = "371300", // 默认组织ID BindStatus = 0 // 未绑定状态 }; await db.LasaGateway.InsertAsync(newGateway); if (db.Commit()) { return new Response { Code = 200, Message = "获取设备绑定码成功", Result = newGateway }; } else { return new Response { Code = 500, Message = "获取设备绑定码失败", }; } } } } public async Task UpdateGateway(string gateway, string did) { using (var db = UnitWork.CreateContext()) { var flag = await db.LasaGateway.UpdateAsync(it => new LasaGateway() { BindStatus = 1, Did = did, UpdateTime = DateTime.Now, }, it => it.GatewaySn == gateway); if (db.Commit()) return true; else return false; } } /// /// 分页获取所有数据 /// /// /// /// public async Task>>> GetPageList(int page, int limit) { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var list = await db.LasaGateway.AsQueryable() .ToPageListAsync(page, limit, totalCount); return new Response>> { Result = new PageInfo> { Items = list, Total = totalCount } }; } } //获取网关 public async Task> GetGatewaysnList() { using (var db = UnitWork.CreateContext()) { var info = await db.LasaGateway.AsQueryable().Select(r => r.GatewaySn).ToListAsync(); if (info != null) { return info; } else { return new List(); } } } public async Task> GetUavSn() { using (var db = UnitWork.CreateContext()) { var uavinfo = await db.LasaUav.AsQueryable().Where(r => r.IsDelete == false).Select(r => r.Sn) .ToListAsync(); var dockinfo = await db.LasaDronePort.AsQueryable().Where(r => r.IsDelete == false).Select(r => r.Sn) .ToListAsync(); if (dockinfo != null) { return dockinfo.Union(uavinfo).ToList(); } else { return new List(); } } } #region 固件版本管理 public async Task> AddFirmware(LasaFirmware info) { using (var db = UnitWork.CreateContext()) { info.Id = Guid.NewGuid().ToString(); var flag = await db.LasaFirmware.InsertAsync(info); if (db.Commit()) return new Response { Result = true, Message = "添加成功" }; else return new Response { Result = false, Message = "添加失败" }; } } //修改无人机或机场版本 public async Task> UpdateFirmware(string id, string version, int type) { using (var db = UnitWork.CreateContext()) { if (type == 1) { var flag = await db.LasaDronePort.UpdateAsync(it => new LasaDronePort() { FirmwareVersion = version, }, it => it.Id == id); if (db.Commit()) return new Response { Result = true, Message = "编辑成功" }; else return new Response { Result = false, Message = "编辑失败" }; } else { var flag = await db.LasaUav.UpdateAsync(it => new LasaUav() { FirmwareVersion = version, }, it => it.Id == id); if (db.Commit()) return new Response { Result = true, Message = "编辑成功" }; else return new Response { Result = false, Message = "编辑失败" }; } } } public Task UploadFile(IFormFile xmlFile) { return _minioService.UploadFile(xmlFile, "firmware"); } #endregion #region 健康报警 /// /// 添加健康报警 /// /// /// public bool AddManageDeviceHms(List newAlarms) { using (var db = UnitWork.CreateContext()) { var now = DateTime.Now; //获取当前所有未处理的告警信息 var existing = db.LasaManageDeviceHms.AsQueryable() .Where(x => x.IsResolved == 0).ToList(); var currentKeys = newAlarms.Select(x => x.Code).ToHashSet(); var existingKeys = existing.Select(x => x.Code).ToHashSet(); // 需要解除的(老有,新没有) 起的隆冬强 var toResolve = existing .Where(x => !currentKeys.Contains(x.Code)).ToList(); foreach (var resolved in toResolve) { resolved.IsResolved = 1; resolved.UpdateTime = now; } db.LasaManageDeviceHms.UpdateRange(toResolve); // 需要新增的(新有,老没有) var toInsert = newAlarms .Where(x => !existingKeys.Contains(x.Code)) .ToList(); if (toInsert.Count > 0) db.LasaManageDeviceHms.InsertRange(toInsert); //var flag = db.LasaManageDeviceHms.InsertRange(newAlarms); if (db.Commit()) return true; else return false; } } //根据时间获取告警信息列表 public async Task>>> GetManageDeviceHmsList(int level, int model, DateTime startTime, DateTime endTime, int page, int limit, string message, string getway) { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var list = await db.LasaManageDeviceHms.AsQueryable() .Where(x => x.CreateTime >= startTime && x.CreateTime <= endTime) .WhereIF(level != 0, x => x.Level == level) .WhereIF(model != 0, x => x.Module == model) .WhereIF(!string.IsNullOrEmpty(message), x => x.MessageZh.Contains(message)) .WhereIF(!string.IsNullOrEmpty(getway), x => x.Sn == getway) .OrderBy(x => x.CreateTime, OrderByType.Desc) .ToPageListAsync(page, limit, totalCount); return new Response>> { Result = new PageInfo> { Items = list, Total = totalCount } }; } } #endregion #region 日志 /// /// 添加日志 /// /// /// public async Task AddLog(LasaLog info) { using (var db = UnitWork.CreateContext()) { var flag = await db.LasaLog.InsertAsync(info); if (db.Commit()) return true; else return false; } } /// /// 获取日志 /// /// /// /// /// /// /// public async Task>>> GetLogList(string sn, DateTime startTime, DateTime endTime, int page, int limit) { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var topic = $"thing/product/{sn}/osd"; var list = await db.LasaLog.AsQueryable() .Where(x => x.CreateTime >= startTime && x.CreateTime <= endTime) .Where(x => x.Topic == topic) .OrderBy(x => x.CreateTime, OrderByType.Asc) .ToPageListAsync(page, limit, totalCount); return new Response>> { Result = new PageInfo> { Items = list, Total = totalCount } }; } } /// /// 添加无人机操作日志 /// /// /// public async Task AddOperationLog(LasaControlOperation info) { using (var db = UnitWork.CreateContext()) { var flag = await db.LasaControlOperation.InsertAsync(info); if (db.Commit()) return true; else return false; } } /// /// 获取无人机操作日志 /// /// /// /// /// public async Task>>> GetOperationLogList(string taskid, int page, int limit) { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { var list = await db.LasaControlOperation.AsQueryable() .Where(x => x.TaskId == taskid) .OrderBy(x => x.CreateTime, OrderByType.Asc) .ToPageListAsync(page, limit, totalCount); return new Response>> { Result = new PageInfo> { Items = list, Total = totalCount } }; } } #endregion public async Task>>> 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) { RefAsync totalCount = 0; using (var db = UnitWork.CreateContext()) { Console.WriteLine(startTime.ToString()); var list = await db.LasaMediaFile.AsQueryable() .LeftJoin((x, b) => x.FlightId == b.FlightId) .WhereIF(!string.IsNullOrEmpty(flightId), (x, b) => x.FlightId == flightId) .WhereIF(!string.IsNullOrEmpty(device), (x, b) => x.DroneModelKey == device) .WhereIF(!string.IsNullOrEmpty(picname), (x, b) => x.Name.Contains(picname)) .WhereIF(!string.IsNullOrEmpty(airId), (x, b) => b.AirLineId == airId) .WhereIF(objectKeyExist is 0, (x, b) => x.ObjectKey == null) .WhereIF(objectKeyExist is 1, (x, b) => x.ObjectKey != null) .WhereIF(!"0001/1/1 0:00:00".Equal(startTime.ToString()), (x, b) => x.CreateTime >= startTime) .WhereIF(!"0001/1/1 0:00:00".Equal(endTime.ToString()), (x, b) => x.CreateTime <= endTime) .WhereIF(!string.IsNullOrEmpty(parentKey), (x, b) => x.ParentKey == parentKey) .WhereIF(!string.IsNullOrEmpty(taskId), (x, b) => x.TaskId == taskId) .WhereIF(type != null, (x, b) => x.Type == type) .OrderBy((x, b) => x.CreateTime, OrderByType.Desc) .Select((x, b) => new LasaMediaFile { Id = x.Id, Name = x.Name, ObjectKey = x.ObjectKey, Path = x.Path, CreateTime = x.CreateTime, TaskId = x.TaskId, Level = x.Level, ParentKey = x.ParentKey, WorkspaceId = x.WorkspaceId, display = x.display, ShowOnMap = x.ShowOnMap, GraffitiJson = x.GraffitiJson, FileTags = x.FileTags, Size = x.Size, Width = x.Width, Height = x.Height, Lat = x.Lat, Lng = x.Lng, AbsoluteAltitude = x.AbsoluteAltitude, Tid = x.Tid, Bid = x.Bid, FlightType = x.FlightType, minipic = x.minipic, CreateUserName = b.CreateUserName, TaskName = b.TaskName, AirLineName = b.TaskAirLineName, GimbalYawDegree = x.GimbalYawDegree, RelativeAltitude = x.RelativeAltitude, PayloadModelName = x.PayloadModelName, Type = x.Type }) .ToPageListAsync(page, limit, totalCount); return new Response>> { Result = new PageInfo> { Items = list, Total = totalCount } }; } } public async Task> UpdatePicStatus(string id, int showOnMap, int display, string fileTags, string graffitiJson) { string sql = "update lasa_mediafile set \"ShowOnMap\"=" + showOnMap + ",display=" + display + ",\"FileTags\"='" + fileTags + "',\"GraffitiJson\"='" + graffitiJson + "' where \"Id\"='" + id + "'"; await _client.Ado.ExecuteCommandAsync(sql); return new Response { Result = "修改成功!" }; } public async Task> deletepic(string ids) { string[] idarray = ids.Split(","); for (int i = 0; i < idarray.Length; i++) { string sqlselect = "select \"ObjectKey\" from lasa_mediafile where \"Id\"='" + idarray[i] + "'"; string objectkey = _client.Ado.SqlQuerySingle(sqlselect); string sql = "delete from lasa_mediafile where \"Id\"='" + idarray[i] + "'"; await _client.Ado.ExecuteCommandAsync(sql); await _minioService.DeleteFile(objectkey); } return new Response { Result = "删除成功!" }; } public async Task> UpdatePicName(string id, string name) { string sql = "update lasa_mediafile set \"Name\"='" + name + "' where \"Id\"='" + id + "'"; await _client.Ado.ExecuteCommandAsync(sql); return new Response { Result = "修改成功!" }; } public async Task> UpdatePicParentKey(string id, string ParentKey) { string sql = "update lasa_mediafile set \"ParentKey\"='" + ParentKey + "' where \"Id\"='" + id + "'"; await _client.Ado.ExecuteCommandAsync(sql); return new Response { Result = "修改成功!" }; } #region 天气阻飞 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 = 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 }; } //天气预报和是否有人在操作 public async Task> IsCanFly(string sn, string dock, string address = "兰山") { var rainThreshforecast = 3; // 天气预报雨量 var windSpeedThresh = 12;// 机场设定雨量 double weatherWindSpeedforecast = 0; // 天气预报风速 double weatherWindSpeedThre = 12;// 机场设定风速 bool islock = false;//是否有人在操作 var existingLocked = await _redisCacheContext.SetMembersAsync("locked_devices"); islock = existingLocked.Any(u => u == sn); //查找被谁锁定 var entries = ParseClient(await _redisCacheContext.HashGetAllAsync($"client:{sn}")); if (islock) return new Response { Result = new { status = false, msg = "设备已被" + entries?.UserName + "锁定" } }; switch (dock) { case "Dock 1": weatherWindSpeedThre = 12; break; case "Dock 2": weatherWindSpeedThre = 8; break; case "Dock 3": weatherWindSpeedThre = 8; break; } using (var httpClient = new HttpClient()) { var response = await httpClient.GetAsync($"http://v1.yiketianqi.com/api?unescape=1&version=v61&appid=84261622&appsecret=k0WPY4Cx&city={address}"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); var weather = Newtonsoft.Json.JsonConvert.DeserializeObject(content); var winMeterStr = weather.GetValue("win_meter")?.Value(); //风速 if (!string.IsNullOrEmpty(winMeterStr)) { weatherWindSpeedforecast = int.Parse(winMeterStr.Replace("km/h", "")) / 3.6; } } } //解析osd的雨量和风速数据 var info = _redisCacheContext.Get(sn + "_osd"); if (!string.IsNullOrEmpty(info)) { var dataObject = JsonConvert.DeserializeObject(info); var windSpeed = dataObject["data"]?["wind_speed"]?.Value(); // m/s var rainfall = dataObject["data"]?["rainfall"]?.Value(); var drone_in_dock = dataObject["data"]?["drone_in_dock"]?.Value(); if (drone_in_dock == "0") return new Response { Result = new { status = false, msg = "执行任务中,请勿重复起飞" } }; if (windSpeedThresh <= windSpeed || rainThreshforecast <= rainfall || weatherWindSpeedThre <= weatherWindSpeedforecast) { return new Response { Result = new { status = false, msg = "当前天气条件不允许起飞" } }; } else { return new Response { Result = new { status = true, msg = "当前天气条件允许起飞" } }; } } return new Response { Result = new { status = true, msg = "当前天气条件允许起飞" } }; } #endregion } }