380 lines
15 KiB
C#
380 lines
15 KiB
C#
using DotNetCore.CAP;
|
||
using Furion.DependencyInjection;
|
||
using Furion.DistributedIDGenerator;
|
||
using Microsoft.Extensions.Caching.Distributed;
|
||
using Nirvana.Common;
|
||
using Senparc.Weixin.MP.AdvancedAPIs;
|
||
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
|
||
using Senparc.Weixin.Open.Containers;
|
||
using SqlSugar;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using YBDevice.Core;
|
||
using YBDevice.Entity;
|
||
|
||
namespace YBDevice.NApi.Application.BodyInfo
|
||
{
|
||
/// <summary>
|
||
/// 八电极处理接口
|
||
/// </summary>
|
||
public class BodyService : IBodyService, ITransient
|
||
{
|
||
public string component_AppId = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Appid;
|
||
public string component_Secret = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Secret;
|
||
public string component_Token = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Token;
|
||
public string component_EncodingAESKey = Senparc.Weixin.Config.SenparcWeixinSetting.Component_EncodingAESKey;
|
||
private readonly ISqlSugarRepository<YB_WifiBind> repository;
|
||
private readonly SqlSugarClient dbClient;
|
||
private readonly ILoggerService _loggerService;
|
||
private readonly INoticeService _noticeService;
|
||
private readonly IDistributedCache _cache;
|
||
private readonly ICapPublisher _capBus;
|
||
public BodyService(ISqlSugarRepository<YB_WifiBind> sqlSugarRepository, ILoggerService loggerService, INoticeService noticeService, IDistributedCache cache, ICapPublisher capPublisher)
|
||
|
||
{
|
||
repository = sqlSugarRepository;
|
||
dbClient = repository.Context;
|
||
_loggerService = loggerService;
|
||
_noticeService = noticeService;
|
||
_cache = cache;
|
||
_capBus = capPublisher;
|
||
}
|
||
/// <summary>
|
||
/// 数据包解析
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
private BodyAnalyDto AnalyProto(BodyRequstDto data)
|
||
{
|
||
BodyAnalyDto dto = new BodyAnalyDto();
|
||
//检查是否为有效的base64数据
|
||
if (!AESEncrypt.IsBase64(data.@params))
|
||
{
|
||
dto.data = data.@params;
|
||
return dto;
|
||
}
|
||
//数据为base64加密
|
||
byte[] resultByte = Convert.FromBase64String(data.@params);
|
||
dto.data = resultByte.BytesToHexStr();
|
||
_loggerService.AddLogger($"八电极wifi结果推送,解析出的数据:{dto.data}", 2);
|
||
int len = resultByte.Count();//数据总长度
|
||
//长度格式是否正确,固定长度为36位
|
||
if (len < 33)
|
||
{
|
||
return dto;
|
||
}
|
||
//前15个字节为sn。中间以 00 分隔。后面为测量结果数据 AA 00 01 F4 00 64 00 64 00 64 00 64 02 30 06 A4 00 00 00 00
|
||
int i = 0;
|
||
byte[] snbyte = new byte[15];
|
||
for (i = 0; i < 15; i++)
|
||
{
|
||
snbyte[i] = resultByte[i];
|
||
}
|
||
dto.sn = snbyte.BytesToHexStr().Replace(" ", "");
|
||
dto.splitstr = resultByte[i].ByteToHexStr();
|
||
int datalen = len - 16;//数据体长度
|
||
byte[] databyte = new byte[datalen];
|
||
i++;
|
||
for (int j = 0; j < datalen; j++)
|
||
{
|
||
databyte[j] = resultByte[i];
|
||
i++;
|
||
}
|
||
dto.Header = databyte[0].ByteToHexStr();
|
||
if (dto.Header != "A1" && dto.Header != "A2") //第一条数据为A1,第二条数据为A2
|
||
{
|
||
return dto;
|
||
}
|
||
dto.ischecked = true;
|
||
string tmpstr = "";
|
||
for (int j = 1; j < datalen; j++)
|
||
{
|
||
tmpstr += databyte[j].ByteToHexStr();
|
||
if (dto.Header == "A1")
|
||
{
|
||
if (j == 3)
|
||
{
|
||
dto.Weight = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 7)
|
||
{
|
||
dto.lefthandimp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 11)
|
||
{
|
||
dto.righthandimp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 15)
|
||
{
|
||
dto.leftfootimp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
}
|
||
if (dto.Header == "A2")
|
||
{
|
||
|
||
if (j == 4)
|
||
{
|
||
dto.rightfootimp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 8)
|
||
{
|
||
dto.bodyimp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 10)
|
||
{
|
||
dto.height = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
}
|
||
}
|
||
return dto;
|
||
}
|
||
///<summary>
|
||
/// 处理wifi模块发送过来的数据
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<int> HandlerBodyDataAsync(BodyRequstDto data)
|
||
{
|
||
//记录发送过来的数据
|
||
_loggerService.AddLogger($"八电极发送原始数据,data={data.ToJson()}", 2);
|
||
var result = AnalyProto(data);
|
||
if (!result.ischecked)
|
||
{
|
||
return -1;
|
||
}
|
||
//数据分两条发送,首先保存第一条,然后根据二条的数据间隔进行保存
|
||
//保存到redis
|
||
var sn = result.sn;
|
||
var key = $"YBDeviceCache:Container:{sn}";
|
||
if (result.Header == "A1")
|
||
{
|
||
var param1 = $"{result.ToJson()}";
|
||
var param1byte = Encoding.UTF8.GetBytes(param1);
|
||
await _cache.SetAsync(key, param1byte, new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(5)));
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
var existsbyte = await _cache.GetAsync(key);
|
||
if (existsbyte != null && existsbyte.Length > 0)
|
||
{
|
||
var firstdata = Encoding.UTF8.GetString(existsbyte);
|
||
var firstjsondata = firstdata.ToObject<BodyAnalyDto>();
|
||
result.Weight = firstjsondata.Weight;
|
||
result.lefthandimp = firstjsondata.lefthandimp;
|
||
result.righthandimp = firstjsondata.righthandimp;
|
||
result.leftfootimp = firstjsondata.leftfootimp;
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
//检查设备是否存在
|
||
var equ = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == result.sn);
|
||
if (equ == null)
|
||
{
|
||
_loggerService.AddLogger($"八电极wifi结果推送,设备未找到,参数:{result.ToJson()}", 3);
|
||
return -1;
|
||
}
|
||
//获取设备绑定的用户列表
|
||
var list = await dbClient.Queryable<YB_WifiBind>().Where(x => x.DevCode == result.sn && x.Subscribe == 1).ToListAsync();
|
||
if (list.Count == 0)
|
||
{
|
||
_loggerService.AddLogger($"八电极wifi结果推送,未绑定用户或均已取关,参数:{result.ToJson()}", 3);
|
||
return -1;
|
||
}
|
||
//由于传送过来的体重为实际*100,身高为实际*10
|
||
decimal weight = (result.Weight * 1.0 / 100.0).ToDecimal();
|
||
decimal height = (result.height * 1.0 / 10.0).ToDecimal();
|
||
#region 记录数据
|
||
Guid resultid = IDGen.NextID();
|
||
await _capBus.PublishAsync("result.service.insertuserresult", new InsertResultDataS2SDto
|
||
{
|
||
DevId = equ.Id,
|
||
IsUserTake = false,
|
||
DeviceLastHeartTime = equ.LastHeartTime,
|
||
DevType = equ.Type,
|
||
BusinessId = equ.BusinessId,
|
||
CreateTime = DateTime.Now,
|
||
SourceType = 3,
|
||
ecode = equ.Ecode,
|
||
familyid = 0,
|
||
fansid = null,
|
||
height = height,
|
||
imp = result.bodyimp,
|
||
LeftArmImp = result.lefthandimp,
|
||
LeftLegImp = result.leftfootimp,
|
||
RightArmImp = result.righthandimp,
|
||
RightLegImp = result.rightfootimp,
|
||
UserId = 0,
|
||
weight = weight,
|
||
orderid = null,
|
||
publicid = "",
|
||
ResultId = resultid
|
||
});
|
||
#endregion
|
||
//发送模版消息
|
||
decimal mheight = height / 100.0m;
|
||
var tpldata = new
|
||
{
|
||
first = new TemplateDataItem($"收到新的测量结果"),
|
||
keyword1 = new TemplateDataItem($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}"),
|
||
keyword2 = new TemplateDataItem($"{height}"),
|
||
keyword3 = new TemplateDataItem($"{weight}"),
|
||
keyword4 = new TemplateDataItem($"{(((weight / (mheight * mheight)) * 10.0m) / 10.0m).ToDecimal(1)}"),
|
||
remark = new TemplateDataItem($"点击查看您的测量报告")
|
||
};
|
||
var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, "wxda671f842dfda2b8");
|
||
string url = $"https://ybapi.ybhdmob.com/body/br?d={result.sn}|{weight}|{height}|{result.lefthandimp}|{result.righthandimp}|{result.leftfootimp}|{result.rightfootimp}|{result.bodyimp}|{resultid}";
|
||
|
||
foreach (var item in list)
|
||
{
|
||
SendTemplateMessageResult results = await TemplateApi.SendTemplateMessageAsync(token, item.OpenId, "0P6GebIlc5vjYJnO272DNt94VS1SDqxDxRgNzAQTmDA", url, tpldata);
|
||
//记录发送结果
|
||
_loggerService.AddLogger($"八电极wifi结果推送,模版消息推送,参数:{result.ToJson()}\r\n结果:{results.ToJson()}", 3);
|
||
}
|
||
return 0;
|
||
}
|
||
/// <summary>
|
||
/// 处理PCH01W发送过来的数据
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public async Task<object> Handler01WDataAsync(BodyRequstDto data)
|
||
{
|
||
var result = AnalyH01WProto(data);
|
||
var successdata = Encoding.UTF8.GetBytes("A901019A");
|
||
var returndata = new
|
||
{
|
||
status = "1",
|
||
data = Convert.ToBase64String(successdata)
|
||
};
|
||
if (!result.ischecked)
|
||
{
|
||
return returndata;
|
||
}
|
||
//发送模版消息
|
||
decimal height = (result.Height * 1.0m) / 10.0m;
|
||
decimal weight = (result.Weight * 1.0m) / 10.0m;
|
||
var tpldata = new
|
||
{
|
||
first = new TemplateDataItem($"收到新的测量结果"),
|
||
keyword1 = new TemplateDataItem($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}"),
|
||
keyword2 = new TemplateDataItem($"{height}CM|{result.imp}Ω"),
|
||
keyword3 = new TemplateDataItem($"{weight}斤"),
|
||
keyword4 = new TemplateDataItem($"{result.sn}"),
|
||
remark = new TemplateDataItem($"点击查看您的测量报告")
|
||
};
|
||
var token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, "wxda671f842dfda2b8");
|
||
var openlist = new List<string>()
|
||
{
|
||
"o2No269VSmA3C3WNFLDrgc1k2vyo",
|
||
"o2No265s2YTuDN4CQwfCcdflk4L0"
|
||
};
|
||
foreach (var item in openlist)
|
||
{
|
||
SendTemplateMessageResult results = await TemplateApi.SendTemplateMessageAsync(token, item, "0P6GebIlc5vjYJnO272DNt94VS1SDqxDxRgNzAQTmDA", "", tpldata);
|
||
//记录发送结果
|
||
_loggerService.AddLogger($"PCH01Wwifi结果推送,模版消息推送,参数:{result.ToJson()}\r\n结果:{results.ToJson()}", 3);
|
||
}
|
||
return returndata;
|
||
}
|
||
/// <summary>
|
||
/// 解析PCH01W数据包
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
private H01WAnalyDto AnalyH01WProto(BodyRequstDto data)
|
||
{
|
||
_loggerService.AddLogger($"PCH01W发送原始数据,data={data.ToJson()}", 3);
|
||
H01WAnalyDto dto = new H01WAnalyDto();
|
||
//检查是否为有效的base64数据
|
||
if (!AESEncrypt.IsBase64(data.@params))
|
||
{
|
||
dto.data = data.@params;
|
||
return dto;
|
||
}
|
||
//数据为base64加密
|
||
byte[] resultByte = Convert.FromBase64String(data.@params);
|
||
dto.data = resultByte.BytesToHexStr();
|
||
_loggerService.AddLogger($"PCH01W_wifi结果推送,解析出的数据:{dto.data}", 3);
|
||
int len = resultByte.Count();//数据总长度
|
||
//长度格式是否正确,固定长度为36位
|
||
if (len < 33)
|
||
{
|
||
return dto;
|
||
}
|
||
//前15个字节为sn。中间以 00 分隔。后面为测量结果数据 A9 0F 01
|
||
int i = 0;
|
||
byte[] snbyte = new byte[15];
|
||
for (i = 0; i < 15; i++)
|
||
{
|
||
snbyte[i] = resultByte[i];
|
||
}
|
||
dto.sn = snbyte.BytesToHexStr().Replace(" ", "");
|
||
dto.splitstr = resultByte[i].ByteToHexStr();
|
||
int datalen = len - 16;//数据体长度
|
||
byte[] databyte = new byte[datalen];
|
||
i++;
|
||
for (int j = 0; j < datalen; j++)
|
||
{
|
||
databyte[j] = resultByte[i];
|
||
i++;
|
||
}
|
||
dto.Header = databyte[0].ByteToHexStr();
|
||
if (dto.Header != "A9") //数据包头为A9
|
||
{
|
||
return dto;
|
||
}
|
||
//检查标志位
|
||
var flag = databyte[2].ByteToHexStr();
|
||
if (flag != "01")
|
||
{
|
||
return dto;
|
||
}
|
||
dto.ischecked = true;
|
||
string tmpstr = "";
|
||
for (int j = 1; j < datalen; j++)
|
||
{
|
||
tmpstr += databyte[j].ByteToHexStr();
|
||
if (j == 2)
|
||
{
|
||
tmpstr = "";
|
||
}
|
||
if (j == 5)
|
||
{
|
||
dto.Weight = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 11)
|
||
{
|
||
tmpstr = "";
|
||
}
|
||
if (j == 13)
|
||
{
|
||
dto.Height = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
if (j == 15)
|
||
{
|
||
dto.imp = tmpstr.HexToDesc();
|
||
tmpstr = "";
|
||
}
|
||
}
|
||
return dto;
|
||
}
|
||
}
|
||
}
|