diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
index 34b4f4b..dfe442d 100644
--- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
@@ -730,7 +730,7 @@ namespace JiShe.CollectBus.IoTDB.Provider
object rawValue = item1Member.Getter(obj);
string value = rawValue?.ToString();
- if (!string.IsNullOrEmpty(value))
+ if (!string.IsNullOrWhiteSpace(value))
{
// 规则1: 严格检查ASCII字母和数字(0-9, A-Z, a-z)
bool hasInvalidChars = value.Any(c =>
diff --git a/services/JiShe.CollectBus.Application.Contracts/RedisDataCache/IRedisDataCacheService.cs b/services/JiShe.CollectBus.Application.Contracts/RedisDataCache/IRedisDataCacheService.cs
index dc7c14e..b5f492c 100644
--- a/services/JiShe.CollectBus.Application.Contracts/RedisDataCache/IRedisDataCacheService.cs
+++ b/services/JiShe.CollectBus.Application.Contracts/RedisDataCache/IRedisDataCacheService.cs
@@ -123,7 +123,7 @@ namespace JiShe.CollectBus.Application.Contracts
/// 最后一个唯一标识
/// 排序方式
///
- Task> GetPagedData(
+ Task> GetSingleData(
string redisHashCacheKey,
string redisZSetScoresIndexCacheKey,
string scoreValueRawData,
diff --git a/services/JiShe.CollectBus.Application/RedisDataCache/RedisDataCacheService.cs b/services/JiShe.CollectBus.Application/RedisDataCache/RedisDataCacheService.cs
index e413527..ebf1d2b 100644
--- a/services/JiShe.CollectBus.Application/RedisDataCache/RedisDataCacheService.cs
+++ b/services/JiShe.CollectBus.Application/RedisDataCache/RedisDataCacheService.cs
@@ -42,8 +42,6 @@ namespace JiShe.CollectBus.RedisDataCache
Instance = _freeRedisProvider.Instance;
}
- //todo 单个数据查询
-
///
/// 单个添加数据
///
@@ -370,7 +368,7 @@ namespace JiShe.CollectBus.RedisDataCache
///
- /// 通过集中器与表计信息排序索引获取数据
+ /// 通过集中器与表计信息排序索引获取单个数据
///
///
/// 主数据存储Hash缓存Key
@@ -381,24 +379,105 @@ namespace JiShe.CollectBus.RedisDataCache
/// 最后一个唯一标识
/// 排序方式
///
- public async Task> GetPagedData(
- string redisHashCacheKey,
- string redisZSetScoresIndexCacheKey,
- string scoreValueRawData,
- int pageSize = 10,
- decimal? lastScore = null,
- string lastMember = null,
- bool descending = true)
- where T : DeviceCacheBasicModel
+ public async Task> GetSingleData(
+ string redisHashCacheKey,
+ string redisZSetScoresIndexCacheKey,
+ string scoreValueRawData,
+ int pageSize = 10,
+ decimal? lastScore = null,
+ string lastMember = null,
+ bool descending = true)
+ where T : DeviceCacheBasicModel
{
- var rawDataArray = scoreValueRawData.Split(":");
- string focusAddress = rawDataArray[0];
- string point = rawDataArray[1];
+ // 参数校验
+ if (string.IsNullOrWhiteSpace(redisHashCacheKey) ||
+ string.IsNullOrWhiteSpace(redisZSetScoresIndexCacheKey) ||
+ string.IsNullOrWhiteSpace(scoreValueRawData))
+ {
+ _logger.LogError($"{nameof(GetSingleData)} 参数异常,-101");
+ return new BusCacheGlobalPagedResult { Items = new List() };
+ }
- long scoreValue = 0;
+ // 解析原始数据
+ var rawDataArray = scoreValueRawData.Split(':');
+ if (rawDataArray.Length != 2)
+ {
+ _logger.LogError($"{nameof(GetSingleData)} scoreValueRawData格式错误,应为[focusAddress:point]");
+ return new BusCacheGlobalPagedResult { Items = new List() };
+ }
+ // 计算Score值
+ long scoreValue;
+ try
+ {
+ var focusAddress = rawDataArray[0];
+ var point = Convert.ToInt32(rawDataArray[1]);
+ scoreValue = CommonHelper.GetFocusScores(focusAddress, point);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"{nameof(GetSingleData)} 计算Score值失败");
+ return new BusCacheGlobalPagedResult { Items = new List() };
+ }
- throw new Exception();
+ // Lua脚本:原子化查询操作
+ const string luaScript = @"
+ local zsetKey = KEYS[1]
+ local hashKey = KEYS[2]
+ local targetScore = ARGV[1]
+
+ -- 精确匹配Score并获取第一个成员
+ local members = redis.call('ZRANGEBYSCORE', zsetKey, targetScore, targetScore, 'LIMIT', 0, 1)
+ if #members == 0 then
+ return nil
+ end
+
+ -- 获取哈希表数据
+ local member = members[1]
+ local data = redis.call('HGET', hashKey, member)
+ return {member, data}";
+
+ try
+ {
+ // 执行脚本
+ var result = await Instance.EvalAsync(
+ luaScript,
+ new[] { redisZSetScoresIndexCacheKey, redisHashCacheKey },
+ new object[] { scoreValue });
+
+ // 处理空结果
+ if (result == null)
+ return new BusCacheGlobalPagedResult { Items = new List() };
+
+ // 解析Redis返回数据
+ var resultArray = (object[])result;
+ var memberId = (string)resultArray[0];
+ var dataStr = (string)resultArray[1];
+
+ // 反序列化数据
+ var data = BusJsonSerializer.Deserialize(dataStr);
+ if (data == null)
+ {
+ _logger.LogError($"{nameof(GetSingleData)} 反序列化失败,MemberId: {memberId}");
+ return new BusCacheGlobalPagedResult { Items = new List() };
+ }
+
+ // 构造返回结果
+ return new BusCacheGlobalPagedResult
+ {
+ Items = new List { data },
+ TotalCount = 1,
+ PageSize = 1,
+ HasNext = false,
+ NextScore = null,
+ NextMember = null
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"{nameof(GetSingleData)} Redis操作异常");
+ return new BusCacheGlobalPagedResult { Items = new List() };
+ }
}
///
@@ -559,67 +638,7 @@ namespace JiShe.CollectBus.RedisDataCache
PageSize = pageSize,
};
}
-
- /////
- ///// 通过集中器与表计信息排序索引获取数据
- /////
- /////
- ///// 主数据存储Hash缓存Key
- ///// ZSET索引缓存Key
- ///// 分页尺寸
- ///// 最后一个索引
- ///// 最后一个唯一标识
- ///// 排序方式
- /////
- //public async Task> GetAllPagedData(
- //string redisHashCacheKey,
- //string redisZSetScoresIndexCacheKey,
- //int pageSize = 1000,
- //decimal? lastScore = null,
- //string lastMember = null,
- //bool descending = true)
- //where T : DeviceCacheBasicModel
- //{
- // // 参数校验增强
- // if (string.IsNullOrWhiteSpace(redisHashCacheKey) || string.IsNullOrWhiteSpace(redisZSetScoresIndexCacheKey))
- // {
- // _logger.LogError($"{nameof(GetAllPagedData)} 参数异常,-101");
- // return null;
- // }
-
- // if (pageSize < 1 || pageSize > 10000)
- // {
- // _logger.LogError($"{nameof(GetAllPagedData)} 分页大小应在1-10000之间,-102");
- // return null;
- // }
-
- // //// 分页参数解析
- // //var (startScore, excludeMember) = descending
- // // ? (lastScore ?? decimal.MaxValue, lastMember)
- // // : (lastScore ?? 0, lastMember);
-
- // //执行分页查询(整合游标处理)
- // var pageResult = await GetPagedMembers(
- // redisZSetScoresIndexCacheKey,
- // pageSize,
- // lastScore,
- // lastMember,
- // descending);
-
- // // 批量获取数据(优化内存分配)
- // var dataDict = await BatchGetData(redisHashCacheKey, pageResult.Members);
-
- // return new BusCacheGlobalPagedResult
- // {
- // Items = pageResult.Members.Select(m => dataDict.TryGetValue(m, out var v) ? v : default)
- // .Where(x => x != null).ToList(),
- // HasNext = pageResult.HasNext,
- // NextScore = pageResult.NextScore,
- // NextMember = pageResult.NextMember,
- // TotalCount = await GetTotalCount(redisZSetScoresIndexCacheKey),
- // PageSize = pageSize,
- // };
- //}
+
///
/// 游标分页查询
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index 9d45f08..270bb67 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -737,7 +737,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
ItemCode = tempItem,
DataTimeMark = new Protocol.DataTimeMark()
{
- Density = ammeterInfo.TimeDensity.GetDensity(),//转换成协议的值
+ Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值
Point = 1,
DataTime = timestamps,
}
diff --git a/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs
index 60d6c91..4cd69ba 100644
--- a/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs
+++ b/services/JiShe.CollectBus.Domain/IotSystems/Ammeters/AmmeterInfo.cs
@@ -20,7 +20,7 @@ namespace JiShe.CollectBus.IotSystems.Ammeters
/// ZSet排序索引分数值,具体值可以根据不同业务场景进行定义,例如时间戳
///
[Column(IsIgnore = true)]
- public override long ScoreValue => ((long)FocusId << 32) | (uint)DateTime.Now.Ticks;
+ public override long ScoreValue => Common.Helpers.CommonHelper.GetFocusScores(FocusAddress,MeteringCode);
///
/// 电表名称
diff --git a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs
index e3177a1..7d3fc4a 100644
--- a/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs
+++ b/shared/JiShe.CollectBus.Common/Helpers/CommonHelper.cs
@@ -10,6 +10,8 @@ using System.Text;
using System.Threading.Tasks;
using JiShe.CollectBus.Common.Attributes;
using System.Collections.Specialized;
+using JiShe.CollectBus.Common.Enums;
+using Newtonsoft.Json.Linq;
namespace JiShe.CollectBus.Common.Helpers
{
@@ -796,7 +798,7 @@ namespace JiShe.CollectBus.Common.Helpers
///
///
///
- public static string GetTaskMark(int afn, int fn, int pn, int msa,int seq)
+ public static string GetTaskMark(int afn, int fn, int pn, int msa, int seq)
{
var makstr = $"{afn.ToString().PadLeft(2, '0')}{fn.ToString().PadLeft(2, '0')}{pn.ToString().PadLeft(2, '0')}{msa.ToString().PadLeft(2, '0')}{seq.ToString().PadLeft(2, '0')}";
@@ -860,20 +862,53 @@ namespace JiShe.CollectBus.Common.Helpers
}
///
- /// 采集频率转换为集中器采集密度
+ /// 系统采集频率转换为集中器采集密度
///
///
///
- public static int GetDensity(this int timeDensity) =>
- timeDensity switch
- {
- 0 => 0,//无
- 1 => 255,//1分钟
- 5 => 245,//5分钟
- 15 => 1,//15分钟
- 30 => 2,//30分钟
- 60 => 3,//60分钟
- _ => -1//采集项本身无密度位
- };
+ public static int GetFocusDensity(this int timeDensity) => timeDensity switch
+ {
+ 0 => 0,//无
+ 1 => 255,//1分钟
+ 5 => 245,//5分钟
+ 15 => 1,//15分钟
+ 30 => 2,//30分钟
+ 60 => 3,//60分钟
+ _ => -1//采集项本身无密度位
+ };
+
+ ///
+ /// 集中器采集密度转换为系统采集频率
+ ///
+ ///
+ ///
+ public static int GetSystemDensity(this int density) => density switch
+ {
+ 0 => 0,//无
+ 255 => 1,//1分钟
+ 245 => 5,//5分钟
+ 1 => 15,//15分钟
+ 2 => 30,//30分钟
+ 3 => 60,//60分钟
+ _ => -1//采集项本身无密度位
+ };
+
+ ///
+ /// 获取集中器ZSet Scores
+ ///
+ ///
+ ///
+ ///
+ public static long GetFocusScores(string focusScores, int point)
+ {
+ bool hasInvalidChars = focusScores.Any(c => !(c >= '0' && c <= '9'));
+ if (hasInvalidChars)
+ {
+ throw new Exception($"{nameof(GetFocusScores)} 集中器地址格式错误");
+ }
+ var scoresStr = $"{focusScores}{point.ToString().PadLeft(2, '0')}";
+
+ return Convert.ToInt64(scoresStr);
+ }
}
}