using HealthMonitor.Model.Service.Mapper; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TelpoDataService.Util.Clients; using TelpoDataService.Util.Entities.GpsCard; using TelpoDataService.Util.Entities.GpsLocationHistory; using TelpoDataService.Util.Models; using TelpoDataService.Util.QueryObjects; using HealthMonitor.Common; namespace HealthMonitor.Service.Cache { public class DeviceCacheManager { private readonly ILogger<DeviceCacheManager> _logger; private const string CACHE_KEY_DEVICE = "Device_"; private const string CACHE_KEY_GPSDEVICE_WATCH_CONFIG = "#GPSDEVICE_WATCH_CONFIG_HASH"; private const string CACHE_KEY_FETALMOVEMENT = "FM_"; private const string CACHE_KEY_FETALHEARTRATE = "FHR_"; private const string CACHE_KEY_PHRFREQSTATUS = "PhrFreqStatus_"; private readonly GpsLocationHistoryAccessorClient<HisGpsFetalMovement> _hisFetalMovementApiClient; private readonly GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> _hisFetalHeartRateApiClient; public DeviceCacheManager(ILogger<DeviceCacheManager> logger , GpsLocationHistoryAccessorClient<HisGpsFetalMovement> hisFetalMovementApiClient , GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> hisFetalHeartRateApiClient) { _logger = logger; _hisFetalMovementApiClient = hisFetalMovementApiClient; _hisFetalHeartRateApiClient = hisFetalHeartRateApiClient; } /// <summary> /// 获取device_id /// </summary> /// <param name="sn"></param> /// <returns></returns> public async Task<GpsDevice?> GetDeviceBySerialNoAsync(string sn) { string key = CACHE_KEY_DEVICE + sn; var device = await RedisHelperDb10.GetAsync<GpsDevice>(key).ConfigureAwait(false); return device; } /// <summary> /// /// </summary> /// <param name="sn"></param> /// <param name="bizCode"> /// 业务码 /// 0067 胎心启动配置 /// </param> /// <returns></returns> public async Task<JObject?> GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(string sn, string bizCode) { if (string.IsNullOrWhiteSpace(sn)) return null; try { var config = await RedisHelperDb7.HGetAsync(CACHE_KEY_GPSDEVICE_WATCH_CONFIG, $"{sn}_{bizCode}").ConfigureAwait(false); if (config == null) return null; _logger.LogInformation($"{sn} 配置信息 {config}"); return (JObject)JsonConvert.DeserializeObject(config)!; } catch (Exception ex) { _logger.LogWarning($"Redis DB7发生异常:{ex.Message}, {ex.StackTrace}"); } return null; } #region 心率相关 /// <summary> /// 读取高频状态 /// </summary> /// <param name="sn"></param> /// <returns></returns> public async Task<PregnancyHeartRateModel?> GetPregnancyHeartRateFreqStatusAsync(string sn) { try { var key = CACHE_KEY_PHRFREQSTATUS+sn; var status = await RedisHelper.GetAsync(key).ConfigureAwait(false); if (string.IsNullOrEmpty(status)) return null; return JsonConvert.DeserializeObject<PregnancyHeartRateModel>(status); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } return null; } public async Task SetPregnancyHeartRateFreqStatusAsync(string sn, PregnancyHeartRateModel status,int expire=-1) { try { var key = CACHE_KEY_PHRFREQSTATUS + sn; var data=JsonConvert.SerializeObject(status); await RedisHelper.SetAsync(key, data, expire).ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } } public async Task DelPregnancyHeartRateFreqStatusAsync(string sn) { try { var key = CACHE_KEY_PHRFREQSTATUS + sn; await RedisHelper.DelAsync(key).ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } } public async Task SetFetalHeartRateAsync(string serialNo, string sampleTime) { try { var key = $"{CACHE_KEY_FETALHEARTRATE}_{serialNo}_{sampleTime}"; var time = long.Parse(sampleTime.Length < 13 ? sampleTime.PadRight(13, '0') : sampleTime); var value = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(time).ToString("yyyy-MM-dd HH:mm:ss"); await RedisHelper.SetAsync(key, value, 7200).ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } } public async Task<bool> FetalHeartRateIsExistedAsync(string serialNo, string sampleTime) { try { var key = $"{CACHE_KEY_FETALHEARTRATE}_{serialNo}_{sampleTime}"; var res = await RedisHelper.GetAsync(key).ConfigureAwait(false); if (string.IsNullOrEmpty(res)) { GeneralParam param = new() { Filters = new List<QueryFilterCondition> { new () { Key=nameof(HisGpsFetalHeartRate.Serialno), Value=serialNo, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal }, new () { Key=nameof(HisGpsFetalHeartRate.SampleTime), Value=sampleTime, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal }, } }; var isFetalMovementExist = await _hisFetalHeartRateApiClient.GetFirstAsync(param, serialNo[^2..], null, new RequestHeader { RequestId = Guid.NewGuid().ToString("D") }); if (isFetalMovementExist != null) { await SetFetalHeartRateAsync(serialNo, sampleTime); return true; } } else { return true; } } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } return false; } #endregion #region 胎动相关 public async Task SetFetalMovementAsync(string serialNo, string sampleTime, HisGpsFetalMovement fm) { try { var key = $"{CACHE_KEY_FETALMOVEMENT}_{serialNo}_{sampleTime}"; var time = long.Parse(sampleTime.Length < 13 ? sampleTime.PadRight(13, '0') : sampleTime); var value = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(time).ToString("yyyy-MM-dd HH:mm:ss"); fm.SampleTime = value; await RedisHelper.SetAsync(key, JsonConvert.SerializeObject(fm), 7200).ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } } public async Task<bool> FetalMovementIsExistedAsync(string serialNo, string sampleTime) { try { var key = $"{CACHE_KEY_FETALMOVEMENT}_{serialNo}_{sampleTime}"; var res = await RedisHelper.GetAsync(key).ConfigureAwait(false); if (string.IsNullOrEmpty(res)) { GeneralParam param = new() { Filters = new List<QueryFilterCondition> { new () { Key=nameof(HisGpsFetalMovement.Serialno), Value=serialNo, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal }, new () { Key=nameof(HisGpsFetalMovement.SampleTime), Value=sampleTime, ValueType=QueryValueTypeEnum.String, Operator=QueryOperatorEnum.Equal }, } }; var isFetalMovementExist = await _hisFetalMovementApiClient.GetFirstAsync(param, serialNo[^2..], null, new RequestHeader { RequestId = Guid.NewGuid().ToString("D") }); if (isFetalMovementExist != null) { await SetFetalMovementAsync(serialNo, sampleTime, isFetalMovementExist); return true; } } else { return true; } } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } return false; } #endregion #region 业务间隔 public async Task<string?> GetBizIntervalAsync(string sn, string biz) { try { var key = biz + "-"+sn; var status = await RedisHelper.GetAsync(key).ConfigureAwait(false); return status; } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } return null; } /// <summary> /// 业务间隔(默认15分钟) /// </summary> /// <param name="sn"></param> /// <param name="biz"></param> /// <param name="ttl"></param> /// <returns></returns> public async Task SetBizIntervalAsync(string sn, string biz, int ttl=60*15) { try { var key = biz + "-" + sn; await RedisHelper.SetAsync(key, biz, ttl).ConfigureAwait(false); } catch (Exception ex) { _logger.LogWarning($"Redis 发生异常:{ex.Message}, {ex.StackTrace}"); } } #endregion } }