zhangbin 2025-09-05 16:38:46 +08:00
commit 753a5063d2
14 changed files with 559 additions and 291 deletions

View File

@ -1,5 +1,11 @@
using NPOI.POIFS.Crypt.Dsig;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Buffers.Text;
using System.Collections.Generic;
@ -10,6 +16,8 @@ using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Unicode;
using System.Threading.Tasks;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Asn1;
namespace Infrastructure.Helpers
{
@ -155,5 +163,59 @@ namespace Infrastructure.Helpers
}
return bytes;
}
#region 图片上传校验码生成
public string GetJYM(string str)
{
string sm3str = ComputeSm3Hash(str);
//return GenerateSm2Signature(sm3str);
byte[] needSignDataByte = Encoding.UTF8.GetBytes(sm3str);
// 4. SM2签名
byte[] signData;
byte[] privatekeybyte = HexToBytes(privateKey);
try
{
signData = SM2CryptoHelper.Sign(privatekeybyte, needSignDataByte);
// 将签名结果转换为十六进制大写字符串
string hexSignature = BytesToHexUpper(signData);
return hexSignature;
}
catch (Exception ex)
{
throw new InvalidOperationException("SM2签名失败", ex);
}
}
// 将字节数组转换为十六进制大写字符串
private static string BytesToHexUpper(byte[] bytes)
{
StringBuilder hex = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
hex.AppendFormat("{0:X2}", b);
}
return hex.ToString();
}
/// <summary>
/// 计算SM3哈希值
/// </summary>
private string ComputeSm3Hash(string input)
{
byte[] msg = Encoding.UTF8.GetBytes(input);
SM3Digest digest = new SM3Digest();
digest.BlockUpdate(msg, 0, msg.Length);
byte[] result = new byte[digest.GetDigestSize()];
digest.DoFinal(result, 0);
return Hex.ToHexString(result).ToUpper();
}
#endregion
}
}

View File

@ -17,6 +17,7 @@
<PackageReference Include="ExifLib" Version="1.7.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Minio" Version="6.0.4" />
@ -34,7 +35,6 @@
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.6.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.111" />
<PackageReference Include="System.Data.SQLite" Version="1.0.119" />
</ItemGroup>
<ItemGroup>

View File

