Browse Source

使用数据订阅方式

td_orm
H Vs 1 year ago
parent
commit
3907e5aca9
10 changed files with 1100 additions and 29 deletions
  1. +710
    -0
      HealthMonitor.Common/DateTimeUtil.cs
  2. +11
    -0
      HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs
  3. +2
    -0
      HealthMonitor.Core/Dal/IDataAccessor.cs
  4. +7
    -6
      HealthMonitor.Service/Biz/db/TDengineService.cs
  5. +34
    -9
      HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs
  6. +37
    -0
      HealthMonitor.Service/Resolver/BloodpressResolver.cs
  7. +24
    -0
      HealthMonitor.Service/Resolver/Factory/ResolverFactory.cs
  8. +16
    -0
      HealthMonitor.Service/Resolver/Interface/IResolver.cs
  9. +14
    -0
      HealthMonitor.Service/Resolver/Interface/IResolverFactory.cs
  10. +245
    -14
      HealthMonitor.Service/Sub/TDengineDataSubcribe.cs

+ 710
- 0
HealthMonitor.Common/DateTimeUtil.cs View File

@@ -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
{

/// <summary>
/// 毫秒时间戳转本地时间
/// </summary>
/// <param name="milliseconds"></param>
/// <returns></returns>
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;
}

/// <summary>
/// 判断给定的日期时间字符串是否符合相应的格式
/// </summary>
/// <param name="strDate">日期时间字符串</param>
/// <returns>是否符合格式</returns>
public static bool IsDateTime(string strDate)
{
if (strDate.Length != 19)
return false;

try
{
DateTime dt = DateTime.Parse(strDate);
return true;
}
catch
{
return false;
}
}

/// <summary>
/// 得到当前月的第一天
/// </summary>
/// <returns>当前月的第一天</returns>
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");
}
}

/// <summary>
/// 得到当前月的最后一天
/// </summary>
/// <returns>当前月的最后一天</returns>
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");
}
}

/// <summary>
/// 指定日期的该月第一天
/// </summary>
/// <param name="sThisDate">指定的日期</param>
/// <returns>该月第一天</returns>
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";
}

/// <summary>
/// 指定日期的该月最后一天
/// </summary>
/// <param name="sThisDate">指定的日期</param>
/// <returns>该月最后一天</returns>
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");
}

/// <summary>
/// 转换字符串类型的时间至日期时间类型
/// </summary>
/// <param name="strDateTime">时间字符串</param>
/// <returns>日期时间类型的值</returns>
/// <remarks>如果格式不正确,则返回当前的时间</remarks>
public static DateTime ToDateTime(string strDateTime)
{
try
{
return DateTime.Parse(strDateTime);
}
catch
{
return DateTime.Now;
}
}

/// <summary>
/// 转换时间类型的字符串至日期时间类型
/// </summary>
/// <param name="strTime">时间字符串</param>
/// <returns>时间值</returns>
/// <remarks>如果格式不正确,则返回的是"00:00:00"的时间值</remarks>
public static DateTime ToTime(string strTime)
{
try
{
return DateTime.Parse(strTime);
}
catch
{
return DateTime.Parse("00:00:00");
}
}

/// <summary>
/// 将时间值转换至时间字符串
/// </summary>
/// <param name="time">时间值</param>
/// <returns>时间字符串</returns>
public static string ToTimeStr(DateTime time)
{
return time.ToString("HH:mm:ss");
}

/// <summary>
/// 将对象转换为指定格式的字符串
/// </summary>
/// <param name="time">待转换的对象</param>
/// <param name="sFormat">指定的字符串格式</param>
/// <returns>转换后的字符串</returns>
/// <remarks>如果为空值,或非日期时间对象,则返回""</remarks>
public static string ToTimeStr(object time, string sFormat)
{
if (time == null || time == DBNull.Value)
return "";
else
{
try
{
return ((DateTime)time).ToString(sFormat);
}
catch
{
return "";
}
}
}

/// <summary>
/// 将对象转换为字符串,格式为"HH:mm:ss"
/// </summary>
/// <param name="time">待转换的对象</param>
/// <returns>转换后的字符串</returns>
public static string ToTimeStr(object time)
{
return ToTimeStr(time, "HH:mm:ss");
}

/// <summary>
/// 从秒数转换为时间字符串
/// </summary>
/// <param name="Second">秒数</param>
/// <returns>时间字符串</returns>
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;
}

