@@ -24,5 +24,10 @@ namespace TelpoPush.Common | |||||
} | } | ||||
return dtStart.AddSeconds(long.Parse(timeStamp)); | 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> | /// </summary> | ||||
BloodSugar = 28, | BloodSugar = 28, | ||||
/// <summary> | |||||
/// 中考实时心率数据上报 | |||||
/// </summary> | |||||
ZkRealHeartRate = 29, | |||||
/// <summary> | /// <summary> | ||||
/// 绑定业务 | /// 绑定业务 | ||||
/// </summary> | /// </summary> | ||||
@@ -11,6 +11,7 @@ using TelpoDataService.Util.Entities.GpsLocationHistory; | |||||
using TelpoDataService.Util.Models; | using TelpoDataService.Util.Models; | ||||
using TelpoDataService.Util.QueryObjects; | using TelpoDataService.Util.QueryObjects; | ||||
using TelpoPush.Common; | using TelpoPush.Common; | ||||
using TelpoPush.Models.Enum; | |||||
using TelpoPush.Models.MqTemplates; | using TelpoPush.Models.MqTemplates; | ||||
using TelpoPush.Service.Cache; | using TelpoPush.Service.Cache; | ||||
@@ -20,17 +21,20 @@ namespace TelpoPush.Service.Biz | |||||
{ | { | ||||
private readonly ILogger<ZkRealHRMonitorService> _logger; | private readonly ILogger<ZkRealHRMonitorService> _logger; | ||||
private readonly HttpHelperAsync _httpHelper; | |||||
private readonly RedisUtil _redis; | private readonly RedisUtil _redis; | ||||
private readonly GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> _messageRealHeartRateAiClient; | private readonly GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> _messageRealHeartRateAiClient; | ||||
public ZkRealHRMonitorService( | public ZkRealHRMonitorService( | ||||
ILogger<ZkRealHRMonitorService> logger, RedisUtil redis, | |||||
ILogger<ZkRealHRMonitorService> logger, RedisUtil redis, HttpHelperAsync httpHelper, | |||||
GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> messageRealHeartRateAiClient) | GpsLocationHistoryAccessorClient<HisGpsRealHeartRate> messageRealHeartRateAiClient) | ||||
{ | { | ||||
_logger = logger; | _logger = logger; | ||||
_redis = redis; | _redis = redis; | ||||
_httpHelper = httpHelper; | |||||
_messageRealHeartRateAiClient = messageRealHeartRateAiClient; | _messageRealHeartRateAiClient = messageRealHeartRateAiClient; | ||||
} | } | ||||
//数据保存、推送 | |||||
public async Task Save(ZkRealHeartRateData data, string MessageId) | public async Task Save(ZkRealHeartRateData data, string MessageId) | ||||
{ | { | ||||
string deviceKey = await _redis.GetHealthyDeviceKey(data.imei); | string deviceKey = await _redis.GetHealthyDeviceKey(data.imei); | ||||
@@ -54,10 +58,25 @@ namespace TelpoPush.Service.Biz | |||||
CreateTime = DateTime.Now, | CreateTime = DateTime.Now, | ||||
}; | }; | ||||
await _messageRealHeartRateAiClient.AddAsync(model); | 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) | public async Task SaveAnomalyCancel(ZkRealHeartRateAnomalyCancelData data, string MessageId) | ||||
{ | { | ||||
string deviceKey = await _redis.GetHealthyDeviceKey(data.imei); | 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 | public class RedisUtil | ||||
{ | { | ||||
private const string CACHE_HASH_KEY_TELPO_MANUFACTOR_CONFIG = "TELPO#MANUFACTOR_CONFG_HASH"; | 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 ILogger<RedisUtil> _logger; | ||||
private readonly ServiceConfig _configService; | 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() | //public async Task<string> ManufactorKafkaTopicQuery() | ||||
//{ | //{ | ||||