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, "资料修改成功"); } } }