diff --git a/HealthMonitor.Common/DateTimeUtil.cs b/HealthMonitor.Common/DateTimeUtil.cs
new file mode 100644
index 0000000..173e270
--- /dev/null
+++ b/HealthMonitor.Common/DateTimeUtil.cs
@@ -0,0 +1,710 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HealthMonitor.Common
+{
+ public class DateTimeUtil
+ {
+
+ ///
+ /// 毫秒时间戳转本地时间
+ ///
+ ///
+ ///
+ public static DateTime GetDateTimeFromUnixTimeMilliseconds(long milliseconds)
+ {
+ DateTimeOffset dt0 = DateTimeOffset.FromUnixTimeMilliseconds(milliseconds);
+
+ //默认为UTC时间:{2019/11/14 1:53:26}
+ //DateTime dt1 = dt0.DateTime;
+
+ //转为本地时区:{2019/11/14 9:53:26}
+ DateTime dt2 = dt0.LocalDateTime;
+ return dt2;
+ }
+
+ ///
+ /// 判断给定的日期时间字符串是否符合相应的格式
+ ///
+ /// 日期时间字符串
+ /// 是否符合格式
+ public static bool IsDateTime(string strDate)
+ {
+ if (strDate.Length != 19)
+ return false;
+
+ try
+ {
+ DateTime dt = DateTime.Parse(strDate);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// 得到当前月的第一天
+ ///
+ /// 当前月的第一天
+ public static string ThisMonthFirstDate
+ {
+ get
+ {
+ DateTime dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
+ return dt.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ }
+
+ ///
+ /// 得到当前月的最后一天
+ ///
+ /// 当前月的最后一天
+ public static string ThisMonthLastDate
+ {
+ get
+ {
+ DateTime dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month + 1, 1);
+ dt = dt.AddDays(-1);
+ return dt.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ }
+
+ ///
+ /// 指定日期的该月第一天
+ ///
+ /// 指定的日期
+ /// 该月第一天
+ public static string MonthFirstDate(string sThisDate)
+ {
+ int nYear = Year(sThisDate);
+ int nMonth = Month(sThisDate);
+ int nDay = 1;
+
+ return EncodeDate(nYear, nMonth, nDay) + " 00:00:00";
+ }
+
+ ///
+ /// 指定日期的该月最后一天
+ ///
+ /// 指定的日期
+ /// 该月最后一天
+ public static string MonthLastDate(string sThisDate)
+ {
+ int nYear = Year(sThisDate);
+ int nMonth = Month(sThisDate);
+
+ nMonth++;
+ if (nMonth == 13)
+ {
+ nYear++;
+ nMonth = 1;
+ }
+
+ DateTime dt = new DateTime(nYear, nMonth, 1);
+ dt = dt.AddDays(-1);
+ return dt.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ ///
+ /// 转换字符串类型的时间至日期时间类型
+ ///
+ /// 时间字符串
+ /// 日期时间类型的值
+ /// 如果格式不正确,则返回当前的时间
+ public static DateTime ToDateTime(string strDateTime)
+ {
+ try
+ {
+ return DateTime.Parse(strDateTime);
+ }
+ catch
+ {
+ return DateTime.Now;
+ }
+ }
+
+ ///
+ /// 转换时间类型的字符串至日期时间类型
+ ///
+ /// 时间字符串
+ /// 时间值
+ /// 如果格式不正确,则返回的是"00:00:00"的时间值
+ public static DateTime ToTime(string strTime)
+ {
+ try
+ {
+ return DateTime.Parse(strTime);
+ }
+ catch
+ {
+ return DateTime.Parse("00:00:00");
+ }
+ }
+
+ ///
+ /// 将时间值转换至时间字符串
+ ///
+ /// 时间值
+ /// 时间字符串
+ public static string ToTimeStr(DateTime time)
+ {
+ return time.ToString("HH:mm:ss");
+ }
+
+ ///
+ /// 将对象转换为指定格式的字符串
+ ///
+ /// 待转换的对象
+ /// 指定的字符串格式
+ /// 转换后的字符串
+ /// 如果为空值,或非日期时间对象,则返回""
+ public static string ToTimeStr(object time, string sFormat)
+ {
+ if (time == null || time == DBNull.Value)
+ return "";
+ else
+ {
+ try
+ {
+ return ((DateTime)time).ToString(sFormat);
+ }
+ catch
+ {
+ return "";
+ }
+ }
+ }
+
+ ///
+ /// 将对象转换为字符串,格式为"HH:mm:ss"
+ ///
+ /// 待转换的对象
+ /// 转换后的字符串
+ public static string ToTimeStr(object time)
+ {
+ return ToTimeStr(time, "HH:mm:ss");
+ }
+
+ ///
+ /// 从秒数转换为时间字符串
+ ///
+ /// 秒数
+ /// 时间字符串
+ public static string ToTimeStrFromSecond(int Second)
+ {
+ //=========== 1. 得到小时、分钟和秒数 ===========
+ string sTimeStr = "";
+
+ int NewSecond = 0;
+ int hour = Math.DivRem(Second, 3600, out NewSecond); //小时
+
+ Second = NewSecond;
+ NewSecond = 0;
+ int minute = Math.DivRem(Second, 60, out NewSecond); //分钟
+
+ //============ 2. 得到返回的字符串 ============
+ if (hour < 10)
+ sTimeStr = sTimeStr + "0" + hour.ToString() + ":";
+ else
+ sTimeStr = sTimeStr + hour.ToString() + ":";
+
+ if (minute < 10)
+ sTimeStr = sTimeStr + "0" + minute.ToString() + ":";
+ else
+ sTimeStr = sTimeStr + minute.ToString() + ":";
+
+ if (NewSecond < 10)
+ sTimeStr = sTimeStr + "0" + NewSecond.ToString();
+ else
+ sTimeStr = sTimeStr + NewSecond.ToString();
+
+ return sTimeStr;
+ }
+
+ ///
+ /// 将时间字符串转换为秒数
+ ///
+ /// 时间字符串
+ /// 转换后的秒数
+ public static int ToSecondsFromTimeStr(string timeStr)
+ {
+ DateTime dt = ToTime(timeStr);
+ return dt.Hour * 3600 + dt.Minute * 60 + dt.Second;
+ }
+
+ ///
+ /// 将日期时间值转换为日期字符串
+ ///
+ /// 日期时间值
+ /// 日期字符串
+ public static string ToDateStr(DateTime dt)
+ {
+ return dt.ToString("yyyy-MM-dd");
+ }
+
+ ///
+ /// 将对象转换为日期字符串
+ ///
+ /// 对象
+ /// 缺省字符串
+ /// 转换后的字符串。如果为空值,则按缺省值返回
+ public static string ToDateStr(object dt, string defaultStr)
+ {
+ if (dt == null || dt is System.DBNull)
+ return defaultStr;
+ else
+ return ((DateTime)dt).ToString("yyyy-MM-dd");
+ }
+
+ ///
+ /// 将对象转换为日期字符串
+ ///
+ /// 对象
+ /// 转换后的字符串。如果转换不成功,则返回""
+ public static string ToDateStr(object dt)
+ {
+ return ToDateStr(dt, "");
+ }
+
+ ///
+ /// 将日期时间值转换为字符串
+ ///
+ /// 日期时间值
+ /// 字符串(len=19)
+ public static string ToDateTimeStr(DateTime dt)
+ {
+ return dt.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ public static string ToDateTimeStrWithMilliSeconds(DateTime dt)
+ {
+ int nMilliSeconds = dt.Millisecond;
+ return dt.ToString("yyyy-MM-dd HH:mm:ss") + "." + nMilliSeconds.ToString("000");
+ }
+
+ ///
+ /// 将对象转换为日期时间字符串
+ ///
+ /// 对象
+ /// 转换不成功时所取的缺省字符串
+ /// 转换后的日期时间字符串(len=19)
+ public static string ToDateTimeStr(object dt, string defaultStr)
+ {
+ return ToDateTimeStr(dt, defaultStr, "yyyy-MM-dd HH:mm:ss");
+ }
+
+ ///
+ /// 将对象转换为日期时间字符串
+ ///
+ /// 对象
+ /// 转换后的日期时间字符串(len=19)
+ /// 如果转换不成功,则返回""
+ public static string ToDateTimeStr(object dt)
+ {
+ return ToDateTimeStr(dt, "", "yyyy-MM-dd HH:mm:ss");
+ }
+
+ ///
+ /// 将对象转换为指定格式的日期时间字符串
+ ///
+ /// 对象
+ /// 缺省字符串
+ /// 格式
+ /// 转换后的字符串
+ public static string ToDateTimeStr(object dt, string defaultStr, string sFormat)
+ {
+ if (dt == null || dt is System.DBNull)
+ return defaultStr;
+ else
+ return ((DateTime)dt).ToString(sFormat);
+ }
+
+
+ ///
+ /// 获取当前的时间
+ ///
+ public static string Now
+ {
+ get
+ {
+ return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ }
+
+ ///
+ /// 带毫秒部分的当前时间,示例为2003.07.22 10:02:52.136
+ ///
+ public static string NowWithMilliSeconds
+ {
+ get
+ {
+ DateTime dtNow = DateTime.Now;
+ int nMilliSeconds = dtNow.Millisecond;
+ return dtNow.ToString("yyyy-MM-dd HH:mm:ss") + "." + nMilliSeconds.ToString("000");
+ }
+ }
+
+ ///
+ /// 获取当前的时间
+ ///
+ public static string Today
+ {
+ get
+ {
+ return DateTime.Today.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ }
+
+ ///
+ /// 获取日期的年份
+ ///
+ /// 日期时间串
+ /// 年份
+ public static int Year(string dtString)
+ {
+ int nYear;
+
+ nYear = Convert.ToInt32(dtString.Substring(0, 4));
+
+ return nYear;
+ }
+
+ ///
+ /// 获取日期的月份
+ ///
+ /// 日期时间串
+ /// 月份
+ public static int Month(string dtString)
+ {
+ int nMonth;
+
+ nMonth = Convert.ToInt32(dtString.Substring(5, 2));
+
+ return nMonth;
+ }
+
+ ///
+ /// 获取日期中该月的第几天
+ ///
+ /// 日期时间串
+ /// 该月的第几天
+ public static int Day(string dtString)
+ {
+ int nDay;
+
+ nDay = Convert.ToInt32(dtString.Substring(8, 2));
+
+ return nDay;
+ }
+
+ ///
+ /// 获取日期中的小时部分
+ ///
+ /// 日期时间串
+ /// 小时部分
+ public static int Hour(string dtString)
+ {
+ int nHour;
+
+ if (dtString.Length != 19 && dtString.Length != 23)
+ return 0;
+
+ nHour = Convert.ToInt32(dtString.Substring(11, 2));
+
+ return nHour;
+ }
+
+ ///
+ /// 获取日期中的分钟部分
+ ///
+ /// 日期时间串
+ /// 分钟部分
+ public static int Minute(string dtString)
+ {
+ int nMinute;
+
+ if (dtString.Length != 19 && dtString.Length != 23)
+ return 0;
+
+ nMinute = Convert.ToInt32(dtString.Substring(14, 2));
+
+ return nMinute;
+ }
+
+ ///
+ /// 获取日期中的秒部分
+ ///
+ /// 日期时间串
+ /// 秒部分
+ public static int Second(string dtString)
+ {
+ int nSecond;
+
+ if (dtString.Length != 19 && dtString.Length != 23)
+ return 0;
+
+ nSecond = Convert.ToInt32(dtString.Substring(17, 2));
+
+ return nSecond;
+ }
+
+ ///
+ /// 获取表示的日期是星期几
+ ///
+ /// 日期时间串
+ /// 星期几
+ /// 返回值从0至6;星期日为0,星期六为6
+ public static int DayOfWeek(string dtString)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ return (int)dt.DayOfWeek;
+ }
+
+ ///
+ /// 获取表示的日期是一年中的第几天
+ ///
+ /// 日期时间串
+ /// 一年中的第几天
+ public static int DayOfYear(string dtString)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ return dt.DayOfYear;
+ }
+
+ ///
+ /// 将指定的月份数加到日期值上
+ ///
+ /// 原来的日期
+ /// 指定的月份数
+ /// 得到的日期
+ public static string AddMonths(string dtString, int nOffset)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ DateTime dtRes = dt.AddMonths(nOffset);
+ return dtRes.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ ///
+ /// 将指定的天数加到日期值上
+ ///
+ /// 原来的日期
+ /// 指定的天数
+ /// 得到的日期
+ /// 天数可以为负数
+ public static string AddDays(string dtString, int offset)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ DateTime dtRes = dt.AddDays(offset);
+ return dtRes.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ ///
+ /// 将指定的秒数加到日期值上
+ ///
+ /// 原来的日期时间
+ /// 指定的秒数
+ /// 得到的日期时间
+ /// 秒数可以为负数
+ public static string AddSeconds(string dtString, int offset)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ DateTime dtRes = dt.AddSeconds(offset);
+ return dtRes.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ public static string AddMilliSeconds(string dtString, int offset)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ DateTime dtRes = dt.AddMilliseconds(offset);
+
+ int nMilliSeconds = dtRes.Millisecond;
+ return dtRes.ToString("yyyy-MM-dd HH:mm:ss") + "." + nMilliSeconds.ToString("000");
+ }
+
+ public static string AddMilliSeconds(string dtString, double offset)
+ {
+ DateTime dt = DateTime.Parse(dtString);
+ DateTime dtRes = dt.AddMilliseconds(offset);
+
+ int nMilliSeconds = dtRes.Millisecond;
+ return dtRes.ToString("yyyy-MM-dd HH:mm:ss") + "." + nMilliSeconds.ToString("000");
+ }
+
+ ///
+ /// 得到两个日期时间之间相差的天数
+ ///
+ /// 起始日期
+ /// 终止日期
+ /// 相差的天数
+ ///
+ /// 不判断时间的情况。只判断日期是否切换,即使时间相差仅数分钟,
+ /// 只要切换了日期,也计算相差的天数。例如,2005-05-05 23:58:58和
+ /// 2005-05-06 00:02:03之间所差的天数也是1。
+ ///
+ public static int DaysAfter(string dtFromString, string dtToString)
+ {
+ DateTime dtFrom = DateTime.Parse(dtFromString).Date;
+ DateTime dtTo = DateTime.Parse(dtToString).Date;
+ TimeSpan timeSpan = dtTo - dtFrom;
+ return (int)timeSpan.TotalDays;
+ }
+
+ ///
+ /// 得到两个日期时间之间相差的秒数
+ ///
+ /// 起始日期时间
+ /// 终止日期时间
+ /// 相差的秒数
+ public static int SecondsAfter(string dtFromString, string dtToString)
+ {
+ DateTime dtFrom = DateTime.Parse(dtFromString);
+ DateTime dtTo = DateTime.Parse(dtToString);
+ TimeSpan timeSpan = dtTo - dtFrom;
+ return (int)timeSpan.TotalSeconds;
+ }
+
+ ///
+ /// 得到两个日期时间之间相差的毫秒数
+ ///
+ /// 起始日期时间
+ /// 终止日期时间
+ /// 相差的毫秒数
+ public static int MilliSecondsAfter(string dtFromString, string dtToString)
+ {
+ DateTime dtFrom = DateTime.Parse(dtFromString);
+ DateTime dtTo = DateTime.Parse(dtToString);
+ TimeSpan timeSpan = dtTo - dtFrom;
+ return (int)timeSpan.TotalMilliseconds;
+ }
+
+ ///
+ /// 通过时、分、秒得到时间串
+ ///
+ /// 小时
+ /// 分钟
+ /// 秒
+ /// 时间部分
+ public static string EncodeTime(int nHour, int nMinute, int nSecond)
+ {
+ string sResult = nHour.ToString("00") + ":" + nMinute.ToString("00")
+ + ":" + nSecond.ToString("00");
+ return sResult;
+ }
+
+ ///
+ /// 通过年、月、日得到日期部分
+ ///
+ /// 年份
+ /// 月份
+ /// 日
+ /// 日期部分
+ public static string EncodeDate(int nYear, int nMonth, int nDay)
+ {
+ string sResult = nYear.ToString("0000") + "-" + nMonth.ToString("00")
+ + "-" + nDay.ToString("00");
+ return sResult;
+ }
+
+ ///
+ /// 得到日期部分
+ ///
+ /// 日期时间
+ /// 日期部分
+ public static string GetDatePart(string sDatetime)
+ {
+ if (sDatetime.Length < 10)
+ return "";
+ return sDatetime.Substring(0, 10);
+ }
+
+ ///
+ /// 得到时间部分
+ ///
+ /// 日期时间
+ /// 时间部分
+ public static string GetTimePart(string sDatetime)
+ {
+ if (sDatetime.Length == 19)
+ return sDatetime.Substring(11, 8);
+ else
+ return "00:00:00";
+ }
+
+ ///
+ /// 得到一天的起始时间
+ ///
+ /// 日期
+ /// 起始时间
+ public static string BeginTimeOfDay(string sDate)
+ {
+ if (sDate.Length > 10)
+ sDate = sDate.Substring(0, 10);
+ return sDate + " 00:00:00";
+ }
+
+ ///
+ /// 得到一天的结束时间
+ ///
+ /// 日期
+ /// 结束时间
+ public static string EndTimeOfDay(string sDate)
+ {
+ if (sDate.Length > 10)
+ sDate = sDate.Substring(0, 10);
+ return sDate + " 23:59:59.999";
+ }
+ ///
+ /// 由19位的日期时间转到14位的日期时间
+ ///
+ /// 19位的日期时间
+ /// 14位的日期时间
+ public static string ToDateTime14Str(string sDT)
+ {
+ if (sDT == "")
+ return "";
+
+ if (sDT.Length != 19)
+ throw new Exception("DateTimeUtil.ToDateTime14Str() error : 参数不是19位");
+
+ string sRet = sDT.Replace(":", "").Replace("-", "").Replace(" ", "");
+ if (sRet.Length != 14)
+ throw new Exception("DateTimeUtil.ToDateTime14Str() error : 返回值不是14位");
+
+ return sRet;
+ }
+
+ ///
+ /// 由14位的日期时间转到19位的日期时间
+ ///
+ /// 14位的日期时间
+ /// 19位的日期时间
+ public static string FromDateTime14Str(string sDT14)
+ {
+ if (sDT14 == "")
+ return "";
+ if (sDT14.Length != 14)
+ throw new Exception("DateTimeUtil.FromDateTime14Str() error : 参数不是14位");
+
+ string sRet = sDT14.Substring(0, 4) + "-" + sDT14.Substring(4, 2)
+ + "-" + sDT14.Substring(6, 2)
+ + " " + sDT14.Substring(8, 2) + ":" + sDT14.Substring(10, 2)
+ + ":" + sDT14.Substring(12, 2);
+ return sRet;
+ }
+
+ /////
+ ///// 是否为日期型字符串
+ /////
+ ///// 日期字符串(2008-05-08)
+ /////
+ //public static bool IsDate(string StrSource)
+ //{
+ // return Regex.IsMatch(StrSource, @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
+ //}
+ }
+}
diff --git a/HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs b/HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs
index 9ff8363..c08dcff 100644
--- a/HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs
+++ b/HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs
@@ -72,6 +72,17 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl
return _context?.Set().AsNoTracking().FirstOrDefault(expression);
}
+ public async Task GetFirstOrDefaultAsync(Expression> expression) where T : class
+ {
+ if (IsClose()) return default!;
+
+ var entity = await _context!.Set().FirstOrDefaultAsync(expression);
+ //var entity = await _context.Set().FindAsync(values);
+ if (entity != null) _context.Entry(entity).State = EntityState.Detached; //取消实体跟踪
+
+ return entity!;
+ }
+
///
/// 根据主键值来查询某条记录,单主键的表可直接输入主键,多主键的表注意主键次序
///
diff --git a/HealthMonitor.Core/Dal/IDataAccessor.cs b/HealthMonitor.Core/Dal/IDataAccessor.cs
index 89c094a..8b046a2 100644
--- a/HealthMonitor.Core/Dal/IDataAccessor.cs
+++ b/HealthMonitor.Core/Dal/IDataAccessor.cs
@@ -27,6 +27,8 @@ namespace HealthMonitor.Core.Dal
///
T GetFirstOrDefault(Expression> expression) where T : class;
+ Task GetFirstOrDefaultAsync(Expression> expression) where T : class;
+
///
/// 根据主键值来查询某条记录,单主键的表可直接输入主键,多主键的表注意主键次序
///
diff --git a/HealthMonitor.Service/Biz/db/TDengineService.cs b/HealthMonitor.Service/Biz/db/TDengineService.cs
index 6d767bc..e20e33d 100644
--- a/HealthMonitor.Service/Biz/db/TDengineService.cs
+++ b/HealthMonitor.Service/Biz/db/TDengineService.cs
@@ -196,18 +196,19 @@ namespace HealthMonitor.Service.Biz.db
{
var sql = $"SELECT MAX({field}), MIN({field}) FROM {_configTDengineService.DB}.{tbName} WHERE {condition}";
+
var result = await GernalRestSqlResText(sql);
var res = JsonConvert.DeserializeObject(result!);
List data = res?.Data!;
return new Aggregate
{
- Max = data[0][0],
- Min = data[0][1],
+ Max = data.Count.Equals(0) ? 0 : data[0][0],
+ Min = data.Count.Equals(0) ? 0 : data[0][1],
};
}
- public async Task GetAvgExceptMaxMinValue(string field, string tbName, string? condition)
+ public async Task GetAvgExceptMaxMinValue(string field, string tbName, string? condition)
{
var sql = $"SELECT MAX({field}), MIN({field}) FROM {_configTDengineService.DB}.{tbName} WHERE {condition}";
@@ -216,12 +217,12 @@ namespace HealthMonitor.Service.Biz.db
var res = JsonConvert.DeserializeObject(result!);
List data = res?.Data!;
- sql = $"SELECT AVG({field}) FROM {_configTDengineService.DB}.{tbName} WHERE {condition} AND {field} < { (data.Count.Equals(0)? 0: data[0][0]) } and {field} > {(data.Count.Equals(0) ? 0 : data[0][1])}";
- result = await GernalRestSqlResText(sql);
+ var sqlAvg = $"SELECT AVG({field}) FROM {_configTDengineService.DB}.{tbName} WHERE {condition} AND {field} < { (data.Count.Equals(0)? 0: data[0][0]) } and {field} > {(data.Count.Equals(0) ? 0 : data[0][1])}";
+ result = await GernalRestSqlResText(sqlAvg);
res = JsonConvert.DeserializeObject(result!);
data = res?.Data!;
- return data.Count.Equals(0)?0:data[0][0];
+ return data.Count.Equals(0)?0:(int)data[0][0];
}
diff --git a/HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs b/HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs
index b64d7b8..4147eca 100644
--- a/HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs
+++ b/HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs
@@ -1,5 +1,8 @@
using HealthMonitor.Core.Dal;
+using HealthMonitor.Core.Query;
+using HealthMonitor.Core.Query.Extensions;
using HealthMonitor.Util.Entities.HealthMonitor;
+using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Security.Cryptography;
@@ -38,17 +41,39 @@ namespace HealthMonitor.Service.Cache
var bpRef = await RedisHelper.GetAsync(cacheKey).ConfigureAwait(false);
if (bpRef == null)
{
- bpRef = _dataAccessor
- .GetFirstOrDefault(
- i =>
- i.Age.Equals(age) &&
- i.Gender.Equals(gender) &&
- i.Hypertension.Equals(isHypertension)
- );
- ;
- await RedisHelper.SetAsync(cacheKey, JsonConvert.SerializeObject(bpRef));
+ try
+ {
+ //bpRef = _dataAccessor
+ //.GetFirstOrDefault(
+ //i =>
+ //i.Age.Equals(age) &&
+ //i.Gender.Equals(gender) &&
+ //i.Hypertension.Equals(isHypertension)
+ //);
+ bpRef = await _dataAccessor
+ .GetFirstOrDefaultAsync
+ (
+ i =>
+ i.Age.Equals(age) &&
+ i.Gender.Equals(gender) &&
+ i.Hypertension.Equals(isHypertension)
+ );
+ await RedisHelper.SetAsync(cacheKey, JsonConvert.SerializeObject(bpRef));
+ return bpRef;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString() );
+ return new HmBloodPressReferenceValue
+ {
+ Age = 0,
+ };
+ }
+
}
+
return bpRef;
+
}
diff --git a/HealthMonitor.Service/Resolver/BloodpressResolver.cs b/HealthMonitor.Service/Resolver/BloodpressResolver.cs
new file mode 100644
index 0000000..3df1dbe
--- /dev/null
+++ b/HealthMonitor.Service/Resolver/BloodpressResolver.cs
@@ -0,0 +1,37 @@
+
+using HealthMonitor.Service.Resolver.Interface;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TDengineTMQ;
+
+namespace HealthMonitor.Service.Resolver
+{
+
+ public class BloodpressResolver: IResolver
+ {
+ private readonly ILogger _logger;
+ public BloodpressResolver
+ (
+ ILogger logger
+ )
+ {
+ _logger = logger;
+ }
+
+ public void SetResolveInfo(IConsumer msg)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task ExecuteMessageAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+
+ }
+}
diff --git a/HealthMonitor.Service/Resolver/Factory/ResolverFactory.cs b/HealthMonitor.Service/Resolver/Factory/ResolverFactory.cs
new file mode 100644
index 0000000..2461b94
--- /dev/null
+++ b/HealthMonitor.Service/Resolver/Factory/ResolverFactory.cs
@@ -0,0 +1,24 @@
+using HealthMonitor.Service.Resolver.Interface;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TDengineTMQ;
+
+namespace HealthMonitor.Service.Resolver.Factory
+{
+ public class ResolverFactory : IResolverFactory
+ {
+ private readonly ILogger _logger;
+ public ResolverFactory(ILogger logger)
+ {
+ _logger = logger;
+ }
+ public void ParseAndWrap(IConsumer msg)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/HealthMonitor.Service/Resolver/Interface/IResolver.cs b/HealthMonitor.Service/Resolver/Interface/IResolver.cs
new file mode 100644
index 0000000..a494120
--- /dev/null
+++ b/HealthMonitor.Service/Resolver/Interface/IResolver.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TDengineTMQ;
+
+namespace HealthMonitor.Service.Resolver.Interface
+{
+ public interface IResolver
+ {
+ void SetResolveInfo(IConsumer msg);
+
+ Task ExecuteMessageAsync();
+ }
+}
diff --git a/HealthMonitor.Service/Resolver/Interface/IResolverFactory.cs b/HealthMonitor.Service/Resolver/Interface/IResolverFactory.cs
new file mode 100644
index 0000000..5a19a24
--- /dev/null
+++ b/HealthMonitor.Service/Resolver/Interface/IResolverFactory.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TDengineTMQ;
+
+namespace HealthMonitor.Service.Resolver.Interface
+{
+ public interface IResolverFactory
+ {
+ void ParseAndWrap(IConsumer msg);
+ }
+}
diff --git a/HealthMonitor.Service/Sub/TDengineDataSubcribe.cs b/HealthMonitor.Service/Sub/TDengineDataSubcribe.cs
index 8ca2903..3a1e21f 100644
--- a/HealthMonitor.Service/Sub/TDengineDataSubcribe.cs
+++ b/HealthMonitor.Service/Sub/TDengineDataSubcribe.cs
@@ -1,4 +1,8 @@
-using Microsoft.Extensions.Logging;
+using HealthMonitor.Common;
+using HealthMonitor.Core.Dal;
+using HealthMonitor.Service.Biz.db;
+using HealthMonitor.Service.Cache;
+using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -6,6 +10,7 @@ using System.Text;
using System.Threading.Tasks;
using TDengineDriver;
using TDengineTMQ;
+using TelpoDataService.Util.Entities.GpsLocationHistory;
namespace HealthMonitor.Service.Sub
{
@@ -14,11 +19,22 @@ namespace HealthMonitor.Service.Sub
private readonly ILogger _logger;
private IConsumer _consumer = default!;
private IntPtr _conn = default!;
+ private readonly TDengineService _serviceTDengine;
+ private readonly PersonCacheManager _personCacheMgr;
+ private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
+
+ private int cnt = 0;
public TDengineDataSubcribe(
+ TDengineService serviceDengine,
+ PersonCacheManager personCacheMgr,
+ BloodPressReferenceValueCacheManager bpRefValCacheManager,
ILogger logger
)
{
+ _serviceTDengine = serviceDengine;
+ _personCacheMgr = personCacheMgr;
+ _bpRefValCacheManager = bpRefValCacheManager;
_logger = logger;
_conn = GetConnection();
}
@@ -64,9 +80,9 @@ namespace HealthMonitor.Service.Sub
TDConnectIp = "47.116.142.20",
};
//IntPtr conn = GetConnection();
- string topic = "topic_name";
+ string topic = "topic_hm_bp_stats";
//create topic
- IntPtr res = TDengine.Query(_conn, $"create topic if not exists {topic} as select * from ctb1");
+ IntPtr res = TDengine.Query(_conn, $"create topic if not exists {topic} as select * from health_monitor.hm_bloodpress");
if (TDengine.ErrorNo(res) != 0)
{
@@ -114,27 +130,242 @@ namespace HealthMonitor.Service.Sub
// return consumer;
//}
- public void ProcessMsg()
+ //public void ProcessMsg()
+ //{
+ // var consumerRes = _consumer.Consume(300);
+ // // process ConsumeResult
+ // foreach (KeyValuePair kv in consumerRes.Message)
+ // {
+ // Console.WriteLine("topic partitions:\n{0}", kv.Key.ToString());
+
+ // kv.Value.Metas.ForEach(meta =>
+ // {
+ // Console.Write("{0} {1}({2}) \t|", meta.name, meta.TypeName(), meta.size);
+ // });
+ // Console.WriteLine("");
+ // kv.Value.Datas.ForEach(data =>
+ // {
+ // Console.WriteLine(data.ToString());
+ // });
+ // }
+
+ // _consumer.Commit(consumerRes);
+ // // Console.WriteLine("\n================ {0} done ");
+ //}
+
+
+ public async Task ProcessMsg()
{
var consumerRes = _consumer.Consume(300);
+
+ Console.WriteLine(consumerRes.Message.Count);
// process ConsumeResult
foreach (KeyValuePair kv in consumerRes.Message)
{
- Console.WriteLine("topic partitions:\n{0}", kv.Key.ToString());
+ //Console.WriteLine("topic partitions:\n{0}", kv.Key.ToString());
- kv.Value.Metas.ForEach(meta =>
- {
- Console.Write("{0} {1}({2}) \t|", meta.name, meta.TypeName(), meta.size);
- });
- Console.WriteLine("");
- kv.Value.Datas.ForEach(data =>
+ //kv.Value.Metas.ForEach(meta =>
+ //{
+ // Console.Write("{0} {1}({2}) \t|", meta.name, meta.TypeName(), meta.size);
+ //});
+ //Console.WriteLine("----------");
+ //kv.Value.Datas.ForEach(data =>
+ //{
+ // Console.WriteLine(data.ToString());
+ //});
+ //Console.WriteLine("----------");
+ for (int i = 0; i < kv.Value.Datas.Count; i++)
{
- Console.WriteLine(data.ToString());
- });
+ // Console.Write($"|{kv.Value.Datas[i].ToString()} \t");
+ //Console.WriteLine("{0},{1},{2}", i, resMeta.Count, (i) % resMeta.Count);
+ if (((i + 1) % kv.Value.Metas.Count == 0))
+ {
+
+
+ try
+ {
+ cnt++;
+ string bloodpress_id = SafeType.SafeString(kv.Value.Datas[i - 8]);
+ string message_id = SafeType.SafeString(kv.Value.Datas[i - 7]);
+ string serialno = SafeType.SafeString(kv.Value.Datas[i - 6]);
+ int systolic_value = SafeType.SafeInt(kv.Value.Datas[i - 5]);
+ int diastolic_value = SafeType.SafeInt(kv.Value.Datas[i - 4]);
+ DateTime create_time = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(kv.Value.Datas[i - 3]) / 1000000);
+ DateTime last_update = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(kv.Value.Datas[i - 2]) / 1000000);
+ int method = SafeType.SafeInt(kv.Value.Datas[i - 1]);
+ bool is_display = SafeType.SafeBool(kv.Value.Datas[i]);
+
+
+ // Console.WriteLine("----------");
+ HisGpsBloodPress bp = new()
+ {
+ //BloodPressId = (string)kv.Value.Datas[i -8],
+ //MessageId = (string)kv.Value.Datas[i -7],
+ //Serialno = (string)kv.Value.Datas[i -6],
+ //SystolicValue = (int)kv.Value.Datas[i -5],
+ //DiastolicValue = (int)kv.Value.Datas[i -4],
+ //CreateTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds((long)kv.Value.Datas[i -3]/1000000),
+ //LastUpdate = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds((long)kv.Value.Datas[i -2]/1000000),
+ //Method = (int)kv.Value.Datas[i -1],
+ //IsDisplay = (bool)kv.Value.Datas[i] ? 1 : 0,
+
+ BloodPressId = bloodpress_id,
+ MessageId = message_id,
+ Serialno = serialno,
+ SystolicValue = systolic_value,
+ DiastolicValue = diastolic_value,
+ CreateTime = create_time,
+ LastUpdate = last_update,
+ Method = method,
+ IsDisplay = is_display ? 1 : 0,
+ };
+
+
+ #region 获取个人信息
+
+ var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(bp.MessageId, bp.Serialno).ConfigureAwait(false);
+ // 验证这个信息是否存在
+ if (person == null || person?.Person.BornDate == null)
+ {
+ Console.WriteLine("验证这个信息是否存在");
+ }
+ else
+ {
+ // 验证年龄是否在范围 (2 - 120)
+
+
+ var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!);
+ #endregion
+ if (age < 1 || age > 120)
+ {
+ Console.WriteLine("验证年龄是否在范围 (2 - 120)");
+ }
+ else
+ {
+ var gender = person?.Person.Gender == true ? 1 : 2;
+ var isHypertension = SafeType.SafeBool(person?.Person.Ishypertension!);
+ var height = SafeType.SafeDouble(person?.Person.Height!);
+ var weight = SafeType.SafeDouble(person?.Person.Weight!);
+
+
+ #region 插入当次BP数据
+ // 保存到TDengine
+
+ //var bpSql = $"INSERT INTO health_monitor.hm_bloodpress VALUES(" +
+ // $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ // $"'{bp.BloodPressId}'," +
+ // $"'{bp.MessageId}'," +
+ // $"'{bp.Serialno}'," +
+ // $"{bp.SystolicValue}," +
+ // $"{bp.DiastolicValue}," +
+ // $"'{bp.CreateTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ // $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ // $"{bp.Method}," +
+ // $"{bp.IsDisplay == 1})";
+
+ //await _serviceTDengine.GernalRestSql(bpSql);
+
+ #endregion
+
+ #region 计算增量值
+ var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension);
+
+ var systolicRefValue = bpRef?.Systolic;//?
+ var diastolicRefValue = bpRef?.Diastolic;//?
+ int duration = 30;
+ // 获取历史数据
+ //DateTime now = DateTime.Now;
+ DateTime now = (DateTime)bp.LastUpdate; //测试
+ DateTime startTime = now.AddDays(-duration);
+ DateTime endTime = now;
+
+ //
+ var systolicAggregate = await _serviceTDengine.GetAggregateValue("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
+ var diastolicAggregate = await _serviceTDengine.GetAggregateValue("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
+
+ // 最大值
+ var systolicMax = systolicAggregate.Max;
+ var diastolicMax = diastolicAggregate.Max;
+ // 最小值
+ var systolicMin = systolicAggregate.Min;
+ var diastolicMin = diastolicAggregate.Min;
+
+
+ // 计算去除最大值和最小值和异常值的平均值
+ var systolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValue("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} ");
+ var diastolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValue("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and diastolic_value < {diastolicRefValue}");
+
+ // 偏移参数
+ var avgOffset = 0.25M;
+
+ var systolicAvgOffset = avgOffset;
+ var diastolicAvgOffset = avgOffset;
+
+
+ // 增量值=(标定值-平均值)* 0.25
+ var systolicInc = systolicAvg.Equals(0M) ? 0 : (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
+ var diastolicInc = diastolicAvg.Equals(0M) ? 0 : (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
+
+ #endregion
+
+ #region 插入BP增量值
+ var sql = $"INSERT INTO health_monitor.hm_bloodpress_stats_inc VALUES(" +
+ $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ $"'{bp.BloodPressId}'," +
+ $"'{bp.MessageId}'," +
+ $"'{bp.Serialno}'," +
+ $"{bp.SystolicValue}," +
+ $"{systolicRefValue}," +
+ $"{systolicAvg}," +
+ $"{systolicMax}," +
+ $"{systolicMin}," +
+ $"{systolicAvgOffset}," +
+ $"{systolicInc}," +
+ $"{bp.DiastolicValue}," +
+ $"{diastolicRefValue}," +
+ $"{diastolicAvg}," +
+ $"{diastolicMax}," +
+ $"{diastolicMin}," +
+ $"{diastolicAvgOffset}," +
+ $"{diastolicInc}," +
+ $"{gender}," +
+ $"{age}," +
+ $"{height}," +
+ $"{weight}," +
+ $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ $"{duration}," +
+ $"'{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ $"'{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
+ $"'{string.Empty}')";
+ var res = await _serviceTDengine.GernalRestSql(sql);
+ #endregion
+
+ };
+ // Console.WriteLine("----------");
+ }
+
+
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ }
+ Console.WriteLine("++++++++++++++++++++++");
+
+ Console.Write($"总共增加{cnt}");
+ }
+
+ // Console.WriteLine("");
+
+
+
+
}
_consumer.Commit(consumerRes);
- Console.WriteLine("\n================ {0} done ");
+ // Console.WriteLine("\n================ {0} done ");
}
public IntPtr GetConnection()