MeiRiYiCheng_1_old/YBDevice.NApi.Application/ThirdClient/OpenService.cs

580 lines
24 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 第三方相关处理
/// </summary>
public class OpenService : IOpenService, ITransient
{
private readonly IBodyFatHelperService _bodyFatHelperService;
private readonly ILevelService _levelService;
private readonly ITouTiaoHttp _touTiaoHttp;
private readonly ISqlSugarRepository<YB_Family> 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<YB_Family> sqlSugarRepository, ITouTiaoHttp touTiaoHttp, IOpenFamilyService openFamilyService)
{
_bodyFatHelperService = bodyFatHelperService;
_levelService = levelService;
repository = sqlSugarRepository;
dbClient = repository.Context;
_touTiaoHttp = touTiaoHttp;
_openFamilyService = openFamilyService;
}
/// <summary>
/// BMI计算
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> 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
});
}
/// <summary>
/// 身高预测
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> CalcPredictHeightAsync(HeightInfoC2SDto data)
{
var month = data.Birthday.ToMonth();
//获取标准身高
var heightdata = await dbClient.Queryable<YB_NewHeightStand>().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
});
}
/// <summary>
/// 成年身高预测,女孩的靶身高=(父亲身高+母亲身高-13cm÷2
/// 男孩的靶身高=(父亲身高+母亲身高+13cm÷2
/// </summary>
/// <param name="dadheight">父亲身高</param>
/// <param name="momheight">母亲身高</param>
/// <param name="sex">性别,1-男,2-女,0-未知</param>
/// <returns></returns>
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)
};
/// <summary>
/// 登录接口
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> OnLoginAsync(TouTiaoLoginC2SDto data)
{
if (data.UA == UAConst.WeiXin)
{
return await WeiXinLogin(data);
}
else
{
return await TouTiaoLoginAsync(data);
}
}
/// <summary>
/// 生成token
/// </summary>
/// <returns></returns>
private ResultInfo GenToken(Guid userid, string openid, string sessionid)
{
openid = openid.ToStr();
sessionid = sessionid.ToStr();
//生成token
var token = JWTEncryption.Encrypt(new Dictionary<string, object>() {
{"UserId",userid},
{"OpenId",openid }
});
var refreshToken = JWTEncryption.GenerateRefreshToken(token, 43200);
return new ResultInfo(ResultState.SUCCESS, "登录成功", new
{
token = token,
sessionid = sessionid,
refreshtoken = refreshToken
});
}
/// <summary>
/// 微信登录处理
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private async Task<ResultInfo> WeiXinLogin(TouTiaoLoginC2SDto data)
{
var jsonResult = await SnsApi.JsCode2JsonAsync(WxOpenAppId, WxOpenAppSecret, data.code);
if (jsonResult.errcode == ReturnCode.)
{
//检查此openid是否已注册
var wxdata = await dbClient.Queryable<T_UserWX>()
.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);
}
/// <summary>
/// 字节登录处理
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private async Task<ResultInfo> 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<TouTiaoResponseData<TuTiaoLoginResponse>>();
if (resdata.err_no != 0)
{
return new ResultInfo(ResultState.FAIL, resdata.err_tips);
}
//检查此openid是否已注册
var wxdata = await dbClient.Queryable<T_UserWX>()
.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);
}
/// <summary>
/// 获取测量记录列表
/// </summary>
/// <param name="familyid">家庭成员ID</param>
/// <param name="page">页码</param>
/// <param name="pagesize">每页显示数量</param>
/// <returns></returns>
public async Task<ResultInfo> GetResultListAsync(Guid familyid, int page, int pagesize)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
RefAsync<int> totalnum = 0;
var query = await dbClient.Queryable<T_Result>()
.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<List<ResultListS2CDto>>();
var list = new PageParms<ResultListS2CDto>
{
page = page,
Items = result,
totalnum = totalnum,
limit = pagesize
};
return new ResultInfo(ResultState.SUCCESS, "success", list);
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="familyid">家庭成员ID</param>
/// <returns></returns>
public async Task<ResultInfo> GetUserInfoAsync(Guid? familyid)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
//检查是否有家庭成员ID
if (!familyid.HasValue)
{
familyid = CurrentUser.UserId;
}
var family = await dbClient.Queryable<T_Family>().Where(x => x.Id == familyid)
.Select(x => new T_Family
{
Name = x.Name,
HeadImg = x.HeadImg
})
.FirstAsync();
var familydata = await dbClient.Queryable<T_FamilyData>().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);
}
/// <summary>
/// 添加测量记录
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> 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<T_FamilyData>().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<T_FamilyData>().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, "记录增加成功");
}
/// <summary>
/// 用户注册
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> RegisterAsync(SubmitUserInfoC2SDto data)
{
var sessionbage = await SessionContainer.GetSessionAsync(data.sessionId);
if (sessionbage == null)
{
return new ResultInfo(ResultState.FAIL, "登录信息已过期");
}
//检查此openid是否已绑定用户
var wxdata = await dbClient.Queryable<T_UserWX>().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<T_RegUser>().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);
}
}
/// <summary>
/// 解密用户资料,如果未注册则自动进行注册,否则更新资料
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> 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<T_UserWX>().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<T_RegUser>().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);
}
}
/// <summary>
/// 退出登录
/// </summary>
/// <param name="sessionId"></param>
/// <returns></returns>
public async Task<ResultInfo> 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<T_UserWX>().Where(x => x.OpenId == sessionBag.OpenId).ExecuteCommandAsync();
return new ResultInfo(ResultState.SUCCESS, "退出登录成功");
}
/// <summary>
/// 修改用户资料
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> SubmitUserInfoAsync(SumitUserInfoC2SDto data)
{
var CurrentUser = AuthUserInfoService.GetUserInfo();
if (await dbClient.Queryable<T_FamilyData>().AnyAsync(x => x.Id == data.FamilyId))
{
await dbClient.Updateable<T_FamilyData>().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, "资料修改成功");
}
}
}