using OpenAuth.App.BaseApp.Base;
using OpenAuth.Repository.Domain;
using OpenAuth.Repository;
using System.Text;
using OpenAuth.App.Interface;
using SqlSugar;
using Infrastructure;
using Infrastructure.Helpers;
using OpenAuth.App.ServiceApp.Response;
using Microsoft.Extensions.Configuration;
using OpenAuth.App.ServiceApp.DroneDocking.Request;
using OpenAuth.App.ServiceApp.DroneDocking.Response;
using System.Net.Http.Headers;
using Microsoft.Data.Sqlite;
using System.Dynamic;
using Infrastructure.CloudSdk.minio;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAuth.WebApi;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Utilities.Encoders;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Text.Json;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using System.Net;
using System.Drawing.Imaging;
using System.Drawing;

namespace OpenAuth.App.ServiceApp.DroneDocking
{
    public class DroneDockApp : SqlSugarBaseApp<DroneDocktask, SugarDbContext>
    {
        private EncryptionHelper _helper;
        private IConfiguration configuration;
        private readonly ISqlSugarClient _client;
        private readonly MinioService _minioService;
        private readonly MqttClientManager _mqttClientManager;
        private readonly IHostEnvironment _env;

        public DroneDockApp(EncryptionHelper helper, IHostEnvironment env, IConfiguration configuration, ISqlSugarClient client,
            MinioService minioService, MqttClientManager mqttClientManager, ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<DroneDocktask> repository, IAuth auth) : base(unitWork, repository, auth)
        {
            _helper = helper;
            this.configuration = configuration;
            _client = client;
            _minioService = minioService;
            _mqttClientManager = mqttClientManager;
            _env = env;
        }

        /// <summary>
        /// 无人机机场接口注册更新
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<string>> RegistService(AirPortRegistReq req)
        {
            Response<string> Response = new Response<string>();

            using var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient(handler))
            {
                try
                {
                    string url = configuration.GetSection("DroneDocking:Url").Value + "/droneAirport/RegistService";
                    string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    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 = "连接错误："+ e.Message;
                }
            }

            return Response;
        }

        /// <summary>
        /// 无人机机场设备注册/更新
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<string>> AddDevice(AddDeviceReq req)
        {
            Response<string> Response = new Response<string>();

            using var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient(handler))
            {
                try
                {
                    string url = configuration.GetSection("DroneDocking:Url").Value + "/droneAirport/addDevice";
                    string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    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 = "连接错误：" + e.Message;
                }
            }

