using DotNetCore.CAP;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Mapster;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using Senparc.Weixin.WxOpen.Containers;
using Senparc.Weixin.WxOpen.Helpers;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.Body.BodyFatHelper;
using YBDevice.CommonService;
using YBDevice.CommonService.DevTypeInfo;
using YBDevice.Entity;

namespace YBDevice.NApi.Application.UserInfo
{
    /// <summary>
    /// 用户信息
    /// </summary>
    public class UserService : BaseService, IUserService, ITransient
    {
        private readonly ISqlSugarRepository<YB_WifiBind> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IFamilyService _familyService;
        private readonly IBodyFatHelperService _bodyFatHelperService;
        private readonly ICapPublisher _capBus;
        private readonly IDeviceTypeService _deviceTypeService;
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="sqlSugarRepository"></param>
        /// <param name="familyServices"></param>
        /// <param name="bodyFatHelperService"></param>
        /// <param name="capPublisher"></param>
        /// <param name="deviceTypeService"></param>
        public UserService(ISqlSugarRepository<YB_WifiBind> sqlSugarRepository, IFamilyService familyServices, IBodyFatHelperService bodyFatHelperService, ICapPublisher capPublisher, IDeviceTypeService deviceTypeService)

        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _familyService = familyServices;
            _bodyFatHelperService = bodyFatHelperService;
            _capBus = capPublisher;
            _deviceTypeService = deviceTypeService;
        }
        /// <summary>
        /// 解密手机号
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> DecryptPhoneAsync(WxOpenDecryptSubmitModel model)
        {
            var sessionBag = await SessionContainer.GetSessionAsync(model.sessionId);
            if (sessionBag == null)
            {
                return new ResultInfo(ResultState.FAIL, "sessionId未找到");
            }
            var phone = EncryptHelper.DecryptPhoneNumberBySessionKey(sessionBag.SessionKey, model.encryptedData, model.iv);
            //更新当前用户的手机号
            await dbClient.Updateable<YB_RegUser>().SetColumns(x => new YB_RegUser
            {
                Phone = phone.purePhoneNumber
            }).Where(x => x.Id == authInfo.UserId).ExecuteCommandAsync();
            return new ResultInfo(ResultState.SUCCESS, "手机号绑定成功");
        }


