using Furion;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Mapster;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using Senparc.Weixin;
using Senparc.Weixin.WxOpen.AdvancedAPIs.Sns;
using Senparc.Weixin.WxOpen.Containers;
using Senparc.Weixin.WxOpen.Entities;
using Senparc.Weixin.WxOpen.Helpers;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YBDevice.Body.BodyFatHelper;
using YBDevice.Body.Level;
using YBDevice.Entity;
using YBDevice.Entity.DataModel.ThirdOpen;
using YBDevice.NApi.Application.ThirdClient.Family;
namespace YBDevice.NApi.Application.ThirdClient
{
///
/// 第三方相关处理
///
public class OpenService : IOpenService, ITransient
{
private readonly IBodyFatHelperService _bodyFatHelperService;
private readonly ILevelService _levelService;
private readonly ITouTiaoHttp _touTiaoHttp;
private readonly ISqlSugarRepository repository;
private readonly IOpenFamilyService _openFamilyService;
private readonly SqlSugarClient dbClient;
private string WxOpenAppId = Config.SenparcWeixinSetting.Items["childresultclient"].WxOpenAppId;
private string WxOpenAppSecret = Config.SenparcWeixinSetting.Items["childresultclient"].WxOpenAppSecret;
private readonly string TouTiaoAppId = App.Configuration["TouTiaoSettiong:AppId"];
public OpenService(IBodyFatHelperService bodyFatHelperService, ILevelService levelService, ISqlSugarRepository sqlSugarRepository, ITouTiaoHttp touTiaoHttp, IOpenFamilyService openFamilyService)
{
_bodyFatHelperService = bodyFatHelperService;
_levelService = levelService;
repository = sqlSugarRepository;
dbClient = repository.Context;
_touTiaoHttp = touTiaoHttp;
_openFamilyService = openFamilyService;
}
///
/// BMI计算
///
///
///
public async Task CalcBmiAsync(BmiInfoC2SDto data)
{
var bmi = _bodyFatHelperService.CalcBMi(data.Height, data.Weight);
var standdata = await _levelService.LevelAsync(data.Sex, data.Birthday, bmi, LevelType.BMI);
return new ResultInfo(ResultState.SUCCESS, "success", new
{
bmi = bmi,
bmilevel = standdata.Level,
bmilevelcolor = standdata.Color,
bmilevellist = standdata.list
});
}
///
/// 身高预测
///
///
///
public async Task CalcPredictHeightAsync(HeightInfoC2SDto data)
{
var month = data.Birthday.ToMonth();
//获取标准身高
var heightdata = await dbClient.Queryable().Where(x => x.Sex == data.sex && x.Month <= month).OrderBy(x => x.Month, OrderByType.Desc).FirstAsync();
//成年身高预测
decimal adultheight = AdultHeight(data.DadHeight, data.MomHeight, data.sex);
return new ResultInfo(ResultState.SUCCESS, "success", new
{
standheight = heightdata != null ? heightdata.median : 0,
adultheight = adultheight
});
}
///
/// 成年身高预测,女孩的靶身高=(父亲身高+母亲身高-13cm)÷2
/// 男孩的靶身高=(父亲身高+母亲身高+13cm)÷2
///
/// 父亲身高
/// 母亲身高
/// 性别,1-男,2-女,0-未知
///
private static decimal AdultHeight(decimal dadheight, decimal momheight, GenderType sex)
=> (dadheight, momheight, sex) switch
{
_ when dadheight <= 0 || momheight <= 0 => 0,
_ when (sex == GenderType.FeMale) => (37.85m + 0.75m * (dadheight + momheight) / 2).ToDecimal(1),
_ => (45.99m + 0.78m * (dadheight + momheight) / 2).ToDecimal(1)
};
///
/// 登录接口
///
///
///
public async Task OnLoginAsync(TouTiaoLoginC2SDto data)
{
if (data.UA == UAConst.WeiXin)
{
return await WeiXinLogin(data);
}
else
{
return await TouTiaoLoginAsync(data);
}
}
///
/// 生成token
///
///
private ResultInfo GenToken(Guid userid, string openid, string sessionid)
{
openid = openid.ToStr();
sessionid = sessionid.ToStr();
//生成token
var token = JWTEncryption.Encrypt(new Dictionary() {
{"UserId",userid},
{"OpenId",openid }
});
var refreshToken = JWTEncryption.GenerateRefreshToken(token, 43200);
return new ResultInfo(ResultState.SUCCESS, "登录成功", new
{
token = token,
sessionid = sessionid,
refreshtoken = refreshToken
});
}
///
/// 微信登录处理
///
///
///
private async Task WeiXinLogin(TouTiaoLoginC2SDto data)
{
var jsonResult = await SnsApi.JsCode2JsonAsync(WxOpenAppId, WxOpenAppSecret, data.code);
if (jsonResult.errcode == ReturnCode.请求成功)
{
//检查此openid是否已注册
var wxdata = await dbClient.Queryable()
.Where(x => x.OpenId == jsonResult.openid)
.Select(x => new T_UserWX
{
UserId = x.UserId,
OpenId = x.OpenId
})
.FirstAsync()
;
TimeSpan val = new TimeSpan(1, 0, 0);//一个小时
if (wxdata == null)
{
//记录信息
var sessionBag = await SessionContainer.UpdateSessionAsync(jsonResult.openid, jsonResult.openid, jsonResult.session_key, jsonResult.unionid, val);
return new ResultInfo(ResultState.WXUNAUTHORITY, "此账户还未注册", new WxOpenLoginData
{
sessionid = sessionBag.Key
});
}
//刷新key
var sessionbag = await SessionContainer.UpdateSessionAsync(jsonResult.openid, jsonResult.openid, jsonResult.session_key, jsonResult.unionid, val);
//生成token
return GenToken(wxdata.UserId, wxdata.OpenId, sessionbag.Key);
}
return new ResultInfo(ResultState.FAIL, jsonResult.errmsg);
}
///
/// 字节登录处理
///
///
///
private async Task TouTiaoLoginAsync(TouTiaoLoginC2SDto data)
{
var requestdata = new TouTiaoCode2SessionRequest
{
anonymous_code = data.anonymous_code,
code = data.code
};
string errmsg = string.Empty;
var response = await _touTiaoHttp.JSCode2SessionAsync(requestdata, (res, error) =>
{
errmsg = error;
});
if (!string.IsNullOrEmpty(errmsg))
{
return new ResultInfo(ResultState.FAIL, errmsg);
}
var returnstr = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var resdata = returnstr.ToObject>();
if (resdata.err_no != 0)
{
return new ResultInfo(ResultState.FAIL, resdata.err_tips);
}
//检查此openid是否已注册
var wxdata = await dbClient.Queryable()
.Where(x => x.OpenId == resdata.data.openid)
.Select(x => new T_UserWX
{
UserId = x.UserId,
OpenId = x.OpenId
})
.FirstAsync()
;
TimeSpan val = new TimeSpan(1, 0, 0);//一个小时
if (wxdata == null)
{
//记录信息
var sessionBag = await SessionContainer.UpdateSessionAsync(resdata.data.openid, resdata.data.openid, resdata.data.session_key, resdata.data.unionid, val);
return new ResultInfo(ResultState.WXUNAUTHORITY, "此账户还未注册", new WxOpenLoginData
{
sessionid = sessionBag.Key
});
}
//刷新key
var sessionbag = await SessionContainer.UpdateSessionAsync(resdata.data.openid, resdata.data.openid, resdata.data.session_key, resdata.data.unionid, val);
//生成token
return GenToken(wxdata.UserId, wxdata.OpenId, sessionbag.Key);
}
return new ResultInfo(ResultState.FAIL, returnstr);
}
///
/// 获取测量记录列表
///
/// 家庭成员ID
/// 页码
/// 每页显示数量
///
public async Task GetResultListAsync(Guid familyid, int page, int pagesize)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
RefAsync totalnum = 0;
var query = await dbClient.Queryable()
.OrderBy(x => x.ResultTime, OrderByType.Desc)
.Where(x => x.FamilyId == familyid)
.Select(x => new T_Result
{
Height = x.Height,
Weight = x.Weight,
BMI = x.BMI,
CreateTime = x.ResultTime
})
.ToPageListAsync(page, pagesize, totalnum);
var result = query.Adapt>();
var list = new PageParms
{
page = page,
Items = result,
totalnum = totalnum,
limit = pagesize
};
return new ResultInfo(ResultState.SUCCESS, "success", list);
}
///
/// 获取用户信息
///
/// 家庭成员ID
///
public async Task GetUserInfoAsync(Guid? familyid)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
//检查是否有家庭成员ID
if (!familyid.HasValue)
{
familyid = CurrentUser.UserId;
}
var family = await dbClient.Queryable().Where(x => x.Id == familyid)
.Select(x => new T_Family
{
Name = x.Name,
HeadImg = x.HeadImg
})
.FirstAsync();
var familydata = await dbClient.Queryable().Where(x => x.Id == familyid).Select(x => new T_FamilyData
{
Brithday = x.Brithday,
Height = x.Height,
LastResultTime = x.LastResultTime,
Sex = x.Sex,
Weight = x.Weight
}).FirstAsync();
var returndata = new UserInfoS2CDto
{
HeadImg = family != null ? family.HeadImg : "",
Name = family != null ? family.Name : "小白",
Sex = familydata != null ? (GenderType)familydata.Sex : GenderType.UnKnow,
Birthday = familydata != null ? familydata.Brithday : null,
Weight = familydata != null ? familydata.Weight : 0,
Height = familydata != null ? familydata.Height : 0,
LastResultTime = familydata != null ? familydata.LastResultTime : null,
Age = familydata != null ? (familydata.Brithday.HasValue ? familydata.Brithday.Value.ToAAge() : "") : "",
FamilyId = familyid.Value
};
returndata.HeadImg = !string.IsNullOrEmpty(returndata.HeadImg) ? returndata.HeadImg : _openFamilyService.HeadImg(returndata.Sex, 1);
returndata.BMI = _bodyFatHelperService.CalcBMi(returndata.Height, returndata.Weight);
var standdata = await _levelService.LevelAsync(returndata.Sex, returndata.Birthday, returndata.BMI, LevelType.BMI);
returndata.BMILevel = standdata.Level;
returndata.BMILevelColor = standdata.Color;
returndata.BMILevelList = standdata.list;
standdata = await _levelService.LevelAsync(returndata.Sex, returndata.Birthday, returndata.Height, LevelType.Height);
returndata.HeightLevel = standdata.Level;
returndata.HeightLevelColor = standdata.Color;
returndata.HeightLevelList = standdata.list;
standdata = await _levelService.LevelAsync(returndata.Sex, returndata.Birthday, returndata.Weight, LevelType.Weight);
returndata.WeightLevel = standdata.Level;
returndata.WeightLevelColor = standdata.Color;
returndata.WeightLevelList = standdata.list;
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
///
/// 添加测量记录
///
///
///
public async Task AddResultAsync(InsertResultC2SDto data)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
decimal bmi = _bodyFatHelperService.CalcBMi(data.Height, data.Weight);
if (data.CreateTime.HasValue)
{
var ctime = data.CreateTime.ToDate();
string time = $"{ctime.Year}-{ctime.Month}-{ctime.Day} {DateTime.Now.Hour}:{DateTime.Now.Minute}:{DateTime.Now.Second}";
data.CreateTime = time.ToDate();
}
else
{
data.CreateTime = DateTime.Now;
}
var insertresult = new T_Result
{
Height = data.Height,
Weight = data.Weight,
BMI = bmi,
ResultTime = data.CreateTime.Value,
Id = IDGen.NextID(),
UserId = CurrentUser.UserId,
FamilyId = data.FamilyId,
CreateTime = DateTime.Now
};
await dbClient.Insertable(insertresult).ExecuteCommandAsync();
var userdata = await dbClient.Queryable().Where(x => x.Id == data.FamilyId)
.Select(x => new T_FamilyData
{
LastResultTime = x.LastResultTime
})
.FirstAsync()
;
if (userdata != null)
{
if (!userdata.LastResultTime.HasValue || userdata.LastResultTime < insertresult.ResultTime)
{
await dbClient.Updateable().SetColumns(x => new T_FamilyData
{
Height = data.Height,
Weight = data.Weight,
LastResultTime = insertresult.ResultTime,
LastResultId = insertresult.Id
}).Where(x => x.Id == data.FamilyId).ExecuteCommandAsync();
}
}
else
{
await dbClient.Insertable(new T_FamilyData
{
Brithday = null,
Sex = 0,
Height = data.Height,
Id = data.FamilyId,
LastResultTime = insertresult.ResultTime,
Weight = data.Weight,
LastResultId = insertresult.Id
}).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "记录增加成功");
}
///
/// 用户注册
///
///
///
public async Task RegisterAsync(SubmitUserInfoC2SDto data)
{
var sessionbage = await SessionContainer.GetSessionAsync(data.sessionId);
if (sessionbage == null)
{
return new ResultInfo(ResultState.FAIL, "登录信息已过期");
}
//检查此openid是否已绑定用户
var wxdata = await dbClient.Queryable().Where(x => x.OpenId == sessionbage.OpenId)
.Select(x => new T_UserWX
{
UserId = x.UserId
})
.FirstAsync()
;
if (wxdata == null)
{
var user = new T_RegUser
{
Id = IDGen.NextID(),
CreateTime = DateTime.Now,
HeadImg = data.avatarUrl,
Name = data.nickName
};
await dbClient.Insertable(user).ExecuteCommandAsync();
var userwx = new T_UserWX
{
Id = IDGen.NextID(),
OpenId = sessionbage.OpenId.ToStr(),
UserId = user.Id
};
await dbClient.Insertable(userwx).ExecuteCommandAsync();
//增加一个默认家庭成员
var family = new T_Family
{
Id = user.Id,
CreateTime = user.CreateTime,
HeadImg = user.HeadImg,
Name = user.Name,
UserId = user.Id
};
await dbClient.Insertable(family).ExecuteCommandAsync();
return GenToken(user.Id, userwx.OpenId, sessionbage.Key);
}
else
{
await dbClient.Updateable().SetColumns(x => new T_RegUser
{
Name = data.nickName,
HeadImg = data.avatarUrl
}).Where(x => x.Id == wxdata.UserId).ExecuteCommandAsync();
return GenToken(wxdata.UserId, sessionbage.OpenId, sessionbage.Key);
}
}
///
/// 解密用户资料,如果未注册则自动进行注册,否则更新资料
///
///
///
public async Task DecryptDataAsync(DecryptUserInfoC2SDto data)
{
var sessionbage = await SessionContainer.GetSessionAsync(data.sessionId);
if (sessionbage == null)
{
return new ResultInfo(ResultState.FAIL, "登录信息已过期");
}
//_loggerService.AddLogger($"sessionkey={sessionbage.SessionKey}");
//var a = DecodeEncryptedData(sessionbage.SessionKey, data.encryptedData, data.iv);
//_loggerService.AddLogger($"info2={a}");
DecodeEntityBase decodedEntity = null;
DecodedUserInfo userinfo = null;
userinfo = EncryptHelper.DecodeUserInfoBySessionId(
data.sessionId,
data.encryptedData, data.iv);
decodedEntity = userinfo;
//检验水印
var checkWartmark = false;
string appid = data.UA == UAConst.WeiXin ? WxOpenAppId : TouTiaoAppId;
if (decodedEntity != null)
{
checkWartmark = decodedEntity.CheckWatermark(appid);
}
if (!checkWartmark)
{
return new ResultInfo(ResultState.FAIL, "水印验证不通过");
}
//检查此openid是否已绑定用户
var wxdata = await dbClient.Queryable().Where(x => x.OpenId == sessionbage.OpenId)
.Select(x => new T_UserWX
{
UserId = x.UserId
})
.FirstAsync()
;
if (wxdata == null)
{
var user = new T_RegUser
{
Id = IDGen.NextID(),
CreateTime = DateTime.Now,
HeadImg = userinfo.avatarUrl,
Name = userinfo.nickName
};
await dbClient.Insertable(user).ExecuteCommandAsync();
var userwx = new T_UserWX
{
Id = IDGen.NextID(),
OpenId = sessionbage.OpenId.ToStr(),
UserId = user.Id
};
await dbClient.Insertable(userwx).ExecuteCommandAsync();
//增加一个默认家庭成员
var family = new T_Family
{
Id = user.Id,
CreateTime = user.CreateTime,
HeadImg = user.HeadImg,
Name = user.Name,
UserId = user.Id
};
await dbClient.Insertable(family).ExecuteCommandAsync();
return GenToken(user.Id, userwx.OpenId, sessionbage.Key);
}
else
{
await dbClient.Updateable().SetColumns(x => new T_RegUser
{
Name = userinfo.nickName,
HeadImg = userinfo.avatarUrl
}).Where(x => x.Id == wxdata.UserId).ExecuteCommandAsync();
return GenToken(wxdata.UserId, sessionbage.OpenId, sessionbage.Key);
}
}
///
/// 退出登录
///
///
///
public async Task OutLoginAsync(string sessionId)
{
var sessionBag = await SessionContainer.GetSessionAsync(sessionId);
if (sessionBag == null)
{
return new ResultInfo(ResultState.FAIL, "sessionId未找到");
}
await SessionContainer.RemoveFromCacheAsync(sessionBag.OpenId);
await dbClient.Deleteable().Where(x => x.OpenId == sessionBag.OpenId).ExecuteCommandAsync();
return new ResultInfo(ResultState.SUCCESS, "退出登录成功");
}
///
/// 修改用户资料
///
///
///
public async Task SubmitUserInfoAsync(SumitUserInfoC2SDto data)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
if (await dbClient.Queryable().AnyAsync(x => x.Id == data.FamilyId))
{
await dbClient.Updateable().SetColumns(x => new T_FamilyData
{
Brithday = data.Birthday,
Sex = data.Sex,
Height = data.Height,
Weight = data.Weight
}).Where(x => x.Id == data.FamilyId).ExecuteCommandAsync();
}
else
{
await dbClient.Insertable(new T_FamilyData
{
Id = data.FamilyId,
Sex = data.Sex,
Brithday = data.Birthday,
Height = data.Height,
LastResultTime = null,
Weight = data.Weight
}).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "资料修改成功");
}
}
}