@ -21,6 +21,7 @@ public class AiAchievementServiceApp : SqlSugarBaseApp<LasaAiAchievement, SugarD
var page = await Repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(req.key), x => x.Title.Contains(req.key))
.WhereIF(req.startTime != null, x => x.CreateTime >= req.startTime && x.CreateTime <= req.endTime)
.OrderByDescending(x => x.CreateTime)
.ToPageListAsync(req.page, req.limit, total);
return new Response<PageInfo<List<LasaAiAchievement>>>()
{

View File

@ -18,7 +18,9 @@ using DocumentFormat.OpenXml.Drawing.Charts;
using Org.BouncyCastle.Ocsp;
using System.Net.Http.Headers;
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using System.Data.SQLite;
using SQLitePCL;
using Microsoft.Data.Sqlite;
using System.Dynamic;
using Infrastructure.CloudSdk.minio;
using Infrastructure.Extensions;
@ -29,6 +31,10 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAuth.WebApi;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Microsoft.Data.Sqlite;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities.Encoders;
using System.Globalization;
namespace OpenAuth.App.ServiceApp.DroneDocking
@ -654,27 +660,9 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<ResData> GetDroneStatus(string deviceid)
public async Task<dynamic> GetDroneStatus(string deviceid)
{
/*string data = @"
{
""code"": 200,
""data"": {
""mode_code"": 0,
""longitude"": 122.45,
""latitude"": 30.45,
""height"": 80,
""elevation"": 50,
""gimbal_pitch"": -45,
""gimbal_yaw"": 23,
""battery_capacity_percent"": 35,
""gps_state"": 2
},
""message"": """",
""traceid"": ""xxx""
}
";*/
dynamic data = new ExpandoObject();
dynamic result = new ExpandoObject();
var dock = await Repository
.ChangeRepository<SugarRepositiry<LasaDronePort>>()
.AsQueryable()
@ -682,14 +670,15 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
.Where((a, b) => b.Sn == deviceid).FirstAsync();
if (dock == null) // 无人机不在线
{
data.code = 200;
result.code = 200;
dynamic inData = new ExpandoObject();
result.data = inData;
inData.mode_code = 1; // 不在线
data.message = "获取无人机状态成功";
result.message = "获取无人机状态成功";
}
else
{
data.code = 200;
result.code = 200;
var dockOsdTopic = $"thing/product/{dock.Sn}/osd";
var now = DateTime.Now;
var time = now.AddSeconds(-5);
@ -754,14 +743,14 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
< 10 => 2, // 高精度
_ => 3 // rtk定位
};
data.data = inData;
data.message = "获取无人机状态成功!";
data.traceid = Guid.NewGuid().ToString();
result.data = inData;
result.message = "获取无人机状态成功!";
result.traceid = Guid.NewGuid().ToString();
}
else
{
data.code = 502;
data.message = "获取无人机状态失败";
result.code = 502;
result.message = "获取无人机状态失败";
}
}
else
@ -786,39 +775,15 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
< 10 => 2,
_ => 3
};
data.data = inData;
data.traceid = Guid.NewGuid().ToString();
data.code = 200;
data.message = "获取无人机状态成功";
result.data = inData;
result.traceid = Guid.NewGuid().ToString();
result.code = 200;
result.message = "获取无人机状态成功";
}
}
}
} // 设备在线
var response = new ResData();
if (data.code == 200)
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态成功!";
response.Code = 200;
response.Secret = xLcSecret;
return response;
}
else
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(" ");
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态失败!";
response.Code = 500;
response.Secret = xLcSecret;
return response;
}
return result;
}
/// <summary>
@ -852,69 +817,86 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
}
/// <summary>
/// 无人机机场设备注册/更新
/// 无人机状态上报
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public async Task<Response<string>> reportDroneStatus(List<AirPortStatusApply> req)
public async Task<Response<bool>> ReportDroneStatus()
{
Response<string> Response = new Response<string>();
var handler = new HttpClientHandler();
// 如果需要忽略服务器证书错误(仅测试环境)
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using (var client = new HttpClient())
var droneList = await Repository
.ChangeRepository<SugarRepositiry<LasaUav>>()
.AsQueryable()
.Where(it => it.IsDelete == false)
.ToListAsync();
var dataList = new List<dynamic>();
foreach (var item in droneList)
{
try
var originalData = await GetDroneStatus(item.Sn);
var inData = originalData.data;
// 转换状态值 mode_code -> onlinestate
// 0:在线1:不在线2:任务执行中 -> 设备在线状态00:不在线10:在线20任务执行中
// 增加设备id deviceid
inData.deviceid = item.Sn;
inData.onlinestate = inData.mode_code switch
{
string url = configuration.GetSection("DroneDocking:Url").Value + "/droneAirport/reportDroneStatus";
string x_lc_secret = _helper.getxseret();
string centercode = "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ";
string x_token = _helper.GetToken(centercode);
// 序列化为 JSON 字符串
string json = JsonSerializer.Serialize(req);
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(json);
var encryptedData = _helper.Encrypt(bytes);
// 创建请求体
var httpContent = new StringContent(encryptedData, Encoding.UTF8, "application/json");
// 添加请求头
client.DefaultRequestHeaders.Add("x-lc-secret", x_lc_secret);
client.DefaultRequestHeaders.Add("x-lc-token", x_token);
//发送请求
HttpResponseMessage response = await client.PostAsync(url, httpContent);
response.EnsureSuccessStatusCode();
// 获取响应头中的 x_cl_screte 参数
string resx_cl_screte = GetHeaderValue(response, "x-lc-secret");
// 读取响应内容并反序列化
string responseBody = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ReciveData<string>>(responseBody);
//解密数据
byte[] resbytesx = Convert.FromBase64String(resx_cl_screte);
byte[] resdatabytes = Convert.FromBase64String(result?.data);
string data = _helper.Decrypt(resbytesx, resdatabytes);
Response.Result = data;
Response.Message = result.message;
Response.Code = result.code;
}
catch (HttpRequestException e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ", e.Message);
Response.Result = "连接错误";
}
0 => "10",
1 => "00",
2 => "20",
_ => "00"
};
dataList.Add(inData);
}
return Response;
using var client = new HttpClient();
try
{
// 无人机状态上报接口
var url = configuration.GetSection("DroneDocking:Url").Value +
"/droneAirport/reportDroneStatus";
var xLcSecret = _helper.getxseret();
var centerCode = "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ";
var xToken = _helper.GetToken(centerCode);
// 序列化为 JSON 字符串
string json = JsonSerializer.Serialize(dataList);
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(json);
var encryptedData = _helper.Encrypt(bytes);
// 创建请求体
var httpContent = new StringContent(encryptedData, Encoding.UTF8, "application/json");
// 添加请求头
client.DefaultRequestHeaders.Add("x-lc-secret", xLcSecret);
client.DefaultRequestHeaders.Add("x-lc-token", xToken);
//发送请求
HttpResponseMessage response = await client.PostAsync(url, httpContent);
response.EnsureSuccessStatusCode();
// 获取响应头中的 x_cl_screte 参数
var resxClScrete = GetHeaderValue(response, "x-lc-secret");
// 读取响应内容并反序列化
var responseBody = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ReciveData<string>>(responseBody);
//解密数据
byte[] resbytesx = Convert.FromBase64String(resxClScrete);
byte[] resdatabytes = Convert.FromBase64String(result?.data);
string data = _helper.Decrypt(resbytesx, resdatabytes);
// 结果
}
catch (HttpRequestException e)
{
return new Response<bool>()
{
Result = false,
Message = e.Message
};
}
return new Response<bool>()
{
Result = true,
};
}
@ -996,31 +978,35 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
MultipartFormDataContent formData = null;
try
{
//文件过大,建议使用 大文件上传接口,分段读取,进行上传
fileBuffer = File.ReadAllBytes(filePath);
client = new HttpClient();
client.Timeout = new TimeSpan(0, 0, 0, 5);
formData = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(fileBuffer);
fileContent.Headers.ContentDisposition = new
ContentDispositionHeaderValue("attachment");
fileContent.Headers.ContentDisposition.FileName = fileName;
//注意:务必 根据 文件扩展名,这里指定 ContentType
fileContent.Headers.ContentType = new
MediaTypeHeaderValue("application/octet-stream");
formData.Add(fileContent);
var request = new HttpRequestMessage
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
//注意:这里是 PUT
Method = HttpMethod.Put,
RequestUri = new Uri(uploadUrl),
Content = formData
};
var result = client.SendAsync(request).Result.Content.ReadAsStringAsync().Result;
if (string.IsNullOrWhiteSpace(result))
{
Response.Result = result;
//文件过大,建议使用 大文件上传接口,分段读取,进行上传
//fileBuffer = File.ReadAllBytes(filePath);
client = new HttpClient();
//client.Timeout = new TimeSpan(0, 0, 0, 5);
client.Timeout = TimeSpan.FromMinutes(5);
formData = new MultipartFormDataContent();
var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
fileContent.Headers.ContentDisposition.FileName = fileName;
//注意:务必 根据 文件扩展名,这里指定 ContentType
fileContent.Headers.ContentType = new
MediaTypeHeaderValue("application/octet-stream");
formData.Add(fileContent);
var request = new HttpRequestMessage
{
//注意:这里是 PUT
Method = HttpMethod.Put,
RequestUri = new Uri(uploadUrl),
Content = formData
};
var result = client.SendAsync(request).Result.Content.ReadAsStringAsync().Result;
if (string.IsNullOrWhiteSpace(result))
{
Response.Result = result;
}
}
}
catch (Exception ex)
{
@ -1055,65 +1041,125 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
byte[] bytes = Encoding.UTF8.GetBytes(json);
var encryptedResData = _helper.Encrypt(bytes);
Response.Result = encryptedResData;
Response.Message = "获取无人机成果成功!";
Response.Message = "无人机成果获取成功!";
Response.Code = 200;
Response.Secret = x_lc_secret;
return Response;
}
}
public async void InsertDb(string taskid)
{
var sqliteconnect = configuration.GetSection("DroneDocking:DbFile").Value;
/*// 确保数据库文件存在
if (!File.Exists(sqliteconnect))
//获取任务数据
var task = _client.Queryable<DroneDocktask>().Where(r => r.id == taskid).First();
if (task == null)
{
var directory = Path.GetDirectoryName(sqliteconnect);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
SQLiteConnection.CreateFile(sqliteconnect);
}*/
string _sqliteConnection = "DataSource = " + sqliteconnect + "; Version = 3; ";
string sql = "select * from drone_docktaskdetail where taskid='" + taskid + "'";
var filigtlist = _client.Ado.SqlQuery<DroneDocktaskdetail>(sql);
using (var sqliteConn = new SQLiteConnection(_sqliteConnection))
throw new Exception("任务不存在");
}
//获取省下发任务id
string taskidsheng = task.taskid;
//拼接字符串
string filepath = configuration.GetSection("DroneDocking:DbFile").Value;
string filename = "";
if (string.IsNullOrEmpty(task.taskname))
{
filename = task.taskid.ToString() + ".db";
}
else
{
filename += task.taskname + ".db";
}
filepath = Path.Combine(filepath, filename);
//获取任务详情数据
var filigtlist = _client.Queryable<DroneDocktaskdetail>().Where(r => r.taskid == taskid).ToList();
//var sqliteconnect = configuration.GetSection("DroneDocking:DbFile").Value;
var connectionStringBuilder = new SqliteConnectionStringBuilder
{
DataSource = filepath,
Mode = SqliteOpenMode.ReadWriteCreate, // 根据情况调整 Mode
Password = "hopetry" // 在连接字符串中设置密码:cite[2]
};
string _sqliteConnection = connectionStringBuilder.ToString();
//FJ表数据总条数
int totalcount = 0;
//加密处理(为了通过验证)
using (var sqliteConn = new SqliteConnection(_sqliteConnection))
{
sqliteConn.Open();
string deleteDbinfo1 = "delete from JMXX";
using (var cmd2 = new SQLiteCommand(deleteDbinfo1, sqliteConn))
using (var command = sqliteConn.CreateCommand())
{
cmd2.ExecuteNonQuery();
//command.CommandText = $"pragma key = '123456';";
//command.ExecuteNonQuery();
command.CommandText = "PRAGMA cipher_compatibility = 3;";
command.ExecuteNonQuery();
// 可选:设置其他加密参数
command.CommandText = "PRAGMA cipher_page_size = 1024;";
command.ExecuteNonQuery();
command.CommandText = $"pragma cipher_memory_security = OFF;";
command.ExecuteNonQuery();
}
string sqlInsert =
"INSERT INTO JMXX (ZSDM, SZZS,ZSBFJGDM,ZSBFJGGY) VALUES (@ZSDM, @SZZS,@ZSBFJGDM,@ZSBFJGGY)";
using (var cmd1 = new SQLiteCommand(sqlInsert, sqliteConn))
//创建db_Info表
using (var command = sqliteConn.CreateCommand())
{
command.CommandText = $"CREATE TABLE \"DB_INFO\" (\r\n \"VERSION\" TEXT (10) NOT NULL,\r\n \"CREATETIME\" TEXT (20),\r\n \"UPDATETIME\" TEXT (20),\r\n \"CREATEUSER\" TEXT (50),\r\n \"DESCRIPTION\" TEXT (255),\r\n PRIMARY KEY (\"VERSION\")\r\n);";
command.ExecuteNonQuery();
}
//创建fj表
using (var command = sqliteConn.CreateCommand())
{
command.CommandText = $"CREATE TABLE \"FJ\" ( \"BSM\" TEXT NOT NULL, \"DKLX\" TEXT NOT NULL ,\"DKBSM\" TEXT NOT NULL ,\"ZDKBH\" TEXT, \"XZQDM\" TEXT NOT NULL ,\"FJMC\" TEXT , \"FJLX\" TEXT NOT NULL,\"PSTZ\" TEXT NOT NULL, \"FJ\" BLOB NOT NULL,\"FJHXZ\" TEXT NOT NULL, \"PSSJ\" TEXT NOT NULL,\"XDGD\" REAL NOT NULL, \"JDGD\" REAL,\"Longitude\" REAL NOT NULL, \"Latitude\" REAL NOT NULL,\"PSFYJ\" INTEGER NOT NULL, \"PSJD\" INTEGER NOT NULL,\"PSHGJ\" INTEGER NOT NULL, \"PSJJ\" INTEGER,\"FJYSKD\" INTEGER, \"FJYSGD\" INTEGER,\"PSRY\" TEXT NOT NULL, \"SPKZXX\" TEXT,\"ZSDM\" TEXT NOT NULL, \"PSDXZXX\" TEXT,\"JYM\" TEXT NOT NULL, PRIMARY KEY(\"BSM\") )";
command.ExecuteNonQuery();
//创建JMXX表
command.CommandText = $"CREATE TABLE \"JMXX\" (\r\n \"ZSDM\" TEXT (32) NOT NULL,\r\n \"SZZS\" TEXT (800) NOT NULL,\r\n \"ZSBFJGDM\" TEXT (18) NOT NULL,\r\n \"ZSBFJGGY\" TEXT (255),\r\n PRIMARY KEY (\"ZSDM\")\r\n);";
command.ExecuteNonQuery();
}
//jmxx表写入数据
using (var cmd2 = sqliteConn.CreateCommand())
{
cmd2.CommandText = "delete from JMXX";
cmd2.ExecuteNonQuery();
}
using (var cmd1 = sqliteConn.CreateCommand())
{
cmd1.CommandText = "INSERT INTO JMXX (ZSDM, SZZS,ZSBFJGDM,ZSBFJGGY) VALUES (@ZSDM, @SZZS,@ZSBFJGDM,@ZSBFJGGY)";
cmd1.Parameters.AddWithValue("@ZSDM", "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ");
cmd1.Parameters.AddWithValue("@SZZS",
"eyJvcmdjb2RlIjoiOTEzNzEzMDAzMjgzOTg1NzdRIiwib3JnbmFtZSI6IuWxseS4nOaFp+WIm+S/oeaBr+enkeaKgOaciemZkOWFrOWPuCIsImNlcnRjb2RlIjoiVUFWMzJfTEpZMkZQTVlERTZVREVTM1AzWkQ3VjNJS1EiLCJjZXJ0b3JnY29kZSI6IjEyMTAwMDAwNDAwMDEwMzk4UCIsImNlcnRvcmduYW1lIjoi5Lit5Zu95Zu95Zyf5YuY5rWL6KeE5YiS6Zmi5omn5rOV5qih5Z2XIiwiZXhwaXJhdGlvbiI6IjIwMjYtMDctMDEgMTU6NDY6MjAiLCJwdWJsaWNrZXkiOiIwNEYxQkYxQkVGRDYzRjE2RTVEQjNCQ0QzMkNBNUQ5QThFOERGN0FERDY3RDZDNEYyOTNGQjIzRjdCREE3NEY1MkQzMUI4RERBRDAzRDk1NUQ1NjY1MDVBMTVEOEI3REJFODNCNDIzNzhCOEU4NzQ5QzBFQjZFMkZCQzg2Nz" +
"U4MzhCIiwic2lnbiI6IjJBQTIyNDkwQzYxNkI0NjEzNUY2MDRBNDczNjFCQjJGRDcxMEJGOTdBQjcyNDdCMzYxQzc2N0NGQTNGNzcyMTQ0MkExQzhDMUVBRTIxRkEwQUZEMzJGRDg1NjdDMDg1MThGRUY4NTg2RUVCNkE4OTE1MDVBQjUxRjZDNDUyRUM2IiwiY2VydHR5cGUiOiLml6DkurrmnLrkuL7or4Hor4HkuaYiLCJyZWdpb25jb2RlIjoiMzcxMzAwIn0=");
cmd1.Parameters.AddWithValue("@ZSBFJGDM", "91371300328398577Q");
cmd1.Parameters.AddWithValue("@ZSBFJGDM", "12100000400010398P");
cmd1.Parameters.AddWithValue("@ZSBFJGGY",
"04F1BF1BEFD63F16E5DB3BCD32CA5D9A8E8DF7ADD67D6C4F293FB23F7BDA74F52D31B8DDAD03D955D566505A15D8B7DBE83B42378B8E8749C0EB6E2FBC8675838B");
"044A57031859F2007B7E97600C16D8F11180B8DF16EFA6BA83FDF6CFE02A4D34F2AD8FC4D2D9CF022D36900733DE1FC8BA7ECF11ECA3D265803F2B2CB03AAA9CA9");
cmd1.ExecuteNonQuery();
}
string deleteDbinfo = "delete from DB_INFO";
using (var cmd = new SQLiteCommand(deleteDbinfo, sqliteConn))
//db_info表写入数据
using (var cmd = sqliteConn.CreateCommand())
{
cmd.CommandText = "delete from DB_INFO";
cmd.ExecuteNonQuery();
}
DateTime dt = DateTime.Now;
string dt24 = dt.ToString("yyyy-MM-dd HH:mm:ss");
string sqlInsertDbinfo =
"INSERT INTO DB_INFO (VERSION, CREATETIME,UPDATETIME,CREATEUSER,DESCRIPTION) VALUES (@VERSION, @CREATETIME,@UPDATETIME,@CREATEUSER,@DESCRIPTION)";
using (var cmd = new SQLiteCommand(sqlInsertDbinfo, sqliteConn))
using (var cmd = sqliteConn.CreateCommand())
{
cmd.CommandText = sqlInsertDbinfo;
cmd.Parameters.AddWithValue("@VERSION", 2.0);
cmd.Parameters.AddWithValue("@CREATETIME", dt24);
cmd.Parameters.AddWithValue("@UPDATETIME", dt24);
@ -1122,18 +1168,18 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
cmd.ExecuteNonQuery();
}
//附件表写入数据
string deleteFj = "delete from FJ";
using (var cmd = new SQLiteCommand(deleteFj, sqliteConn))
using (var cmd = sqliteConn.CreateCommand())
{
cmd.CommandText = deleteFj;
cmd.ExecuteNonQuery();
}
for (int i = 0; i < filigtlist.Count; i++)
{
var flightid = filigtlist[i];
string fligthpicsql = "select * from lasa_mediafile where \"FlightId\"='" + flightid.flighttaskid +
"'";
var pics = _client.Ado.SqlQuery<LasaMediaFile>(fligthpicsql);
for (int j = 0; j < pics.Count; j++)
{
@ -1152,89 +1198,168 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
}
string fileHash;
using (var sha256 = SHA256.Create())
{
var hashBytes = sha256.ComputeHash(bytes);
fileHash = BitConverter.ToString(hashBytes).Replace("-",
"").ToLower();
}
SM3Digest digest = new SM3Digest();
digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] resultss = new byte[digest.GetDigestSize()];
digest.DoFinal(resultss, 0);
fileHash = Hex.ToHexString(resultss).ToUpper();
string sqlintoFj =
"INSERT INTO FJ (BSM, DKLX,DKBSM,ZDKBH,XZQDM,FJMC,FJLX,PSTZ,FJ,FJHXZ,PSSJ,XDGD,JDGD,Longitude,Latitude,PSFYJ,PSJD,PSHGJ,PSJJ,FJYSKD,FJYSGD,PSDXZXX,PSRY,SPKZXX,ZSDM,JYM) " +
"VALUES (@BSM, @DKLX,@DKBSM,@ZDKBH,@XZQDM,@FJMC,@FJLX,@PSTZ,@FJ,@FJHXZ,@PSSJ,@XDGD,@JDGD,@Longitude,@Latitude,@PSFYJ,@PSJD,@PSHGJ,@PSJJ,@FJYSKD,@FJYSGD,@PSDXZXX,@PSRY,@SPKZXX,@ZSDM,@JYM)";
using (var cmd = new SQLiteCommand(sqlintoFj, sqliteConn))
"INSERT INTO FJ (BSM, DKLX, DKBSM, ZDKBH, XZQDM, FJMC, FJLX, PSTZ, FJ, FJHXZ, PSSJ, XDGD, JDGD, Longitude, Latitude, PSFYJ, PSJD, PSHGJ, PSJJ, FJYSKD, FJYSGD, PSDXZXX, PSRY, SPKZXX, ZSDM, JYM) " +
"VALUES (@BSM, @DKLX, @DKBSM, @ZDKBH, @XZQDM, @FJMC, @FJLX, @PSTZ, @FJ, @FJHXZ, @PSSJ, @XDGD, @JDGD, @Longitude, @Latitude, @PSFYJ, @PSJD, @PSHGJ, @PSJJ, @FJYSKD, @FJYSGD, @PSDXZXX, @PSRY, @SPKZXX, @ZSDM, @JYM)";
using (var cmd = sqliteConn.CreateCommand())
{
cmd.Parameters.AddWithValue("@BSM", pic.Id);
cmd.Parameters.AddWithValue("@DKLX", flightid.dklx);
cmd.Parameters.AddWithValue("@DKBSM", flightid.dkbh);
cmd.Parameters.AddWithValue("@ZDKBH", flightid.zdkbh);
cmd.Parameters.AddWithValue("@XZQDM", flightid.xzqdm);
cmd.Parameters.AddWithValue("@FJMC", pic.Name);
cmd.Parameters.AddWithValue("@FJLX", 1);
cmd.CommandText = sqlintoFj;
// 确保所有 NOT NULL 列都有值
cmd.Parameters.AddWithValue("@BSM", pic.Id ?? "");
cmd.Parameters.AddWithValue("@DKLX", flightid.dklx ?? "");
cmd.Parameters.AddWithValue("@DKBSM", flightid.dkbh ?? "");
cmd.Parameters.AddWithValue("@ZDKBH", flightid.zdkbh ?? "");
cmd.Parameters.AddWithValue("@XZQDM", flightid.xzqdm ?? "");
cmd.Parameters.AddWithValue("@FJMC", pic.Name ?? "");
cmd.Parameters.AddWithValue("@FJLX", "1"); // 确保是字符串
cmd.Parameters.AddWithValue("@PSTZ", "Y");
// 特别注意 FJ 列 - 这是 BLOB 数据,必须确保 bytes 不为 null
if (bytes == null || bytes.Length == 0)
{
throw new ArgumentException("FJ (BLOB) cannot be null or empty");
}
cmd.Parameters.AddWithValue("@FJ", bytes);
cmd.Parameters.AddWithValue("@FJHXZ", fileHash);
cmd.Parameters.AddWithValue("@PSSJ", pic.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
cmd.Parameters.AddWithValue("@XDGD", pic.RelativeAltitude);
cmd.Parameters.AddWithValue("@JDGD", pic.AbsoluteAltitude);
cmd.Parameters.AddWithValue("@Longitude", pic.Lat);
cmd.Parameters.AddWithValue("@Latitude", pic.Lng);
cmd.Parameters.AddWithValue("@PSFYJ", pic.GimbalYawDegree);
cmd.Parameters.AddWithValue("@PSJD", pic.GimbalYawDegree);
cmd.Parameters.AddWithValue("@PSHGJ", pic.GimbalYawDegree);
cmd.Parameters.AddWithValue("@PSJJ", pic.FocalLength);
cmd.Parameters.AddWithValue("@FJYSKD", pic.Width);
cmd.Parameters.AddWithValue("@FJYSGD", pic.Height);
cmd.Parameters.AddWithValue("@PSDXZXX", "");
cmd.Parameters.AddWithValue("@PSRY", "system");
cmd.Parameters.AddWithValue("@SPKZXX", "wu");
// 确保文件哈希不为空
cmd.Parameters.AddWithValue("@FJHXZ", fileHash ?? "");
string time = ((DateTime)pic.CreateTime).ToString("yyyy-MM-dd HH:mm:ss");
// 确保时间不为空
cmd.Parameters.AddWithValue("@PSSJ", time);
// 处理可能为空的数值类型
cmd.Parameters.AddWithValue("@XDGD", pic.RelativeAltitude == null ? 0 : Math.Round((float)pic.RelativeAltitude, 2));
cmd.Parameters.AddWithValue("@JDGD", pic.AbsoluteAltitude == null ? 0 : Math.Round((float)pic.AbsoluteAltitude, 2));
// 确保经纬度不为空
if (!pic.Lat.HasValue) throw new ArgumentException("Longitude cannot be null");
if (!pic.Lng.HasValue) throw new ArgumentException("Latitude cannot be null");
decimal longitude = pic.Lng.HasValue ? decimal.Round((decimal)pic.Lng.Value, 7) : 0;
decimal latitude = pic.Lat.HasValue ? decimal.Round((decimal)pic.Lat.Value, 7) : 0;
cmd.Parameters.AddWithValue("@Longitude", longitude);
cmd.Parameters.AddWithValue("@Latitude", latitude);
// 确保这些整数字段不为空
int psfyj = pic.GimbalPitchDegree == null ? 0 : Convert.ToInt32(pic.GimbalPitchDegree);
cmd.Parameters.AddWithValue("@PSFYJ", psfyj);
//方位角,后面得改
int psjd = pic.GimbalYawDegree == null ? 0 : Convert.ToInt32((pic.GimbalYawDegree + 360) % 360);
cmd.Parameters.AddWithValue("@PSJD", psjd);
int pshgj = pic.GimbalRollDegree == null ? 0 : Convert.ToInt32(pic.GimbalRollDegree);
cmd.Parameters.AddWithValue("@PSHGJ", pshgj);
// 处理可能为空的数值类型
cmd.Parameters.AddWithValue("@PSJJ", pic.FocalLength ?? 0);
cmd.Parameters.AddWithValue("@FJYSKD", pic.Width ?? 0);
cmd.Parameters.AddWithValue("@FJYSGD", pic.Height ?? 0);
// 确保文本字段不为空
cmd.Parameters.AddWithValue("@PSDXZXX", DBNull.Value);
string psry = String.IsNullOrEmpty(pic.CreateUserName) ? "system" : pic.CreateUserName;
cmd.Parameters.AddWithValue("@PSRY", psry);
cmd.Parameters.AddWithValue("@SPKZXX", DBNull.Value);
cmd.Parameters.AddWithValue("@ZSDM", "UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ");
cmd.Parameters.AddWithValue("@JYM", "DESCRIPTION");
string str = $"{fileHash},{time},{longitude},{latitude},{psfyj},{psjd},{pshgj},{psry},UAV32_LJY2FPMYDE6UDES3P3ZD7V3IKQ";
string sm3 = _helper.GetJYM(str);
cmd.Parameters.AddWithValue("@JYM", sm3);
cmd.ExecuteNonQuery();
totalcount += 1;
}
}
}
sqliteConn.Close();
}
//获取上传及下载地址
AirPortUploadReq airPortUploadReq = new AirPortUploadReq();
airPortUploadReq.code = "AirportData";
airPortUploadReq.regioncode = filigtlist[0].xzqdm;
List<string> strings = new List<string>();
strings.Add(filigtlist[0].xzqdm + ".db");
airPortUploadReq.filenames = strings;
List<string> filesname = new List<string>();
filesname.Add(filename);
airPortUploadReq.filenames = filesname;
var result = await getUploadFilePath(airPortUploadReq);
var jsonstr = result.Result;
JArray jObject = JArray.Parse(jsonstr);
var liststr = jObject[0].Value<JObject>();
var write = liststr["writeurl"].ToString();
var read = liststr["readurl"].ToString();
var write = liststr["writeurl"].ToString(); //文件上传地址
var read = liststr["readurl"].ToString(); //文件下载地址
//上传文件
AirPortUploadDbReq req = new AirPortUploadDbReq();
req.fileUrl = write;
req.filePath = configuration.GetSection("DroneDocking:DbFile").Value;
req.filename = filigtlist[0].xzqdm + ".db";
req.filePath = filepath;
req.filename = filename;
// 获取文件大小
FileInfo fileInfo = new FileInfo(filepath);
long fileSize = fileInfo.Length;
//获取文件哈希值
byte[] res = ComputeFileSm3Hash(filepath);
string hash = Hex.ToHexString(res).ToUpper();
//数据写入数据库
using (var uow = base.UnitWork.CreateContext())
{
DbfineInfo dbfine = new DbfineInfo();
dbfine.id = Guid.NewGuid().ToString();
dbfine.taskid = taskid;
dbfine.taskid = taskidsheng;
dbfine.regioncode = filigtlist[0].xzqdm;
dbfine.extension = ".db";
dbfine.attachment_count = 1;
dbfine.size = 1000;
dbfine.count = 50;
dbfine.size = (int)fileSize;
dbfine.count = 3;
dbfine.url = read;
dbfine.hashcode = "adewfdafdaf";
dbfine.hash = hash;
dbfine.key = "hopetry";
var info = await uow.DbfineInfo.InsertAsync(dbfine);
if (info == false)
{
throw new Exception("上传信息写入数据库失败");
}
uow.Commit();
Console.WriteLine(info);
}
//上传db包
await UploadFile(req);
}
// 计算文件SM3哈希值的辅助方法
private byte[] ComputeFileSm3Hash(string filePath)
{
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
SM3Digest digest = new SM3Digest();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
digest.BlockUpdate(buffer, 0, bytesRead);
}
byte[] result = new byte[digest.GetDigestSize()];
digest.DoFinal(result, 0);
return result;
}
}
// 安全获取响应头值的方法
private static string GetHeaderValue(HttpResponseMessage response, string headerName)
{
@ -1260,35 +1385,37 @@ namespace OpenAuth.App.ServiceApp.DroneDocking
{
RefAsync<int> totalCount = 0;
var info = await base.Repository.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(keyWord), t => t.taskname.Contains(keyWord)||t.bizidname.Contains(keyWord))
.Select(t=>new DroneDockRes
{
id= t.id,
bizidname= t.bizidname,
taskname= t.taskname,
createtime= t.createtime,
state= t.state,
datacode= t.datacode,
deviceid= t.deviceid,
taskid= t.taskid,
tasklist = SqlFunc.Subqueryable<DroneDocktaskdetail>().Where(r => r.taskid == t.id).LeftJoin<LasaTask>((r, s) => r.flighttaskid == s.FlightId).ToList((r,s)=> new DetailRes
.WhereIF(!string.IsNullOrEmpty(keyWord),
t => t.taskname.Contains(keyWord) || t.bizidname.Contains(keyWord))
.Select(t => new DroneDockRes
{
id = r.id,
bsm=r.bsm,
Status=s.Status,
bz=r.bz,
dkbh=r.dkbh,
dkfw=r.dkfw,
dklx=r.dklx,
dkmc=r.dkmc,
dkmj=r.dkmj,
flighttaskid=r.flighttaskid,
taskid=r.taskid,
xzqdm=r.xzqdm,
zdkbh=r.zdkbh
id = t.id,
bizidname = t.bizidname,
taskname = t.taskname,
createtime = t.createtime,
state = t.state,
datacode = t.datacode,
deviceid = t.deviceid,
taskid = t.taskid,
tasklist = SqlFunc.Subqueryable<DroneDocktaskdetail>().Where(r => r.taskid == t.id)
.LeftJoin<LasaTask>((r, s) => r.flighttaskid == s.FlightId).ToList((r, s) => new DetailRes
{
id = r.id,
bsm = r.bsm,
Status = s.Status,
bz = r.bz,
dkbh = r.dkbh,
dkfw = r.dkfw,
dklx = r.dklx,
dkmc = r.dkmc,
dkmj = r.dkmj,
flighttaskid = r.flighttaskid,
taskid = r.taskid,
xzqdm = r.xzqdm,
zdkbh = r.zdkbh
})
})
})
.ToPageListAsync(page, limit, totalCount);
.ToPageListAsync(page, limit, totalCount);
return new Response<PageInfo<List<DroneDockRes>>>
{
Result = new PageInfo<List<DroneDockRes>>

View File

@ -13,8 +13,6 @@ namespace OpenAuth.App.ServiceApp.DroneDocking.Request
public string regioncode { get; set; }
public List<string> filenames { get; set; }
}
}

View File

@ -2378,6 +2378,7 @@ namespace OpenAuth.App.ServiceApp
TaskType = 0,
//0 计划任务 1 手飞任务
FlightTaskType = 1,
AIInspection = "true",
WorkspaceId = task.WorkspaceId,
FlightId = task.FlightId,
Status = 1, // 待执行
@ -2425,8 +2426,14 @@ namespace OpenAuth.App.ServiceApp
{
aiInspection.WarningContent = req.WarningContent;
}
// 更新
await db.Insertable(aiInspection).ExecuteCommandAsync();
// todo 关于多次调用问题
var count = await db.Queryable<LasaAiInspection>().Where(x => x.TaskId == req.TaskId).CountAsync();
if (count == 0)
{
await db.Insertable(aiInspection).ExecuteCommandAsync();
}
}
else
{
@ -2469,7 +2476,7 @@ namespace OpenAuth.App.ServiceApp
Status = 6, // 智能巡检状态
PushUrl = pushUrl
};
var tagIdArray = new List<string>();
var tagIdArray = new List<string>();
foreach (var tagId in tagsIds)
{
tagIdArray.AddRange(tagId.Split(",").ToList());
@ -2490,7 +2497,9 @@ namespace OpenAuth.App.ServiceApp
};
jsonTag[lasaModelLabel.EnumValue.ToString()] = model;
}
json.tag = jsonTag;
Console.WriteLine(JsonConvert.SerializeObject(json));
var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
var url = config["AIModelApi:Url"];
using var httpClient = new HttpClient();
@ -2526,11 +2535,11 @@ namespace OpenAuth.App.ServiceApp
{
db.Ado.BeginTran();
await db.Updateable(task).IgnoreNullColumns().ExecuteCommandAsync();
var config = ConfigHelper.GetConfigRoot();
/*var config = ConfigHelper.GetConfigRoot();
var url = config["AIModelApi:Url"];
// 结束智能巡检
using var httpClient = new HttpClient();
await httpClient.PostAsync($"{url}/stop_detection", null);
await httpClient.PostAsync($"{url}/stop_detection", null);*/
db.Ado.CommitTran();
}
catch (Exception ex)