        /// <summary>
        /// 获取用户测量数据
        /// </summary>
        /// <returns></returns>
        public async Task<ResultInfo> GetMeasureInfoAsync(UserMeasureInfoModel model)
        {
            //获取此家庭成员的体重信息
            var family = await dbClient.Queryable<YB_Family>().Where(x => x.Id == model.familyid).FirstAsync();
            if (family == null)
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            int age = model.birthday.ToAge();
            //更新家庭成员信息
            await dbClient.Updateable<YB_Family>().SetColumns(x => new YB_Family
            {
                Height = model.height,
                Age = age,
                Sex = model.sex,
                Birthday = model.birthday,
                Type = _familyService.GetType(model.birthday)
            }).Where(x => x.Id == model.familyid).ExecuteCommandAsync();
            var tempquery = dbClient.Queryable<YB_nUserResult>().Where(x => x.FamilyId == family.Id && x.Status == 1);
            //设备类型列表
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(model.devtype);
            tempquery = tempquery.Where(x => devtypes.Contains(x.DevType));
            if (!await tempquery.Clone().AnyAsync())
            {
                return new ResultInfo(ResultState.NORESULT, "未找到测量数据");
            }
            var familyrealdata = await dbClient.Queryable<YB_FamilyRealData>()
                .Where(x => x.FamilyId == model.familyid && x.DevType == model.devtype)
                .Select(x => new YB_FamilyRealData
                {
                    LastHeight = x.LastHeight,
                    LastResultHeightTime = x.LastResultHeightTime
                })
                .FirstAsync()
                ;
            //如果此设备类型还未有记录
            if (familyrealdata == null)
            {
                var otherdata = await dbClient.Queryable<YB_FamilyRealData>()
                .Where(x => x.FamilyId == model.familyid && devtypes.Contains(x.DevType))
                .Select(x => new YB_FamilyRealData
                {
                    LastHeight = x.LastHeight,
                    LastResultHeightTime = x.LastResultHeightTime
                })
                .FirstAsync()
                ;
                familyrealdata = new YB_FamilyRealData
                {
                    DevType = model.devtype,
                    CreateTime = DateTime.Now,
                    FamilyId = model.familyid,
                    FirstHeight = otherdata != null ? otherdata.FirstHeight : 0,
                    FirstResultTime = otherdata != null ? otherdata.FirstResultTime : null,
                    FirstWeight = otherdata != null ? otherdata.FirstWeight : 0,
                    HalfYearHeight = otherdata != null ? otherdata.HalfYearHeight : 0,
                    HalfYearHeightTime = otherdata != null ? otherdata.HalfYearHeightTime : null,
                    LastHeight = otherdata != null ? otherdata.LastHeight : 0,
                    LastResultHeightTime = otherdata != null ? otherdata.LastResultHeightTime : null,
                    LastResultId = otherdata != null ? otherdata.LastResultId : null,
                    LastResultTime = otherdata != null ? otherdata.LastResultTime : null,
                    LastTimeHeight = otherdata != null ? otherdata.LastTimeHeight : 0,
                    LastTimeWeight = otherdata != null ? otherdata.LastTimeWeight : 0,
                    LastWeight = otherdata != null ? otherdata.LastWeight : 0,
                    MonthHeight = otherdata != null ? otherdata.MonthHeight : 0,
                    MonthWeight = otherdata != null ? otherdata.MonthWeight : 0,
                    TodayCount = otherdata != null ? otherdata.TodayCount : 0,
                    TotalCount = otherdata != null ? otherdata.TotalCount : 0,
                    UserId = authInfo.UserId,
                    YearHeight = otherdata != null ? otherdata.YearHeight : 0,
                    YearHeightTime = otherdata != null ? otherdata.YearHeightTime : null,
                    Id = IDGen.NextID()
                };
                await dbClient.Insertable(familyrealdata).ExecuteCommandAsync();
            }
            bool IsUpdateData = false;//是否更新数据
            if (familyrealdata != null && familyrealdata.LastHeight != model.height)
            {
                IsUpdateData = true;
            }
            if (IsUpdateData)
            {
                //更新实时数据和儿童模式的曲线
                await _capBus.PublishAsync("result.service.updateuserheightdata", new UpdateUserHeightDataS2SDto
                {
                    familyid = model.familyid,
                    DevType = model.devtype,
                    Height = model.height,
                    LastResultHeightTime = familyrealdata.LastResultHeightTime,
                    LastHeight = familyrealdata.LastHeight,
                    HalfYearHeight = familyrealdata.HalfYearHeight,
                    YearHeight = familyrealdata.YearHeight
                });
            }
            var userresult = await tempquery.Clone()
                .OrderBy(x => x.CreateTime, OrderByType.Desc)
                .FirstAsync();
            var result = await dbClient.Queryable<YB_nResult>().FirstAsync(x => x.Id == userresult.Id);
            UserMeasureModel data = new UserMeasureModel();
            if (model.IsCalc == 0)
            {
                data = _bodyFatHelperService.CalcBodyFat(result.Weight.ToDouble(), model.height.ToDouble(), age, result.Imp.ToInt(), model.sex);
                if (IsUpdateData)
                {
                    #region 更新测量结果
                    int month = model.birthday.ToMonth();
                    await dbClient.Updateable<YB_nMeasureResult>().SetColumns(x => new YB_nMeasureResult
                    {
                        Height = model.height,
                        Sex = family.Sex,
                        Age = family.Age,
                        fat_r = data.fat_r,
                        muscle = data.muscle,
                        water = data.water,
                        bone = data.bone,
                        kcal = data.kcal,
                        fat_w = data.fat_w,
                        visceral = data.visceral,
                        protein = data.protein,
                        bodyage = data.bodyage,
                        bmi = data.bmi,
                        cmi = data.cmi,
                        sfr = data.cmi,
                        muscleval = data.muscleval,
                        proteinval = data.proteinval,
                        lbm = data.lbm,
                        body = data.bodylevel,
                        fatlevel = data.fatLevel,
                        Month = month
                    }).Where(x => x.Id == result.Id).ExecuteCommandAsync();
                    #endregion
                }
            }
            else
            {
                var measureresult = await dbClient.Queryable<YB_nMeasureResult>().FirstAsync(x => x.Id == result.Id);
                MeasureCalcDto calcdto = new MeasureCalcDto
                {
                    weight = measureresult.Weight.ToString(),
                    imp = result.Imp,
                    height = model.height,
                    ecode = "",
                    familyid = model.familyid,
                    bodyage = measureresult.bodyage,
                    fat_r = measureresult.fat_r,
                    muscle = measureresult.muscle,
                    water = measureresult.water,
                    bone = measureresult.bone,
                    kcal = measureresult.kcal,
                    visceral = measureresult.visceral,
                    protein = measureresult.protein,
                    bmi = measureresult.bmi,
                    sfr = measureresult.sfr,
                    fatlevlval = measureresult.fatlevel,
                    StandardWeight = 0,
                    fat_w = measureresult.fat_w,
                    lbm = measureresult.lbm,
                    muscleval = measureresult.muscleval,
                    proteinval = measureresult.proteinval,
                    age = measureresult.Age,
                    sex = (GenderType)measureresult.Sex,
                    IsCalc = model.IsCalc
                };
                data = _bodyFatHelperService.CalcBodyFat(calcdto);
                if (familyrealdata == null)
                {
                    DateTime nowtime = DateTime.Now;
                    bool nowmonth = measureresult.createtime.Year == nowtime.Year && measureresult.createtime.Month == nowtime.Month;
                    var insertdata = new YB_FamilyRealData
                    {
                        FamilyId = model.familyid,
                        FirstHeight = measureresult.Height,
                        FirstResultTime = measureresult.createtime,
                        DevType = model.devtype,
                        CreateTime = measureresult.createtime,
                        FirstWeight = measureresult.Weight,
                        Id = IDGen.NextID(),
                        LastHeight = model.height,
                        LastResultTime = measureresult.createtime,
                        LastTimeHeight = 0,
                        LastTimeWeight = 0,
                        LastWeight = measureresult.Weight,
                        TodayCount = measureresult.createtime.Date == nowtime.Date ? 1 : 0,
                        TotalCount = measureresult.createtime.Date == nowtime.Date ? 1 : 0,
                        UserId = family.UserId,
                        MonthHeight = nowmonth ? model.height : 0,
                        MonthWeight = nowmonth ? measureresult.Weight : 0,
                        LastResultHeightTime = measureresult.createtime
                    };
                    await dbClient.Insertable(insertdata).ExecuteCommandAsync();
                }
            }
            var returndata = new UserMeasureInfo
            {
                bmi = data.bmi,
                bmiLevel = data.bmiLevel,
                body = data.body,
                bodyage = data.bodyage,
                bodyageLevel = data.bodyageLevel,
                bodylevel = data.bodylevel,
                bone = data.bone,
                boneLevel = data.boneLevel,
                cmi = data.cmi,
                fatLevel = data.fatLevel,
                fatlevlval = data.fatlevlval,
                fat_r = data.fat_r,
                fat_rLevel = data.fat_rLevel,
                fat_w = data.fat_w,
                fat_wLevel = data.fat_wLevel,
                kcal = data.kcal,
                kcalLevel = data.kcalLevel,
                lbm = data.lbm,
                muscle = data.muscle,
                muscleLevel = data.muscleLevel,
                muscleval = data.muscleval,
                musulevalLevel = data.musulevalLevel,
                protein = data.protein,
                proteinLevel = data.proteinLevel,
                proteinval = data.proteinval,
                proteinvalLevel = data.proteinvalLevel,
                sfr = data.sfr,
                sfrLevel = data.sfrLevel,
                standardbmi = data.standardbmi,
                standardbody = data.standardbody,
                standardbodyage = data.standardbodyage,
                standardbone = data.standardbone,
                standardfatlevel = data.standardfatlevel,
                standardfat_r = data.standardfat_r,
                standardfat_w = data.standardfat_w,
                standardkcal = data.standardkcal,
                standardlbm = data.standardlbm,
                standardmuscle = data.standardmuscle,
                standardmuscleval = data.standardmuscleval,
                standardprotein = data.standardprotein,
                standardproteinval = data.standardproteinval,
                standardsfr = data.standardsfr,
                standardviscera = data.standardviscera,
                standardwater = data.standardwater,
                standardWeight = data.standardWeight,
                visceral = data.visceral,
                visceralLevel = data.visceralLevel,
                water = data.water,
                waterLevel = data.waterLevel,
                height = model.height,
                weight = result.Weight
            };
            //获取每项的历史值
            var starttime = DateTime.Now.AddMonths(-1).Date;
            var endtime = DateTime.Now.AddDays(1).Date;
            var dataset = await dbClient.Ado.UseStoredProcedure().GetDataSetAllAsync("proc_getmeasureitem_page", new
            {
                pagesize = model.pagesize,
                pagenum = model.pagenum,
                familyid = model.familyid,
                type = model.devtype,
                starttime = starttime,
                endtime = endtime
            });
            if (dataset.Tables.Count == 0)
            {
                returndata.list = new List<MeasureInfoItem>();
            }
            else
            {
                //BMI标准,最大值,最小值,标准范围
                var listcnt = DataTableListHelper.ToList<MeasureModels>(dataset.Tables[0]);
                var listday = DataTableListHelper.ToList<MeasureModels>(dataset.Tables[1]);
                //最近的上上次测量结果
                var lastresult = await tempquery.Clone().Where(x => x.Id != result.Id)
                    .OrderBy(x => x.CreateTime, OrderByType.Desc)
                    .FirstAsync();
                UserMeasureModel levelresult = new UserMeasureModel();
                if (lastresult != null)
                {
                    var mresult = await dbClient.Queryable<YB_nMeasureResult>().Where(x => x.Id == lastresult.Id).FirstAsync();
                    if (mresult != null)
                    {
                        var res = await dbClient.Queryable<YB_nResult>()
                            .Select(x => new YB_nResult
                            {
                                Imp = x.Imp
                            })
                            .FirstAsync(x => x.Id == lastresult.Id);
                        int imp = res != null ? res.Imp.ToInt() : 0;
                        levelresult = _bodyFatHelperService.CalcBodyFat(mresult.Weight.ToDouble(), mresult.Height.ToDouble(), mresult.Age, imp, (GenderType)mresult.Sex);
                    }
                }
                returndata.list = HisList(model.sex, listcnt, listday, age, data, levelresult, result.Weight);
            }
            return new ResultInfo(ResultState.SUCCESS, "success", returndata);
        }
        /// <summary>
        /// 历史记录分类
        /// </summary>
        /// <param name="sex">性别,1-男,2-女</param>
        /// <param name="listcnt">按次列表</param>
        /// <param name="listday">按天列表</param>
        /// <param name="age">年龄</param>
        /// <param name="data">当前测量数据</param>
        /// <param name="levelresult">上次测量数据</param>
        /// <param name="weight">重量</param>
        /// <returns></returns>
        private List<MeasureInfoItem> HisList(GenderType sex, List<MeasureModels> listcnt, List<MeasureModels> listday, int age, UserMeasureModel data, UserMeasureModel levelresult, decimal weight)
        {
            List<MeasureInfoItem> info = new List<MeasureInfoItem>();
            List<string> mlist = new List<string> { "bmi", "fat_r", "muscle", "water", "bone", "kcal", "fat_w", "visceral", "protein", "bodyage","sfr","sfrval","body",
                        "muscleval","proteinval","lbm","fatlevel","weight"};
            mlist.ForEach(x =>
            {
                var m = new MeasureInfoItem()
                {
                    name = x
                };
                if (x == "bmi")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.bmi.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.bmi.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.bmi_value(sex, age);
                    m.value = data.bmi;
                    m.lastvalue = m.value - levelresult.bmi;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.bmiLevel);
                }
                else if (x == "fat_r")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.fat_r.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.fat_r.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.fa_r_value(sex, age);
                    m.value = data.fat_r;
                    m.lastvalue = m.value - levelresult.fat_r;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.fat_rLevel);
                }
                else if (x == "muscle")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.muscle.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.muscle.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.muscle_value(sex, age);
                    m.value = data.muscle;
                    m.lastvalue = m.value - levelresult.muscle;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.muscleLevel);
                }
                else if (x == "water")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.water.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.water.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.water_value(sex, age);
                    m.value = data.water;
                    m.lastvalue = m.value - levelresult.water;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.waterLevel);
                }
                else if (x == "bone")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.bone.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.bone.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.bone_value(sex, age, weight);
                    m.value = data.bone;
                    m.lastvalue = m.value - levelresult.bone;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.boneLevel);
                }
                else if (x == "kcal")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.kcal.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.kcal.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.kcal_value(sex, age, weight);
                    m.value = data.kcal;
                    m.lastvalue = m.value - levelresult.kcal;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.kcalLevel);
                }
                else if (x == "fat_w")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.fat_w.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.fat_w.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.value = data.fat_w;
                    m.slist = _bodyFatHelperService.fat_w_value(sex, age, weight);
                    m.lastvalue = m.value - levelresult.fat_w;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.fat_rLevel);
                }
                else if (x == "visceral")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.visceral.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.visceral.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.visceral_value(sex, age);
                    m.value = data.visceral;
                    m.lastvalue = m.value - levelresult.visceral;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.visceralLevel);
                }
                else if (x == "protein")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.protein.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.protein.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.protein_value(sex, age);
                    m.value = data.protein;
                    m.lastvalue = m.value - levelresult.protein;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.proteinLevel);
                }
                else if (x == "bodyage")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.bodyage.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.bodyage.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.value = data.bodyage;
                    m.lastvalue = m.value - levelresult.bodyage;
                }
                else if (x == "sfr")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.sfr.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.sfr.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.sfr_value(sex, age);
                    m.value = data.sfr;
                    m.lastvalue = m.value - levelresult.sfr;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.sfrLevel);
                }
                else if (x == "sfrval")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.sfrval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.sfrval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.sfrval_value(sex, age, weight);
                    m.value = data.sfrval;
                    m.lastvalue = m.value - levelresult.sfrval;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.sfrLevel);
                }
                else if (x == "body")
                {
                    m.list = listcnt
                    .Select(e => new MeasureHisItem { value = e.body, time = e.timestamp.ToYearDate() })
                    .ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.body, time = e.timestamp.ToYearDate() }).ToList();
                    m.value = 0;
                    m.lastvalue = 0;
                }
                else if (x == "muscleval")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.muscleval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.muscleval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.muscleval_value(sex, age, weight);
                    m.value = data.muscleval;
                    m.lastvalue = m.value - levelresult.muscleval;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.muscleLevel);
                }
                else if (x == "proteinval")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.proteinval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.proteinval.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.slist = _bodyFatHelperService.proteinval_value(sex, age, weight);
                    m.value = data.proteinval;
                    m.lastvalue = m.value - levelresult.proteinval;
                    m.Color = _bodyFatHelperService.GetLevelColor(data.proteinvalLevel);
                }
                else if (x == "lbm")
                {
                    m.list = listcnt.Select(e => new MeasureHisItem { value = e.lbm.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.lbm.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.value = data.lbm;
                    m.lastvalue = m.value - levelresult.lbm;
                }
                else if (x == "fatlevel")
                {
                    m.list = listcnt
                    .Select(e => new MeasureHisItem { value = _bodyFatHelperService.fatlevel(e.fatlevlval.ToDouble()), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = _bodyFatHelperService.fatlevel(e.fatlevlval.ToDouble()), time = e.timestamp.ToYearDate() }).ToList();
                    m.value = 0;
                    m.lastvalue = 0;
                }
                else if (x == "weight")
                {
                    m.list = listcnt
                    .Select(e => new MeasureHisItem { value = e.weight.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.daylist = listday.Select(e => new MeasureHisItem { value = e.weight.ToString(), time = e.timestamp.ToYearDate() }).ToList();
                    m.value = data.weight;
                    m.lastvalue = m.value - levelresult.weight;
                }
                info.Add(m);
            });
            return info;
        }
        /// <summary>
        /// 历史记录分类
        /// </summary>
        /// <param name="sex">性别,1-男,2-女</param>
        /// <param name="age">年龄</param>
        /// <param name="weight">重量</param>
        /// <param name="data">当前测量数据</param>
        /// <returns></returns>
        public List<MeasureInfoItem> HisList(GenderType sex, int age, decimal weight, UserMeasureModel data)
        {
            List<MeasureModels> listcnt = new List<MeasureModels>();
            List<MeasureModels> listday = new List<MeasureModels>();
            UserMeasureModel levelresult = new UserMeasureModel();
            return HisList(sex, listcnt, listday, age, data, levelresult, weight);
        }

        /// <summary>
        /// 获取用户个人资料
        /// </summary>
        /// <param name="familyid">家庭成员ID</param>
        /// <param name="devtype">设备类型</param>
        /// <returns></returns>
        public async Task<ResultInfo> GetUserInfoAsync(int familyid = 0, int devtype = 0)
        {
            var user = await dbClient.Queryable<YB_RegUser>().Where(x => x.Id == authInfo.UserId).FirstAsync();
            YB_Family family = new YB_Family();
            if (familyid > 0)
            {
                family = await dbClient.Queryable<YB_Family>().Where(x => x.Id == familyid && x.UserId == user.Id && x.Status != StatusType.Delete).FirstAsync();
            }
            //试着获取一个最新的
            if (family == null || family.Id <= 0)
            {
                //如果是H018则查找默认家庭成员
                if (devtype == 2)
                {
                    family = await dbClient.Queryable<YB_Family>().Where(x => x.UserId == user.Id && x.IsSelf == 1).FirstAsync();
                }
                else
                {
                    family = await dbClient.Queryable<YB_Family>().Where(x => x.UserId == user.Id && x.Status != StatusType.Delete).OrderBy(x => x.LastHeartTime, OrderByType.Desc).FirstAsync();
                }
            }
            var target = await dbClient.Queryable<YB_FamilyTarget>().FirstAsync(x => x.familyid == family.Id);
            decimal standweight = _bodyFatHelperService.CalcStandWeight(family.Height, family.Sex);
            var familydata = await dbClient.Queryable<YB_FamilyRealData>()
                    .Where(x => x.FamilyId == family.Id && x.DevType == devtype)
                    .Select(x => new YB_FamilyData
                    {
                        FirstResultTime = x.FirstResultTime,
                        TotalCount = x.TotalCount,
                        FirstWeight = x.FirstWeight,
                        LastWeight = x.LastWeight,
                        LastTimeHeight = x.LastTimeHeight,
                        LastHeight = x.LastHeight
                    })
                    .FirstAsync()
                    ;
            //如果未找到,则查询同类型的
            if (familydata == null)
            {
                var devtypes = await _deviceTypeService.GetDevTypesAsync(devtype);
                familydata = await dbClient.Queryable<YB_FamilyRealData>()
                    .Where(x => x.FamilyId == family.Id && devtypes.Contains(x.DevType))
                    .Select(x => new YB_FamilyData
                    {
                        FirstResultTime = x.FirstResultTime,
                        TotalCount = x.TotalCount,
                        FirstWeight = x.FirstWeight,
                        LastWeight = x.LastWeight,
                        LastTimeHeight = x.LastTimeHeight,
                        LastHeight = x.LastHeight
                    })
                    .FirstAsync()
                    ;
            }
            int day = 0;
            if (familydata != null && familydata.FirstResultTime.HasValue)
            {
                day = (DateTime.Now.Date - familydata.FirstResultTime.Value.Date).TotalDays.ToInt();
            }
            decimal height = (familydata != null && familydata.LastHeight > 0) ? familydata.LastHeight : family.Height;
            decimal weight = (familydata != null && familydata.LastWeight > 0) ? familydata.LastWeight.ToDecimal() : 0;
            var data = new UserInfoModel
            {
                headimg = !string.IsNullOrEmpty(family.HeadImg) ? family.HeadImg : DefaultService.HeadImg(family.Sex, family.Type),
                sex = family.Sex,
                nickname = family.Name,
                isbindphone = string.IsNullOrEmpty(user.Phone) ? false : true,
                age = family.Age,
                familyid = family.Id,
                height = height,
                targetweight = target != null ? target.weight : 0,
                targettime = target != null ? target.time.ToYearDate() : "-- --",
                weight = weight.ToDecimal(1),
                lasthearttime = family.LastHeartTime.HasValue ? family.LastHeartTime.Value.ToYearDate() : "-- --",
                Birthday = family.Birthday.ToString("yyyy-MM-dd"),
                Cnt = familydata != null ? familydata.TotalCount : 0,
                FirstWeight = familydata != null ? familydata.FirstWeight.ToDecimal(1) : 0,
                TotalWeight = familydata != null ? (familydata.LastWeight == 0 ? 0 : (familydata.FirstWeight - familydata.LastWeight).ToDecimal(1)) : 0,
                LastWeight = familydata != null ? familydata.LastTimeWeight.ToDecimal(1) : 0,
                StandWeight = standweight < 0 ? 0 : standweight.ToDecimal(1),
                Day = day,
                FirstResultTime = familydata != null ? familydata.FirstResultTime : null,
                Type = family.Type,
                BMI = _bodyFatHelperService.CalcBMi(height, weight),
                MAge = family.Birthday.TomAge()
            };
            return new ResultInfo(ResultState.SUCCESS, "success", data);
        }

        /// <summary>
        /// 提交意见
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> SubmitAdviceAsync(YB_Advice model)
        {
            if (!Validate.IsValidMobile(model.Phone))
            {
                return new ResultInfo(ResultState.FAIL, "手机号格式不正确");
            }
            if (string.IsNullOrEmpty(model.Content))
            {
                return new ResultInfo(ResultState.SUCCESS, "内容不可为空");
            }
            if (model.Content.Length > 500)
            {
                return new ResultInfo(ResultState.FAIL, "内容不可超过500字");
            }
            model.CreateTime = DateTime.Now;
            await dbClient.Insertable<YB_Advice>(model).ExecuteCommandAsync();
            return new ResultInfo(ResultState.SUCCESS, "感谢您的反馈");
        }

        /// <summary>
        /// 解密微信运动
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public async Task<WXRunListModel> DecodeWxRunBySessionIdAsync(string sessionId, string encryptedData, string iv)
        {
            var sessionBag = await SessionContainer.GetSessionAsync(sessionId);
            if (sessionBag == null)
            {
                return null;
            }
            var rundata = Senparc.Weixin.WxOpen.Helpers.EncryptHelper.DecryptRunData(sessionId, encryptedData, iv);
            if (rundata != null && rundata.stepInfoList.Count > 0)
            {
                //第一次保存30天的,第二次就更新当天的。
                var list = new List<YB_WXRun>();
                YB_WXRun step = null;
                long topstep = 0;
                long topsteptime = 0;
                bool ischange = false;
                var reldata = await dbClient.Queryable<YB_UserRealData>().Where(x => x.UserId == authInfo.UserId).FirstAsync();
                if (reldata != null)
                {
                    topstep = reldata.TopStep;
                    topsteptime = reldata.TopStepTime;
                }
                rundata.stepInfoList.ForEach(x =>
                {
                    var data = new YB_WXRun
                    {
                        Step = x.step,
                        CreateTime = x.timestamp.ToDatetimeFromTimeStamp(),
                        TimeStamp = x.timestamp,
                        UserId = authInfo.UserId
                    };
                    list.Add(data);
                    if (data.CreateTime.Date.Equals(DateTime.Now.Date))
                    {
                        step = data;
                    }
                    if (data.Step > topstep)
                    {
                        topstep = data.Step;
                        topsteptime = data.TimeStamp;
                        ischange = true;
                    }
                });
                var olddata = await dbClient.Queryable<YB_WXRun>().Where(x => SqlFunc.DateIsSame(x.CreateTime, step.CreateTime, DateType.Day) && x.UserId == authInfo.UserId).FirstAsync();
                if (olddata != null)
                {
                    await dbClient.Updateable<YB_WXRun>()
                         .SetColumns(x => new YB_WXRun
                         {
                             Step = step.Step,
                             CreateTime = step.CreateTime,
                             TimeStamp = step.TimeStamp
                         })
                         .Where(x => x.Id == olddata.Id)
                         .ExecuteCommandAsync();
                }
                else
                {
                    if (await dbClient.Queryable<YB_WXRun>().AnyAsync(x => x.UserId == authInfo.UserId))
                    {
                        await dbClient.Insertable<YB_WXRun>(step).ExecuteCommandAsync();
                    }
                    else
                    {
                        await dbClient.Insertable<YB_WXRun>(list).ExecuteCommandAsync();
                    }
                }
                if (ischange)
                {
                    await dbClient.Updateable<YB_UserRealData>().SetColumns(x => new YB_UserRealData
                    {
                        TopStep = topstep,
                        TopStepTime = topsteptime
                    }).Where(x => x.UserId == authInfo.UserId).ExecuteCommandAsync();
                }
                var returndata = new WXRunListModel
                {
                    stepInfoList = list.OrderByDescending(x => x.TimeStamp)
                    .Take(7)
                    .Select(x => new WXRunItemModel
                    {
                        createtime = x.CreateTime.ToYearDate(),
                        Step = x.Step
                    })
                    .ToList(),
                    TodayStep = step.Step,
                    TopStep = topstep,
                    TopStepTime = topsteptime,
                    TopStepDateTime = topsteptime.ToDatetimeFromTimeStamp().ToYearDate()
                };
                returndata.TotalStep = returndata.stepInfoList.Sum(x => x.Step);
                return returndata;
            }
            return null;
        }
        /// <summary>
        /// 获取八电极测量数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetBodyMeasureInfoAsync(UserBodyMeasureInfoModel model)
        {
            //获取此家庭成员的体重信息
            var family = await dbClient.Queryable<YB_Family>().Where(x => x.Id == model.familyid).FirstAsync();
            if (family == null)
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            int age = model.birthday.ToAge();
            YB_nResult result = null;
            Guid fansid = Guid.Empty;
            int isfirst = 0;//认领状态,0-未认领,1-已认领
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(model.devtype);
            if (!string.IsNullOrEmpty(model.fansid) && Guid.TryParse(model.fansid, out fansid))
            {
                //更新关联用户
                await dbClient.Updateable<YB_RegUser>().SetColumns(x => new YB_RegUser
                {
                    FansId = fansid
                }).Where(x => x.Id == authInfo.UserId).ExecuteCommandAsync();

                //更新最新的记录为当前用户
                var lastresult = await dbClient.Queryable<YB_nUserResult>()
                    .Where(x => x.FansId == fansid && x.DevType == 2 && x.Status == 1)
                    .OrderBy(x => x.CreateTime, OrderByType.Desc)
                    .FirstAsync();
                if (lastresult != null)
                {
                    result = await dbClient.Queryable<YB_nResult>().FirstAsync(x => x.Id == lastresult.Id);
                }
            }
            else if(model.familyid > 0)
            {
                var userresult = await dbClient.Queryable<YB_nUserResult>().Where(x => devtypes.Contains(x.DevType) && x.FamilyId == model.familyid && x.Status == 1)
                    .OrderBy(x => x.CreateTime, OrderByType.Desc)
                    .FirstAsync();
                if (userresult != null)
                {
                    result = await dbClient.Queryable<YB_nResult>().FirstAsync(x => x.Id == userresult.Id);
                    isfirst = 1;
                }
            }
            else
            {
                var userresult = await dbClient.Queryable<YB_nUserResult>().Where(x => devtypes.Contains(x.DevType) && x.UserId == authInfo.UserId && x.Status == 1)
                    .OrderBy(x => x.CreateTime, OrderByType.Desc)
                    .FirstAsync();
                if (userresult != null)
                {
                    result = await dbClient.Queryable<YB_nResult>().FirstAsync(x => x.Id == userresult.Id);
                    isfirst = 1;
                }
            }
            decimal height = model.height;
            //更新家庭成员信息
            //如果未认领
            if (isfirst == 0 && result != null)
            {
                height = result.Height;
                await dbClient.Updateable<YB_Family>().SetColumns(x => new YB_Family
                {
                    Height = height,
                    Age = age,
                    Sex = model.sex,
                    Birthday = model.birthday,
                    LastHeartTime = result.CreateTime,
                    Weight = result.Weight
                }).Where(x => x.Id == model.familyid).ExecuteCommandAsync();
                //更新家庭成员数据
                var familydata = await dbClient.Queryable<YB_FamilyData>().FirstAsync(x => x.FamilyId == model.familyid);
                if (familydata != null)
                {
                    decimal lasttimeheight = familydata.LastHeight - height;
                    decimal lasttimeweight = familydata.LastWeight - result.Weight;
                    await dbClient.Updateable<YB_FamilyData>().SetColumns(x => new YB_FamilyData
                    {
                        LastWeight = result.Weight,
                        LastResultTime = result.CreateTime,
                        LastHeight = height,
                        LastTimeHeight = lasttimeheight,
                        LastTimeWeight = lasttimeweight,
                        TodayCount = x.TodayCount + 1,
                        TotalCount = x.TotalCount + 1
                    }).Where(x => x.FamilyId == model.familyid).ExecuteCommandAsync();
                }
                if (await dbClient.Queryable<YB_FamilyRealData>().AnyAsync(x => x.FamilyId == model.familyid && x.DevType == model.devtype && !SqlFunc.HasValue(x.FirstResultTime)))
                {
                    await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                    {
                        LastHeight = height,
                        LastResultTime = result.CreateTime,
                        LastTimeHeight = x.LastHeight - height,
                        LastTimeWeight = x.LastWeight - result.Weight,
                        TodayCount = x.TodayCount + 1,
                        TotalCount = x.TotalCount + 1,
                        LastWeight = result.Weight,
                        FirstResultTime = result.CreateTime,
                        FirstHeight = height,
                        FirstWeight = result.Weight
                    })
                        .Where(x => x.FamilyId == model.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                }
                else if (await dbClient.Queryable<YB_FamilyRealData>().AnyAsync(x => x.FamilyId == model.familyid && x.DevType == model.devtype))
                {
                    await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                    {
                        LastHeight = height,
                        LastResultTime = result.CreateTime,
                        LastTimeHeight = x.LastHeight - height,
                        LastTimeWeight = x.LastWeight - result.Weight,
                        TodayCount = x.TodayCount + 1,
                        TotalCount = x.TotalCount + 1,
                        LastWeight = result.Weight
                    })
                        .Where(x => x.FamilyId == model.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                }
                else
                {
                    var realdata = new YB_FamilyRealData
                    {
                        FamilyId = model.familyid,
                        FirstHeight = height,
                        FirstResultTime = result.CreateTime,
                        DevType = model.devtype,
                        CreateTime = DateTime.Now,
                        FirstWeight = result.Weight,
                        Id = IDGen.NextID(),
                        LastHeight = height,
                        LastResultTime = result.CreateTime,
                        LastTimeHeight = 0,
                        LastTimeWeight = 0,
                        LastWeight = result.Weight,
                        TodayCount = 1,
                        TotalCount = 1,
                        UserId = authInfo.UserId
                    };
                    await dbClient.Insertable(realdata).ExecuteCommandAsync();
                }
                //更新yb_nuserresult
                await dbClient.Updateable<YB_nUserResult>().SetColumns(x => new YB_nUserResult
                {
                    UserId = authInfo.UserId,
                    FamilyId = model.familyid
                }).Where(x => x.Id == result.Id).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Updateable<YB_Family>().SetColumns(x => new YB_Family
                {
                    Height = height,
                    Age = age,
                    Sex = model.sex,
                    Birthday = model.birthday
                }).Where(x => x.Id == model.familyid).ExecuteCommandAsync();
            }
            if (result == null)
            {
                return new ResultInfo(ResultState.NORESULT, "未找到测量数据,请重新测量");
            }
            var data = await _bodyFatHelperService.CalcBody120FatAsync(result.Weight, height, age, model.sex, result.LeftArmImp, result.RightArmImp, result.LeftLegImp, result.RightLegImp, result.Imp);
            if (data == null)
            {
                return new ResultInfo(ResultState.NORESULT, "测量结果计算失败");
            }
            data.Id = result.Id;
            var leveljson = new MeasureLevelDto
            {
                bmiLevel = data.bmiLevel,
                sfrLevel = data.sfrLevel,
                SkeletalMuscleLevel = data.SkeletalMuscleLevel,
                bodyageLevel = data.bodyageLevel,
                bodylevel = data.bodylevel,
                boneLevel = data.boneLevel,
                fatLevel = data.fatLevel,
                fat_rLevel = data.fat_rLevel,
                fat_wLevel = data.fat_wLevel,
                kcalLevel = data.kcalLevel,
                muscleLevel = data.muscleLevel,
                musulevalLevel = data.musulevalLevel,
                proteinLevel = data.proteinLevel,
                proteinvalLevel = data.proteinvalLevel,
                visceralLevel = data.visceralLevel,
                waterLevel = data.waterLevel
            }.ToJson();
            #region 更新测量结果
            int month = model.birthday.ToMonth();
            if (!await dbClient.Queryable<YB_nMeasureResult>().AnyAsync(x => x.Id == result.Id))
            {
                await dbClient.Insertable(new YB_nMeasureResult
                {
                    Id = result.Id,
                    DevType = result.DevType,
                    Age = family.Age,
                    sfr = data.sfr,
                    Sex = family.Sex,
                    bmi = data.bmi,
                    body = data.body,
                    bodyage = data.bodyage,
                    bone = data.bone,
                    cmi = data.cmi,
                    createtime = DateTime.Now,
                    fatlevel = data.fatLevel,
                    fat_r = data.fat_r,
                    fat_w = data.fat_w,
                    Height = result.Height,
                    kcal = data.kcal,
                    lbm = data.lbm,
                    Month = month,
                    muscle = data.muscle,
                    muscleval = data.muscleval,
                    protein = data.protein,
                    proteinval = data.proteinval,
                    visceral = data.visceral,
                    water = data.water,
                    Weight = result.Weight,
                    BodyFat = data.bodyfatraterunk,
                    SfrVal = data.sfrval,
                    SkeletalMuscle = data.SkeletalMuscle,
                    BodyFatVal = data.bodyfatkgtrunk,
                    LeftFootFat = data.bodyfatrateleftleg,
                    BodyMuscle = data.muscleratetrunk,
                    BodyMuscleVal = data.musclekgtrunk,
                    IdealWeight = data.idealweight,
                    LeftFootFatVal = data.bodyfatkgleftleg,
                    LeftFootMuscle = data.musclerateleftleg,
                    LeftFootMuscleVal = data.musclekgleftleg,
                    LeftHandFat = data.bodyfatrateleftarm,
                    LeftHandFatVal = data.bodyfatkgleftarm,
                    LeftHandMuscle = data.musclerateleftarm,
                    LeftHandMuscleVal = data.musclekgleftarm,
                    RightFootFat = data.bodyfatraterightleg,
                    RightFootFatVal = data.bodyfatkgrightleg,
                    RightFootMuscle = data.muscleraterightleg,
                    RightFootMuscleVal = data.musclekgrightleg,
                    RightHandFat = data.bodyfatraterightarm,
                    RightHandFatVal = data.bodyfatkgrightarm,
                    RightHandMuscle = data.muscleraterightarm,
                    RightHandMuscleVal = data.musclekgrightarm
                }).ExecuteCommandAsync();
            }
            else
            {
                //更新记录
                await dbClient.Updateable<YB_nMeasureResult>().SetColumns(x => new YB_nMeasureResult
                {
                    Age = family.Age,
                    sfr = data.sfr,
                    Sex = family.Sex,
                    bmi = data.bmi,
                    body = data.body,
                    bodyage = data.bodyage,
                    bone = data.bone,
                    cmi = data.cmi,
                    fatlevel = data.fatLevel,
                    fat_r = data.fat_r,
                    fat_w = data.fat_w,
                    Height = height,
                    kcal = data.kcal,
                    lbm = data.lbm,
                    Month = month,
                    muscle = data.muscle,
                    muscleval = data.muscleval,
                    protein = data.protein,
                    proteinval = data.proteinval,
                    visceral = data.visceral,
                    water = data.water,
                    BodyFat = data.bodyfatraterunk,
                    SfrVal = data.sfrval,
                    SkeletalMuscle = data.SkeletalMuscle,
                    BodyFatVal = data.bodyfatkgtrunk,
                    LeftFootFat = data.bodyfatrateleftleg,
                    BodyMuscle = data.muscleratetrunk,
                    BodyMuscleVal = data.musclekgtrunk,
                    IdealWeight = data.idealweight,
                    LeftFootFatVal = data.bodyfatkgleftleg,
                    LeftFootMuscle = data.musclerateleftleg,
                    LeftFootMuscleVal = data.musclekgleftleg,
                    LeftHandFat = data.bodyfatrateleftarm,
                    LeftHandFatVal = data.bodyfatkgleftarm,
                    LeftHandMuscle = data.musclerateleftarm,
                    LeftHandMuscleVal = data.musclekgleftarm,
                    RightFootFat = data.bodyfatraterightleg,
                    RightFootFatVal = data.bodyfatkgrightleg,
                    RightFootMuscle = data.muscleraterightleg,
                    RightFootMuscleVal = data.musclekgrightleg,
                    RightHandFat = data.bodyfatraterightarm,
                    RightHandFatVal = data.bodyfatkgrightarm,
                    RightHandMuscle = data.muscleraterightarm,
                    RightHandMuscleVal = data.musclekgrightarm
                }).Where(x => x.Id == result.Id).ExecuteCommandAsync();

                //更新实时数据和儿童模式的曲线
                var familyrealdata = await dbClient.Queryable<YB_FamilyRealData>().FirstAsync(x => x.FamilyId == model.familyid && x.DevType == model.devtype);
                if (familyrealdata != null && familyrealdata.LastHeight != height)
                {
                    await _capBus.PublishAsync("result.service.updateuserheightdata", new UpdateUserHeightDataS2SDto
                    {
                        familyid = model.familyid,
                        DevType = model.devtype,
                        Height = height,
                        LastResultHeightTime = familyrealdata.LastResultHeightTime,
                        LastHeight = familyrealdata.LastHeight,
                        HalfYearHeight = familyrealdata.HalfYearHeight,
                        YearHeight = familyrealdata.YearHeight
                    });
                }
            }
            if (!await dbClient.Queryable<YB_nBodyMeasure>().AnyAsync(x => x.Id == result.Id))
            {
                await dbClient.Insertable(new YB_nBodyMeasure
                {
                    Id = result.Id,
                    LevelJson = leveljson
                }).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Updateable<YB_nBodyMeasure>().SetColumns(x => new YB_nBodyMeasure
                {
                    LevelJson = leveljson
                }).Where(x => x.Id == result.Id).ExecuteCommandAsync();
            }
            #endregion
            var returndata = data.Adapt<UserBodyMeasureS2CDto>();
            var currentdata = data.Adapt<UserMeasureModel>();
            var list = HisList(model.sex, age, result.Weight, currentdata);
            if (list != null)
            {
                list.Add(new MeasureInfoItem
                {
                    name = "skeletalmuscle",
                    slist = _bodyFatHelperService.skeletalmusclekg_val(model.sex, age, returndata.SkeletalMuscle),
                    Color = _bodyFatHelperService.GetLevelColor(returndata.SkeletalMuscleLevel)
                });
            }
            returndata.list = list;
            return new ResultInfo(ResultState.SUCCESS, "success", returndata);
        }
        /// <summary>
        /// 获取趋势信息
        /// </summary>
        /// <param name="bodyQueryTrandDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetTrendListAsync(BodyQueryTrandDto bodyQueryTrandDto)
        {
            if (!bodyQueryTrandDto.starttime.HasValue)
            {
                bodyQueryTrandDto.starttime = DateTime.Now.AddDays(-7).Date;
            }
            if (!bodyQueryTrandDto.endtime.HasValue)
            {
                bodyQueryTrandDto.endtime = DateTime.Now.AddDays(1).Date;
            }
            else
            {
                bodyQueryTrandDto.endtime = bodyQueryTrandDto.endtime.Value.AddDays(1).Date;
            }
            //获取每项的历史值
            var table = await dbClient.Ado.UseStoredProcedure().GetDataTableAsync("proc_getmeasureitem_page", new
            {
                familyid = bodyQueryTrandDto.familyid,
                type = bodyQueryTrandDto.DevType,
                starttime = bodyQueryTrandDto.starttime.Value,
                endtime = bodyQueryTrandDto.endtime.Value,
                stype = 1, //按次
                nopage = 0 //不分页
            });
            if (table == null)
            {
                return new ResultInfo(ResultState.FAIL, "未找到测量记录");
            }
            List<TrandS2CDto> list = new List<TrandS2CDto>();
            foreach (DataRow row in table.Rows)
            {
                list.Add(new TrandS2CDto
                {
                    id = row["resultid"].ToString(),
                    bmi = row["bmi"].ToDecimal(1),
                    createtime = row["timestamp"].ToString().ToYearDate(),
                    fat_r = row["fat_r"].ToDecimal(1),
                    muscle = row["muscle"].ToDecimal(1),
                    weight = row["weight"].ToDecimal(1),
                    time = row["timestamp"].ToDate(),
                    height = row["height"].ToDecimal()
                });
            }
            return new ResultInfo(ResultState.SUCCESS, "success", list);
        }

        /// <summary>
        /// 获取八电极趋势信息
        /// </summary>
        /// <param name="bodyQueryTrandDto"></param>
        /// <returns></returns>
        public async Task<ResultInfo> GetBodyTrendListAsync(BodyQueryTrandDto bodyQueryTrandDto)
        {
            return await GetTrendListAsync(bodyQueryTrandDto);
        }
        /// <summary>
        /// 检查用户是否存在
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public async Task<bool> IsExistUserAsync(int userid)
        {
            return await dbClient.Queryable<YB_RegUser>().AnyAsync(x => x.Id == userid && x.Status == StatusType.Enabled);
        }
        /// <summary>
        /// 设备激活
        /// </summary>
        /// <returns></returns>
        public async Task<ResultInfo> ActiveAsync(string sn, string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return new ResultInfo(ResultState.FAIL, "请先扫描产品码");
            }
            sn = sn.ToStrNoEmpty();
            code = code.ToStrNoEmpty();
            //记录日志
            if (code.ToLower().StartsWith("http"))
            {
                var arr = code.Split('?');
                if (arr.Length != 2)
                {
                    return new ResultInfo(ResultState.FAIL, "请先扫描产品码");
                }
                arr = arr[1].Split('=');
                if (arr.Length != 2)
                {
                    return new ResultInfo(ResultState.FAIL, "请先扫描产品码");
                }
                code = arr[1];
            }
            if (sn.ToLower().StartsWith("http://ybapi.ybhdmob.com/body/get"))
            {
                var arr = sn.Split('&');
                if (arr.Length != 3)
                {
                    return new ResultInfo(ResultState.FAIL, "请先扫描测量二维码");
                }
                var newarr = arr[1].Split('=');
                if (newarr.Length != 2)
                {
                    return new ResultInfo(ResultState.FAIL, "请先扫描测量二维码");
                }
                sn = newarr[1];
            }
            //检查是否存在发货记录
            var productdev = await dbClient.Queryable<YB_OutProductDev>().Where(x => x.DeviceCode == code).FirstAsync();
            if (productdev == null)
            {
                return new ResultInfo(ResultState.FAIL, "未找到出货记录,请联系客服人员");
            }
            var product = await dbClient.Queryable<YB_OutProduct>().FirstAsync(x => x.Id == productdev.OrderId);
            if (product == null)
            {
                return new ResultInfo(ResultState.FAIL, "未找到出货记录,请联系客服人员");
            }
            //检查此sn是否已存在,如果不存在则进行注册,否则继续下一步
            var equ = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.FacCode == code);
            if (equ == null)
            {
                return new ResultInfo(ResultState.FAIL, "设备未找到,请联系客服人员");
            }
            //检查此设备是否已激活
            if (!string.IsNullOrEmpty(equ.Ecode) && equ.Status == DeviceStatus.Run)
            {
                return new ResultInfo(ResultState.FAIL, "设备已运行,重复激活");
            }
            if (equ.Status == (int)DeviceStatus.Stop)
            {
                return new ResultInfo(ResultState.FAIL, "设备已停止运行");
            }
            //检查此sn是否已存在
            if (await dbClient.Queryable<YB_Device>().AnyAsync(x => x.Ecode == sn && x.FacCode != code))
            {
                return new ResultInfo(ResultState.FAIL, "设备编号匹配失败");
            }
            //激活设备
            await dbClient.Updateable<YB_Device>().SetColumns(x => new YB_Device
            {
                ActiveTime = DateTime.Now,
                Status = DeviceStatus.Run,
                BusinessId = product.BusinessId,
                Ecode = sn
            }).Where(x => x.FacCode == code).ExecuteCommandAsync();

            //记录分配记录
            var allocdata = new YB_DeviceAlloc
            {
                Id = IDGen.NextID(),
                CreateTime = DateTime.Now,
                EquId = equ.Id,
                FromBusinessId = product.BusinessId,
                ToBusinessId = 0,
                Type = DeviceAllocType.ACTIVE
            };
            await dbClient.Insertable(allocdata).ExecuteCommandAsync();
            //更新统计
            int todaydevactivecnt = await dbClient.Queryable<YB_Device>().Where(x => x.BusinessId == product.BusinessId && SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
            int devcnt = await dbClient.Queryable<YB_Device>().Where(x => x.BusinessId == product.BusinessId).CountAsync();
            int businesscnt = await dbClient.Queryable<YB_Business>().Where(x => x.ParentId == product.BusinessId).CountAsync();
            if (!await dbClient.Queryable<YB_BusinessRealData>().AnyAsync(x => x.BusinessId == product.BusinessId))
            {
                await dbClient.Insertable<YB_BusinessRealData>(new YB_BusinessRealData
                {
                    BusinessId = product.BusinessId,
                    Balance = 0,
                    BusinessCount = businesscnt,
                    CreateTime = DateTime.Now,
                    DevCount = devcnt,
                    TodayIncome = 0,
                    TodayResultCnt = 0,
                    TotalIncome = 0,
                    TotalResultCnt = 0,
                    TotalTxAmount = 0,
                    TodayDevCount = todaydevactivecnt,
                    TotalRealCnt = 0,
                    TodayRealCnt = 0
                }).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                {
                    DevCount = devcnt,
                    TodayDevCount = todaydevactivecnt,
                    BusinessCount = businesscnt
                }).Where(x => x.BusinessId == product.BusinessId).ExecuteCommandAsync();
            }
            return new ResultInfo(ResultState.SUCCESS, "设备激活成功");
        }
        /// <summary>
        /// 退出登录
        /// </summary>
        /// <param name="sessionId"></param>
        /// <returns></returns>
        public async Task<ResultInfo> OutLogin(string sessionId)
        {
            var sessionBag = await SessionContainer.GetSessionAsync(sessionId);
            if (sessionBag == null)
            {
                return new ResultInfo(ResultState.FAIL, "sessionId未找到");
            }
            //更新
            await dbClient.Updateable<YB_UserWX>().SetColumns(x => new YB_UserWX
            {
                IsOutLogin = 0
            }).Where(x => x.openid == sessionBag.OpenId).ExecuteCommandAsync();
            await SessionContainer.RemoveFromCacheAsync(sessionBag.OpenId);
            return new ResultInfo(ResultState.SUCCESS, "退出登录成功");
        }

        /// <summary>
        /// 获取用户使用过的设备类型列表
        /// </summary>
        /// <param name="appid">小程序appid</param>
        /// <returns></returns>
        public async Task<ResultInfo> GetDevTypeListAsync(string appid)
        {
            var newlist = new List<YB_DeviceTypeExt>();
            var AppData = await dbClient.Queryable<YB_DeviceTypeApp>().Where(x => x.Status == StatusType.Enabled && x.AppId == appid).FirstAsync();
            if (AppData != null)
            {
                var ids = AppData.DevType.Split(",").ToList();
                var list = await dbClient.Queryable<YB_UserEqu>()
                .Where(x => x.UserId == authInfo.UserId)
                .OrderBy(x => x.CreateTime, OrderByType.Desc)
                .Select(x => x.DevType)
                .ToListAsync();
                var types = await dbClient.Queryable<YB_DeviceType>().ToListAsync();
                //  var InIds = new List<string>();
                types.ForEach(x =>
                {
                    //List<string> newids = x.Content.Split(",").ToList();
                    //bool IsExist = false;
                    //for(var i = 0; i < InIds.Count; i++)
                    //{
                    //    if (newids.Contains(InIds[i])){
                    //        IsExist = true;
                    //        break;
                    //    }
                    //}
                    if (ids.Contains($"{x.Code}") && list.Contains(x.Code)
                    // && !IsExist
                    )
                    {
                        newlist.Add(new YB_DeviceTypeExt
                        {
                            Name = x.ExtName,
                            HeadImg = x.HeadImg,
                            Id = x.Code
                        });
                        //   InIds.Add($"{x.Code}");
                    }
                });
            }
            var returnlist = newlist.Adapt<List<UserDevTypeS2CDto>>();
            return new ResultInfo(ResultState.SUCCESS, "success", returnlist);
        }

        /// <summary>
        /// 添加设备类型
        /// </summary>
        /// <param name="devtype"></param>
        /// <returns></returns>
        public async Task<ResultInfo> AddDevTypeAsync(int devtype)
        {
            //更新合计数据并添加用户设备类型
            await _capBus.PublishAsync("reguser.service.insertreguserdevtype", new RegUserDevTypeS2SDto
            {
                DevType = devtype,
                UserId = authInfo.UserId
            });
            return new ResultInfo(ResultState.SUCCESS, "类型添加成功");
        }
        /// <summary>
        /// 修改初始体重
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ResultInfo> SubmitFirstWeight(UserFirstWeightC2SDto data)
        {
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(data.DevType);
            if (!await dbClient.Queryable<YB_FamilyRealData>().AnyAsync(x => x.FamilyId == data.FamilyId && x.DevType == data.DevType))
            {
                var familydata = await dbClient.Queryable<YB_FamilyData>().FirstAsync(x => x.FamilyId == data.FamilyId);
                var insertdata = new YB_FamilyRealData
                {
                    FirstHeight = familydata != null ? familydata.FirstHeight : 0,
                    FirstResultTime = data.Time,
                    FirstWeight = data.Weight,
                    CreateTime = DateTime.Now,
                    DevType = data.DevType,
                    FamilyId = data.FamilyId,
                    Id = IDGen.NextID(),
                    LastHeight = familydata != null ? familydata.LastHeight : 0,
                    LastResultTime = null,
                    LastTimeHeight = 0,
                    LastTimeWeight = 0,
                    LastWeight = 0,
                    TodayCount = 0,
                    TotalCount = 0,
                    UserId = authInfo.UserId
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                {
                    FirstResultTime = data.Time,
                    FirstWeight = data.Weight
                }).Where(x => x.FamilyId == data.FamilyId && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
            }
            return new ResultInfo(ResultState.SUCCESS, "初始体重设置成功");
        }
    }
}
