using GpsCardGatewayPosition.Model.Config;
using GpsCardGatewayPosition.Model.Enum;
using GpsCardGatewayPosition.Service.Cache;
using GpsCardGatewayPosition.Service.MqProducer;
using GpsCardGatewayPosition.Service.Resolver.Property.Dto;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelpoDataService.Util.Clients;
using TelpoDataService.Util.Entities.GpsLocationHistory;
namespace GpsCardGatewayPosition.Service.Biz.Health
{
public class HealthLogic
{
public enum TemperatureStatusType : int
{
///
/// 不存在
///
NotExisted = 0,
///
/// 不完整,已填写内容
///
FilledContent = 1,
///
/// 不完整,已填写地址
///
FilledAddress = 2,
///
/// 信息已完整
///
Complete = 3,
///
///
///
Reserved
}
private const string KEY_CACHE_TEMPERATURE_STATUS = "Temperature_Status";
private const int KEY_CACHE_SECONDS = 600;
private readonly ServiceConfig _configService;
private readonly MqProcessLogic _serviceMqProcess;
private readonly PersonCacheManager _personCacheMgr;
private readonly DeviceCacheManager _deviceCacheMgr;
//private readonly StepCacheManager _stepCacheMgr;
private readonly GpsLocationHistoryAccessorClient _hisTemperatureApiClient;
private readonly GpsLocationHistoryAccessorClient _hisStepApiClient;
private readonly GpsLocationHistoryAccessorClient _hisHeartApiClient;
private readonly GpsLocationHistoryAccessorClient _hisSpo2ApiClient;
private readonly GpsLocationHistoryAccessorClient _hisBloodPressApiClient;
private readonly GpsLocationHistoryAccessorClient _hisDrownReportApiClient;
private readonly GpsLocationHistoryAccessorClient _hisWearStatusApiClient;
private readonly GpsLocationHistoryAccessorClient _hisSportResultApiClient;
private readonly ILogger _logger;
public HealthLogic(IOptions optConfigService, MqProcessLogic serviceMqProcess,
// StepCacheManager stepCacheMgr,
PersonCacheManager personCacheMgr,
DeviceCacheManager deviceCacheMgr,
GpsLocationHistoryAccessorClient temperatureApiClient,
GpsLocationHistoryAccessorClient stepApiClient,
GpsLocationHistoryAccessorClient hisHeartApiClient,
GpsLocationHistoryAccessorClient hisSpo2ApiClient,
GpsLocationHistoryAccessorClient hisBloodPressApiClient,
GpsLocationHistoryAccessorClient hisDrownReportApiClient,
GpsLocationHistoryAccessorClient hisWearStatusApiClient,
GpsLocationHistoryAccessorClient hisSportResultApiClient,
ILogger logger)
{
_configService = optConfigService.Value;
_serviceMqProcess = serviceMqProcess;
_deviceCacheMgr = deviceCacheMgr;
_personCacheMgr = personCacheMgr;
//_stepCacheMgr = stepCacheMgr;
_hisTemperatureApiClient = temperatureApiClient;
_hisStepApiClient = stepApiClient;
_logger = logger;
_hisHeartApiClient = hisHeartApiClient;
_hisSpo2ApiClient = hisSpo2ApiClient;
_hisDrownReportApiClient = hisDrownReportApiClient;
_hisWearStatusApiClient = hisWearStatusApiClient;
_hisBloodPressApiClient = hisBloodPressApiClient;
_hisSportResultApiClient = hisSportResultApiClient;
}
#region 体温相关
///
/// 处理测温事件消息(内容部分)
///
///
/// 和serialno组合的tempId
/// 返回测温对象用于插入数据库
/// 返回测温对象用于更新数据库
/// 后续处理
/// 定位类型 // 2022/11/10 增加 type 参数判断定位类型
///
public async Task HandleTemperatureContent(string messageId, string tempId,
Func factoryToAdd, Func factoryToUpdate,
Action handleFollowup = null, LocationType type = default)
{
if (factoryToAdd == null || factoryToUpdate == null) throw new ArgumentNullException();
HisGpsTemperature temperature = null;
var status = await GetTemperatureStatusAsync(tempId).ConfigureAwait(false);
if (status == TemperatureStatusType.Complete || status == TemperatureStatusType.FilledContent)
{
_logger.LogWarning($"TEMPERATURE事件[{tempId}]已处理(内容部分)|事件");
return false;
}
if (status == TemperatureStatusType.NotExisted)
{
temperature = factoryToAdd.Invoke();
await AddTemperatureAsync(messageId, temperature).ConfigureAwait(false);
SetTemperatureStatus(tempId, TemperatureStatusType.FilledContent);
// 对应无地址也要推送测温情况,创建一个线程,并让该线程休眠 60 秒
Thread thread = new Thread(async () =>
{
_logger.LogInformation($"messageId:[{messageId}],TEMPERATURE事件[{tempId}] 无地址测温推送延时60s,判断入库后gps_temperature表中address是否为空,若为空也推送");
Task.Delay(TimeSpan.FromSeconds(60)).Wait();
var temperatureLate = await GetTemperatureAsync(messageId, tempId).ConfigureAwait(false);
if (string.IsNullOrEmpty(temperatureLate.Address))
{
PushWxTemperature(messageId, temperatureLate);
_logger.LogInformation($"messageId:[{messageId}],TEMPERATURE事件[{tempId}]延时60s,无地址已推送");
}
_logger.LogInformation($"messageId:[{messageId}],TEMPERATURE事件[{tempId}]延时60s,在HandleTemperatureAddressAsync地址已推送");
});
thread.Start();
}
else
{
temperature = await GetTemperatureAsync(messageId, tempId).ConfigureAwait(false);
if (temperature != null)
{
temperature = factoryToUpdate.Invoke(temperature);
await UpdateTemperatureAsync(messageId, temperature).ConfigureAwait(false);
SetTemperatureStatus(tempId, TemperatureStatusType.Complete);
//推送微信公众号
await PushWxTemperature(messageId, temperature, type);
}
}
handleFollowup?.Invoke();
return true;
}
///
/// 处理测温事件消息(地址信息部分)
///
///
/// 和serialno组合的tempId
/// 返回测温对象用于插入数据库
/// 返回测温对象用于更新数据库
/// 后续处理
/// 定位类型 // 2022/11/10 增加 type 参数判断定位类型
///
public async Task HandleTemperatureAddressAsync(string messageId, string tempId,
Func factoryToAdd, Func factoryToUpdate,
Action handleFollowup = null, LocationType type = default)
{
if (factoryToAdd == null || factoryToUpdate == null) throw new ArgumentNullException();
HisGpsTemperature temperature = null;
var status = await GetTemperatureStatusAsync(tempId).ConfigureAwait(false);
if (status == TemperatureStatusType.Complete || status == TemperatureStatusType.FilledAddress)
{
_logger.LogWarning($"TEMPERATURE事件[{tempId}]已处理(地址信息内容部分)");
return false;
}
if (status == TemperatureStatusType.NotExisted)
{
temperature = factoryToAdd.Invoke();
await AddTemperatureAsync(messageId, temperature).ConfigureAwait(false);
SetTemperatureStatus(tempId, TemperatureStatusType.FilledAddress);
// 2023/02/02 新增测温数据 没有匹配定位信息,也推送给第三方平台。
// if (temperature.Temperature != null)
// {
// PushWxTemperature(messageId, temperature);
// }
}
else
{
temperature = await GetTemperatureAsync(messageId, tempId).ConfigureAwait(false);
if (temperature != null)
{
temperature = factoryToUpdate.Invoke(temperature);
await UpdateTemperatureAsync(messageId, temperature).ConfigureAwait(false);
SetTemperatureStatus(tempId, TemperatureStatusType.Complete);
//推送微信公众号
PushWxTemperature(messageId, temperature, type);
}
}
handleFollowup?.Invoke();
return true;
}
// 2022/11/10 增加 type 参数判断定位类型
private async Task PushWxTemperature(string messageId, HisGpsTemperature temperature, LocationType type = default)
{
var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(messageId, temperature.Serialno);
if (device == null) return;
string deviceName = temperature.Serialno;
var person = await _personCacheMgr.GetPersonBySerialNoAsync(messageId, temperature.Serialno).ConfigureAwait(false);
if (person != null) deviceName = person.NickName;
MethodType method = MethodType.Manual;
//if (temperature.Method == 0) method = MethodType.Manual;
if (temperature.Method == 1) method = MethodType.Period;
await _serviceMqProcess.ProcessWxTemperatureAsync(messageId, new TemperatureInfoModel
{
DeviceId = device.DeviceId,
DeviceName = deviceName,
TempId = temperature.TempId,
TempTime = temperature.LastUpdate,
Imei = temperature.Serialno,
Temperature = temperature.Temperature,
Province = temperature.Province,
City = temperature.City,
District = temperature.District,
Address = temperature.Address
}, type, method);
}
private async Task GetTemperatureStatusAsync(string tempId)
{
var key = $"{KEY_CACHE_TEMPERATURE_STATUS}_{tempId}";
var result = await RedisHelper.GetAsync(key);
if (result == null) return TemperatureStatusType.NotExisted;
if (result > TemperatureStatusType.Reserved || result < TemperatureStatusType.NotExisted) return TemperatureStatusType.NotExisted;
return result.Value;
}
private void SetTemperatureStatus(string sosId, TemperatureStatusType status)
{
var key = $"{KEY_CACHE_TEMPERATURE_STATUS}_{sosId}";
RedisHelper.SetAsync(key, (int)status, KEY_CACHE_SECONDS);
}
public async Task GetTemperatureAsync(string messageId, string temperatureId)
{
try
{
//var param = new GeneralParam
//{
// Filters = new List
// {
// new QueryFilterCondition
// {
// Key=nameof(HisGpsTemperature.TempId),
// Value=tempId,
// ValueType=QueryValueTypeEnum.String,
// Operator=QueryOperatorEnum.Equal
// },
// new QueryFilterCondition
// {
// Key=nameof(HisGpsTemperature.Serialno),
// Value=serialno,
// ValueType=QueryValueTypeEnum.String,
// Operator=QueryOperatorEnum.Equal
// }
// }
//};
//var temperature = await _hisTemperatureApiClient.GetFirstAsync(param, header: new RequestHeader { RequestId = messageId }).ConfigureAwait(false);
//return temperature;
var temperature = await _hisTemperatureApiClient.GetByIdAsync(temperatureId, header: new RequestHeader { RequestId = messageId }).ConfigureAwait(false);
return temperature;
}
catch (Exception ex)
{
_logger.LogError($"根据{temperatureId}获取指定测温信息失败, {ex.Message}, {ex.StackTrace}");
return null;
}
}
public async Task AddTemperatureAsync(string messageId, HisGpsTemperature temperature)
{
try
{
// 体温gps_temperature,步数gps_step,血压gps_bloodpress,心率gps_heart_rate,血氧gps_spo2 五个表新增 person_id 字段
var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(messageId, temperature.Serialno).ConfigureAwait(false);
var persnId = string.Empty;
if (person != null && person.Person != null) persnId = person.Person.PersonId;
temperature.PersonId = persnId;
await _hisTemperatureApiClient.AddAsync(temperature, header: new RequestHeader { RequestId = messageId }).ConfigureAwait(false);
return true;
}
catch (Exception ex)
{
_logger.LogError($"新增体温信息发生异常:{ex.Message}, {ex.StackTrace}");
}
return false;
}
public async Task UpdateTemperatureAsync(string messageId, HisGpsTemperature temperature)
{
try
{
await _hisTemperatureApiClient.UpdateAsync(temperature, header: new RequestHeader { RequestId = messageId }).ConfigureAwait(false);
return true;
}
catch (Exception ex)
{
_logger.LogError($"更新体温信息发生异常:{ex.Message}, {ex.StackTrace}");
}
return false;
}
#endregion
}
}