using DotNetCore.CAP;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Mapster;
using Nirvana.Common;
using Senparc.Weixin.Entities.TemplateMessage;
using Senparc.Weixin.Open.Containers;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using YBDevice.Body.BodyFatHelper;
using YBDevice.CommonService.DevTypeInfo;
using YBDevice.Core;
using YBDevice.Entity;

namespace YBDevice.NApi.Application.SubscriberInfo
{
    /// <summary>
    /// CAP订阅相关接口
    /// </summary>
    public class SubscriberService : ISubscriberService, ICapSubscribe, ITransient
    {
        public string component_AppId = Senparc.Weixin.Config.SenparcWeixinSetting.Component_Appid;
        private readonly ILoggerService _loggerService;
        private readonly ISqlSugarRepository<YB_nMeasureResult> repository;
        private readonly SqlSugarClient dbClient;
        private readonly IDeviceTypeService _deviceTypeService;
        private readonly IBodyFatHelperService _bodyFatHelperService;

        public SubscriberService(ISqlSugarRepository<YB_nMeasureResult> sqlSugarRepository, ILoggerService loggerService, IDeviceTypeService deviceTypeService, IBodyFatHelperService bodyFatHelperService)
        {
            _loggerService = loggerService;
            repository = sqlSugarRepository;
            dbClient = repository.Context;
            _deviceTypeService = deviceTypeService;
            _bodyFatHelperService = bodyFatHelperService;
        }

