using NCC.Common.Core.Manager;
using NCC.Common.Enum;
using NCC.Common.Extension;
using NCC.Common.Filter;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.FriendlyException;
using NCC.Extend.Interfaces.UavDevice;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NCC.Extend.Entitys;
using NCC.Extend.Entitys.Dto.UavDevice;
using Yitter.IdGenerator;
using NCC.Common.Helper;
using NCC.JsonSerialization;
using NCC.Extend.Entitys.Dto.UavDeviceCell;
using NCC.Extend.Entitys.Enums;
using System.ComponentModel;
using System.Reflection;
using NCC.Code;
using Microsoft.AspNetCore.Authorization;
using NCC.Extend.Interfaces.MqttPublisher;
using Serilog;
using NCC.System.Entitys.Permission;
namespace NCC.Extend.UavDevice
{
///
/// 无人机机柜管理服务
///
[ApiDescriptionSettings(Tag = "无人机机柜管理服务", Name = "UavDevice", Order = 200)]
[Route("api/Extend/[controller]")]
public class UavDeviceService : IUavDeviceService, IDynamicApiController, ITransient
{
///
/// MQTT配置信息类
///
private class MqttConfig
{
public string ServerUri { get; set; }
public int Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Qos { get; set; }
}
///
/// 设备配置信息类
///
private class DeviceConfig
{
public MqttConfig Mqtt { get; set; }
public string MaxRetryCount { get; set; }
public string DevicePortPath { get; set; }
public string RfidPortPath { get; set; }
public int DeleteVideo { get; set; }
}
private readonly ISqlSugarRepository _uavDeviceRepository;
private readonly SqlSugarScope _db;
private readonly IUserManager _userManager;
private readonly IMqttPublisherService _mqttService;
///
/// 初始化一个类型的新实例
///
public UavDeviceService(
ISqlSugarRepository uavDeviceRepository,
IUserManager userManager,
IMqttPublisherService mqttService)
{
_uavDeviceRepository = uavDeviceRepository;
_db = _uavDeviceRepository.Context;
_userManager = userManager;
_mqttService = mqttService;
}
#region 获取无人机机柜管理信息
///
/// 获取无人机机柜管理
///
/// 参数
///
[HttpGet("{id}")]
public async Task GetInfo(string id)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == id);
var output = entity.Adapt();
output.uavDeviceCellEntities = _db.Queryable().Where(p => p.DeviceId == output.id)
.Select(it => new UavDeviceCellListOutput
{
id = it.Id,
deviceId = it.DeviceId,
cellCode = it.CellCode,
status = it.Status,
rfid1 = it.Rfid1,
rfid2 = it.Rfid2,
uavCode = it.UavCode,
}).ToList();
output.isOnline = await _mqttService.IsClientOnlineAsync(output.deviceCode);
return output;
}
#endregion
#region 获取无人机机柜管理列表
///
/// 获取无人机机柜管理列表
///
/// 请求参数
///
[HttpGet("")]
public async Task GetList([FromQuery] UavDeviceListQueryInput input)
{
var sidx = input.sidx == null ? "id" : input.sidx;
var data = await _db.Queryable()
.WhereIF(!string.IsNullOrEmpty(input.deviceName), p => p.DeviceName.Contains(input.deviceName))
.WhereIF(!string.IsNullOrEmpty(input.deviceCode), p => p.DeviceCode.Contains(input.deviceCode))
.WhereIF(!string.IsNullOrEmpty(input.belongUserId), p => p.BelongUserId.Contains(input.belongUserId))
.Select(it => new UavDeviceListOutput
{
id = it.Id,
deviceName = it.DeviceName,
deviceCode = it.DeviceCode,
siteId = it.SiteId,
belongUserId = it.BelongUserId,
lng = it.Lng,
lat = it.Lat,
status = it.Status,
remark = it.Remark,
appVersion = it.AppVersion,
cellnumber = SqlFunc.Subqueryable().Where(u => u.DeviceId == it.Id).Count(),
belongUserName = SqlFunc.Subqueryable().Where(u => u.Id == it.BelongUserId).Select(u => u.RealName),
}).MergeTable().Mapper(async res =>
{
res.uavDeviceCells = _db.Queryable().Where(p => p.DeviceId == res.id).Select(it => new UavDeviceCellListOutput
{
id = it.Id,
cellCode = it.CellCode,
status = it.Status,
rfid1 = it.Rfid1,
rfid2 = it.Rfid2,
uavCode = it.UavCode,
}).ToList();
res.isOnline = await _mqttService.IsClientOnlineAsync(res.deviceCode);
}).OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(data);
}
#endregion
#region 获取代理商获取自己的无人机机柜管理列表
///
/// 获取代理商获取自己的无人机机柜管理列表
///
/// 请求参数
///
[HttpGet("GetListByCurrent")]
public async Task GetListByCurrent([FromQuery] UavDeviceListQueryInput input)
{
var sidx = input.sidx == null ? "id" : input.sidx;
var data = await _db.Queryable()
.WhereIF(!string.IsNullOrEmpty(input.deviceName), p => p.DeviceName.Contains(input.deviceName))
.WhereIF(!string.IsNullOrEmpty(input.deviceCode), p => p.DeviceCode.Contains(input.deviceCode))
.WhereIF(!string.IsNullOrEmpty(input.siteId), p => p.SiteId == input.siteId)
.Where(p => p.BelongUserId == _userManager.UserId)
.Select(it => new UavDeviceListOutput
{
id = it.Id,
deviceName = it.DeviceName,
deviceCode = it.DeviceCode,
siteId = it.SiteId,
belongUserId = it.BelongUserId,
lng = it.Lng,
lat = it.Lat,
status = it.Status,
remark = it.Remark,
siteName = SqlFunc.Subqueryable().Where(u => u.Id == it.SiteId).Select(u => u.SiteName),
cellnumber = SqlFunc.Subqueryable().Where(u => u.DeviceId == it.Id).Count(),
}).MergeTable().Mapper(async it =>
{
it.isOnline = await _mqttService.IsClientOnlineAsync(it.deviceCode);
}).OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(data);
}
#endregion
#region 获取根据代理商id获取的无人机机柜管理列表
///
/// 获取根据代理商id获取的无人机机柜管理列表
///
/// 请求参数
///
[HttpGet("GetListByUserId")]
public async Task GetListByUserId([FromQuery] UavDeviceListQueryInput input)
{
var sidx = input.sidx == null ? "id" : input.sidx;
var data = await _db.Queryable()
.WhereIF(!string.IsNullOrEmpty(input.deviceName), p => p.DeviceName.Contains(input.deviceName))
.WhereIF(!string.IsNullOrEmpty(input.deviceCode), p => p.DeviceCode.Contains(input.deviceCode))
.WhereIF(!string.IsNullOrEmpty(input.siteId), p => p.SiteId == input.siteId)
.Where(p => p.BelongUserId == input.belongUserId)
.Select(it => new UavDeviceListOutput
{
id = it.Id,
deviceName = it.DeviceName,
deviceCode = it.DeviceCode,
siteId = it.SiteId,
belongUserId = it.BelongUserId,
lng = it.Lng,
lat = it.Lat,
status = it.Status,
remark = it.Remark,
siteName = SqlFunc.Subqueryable().Where(u => u.Id == it.SiteId).Select(u => u.SiteName),
cellnumber = SqlFunc.Subqueryable().Where(u => u.DeviceId == it.Id).Count(),
}).MergeTable().Mapper(async res =>
{
res.isOnline = await _mqttService.IsClientOnlineAsync(res.deviceCode);
}).OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(data);
}
#endregion
#region 新建无人机机柜管理
///
/// 新建无人机机柜管理
///
/// 参数
///
[HttpPost("")]
public async Task Create([FromBody] UavDeviceCrInput input)
{
var entity = input.Adapt();
entity.Id = YitIdHelper.NextId().ToString();
entity.BelongUserId = _userManager.UserId;
if (input.deviceCode.IsNullOrEmpty())
{
entity.DeviceCode = "SA" + YitIdHelper.NextId().ToString();
}
var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
//新建完毕后,添加格位的信息,也就是货道信息
List cellEntities = new List();
//初始化的时候就提供6个货道
for (int i = 1; i <= 6; i++)
{
UavDeviceCellEntity uavDeviceCellEntitycellEntity = new UavDeviceCellEntity
{
Id = YitIdHelper.NextId().ToString(),
DeviceId = entity.Id,
CellCode = i.ToString(),
Status = DeviceCellStatusEnum.空闲.GetHashCode(),
CreateTime = DateTime.Now,
};
cellEntities.Add(uavDeviceCellEntitycellEntity);
}
isOk = await _db.Insertable(cellEntities).ExecuteCommandAsync();
if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000);
}
#endregion
#region 更新无人机机柜管理
///
/// 更新无人机机柜管理
///
/// 主键
/// 参数
///
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] UavDeviceUpInput input)
{
var entity = input.Adapt();
var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001);
}
#endregion
#region 小程序端更新无人机机柜信息
///
/// 更新无人机机柜管理
///
/// 主键
/// 参数
///
[HttpPut("UpdateByWechat")]
public async Task UpdateByWechat(string id, [FromBody] UavDeviceUpInput input)
{
var entity = input.Adapt();
var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
//更新完基本信息后,需要去更新机柜格子信息
foreach (var item in input.uavDeviceCellEntities)
{
var cellEntity = await _db.Queryable().FirstAsync(p => p.Id == item.id);
//需要判断是否有此机柜格子
if (cellEntity != null)
{
cellEntity.DeviceId = input.id;
cellEntity.CellCode = item.cellCode;
cellEntity.Status = item.status;
cellEntity.Remark = item.remark;
await _db.Updateable(cellEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
else
{
//如果没有这个机柜格子,则创建
UavDeviceCellEntity uavDeviceCellEntity = new UavDeviceCellEntity
{
DeviceId = input.id,
CellCode = item.cellCode,
Status = item.status,
Remark = item.remark,
Id = YitIdHelper.NextId().ToString(),
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now,
CreatorId = _userManager.UserId
};
await _db.Insertable(uavDeviceCellEntity).ExecuteCommandAsync();
}
}
if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001);
}
#endregion
#region 获取设备状态枚举列表
///
/// 获取设备状态枚举列表
///
[HttpGet("GetDeviceStatusEnum")]
public async Task GetDeviceStatusEnum()
{
var list = Enum.GetValues(typeof(DeviceStatusEnum))
.Cast()
.Select(e => new
{
Value = (int)e,
Label = GetDescription(e)
}).ToList();
return list;
}
private string GetDescription(Enum enumValue)
{
var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
var descriptionAttribute = fieldInfo?.GetCustomAttribute();
return descriptionAttribute?.Description ?? enumValue.ToString();
}
#endregion
#region 删除无人机机柜管理
///
/// 删除无人机机柜管理
///
///
[HttpDelete("{id}")]
public async Task Delete(string id)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == id);
_ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
var isOk = await _db.Deleteable().Where(d => d.Id == id).ExecuteCommandAsync();
if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002);
}
#endregion
#region 解绑设备
///
/// 解绑设备
///
///
///
[HttpPut("UnbindDevice/{id}")]
public async Task UnbindDevice(string id)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == id);
entity.BelongUserId = "";
var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001);
}
#endregion
#region 绑定设备
///
/// 绑定设备
///
///
///
[HttpPut("BindDevice")]
public async Task BindDevice(UavDeviceUpInput input)
{
var entity = await _db.Queryable().FirstAsync(p => p.DeviceCode == input.deviceCode);
if (entity.IsNull())
{
return new
{
code = -1,
message = "设备不存在!",
};
}
if (entity.BelongUserId.IsNotEmptyOrNull())
{
return new
{
code = -1,
message = "该设备已绑定,请勿重复绑定!",
};
}
entity.DeviceName = input.deviceCode;
entity.BelongUserId = _userManager.UserId;
entity.SiteId = input.siteId;
entity.Remark = input.remark;
entity.Status = input.status;
var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
if (!(isOk > 0))
{
return NCCException.Oh(ErrorCode.COM1001);
}
return new
{
code = 0,
message = "绑定设备成功!",
};
}
#endregion
#region 获取代理商设备数量信息
///
/// 获取代理商设备数量信息
///
///
[HttpGet("GetAgentDeviceCount")]
public async Task GetAgentDeviceCount()
{
var DeviceCount = await _db.Queryable().Where(p => p.BelongUserId == _userManager.UserId).CountAsync();
return new
{
DeviceCount = DeviceCount
};
}
#endregion
#region 柜子服务端进行绑定
///
/// 柜子服务端进行绑定
///
///
///
[HttpPut("CabinetBind")]
[AllowAnonymous]
public async Task CabinetBind(UavDeviceBindCrInput input)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == input.id);
if (entity.MacAddress.IsNotEmptyOrNull())
{
return new
{
code = -1,
message = "设备已绑定!",
};
}
entity.MacAddress = input.macAddress;
var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
return new
{
code = 0,
message = "绑定成功!",
};
}
#endregion
#region 测试发布订阅
///
/// 测试发布订阅
///
///
///
[HttpPost("testPublish")]
public async Task testPublish(UavDeviceOprnNotifyCrInput input)
{
string topic = $"device/{input.id}/response";
string message = input.ToJson();
await _mqttService.PublishAsync(topic, message);
return new { code = 200, msg = "测试开门指令已发送" };
}
#endregion
#region 检测开门
///
/// 检测开门
///
///
///
[HttpPost("DetectionCheckOpenDoor")]
public async Task DetectionCheckOpenDoor(UavDeviceOpenCrInput input)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == input.id);
string topic = $"device/{entity.DeviceCode}/uav";
string message = new MqttContent
{
className = "DetectionOpen",
action = "open",
lane = input.lane,
orderNo = "",
instructionTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
tokenUrl = ""
}.ToJson();
await _mqttService.PublishAsync(topic, message);
return new { code = 200, msg = "测试开门指令已发送" };
}
#endregion
#region 同步设备信息(补货)
///
/// 同步设备信息(补货)
///
///
///
[HttpPost("SyncDeviceInfo")]
[AllowAnonymous]
public async Task SyncDeviceInfo(UavDeviceOprnNotifyCrInput input)
{
//获取设备信息
var DeviceInfo = await _db.Queryable().FirstAsync(p => p.Id == input.id);
//通过设备编号以及货道code获取信息
var DeviceCellInfo = await _db.Queryable().FirstAsync(p => p.DeviceId == input.id && p.CellCode == input.lane);
if (input.rfid_1.IsNotEmptyOrNull())
{
//如果传入的无人机FRID不为空,就需要去修改无人机的信息
//通过传入的无人机FRID以及电池FRID去查询信息
var UavInfo = await _db.Queryable().FirstAsync(p => p.UavFrid == input.rfid_1);
UavInfo.Status = UavAircraftStatusEnum.空闲.GetHashCode();
UavInfo.UavFrid = input.rfid_1;
UavInfo.DeviceId = input.id;
UavInfo.CellId = DeviceCellInfo.Id;
UavInfo.BatteryCapacity = input.batteryCapacity;
_db.Updateable(UavInfo).ExecuteCommand();
}
else
{
//如果传入的无人机FRID为空,就通过货道id去找到之前绑定的无人机,然后去把绑定取消,并且标注无人机为
var UavInfo = _db.Queryable().Where(x => x.CellId == DeviceCellInfo.Id).First();
UavInfo.Status = UavAircraftStatusEnum.维修.GetHashCode();
UavInfo.DeviceId = string.Empty;
UavInfo.CellId = string.Empty;
UavInfo.BatteryCapacity = input.batteryCapacity;
_db.Updateable(UavInfo).ExecuteCommand();
}
return new
{
code = 0,
message = "同步成功!",
};
}
#endregion
#region 注册设备
///
/// 注册设备
///
///
///
[HttpPost("RegisterDevice/{DeviceCOde}")]
[AllowAnonymous]
public async Task RegisterDevice(string DeviceCOde)
{
Log.Information($"设备更新信息1111: {DeviceCOde}");
// 查询是否存在该设备
// 查询是否存在该设备
var entity = await _db.Queryable().Where(x => x.DeviceCode == DeviceCOde).FirstAsync();
if (!entity.IsNullOrEmpty())
{
return new { success = true, message = "设备已存在,无需重复注册。" };
}
// 开启事务
try
{
await _db.Ado.UseTranAsync(async () =>
{
// 新建设备
var info = new UavDeviceEntity
{
Id = YitIdHelper.NextId().ToString(),
DeviceCode = DeviceCOde,
DeviceName = DeviceCOde,
Status = DeviceStatusEnum.启用.GetHashCode(),
CreateTime = DateTime.Now,
};
await _db.Insertable(info).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
// 新建货道
var cellEntities = new List();
for (int i = 1; i <= 6; i++)
{
cellEntities.Add(new UavDeviceCellEntity
{
Id = YitIdHelper.NextId().ToString(),
DeviceId = info.Id,
CellCode = i.ToString(),
Status = DeviceCellStatusEnum.空闲.GetHashCode(),
CreateTime = DateTime.Now
});
}
await _db.Insertable(cellEntities).ExecuteCommandAsync();
});
return new { success = true, message = "设备注册成功。" };
}
catch (Exception ex)
{
// 日志记录异常(如有日志组件)
Log.Error($"设备注册异常: {ex.Message}");
return new { success = false, message = "设备注册失败,请联系系统管理员。" };
}
}
#endregion
#region 注册设备(用于APP更新)
///
/// 注册设备(用于APP更新)
///
///
///
[HttpPost("RegisterDeviceForAppUpdate")]
[AllowAnonymous]
public async Task RegisterDeviceForAppUpdate(UavDeviceBindInput DeviceCodeInfo)
{
Log.Information($"设备更新信息: {DeviceCodeInfo.ToJson()}");
// 查询是否存在该设备
var entity = await _db.Queryable().Where(x => x.DeviceCode == DeviceCodeInfo.newDeviceCode || x.DeviceCode == DeviceCodeInfo.deviceCode).FirstAsync();
if (!entity.IsNullOrEmpty())
{
entity.AppVersion = DeviceCodeInfo.appVersion;
//判断两个设备编号
if (entity.DeviceCode == DeviceCodeInfo.newDeviceCode)
{
await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
return new { success = true, message = "设备已存在,无需重复注册。" };
}
//如果两个设备编号不一致,则需要修改设备编号
entity.DeviceCode = DeviceCodeInfo.newDeviceCode;
await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
return new { success = true, message = "设备信息更新成功" };
}
// 开启事务
try
{
await _db.Ado.UseTranAsync(async () =>
{
// 新建设备
var info = new UavDeviceEntity
{
Id = YitIdHelper.NextId().ToString(),
DeviceCode = DeviceCodeInfo.newDeviceCode,
DeviceName = DeviceCodeInfo.newDeviceCode,
Status = DeviceStatusEnum.启用.GetHashCode(),
CreateTime = DateTime.Now,
AppVersion = DeviceCodeInfo.appVersion,
};
await _db.Insertable(info).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
// 新建货道
var cellEntities = new List();
for (int i = 1; i <= 6; i++)
{
cellEntities.Add(new UavDeviceCellEntity
{
Id = YitIdHelper.NextId().ToString(),
DeviceId = info.Id,
CellCode = i.ToString(),
Status = DeviceCellStatusEnum.空闲.GetHashCode(),
CreateTime = DateTime.Now
});
}
await _db.Insertable(cellEntities).ExecuteCommandAsync();
});
return new { success = true, message = "设备注册成功。" };
}
catch (Exception ex)
{
// 日志记录异常(如有日志组件)
Log.Error($"设备注册异常: {ex.Message}");
return new { success = false, message = "设备注册失败,请联系系统管理员。" };
}
}
#endregion
#region 机柜获取MQTT配置
///
/// 机柜获取MQTT配置
///
/// 设备编码
/// MQTT配置信息
[HttpGet("GetMqttConfig/{deviceCode}")]
[AllowAnonymous]
public async Task GetMqttConfig(string deviceCode = "")
{
var mqttBaseConfig = new
{
serverUri = "mqtt.cqjiangzhichao.cn",
port = 1883,
username = "wrjservice",
password = "P@ssw0rd",
qos = "0"
};
var baseConfig = new
{
mqtt = mqttBaseConfig,
maxRetryCount = "3",
devicePortPath = "/dev/ttyS2",
rfidPortPath = "/dev/ttyS4",
downloadUrl = "https://wrj.cqjiangzhichao.cn/app.apk",
deleteVideo = deviceCode.IsNullOrEmpty() ? 168 : (await _db.Queryable().FirstAsync(p => p.DeviceCode == deviceCode))?.DelVideoTime ?? 168,
openLogActions = "close"
};
return baseConfig;
}
#endregion
#region 设备转让
///
/// 设备转让
///
///
///
[HttpPost("TransferDevice")]
public async Task TransferDevice([FromBody] UavDeviceTransferInput input)
{
var entity = await _db.Queryable().FirstAsync(x => x.Id == input.id);
if (entity.IsNullOrEmpty())
{
return NCCException.Oh("设备不存在!");
}
var userBool = await _db.Queryable().Where(x => x.Id == entity.BelongUserId).AnyAsync();
if (!userBool)
{
return NCCException.Oh("用户不存在!");
}
entity.BelongUserId = input.belongUserId;
var isOk = await _db.Updateable(entity).ExecuteCommandAsync();
if (isOk > 0)
{
return new
{
code = 0,
message = "转让成功!",
};
}
else
{
return NCCException.Oh("转让失败!");
}
}
#endregion
#region 推送APP更新消息
///
/// 推送APP更新消息给设备
///
/// 设备编码
/// APP下载地址
///
[HttpPost("PushAppUpdate")]
public async Task PushAppUpdate(string deviceCode, string downloadUrl = "")
{
try
{
// 验证设备是否存在
var device = await _db.Queryable().FirstAsync(x => x.DeviceCode == deviceCode);
if (device == null)
{
return new { code = 400, msg = "设备不存在" };
}
// 如果没有提供下载地址,使用默认地址
if (string.IsNullOrEmpty(downloadUrl))
{
downloadUrl = "https://wrj.cqjiangzhichao.cn/app.apk";
}
// 构建MQTT消息
string topic = $"device/{deviceCode}/uav";
string message = new MqttContent
{
className = "updateapp",
action = "open",
lane = "1", // APP更新通常使用固定货道
orderNo = downloadUrl, // 将下载地址放在orderNo字段中
instructionTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
tokenUrl = ""
}.ToJson();
// 发送MQTT消息
await _mqttService.PublishAsync(topic, message);
Log.Information($"已推送APP更新消息到设备 {deviceCode},下载地址:{downloadUrl}");
return new
{
code = 200,
msg = "APP更新消息推送成功",
data = new
{
deviceCode = deviceCode,
downloadUrl = downloadUrl,
messageId = Guid.NewGuid().ToString()
}
};
}
catch (Exception ex)
{
Log.Error($"推送APP更新消息失败:{ex.Message}");
return new { code = 500, msg = $"推送APP更新消息失败:{ex.Message}" };
}
}
///
/// 批量推送APP更新消息给多个设备
///
/// 设备编码列表
/// APP下载地址
///
[HttpPost("PushAppUpdateBatch")]
public async Task PushAppUpdateBatch(string downloadUrl = "")
{
try
{
var deviceCodes = await _db.Queryable().ToListAsync();
// 如果没有提供下载地址,使用默认地址
if (string.IsNullOrEmpty(downloadUrl))
{
downloadUrl = "https://wrj.cqjiangzhichao.cn/app.apk";
}
var results = new List