@@ -24,5 +24,10 @@ namespace TelpoPush.Common | |||
} | |||
return dtStart.AddSeconds(long.Parse(timeStamp)); | |||
} | |||
public static string ToDateTimeStr(DateTime dt) | |||
{ | |||
return dt.ToString("yyyy-MM-dd HH:mm:ss"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Security.Cryptography; | |||
namespace TelpoPush.Common | |||
{ | |||
public class Utils | |||
{ | |||
public static MultipartFormDataContent GetMultipartFormDataContent(Dictionary<string, object> dic, string appId, ref Dictionary<string, object> outDic) | |||
{ | |||
MultipartFormDataContent mfdc = new MultipartFormDataContent(); | |||
StringBuilder sb = new StringBuilder(); | |||
if (dic != null && dic.Count > 0) | |||
{ | |||
var dicOrderBy = dic.OrderBy(z => z.Key); | |||
foreach (KeyValuePair<string, object> kv in dicOrderBy) | |||
{ | |||
sb.Append($"{kv.Key}={kv.Value.ToString()}&"); | |||
mfdc.Add(new StringContent(kv.Value.ToString()), kv.Key);//参数, 内容在前,参数名称在后 | |||
} | |||
} | |||
string signStr = $"{sb.ToString().Trim('&')}{appId}"; | |||
byte[] bytes = Encoding.UTF8.GetBytes(signStr); | |||
byte[] hash = SHA256.Create().ComputeHash(bytes); | |||
StringBuilder builder = new StringBuilder(); | |||
for (int i = 0; i < hash.Length; i++) | |||
{ | |||
builder.Append(hash[i].ToString("X2")); | |||
} | |||
string sign = builder.ToString().ToLower(); | |||
dic.Add("sign", sign); | |||
mfdc.Add(new StringContent(sign), "sign");//参数, 内容在前,参数名称在后 | |||
outDic = dic; | |||
return mfdc; | |||
} | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace TelpoPush.Models.CacheTemplates | |||
{ | |||
public class ManufactorPushSettingInfoModel | |||
{ | |||
public string id { get; set; } | |||
public string manufactorId { get; set; } | |||
public string manufactorName { get; set; } | |||
public string imei { get; set; } | |||
public List<PushSettingsItem> pushSettings { get; set; } | |||
public int settingType { get; set; } | |||
} | |||
public class PushSettingsItem | |||
{ | |||
public string dataName { get; set; } | |||
public int dataType { get; set; } | |||
public List<SettingInfosItem> settingInfos { get; set; } | |||
} | |||
public class SettingInfosItem | |||
{ | |||
public bool pushFlag { get; set; } | |||
public string pushStartTime { get; set; } | |||
public string pushEndTime { get; set; } | |||
public int pushType { get; set; } | |||
public string pushUrl { get; set; } | |||
public string remark { get; set; } | |||
} | |||
} |
@@ -144,6 +144,10 @@ namespace TelpoPush.Models.Enum | |||
/// </summary> | |||
BloodSugar = 28, | |||
/// <summary> | |||
/// 中考实时心率数据上报 | |||
/// </summary> | |||
ZkRealHeartRate = 29, | |||
/// <summary> | |||
/// 绑定业务 | |||
/// </summary> | |||
@@ -11,6 +11,7 @@ using TelpoDataService.Util.Entities.GpsLocationHistory; | |||
using TelpoDataService.Util.Models; | |||
using TelpoDataService.Util.QueryObjects; | |||
using TelpoPush.Common; | |||
using TelpoPush.Models.Enum; | |||
using TelpoPush.Models.MqTemplates; | |||
using TelpoPush.Service.Cache; | |||
@@ -20,17 +21,20 @@ namespace TelpoPush.Service.Biz | |||
{ | |||
private readonly ILogger<ZkRealHRMonitorService> _logger; | |||
private readonly HttpHelperAsync _httpHelper; | |||
private readonly RedisUtil _redis; | |||
private readonly GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> _messageRealHeartRateAiClient; | |||
public ZkRealHRMonitorService( | |||
ILogger<ZkRealHRMonitorService> logger, RedisUtil redis, | |||
ILogger<ZkRealHRMonitorService> logger, RedisUtil redis, HttpHelperAsync httpHelper, | |||
GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> messageRealHeartRateAiClient) | |||
{ | |||
_logger = logger; | |||
_redis = redis; | |||
_httpHelper = httpHelper; | |||
_messageRealHeartRateAiClient = messageRealHeartRateAiClient; | |||
} | |||
//数据保存、推送 | |||
public async Task Save(ZkRealHeartRateData data, string MessageId) | |||
{ | |||
string deviceKey = await _redis.GetHealthyDeviceKey(data.imei); | |||
@@ -54,10 +58,25 @@ namespace TelpoPush.Service.Biz | |||
CreateTime = DateTime.Now, | |||
}; | |||
await _messageRealHeartRateAiClient.AddAsync(model); | |||
var settingInfo = await _redis.GetManufactorPushSettingHash(data.imei, data.agencyid, (int)MqDataType.ZkRealHeartRate); | |||
if (settingInfo != null) | |||
{ | |||
Dictionary<string, object> dic = new Dictionary<string, object>(); | |||
dic.Add("imei", data.imei); | |||
dic.Add("value", item.value); | |||
dic.Add("alarmType", item.isAnomaly); | |||
dic.Add("alarmInfo", "异常告警"); | |||
dic.Add("value", item.value); | |||
dic.Add("dataTime", TimeHelper.ToDateTimeStr(lastUpdate)); | |||
MultipartFormDataContent mfdc = Utils.GetMultipartFormDataContent(dic, data.agencyid, ref dic); | |||
var result = await _httpHelper.PostFormAsync(settingInfo.pushUrl, mfdc); | |||
_logger.LogInformation($"[中考实时心率-第三方数据推送<{data.imei}>] url:{settingInfo.pushUrl},参数:{JsonConvert.SerializeObject(dic)},结果:{result}"); | |||
} | |||
} | |||
} | |||
} | |||
//取消 数据保存 | |||
public async Task SaveAnomalyCancel(ZkRealHeartRateAnomalyCancelData data, string MessageId) | |||
{ | |||
string deviceKey = await _redis.GetHealthyDeviceKey(data.imei); | |||
@@ -80,3 +99,4 @@ namespace TelpoPush.Service.Biz | |||
} | |||
} | |||
} | |||
@@ -13,6 +13,7 @@ namespace TelpoPush.Service.Cache | |||
public class RedisUtil | |||
{ | |||
private const string CACHE_HASH_KEY_TELPO_MANUFACTOR_CONFIG = "TELPO#MANUFACTOR_CONFG_HASH"; | |||
private const string CACHE_HASH_KEY_TELPO_GPSDEVICE_PUSHSITTTIGS = "TELPO#GPSDEVICE_PUSH_SITTINGS_HASH"; | |||
private readonly ILogger<RedisUtil> _logger; | |||
private readonly ServiceConfig _configService; | |||
@@ -62,6 +63,87 @@ namespace TelpoPush.Service.Cache | |||
} | |||
} | |||
public async Task<SettingInfosItem> GetManufactorPushSettingHash(string imei, string manufactorId, int dataType) | |||
{ | |||
if (string.IsNullOrWhiteSpace(manufactorId)) return null; | |||
string keyCache = $"{manufactorId}_{dataType}_ManufactorPushSettingHash"; | |||
SettingInfosItem settingInfos = null; | |||
try | |||
{ | |||
var objCache = MemoryCacheUtil.Get<SettingInfosItem>(keyCache); | |||
if (objCache == null) | |||
{ | |||
var obj = await RedisHelper.HGetAsync<ManufactorPushSettingInfoModel>(CACHE_HASH_KEY_TELPO_GPSDEVICE_PUSHSITTTIGS, manufactorId); | |||
if (obj != null) | |||
{ | |||
if (obj.pushSettings.Any()) | |||
{ | |||
DateTime dt = DateTime.Now; | |||
var settingsItem = obj.pushSettings.FirstOrDefault<PushSettingsItem>(x => x.dataType == dataType); | |||
if (settingsItem != null) | |||
{ | |||
if (settingsItem.settingInfos.Any()) | |||
{ | |||
foreach (var item in settingsItem.settingInfos) | |||
{ | |||
DateTime startTime = DateTime.Parse($"{dt.Year}-{dt.Month}-{dt.Day} {item.pushStartTime}"); | |||
DateTime endTime = DateTime.Parse($"{dt.Year}-{dt.Month}-{dt.Day} {item.pushEndTime}"); | |||
if (item.pushFlag && (dt > startTime && dt < endTime)) | |||
{ | |||
settingInfos = item; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (settingInfos != null) | |||
MemoryCacheUtil.Set(keyCache, settingInfos, _configService.CacheDurationSeconds10); | |||
else | |||
MemoryCacheUtil.Remove(keyCache); | |||
} | |||
} | |||
else | |||
settingInfos = objCache; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"GetManufactorPushSettingHash(imei={imei},dataType={dataType}),key={manufactorId},缓存异常,重新获取数据,{ex.Message}|{ex.Source}|{ex.StackTrace}"); | |||
var obj = await RedisHelper.HGetAsync<ManufactorPushSettingInfoModel>(CACHE_HASH_KEY_TELPO_GPSDEVICE_PUSHSITTTIGS, manufactorId); | |||
if (obj != null) | |||
{ | |||
if (obj.pushSettings.Any()) | |||
{ | |||
DateTime dt = DateTime.Now; | |||
var settingsItem = obj.pushSettings.FirstOrDefault<PushSettingsItem>(x => x.dataType == dataType); | |||
if (settingsItem != null) | |||
{ | |||
if (settingsItem.settingInfos.Any()) | |||
{ | |||
foreach (var item in settingsItem.settingInfos) | |||
{ | |||
DateTime startTime = DateTime.Parse($"{dt.Year}-{dt.Month}-{dt.Day} {item.pushStartTime}"); | |||
DateTime endTime = DateTime.Parse($"{dt.Year}-{dt.Month}-{dt.Day} {item.pushEndTime}"); | |||
if (item.pushFlag && (dt > startTime && dt < endTime)) | |||
{ | |||
settingInfos = item; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if (settingInfos != null) | |||
MemoryCacheUtil.Set(keyCache, settingInfos, _configService.CacheDurationSeconds10); | |||
else | |||
MemoryCacheUtil.Remove(keyCache); | |||
} | |||
} | |||
return settingInfos; | |||
} | |||
//public async Task<string> ManufactorKafkaTopicQuery() | |||
//{ | |||