        /// <summary>
        /// 添加用户使用过的设备类型
        /// </summary>
        /// <param name="data"></param>
        [CapSubscribe("reguser.service.insertreguserdevtype")]
        public async Task InsertRegUserDevTypeAsync(RegUserDevTypeS2SDto data)
        {
            if (!await dbClient.Queryable<YB_UserEqu>().AnyAsync(x => data.DevType == x.DevType && x.UserId == data.UserId))
            {
                var insertdata = new YB_UserEqu
                {
                    Id = IDGen.NextID(),
                    CreateTime = DateTime.Now,
                    DevType = data.DevType,
                    UserId = data.UserId
                };
                await dbClient.Insertable(insertdata).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 更新粉丝数据
        /// </summary>
        /// <param name="userinfo"></param>
        /// <returns></returns>
        [CapSubscribe("fans.service.update")]
        public async Task UpdateFansData(YB_WXFans userinfo)
        {
            if (await dbClient.Queryable<YB_WXFans>().AnyAsync(x => x.FansId == userinfo.FansId))
            {
                await dbClient.Updateable<YB_WXFans>().SetColumns(x => new YB_WXFans
                {
                    HeadImgUrl = userinfo.HeadImgUrl,
                    NickName = userinfo.NickName,
                    Sex = userinfo.Sex,
                    City = userinfo.City,
                    Country = userinfo.Country,
                    Province = userinfo.Province
                }).Where(x => x.Id == userinfo.Id).ExecuteCommandAsync();
            }
            else
            {
                var fansdata = new YB_WXFans
                {
                    Id = userinfo.Id,
                    Sex = userinfo.Sex,
                    City = userinfo.City,
                    Country = userinfo.Country,
                    CreateTime = DateTime.Now,
                    FansId = userinfo.FansId,
                    FromType = 1,
                    HeadImgUrl = userinfo.HeadImgUrl,
                    Language = "",
                    NickName = userinfo.NickName,
                    OldOpenId = userinfo.OldOpenId,
                    Province = userinfo.Province
                };
                await dbClient.Insertable(fansdata).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="message"></param>
        [CapSubscribe("system.service.inserterrorlogger")]
        public void InsertErrorLogger(string message)
        {
            _loggerService.AddLogger(message, 1);
        }

        /// <summary>
        /// 更新用户身高数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.updateuserheightdata")]
        public async Task UpdateUserHeightDataAsync(UpdateUserHeightDataS2SDto data)
        {
            //更新yb_familydata
            var lastresult = await dbClient.Queryable<YB_FamilyData>().Where(x => x.FamilyId == data.familyid).FirstAsync();
            var lastheight = lastresult != null ? lastresult.LastHeight : 0;
            lastheight = lastheight == 0 ? 0 : lastheight - data.Height;
            await dbClient.Updateable<YB_FamilyData>().SetColumns(x => new YB_FamilyData
            {
                LastHeight = data.Height,
                LastTimeHeight = x.LastTimeHeight + lastheight
            }).Where(x => x.FamilyId == data.familyid).ExecuteCommandAsync();

            //更新YB_FamilyRealData
            decimal monthheight = data.LastHeight > data.Height ? data.LastHeight : data.Height;
            data.LastHeight = data.LastHeight == 0 ? 0 : data.LastHeight - data.Height;
            //设备类型列表
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(data.DevType);
            if (devtypes.Count > 0)
            {
                await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                {
                    LastHeight = data.Height,
                    LastTimeHeight = x.LastTimeHeight + data.LastHeight,
                    MonthHeight = monthheight
                }).Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();

                //更新月度成长曲线
                var time = data.LastResultHeightTime.HasValue ? data.LastResultHeightTime.Value : DateTime.Now;
                DateTime day1 = time.Date.AddDays(1 - time.Day);//本月月初
                DateTime nowtime = DateTime.Now;
                var reportdata = await dbClient.Queryable<YB_FamilyReportData>()
                    .Select(x => new YB_FamilyReportData
                    {
                        Height = x.Height
                    })
                    .FirstAsync(x => x.CreateTime == day1 && x.FamilyId == data.familyid && x.DevType == data.DevType);
                if (reportdata != null)
                {
                    //如果身高值大于所属月度值的身高值,则进行更新
                    if (reportdata.Height < data.Height)
                    {
                        await dbClient.Updateable<YB_FamilyReportData>().SetColumns(x => new YB_FamilyReportData
                        {
                            Height = data.Height
                        }).Where(x => x.CreateTime == day1 && x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                }
                //增量数据更新
                DateTime halfyeartime = nowtime.AddMonths(-6).Date;
                halfyeartime = halfyeartime.AddDays(1 - halfyeartime.Day);
                DateTime yeartime = nowtime.AddYears(-1).Date;
                yeartime = yeartime.AddDays(1 - yeartime.Day);
                //如果时间是半年前的那个月份中
                if (time >= halfyeartime.Date && time < halfyeartime.AddMonths(1).Date && data.HalfYearHeight < data.Height)
                {
                    await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                    {
                        HalfYearHeight = data.Height,
                        HalfYearHeightTime = time
                    })
                        .Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                }
                //如果时间是一年前的那个月份中
                if (time.Date >= yeartime.Date && time.Date < yeartime.AddMonths(1).Date && data.YearHeight < data.Height)
                {
                    await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                    {
                        YearHeight = data.Height,
                        YearHeightTime = time
                    })
                        .Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                }
            }
        }

        /// <summary>
        /// 更新实时数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.updaterealdata")]
        public async Task UpdateRealData(UpdateRealDataS2SDtO data)
        {
            //更新设备测量时间
            await dbClient.Updateable<YB_Device>().SetColumns(x => new YB_Device
            {
                LastHeartTime = data.CreateTime
            }).Where(x => x.Id == data.DevId).ExecuteCommandAsync();

            //设备今天是否活跃
            int activecnt = (!data.DeviceLastHeartTime.HasValue || data.DeviceLastHeartTime.Value.Date != DateTime.Now.Date) ? 1 : 0;
            //更新合计统计
            if (await dbClient.Queryable<YB_Combined>().AnyAsync())
            {
                await dbClient.Updateable<YB_Combined>().SetColumns(x => new YB_Combined
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt,
                    TodayDevCnt = x.TodayDevCnt + activecnt
                }).Where(x => x.Id == 1).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_Combined
                {
                    Id = 1,
                    BusinessCnt = 0,
                    TodayDevCnt = 1,
                    TodayIncome = 0,
                    TodayRegCnt = 0,
                    TotalDevCnt = 0,
                    TodayResultCnt = 1,
                    TotalIncome = 0,
                    TotalRegCnt = 0,
                    TotalResultCnt = 1
                }).ExecuteCommandAsync();
            }
            //更新设备统计
            if (await dbClient.Queryable<YB_EquRealData>().AnyAsync(x => x.EquId == data.DevId && x.BusinessId == data.BusinessId))
            {
                await dbClient.Updateable<YB_EquRealData>().SetColumns(x => new YB_EquRealData
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt + 1
                }).Where(x => x.EquId == data.DevId && x.BusinessId == data.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_EquRealData
                {
                    EquId = data.DevId,
                    BusinessId = data.BusinessId,
                    CreateTime = data.CreateTime,
                    TodayInCome = 0,
                    TodayRealCnt = 0,
                    TodayResultCnt = 1,
                    TotalInCome = 0,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1
                }).ExecuteCommandAsync();
            }
            //更新客户统计
            if (await dbClient.Queryable<YB_BusinessRealData>().AnyAsync(x => x.BusinessId == data.BusinessId))
            {
                await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                {
                    TodayResultCnt = x.TodayResultCnt + 1,
                    TotalResultCnt = x.TotalResultCnt + 1,
                    TodayDevCount = x.TodayDevCount + activecnt
                }).Where(x => x.BusinessId == data.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_BusinessRealData
                {
                    BusinessId = data.BusinessId,
                    CreateTime = data.CreateTime,
                    TodayRealCnt = 0,
                    TodayResultCnt = 1,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1,
                    Balance = 0,
                    BusinessCount = 0,
                    DevCount = 0,
                    TodayDevCount = 1,
                    TodayIncome = 0,
                    TotalIncome = 0,
                    TotalTxAmount = 0
                }).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 添加测量记录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("result.service.insertuserresult")]
        public async Task InsertResultData(InsertResultDataS2SDto data)
        {
            if (data.ResultId != Guid.Empty && await dbClient.Queryable<YB_nResult>().AnyAsync(x => x.Id == data.ResultId))
            {
                return;
            }
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(data.DevType);
            //添加一条测量记录
            var result = new YB_nResult
            {
                Id = data.ResultId != Guid.Empty ? data.ResultId : IDGen.NextID(),
                SourceType = data.SourceType,
                BusinessId = data.BusinessId,
                CreateTime = data.CreateTime.Value,
                DevType = data.DevType,
                EquId = data.DevId,
                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();
            //如果是八电极wifi推送的
            if (data.SourceType == 3)
            {
                //添加一条认领记录
                await dbClient.Insertable(new YB_nUserResult
                {
                    Id = result.Id,
                    CreateTime = result.CreateTime,
                    DevType = data.DevType,
                    FamilyId = 0,
                    FansId = null,
                    UserId = 0,
                    Status = 1
                }).ExecuteCommandAsync();
            }
            //如果用户认领
            if (data.IsUserTake)
            {
                //增加一条认领记录
                var fansid = await dbClient.Queryable<YB_RegUser>().Where(x => x.Id == data.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 = result.DevType,
                    Status = 1
                };
                await dbClient.Insertable(userresult).ExecuteCommandAsync();

                var family = await dbClient.Queryable<YB_Family>().FirstAsync(x => x.Id == data.familyid);
                var month = family.Birthday.ToMonth();
                //如果是八电极则调用八电极算法
                if (await dbClient.Queryable<YB_DeviceType>().AnyAsync(x => x.Code == data.DevType && x.ProType == DeviceProType.WT8))
                {
                    if (!await dbClient.Queryable<YB_nMeasureResult>().AnyAsync(x => x.Id == result.Id))
                    {
                        var calcresult = await _bodyFatHelperService.CalcBody120FatAsync(data.weight, data.height, family.Age, (GenderType)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.body,
                            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,
                            Head = data.Head,
                            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(), (GenderType)family.Sex);
                    //增加计算结果
                    var measureresult = new YB_nMeasureResult
                    {
                        Id = result.Id,
                        sfr = calcresult.sfr,
                        Sex = family.Sex,
                        SfrVal = 0,
                        SkeletalMuscle = 0,
                        Age = family.Age,
                        DevType = data.DevType,
                        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,
                        Head = data.Head
                    };
                    await dbClient.Insertable(measureresult).ExecuteCommandAsync();
                }
                //添加用户使用过的设备类型
                if (!await dbClient.Queryable<YB_UserEqu>().AnyAsync(x => data.DevType == x.DevType && x.UserId == data.UserId))
                {
                    var insertdata = new YB_UserEqu
                    {
                        Id = IDGen.NextID(),
                        CreateTime = result.CreateTime,
                        DevType = data.DevType,
                        UserId = data.UserId
                    };
                    await dbClient.Insertable(insertdata).ExecuteCommandAsync();
                }
                else
                {
                    await dbClient.Updateable<YB_UserEqu>().SetColumns(x => new YB_UserEqu
                    {
                        CreateTime = DateTime.Now
                    }).Where(x => x.DevType == data.DevType && x.UserId == data.UserId).ExecuteCommandAsync();
                }
                //记录用户最近记录信息
                if (data.SourceType != 2)
                {
                    if (await dbClient.Queryable<YB_UserLastData>().AnyAsync(x => x.UserId == data.UserId))
                    {
                        await dbClient.Updateable<YB_UserLastData>().SetColumns(x => new YB_UserLastData
                        {
                            LastResultId = result.Id,
                            LastResultTime = result.CreateTime
                        }).Where(x => x.UserId == data.UserId).ExecuteCommandAsync();
                    }
                    else
                    {
                        await dbClient.Insertable(new YB_UserLastData
                        {
                            LastResultId = result.Id,
                            LastResultTime = result.CreateTime,
                            UserId = data.UserId
                        }).ExecuteCommandAsync();
                    }
                }
            }
            //如果是手动添加的记录
            if (data.SourceType == 2)
            {
                var resultadd = new YB_nResultAdd
                {
                    CreateTime = DateTime.Now,
                    ResultTime = result.CreateTime,
                    FamilyId = data.familyid,
                    Height = result.Height,
                    Id = result.Id,
                    UserId = data.UserId,
                    Weight = result.Weight,
                    Head = data.Head
                };
                await dbClient.Insertable(resultadd).ExecuteCommandAsync();
            }
            //检查设备的最新测量时间是否大于传过来的时间
            if (!data.DeviceLastHeartTime.HasValue || data.DeviceLastHeartTime.Value < data.CreateTime.Value)
            {
                //更新设备测量时间
                await dbClient.Updateable<YB_Device>().SetColumns(x => new YB_Device
                {
                    LastHeartTime = data.CreateTime
                }).Where(x => x.Id == data.DevId).ExecuteCommandAsync();
            }

            //设备今天是否活跃
            int activecnt = (!data.DeviceLastHeartTime.HasValue || data.DeviceLastHeartTime.Value.Date != DateTime.Now.Date) ? 1 : 0;
            int todaycnt = data.CreateTime.Value.Date == DateTime.Now.Date ? 1 : 0;
            //更新合计统计
            await dbClient.Updateable<YB_Combined>().SetColumns(x => new YB_Combined
            {
                TodayResultCnt = x.TodayResultCnt + todaycnt,
                TotalResultCnt = x.TotalResultCnt + 1,
                TodayDevCnt = x.TodayDevCnt + activecnt
            }).Where(x => x.Id == 1).ExecuteCommandAsync();
            //更新设备统计
            if (await dbClient.Queryable<YB_EquRealData>().AnyAsync(x => x.EquId == data.DevId && x.BusinessId == data.BusinessId))
            {
                await dbClient.Updateable<YB_EquRealData>().SetColumns(x => new YB_EquRealData
                {
                    TodayResultCnt = x.TodayResultCnt + todaycnt,
                    TotalResultCnt = x.TotalResultCnt + 1
                }).Where(x => x.EquId == data.DevId && x.BusinessId == data.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_EquRealData
                {
                    EquId = data.DevId,
                    BusinessId = data.BusinessId,
                    CreateTime = result.CreateTime,
                    TodayInCome = 0,
                    TodayRealCnt = 0,
                    TodayResultCnt = todaycnt,
                    TotalInCome = 0,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1
                }).ExecuteCommandAsync();
            }
            //更新客户统计
            if (await dbClient.Queryable<YB_BusinessRealData>().AnyAsync(x => x.BusinessId == data.BusinessId))
            {
                await dbClient.Updateable<YB_BusinessRealData>().SetColumns(x => new YB_BusinessRealData
                {
                    TodayResultCnt = x.TodayResultCnt + todaycnt,
                    TotalResultCnt = x.TotalResultCnt + 1,
                    TodayDevCount = x.TodayDevCount + activecnt
                }).Where(x => x.BusinessId == data.BusinessId).ExecuteCommandAsync();
            }
            else
            {
                await dbClient.Insertable(new YB_BusinessRealData
                {
                    BusinessId = data.BusinessId,
                    CreateTime = result.CreateTime,
                    TodayRealCnt = 0,
                    TodayResultCnt = todaycnt,
                    TotalRealCnt = 0,
                    TotalResultCnt = 1,
                    Balance = 0,
                    BusinessCount = 0,
                    DevCount = 0,
                    TodayDevCount = 1,
                    TodayIncome = 0,
                    TotalIncome = 0,
                    TotalTxAmount = 0
                }).ExecuteCommandAsync();
            }
            if (data.SourceType == 2)
            {
                //更新月度成长曲线
                var time = data.CreateTime.Value;
                DateTime day1 = time.Date.AddDays(1 - time.Day);//本月月初
                DateTime nowtime = DateTime.Now;
                var reportdata = await dbClient.Queryable<YB_FamilyReportData>()
                    .Select(x => new YB_FamilyReportData
                    {
                        Height = x.Height,
                        Weight = x.Weight,
                        LastWeightTime = x.LastWeightTime
                    })
                    .FirstAsync(x => x.CreateTime == day1 && x.FamilyId == data.familyid && x.DevType == data.DevType);
                if (reportdata != null)
                {
                    //如果身高值大于所属月度值的身高值,则进行更新
                    if (reportdata.Height < data.height)
                    {
                        await dbClient.Updateable<YB_FamilyReportData>().SetColumns(x => new YB_FamilyReportData
                        {
                            Height = data.height
                        }).Where(x => x.CreateTime == day1 && x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                    //如果体重时间大于所属月度值的最新体重,则进行更新
                    if (reportdata.LastWeightTime.HasValue && reportdata.LastWeightTime.Value < time)
                    {
                        await dbClient.Updateable<YB_FamilyReportData>().SetColumns(x => new YB_FamilyReportData
                        {
                            Weight = data.weight,
                            LastWeightTime = time
                        }).Where(x => x.CreateTime == day1 && x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                }
                else if (time.Year != nowtime.Year || (time.Year == nowtime.Year && time.Month != nowtime.Month))
                {
                    await dbClient.Insertable(new YB_FamilyReportData
                    {
                        DevType = data.DevType,
                        CreateTime = day1,
                        FamilyId = data.familyid,
                        Height = data.height,
                        LastWeightTime = time,
                        Weight = data.weight
                    }).ExecuteCommandAsync();
                }
                //增量数据更新
                var familyrealdata = await dbClient.Queryable<YB_FamilyRealData>().FirstAsync(x => x.FamilyId == data.familyid && x.DevType == data.DevType);
                if (familyrealdata != null)
                {
                    DateTime halfyeartime = nowtime.AddMonths(-6).Date;
                    halfyeartime = halfyeartime.AddDays(1 - halfyeartime.Day);
                    DateTime yeartime = nowtime.AddYears(-1).Date;
                    yeartime = yeartime.AddDays(1 - yeartime.Day);
                    //如果时间是半年前的那个月份中
                    if (time.Date >= halfyeartime.Date && time.Date < halfyeartime.AddMonths(1).Date && familyrealdata.HalfYearHeight < data.height)
                    {
                        await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                        {
                            HalfYearHeight = data.height,
                            HalfYearHeightTime = time
                        })
                            .Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                    //如果时间是一年前的那个月份中
                    if (time.Date >= yeartime.Date && time.Date < yeartime.AddMonths(1).Date && familyrealdata.YearHeight < data.height)
                    {
                        await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
                        {
                            YearHeight = data.height,
                            YearHeightTime = time
                        })
                            .Where(x => x.FamilyId == data.familyid && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                }
            }
        }

        /// <summary>
        /// 添加通知日志
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        [CapSubscribe("system.service.insertnoticelogger")]
        public async Task InsertNoticeLoggerAsync(YB_NoticeLogger message)
        {
            if (await dbClient.Queryable<YB_NoticeLogger>().AnyAsync(x => x.Id == message.Id))
            {
                return;
            }
            var data = new YB_NoticeLogger
            {
                Ip = Net.Ip,
                CreateTime = DateTime.Now,
                FromInfo = message.FromInfo.ToStr(),
                Info = message.Info.ToStr(),
                UA = message.UA.ToStr(),
                UserInfo = message.UserInfo.ToStr(),
                Id = message.Id
            };
            await dbClient.Insertable(data).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除用户测量记录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("system.service.deleteuserresult")]
        public async Task DeleteUserDataAsync(DeleteUserDataS2SDto data)
        {
            var familydata = await dbClient.Queryable<YB_FamilyRealData>().FirstAsync(x => x.DevType == data.DevType && x.FamilyId == data.FamilyId);
            if (familydata == null)
            {
                return;
            }
            List<int> devtypes = await _deviceTypeService.GetDevTypesAsync(data.DevType);
            var topresult = await dbClient.Queryable<YB_nMeasureResult>().Where(x => SqlFunc.Subqueryable<YB_nUserResult>().Where(e => e.FamilyId == data.FamilyId && e.Status == 1 && e.Id == x.Id && devtypes.Contains(e.DevType)).Any()).OrderBy(x => x.createtime, OrderByType.Desc).Select(x => new YB_nResult
            {
                Id = x.Id,
                CreateTime = x.createtime,
                Height = x.Height,
                Weight = x.Weight
            }).FirstAsync();
            DateTime nowtime = DateTime.Now;
            //当前删除的记录值
            var CurrentResult = await dbClient.Queryable<YB_nMeasureResult>().Where(x => x.Id == data.ResultId).Select(x => new YB_nResult
            {
                Id = x.Id,
                CreateTime = x.createtime,
                Height = x.Height,
                Weight = x.Weight
            }).FirstAsync();
            //1、更新yb_familyrealdata记录为上一条,2、更新重量/身高变化,3、更新月度身高/重量,4、更新半年/一年身高数据
            //如果删除的记录等于最新记录值
            if (topresult.Id == data.ResultId)
            {
                //更新上条为最新值
                var lastresultlist = await dbClient.Queryable<YB_nMeasureResult>()
                    .Where(x => SqlFunc.Subqueryable<YB_nUserResult>().Where(e => e.FamilyId == data.FamilyId && e.Status == 1 && e.Id == x.Id && devtypes.Contains(e.DevType)).Any() && x.Id != data.ResultId)
                    .OrderBy(x => x.createtime, OrderByType.Desc)
                    .Select(x => new YB_nResult
                    {
                        Id = x.Id,
                        CreateTime = x.createtime,
                        Height = x.Height,
                        Weight = x.Weight
                    }).Take(2).ToListAsync();
                if (lastresultlist.Count > 0)
                {
                    var lastresult = lastresultlist[0];
                    var nextresult = lastresultlist.Count == 2 ? lastresultlist[1] : null;

                    familydata.LastResultId = lastresult.Id;
                    familydata.LastHeight = lastresult.Height;
                    familydata.LastResultHeightTime = lastresult.CreateTime;
                    familydata.LastResultTime = lastresult.CreateTime;
                    familydata.LastTimeHeight = nextresult == null ? 0 : nextresult.Height - lastresult.Height;
                    familydata.LastTimeWeight = nextresult == null ? 0 : nextresult.Weight - lastresult.Weight;
                    familydata.LastWeight = lastresult.Weight;

                    //检查是否修改月度值,最新记录的月份是否还在当前月,如果在则更新月度数据,否则置0
                    if (lastresult.CreateTime.Year == nowtime.Year && lastresult.CreateTime.Month == nowtime.Month)
                    {
                        familydata.MonthWeight = lastresult.Weight;
                    }
                    else
                    {
                        familydata.MonthWeight = 0;
                        familydata.MonthHeight = 0;
                    }
                }
            }
            else
            {
                var lastresultlist = await dbClient.Queryable<YB_nMeasureResult>().Where(x => SqlFunc.Subqueryable<YB_nUserResult>().Where(e => e.FamilyId == data.FamilyId && e.Status == 1 && e.Id == x.Id && devtypes.Contains(e.DevType)).Any() && x.Id != topresult.Id).OrderBy(x => x.createtime, OrderByType.Desc).Select(x => new YB_nResult
                {
                    Id = x.Id,
                    CreateTime = x.createtime,
                    Height = x.Height,
                    Weight = x.Weight
                }).Take(2).ToListAsync();
                //如果记录是上一条
                if (lastresultlist != null && lastresultlist.Count > 0)
                {
                    var lastresult = lastresultlist[0];
                    if (lastresult.Id == data.ResultId)
                    {
                        var nextresult = lastresultlist.Count == 2 ? lastresultlist[1] : null;
                        familydata.LastTimeHeight = nextresult == null ? 0 : nextresult.Height - topresult.Height;
                        familydata.LastTimeWeight = nextresult == null ? 0 : nextresult.Weight - topresult.Weight;
                    }
                }
                else
                {
                    familydata.LastTimeHeight = 0;
                    familydata.LastTimeWeight = 0;
                }
            }
            //检查是否引起月度身高变化
            if (CurrentResult.CreateTime.Year == nowtime.Year && CurrentResult.CreateTime.Month == nowtime.Month)
            {
                if (CurrentResult.Height == familydata.MonthHeight)
                {
                    DateTime monthstart = nowtime.AddDays(1 - nowtime.Day).Date;
                    familydata.MonthHeight = await dbClient.Queryable<YB_nMeasureResult>()
                        .Where(x => SqlFunc.Subqueryable<YB_nUserResult>()
                        .Where(e => e.FamilyId == data.FamilyId
                        && e.CreateTime >= monthstart
                        && e.Status == 1
                        && e.Id == x.Id
                        && devtypes.Contains(e.DevType)).Any())
                        .MaxAsync(x => x.Height);
                }
            }
            else
            {
                //不在本月的统计重新计算
                var time = CurrentResult.CreateTime.AddDays(1 - CurrentResult.CreateTime.Day).Date;
                var timend = time.AddMonths(1);
                //检查是否引起月度记录表变化
                var NewResult = await dbClient.Queryable<YB_nMeasureResult>()
                    .Where(x => SqlFunc.Subqueryable<YB_nUserResult>()
                    .Where(e => e.FamilyId == data.FamilyId
                    && e.CreateTime >= time
                    && e.CreateTime < timend
                    && e.Status == 1
                    && e.Id == x.Id
                    && devtypes.Contains(e.DevType)).Any())
                    .OrderBy(x => x.createtime, OrderByType.Desc)
                    .Select(x => new YB_nResult
                    {
                        Id = x.Id,
                        CreateTime = x.createtime,
                        Height = x.Height,
                        Weight = x.Weight
                    })
                    .FirstAsync();
                //查找本月的最大身高值和最新体重
                if (NewResult != null)
                {
                    var MonthHeight = await dbClient.Queryable<YB_nMeasureResult>()
                    .Where(x => SqlFunc.Subqueryable<YB_nUserResult>()
                    .Where(e => e.FamilyId == data.FamilyId
                    && e.CreateTime >= time
                    && e.CreateTime < timend
                    && e.Status == 1
                    && e.Id == x.Id
                    && devtypes.Contains(e.DevType)).Any())
                    .MaxAsync(x => x.Height);
                    if (await dbClient.Queryable<YB_FamilyReportData>().Where(x => x.FamilyId == data.FamilyId && x.DevType == data.DevType && x.CreateTime == time).AnyAsync())
                    {
                        await dbClient.Insertable(new YB_FamilyReportData
                        {
                            DevType = data.DevType,
                            CreateTime = time,
                            FamilyId = data.FamilyId,
                            Height = MonthHeight,
                            LastWeightTime = NewResult.CreateTime,
                            Weight = NewResult.Weight
                        }).ExecuteCommandAsync();
                    }
                    else
                    {
                        await dbClient.Updateable<YB_FamilyReportData>().SetColumns(x => new YB_FamilyReportData
                        {
                            Height = MonthHeight,
                            LastWeightTime = NewResult.CreateTime,
                            Weight = NewResult.Weight
                        }).Where(x => x.CreateTime == time && x.FamilyId == data.FamilyId && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
                    }
                }
            }
            //是否引起年度数据更新
            DateTime halfyeartime = nowtime.AddMonths(-6).Date;
            halfyeartime = halfyeartime.AddDays(1 - halfyeartime.Day);
            DateTime halfyearendtime = halfyeartime.AddMonths(1);
            DateTime yeartime = nowtime.AddYears(-1).Date;
            yeartime = yeartime.AddDays(1 - yeartime.Day);
            DateTime yearendtime = yeartime.AddMonths(1);
            if (CurrentResult.CreateTime.Year == halfyeartime.Year && CurrentResult.CreateTime.Month == halfyeartime.Month)
            {
                //找出最大值
                var MonthHeight = await dbClient.Queryable<YB_nMeasureResult>()
                   .Where(x => SqlFunc.Subqueryable<YB_nUserResult>()
                   .Where(e => e.FamilyId == data.FamilyId
                   && e.CreateTime >= halfyeartime
                   && e.CreateTime < halfyearendtime
                   && e.Status == 1
                   && e.Id == x.Id
                   && devtypes.Contains(e.DevType)).Any())
                   .OrderBy(x => x.Height, OrderByType.Desc)
                   .FirstAsync();
                familydata.HalfYearHeight = MonthHeight != null ? MonthHeight.Height : 0;
                familydata.HalfYearHeightTime = MonthHeight != null ? MonthHeight.createtime : null;
            }
            if (CurrentResult.CreateTime.Year == yeartime.Year && CurrentResult.CreateTime.Month == yeartime.Month)
            {
                //找出最大值
                var MonthHeight = await dbClient.Queryable<YB_nMeasureResult>()
                  .Where(x => SqlFunc.Subqueryable<YB_nUserResult>()
                  .Where(e => e.FamilyId == data.FamilyId
                  && e.CreateTime >= yeartime
                  && e.CreateTime < yearendtime
                  && e.Status == 1
                  && e.Id == x.Id
                  && devtypes.Contains(e.DevType)).Any())
                  .OrderBy(x => x.Height, OrderByType.Desc)
                  .FirstAsync();
                familydata.YearHeight = MonthHeight != null ? MonthHeight.Height : 0;
                familydata.YearHeightTime = MonthHeight != null ? MonthHeight.createtime : null;
            }
            //更新统计数据
            await dbClient.Updateable<YB_FamilyRealData>().SetColumns(x => new YB_FamilyRealData
            {
                LastHeight = familydata.LastHeight,
                LastResultHeightTime = familydata.LastResultHeightTime,
                LastResultId = familydata.LastResultId,
                LastResultTime = familydata.LastResultTime,
                LastTimeHeight = familydata.LastTimeHeight,
                LastTimeWeight = familydata.LastWeight,
                LastWeight = familydata.LastWeight,
                HalfYearHeight = familydata.HalfYearHeight,
                HalfYearHeightTime = familydata.HalfYearHeightTime,
                MonthHeight = familydata.MonthHeight,
                MonthWeight = familydata.MonthWeight,
                YearHeight = familydata.YearHeight,
                YearHeightTime = familydata.YearHeightTime
            }).Where(x => x.FamilyId == data.FamilyId && devtypes.Contains(x.DevType)).ExecuteCommandAsync();
            //更新记录
            await dbClient.Updateable<YB_nUserResult>()
              .SetColumns(x => new YB_nUserResult
              {
                  Status = 0
              })
              .Where(x => x.Id == data.ResultId).ExecuteCommandAsync();
        }

        /// <summary>
        /// 邮件发送
        /// </summary>
        /// <returns></returns>
        public Task SendEmailAsync(SendEmailS2SDto data)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 订阅消息发送
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [CapSubscribe("system.service.sendsubscribemessage")]
        public async Task SendSubscribeMessageAsync(SendSubscribeMessageS2SDto data)
        {
            string token = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, data.AppId);
            //解析模板参数
            var tpl = await dbClient.Queryable<YB_MiniProgramSubscribeMessageTpl>().FirstAsync(x => x.PriTmplId == data.TplId);
            if (tpl == null)
            {
                return;
            }
            var keywords = tpl.KeyWords.Split('|');
            var examples = tpl.Example.Split('|');
            var senddata = new Dictionary<string, TemplateMessageDataValue>();
            for (var i = 0; i < keywords.Length; i++)
            {
                string val = GetSubscribeValue(examples[i]);
                senddata.Add(keywords[i], new TemplateMessageDataValue(val));
            }
            string page = "pages/index/index";
            var tpldata = new TemplateMessageData(senddata);
            var result = await Senparc.Weixin.WxOpen.AdvancedAPIs.MessageApi.SendSubscribeAsync(token, data.OpenId, data.TplId, tpldata, page);
            if (result.errcode != 0)
            {
                InsertErrorLogger($"订阅消息发送失败,失败原因:{result.errmsg},参数:{data.ToJson()}");
            }
            //删除此条消息
            await dbClient.Deleteable<YB_UserSubscribeMessage>().Where(x => x.Id == data.Id).ExecuteCommandAsync();
        }

        /// <summary>
        /// 解析关键字特殊值
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public string GetSubscribeValue(string val)
            => (val.ToUpper()) switch
            {
                SubscribeKeyWordConst.Date => $"{DateTime.Now.ToString("yyyy/MM/dd")}",
                SubscribeKeyWordConst.DateTime => $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}",
                _ => val
            };

        /// <summary>
        /// 添加审计日志
        /// </summary>
        /// <returns></returns>
        [CapSubscribe("system.service.insertauditlogger")]
        public async Task InsertAuditLogger(AduitLogS2SDto data)
        {
            var audit = data.Adapt<YB_AuditLogger>();
            audit.Id = IDGen.NextID();
            audit.CreatTime = DateTime.Now;
            await dbClient.Insertable(audit).ExecuteCommandAsync();
        }
    }
}