View File

@ -332,20 +332,14 @@ public class ConfigSubscribe : IJob
var y = response.Content.ReadAsByteArrayAsync().Result;
var ms = new MemoryStream(y);
var directories = ImageMetadataReader.ReadMetadata(ms);
// 获取 XMP 目录(包含 XMP 原始 XML 数据)
var xmpDirectory = directories.OfType<XmpDirectory>().FirstOrDefault();
if (xmpDirectory != null)
{
// 获取 XMP 的 XML 字符串(原始数据)
var xmpXml = xmpDirectory.GetXmpProperties();
foreach (var keyValuePair in xmpXml)
{
switch (keyValuePair.Key)
{
// // drone-dji:GimbalPitchDegree: -90.00
//drone-dji:GimbalReverse: 0
//drone-dji:GimbalRollDegree: +180.00
//drone-dji:GimbalYawDegree: -96.40
case "drone-dji:GimbalPitchDegree":
gimbalPitch = float.Parse(keyValuePair.Value);
break;
@ -490,8 +484,16 @@ public class ConfigSubscribe : IJob
};
if (executeTask != null)
{
fileUpload.CreateUserName = executeTask.CreateUserName;
fileUpload.CreateUserId = executeTask.CreateId;
_logger.LogDebug($"任务信息:{JsonConvert.SerializeObject(executeTask)}");
if (!string.IsNullOrEmpty(executeTask.CreateUserName))
{
fileUpload.CreateUserName = executeTask.CreateUserName;
}
if (executeTask.CreateId != null)
{
fileUpload.CreateUserId = executeTask.CreateId;
}
}
// 添加事务
@ -665,8 +667,7 @@ public class ConfigSubscribe : IJob
if (!string.IsNullOrEmpty(task.AIInspection) && task.AIInspection.Equals(true) &&
!string.IsNullOrEmpty(task.PushUrl))
{
// 停止直播
// 停止 aimodel 运行
// todo video_id 需要根据不同设备改变
var para = @$"{{
""bid"": {Guid.NewGuid().ToString()},
""data"": {{

View File

@ -7,7 +7,7 @@ using System;
/// <summary>
/// 媒体文件实体类
/// </summary>
[SugarTable("dbfile_info")]
[SugarTable("drone_dbfileinfo")]
public class DbfineInfo
{
/// <summary>
@ -22,39 +22,49 @@ public class DbfineInfo
public string taskid { get; set; }
/// <summary>
/// 飞行器产品枚举
/// 区域代码
/// </summary>
public string regioncode { get; set; }
/// <summary>
/// 是否是原图 0否1是
/// 数据包大小
/// </summary>
public int size { get; set; }
/// <summary>
/// 文件索引
/// 图斑数量
/// </summary>
public int count { get; set; }
/// <summary>
/// 负载产品枚举
/// 外业附件个数
/// </summary>
public int attachment_count { get; set; }
/// <summary>
/// 拍摄绝对高度
/// 数据包扩展名
/// </summary>
public string extension { get; set; }
/// <summary>
/// 云台偏航角
/// 文件哈希值
/// </summary>
public string hashcode { get; set; }
public string hash { get; set; }
/// <summary>
/// 拍摄相对高度
/// 数据包下载地址
/// </summary>
public string url { get; set; }
/// <summary>
/// 数据包的解密密钥
/// </summary>
public string key { get; set; }
/// <summary>
/// 签章数据
/// </summary>
public string sign { get; set; }
}

View File

@ -146,5 +146,5 @@ public class LasaMediaFile
public string CreateUserName { get; set; }
[SugarColumn(IsIgnore = true)] public string TaskName { get; set; }
[SugarColumn(IsIgnore = true)] public string AirLineName { get; set; }
public long CreateUserId { get; set; }
public long? CreateUserId { get; set; }
}

View File

@ -81,7 +81,7 @@ namespace OpenAuth.Repository.Domain
/// </summary>
public string AirLineId { get; set; }
public long CreateId { get; set; }
public long? CreateId { get; set; }
public DateTime? CreateTime { get; set; }
/// <summary>

View File

@ -10,6 +10,7 @@ using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository.Domain;
using Org.BouncyCastle.Ocsp;
using System.Text;
using Newtonsoft.Json;
namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
@ -311,18 +312,42 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
try
{
var data = await _app.GetDroneStatus(deviceid);
result.data = data.Result;
result.code = data.Code;
result.message = data.Message;
var inResult = await _app.GetDroneStatus(deviceid);
var response = new ResData();
if (inResult.code == 200)
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(inResult));
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态成功!";
response.Code = 200;
response.Secret = xLcSecret;
}
else
{
string xLcSecret = _helper.getxseret();
// 转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(" ");
var encryptedResData = _helper.Encrypt(bytes);
response.Result = encryptedResData;
response.Message = "获取无人机状态失败!";
response.Code = 500;
response.Secret = xLcSecret;
}
result.data = response.Result;
result.code = response.Code;
result.message = response.Message;
result.traceid = Guid.NewGuid().ToString();
Response.Headers.Add("x-lc-secret", data.Secret);
Response.Headers.Add("x-lc-secret", response.Secret);
}
catch (Exception ex)
{
result.code = 200;
result.message = "error";
result.traceid = Guid.NewGuid().ToString();
}
return result;
@ -338,26 +363,7 @@ namespace OpenAuth.WebApi.Controllers.ServiceControllers
}
}
/// <summary>
/// 无人机状态上报
/// </summary>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public async Task<Response<string>> reportDroneStatus([FromBody] List<AirPortStatusApply> req)
{
var result = new Response<string>();
try
{
result = await _app.reportDroneStatus(req);
}
catch (Exception ex)
{
result.Code = 500;
result.Message = ex.Message;
}
return result;
}
/// <summary>
/// 无人机任务进度查询
/// </summary>

