2025-11-02 00:41:36 +08:00
|
|
|
|
using JiShe.ServicePro;
|
2025-09-19 11:36:17 +08:00
|
|
|
|
using JiShe.ServicePro.ApacheIoTDB.Provider.Options;
|
|
|
|
|
|
using JiShe.ServicePro.Consts;
|
|
|
|
|
|
using JiShe.ServicePro.Core;
|
|
|
|
|
|
using JiShe.ServicePro.Dto;
|
2025-10-16 17:25:50 +08:00
|
|
|
|
using JiShe.ServicePro.Encrypt;
|
2025-09-19 11:36:17 +08:00
|
|
|
|
using JiShe.ServicePro.Enums;
|
2025-05-27 16:16:07 +08:00
|
|
|
|
using JiShe.ServicePro.FreeRedisProvider;
|
|
|
|
|
|
using JiShe.ServicePro.FreeSqlProvider;
|
2025-09-19 11:36:17 +08:00
|
|
|
|
using JiShe.ServicePro.IoTDBManagement.TableModels;
|
2025-10-16 17:25:50 +08:00
|
|
|
|
using System.Xml.Linq;
|
2025-09-19 11:36:17 +08:00
|
|
|
|
using Volo.Abp;
|
2025-05-27 16:16:07 +08:00
|
|
|
|
|
2025-05-27 14:27:50 +08:00
|
|
|
|
namespace JiShe.IoT
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Inherit your application services from this class.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public abstract class IoTAppService : ApplicationService
|
|
|
|
|
|
{
|
2025-05-27 16:16:07 +08:00
|
|
|
|
protected IFreeSqlProvider FreeSqlDbContext => LazyServiceProvider.LazyGetRequiredService<IFreeSqlProvider>();
|
2025-10-11 15:22:25 +08:00
|
|
|
|
protected IFreeRedisProvider FreeRedisProvider => LazyServiceProvider.LazyGetRequiredService<IFreeRedisProvider>();
|
2025-05-27 16:16:07 +08:00
|
|
|
|
|
2025-05-27 14:27:50 +08:00
|
|
|
|
protected IoTAppService()
|
|
|
|
|
|
{
|
|
|
|
|
|
LocalizationResource = typeof(IoTResource);
|
|
|
|
|
|
}
|
2025-09-19 11:36:17 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-11-02 00:41:36 +08:00
|
|
|
|
/// 获取设备遥测指令信息
|
2025-09-19 11:36:17 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="iotDBOptions">IoTDBOptions</param>
|
2025-11-02 00:41:36 +08:00
|
|
|
|
/// <param name="input">请求原始对象</param>
|
|
|
|
|
|
/// <param name="deviceInfo">设备信息</param>
|
|
|
|
|
|
/// <param name="messageBody">明文消息体</param>
|
2025-09-19 11:36:17 +08:00
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="UserFriendlyException"></exception>
|
|
|
|
|
|
protected DeviceTelemetryPacketTaskInfo GetDeviceTelemetryPacketTaskInfo(IoTDBOptions iotDBOptions, OpenApiRequest input, DeviceCacheInfos deviceInfo,string messageBody)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (iotDBOptions == null || string.IsNullOrWhiteSpace(iotDBOptions.DataBaseName) || input == null || deviceInfo == null || string.IsNullOrWhiteSpace(messageBody))
|
|
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
throw new UserFriendlyException($"设备遥测指令创建失败,参数信息异常。");
|
2025-09-19 11:36:17 +08:00
|
|
|
|
}
|
2025-11-02 00:41:36 +08:00
|
|
|
|
//反序列化消息数据,得到数据实体
|
2025-09-19 11:36:17 +08:00
|
|
|
|
ReceiveCommandInfoDto commandIssueInfo = input.Message.Deserialize<ReceiveCommandInfoDto>();
|
|
|
|
|
|
|
|
|
|
|
|
var oneNETIssueMessageEntity = new DeviceTelemetryPacketTaskInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
DataBaseName = iotDBOptions.DataBaseName,
|
|
|
|
|
|
DeviceType = $"{commandIssueInfo.DeviceType}",
|
|
|
|
|
|
DeviceAddress = commandIssueInfo.DeviceAddress,
|
|
|
|
|
|
IssueRawMessage = input.Serialize(),
|
|
|
|
|
|
IoTDataType = IoTDBDataTypeConst.Command,
|
|
|
|
|
|
TelemetryType = (int)commandIssueInfo.TelemetryType,
|
|
|
|
|
|
TelemetrySource = (int)commandIssueInfo.SourceType,
|
|
|
|
|
|
IoTPlatform = (int)commandIssueInfo.IoTPlatform,
|
|
|
|
|
|
IoTPlatformProductId = deviceInfo.IoTPlatformProductId,
|
|
|
|
|
|
IoTPlatformDeviceOpenInfo = deviceInfo.IoTPlatformDeviceOpenInfo,
|
|
|
|
|
|
IoTPlatformAccountId = deviceInfo.IoTPlatformAccountId,
|
|
|
|
|
|
AccountPhoneNumber = deviceInfo.AccountPhoneNumber,
|
|
|
|
|
|
IoTPlatformProductName = deviceInfo.IoTPlatformProductName,
|
|
|
|
|
|
IssuePayload = messageBody,
|
|
|
|
|
|
RetryCount = 0,
|
2025-10-29 15:19:18 +08:00
|
|
|
|
IssueStatus = (int)DeviceCommandIssueStatusEnum.Unprocessed,
|
|
|
|
|
|
LastIssueTime = DateTime.Now
|
2025-09-19 11:36:17 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return oneNETIssueMessageEntity;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
throw;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-16 17:25:50 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-11-02 00:41:36 +08:00
|
|
|
|
/// 处理开放接口请求
|
2025-10-16 17:25:50 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
2025-11-02 00:41:36 +08:00
|
|
|
|
/// <param name="input">接口请求体</param>
|
|
|
|
|
|
/// <param name="serverOptions">服务配置</param>
|
2025-10-16 17:25:50 +08:00
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
protected HttpDataResult<T> HandleOpenApiRequest<T>(OpenApiRequest input, ServerApplicationOptions serverOptions) where T : class
|
|
|
|
|
|
{
|
2025-10-31 14:58:33 +08:00
|
|
|
|
if (input == null || serverOptions == null || string.IsNullOrWhiteSpace(input.Message) || string.IsNullOrWhiteSpace(input.Nonce) || string.IsNullOrWhiteSpace(input.Signature))
|
2025-10-16 17:25:50 +08:00
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
return HttpDataResultExtensions.Failed<T>(null, "请求参数不能为空", -1101);
|
2025-10-16 17:25:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-02 00:41:36 +08:00
|
|
|
|
if (input.Timestamp <= 946656000000)//时间戳小于2000年,视为错误
|
2025-10-16 17:25:50 +08:00
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
return HttpDataResultExtensions.Failed<T>(null, "时间戳异常", -1102);
|
2025-10-16 17:25:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, serverOptions.SignatureToken);
|
2025-11-02 00:41:36 +08:00
|
|
|
|
if (verifySignatureReult == false)//签名校验失败
|
2025-10-16 17:25:50 +08:00
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
return HttpDataResultExtensions.Failed<T>(null, "签名校验失败", -1103);
|
2025-10-16 17:25:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-02 00:41:36 +08:00
|
|
|
|
//判断是否需要解密
|
2025-10-16 17:25:50 +08:00
|
|
|
|
T messageBody = default;
|
|
|
|
|
|
string tempMessageBody = null;
|
2025-10-17 17:25:33 +08:00
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(input.Message))
|
|
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
return HttpDataResultExtensions.Success(messageBody, "签名校验成功,没有请求体");
|
2025-10-17 17:25:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-16 17:25:50 +08:00
|
|
|
|
if (serverOptions.IsAesEncrypted && !string.IsNullOrWhiteSpace(serverOptions.AesSecurityKey))
|
|
|
|
|
|
{
|
|
|
|
|
|
tempMessageBody = EncryptUtil.OpenApiDecrypto(input.Message, serverOptions.AesSecurityKey);
|
|
|
|
|
|
messageBody = tempMessageBody.Deserialize<T>();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tempMessageBody = input.Message;
|
|
|
|
|
|
messageBody = input.Message.Deserialize<T>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (messageBody == null)
|
|
|
|
|
|
{
|
2025-11-02 00:41:36 +08:00
|
|
|
|
return HttpDataResultExtensions.Failed<T>(null, "获取数据体失败", -1104);
|
2025-10-16 17:25:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return HttpDataResultExtensions.Success(messageBody, tempMessageBody);
|
|
|
|
|
|
}
|
2025-05-27 14:27:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|