            return Response;
        }

        /// <summary>
        /// 无人机机场授权
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<string>> Authorization(AuthorizationReq req)
        {
            Response<string> Response = new Response<string>();

            using var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient(handler))
            {
                try
                {
                    string url = configuration.GetSection("DroneDocking:Url").Value + "/droneAirport/authorization";
                    string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    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 = "连接错误";
                }
            }

            return Response;
        }

        /// <summary>
        /// 无人机机场授权
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<string>> Test(AirPortTaskReq req)
        {
            Response<string> Response = new Response<string>();

            var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient())
            {
                try
                {
                    string url = "http://localhost:10042/zhcfzx/droneAirport/AddTask";
                    string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    string x_token =
                        "API32_HENJOZMPBYKEXNVLFMY3Y5W5SQ.1751622229582.fmCjIucQYyq4YZe4CnSStN/rHcwjZTxUsDuXeXJfrYn0bwoaV1/IW8mcFwtLw8JHjowvMJrmPyy/QZAhssxQCQ==";

                    // 序列化为 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 = "连接错误";
                }
            }

            return Response;
        }

        public async Task<Response<string>> Test1(string taskid)
        {
            Response<string> Response = new Response<string>();

            var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient())
            {
                try
                {
                    string url = $"http://localhost:10042/zhcfzx/droneAirport/cancelTask?taskid={taskid}";
                    //string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    string x_token =
                        "API32_HENJOZMPBYKEXNVLFMY3Y5W5SQ.1751622229582.fmCjIucQYyq4YZe4CnSStN/rHcwjZTxUsDuXeXJfrYn0bwoaV1/IW8mcFwtLw8JHjowvMJrmPyy/QZAhssxQCQ==";

                    // 添加请求头
                    client.DefaultRequestHeaders.Add("x-lc-token", x_token);

                    //发送请求
                    HttpResponseMessage response = await client.GetAsync(url);
                    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 = "连接错误";
                }
            }

            return Response;
        }

        /// <summary>
        /// 无人机任务添加
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ResData> AddTask(string req, string secret)
        {
            ResData Response = new ResData();

            //解密数据
            byte[] secretbyte = Convert.FromBase64String(secret); //x-lc-secret
            byte[] reqbyte = Convert.FromBase64String(req); //返回数据
            string data = _helper.Decrypt(secretbyte, reqbyte);

            //序列化返回数据并处理
            var task = JsonSerializer.Deserialize<AirPortTaskReq>(data);

            string ids = "";
            foreach (var item in task.deviceid)
            {
            }

            //task数据生成
            DroneDocktask dt = new DroneDocktask();
            dt.id = Guid.NewGuid().ToString();
            dt.deviceid = string.Join(",", task.deviceid);
            dt.bizidname = task.bizidname.ToString();
            dt.taskid = task.taskid;
            dt.taskname = task.taskname;
            dt.datacode = task.datacode;
            dt.state = 0;
            dt.createtime = DateTime.Now;

            //taskdetail数据生成
            List<DroneDocktaskdetail> dalist = new List<DroneDocktaskdetail>();
            if (task.tasklist.Count > 0)
            {
                foreach (var item in task.tasklist)
                {
                    DroneDocktaskdetail da = new DroneDocktaskdetail();
                    da.id = Guid.NewGuid().ToString();
                    da.taskid = dt.id;
                    da.bz = item.bz;
                    da.dkbh = item.dkbh;
                    da.dkfw = item.dkfw;
                    da.dkmj = item.dkmj;
                    da.dkmc = item.dkmc;
                    da.xzqdm = item.xzqdm;
                    da.zdkbh = item.zdkbh;
                    da.bsm = item.bsm;
                    da.dklx = item.dklx;
                    dalist.Add(da);
                }
            }

            using (var uow = base.UnitWork.CreateContext())
            {
                //查询数据  检查是否有重复数据
                var info = uow.DroneDocktask.AsQueryable().Where(r => r.taskid == task.taskid).First();
                if (info == null)
                {
                    //本地数据库数据添加
                    await uow.DroneDocktask.InsertAsync(dt);
                    await uow.DroneDocktaskdetail.InsertRangeAsync(dalist);
                    var flag = uow.Commit();

                    //返回数据
                    if (flag)
                    {
                        string x_lc_secret = _helper.getxseret();
                        // 转换为字节数组
                        byte[] bytes = Encoding.UTF8.GetBytes(dt.taskid);
                        var encryptedResData = _helper.Encrypt(bytes);
                        Response.Result = encryptedResData;
                        Response.Message = "无人机机场任务添加成功";
                        Response.Code = 200;
                        Response.Secret = x_lc_secret;
                        return Response;
                    }
                    else
                    {
                        string x_lc_secret = _helper.getxseret();
                        // 转换为字节数组
                        byte[] bytes = Encoding.UTF8.GetBytes(" ");

                        var encryptedResData = _helper.Encrypt(bytes);
                        Response.Result = encryptedResData;
                        Response.Message = "无人机机场任务添加失败";
                        Response.Code = 500;
                        Response.Secret = x_lc_secret;
                        return Response;
                    }
                }
                else
                {
                    string x_lc_secret = _helper.getxseret();
                    // 转换为字节数组
                    byte[] bytes = Encoding.UTF8.GetBytes(" ");

                    var encryptedResData = _helper.Encrypt(bytes);
                    Response.Result = encryptedResData;
                    Response.Message = "已存在相同taskid任务";
                    Response.Code = 500;
                    Response.Secret = x_lc_secret;
                    return Response;
                }
            }
        }


        /// <summary>
        /// 无人机任务更新
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ResData> UpdateTask(string req, string secret)
        {
            ResData Response = new ResData();

            //解密数据
            byte[] secretbyte = Convert.FromBase64String(secret); //x-lc-secret
            byte[] reqbyte = Convert.FromBase64String(req); //返回数据
            string data = _helper.Decrypt(secretbyte, reqbyte);

            //序列化返回数据并处理
            var task = JsonSerializer.Deserialize<AirPortUpdateTaskReq>(data);

            using (var uow = base.UnitWork.CreateContext())
            {
                //查询数据
                var info = uow.DroneDocktask.AsQueryable().Where(r => r.taskid == task.taskid).First();
                if (info != null)
                {
                    if (info.state == 0)
                    {
                        //taskdetail数据生成
                        List<DroneDocktaskdetail> dalist = new List<DroneDocktaskdetail>();
                        if (task.tasklist.Count > 0)
                        {
                            foreach (var item in task.tasklist)
                            {
                                DroneDocktaskdetail da = new DroneDocktaskdetail();
                                da.id = Guid.NewGuid().ToString();
                                da.taskid = info.id;
                                da.bz = item.bz;
                                da.dkbh = item.dkbh;
                                da.dkfw = item.dkfw;
                                da.dkmj = item.dkmj;
                                da.dkmc = item.dkmc;
                                da.xzqdm = item.xzqdm;
                                da.zdkbh = item.zdkbh;
                                da.bsm = item.bsm;
                                da.dklx = item.dklx;
                                dalist.Add(da);
                            }
                        }

                        await uow.DroneDocktaskdetail.DeleteAsync(r => r.taskid == info.taskid);
                        await uow.DroneDocktaskdetail.InsertRangeAsync(dalist);
                        var flag = uow.Commit();

                        //返回数据
                        if (flag)
                        {
                            string x_lc_secret = _helper.getxseret();
                            // 转换为字节数组
                            byte[] bytes = Encoding.UTF8.GetBytes(info.taskid);
                            var encryptedResData = _helper.Encrypt(bytes);
                            Response.Result = encryptedResData;
                            Response.Message = "无人机机场任务更新成功";
                            Response.Code = 200;
                            Response.Secret = x_lc_secret;
                            return Response;
                        }
                        else
                        {
                            string x_lc_secret = _helper.getxseret();
                            // 转换为字节数组
                            byte[] bytes = Encoding.UTF8.GetBytes(" ");

                            var encryptedResData = _helper.Encrypt(bytes);
                            Response.Result = encryptedResData;
                            Response.Message = "无人机机场任务更新失败";
                            Response.Code = 500;
                            Response.Secret = x_lc_secret;
                            return Response;
                        }
                    }
                    else
                    {
                        string x_lc_secret = _helper.getxseret();
                        // 转换为字节数组
                        byte[] bytes = Encoding.UTF8.GetBytes(" ");

                        var encryptedResData = _helper.Encrypt(bytes);
                        Response.Result = encryptedResData;
                        Response.Message = "任务已开始执行，无法更新，请重新添加任务";
                        Response.Code = 500;
                        Response.Secret = x_lc_secret;
                        return Response;
                    }
                }
                else
                {
                    string x_lc_secret = _helper.getxseret();
                    // 转换为字节数组
                    byte[] bytes = Encoding.UTF8.GetBytes(" ");

                    var encryptedResData = _helper.Encrypt(bytes);
                    Response.Result = encryptedResData;
                    Response.Message = "未找到任务数据";
                    Response.Code = 500;
                    Response.Secret = x_lc_secret;
                    return Response;
                }
            }
        }

        /// <summary>
        /// 取消任务
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ResData> CancelTask(string taskid)
        {
            ResData Response = new ResData();

            using (var uow = base.UnitWork.CreateContext())
            {
                //查询数据
                var info = uow.DroneDocktask.AsQueryable().Where(r => r.taskid == taskid).First();
                if (info != null)
                {
                    var flag = await uow.DroneDocktask.UpdateAsync(it => new DroneDocktask()
                    {
                        state = 3
                    }, it => it.id == info.id);

                    //返回数据
                    if (uow.Commit())
                    {
                        string x_lc_secret = _helper.getxseret();
                        // 转换为字节数组
                        byte[] bytes = Encoding.UTF8.GetBytes(info.taskid);
                        var encryptedResData = _helper.Encrypt(bytes);
                        Response.Result = encryptedResData;
                        Response.Message = "无人机机场任务取消成功";
                        Response.Code = 200;
                        Response.Secret = x_lc_secret;
                        return Response;
                    }
                    else
                    {
                        string x_lc_secret = _helper.getxseret();
                        // 转换为字节数组
                        byte[] bytes = Encoding.UTF8.GetBytes(" ");

                        var encryptedResData = _helper.Encrypt(bytes);
                        Response.Result = encryptedResData;
                        Response.Message = "无人机机场任务取消失败";
                        Response.Code = 500;
                        Response.Secret = x_lc_secret;
                        return Response;
                    }
                }
                else
                {
                    string x_lc_secret = _helper.getxseret();
                    // 转换为字节数组
                    byte[] bytes = Encoding.UTF8.GetBytes(" ");

                    var encryptedResData = _helper.Encrypt(bytes);
                    Response.Result = encryptedResData;
                    Response.Message = "未找到任务数据";
                    Response.Code = 500;
                    Response.Secret = x_lc_secret;
                    return Response;
                }
            }
        }

        /// <summary>
        /// 无人机状态获取
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<dynamic> GetDroneStatus(string deviceid)
        {
            dynamic result = new ExpandoObject();
            var dock = await Repository
                .ChangeRepository<SugarRepositiry<LasaDronePort>>()
                .AsQueryable()
                .LeftJoin<LasaUav>((a, b) => a.Id == b.PId)
                .Where((a, b) => b.Sn == deviceid).FirstAsync();
            if (dock == null) // 无人机不在线
            {
                result.code = 200;
                dynamic inData = new ExpandoObject();
                result.data = inData;
                inData.mode_code = 1; // 不在线
                result.message = "获取无人机状态成功";
            }
            else
            {
                result.code = 200;
                var dockOsdTopic = $"thing/product/{dock.Sn}/osd";
                var now = DateTime.Now;
                var time = now.AddSeconds(-5);
                var log = await Repository
                    .ChangeRepository<SugarRepositiry<LasaLog>>()
                    .AsQueryable()
                    .Where(r => r.Topic == dockOsdTopic)
                    .Where(r => r.CreateTime > time) // 查询5秒以内数据
                    .Where(r => SqlFunc.JsonLike(r.Data, "drone_in_dock"))
                    .OrderByDescending(r => r.CreateTime)
                    .FirstAsync();
                if (log != null)
                {
                    // 当前时间
                    var dockOsdData =
                        JsonConvert.DeserializeObject<JObject>(JsonConvert.DeserializeObject<string>(log.Data));
                    //drone_in_dock 0":"舱外","1":"舱内"
                    var droneInDock = dockOsdData["data"]?["drone_in_dock"]?.Value<int>();
                    if (droneInDock == 0) // 飞行任务状态
                    {
                        var droneOsdTopic = $"thing/product/{deviceid}/osd";
                        log = await Repository
                            .ChangeRepository<SugarRepositiry<LasaLog>>()
                            .AsQueryable()
                            .Where(r => r.Topic == droneOsdTopic)
                            .Where(r => r.CreateTime > time) // 查询5秒以内数据
                            .OrderByDescending(r => r.CreateTime)
                            .FirstAsync();
                        if (log != null)
                        {
                            var droneOsdData =
                                JsonConvert.DeserializeObject<JObject>(JsonConvert.DeserializeObject<string>(log.Data));

                            var longitude = Math.Round(droneOsdData["data"]?["longitude"]?.Value<decimal>() ?? 0m, 7);
                            var latitude = Math.Round(droneOsdData["data"]?["latitude"]?.Value<decimal>() ?? 0m, 7);
                            var height = Math.Round(droneOsdData["data"]?["height"]?.Value<decimal>() ?? 0m, 2);
                            var elevation = Math.Round(droneOsdData["data"]?["elevation"]?.Value<decimal>() ?? 0m, 2);
                            // 云台信息
                            var payload99 = droneOsdData["data"]?["99-0-0"];
                            var gimbalPitch = payload99?["gimbal_pitch"]?.Value<double>();
                            var gimbalYaw = payload99?["gimbal_yaw"]?.Value<double>();
                            //var gimbalRoll = payload99?["gimbal_roll"]?.Value<double>();
                            var batteryCapacityPercent =
                                droneOsdData["data"]?["battery"]?["capacity_percent"]?.Value<int>();
                            var quality = droneOsdData["data"]?["position_state"]?["quality"]?.Value<int>();

                            dynamic inData = new ExpandoObject();
                            // mode_code  0:在线；1:不在线；2:任务执行中
                            inData.mode_code = 2;
                            inData.longitude = longitude;
                            inData.latitude = latitude;
                            inData.height = height;
                            inData.elevation = elevation;
                            inData.gimbal_pitch = gimbalPitch;
                            inData.gimbal_yaw = gimbalYaw;
                            //data.gimbal_roll = gimbalRoll;
                            inData.battery_capacity_percent = batteryCapacityPercent;

                            inData.gps_state = quality switch
                            {
                                < 2 => 1, // 低精度
                                < 10 => 2, // 高精度
                                _ => 3 // rtk定位
                            };
                            result.data = inData;
                            result.message = "获取无人机状态成功！";
                            result.traceid = Guid.NewGuid().ToString();
                        }
                        else
                        {
                            result.code = 502;
                            result.message = "获取无人机状态失败";
                        }
                    }
                    else
                    {
                        // 舱内 关机或者开机状态
                        // 这里取机场osd日志信息
                        dynamic inData = new ExpandoObject();
                        inData.battery_capacity_percent =
                            dockOsdData["data"]?["drone_charge_state"]?["capacity_percent"]?.Value<int>();
                        inData.elevation = 0;
                        inData.mode_code = 0;
                        var longitude = Math.Round(dockOsdData["data"]?["longitude"]?.Value<decimal>() ?? 0m, 7);
                        var latitude = Math.Round(dockOsdData["data"]?["latitude"]?.Value<decimal>() ?? 0m, 7);
                        var height = Math.Round(dockOsdData["data"]?["height"]?.Value<decimal>() ?? 0m, 2);
                        inData.longitude = longitude;
                        inData.latitude = latitude;
                        inData.height = height;
                        var quality = dockOsdData["data"]?["position_state"]?["quality"]?.Value<int>();
                        inData.gps_state = quality switch
                        {
                            < 2 => 1,
                            < 10 => 2,
                            _ => 3
                        };
                        result.data = inData;
                        result.traceid = Guid.NewGuid().ToString();
                        result.code = 200;
                        result.message = "获取无人机状态成功";
                    }
                }
            } // 设备在线

            return result;
        }

        /// <summary>
        /// 无人机任务查询
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ResData> queryTaskStatus(string taskid)
        {
            ResData Response = new ResData();
            Response.Code = 205;
            var taskinfo = await _client.Queryable<DroneDocktask>().Where(r => r.taskid == taskid).FirstAsync();
            if (taskinfo != null)
            {
                if (taskinfo.state == 0)
                {
                    Response.Code = 201;
                }
                else if (taskinfo.state == 1)
                {
                    Response.Code = 202;
                }
                else if (taskinfo.state == 2)
                {
                    Response.Code = 200;
                }
                else if (taskinfo.state == 3)
                {
                    Response.Code = 204;
                }
            }

            string x_lc_secret = _helper.getxseret();
            // 转换为字节数组
            byte[] bytes = Encoding.UTF8.GetBytes(taskid);
            var encryptedResData = _helper.Encrypt(bytes);
            Response.Result = encryptedResData;
            Response.Message = "查询无人机机场任务状态成功！";
            Response.Secret = x_lc_secret;
            return Response;
        }

        /// <summary>
        /// 无人机状态上报
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<bool>> ReportDroneStatus()
        {
            var droneList = await Repository
                .ChangeRepository<SugarRepositiry<LasaDronePort>>()
                .AsQueryable()
                .Where(it => it.IsDelete == false)
                .ToListAsync();
            var dataList = new List<dynamic>();
            foreach (var item in droneList)
            {
                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
                {
                    0 => "10",
                    1 => "00",
                    2 => "20",
                    _ => "00"
                };
                dataList.Add(inData);
            }

            using var client = new HttpClient();
            try
            {
                // 无人机状态上报接口
                var url = configuration.GetSection("DroneDocking:Url").Value +
                          "/droneAirport/reportDroneStatus";
                var xLcSecret = _helper.getxseret();
                var centerCode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                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);
                Console.WriteLine($"无人机状态上报结果：{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,
            };
        }
        /// <summary>
        /// 无人机状态上报
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ReciveData<string>> ReportDroneStatusForBu()
        {
            var droneList = await Repository
                .ChangeRepository<SugarRepositiry<LasaDronePort>>()
                .AsQueryable()
                .Where(it => it.IsDelete == false)
                .ToListAsync();
            var dataList = new List<dynamic>();
            foreach (var item in droneList)
            {
                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
                {
                    0 => "10",
                    1 => "00",
                    2 => "20",
                    _ => "00"
                };
                dataList.Add(inData);
            }

            using var client = new HttpClient();
            try
            {
                // 无人机状态上报接口
                var url = configuration.GetSection("DroneDocking:Url").Value +
                          "/droneAirport/reportDroneStatus";
                var xLcSecret = _helper.getxseret();
                var centerCode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                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);
                Console.WriteLine($"无人机状态上报结果：{responseBody}");
                return result;
                 
                //解密数据
                /*byte[] resbytesx = Convert.FromBase64String(resxClScrete);
                byte[] resdatabytes = Convert.FromBase64String(result?.data);
                string data = _helper.Decrypt(resbytesx, resdatabytes);*/
                // 结果
            }
            catch (HttpRequestException e)
            {
                return new ReciveData<string>()
                {
                    code = 500,
                    data = e.Message,
                    message = e.Message,
                    traceid = ""
                };
            } 
        }


        /// <summary>
        /// 获取临时上传地址
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<string>> getUploadFilePath(AirPortUploadReq req)
        {
            Response<string> Response = new Response<string>();

            using var handler = new HttpClientHandler();
            // 如果需要忽略服务器证书错误（仅测试环境）
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            using (var client = new HttpClient(handler))
            {
                try
                {
                    string url = configuration.GetSection("DroneDocking:Url").Value + "/DataExchange/getUploadFilePath";
                    string x_lc_secret = _helper.getxseret();
                    string centercode = "UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";
                    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);
                    client.DefaultRequestHeaders.Add("x-lc-datacode", "AirportData");

                    //发送请求
                    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 = "连接错误";
                }
            }

            return Response;
        }

        public async Task<Response<string>> UploadFile(AirPortUploadDbReq req)
        {
            Response<string> Response = new Response<string>();

            // 首先检查文件是否存在
            if (!File.Exists(req.filePath))
            {
                Response.Result = $"错误: 文件 '{req.filePath}' 不存在";
                Response.Code = 500;
                return Response;
            }

            var filePath = req.filePath;
            var uploadUrl = req.fileUrl;
            var fileName = req.filename;
            MultipartFormDataContent formData = null;
            try
            {
                using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    //文件过大，建议使用 大文件上传接口，分段读取，进行上传
                    //fileBuffer = File.ReadAllBytes(filePath);
                    using var 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 = fileContent
                    };
                    var result = client.SendAsync(request).Result.Content.ReadAsStringAsync().Result;
                    if (string.IsNullOrWhiteSpace(result))
                    {
                        Response.Result = result;
                    }
                }

            }
            catch (Exception ex)
            {
                Response.Result = "上传失败";
            }
            finally
            {
                formData?.Dispose();
                //client?.Dispose();
            }

            #region
            //string fileName = Path.GetFileName(filePath);
            //HttpWebRequest reqs = null;
            //HttpWebResponse resp = null;
            //try
            //{
            //    reqs = WebRequest.Create(uploadUrl) as HttpWebRequest;
            //    reqs.Method = "PUT";
            //    reqs.ContentType = "application/octet-stream";
            //    reqs.ContentLength = new FileInfo(filePath).Length;

            //    reqs.SendChunked = true;
            //    reqs.AllowWriteStreamBuffering = false;

            //    using (Stream dataStream = reqs.GetRequestStream())
            //    {
            //        var buffer = new byte[8000];
            //        using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            //        {
            //            int bytesRead = 0;
            //            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            //            {
            //                dataStream.Write(buffer, 0, bytesRead);
            //            }
            //        }
            //    }
            //    resp = reqs.GetResponse() as HttpWebResponse;
            //    var isOk = resp.StatusCode == HttpStatusCode.OK;

            //    Stream streamReceive = resp.GetResponseStream();
            //    var encoding = Encoding.UTF8;

            //    StreamReader streamReader = new StreamReader(streamReceive, encoding);
            //    string strResult = streamReader.ReadToEnd();
            //}
            //catch (Exception ex)
            //{
            //}
            //finally
            //{
            //    resp?.Dispose();
            //}
            #endregion

            return Response;
        }

        /// <summary>
        /// 无人机状态获取
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<ResData> getResult(string taskid)
        {
            ResData Response = new ResData();
            using (var uow = base.UnitWork.CreateContext())
            {
                //查询数据  检查是否有重复数据
                var info = uow.DbfineInfo.AsQueryable().Where(r => r.taskid == taskid).First();

                string json = JsonSerializer.Serialize(info);
                string x_lc_secret = _helper.getxseret();
                // 转换为字节数组
                byte[] bytes = Encoding.UTF8.GetBytes(json);
                var encryptedResData = _helper.Encrypt(bytes);
                Response.Result = encryptedResData;
                Response.Message = "无人机成果获取成功！";
                Response.Code = 200;
                Response.Secret = x_lc_secret;
                return Response;
            }
        }



        public async void InsertDb(string taskid)
        {
            //获取任务数据
            var task = _client.Queryable<DroneDocktask>().Where(r => r.id == taskid).First();
            if (task == null)
            {
                throw new Exception("任务不存在");
            }
            //获取省下发任务id 
            string taskidsheng = task.taskid;
            //拼接字符串
            string filepath = configuration.GetSection("DroneDocking:DbFile").Value;
            string filename = "";
            string signname = "";
            if (string.IsNullOrEmpty(task.taskname))
            {
                filename = task.taskid.ToString() + ".db";
                signname = task.taskid.ToString() + ".sign";
            }
            else
            {
                filename += task.taskname + ".db";
                signname = task.taskname + ".sign";
            }
            filepath = Path.Combine(filepath, filename);

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }

            //获取任务详情数据
            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();
                using (var command = sqliteConn.CreateCommand())
                {
                    //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();
                }

                //创建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_O2MU763AYA3UXKY5S2VZ6UYNN4");
                    cmd1.Parameters.AddWithValue("@SZZS",
                        "eyJvcmdjb2RlIjoiOTEzNzEzMDAzMjgzOTg1NzdRIiwib3JnbmFtZSI6IuWxseS4nOaFp+WIm+S/oeaBr+enkeaKgOaciemZkOWFrOWPuCIsImNlcnRjb2RlIjoiVUFWMzJfTEpZMkZQTVlERTZVREVTM1AzWkQ3VjNJS1EiLCJjZXJ0b3JnY29kZSI6IjEyMTAwMDAwNDAwMDEwMzk4UCIsImNlcnRvcmduYW1lIjoi5Lit5Zu95Zu95Zyf5YuY5rWL6KeE5YiS6Zmi5omn5rOV5qih5Z2XIiwiZXhwaXJhdGlvbiI6IjIwMjYtMDctMDEgMTU6NDY6MjAiLCJwdWJsaWNrZXkiOiIwNEYxQkYxQkVGRDYzRjE2RTVEQjNCQ0QzMkNBNUQ5QThFOERGN0FERDY3RDZDNEYyOTNGQjIzRjdCREE3NEY1MkQzMUI4RERBRDAzRDk1NUQ1NjY1MDVBMTVEOEI3REJFODNCNDIzNzhCOEU4NzQ5QzBFQjZFMkZCQzg2Nz" +
                        "U4MzhCIiwic2lnbiI6IjJBQTIyNDkwQzYxNkI0NjEzNUY2MDRBNDczNjFCQjJGRDcxMEJGOTdBQjcyNDdCMzYxQzc2N0NGQTNGNzcyMTQ0MkExQzhDMUVBRTIxRkEwQUZEMzJGRDg1NjdDMDg1MThGRUY4NTg2RUVCNkE4OTE1MDVBQjUxRjZDNDUyRUM2IiwiY2VydHR5cGUiOiLml6DkurrmnLrkuL7or4Hor4HkuaYiLCJyZWdpb25jb2RlIjoiMzcxMzAwIn0=");
                    cmd1.Parameters.AddWithValue("@ZSBFJGDM", "12100000400010398P");
                    cmd1.Parameters.AddWithValue("@ZSBFJGGY",
                        "044A57031859F2007B7E97600C16D8F11180B8DF16EFA6BA83FDF6CFE02A4D34F2AD8FC4D2D9CF022D36900733DE1FC8BA7ECF11ECA3D265803F2B2CB03AAA9CA9");
                    cmd1.ExecuteNonQuery();
                }


                //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 = sqliteConn.CreateCommand())
                {
                    cmd.CommandText = sqlInsertDbinfo;
                    cmd.Parameters.AddWithValue("@VERSION", 2.0);
                    cmd.Parameters.AddWithValue("@CREATETIME", dt24);
                    cmd.Parameters.AddWithValue("@UPDATETIME", dt24);
                    cmd.Parameters.AddWithValue("@CREATEUSER", "system");
                    cmd.Parameters.AddWithValue("@DESCRIPTION", "DESCRIPTION");
                    cmd.ExecuteNonQuery();
                }

                //附件表写入数据
                string deleteFj = "delete from FJ";
                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++)
                    {
                        var pic = pics[j];

                        #region  筛选.jpeg图片，添加exif信息，转byte
                        if (pic.ObjectKey == null || !pic.ObjectKey.EndsWith(".jpeg"))
                        {
                            continue;
                        }
                        var imageStream = _minioService.GetObjectAsStream("", pic.ObjectKey + "");
                        if (imageStream.Result == null)
                        {
                            continue;
                        }
                        byte[] bytes;
                        using (var image = Image.FromStream(await imageStream))
                        {
                            // 获取属性项列表（如果不存在则创建）
                            if (image.PropertyIdList.Contains(0x8298)) // 0x8298 是 Copyright 的 Exif tag ID
                            {
                                // 移除现有的 Copyright 信息（可选）
                                image.RemovePropertyItem(0x8298);
                            }

                            // 创建新的属性项
                            PropertyItem propItem = image.PropertyItems[0];
                            propItem.Id = 0x8298; // Copyright tag
                            propItem.Type = 2; // ASCII 类型
                            propItem.Value = System.Text.Encoding.ASCII.GetBytes("UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4"); // 以 null 结尾的字符串
                            propItem.Len = propItem.Value.Length;

                            // 设置属性
                            image.SetPropertyItem(propItem);

                            using (MemoryStream memoryStream = new MemoryStream())
                            {
                                image.Save(memoryStream, ImageFormat.Jpeg); ; // 将原始流复制到MemoryStream中
                                bytes = memoryStream.ToArray(); // 获取MemoryStream的字节数组表示
                            }
                        }
                        #endregion

                        #region  图片转hash
                        //转hash
                        string fileHash;
                        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();
                        #endregion

                        #region  将数据写入FJ表
                        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 = sqliteConn.CreateCommand())
                        {
                            cmd.CommandText = sqlintoFj;

                            // 确保所有 NOT NULL 列都有值
                            cmd.Parameters.AddWithValue("@BSM", pic.Id ?? "");
                            cmd.Parameters.AddWithValue("@DKLX", flightid.dklx ?? "");
                            cmd.Parameters.AddWithValue("@DKBSM", flightid.bsm ?? "");
                            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 ?? "");

                            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_O2MU763AYA3UXKY5S2VZ6UYNN4");

                            string str = $"{fileHash},{time},{longitude},{latitude},{psfyj},{psjd},{pshgj},{psry},UAV32_O2MU763AYA3UXKY5S2VZ6UYNN4";

                            string sm3 = _helper.GetJYM(str);
                            cmd.Parameters.AddWithValue("@JYM", sm3);

                            cmd.ExecuteNonQuery();
                            totalcount += 1;
                        }
                        #endregion
                    }
                }


                sqliteConn.Close();
            }

            // 添加短暂延迟以确保文件句柄被释放
            await Task.Delay(500);
            // 确定临时文件夹路径，例如使用Web根路径下的temp文件夹
            string tempFolderPath = Path.Combine(_env.ContentRootPath, "temp");

            // 如果temp文件夹不存在，则创建
            if (!Directory.Exists(tempFolderPath))
            {
                Directory.CreateDirectory(tempFolderPath);
            }

            // 构建临时文件的完整路径
            string tempFilePath = Path.Combine(tempFolderPath, filename);

            // 复制文件
            File.Copy(filepath, tempFilePath, true);

            // 创建进程对象
            Process process = new Process();

            // 配置进程启动参数
            process.StartInfo.FileName = configuration.GetSection("DroneDocking:JYMUrl").Value;
            process.StartInfo.Arguments = $"checkdb -f \"{tempFilePath}\" --pwd hopetry";  // "/c" 表示执行后关闭命令行
            process.StartInfo.RedirectStandardOutput = true; // 重定向输出
            process.StartInfo.UseShellExecute = false;       // 不使用系统外壳
            process.StartInfo.CreateNoWindow = true;         // 不创建窗口

            // 启动进程
            process.Start();

            // 读取输出
            string output = process.StandardOutput.ReadToEnd();
            process.WaitForExit(); // 等待进程结束
            //File.Delete(tempFilePath);
            if (output.IndexOf("签章成功") > 0)
            {
                string signpath = Path.Combine(tempFolderPath, signname);

                #region 获取签章中内容
                // 检查文件是否存在
                if (!File.Exists(signpath))
                {
                    throw new FileNotFoundException($"签名文件不存在: {signpath}");
                }

                // 读取文件内容
                string jsonContent = File.ReadAllText(signpath);

                // 解析JSON
                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true, // 忽略属性名称大小写
                    AllowTrailingCommas = true,         // 允许尾随逗号
                    ReadCommentHandling = JsonCommentHandling.Skip // 跳过注释
                };

                SignFileContent signData = JsonSerializer.Deserialize<SignFileContent>(jsonContent, options);
                #endregion

                //获取上传及下载地址
                AirPortUploadReq airPortUploadReq = new AirPortUploadReq();
                airPortUploadReq.code = "AirportData";
                airPortUploadReq.regioncode = filigtlist[0].xzqdm;
                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();     //文件下载地址
                                                              //上传文件
                AirPortUploadDbReq req = new AirPortUploadDbReq();
                req.fileUrl = write;
                req.filePath = tempFilePath;
                req.filename = filename;

                //数据写入数据库
                using (var uow = base.UnitWork.CreateContext())
                {
                    DbfineInfo dbfine = new DbfineInfo();
                    dbfine.id = Guid.NewGuid().ToString();
                    dbfine.taskid = taskidsheng;
                    dbfine.regioncode = signData.RegionCode;
                    dbfine.extension = signData.Extension;
                    dbfine.attachment_count = Convert.ToInt32(signData.AttachmentCount);
                    dbfine.size = Convert.ToInt32(signData.Size);
                    dbfine.count = Convert.ToInt32(signData.Count);
                    dbfine.url = read;
                    dbfine.hash = signData.Hash;
                    dbfine.key = "hopetry";
                    dbfine.sign = signData.Sign;
                    dbfine.timestamp = Convert.ToInt32(signData.Timestamp);
                    var dbinfo = uow.DbfineInfo.GetList(r => r.taskid == taskidsheng);
                    if (dbinfo.Count > 0)
                    {
                        await uow.DbfineInfo.DeleteAsync(r => r.taskid == taskidsheng);
                    }
                    var info = await uow.DbfineInfo.InsertAsync(dbfine);
                    if (info == false)
                    {
                        throw new Exception("上传信息写入数据库失败");
                    }


                    await uow.DroneDocktask.UpdateAsync(r => new DroneDocktask()
                    {
                        state = 2
                    }, r => r.id == task.id);

                    uow.Commit();
                }

                //上传db包
                await UploadFile(req);
            }
            else
            {
                throw new Exception("验签失败");
            }

        }

        // 计算文件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)
        {
            if (response.Headers.TryGetValues(headerName, out IEnumerable<string> values))
            {
                return string.Join(", ", values); // 如果多个值则合并
            }

            // 尝试忽略大小写再次查找
            foreach (var header in response.Headers)
            {
                if (header.Key.Equals(headerName, StringComparison.OrdinalIgnoreCase))
                {
                    return string.Join(", ", header.Value);
                }
            }

            return null; // 未找到
        }

        //获取省对接任务信息
        public async Task<Response<PageInfo<List<DroneDockRes>>>> GetDroneDockInfos(string keyWord, int page, int limit)
        {
            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
                        {
                            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);
            return new Response<PageInfo<List<DroneDockRes>>>
            {
                Result = new PageInfo<List<DroneDockRes>>
                {
                    Items = info,
                    Total = totalCount
                }
            };
        }

        //获取飞行数据
        public async Task<Response<DroneDockflightRes>> GetDroneDockflightInfos(string taskid)
        {
            DroneDockflightRes res = new DroneDockflightRes();
            var detailinfo = await Repository.ChangeRepository<SugarRepositiry<DroneDocktaskdetail>>()
                .AsQueryable()
                .Where(r => r.flighttaskid == taskid)
                .ToListAsync();
            if (detailinfo.Count > 0)
            {
                var taskId = detailinfo[0].taskid;
                var taskinfo = await Repository.AsQueryable().Where(r => r.id == taskId).FirstAsync();
                var flighttaskinfo = await Repository.ChangeRepository<SugarRepositiry<LasaTask>>()
                    .AsQueryable()
                    .Where(r => r.FlightId == taskid)
                    .FirstAsync();
                if (taskinfo != null)
                {
                    res.bizidname = taskinfo.bizidname;
                    res.taskname = taskinfo.taskname;
                }

                res.tasklist = detailinfo;
                if (flighttaskinfo != null)
                {
                    res.taskExecuteTime =
                        Convert.ToDateTime(flighttaskinfo.ExecuteTime).ToString("yyyy-MM-dd HH:mm:ss");
                    res.waylineName = flighttaskinfo.TaskAirLineName;
                    res.flightTaskType = Convert.ToInt32(flighttaskinfo.FlightTaskType);
                    switch (flighttaskinfo.Status)
                    {
                        case 0:
                            res.flightTaskState = 1;
                            break;

                        case 1:
                            res.flightTaskState = 2;
                            break;

                        case 2:
                            res.flightTaskState = 3;
                            break;

                        case 5:
                            res.flightTaskState = 0;
                            break;
                        case null: //交集
                            res.flightTaskState = 4;
                            break;
                    }
                }
            }

            return new Response<DroneDockflightRes>
            {
                Result = res
            };
        }
    }
}