using DotNetCore.CAP;
using Furion;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Mapster;
using Nirvana.Common;
using Nirvana.Common.ApiBase;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.CommonService.BodyFatHelper;
using YBDevice.CommonService.DevTypeInfo;
using YBDevice.Entity;
using YBDevice.NApi.Application.UserInfo;

namespace YBDevice.NApi.Application.MeasureInfo
{
    /// <summary>
    /// 用户测量处理
    /// </summary>
    public class ResultService : BaseService, IResultService, ITransient
    {
        private readonly ISqlSugarRepository<YB_nMeasureResult> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IBodyFatHelperService _bodyFatHelperService;
        private readonly IDeviceTypeService _deviceTypeService;
        private readonly ICapPublisher _capBus;
        public ResultService(ISqlSugarRepository<YB_nMeasureResult> sqlSugarRepository, IBodyFatHelperService bodyFatHelperService, ICapPublisher capPublisher, IDeviceTypeService deviceTypeService)

        {
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _bodyFatHelperService = bodyFatHelperService;
            _capBus = capPublisher;
            _deviceTypeService = deviceTypeService;
        }
        /// <summary>
        /// 增加测量记录,用于蓝牙传输,适用于F01PRO
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> MeasureDataAsync(MeasureDataSubmitModel model)
        {
            //检查家庭成员是否存在
            if (!await dbClient.Queryable<YB_Family>().AnyAsync(x => x.Id == model.familyid))
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            //检查设备是否存在
            var device = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == model.ecode);
            if (device == null)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备未找到,请到管理端进行激活");
            }
            if (device.Status != (int)DeviceStatus.Run)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备还未激活,请先激活");
            }
            decimal weight = AnalyWeight(model.weight);
            var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == model.familyid);
            //增加yb_nresult
            var result = new YB_nResult
            {
                Id = IDGen.NextID(),
                SourceType = 1,
                BusinessId = device.BusinessId,
                CreateTime = DateTime.Now,
                DevType = device.Type,
                EquId = device.Id,
                Height = model.height,
                Weight = weight,
                Imp = model.imp,
                LeftArmImp = 0,
                RightArmImp = 0,
                LeftLegImp = 0,
                RightLegImp = 0
            };
            await dbClient.Insertable(result).ExecuteCommandAsync();

            //用户认领,加入认领表并进行结果计算
            var month = family.Birthday.ToMonth();
            var fansid = await dbClient.Queryable<YB_RegUser>().Where(x => x.Id == authInfo.UserId).Select(x => x.FansId).FirstAsync();
            //增加yb_nuserresult
            var userresult = new YB_nUserResult
            {
                CreateTime = result.CreateTime,
                FamilyId = model.familyid,
                Id = result.Id,
                UserId = authInfo.UserId,
                DevType = result.DevType,
                FansId = fansid
            };
            await dbClient.Insertable(userresult).ExecuteCommandAsync();
            //计算结果
            MeasureCalcDto calcdata = new MeasureCalcDto
            {
                weight = weight.ToString(),
                imp = model.imp,
                height = model.height,
                ecode = model.ecode,
                familyid = model.familyid,
                bodyage = model.bodyage,
                fat_r = model.fat_r,
                muscle = model.muscle,
                water = model.water,
                bone = model.bone,
                kcal = model.kcal,
                visceral = model.visceral,
                protein = model.protein,
                bmi = model.bmi,
                sfr = model.sfr,
                fatlevlval = model.fatlevlval,
                StandardWeight = model.StandardWeight,
                fat_w = model.fat_w,
                lbm = model.lbm,
                muscleval = model.muscleval,
                proteinval = model.proteinval,
                age = family.Age,
                sex = family.Sex
            };
            var calcresult = _bodyFatHelperService.CalcBodyFat(calcdata);
            //增加计算结果
            var measureresult = new YB_nMeasureResult
            {
                Id = result.Id,
                sfr = calcresult.sfr,
                Sex = family.Sex,
                SfrVal = 0,
                SkeletalMuscle = 0,
                Age = family.Age,
                DevType = device.Type,
                bmi = calcresult.bmi,
                body = calcresult.bodylevel,
                bodyage = calcresult.bodyage,
                BodyFat = 0,
                BodyFatVal = 0,
                BodyMuscle = 0,
                BodyMuscleVal = 0,
                bone = calcresult.bone,
                cmi = calcresult.cmi,
                createtime = DateTime.Now,
                fatlevel = calcresult.fatLevel,
                fat_r = calcresult.fat_r,
                fat_w = calcresult.fat_w,
                Height = model.height,
                IdealWeight = calcresult.standardWeight.ToDecimal(),
                kcal = calcresult.kcal,
                lbm = calcresult.lbm,
                LeftFootFat = 0,
                LeftFootFatVal = 0,
                LeftFootMuscle = 0,
                LeftFootMuscleVal = 0,
                LeftHandFat = 0,
                LeftHandFatVal = 0,
                LeftHandMuscle = 0,
                LeftHandMuscleVal = 0,
                Month = month,
                muscle = calcresult.muscle,
                muscleval = calcresult.muscleval,
                protein = calcresult.protein,
                proteinval = calcresult.proteinval,
                RightFootFat = 0,
                RightFootFatVal = 0,
                RightFootMuscle = 0,
                RightFootMuscleVal = 0,
                RightHandFat = 0,
                RightHandFatVal = 0,
                RightHandMuscle = 0,
                RightHandMuscleVal = 0,
                visceral = calcresult.visceral,
                water = calcresult.water,
                Weight = calcresult.weight
            };
            await dbClient.Insertable(measureresult).ExecuteCommandAsync();

            //更新合计数据并添加用户设备类型
            await _capBus.PublishAsync("result.service.updaterealdata", new UpdateRealDataS2SDtO
            {
                CreateTime = result.CreateTime,
                DevId = device.Id,
                familyid = family.Id,
                height = model.height,
                IsUserTake = true,
                UserId = userresult.UserId,
                weight = weight
            });
            return new ResultInfo(ResultState.SUCCESS, "测量成功");
        }
        /// <summary>
        /// 添加测量记录
        /// </summary>
        /// <param name="data"></param>
        /// <param name="device"></param>
        /// <param name="family"></param>
        /// <returns></returns>
        private async Task InsertResultAsync(InsertResultC2SDto data, YB_Device device, YB_Family family)
        {
            #region 增加yb_nresult
            if (!data.CreateTime.HasValue)
            {
                data.CreateTime = DateTime.Now;
            }
            var result = new YB_nResult
            {
                Id = data.ResultId != Guid.Empty ? data.ResultId : IDGen.NextID(),
                SourceType = data.SourceType,
                BusinessId = device.BusinessId,
                CreateTime = data.CreateTime.Value,
                DevType = device.Type,
                EquId = device.Id,
                Height = data.height,
                Weight = data.weight,
                Imp = data.imp,
                LeftArmImp = data.LeftArmImp,
                RightArmImp = data.RightArmImp,
                LeftLegImp = data.LeftLegImp,
                RightLegImp = data.RightLegImp
            };
            await dbClient.Insertable(result).ExecuteCommandAsync();
            #endregion
            if (data.IsUserTake)
            {
                var month = family.Birthday.ToMonth();
                var fansid = await dbClient.Queryable<YB_RegUser>().Where(x => x.Id == authInfo.UserId).Select(x => x.FansId).FirstAsync();
                //增加yb_nuserresult
                var userresult = new YB_nUserResult
                {
                    CreateTime = result.CreateTime,
                    FamilyId = data.familyid,
                    Id = result.Id,
                    UserId = data.UserId,
                    FansId = fansid,
                    DevType = device.Type
                };
                await dbClient.Insertable(userresult).ExecuteCommandAsync();
                //如果是八电极则调用八电极算法
                if (await dbClient.Queryable<YB_DeviceType>().AnyAsync(x => x.Code == device.Type && x.ProType == 3))
                {
                    var calcresult = await _bodyFatHelperService.CalcBody120FatAsync(data.weight, data.height, family.Age, family.Sex, data.LeftArmImp, data.RightArmImp, data.LeftLegImp, data.RightLegImp,data.imp);
                    var leveljson = new MeasureLevelDto
                    {
                        bmiLevel = calcresult.bmiLevel,
                        sfrLevel = calcresult.sfrLevel,
                        SkeletalMuscleLevel = calcresult.SkeletalMuscleLevel,
                        bodyageLevel = calcresult.bodyageLevel,
                        bodylevel = calcresult.bodylevel,
                        boneLevel = calcresult.boneLevel,
                        fatLevel = calcresult.fatLevel,
                        fat_rLevel = calcresult.fat_rLevel,
                        fat_wLevel = calcresult.fat_wLevel,
                        kcalLevel = calcresult.kcalLevel,
                        muscleLevel = calcresult.muscleLevel,
                        musulevalLevel = calcresult.musulevalLevel,
                        proteinLevel = calcresult.proteinLevel,
                        proteinvalLevel = calcresult.proteinvalLevel,
                        visceralLevel = calcresult.visceralLevel,
                        waterLevel = calcresult.waterLevel
                    }.ToJson();
                    var measureresult = new YB_nMeasureResult { 
                        Id = result.Id,
                        DevType = result.DevType,
                        Age = family.Age,
                        sfr = calcresult.sfr,
                        Sex = family.Sex,
                        bmi = calcresult.bmi,
                        body = calcresult.bodylevel,
                        bodyage = calcresult.bodyage,
                        bone = calcresult.bone,
                        cmi = calcresult.cmi,
                        createtime = result.CreateTime,
                        fatlevel = calcresult.fatLevel,
                        fat_r = calcresult.fat_r,
                        fat_w = calcresult.fat_w,
                        Height = result.Height,
                        kcal = calcresult.kcal,
                        lbm = calcresult.lbm,
                        Month = month,
                        muscle = calcresult.muscle,
                        muscleval = calcresult.muscleval,
                        protein = calcresult.protein,
                        proteinval = calcresult.proteinval,
                        visceral = calcresult.visceral,
                        water = calcresult.water,
                        Weight = result.Weight,
                        BodyFat = calcresult.bodyfatraterunk,
                        SfrVal = calcresult.sfrval,
                        SkeletalMuscle = calcresult.SkeletalMuscle,
                        BodyFatVal = calcresult.bodyfatkgtrunk,
                        LeftFootFat = calcresult.bodyfatrateleftleg,
                        BodyMuscle = calcresult.muscleratetrunk,
                        BodyMuscleVal = calcresult.musclekgtrunk,
                        IdealWeight = calcresult.idealweight,
                        LeftFootFatVal = calcresult.bodyfatkgleftleg,
                        LeftFootMuscle = calcresult.musclerateleftleg,
                        LeftFootMuscleVal = calcresult.musclekgleftleg,
                        LeftHandFat = calcresult.bodyfatrateleftarm,
                        LeftHandFatVal = calcresult.bodyfatkgleftarm,
                        LeftHandMuscle = calcresult.musclerateleftarm,
                        LeftHandMuscleVal = calcresult.musclekgleftarm,
                        RightFootFat = calcresult.bodyfatraterightleg,
                        RightFootFatVal = calcresult.bodyfatkgrightleg,
                        RightFootMuscle = calcresult.muscleraterightleg,
                        RightFootMuscleVal = calcresult.musclekgrightleg,
                        RightHandFat = calcresult.bodyfatraterightarm,
                        RightHandFatVal = calcresult.bodyfatkgrightarm,
                        RightHandMuscle = calcresult.muscleraterightarm,
                        RightHandMuscleVal = calcresult.musclekgrightarm
                    };
                    await dbClient.Insertable(measureresult).ExecuteCommandAsync();
                }
                //如果是两/四点击则调用四电极算法
                else
                {
                    //计算结果
                    var calcresult = _bodyFatHelperService.CalcBodyFat(data.weight.ToDouble(), data.height.ToDouble(), family.Age, data.imp.ToInt(), family.Sex);
                    //增加计算结果
                    var measureresult = new YB_nMeasureResult
                    {
                        Id = result.Id,
                        sfr = calcresult.sfr,
                        Sex = family.Sex,
                        SfrVal = 0,
                        SkeletalMuscle = 0,
                        Age = family.Age,
                        DevType = device.Type,
                        bmi = calcresult.bmi,
                        body = calcresult.bodylevel,
                        bodyage = calcresult.bodyage,
                        BodyFat = 0,
                        BodyFatVal = 0,
                        BodyMuscle = 0,
                        BodyMuscleVal = 0,
                        bone = calcresult.bone,
                        cmi = calcresult.cmi,
                        createtime = result.CreateTime,
                        fatlevel = calcresult.fatLevel,
                        fat_r = calcresult.fat_r,
                        fat_w = calcresult.fat_w,
                        Height = data.height,
                        IdealWeight = calcresult.standardWeight.ToDecimal(),
                        kcal = calcresult.kcal,
                        lbm = calcresult.lbm,
                        LeftFootFat = 0,
                        LeftFootFatVal = 0,
                        LeftFootMuscle = 0,
                        LeftFootMuscleVal = 0,
                        LeftHandFat = 0,
                        LeftHandFatVal = 0,
                        LeftHandMuscle = 0,
                        LeftHandMuscleVal = 0,
                        Month = month,
                        muscle = calcresult.muscle,
                        muscleval = calcresult.muscleval,
                        protein = calcresult.protein,
                        proteinval = calcresult.proteinval,
                        RightFootFat = 0,
                        RightFootFatVal = 0,
                        RightFootMuscle = 0,
                        RightFootMuscleVal = 0,
                        RightHandFat = 0,
                        RightHandFatVal = 0,
                        RightHandMuscle = 0,
                        RightHandMuscleVal = 0,
                        visceral = calcresult.visceral,
                        water = calcresult.water,
                        Weight = data.weight
                    };
                    await dbClient.Insertable(measureresult).ExecuteCommandAsync();
                }
                //如果是手动添加的
                if (data.SourceType == 2)
                {
                    var resultadd = new YB_nResultAdd
                    {
                        CreateTime = DateTime.Now,
                        ResultTime = result.CreateTime,
                        FamilyId = userresult.FamilyId,
                        Height = result.Height,
                        Id = result.Id,
                        UserId = data.UserId,
                        Weight = result.Weight
                    };
                }
            }
            //更新合计数据并添加用户设备类型
            if(data.SourceType != 2)
            {
                await _capBus.PublishAsync("result.service.updaterealdata", new UpdateRealDataS2SDtO
                {
                    CreateTime = result.CreateTime,
                    DevId = device.Id,
                    familyid = family.Id,
                    height = data.height,
                    IsUserTake = true,
                    UserId = data.UserId,
                    weight = data.weight,
                    SourceType = data.SourceType
                });
            }
        }

        /// <summary>
        /// 体重解析
        /// </summary>
        /// <param name="weight">重量值,带有单位</param>
        /// <returns></returns>
        private decimal AnalyWeight(string weight)
        {
            var wg = weight.ToUpper();
            if (wg.Contains("LB"))
            {
                wg = (wg.Replace("LB", "").ToDouble() * 0.4536).ToString();
            }
            else if (wg.Contains("JIN"))
            {
                wg = (wg.Replace("JIN", "").ToDouble() / 2.0).ToString();
            }
            else if (wg.Contains("ST")) //英石
            {
                wg = (wg.Replace("ST", "").ToDouble() * 6.35).ToString();
            }
            else
            {
                wg = wg.Replace("KG", "");
            }
            return wg.ToDecimal(2);
        }

        /// <summary>
        /// 增加测量记录,用于蓝牙传输
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> MeasureAsync(MeasureSubmitModel model)
        {
            //检查家庭成员是否存在
            if (!await dbClient.Queryable<YB_Family>().AnyAsync(x => x.Id == model.familyid))
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            //检查设备是否存在
            var device = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == model.ecode);
            if (device == null)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备未找到,请到管理端进行激活");
            }
            if (device.Status != (int)DeviceStatus.Run)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备还未激活,请先激活");
            }
            decimal weight = AnalyWeight(model.weight);
            var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == model.familyid);
            await InsertResultAsync(new InsertResultC2SDto
            {
                DevId = device.Id,
                SourceType = 1,
                ecode = device.Ecode,
                familyid = family.Id,
                height = model.height,
                imp = model.imp,
                IsUserTake = true,
                UserId = authInfo.UserId,
                weight = weight
            }, device, family);
            return new ResultInfo(ResultState.SUCCESS, "测量成功");
        }

        /// <summary>
        /// 手动增加测量记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultInfo> InsertMeasureAsync(UserMeasureSubmitModel model)
        {
            //检查家庭成员是否存在
            if (!await dbClient.Queryable<YB_Family>().AnyAsync(x => x.Id == model.familyid))
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            var device = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Id == 1);
            var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == model.familyid);
            var ctime = model.time.ToDate();
            string time = $"{ctime.Year}-{ctime.Month}-{ctime.Day} {DateTime.Now.Hour}:{DateTime.Now.Minute}:{DateTime.Now.Second}";
            DateTime createtime = time.ToDate();
            device.Type = model.DevType;
            await InsertResultAsync(new InsertResultC2SDto
            {
                DevId = device.Id,
                SourceType = 2,
                ecode = device.Ecode,
                familyid = family.Id,
                height = model.Height <= 0 ? family.Height : model.Height,
                imp = 0,
                IsUserTake = true,
                UserId = authInfo.UserId,
                weight = model.weight,
                CreateTime = createtime
            }, device, family);
            return new ResultInfo(ResultState.SUCCESS, "记录成功");
        }

        /// <summary>
        /// 获取历史记录
        /// </summary>
        /// <param name="param">查询参数</param>
        /// <returns></returns>
        public async Task<PageParms<MeasureHisList>> GetHistoryListAsync(ParamQuery param)
        {
            int familyid = param.keyword.ToInt();
            List<int> devtypes = new List<int>();
            var tempquery = dbClient.Queryable<YB_nUserResult, YB_nMeasureResult>((u, x) => new JoinQueryInfos(
                   JoinType.Left, u.Id == x.Id
               )).Where((u, x) => u.FamilyId == familyid);
            if (param.devtype > 0)
            {
                devtypes = await _deviceTypeService.GetDevTypesAsync(param.devtype);
                tempquery = tempquery.Where((u, x) => devtypes.Contains(u.DevType));
            }
            RefAsync<int> totalnum = 0;
            var query = await tempquery.OrderBy((u, x) => x.createtime, OrderByType.Desc)
                .Select((u, x) => new MeasureHisList
                {
                    bmi = x.bmi,
                    body = x.body,
                    bodyage = x.bodyage,
                    bone = x.bone,
                    cmi = x.cmi,
                    createtime = SqlFunc.ToString(x.createtime),
                    fatlevel = x.fatlevel,
                    fat_r = x.fat_r,
                    fat_w = x.fat_w,
                    Height = x.Height,
                    kcal = x.kcal,
                    lbm = x.lbm,
                    muscle = x.muscle,
                    muscleval = x.muscleval,
                    protein = x.protein,
                    proteinval = x.proteinval,
                    sfr = x.sfr,
                    visceral = x.visceral,
                    water = x.water,
                    weight = x.Weight,
                    Age = SqlFunc.ToString(x.Age),
                    Month = x.Month
                })
                .Mapper((it, cache) =>
                {
                    it.createtime = it.createtime.ToYearDateTime();
                    it.Age = it.Month.TomAge();
                })
                .ToPageListAsync(param.page, param.pagesize, totalnum);
            return new PageParms<MeasureHisList>
            {
                page = param.page,
                Items = query,
                totalnum = totalnum,
                limit = param.pagesize
            };
        }
        /// <summary>
        /// 手动添加的历史记录
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<PageParms<AddResultList>> GetAddListAsync(ParamQuery param)
        {
            var tempquery = dbClient.Queryable<YB_nResultAdd>();
            RefAsync<int> totalnum = 0;
            if (!string.IsNullOrEmpty(param.keyword))
            {
                var familyid = param.keyword.ToInt();
                tempquery = tempquery.Where(x => x.FamilyId == familyid);
            }
            else
            {
                tempquery = tempquery.Where(x => x.UserId == authInfo.UserId);
            }
            var query = await tempquery.OrderBy(x => x.CreateTime, OrderByType.Desc)
                .Select(x => new AddResultList
                {
                    CreateTime = SqlFunc.ToString(x.CreateTime),
                    Height = x.Height,
                    Weight = x.Weight,
                    Id = x.Id,
                    ResultTime = SqlFunc.ToString(x.ResultTime)
                })
                .Mapper((it, cache) =>
                {
                    it.CreateTime = it.CreateTime.ToYearDateTime();
                    it.ResultTime = it.ResultTime.ToYearDate();
                })
                .ToPageListAsync(param.page, param.pagesize, totalnum);
            return new PageParms<AddResultList>
            {
                page = param.page,
                Items = query,
                totalnum = totalnum,
                limit = param.pagesize
            };
        }

        /// <summary>
        /// 删除手动添加的记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultInfo> DeleteAddResultAsync(Guid id)
        {
            var data = await dbClient.Queryable<YB_nResultAdd>().FirstAsync(x => x.Id == id);
            if (data == null)
            {
                return new ResultInfo(ResultState.FAIL, "记录未找到");
            }

            await dbClient.Deleteable<YB_nResultAdd>().Where(x => x.Id == id).ExecuteCommandAsync();
            //删除关联的记录
            await dbClient.Deleteable<YB_nResult>().Where(x => x.Id == data.Id).ExecuteCommandAsync();
            await dbClient.Deleteable<YB_nUserResult>().Where(x => x.Id == data.Id).ExecuteCommandAsync();
            await dbClient.Deleteable<YB_nMeasureResult>().Where(x => x.Id == data.Id).ExecuteCommandAsync();
            return new ResultInfo(ResultState.SUCCESS, "删除成功");
        }
        /// <summary>
        /// 检测设备状态
        /// </summary>
        /// <param name="sn">设备机器码</param>
        /// <param name="type">类型,0-检测设备是否存在,1-不检测</param>
        /// <returns></returns>
        public async Task<ResultInfo> CheckDevStatus(string sn, int type = 0)
        {
            if (string.IsNullOrEmpty(sn))
            {
                return new ResultInfo(ResultState.FAIL, "设备编码不可为空");
            }
            var equ = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == sn);
            if (equ == null)
            {
                if (type == 1)
                {
                    return new ResultInfo(ResultState.DEVNOTFOUND, "此设备还未激活,请先激活", new
                    {
                        type = 4
                    });
                }
                return new ResultInfo(ResultState.FAIL, "此设备还未注册,请联系客服人员");
            }
            if (equ.Status == (int)DeviceStatus.UnActive)
            {
                //检查设备类型,
                var devicetype = await dbClient.Queryable<YB_DeviceType>().FirstAsync(x => x.Code == equ.Type);
                return new ResultInfo(ResultState.DEVNOTFOUND, "此设备还未激活,请先激活", new
                {
                    type = devicetype.ProType
                });
            }
            if (equ.Status == (int)DeviceStatus.Stop)
            {
                return new ResultInfo(ResultState.FAIL, "此设备暂不可使用");
            }
            return new ResultInfo(ResultState.SUCCESS, "success");
        }
        /// <summary>
        /// 获取八电极历史记录
        /// </summary>
        /// <param name="param">查询参数</param>
        /// <returns></returns>
        public async Task<PageParms<BodyMeasureHisListDto>> GetBodyHistoryListAsync(ParamQuery param)
        {
            int familyid = param.keyword.ToInt();
            if (familyid <= 0)
            {
                familyid = (await dbClient.Queryable<YB_Family>().FirstAsync(x => x.UserId == authInfo.UserId && x.IsSelf == 1)).Id;
            }
            var tempquery = dbClient.Queryable<YB_nUserResult, YB_nMeasureResult>((b, x) => new JoinQueryInfos(
                      JoinType.Left, b.Id == x.Id
                  )).Where((b, x) => b.FamilyId == familyid && b.DevType == 2);
            RefAsync<int> totalnum = 0;
            var query = await tempquery.OrderBy((b, x) => b.CreateTime, OrderByType.Desc)
                .Select((b, x) => new BodyMeasureHisList
                {
                    bmi = x.bmi,
                    body = x.body,
                    bodyage = x.bodyage,
                    bone = x.bone,
                    cmi = x.cmi,
                    time = b.CreateTime,
                    fat_r = x.fat_r,
                    fat_w = x.fat_w,
                    height = x.Height,
                    kcal = x.kcal,
                    lbm = x.lbm,
                    muscle = x.muscle,
                    muscleval = x.muscleval,
                    protein = x.protein,
                    sfr = x.sfr,
                    visceral = x.visceral,
                    water = x.water,
                    weight = x.Weight,
                    age = x.Age,
                    sfrval = x.SfrVal,
                    SkeletalMuscle = x.SkeletalMuscle,
                    muscleratetrunk = x.BodyMuscle,
                    musclerateleftleg = x.LeftFootMuscle,
                    muscleraterightleg = x.RightFootMuscle,
                    musclerateleftarm = x.LeftHandMuscle,
                    muscleraterightarm = x.RightHandMuscle,
                    musclekgtrunk = x.BodyMuscleVal,
                    musclekgleftleg = x.LeftFootMuscleVal,
                    musclekgrightleg = x.RightFootMuscleVal,
                    musclekgleftarm = x.LeftHandMuscleVal,
                    musclekgrightarm = x.RightHandMuscleVal,
                    bodyfatraterunk = x.BodyFat,
                    bodyfatrateleftleg = x.LeftFootFat,
                    bodyfatraterightleg = x.RightFootFat,
                    bodyfatrateleftarm = x.LeftHandFat,
                    bodyfatraterightarm = x.RightHandFat,
                    bodyfatkgtrunk = x.BodyFatVal,
                    bodyfatkgleftleg = x.LeftFootFatVal,
                    bodyfatkgrightleg = x.RightFootFatVal,
                    bodyfatkgleftarm = x.LeftHandFatVal,
                    bodyfatkgrightarm = x.RightHandFatVal,
                    idealweight = x.IdealWeight
                })
                .Mapper((it, cache) =>
                {
                    if (!string.IsNullOrEmpty(it.leveljson))
                    {
                        var data = it.leveljson.ToObject<MeasureLevelDto>();
                        if (data != null)
                        {
                            it.SkeletalMuscleLevel = data.SkeletalMuscleLevel;
                            it.fatLevel = data.fatLevel;
                            it.fat_rLevel = data.fat_rLevel;
                            it.muscleLevel = data.muscleLevel;
                            it.waterLevel = data.waterLevel;
                            it.boneLevel = data.boneLevel;
                            it.kcalLevel = data.kcalLevel;
                            it.fat_wLevel = data.fat_wLevel;
                            it.visceralLevel = data.visceralLevel;
                            it.proteinLevel = data.proteinLevel;
                            it.bodyageLevel = data.bodyageLevel;
                            it.bmiLevel = data.bmiLevel;
                            it.musulevalLevel = data.musulevalLevel;
                            it.proteinvalLevel = data.proteinvalLevel;
                            it.sfrLevel = data.sfrLevel;
                            it.bodylevel = data.bodylevel;
                        }
                    }
                })
                .ToPageListAsync(param.page, param.pagesize, totalnum);
            var list = query.Adapt<List<BodyMeasureHisListDto>>();
            return new PageParms<BodyMeasureHisListDto>
            {
                page = param.page,
                Items = list,
                totalnum = totalnum,
                limit = param.pagesize
            };
        }

        /// <summary>
        /// 两次测量记录对比
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ResultInfo> ResultDiff(ResultDiffC2SDto data)
        {
            var firstresult = await dbClient.Queryable<YB_nResult>()
                .Select(x => new YB_nResult
                {
                    Imp = x.Imp,
                    LeftArmImp = x.LeftArmImp,
                    LeftLegImp = x.LeftLegImp,
                    RightArmImp = x.RightArmImp,
                    RightLegImp = x.RightLegImp,
                    Weight = x.Weight
                })
                .FirstAsync(x => x.Id == data.FirstId);
            if (firstresult == null)
            {
                return new ResultInfo(ResultState.FAIL, "第一条测量记录未找到");
            }
            var secondresult = await dbClient.Queryable<YB_nResult>()
                 .Select(x => new YB_nResult
                 {
                     Imp = x.Imp,
                     LeftArmImp = x.LeftArmImp,
                     LeftLegImp = x.LeftLegImp,
                     RightArmImp = x.RightArmImp,
                     RightLegImp = x.RightLegImp,
                     Weight = x.Weight
                 })
                .FirstAsync(x => x.Id == data.SecondId);
            if (secondresult == null)
            {
                return new ResultInfo(ResultState.FAIL, "第二条测量记录未找到");
            }
            var firstres = await dbClient.Queryable<YB_nMeasureResult>()
                .Select(x => new YB_nMeasureResult
                {
                    Height = x.Height,
                    Sex = x.Sex,
                    Age = x.Age,
                    createtime = x.createtime
                })
                .FirstAsync(x => x.Id == data.FirstId);
            var secondres = await dbClient.Queryable<YB_nMeasureResult>()
               .Select(x => new YB_nMeasureResult
               {
                   Height = x.Height,
                   Sex = x.Sex,
                   Age = x.Age,
                   createtime = x.createtime
               })
               .FirstAsync(x => x.Id == data.SecondId);
            var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == data.FamilyId);
            string headimg = family.HeadImg;
            if (!string.IsNullOrEmpty(headimg))
            {
                headimg = headimg.ToLower().StartsWith("http") ? headimg : $"{APICDNURL}{headimg}";
            }
            else
            {
                var _familyService = App.GetService<IFamilyService>();
                headimg = _familyService.HeadImg(family.Sex, family.Type);
            }
            var firstdata = _bodyFatHelperService.CalcBodyFat(firstresult.Weight.ToDouble(), firstres.Height.ToDouble(), firstres.Age, firstresult.Imp.ToInt(), firstres.Sex);
            var seconddata = _bodyFatHelperService.CalcBodyFat(secondresult.Weight.ToDouble(), secondres.Height.ToDouble(), secondres.Age, secondresult.Imp.ToInt(), secondres.Sex);
            int day = (secondres.createtime.Date - firstres.createtime.Date).TotalDays.ToInt();
            ResultDiffS2CDto returndata = new ResultDiffS2CDto
            {
                Day = Math.Abs(day),
                WeightDiff = secondresult.Weight - firstresult.Weight,
                Fat_WDiff = seconddata.fat_w - firstdata.fat_w,
                FirstResult = firstdata,
                SecondResult = seconddata,
                HeadImg = headimg,
                NickName = family.Name,
                Time = $"{firstres.createtime.ToString("yyyy/MM/dd")}-{secondres.createtime.ToString("yyyy/MM/dd")}"
            };
            return new ResultInfo(ResultState.SUCCESS, "success", returndata);
        }
        /// <summary>
        /// 添加测量记录,针对八电极
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ResultInfo> InsertBodyMeasureAsync(MeasureBodySubmitC2SDto data)
        {
            //检查家庭成员是否存在
            var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == data.familyid);
            if (family == null)
            {
                return new ResultInfo(ResultState.FAIL, "家庭成员未找到");
            }
            //检查设备是否存在
            var device = await dbClient.Queryable<YB_Device>().FirstAsync(x => x.Ecode == data.ecode);
            if (device == null)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备未找到,请到管理端进行激活");
            }
            if (device.Status != (int)DeviceStatus.Run)
            {
                return new ResultInfo(ResultState.DEVNOTFOUND, "设备还未激活,请先激活");
            }
            decimal weight = AnalyWeight(data.weight);
            await InsertResultAsync(new InsertResultC2SDto
            {
                DevId = device.Id,
                SourceType = 1,
                ecode = device.Ecode,
                familyid = family.Id,
                height = data.height,
                imp = data.imp,
                IsUserTake = true,
                UserId = authInfo.UserId,
                weight = weight,
                LeftArmImp = data.LeftHandImp,
                LeftLegImp = data.LeftFootImp,
                RightArmImp = data.RightHandImp,
                RightLegImp  = data.RightFootImp
            }, device, family);
            return new ResultInfo(ResultState.SUCCESS, "测量成功");
        }
    }
}