/// <summary>
/// 将时间字符串转换为秒数
/// </summary>
/// <param name="timeStr">时间字符串</param>
/// <returns>转换后的秒数</returns>
public static int ToSecondsFromTimeStr(string timeStr)
{
DateTime dt = ToTime(timeStr);
return dt.Hour * 3600 + dt.Minute * 60 + dt.Second;
}

/// <summary>
/// 将日期时间值转换为日期字符串
/// </summary>
/// <param name="dt">日期时间值</param>
/// <returns>日期字符串</returns>
public static string ToDateStr(DateTime dt)
{
return dt.ToString("yyyy-MM-dd");
}

/// <summary>
/// 将对象转换为日期字符串
/// </summary>
/// <param name="dt">对象</param>
/// <param name="defaultStr">缺省字符串</param>
/// <returns>转换后的字符串。如果为空值,则按缺省值返回</returns>
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");
}

/// <summary>
/// 将对象转换为日期字符串
/// </summary>
/// <param name="dt">对象</param>
/// <returns>转换后的字符串。如果转换不成功,则返回""</returns>
public static string ToDateStr(object dt)
{
return ToDateStr(dt, "");
}

/// <summary>
/// 将日期时间值转换为字符串
/// </summary>
/// <param name="dt">日期时间值</param>
/// <returns>字符串(len=19)</returns>
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");
}

/// <summary>
/// 将对象转换为日期时间字符串
/// </summary>
/// <param name="dt">对象</param>
/// <param name="defaultStr">转换不成功时所取的缺省字符串</param>
/// <returns>转换后的日期时间字符串(len=19)</returns>
public static string ToDateTimeStr(object dt, string defaultStr)
{
return ToDateTimeStr(dt, defaultStr, "yyyy-MM-dd HH:mm:ss");
}

/// <summary>
/// 将对象转换为日期时间字符串
/// </summary>
/// <param name="dt">对象</param>
/// <returns>转换后的日期时间字符串(len=19)</returns>
/// <remarks>如果转换不成功,则返回""</remarks>
public static string ToDateTimeStr(object dt)
{
return ToDateTimeStr(dt, "", "yyyy-MM-dd HH:mm:ss");
}

/// <summary>
/// 将对象转换为指定格式的日期时间字符串
/// </summary>
/// <param name="dt">对象</param>
/// <param name="defaultStr">缺省字符串</param>
/// <param name="sFormat">格式</param>
/// <returns>转换后的字符串</returns>
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);
}


/// <summary>
/// 获取当前的时间
/// </summary>
public static string Now
{
get
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
}

/// <summary>
/// 带毫秒部分的当前时间,示例为2003.07.22 10:02:52.136
/// </summary>
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");
}
}

/// <summary>
/// 获取当前的时间
/// </summary>
public static string Today
{
get
{
return DateTime.Today.ToString("yyyy-MM-dd HH:mm:ss");
}
}

/// <summary>
/// 获取日期的年份
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>年份</returns>
public static int Year(string dtString)
{
int nYear;

nYear = Convert.ToInt32(dtString.Substring(0, 4));

return nYear;
}

/// <summary>
/// 获取日期的月份
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>月份</returns>
public static int Month(string dtString)
{
int nMonth;

nMonth = Convert.ToInt32(dtString.Substring(5, 2));

return nMonth;
}

/// <summary>
/// 获取日期中该月的第几天
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>该月的第几天</returns>
public static int Day(string dtString)
{
int nDay;

nDay = Convert.ToInt32(dtString.Substring(8, 2));

return nDay;
}

/// <summary>
/// 获取日期中的小时部分
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>小时部分</returns>
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;
}

/// <summary>
/// 获取日期中的分钟部分
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>分钟部分</returns>
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;
}

/// <summary>
/// 获取日期中的秒部分
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>秒部分</returns>
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;
}

/// <summary>
/// 获取表示的日期是星期几
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>星期几</returns>
/// <remarks>返回值从0至6;星期日为0,星期六为6</remarks>
public static int DayOfWeek(string dtString)
{
DateTime dt = DateTime.Parse(dtString);
return (int)dt.DayOfWeek;
}

/// <summary>
/// 获取表示的日期是一年中的第几天
/// </summary>
/// <param name="dtString">日期时间串</param>
/// <returns>一年中的第几天</returns>
public static int DayOfYear(string dtString)
{
DateTime dt = DateTime.Parse(dtString);
return dt.DayOfYear;
}

