using Nirvana.Common;
using Nirvana.Common.ApiBase;
using Nirvana.Data;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.Entity;
namespace YBDevice.NApi.DBServices
{
///
/// 儿童模式相关处理
///
public partial class ChildApp : BaseApp
{
///
/// 获取儿童信息
///
///
///
public async Task GetInfoAsync(int familyid)
{
//如果familyid=0,则加载演示数据
var data = new ChildInfoModel();
using (var dbClient = ReadDbContext.GetInstance())
{
//如果传的成人类型,则自动寻找一个最新的
var family = await dbClient.Queryable().Where(x => x.Id == familyid && x.Type == 2 && x.Status != -1).FirstAsync();
if (family == null)
{
family = await dbClient.Queryable().Where(x => x.UserId == authInfo.UserId && x.Type == 2 && x.Status != -1).OrderBy(x => x.LastHeartTime, OrderByType.Desc).FirstAsync();
}
if (family == null)
{
var ysfamily = new YSFamily();
//返回一条演示数据
data = new ChildInfoModel
{
IsTest = true,
Height = ysfamily.Height,
DadHeight = ysfamily.DadHeight,
Time = ysfamily.Time,
Weight = ysfamily.Weight,
MomHeight = ysfamily.MomHeight,
Birthday = ysfamily.Birthday.ToString("yyyy-MM-dd"),
PredictHeight = await StandHeightAsync(ysfamily.Sex, ysfamily.Month),
HalfYearHeight = ysfamily.HalfYearHeight,
YearHeight = ysfamily.YearHeight,
Name = ysfamily.Name,
HeadImg = ysfamily.HeadImg,
Age = ysfamily.mAge,
Sex = ysfamily.Sex,
Id = ysfamily.Id
};
data.IsHeight = data.PredictHeight > data.Height;
data.AlertType = AletType(data.Height, data.PredictHeight);
data.GeneticHeight = AdultHeight(data.DadHeight, data.MomHeight, data.Sex);
return new ResultInfo(ResultState.SUCCESS, "success", data);
//return new ResultInfo(ResultState.FAIL, "成员未找到");
}
var familydata = await dbClient.Queryable().Where(x => x.FamilyId == family.Id).FirstAsync();
int month = family.Birthday.ToMonth();
data = new ChildInfoModel
{
Height = family.Height,
DadHeight = familydata != null ? familydata.DadHeight : 0,
Time = family.LastHeartTime,
Weight = family.Weight,
MomHeight = familydata != null ? familydata.MomHeight : 0,
PredictHeight = await StandHeightAsync(family.Sex, month),
HalfYearHeight = familydata != null ? family.Height - familydata.HalfYearHeight : 0,
YearHeight = familydata != null ? family.Height - familydata.YearHeight : 0,
Name = family.Name,
HeadImg = !string.IsNullOrEmpty(family.HeadImg) ? family.HeadImg : new FamilyApp().HeadImg(family.Sex, family.Type),
Age = family.Birthday.TomAge(),
Sex = family.Sex,
Birthday = family.Birthday.ToString("yyyy-MM-dd"),
Id = family.Id
};
data.IsHeight = data.PredictHeight > data.Height;
data.AlertType = AletType(data.Height, data.PredictHeight);
data.GeneticHeight = AdultHeight(data.DadHeight, data.MomHeight, family.Sex);
return new ResultInfo(ResultState.SUCCESS, "success", data);
}
}
///
/// 获取成长曲线
///
/// 家庭成员ID
///
public async Task GetGrowthCurveAsync(ChildGrowthQueryModel model)
{
//如果familyid为0,则加载演示数据
if (model.familyid <= 0)
{
var list = new List();
for (var i = 0; i < 10; i++)
{
list.Add(new ChildGrowthModel
{
Time = $"{i + 1}",
Height = 100 + i * 2,
Weight = 20 + i
});
}
return new ResultInfo(ResultState.SUCCESS, "success", list);
}
using (var dbClient = ReadDbContext.GetInstance())
{
model.StartTime = model.StartTime.Date;
model.EndTime = model.EndTime.Date;
var tempquery = dbClient.Queryable()
.Where(x => x.FamilyId == model.familyid && x.CreateTime>=model.StartTime && x.CreateTime<=model.EndTime);
var query = await tempquery.OrderBy(x => x.CreateTime, OrderByType.Desc).Select(x => new ChildGrowthModel
{
Time = SqlFunc.ToString(x.CreateTime),
Height = x.Height,
Weight = x.Weight
})
.Mapper((it, cache) =>
{
it.Time = it.Time.ToDate().ToString("yyyy-MM");
})
.ToPageListAsync(model.page, model.pagesize);
return new ResultInfo(ResultState.SUCCESS, "success", query);
}
}
///
/// 获取身高/体重成长测评报告,与标准身高进行对比
///
///
///
///
///
public async Task GetHWListAsync(int familyid, int page, int pagesize)
{
if (familyid <= 0)
{
var thlist = new List();
var twlist = new List();
for (var i = 0; i < 10; i++)
{
thlist.Add(new ChildWHModel
{
Time = $"{i + 1}",
Value = 100 + i * 2,
StandValue = await StandHeightAsync(1, 84)
});
twlist.Add(new ChildWHModel
{
Time = $"{i + 1}",
Value = 20 + i * 2,
StandValue = await StandWeightAsync(1, 84)
});
}
return new ResultInfo(ResultState.SUCCESS, "success", new
{
hlist = thlist,
wlist = twlist
});
}
using (var dbClient = ReadDbContext.GetInstance())
{
var family = await dbClient.Queryable().FirstAsync(x => x.Id == familyid);
if (family == null)
{
return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
}
var tempquery = dbClient.Queryable().Where(x => x.FamilyId == familyid);
var query = await tempquery
.OrderBy(x => x.CreateTime, OrderByType.Desc)
.ToPageListAsync(page, pagesize);
var hlist = new List();
var wlist = new List();
query.ForEach(async x =>
{
hlist.Add(new ChildWHModel
{
Time = x.CreateTime.ToYearDate(),
Value = x.Height,
StandValue = await StandHeightAsync(family.Sex, family.Birthday)
});
wlist.Add(new ChildWHModel
{
Time = x.CreateTime.ToYearDate(),
Value = x.Weight,
StandValue = await StandWeightAsync(family.Sex, family.Birthday)
}); ;
});
return new ResultInfo(ResultState.SUCCESS, "success", new
{
hlist = hlist,
wlist = wlist
});
}
}
///
/// 计算遗传身高和成年身高
///
///
///
public async Task PredictHeightAsync(ChildPredictHeightModel model)
{
//计算遗传身高
decimal geneticheight = await StandHeightAsync(model.sex, model.Birthday);
//成年身高预测
decimal adultheight = AdultHeight(model.DadHeight, model.MomHeight, model.sex);
if (model.familyid > 0)
{
using (var dbClient = ReadDbContext.GetInstance())
{
await dbClient.Updateable().SetColumns(x => new YB_FamilyData
{
DadHeight = model.DadHeight,
MomHeight = model.MomHeight
})
.Where(x => x.FamilyId == model.familyid)
.ExecuteCommandAsync();
}
}
return new ResultInfo(ResultState.SUCCESS, "success", new ChildPredictHeightReturnModel
{
GeneticHeight = geneticheight,
AdultHeight = adultheight
});
}
///
/// 获取儿童增量信息
///
///
///
public async Task GetYearHeightInfoAsync(int familyid)
{
using (var dbClient = ReadDbContext.GetInstance())
{
if(familyid == 0)
{
//返回演示数据
var ysfamily = new YSFamily();
var ysstanddata = await dbClient.Queryable().Where(x => x.Sex == ysfamily.Sex && x.Month >= ysfamily.Month).OrderBy(x => x.Month, OrderByType.Asc).FirstAsync();
var ysdata = new ChildYearHeightModel {
f1sd= ysstanddata.f1sd,
f2sd=ysstanddata.f2sd,
z1sd=ysstanddata.z1sd,
z2sd=ysstanddata.z2sd,
Height=ysfamily.Height,
HalfYearHeight=ysfamily.HalfYearHeight,
median=ysstanddata.median,
HalfYearStandHeight=HalfYearStandHeight(ysfamily.Age),
YearHeight=ysfamily.YearHeight,
HeightLevel=HeightLevel(ysstanddata,ysfamily.Height)
};
ysdata.HalfYearHeightLevel = HalfYearHeightLevel(ysdata.HalfYearHeight, ysdata.HalfYearStandHeight);
ysdata.YearHeightLevel = YearHeightLevel(ysdata.YearHeight, ysdata.YearStandHeight);
return new ResultInfo(ResultState.SUCCESS, "success", ysdata);
}
var family = await dbClient.Queryable().FirstAsync(x => x.Id == familyid);
if (family == null)
{
return new ResultInfo(ResultState.FAIL, "成员未找到");
}
var familydata = await dbClient.Queryable().FirstAsync(x => x.FamilyId == familyid);
int month = family.Birthday.ToMonth();
int age = family.Birthday.ToAge();
var data = await dbClient.Queryable().Where(x => x.Sex == family.Sex && (x.Month >= month)).OrderBy(x => x.Month, OrderByType.Asc).FirstAsync();
var returndata = new ChildYearHeightModel
{
f1sd = data.f1sd,
f2sd = data.f2sd,
z1sd = data.z1sd,
z2sd = data.z2sd,
Height = family.Height,
HalfYearHeight = familydata != null && familydata.HalfYearHeight > 0 ? family.Height - familydata.HalfYearHeight : 0, //如果半年前身高为0则表示未测量过,则增量为0
median = data.median,
HalfYearStandHeight = HalfYearStandHeight(age),
YearHeight = familydata != null && familydata.YearHeight > 0 ? family.Height - familydata.YearHeight : 0,
YearStandHeight = YearStandHeight(age),
HeightLevel = HeightLevel(data, family.Height)
};
returndata.HalfYearHeightLevel = HalfYearHeightLevel(returndata.HalfYearHeight, returndata.HalfYearStandHeight);
returndata.YearHeightLevel = YearHeightLevel(returndata.YearHeight, returndata.YearStandHeight);
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
}
///
/// 身高等级
///
/// 等级标准
/// 身高
///
private int HeightLevel(YB_HeightStand data, decimal height)
=> (data, height) switch
{
_ when height >= data.f1sd && height < data.z1sd => (int)ChildHeightLevel.Normal,
_ when height >= data.f2sd && height < data.f1sd => (int)ChildHeightLevel.Low,
_ when height >= data.z1sd && height < data.z2sd => (int)ChildHeightLevel.Height,
_ when height >= data.f3sd && height < data.f2sd => (int)ChildHeightLevel.MoreLow,
_ when height >= data.z2sd && height < data.z3sd => (int)ChildHeightLevel.MoreHeight,
_ => (int)ChildHeightLevel.Error
};
///
/// 半年增量标准身高值
///
/// 年龄
///
private decimal HalfYearStandHeight(int age)
=> (age) switch
{
_ when age < 10 => 2.5m,
_ => 3m
};
///
/// 半年增量标准
///
/// 半年增量
/// 标准增量
///
private int HalfYearHeightLevel(decimal height, decimal standheight)
=> (height, standheight) switch
{
_ when height >= standheight => (int)ChildYearHeightLevel.Normal,
_ => (int)ChildHeightLevel.Low
};
///
/// 一年的身高增量标准值
///
///
///
private decimal YearStandHeight(int age)
=> (age) switch
{
_ when age < 10 => 5m,
_ => 6m
};
///
/// 一年增量标准
///
/// 一年增量
/// 标准增量
///
private int YearHeightLevel(decimal height, decimal standheight)
=> (height, standheight) switch
{
_ when height >= standheight => (int)ChildYearHeightLevel.Normal,
_ => (int)ChildHeightLevel.Low
};
///
/// 成年身高预测,女孩的靶身高=(父亲身高+母亲身高-13cm)÷2
/// 男孩的靶身高=(父亲身高+母亲身高+13cm)÷2
///
/// 父亲身高
/// 母亲身高
/// 性别,1-男,2-女,0-未知
///
private static decimal AdultHeight(decimal dadheight, decimal momheight, int sex)
=> (dadheight, momheight, sex) switch
{
_ when dadheight <= 0 || momheight <= 0 => 0,
_ when (sex == 2) => (37.85m + 0.75m * (dadheight + momheight) / 2).ToDecimal(1),
_ => (45.99m + 0.78m * (dadheight + momheight) / 2).ToDecimal(1)
};
///
/// 标准身高,参考
/// 5-19岁女孩:https://www.who.int/docs/default-source/child-growth/growth-reference-5-19-years/height-for-age-(5-19-years)/sft-hfa-girls-perc-5-19years.pdf?sfvrsn=59b013d8_4,
/// 5-19岁男孩:https://www.who.int/docs/default-source/child-growth/growth-reference-5-19-years/height-for-age-(5-19-years)/sft-hfa-boys-perc-5-19years.pdf?sfvrsn=3fe316bf_4
///
///
///
///
///
private static async Task StandHeightAsync(int sex, DateTime birthday)
{
var month = birthday.ToMonth();
var height= await StandHeightAsync(sex, month);
return height.ToDecimal(1);
}
///
/// 标准身高
///
/// 性别,1-男,2-女
/// 月龄
///
private static async Task StandHeightAsync(int sex, int month)
{
using (var dbClient = ReadDbContext.GetInstance())
{
var data = await dbClient.Queryable().Where(x => x.Sex == sex && (x.Month >= month)).OrderBy(x => x.Month, OrderByType.Asc).FirstAsync();
return data != null ? data.median : 0;
}
}
///
/// 标准身高,参考
/// 5-19岁女孩:https://www.who.int/docs/default-source/child-growth/growth-reference-5-19-years/height-for-age-(5-19-years)/sft-hfa-girls-perc-5-19years.pdf?sfvrsn=59b013d8_4,
/// 5-19岁男孩:https://www.who.int/docs/default-source/child-growth/growth-reference-5-19-years/height-for-age-(5-19-years)/sft-hfa-boys-perc-5-19years.pdf?sfvrsn=3fe316bf_4
///
///
///
///
///
private static async Task StandWeightAsync(int sex, DateTime birthday)
{
var month = birthday.ToMonth();
return await StandWeightAsync(sex, month);
}
///
/// 标准体重
///
/// 性别,1-男,2-女
/// /// 月龄
///
private static async Task StandWeightAsync(int sex, int month)
{
using (var dbClient = ReadDbContext.GetInstance())
{
var data = await dbClient.Queryable().Where(x => x.Sex == sex && (x.Month >= month)).OrderBy(x => x.Month, OrderByType.Asc).FirstAsync();
return data != null ? data.median : 0;
}
//理想体重 = 22 ×身高² (米)
//return 22 * ((height / 100) * (height / 100));
}
///
/// 智能追踪分析,该分析是基于标准身高与实测身高的对比,对孩子是否因为后天因素有利于长高进行判断
///
/// 实测身高
/// 标准身高
///
private static int AletType(decimal height, decimal standheight)
=> (height, standheight) switch
{
_ when (standheight - height > 6) => (int)ChildAlertType.RedAlert,
_ when (standheight - height <= 6 && standheight - height > 3) => (int)ChildAlertType.OrangeAlert,
_ when (standheight - height <= 3 && standheight - height > 0) => (int)ChildAlertType.YellowAlert,
_ when (standheight - height <= 0 && standheight - height >= -4) => (int)ChildAlertType.BlueReward,
_ => (int)ChildAlertType.GreenAlert
};
}
}