diff --git a/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs b/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs index dfcf45f..a113b04 100644 --- a/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs +++ b/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs @@ -31,6 +31,11 @@ namespace JiShe.IoT.BusinessSystemAggregation ServerApplicationOptions serverOptions = options.Value; IoTDBOptions ioTDBOptions = _ioTDBOptions.Value; + private const string LUA_SCRIPT = @" + local hashKey = KEYS[1] + local fieldKeys = ARGV + return redis.call('HMGET', hashKey, unpack(fieldKeys))"; + /// /// 接收业务系统指令信息 /// @@ -118,9 +123,14 @@ namespace JiShe.IoT.BusinessSystemAggregation return HttpDataResultExtensions.Success("指令下发成功"); } + catch (UserFriendlyException) + { + throw; // 重新抛出用户友好异常 + } catch (Exception ex) { - return HttpDataResultExtensions.Failed($"指令处理失败,发送异常:{ex.Message}", -106); + _logger.LogError(ex, "接收业务系统指令信息时发生异常"); + return HttpDataResultExtensions.Failed("指令处理失败,发送异常", -106); } } @@ -147,16 +157,19 @@ namespace JiShe.IoT.BusinessSystemAggregation return HttpDataResultExtensions.Failed>(null, "设备地址不能为空", -103); } - // Lua脚本 - string luaScript = @" - local hashKey = KEYS[1] - local fieldKeys = ARGV - return redis.call('HMGET', hashKey, unpack(fieldKeys))"; + // 验证设备地址格式,防止注入攻击 + foreach (var deviceAddress in messageBody.DeviceAddresses) + { + if (!IsValidDeviceAddress(deviceAddress)) + { + return HttpDataResultExtensions.Failed>(null, $"设备地址格式不正确: {deviceAddress}", -107); + } + } //执行脚本 var result = await FreeRedisProvider.Instance.EvalAsync ( - luaScript, + LUA_SCRIPT, new[] { RedisConst.CacheAllDeviceInfoHashKey }, messageBody.DeviceAddresses.ToArray() ); @@ -168,15 +181,23 @@ namespace JiShe.IoT.BusinessSystemAggregation { foreach (var value in values) { - var tempFocusInfo = ServiceProJsonSerializer.Deserialize(value as string); - deviceCacheInfos.Add(tempFocusInfo); + if (value != null) + { + var tempFocusInfo = ServiceProJsonSerializer.Deserialize(value as string); + deviceCacheInfos.Add(tempFocusInfo); + } + else + { + deviceCacheInfos.Add(null); // 添加空值以保持索引对应 + } } } List queryResult = new List(); - foreach (var deviceAddress in messageBody.DeviceAddresses) + for (int i = 0; i < messageBody.DeviceAddresses.Count; i++) { - var deviceCacheInfo = deviceCacheInfos.FirstOrDefault(x => x.DeviceAddress == deviceAddress); + var deviceAddress = messageBody.DeviceAddresses[i]; + var deviceCacheInfo = deviceCacheInfos.Count > i ? deviceCacheInfos[i] : null; if (deviceCacheInfo == null) { @@ -207,8 +228,8 @@ namespace JiShe.IoT.BusinessSystemAggregation } catch (Exception ex) { - - return HttpDataResultExtensions.Failed>(null, $"查询设备数据失败,发送异常:{ex.Message}", -106); + _logger.LogError(ex, "批量查询设备数据时发生异常"); + return HttpDataResultExtensions.Failed>(null, "查询设备数据失败", -106); } } @@ -235,16 +256,16 @@ namespace JiShe.IoT.BusinessSystemAggregation return HttpDataResultExtensions.Failed>(null, "设备地址不能为空", -103); } - // Lua脚本 - string luaScript = @" - local hashKey = KEYS[1] - local fieldKeys = ARGV - return redis.call('HMGET', hashKey, unpack(fieldKeys))"; + // 验证设备地址格式,防止注入攻击 + if (!IsValidDeviceAddress(messageBody.DeviceAddress)) + { + return HttpDataResultExtensions.Failed>(null, $"设备地址格式不正确: {messageBody.DeviceAddress}", -107); + } //执行脚本 var result = await FreeRedisProvider.Instance.EvalAsync ( - luaScript, + LUA_SCRIPT, new[] { RedisConst.CacheAllDeviceInfoHashKey }, new List() { messageBody.DeviceAddress }.ToArray() ); @@ -256,17 +277,25 @@ namespace JiShe.IoT.BusinessSystemAggregation { foreach (var value in values) { - var tempFocusInfo = ServiceProJsonSerializer.Deserialize(value as string); - deviceCacheInfos.Add(tempFocusInfo); + if (value != null) + { + var tempFocusInfo = ServiceProJsonSerializer.Deserialize(value as string); + deviceCacheInfos.Add(tempFocusInfo); + } + else + { + deviceCacheInfos.Add(null); + } } } List queryResult = new List(); - var deviceCacheInfo = deviceCacheInfos.FirstOrDefault(x => x.DeviceAddress == messageBody.DeviceAddress); + var deviceCacheInfo = deviceCacheInfos.FirstOrDefault(); if (deviceCacheInfo == null) { - _logger.LogError($"{nameof(BatchQueryDeviceDataInfoAsync)} 业务系统单个查询设备数据,设备地址:{messageBody.DeviceAddress}未找到设备地址缓存信息,消息体为:{input.Serialize()}"); + _logger.LogError($"{nameof(QueryDeviceDataInfoAsync)} 业务系统单个查询设备数据,设备地址:{messageBody.DeviceAddress}未找到设备地址缓存信息,消息体为:{input.Serialize()}"); + return HttpDataResultExtensions.Failed>(null, "设备信息不存在", -108); } var pageResult = await treeModelService.OpenRequestDeviceDataInfoPageAsync(new DeviceTreeModelDataInfoInput() @@ -292,8 +321,8 @@ namespace JiShe.IoT.BusinessSystemAggregation } catch (Exception ex) { - - return HttpDataResultExtensions.Failed>(null, $"查询设备数据失败,发送异常:{ex.Message}", -106); + _logger.LogError(ex, "查询单个设备数据时发生异常"); + return HttpDataResultExtensions.Failed>(null, "查询设备数据失败", -106); } } @@ -334,8 +363,26 @@ namespace JiShe.IoT.BusinessSystemAggregation } catch (Exception ex) { - return HttpDataResultExtensions.Failed($"查询设备数据失败,发送异常:{ex.Message}", -106); + _logger.LogError(ex, "批量新增设备数据时发生异常"); + return HttpDataResultExtensions.Failed("新增设备失败", -106); } } + + /// + /// 验证设备地址格式是否合法 + /// + /// 设备地址 + /// 是否合法 + private bool IsValidDeviceAddress(string deviceAddress) + { + if (string.IsNullOrWhiteSpace(deviceAddress)) + return false; + + // 可根据实际业务规则调整验证逻辑 + // 这里简单检查是否包含非法字符 + return !deviceAddress.Contains("..") && + !deviceAddress.Contains("*") && + !deviceAddress.Contains("~"); + } } -} +} \ No newline at end of file diff --git a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs index 5315403..3b8ce46 100644 --- a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs +++ b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs @@ -276,8 +276,10 @@ namespace JiShe.IoT.DeviceAggregation UpdateDeviceInput updateDeviceInput = input.Adapt(); updateDeviceInput.IoTPlatformResponse = pushResult.Serialize(); updateDeviceInput.IsPlatformPushSuccess = true; - updateDeviceInput.PlatformPassword = platformPassword; - + if (!string.IsNullOrWhiteSpace(updateDeviceInput.PlatformPassword)) + { + updateDeviceInput.PlatformPassword = platformPassword; + } var updateResult = await deviceAppService.UpdateAsync(updateDeviceInput); if (updateResult == null) @@ -799,28 +801,29 @@ namespace JiShe.IoT.DeviceAggregation IoTPlatformProductId = input.IoTPlatformProductId, }); - foreach (var item in input.AddressList) + foreach (var item in input.DeviceInfos) { if (checkDevicesInfos != null) { - if (checkDevicesInfos.Any(e => e.DeviceAddress == item)) + + var checkDevices = checkDevicesInfos.Where(e => e.DeviceAddress == item.DeviceAddress).FirstOrDefault(); + + if (checkDevices != null && checkDevices.IsPlatformPushSuccess) { - logger.LogError($"{nameof(OneNETDeviceBatchCreateAsync)} 平台{input.IoTPlatform} 产品 {input.IoTPlatformProductId} 下设备信息已存在:{item}"); + logger.LogError($"{nameof(OneNETDeviceBatchCreateAsync)} 平台{input.IoTPlatform} 产品 {input.IoTPlatformProductId} 下设备信息已存在:{item.DeviceAddress}"); continue; } } CreateDeviceInput createDeviceInput = input.Adapt(); - createDeviceInput.DeviceName = item; - createDeviceInput.DeviceAddress = item; + createDeviceInput.DeviceName = item.DeviceAddress; + createDeviceInput.DeviceAddress = item.DeviceAddress; createDeviceInput.IoTPlatformAccountId = productInfo.OneNETAccountId; - createDeviceInput.IoTPlatformDeviceOpenInfo = $"{input.IoTPlatformProductId}{item}"; + createDeviceInput.IoTPlatformDeviceOpenInfo = $"{input.IoTPlatformProductId}{item.DeviceAddress}"; createDeviceInput.PlatformPassword = productInfo.ProductAccesskey; createDeviceInput.IoTPlatformProductName = productInfo.ProductName; createDeviceInput.AccountPhoneNumber = productInfo.AccountPhoneNumber; - createDeviceInput.DeviceSourceType = input.DeviceSourceType.Value; - createDeviceInput.DeviceType = input.DeviceType.Value; if (input.DeviceSourceType.HasValue) { @@ -832,45 +835,58 @@ namespace JiShe.IoT.DeviceAggregation createDeviceInput.DeviceType = input.DeviceType.Value; } + if(item.BusinessSystemDeviceDataId.HasValue) + { + createDeviceInput.BusinessSystemDeviceDataId = item.BusinessSystemDeviceDataId.Value; + } + batchCreateDeviceInput.DeviceInputs.Add(createDeviceInput); } - var insertResult = await deviceAppService.BatchCreateAsync(batchCreateDeviceInput); - if (insertResult == null) + if(batchCreateDeviceInput.DeviceInputs != null || batchCreateDeviceInput.DeviceInputs.Count > 0) { - logger.LogError($"{nameof(OneNETDeviceBatchCreateAsync)} OneNET设备批量创建添加设备信息失败:{input.Serialize()}"); - return false; - } - //推送至OneNET平台 - var oneNETBatchCreateDeviceInfoInput = new BatchCreateDeviceInfoInput() - { - ProductId = productInfo.IoTPlatformProductId, - OneNETAccountId = productInfo.OneNETAccountId, - DeviceList = new List() - }; - oneNETBatchCreateDeviceInfoInput.DeviceList = batchCreateDeviceInput.DeviceInputs.Select(d => d.IoTPlatformDeviceOpenInfo).ToList(); - - var pushResult = await oneNETDeviceService.BatchCreateDeviceInfoAsync(oneNETBatchCreateDeviceInfoInput); - - if (pushResult == null || pushResult.Code != ServicePro.Enums.ResponeResultEnum.Success) - { - logger.LogError($"{nameof(CreateDeviceForApiAsync)} 推送设备信息失败:{pushResult.Serialize()}"); - return false; - } - - //更新OneNET平台推送结果 - foreach (var item in insertResult) - { - var successEntity = pushResult.Data.Successlist.Where(d => d.DeviceName == item.IoTPlatformDeviceOpenInfo).FirstOrDefault(); - if (successEntity != null) + var insertResult = await deviceAppService.BatchCreateAsync(batchCreateDeviceInput); + if (insertResult == null) { - await DeviceUpdateHandler(item, HttpDataResultExtensions.Success(successEntity), successEntity.SecurityKey); + logger.LogError($"{nameof(OneNETDeviceBatchCreateAsync)} OneNET设备批量创建添加设备信息失败:{input.Serialize()}"); + return false; + } + //网关或者直连设备 推送至OneNET平台 + var oneNETBatchCreateDeviceInfoInput = new BatchCreateDeviceInfoInput() + { + ProductId = productInfo.IoTPlatformProductId, + OneNETAccountId = productInfo.OneNETAccountId, + DeviceList = new List() + }; + + oneNETBatchCreateDeviceInfoInput.DeviceList = batchCreateDeviceInput.DeviceInputs.Select(d => d.IoTPlatformDeviceOpenInfo).ToList(); + + var pushResult = await oneNETDeviceService.BatchCreateDeviceInfoAsync(oneNETBatchCreateDeviceInfoInput); + + if (pushResult == null || pushResult.Code != ServicePro.Enums.ResponeResultEnum.Success) + { + logger.LogError($"{nameof(CreateDeviceForApiAsync)} 推送设备信息失败:{pushResult.Serialize()}"); + return false; + } + + //更新OneNET平台推送结果 + foreach (var item in insertResult) + { + var successEntity = pushResult.Data.Successlist.Where(d => d.DeviceName == item.IoTPlatformDeviceOpenInfo).FirstOrDefault(); + if (successEntity != null) + { + await DeviceUpdateHandler(item, HttpDataResultExtensions.Success(successEntity), successEntity.SecurityKey); + } } } + //处理子设备 + + + return true; } catch (Exception)