/// <summary>
/// 将指定的月份数加到日期值上
/// </summary>
/// <param name="dtString">原来的日期</param>
/// <param name="nOffset">指定的月份数</param>
/// <returns>得到的日期</returns>
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");
}

/// <summary>
/// 将指定的天数加到日期值上
/// </summary>
/// <param name="dtString">原来的日期</param>
/// <param name="offset">指定的天数</param>
/// <returns>得到的日期</returns>
/// <remarks>天数可以为负数</remarks>
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");
}

/// <summary>
/// 将指定的秒数加到日期值上
/// </summary>
/// <param name="dtString">原来的日期时间</param>
/// <param name="offset">指定的秒数</param>
/// <returns>得到的日期时间</returns>
/// <remarks>秒数可以为负数</remarks>
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");
}

/// <summary>
/// 得到两个日期时间之间相差的天数
/// </summary>
/// <param name="dtFromString">起始日期</param>
/// <param name="dtToString">终止日期</param>
/// <returns>相差的天数</returns>
/// <remarks>
/// 不判断时间的情况。只判断日期是否切换,即使时间相差仅数分钟,
/// 只要切换了日期,也计算相差的天数。例如,2005-05-05 23:58:58和
/// 2005-05-06 00:02:03之间所差的天数也是1。
/// </remarks>
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;
}

/// <summary>
/// 得到两个日期时间之间相差的秒数
/// </summary>
/// <param name="dtFromString">起始日期时间</param>
/// <param name="dtToString">终止日期时间</param>
/// <returns>相差的秒数</returns>
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;
}

/// <summary>
/// 得到两个日期时间之间相差的毫秒数
/// </summary>
/// <param name="dtFromString">起始日期时间</param>
/// <param name="dtToString">终止日期时间</param>
/// <returns>相差的毫秒数</returns>
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;
}

/// <summary>
/// 通过时、分、秒得到时间串
/// </summary>
/// <param name="nHour">小时</param>
/// <param name="nMinute">分钟</param>
/// <param name="nSecond">秒</param>
/// <returns>时间部分</returns>
public static string EncodeTime(int nHour, int nMinute, int nSecond)
{
string sResult = nHour.ToString("00") + ":" + nMinute.ToString("00")
+ ":" + nSecond.ToString("00");
return sResult;
}

/// <summary>
/// 通过年、月、日得到日期部分
/// </summary>
/// <param name="nYear">年份</param>
/// <param name="nMonth">月份</param>
/// <param name="nDay">日</param>
/// <returns>日期部分</returns>
public static string EncodeDate(int nYear, int nMonth, int nDay)
{
string sResult = nYear.ToString("0000") + "-" + nMonth.ToString("00")
+ "-" + nDay.ToString("00");
return sResult;
}

/// <summary>
/// 得到日期部分
/// </summary>
/// <param name="sDatetime">日期时间</param>
/// <returns>日期部分</returns>
public static string GetDatePart(string sDatetime)
{
if (sDatetime.Length < 10)
return "";
return sDatetime.Substring(0, 10);
}

/// <summary>
/// 得到时间部分
/// </summary>
/// <param name="sDatetime">日期时间</param>
/// <returns>时间部分</returns>
public static string GetTimePart(string sDatetime)
{
if (sDatetime.Length == 19)
return sDatetime.Substring(11, 8);
else
return "00:00:00";
}

/// <summary>
/// 得到一天的起始时间
/// </summary>
/// <param name="sDate">日期</param>
/// <returns>起始时间</returns>
public static string BeginTimeOfDay(string sDate)
{
if (sDate.Length > 10)
sDate = sDate.Substring(0, 10);
return sDate + " 00:00:00";
}

/// <summary>
/// 得到一天的结束时间
/// </summary>
/// <param name="sDate">日期</param>
/// <returns>结束时间</returns>
public static string EndTimeOfDay(string sDate)
{
if (sDate.Length > 10)
sDate = sDate.Substring(0, 10);
return sDate + " 23:59:59.999";
}
/// <summary>
/// 由19位的日期时间转到14位的日期时间
/// </summary>
/// <param name="sDT">19位的日期时间</param>
/// <returns>14位的日期时间</returns>
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;
}

/// <summary>
/// 由14位的日期时间转到19位的日期时间
/// </summary>
/// <param name="sDT14">14位的日期时间</param>
/// <returns>19位的日期时间</returns>
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;
}