View File

@ -36,6 +36,8 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.16" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.16" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.16" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.8" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
@ -49,6 +51,7 @@
<PackageReference Include="NPOI" Version="2.5.6" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.11" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="RabbitMQ.Client" Version="7.1.2" />
</ItemGroup>

View File

@ -27,6 +27,7 @@ using OpenAuth.Repository;
using OpenAuth.WebApi.Model;
using OpenAuth.WebApi.Model.mqtt;
using OpenAuth.WebApi.Model.RabbitMQService;
using OpenAuth.WebApi.SystemTask;
using SqlSugar;
using Swashbuckle.AspNetCore.SwaggerUI;
using Yitter.IdGenerator;
@ -49,6 +50,7 @@ namespace OpenAuth.WebApi
public void ConfigureServices(IServiceCollection services)
{
SQLitePCL.Batteries_V2.Init();
services.AddHttpContextAccessor();
services.AddSingleton<MqttClientManager>();
services.AddSingleton<EncryptionHelper>();
@ -182,6 +184,8 @@ namespace OpenAuth.WebApi
services.AddHostedService<MqttHostedService>();
#endregion
services.AddHostedService<DelayedExecutionService>();
#region rabbitmq
//services.AddSingleton<RabbitMqListenerService>();
//services.AddHostedService(sp => sp.GetRequiredService<RabbitMqListenerService>());

View File

@ -0,0 +1,47 @@
using OpenAuth.App.ServiceApp.DroneDocking;
namespace OpenAuth.WebApi.SystemTask;
public class DelayedExecutionService : BackgroundService
{
private readonly ILogger<DelayedExecutionService> _logger;
private readonly DroneDockApp _droneDockApp;
public DelayedExecutionService(ILogger<DelayedExecutionService> logger, DroneDockApp droneDockApp)
{
_logger = logger;
_droneDockApp = droneDockApp;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("定时任务已启动将每5秒执行一次");
while (!stoppingToken.IsCancellationRequested)
{
try
{
await PerformDelayedTask();
// 等待5秒
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
catch (OperationCanceledException)
{
_logger.LogInformation("定时任务被取消");
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "定时任务执行时发生错误");
// 即使出错也继续下一次执行
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
}
}
}
private async Task PerformDelayedTask()
{
await _droneDockApp.ReportDroneStatus();
await Task.CompletedTask;
}
}