///// <summary>
///// 是否为日期型字符串
///// </summary>
///// <param name="StrSource">日期字符串(2008-05-08)</param>
///// <returns></returns>
//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-))$");
//}
}
}

+ 11
- 0
HealthMonitor.Core/Dal/EfCoreImpl/EfCoreDataAccessor.cs View File

@@ -72,6 +72,17 @@ namespace HealthMonitor.Core.Dal.EfCoreImpl
return _context?.Set<T>().AsNoTracking().FirstOrDefault(expression);
}

public async Task<T> GetFirstOrDefaultAsync<T>(Expression<Func<T, bool>> expression) where T : class
{
if (IsClose()) return default!;

var entity = await _context!.Set<T>().FirstOrDefaultAsync(expression);
//var entity = await _context.Set<T>().FindAsync(values);
if (entity != null) _context.Entry(entity).State = EntityState.Detached; //取消实体跟踪

return entity!;
}

/// <summary>
/// 根据主键值来查询某条记录,单主键的表可直接输入主键,多主键的表注意主键次序
/// </summary>


+ 2
- 0
HealthMonitor.Core/Dal/IDataAccessor.cs View File

@@ -27,6 +27,8 @@ namespace HealthMonitor.Core.Dal
/// <returns></returns>
T GetFirstOrDefault<T>(Expression<Func<T, bool>> expression) where T : class;

Task<T> GetFirstOrDefaultAsync<T>(Expression<Func<T, bool>> expression) where T : class;

/// <summary>
/// 根据主键值来查询某条记录,单主键的表可直接输入主键,多主键的表注意主键次序
/// </summary>


+ 7
- 6
HealthMonitor.Service/Biz/db/TDengineService.cs View File

@@ -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<Aggregate>(result!);
List<dynamic> 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<decimal> GetAvgExceptMaxMinValue(string field, string tbName, string? condition)
public async Task<int> 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<TDengineRestResBase>(result!);
List<dynamic> 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<TDengineRestResBase>(result!);
data = res?.Data!;

return data.Count.Equals(0)?0:data[0][0];
return data.Count.Equals(0)?0:(int)data[0][0];
}




+ 34
- 9
HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs View File

@@ -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<HmBloodPressReferenceValue>(cacheKey).ConfigureAwait(false);
if (bpRef == null)
{
bpRef = _dataAccessor
.GetFirstOrDefault<HmBloodPressReferenceValue>(
i =>
i.Age.Equals(age) &&
i.Gender.Equals(gender) &&
i.Hypertension.Equals(isHypertension)
);
;
await RedisHelper.SetAsync(cacheKey, JsonConvert.SerializeObject(bpRef));
try
{
//bpRef = _dataAccessor
//.GetFirstOrDefault<HmBloodPressReferenceValue>(
//i =>
//i.Age.Equals(age) &&
//i.Gender.Equals(gender) &&
//i.Hypertension.Equals(isHypertension)
//);
bpRef = await _dataAccessor
.GetFirstOrDefaultAsync<HmBloodPressReferenceValue>
(
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;

}




+ 37
- 0
HealthMonitor.Service/Resolver/BloodpressResolver.cs View File

@@ -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<BloodpressResolver> _logger;
public BloodpressResolver
(
ILogger<BloodpressResolver> logger
)
{
_logger = logger;
}

public void SetResolveInfo(IConsumer msg)
{
throw new NotImplementedException();
}

public Task ExecuteMessageAsync()
{
throw new NotImplementedException();
}

}
}

+ 24
- 0
HealthMonitor.Service/Resolver/Factory/ResolverFactory.cs View File

@@ -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<ResolverFactory> _logger;
public ResolverFactory(ILogger<ResolverFactory> logger)
{
_logger = logger;
}
public void ParseAndWrap(IConsumer msg)
{
throw new NotImplementedException();
}
}
}

+ 16
- 0
HealthMonitor.Service/Resolver/Interface/IResolver.cs View File

@@ -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();
}
}

+ 14
- 0
HealthMonitor.Service/Resolver/Interface/IResolverFactory.cs View File

@@ -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);
}
}

+ 245
- 14
HealthMonitor.Service/Sub/TDengineDataSubcribe.cs View File

@@ -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<TDengineDataSubcribe> _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<TDengineDataSubcribe> 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<TopicPartition, TaosResult> 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<TopicPartition, TaosResult> 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()


Loading…
Cancel
Save