using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.ApiModel.PF;
using APT.BaseData.Domain.ApiModel.Platform;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Entities.BD;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.IServices.BD;
using APT.ECM.Domain.ApiModel.DD;
using APT.ECM.Domain.ApiModel.PF;
using APT.ECM.Domain.Enums.ED;
using APT.ECM.Domain.Enums.KR;
using APT.Infrastructure.Api.Redis;
using APT.Infrastructure.Core;
using APT.Infrastructure.Core.Refctor;
using APT.Utility;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace APT.PF.WebApiControllers.Api.PF
{
    /// <summary>
    /// 系统日志
    /// </summary>
    [Route("api/PF/HomePage")]
    public partial class HomePageController : AuthorizeApiController<T_PF_DATA_CHANNEL>
    {
        private const int RANK_NO_WIDTH = 30;
        private const int RANK_VAL_WIDTH = 50;
        private const int RANK_NAME_WIDTH = 100;
        /// <param name="filter">
        /// 首页显示
        /// Keyword：用户id
        /// Parameter1:表单编码
        /// </param>
        /// <returns>首页显示实体数据</returns>
        [HttpPost, Route("Show")]
        public JsonActionResult<HomePageModel> Show([FromBody] KeywordFilter filter)
        {
            return base.SafeExecute(() =>
            {
                HomePageModel homePage = new HomePageModel();
                var redisConf = GetRedisConfig(filter);

                #region 统计区域
                foreach (var item in redisConf.StatisticsData.Where(i => i.IsCheck))
                {
                    var redisKey = RedisCacheKey.HomePageStatistics + "_" + item.Code + "_" + filter.Keyword;
                    var redisData = CsRedisManager.GetClient().Get<HomePageCheckSeeting>(redisKey);
                    if (redisData != null && redisData.Time.Date == DateTime.Now.Date)
                    {
                        homePage.StatisticsData.Add(redisData.Prop);
                        continue;
                    }
                    var statistic = new StatisticsProps();
                    switch (Convert.ToInt32(item.Code))
                    {

                        case (int)HomePageStatisticsEnum.月总能耗:
                        case (int)HomePageStatisticsEnum.年总能耗:
                        case (int)HomePageStatisticsEnum.月总费用:
                        case (int)HomePageStatisticsEnum.年总费用:
                            {
                                statistic = CalTotalConsumption(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageStatisticsEnum.月用电量:
                        case (int)HomePageStatisticsEnum.年用电量:
                            {
                                statistic = CalDosage(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.月用水量:
                        case (int)HomePageStatisticsEnum.年用水量:
                            {
                                statistic = CalDosage(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.月用气量:
                        case (int)HomePageStatisticsEnum.年用气量:
                            {
                                statistic = CalDosage(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.电器具在线数:
                        case (int)HomePageStatisticsEnum.电器具不线数:
                            {
                                statistic = CalAppMonitor(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.水器具在线数:
                        case (int)HomePageStatisticsEnum.水器具不线数:
                            {
                                statistic = CalAppMonitor(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.气器具在线数:
                        case (int)HomePageStatisticsEnum.气器具不线数:
                            {
                                statistic = CalAppMonitor(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本月电数据修复:
                        case (int)HomePageStatisticsEnum.本月电数据离线:
                            {
                                statistic = CalDataQuality(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本月水数据修复:
                        case (int)HomePageStatisticsEnum.本月水数据离线:
                            {
                                statistic = CalDataQuality(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本月气数据修复:
                        case (int)HomePageStatisticsEnum.本月气数据离线:
                            {
                                statistic = CalDataQuality(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本月我审批流程:
                        case (int)HomePageStatisticsEnum.本月我发起流程:
                        case (int)HomePageStatisticsEnum.当前待审批单据:
                        case (int)HomePageStatisticsEnum.当前待我审批数:
                        case (int)HomePageStatisticsEnum.本月发起流程总数:

                            {
                                statistic = CalFlowQty(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本月报警总数:
                        case (int)HomePageStatisticsEnum.年度报警总数:
                        case (int)HomePageStatisticsEnum.未处理报警数:
                            {
                                statistic = CalAlarmLog(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageStatisticsEnum.本年摊销总量:
                        case (int)HomePageStatisticsEnum.本月摊销总量:
                        case (int)HomePageStatisticsEnum.本年摊销总价:
                        case (int)HomePageStatisticsEnum.本月摊销总价:
                        case (int)HomePageStatisticsEnum.本月核销总量:
                        case (int)HomePageStatisticsEnum.本年核销总量:
                        case (int)HomePageStatisticsEnum.本月用电摊销总量:
                        case (int)HomePageStatisticsEnum.本月用水摊销总量:
                        case (int)HomePageStatisticsEnum.本月用气摊销总量:
                            {
                                statistic = CalAmortize(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                    }
                    homePage.StatisticsData.Add(statistic);
                    SetStatisticRedis(statistic, redisKey);
                }
                #endregion

                #region 图表区域
                foreach (var item in redisConf.ChartData.Where(i => i.IsCheck))
                {
                    //redis获取，判断时间如果存在当天的Redis数据则直接返回
                    var redisKey = RedisCacheKey.HomePageCharts + "_" + item.Code + "_" + filter.Keyword;
                    var redisData = CsRedisManager.GetClient().Get<HomePageCheckSeeting>(redisKey);
                    if (redisData != null && redisData.Time.Date == DateTime.Now.Date && redisData.Prop.Data != null)
                    {
                        homePage.ChartData.Add(redisData.Prop);
                        continue;
                    }

                    var chart = new ChartProps();
                    switch (Convert.ToInt32(item.Code))
                    {
                        case (int)HomePageChartEnum.能耗统计:
                            {
                                chart = CalEnergyConStatistics(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.能源统计:
                            {
                                chart = CalEnergyStatistics(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.费用统计:
                            {
                                chart = CalPriceStatistics(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.峰谷分析:
                            {
                                chart = CalPeakValley(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.本月电数据质量统计:
                            {
                                chart = CalDataQualityChart(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageChartEnum.本月水数据质量统计:
                            {
                                chart = CalDataQualityChart(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageChartEnum.本月气数据质量统计:
                            {
                                chart = CalDataQualityChart(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageChartEnum.本月核销统计:
                            {
                                chart = CalWriteOffChart(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.本年产量统计:
                            {
                                chart = CalProStatisticalChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.年);
                                break;
                            }
                        case (int)HomePageChartEnum.本月产量统计:
                            {
                                chart = CalProStatisticalChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.月);
                                break;
                            }
                        case (int)HomePageChartEnum.本年工时单耗统计:
                            {
                                chart = CalUnitUseDataByTimeChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.年, EDConsType.时间统计);
                                break;
                            }
                        case (int)HomePageChartEnum.本年产量单耗统计:
                            {
                                chart = CalUnitUseDataByTimeChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.年, EDConsType.产量统计);
                                break;
                            }
                        case (int)HomePageChartEnum.本月工时单耗统计:
                            {
                                chart = CalUnitUseDataByTimeChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.月, EDConsType.时间统计);
                                break;
                            }
                        case (int)HomePageChartEnum.本月产量单耗统计:
                            {
                                chart = CalUnitUseDataByTimeChart(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.月, EDConsType.产量统计);
                                break;
                            }
                        case (int)HomePageChartEnum.本月峰谷平用量:
                        case (int)HomePageChartEnum.本月峰谷平费用:
                        case (int)HomePageChartEnum.本年峰谷平用量:
                        case (int)HomePageChartEnum.本年峰谷平费用:
                            {
                                chart = CalPeakValleyPie(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.本年能源分类摊销:
                            {
                                chart = CalAmortizePie(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.年);
                                break;
                            }
                        case (int)HomePageChartEnum.本月能源分类摊销:
                            {
                                chart = CalAmortizePie(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.月);
                                break;
                            }
                        case (int)HomePageChartEnum.本年能源分类数据修复:
                            {
                                chart = CalRepairPie(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.年);
                                break;
                            }
                        case (int)HomePageChartEnum.本月能源分类数据修复:
                            {
                                chart = CalRepairPie(filter, Convert.ToInt32(item.Code), FMTimeDimEnum.月);
                                break;
                            }
                        case (int)HomePageChartEnum.本年报警柱状图:
                        case (int)HomePageChartEnum.本月报警柱状图:
                            {
                                chart = CalAlarmNumChart(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageChartEnum.本年报警等级饼状图:
                        case (int)HomePageChartEnum.本月报警等级饼状图:
                            {
                                chart = CalAlarmLevelChart(filter, Convert.ToInt32(item.Code));
                                break;
                            }

                    }

                    homePage.ChartData.Add(chart);
                    SetStatisticRedis(chart, redisKey);
                }
                #endregion

                #region 排名区域
                foreach (var item in redisConf.RankingData.Where(i => i.IsCheck))
                {
                    //redis获取，判断时间如果存在当天的Redis数据则直接返回
                    var redisKey = RedisCacheKey.HomePageRankings + "_" + item.Code + "_" + filter.Keyword;
                    var redisData = CsRedisManager.GetClient().Get<HomePageCheckSeeting>(redisKey);
                    if (redisData != null && redisData.Time.Date == DateTime.Now.Date && redisData.Prop.Data != null)
                    {
                        homePage.RankingData.Add(redisData.Prop);
                        continue;
                    }

                    var ranking = new RankingProps();
                    switch (Convert.ToInt32(item.Code))
                    {

                        case (int)HomePageRankingEnum.本月能耗排名:
                            {
                                ranking = CalEnergyRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本月用电排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月用水排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月用气排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月电费排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月水费排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月气费排名:
                            {
                                ranking = CalDosageRanking(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageRankingEnum.用电摊销排名:
                            {
                                ranking = CalAmortizeRanking(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageRankingEnum.用水摊销排名:
                            {
                                ranking = CalAmortizeRanking(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageRankingEnum.用气摊销排名:
                            {
                                ranking = CalAmortizeRanking(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                        case (int)HomePageRankingEnum.核销费用排名:
                            {
                                ranking = CalWriteOffRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本月器具报警排名:
                        case (int)HomePageRankingEnum.本年器具报警排名:
                            {
                                ranking = CalAlarmRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本月报警处理时长排名:
                        case (int)HomePageRankingEnum.本年报警处理时长排名:
                            {
                                ranking = CalAlarmTimeRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本年节点KPI排名:
                        case (int)HomePageRankingEnum.本月节点KPI排名:
                        case (int)HomePageRankingEnum.本年节点KPI分值变化率排名:
                        case (int)HomePageRankingEnum.本月节点KPI分值变化率排名:
                            {
                                ranking = GetMarkItemData(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本年用能费用排名:
                        case (int)HomePageRankingEnum.本月用能费用排名:
                            {
                                ranking = CalCostRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本月器具离线数排名:
                        case (int)HomePageRankingEnum.本年器具离线数排名:
                            {
                                ranking = OffLineDataRanking(filter, Convert.ToInt32(item.Code));
                                break;
                            }
                        case (int)HomePageRankingEnum.本月电表修复数排名:
                        case (int)HomePageRankingEnum.本年电表修复数排名:
                            {
                                ranking = RepairDataRanking(filter, Convert.ToInt32(item.Code), "Electric");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月水表修复数排名:
                        case (int)HomePageRankingEnum.本年水表修复数排名:
                            {
                                ranking = RepairDataRanking(filter, Convert.ToInt32(item.Code), "Water");
                                break;
                            }
                        case (int)HomePageRankingEnum.本月气表修复数排名:
                        case (int)HomePageRankingEnum.本年气表修复数排名:
                            {
                                ranking = RepairDataRanking(filter, Convert.ToInt32(item.Code), "Gas");
                                break;
                            }
                    }

                    homePage.RankingData.Add(ranking);
                    SetStatisticRedis(ranking, redisKey);
                }
                #endregion

                #region HMI
                foreach (var item in redisConf.HmiData.Where(i => i.IsCheck))
                {
                    //redis获取，判断时间如果存在当天的Redis数据则直接返回
                    homePage.HmiData.Add(item);
                }

                #endregion

                return homePage;
            });
        }

        #region 计算统计区域

        /// <summary>
        /// 计算总能耗
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private StatisticsProps CalTotalConsumption(KeywordFilter filter, int code)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };

            var st = new DateTime();
            var et = new DateTime();
            if (code == (int)HomePageStatisticsEnum.月总能耗 || code == (int)HomePageStatisticsEnum.月总费用)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }

            var appids = this.GetEntitiesByRedis<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            List<T_BD_APPLIANCE_ATTR> appAttrs = GetApplicaceAttr(filter, appids);

            var vids = appAttrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var totalData = 0m;
            var isEnergy = code == (int)HomePageStatisticsEnum.月总能耗 || code == (int)HomePageStatisticsEnum.年总能耗;

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { isEnergy ? "CONS_DATA" : "PRICE" };
            if (isEnergy)
            {
                var monthEnergy = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME >= st && i.TIME < et && vids.Contains(i.VAR_ID), baseFilter);
                totalData = monthEnergy.Sum(i => i.CONS_DATA);
            }
            else
            {
                var monthVal = this.GetEntities<T_EM_ENERGY_VAL_MONTH>(i => i.TIME >= st && i.TIME < et && vids.Contains(i.VAR_ID), baseFilter);
                totalData = monthVal.Sum(i => i.PRICE);
            }

            statistic.Data.Val = (totalData / 10000).ToString("f3");
            statistic.Data.Unit = isEnergy ? "万tCe" : "万元";

            return statistic;
        }

        private List<T_BD_APPLIANCE_ATTR> GetApplicaceAttr(KeywordFilter filter, IEnumerable<Guid> appids)
        {
            var APP_COUNT = 20;
            List<T_BD_APPLIANCE_ATTR> appAttrs = new List<T_BD_APPLIANCE_ATTR>();
            List<T_BD_METER_APPLIANCE> meterAppliances = new List<T_BD_METER_APPLIANCE>();
            var varAttrs = this.GetEntitiesByRedis<T_BD_VARIABLE_ATTR>(null, filter);
            if (appids.Count() < APP_COUNT)
            {
                foreach (var id in appids)
                {
                    var appList = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(null, filter, id.ToString());
                    if (appList.Any())
                    {
                        appList.ForEach(x => x.Nav_VariableAttr = varAttrs.FirstOrDefault(m => m.ID == x.VAR_ATTR_ID));
                        appAttrs.AddRange(appList);
                    }

                }
            }
            else
            {
                //filter.SelectField = new string[] { "APPLIANCE_ID", "VAR_ATTR_TYPE", "VAR_ID","" };
                appAttrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(i => appids.Contains(i.APPLIANCE_ID), filter).ToList();
                appAttrs.ForEach(x => x.Nav_VariableAttr = varAttrs.FirstOrDefault(m => m.ID == x.VAR_ATTR_ID));
            }

            return appAttrs;
        }

        private StatisticsProps CalDosage(KeywordFilter filter, int code, string type)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };
            var st = new DateTime();
            var et = new DateTime();
            if (code == (int)HomePageStatisticsEnum.月用电量 || code == (int)HomePageStatisticsEnum.月用水量 || code == (int)HomePageStatisticsEnum.月用气量)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }

            var energyType = this.GetEntityByRedis<T_BD_ENERGY_TYPE>(type, filter.GetOrgId());
            if (energyType == null)
                return statistic;

            var appids = this.GetEntitiesByRedis<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null && x.ENERGY_TYPE_ID == energyType.ID, filter).Select(x => x.APPLIANCE_ID);
            //var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter);
            var attrs = GetApplicaceAttr(filter, appids);
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
            var unit = this.GetEntityByRedis<T_FM_ENUM_ITEM>(energyType.UNIT_ENUM_ITEM_ID, filter.GetOrgId());

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "DOSAFGE" }; ;

            var totalData = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME >= st && i.TIME < et && vids.Contains(i.VAR_ID), baseFilter).Sum(i => i.DOSAFGE);

            statistic.Data.Val = totalData.ToString("f1");
            statistic.Data.Unit = unit?.NAME_EN;

            return statistic;
        }

        private StatisticsProps CalAppMonitor(KeywordFilter filter, int code, string type)
        {
            var onLine = code == (int)HomePageStatisticsEnum.电器具在线数 || code == (int)HomePageStatisticsEnum.水器具在线数 ||
                         code == (int)HomePageStatisticsEnum.气器具在线数;

            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };
            var appliances = this.GetEntitiesByRedis<T_BD_APPLIANCE>(
                x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.IS_VIRTUAL == false, filter, "", "Nav_EnergyClass.Nav_EnergyType");

            var applianceAttrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点,
                filter, "", "Nav_Var", "Nav_Appliance", "Nav_VariableAttr");

            var appIds = applianceAttrs.Select(x => x.APPLIANCE_ID)?.Distinct().ToList();
            var groupApp = appliances.Where(i => i.Nav_EnergyClass.Nav_EnergyType.CODE == type);
            List<ApplianceInfoModel> appInfoList = new List<ApplianceInfoModel>();

            int OFFLINE_TIME = 30;//断线时间：30分钟
            var total = 0;
            foreach (var item in groupApp)
            {
                var applicanAttrs = applianceAttrs.FirstOrDefault(i => i.APPLIANCE_ID == item.ID);
                if (applicanAttrs != null)
                {

                    var redisValue = CsRedisManager.GetClient().HGet<HisPoint>(RedisCacheKey.RealTime, applicanAttrs?.Nav_Var?.SRC_TAG_ID.ToString());
                    if (onLine)
                    {
                        if (redisValue != null)
                        {
                            if (redisValue.HistTime.AddMinutes(OFFLINE_TIME) > DateTime.Now)
                                total++;
                        }
                    }
                    else
                    {
                        if (redisValue == null || redisValue.HistTime.AddMinutes(OFFLINE_TIME) < DateTime.Now)
                            total++;
                    }
                }

            }


            statistic.Data.Val = total.ToString();
            statistic.Data.Unit = "个";

            return statistic;
        }

        private StatisticsProps CalDataQuality(KeywordFilter filter, int code, string type)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };

            var isRepair = code == (int)HomePageStatisticsEnum.本月电数据修复 || code == (int)HomePageStatisticsEnum.本月水数据修复 ||
                           code == (int)HomePageStatisticsEnum.本月气数据修复;
            var st = new DateTime(DateTime.Now.Year,DateTime.Now.Month, 1);
            //var et = st.AddMonths(1);

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "TOTAL", "REPAIR", "OFFLINE" };
            var list = this.GetEntities<T_BD_DATA_QUALITY>(x => x.TIME >= st  && x.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE == type, baseFilter);

            var total = list.Sum(x => x.TOTAL);
            var value = isRepair ? list.Sum(x => x.REPAIR) : list.Sum(x => x.OFFLINE);

            statistic.Data.Val = total == 0 ? "0" : (value / (decimal)total * 100).ToString("F2");
            statistic.Data.Unit = "%";

            return statistic;
        }
        /// <summary>
        /// 流程统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private StatisticsProps CalFlowQty(KeywordFilter filter, int code)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };
            var dtStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            //本月我发起的
            var count = 0;
            if (code == (int)HomePageStatisticsEnum.本月我发起流程)
                count = this.GetCount<T_PF_FLOW_INSTANCE>(i => i.CreateUserId == filter.Keyword && i.CreateDate >= dtStart, filter);
            if (code == (int)HomePageStatisticsEnum.本月发起流程总数)
                count = this.GetCount<T_PF_FLOW_INSTANCE>(i => i.CreateDate >= dtStart, filter);
            else if (code == (int)HomePageStatisticsEnum.本月我审批流程)
                count = this.GetCount<T_PF_FLOW_INSTANCE>(u => u.TransitionHistorys.Any(x => x.CreateUserId == filter.Keyword && x.CreateDate >= dtStart), filter);
            else if (code == (int)HomePageStatisticsEnum.当前待审批单据)
                count = this.GetCount<T_PF_FLOW_INSTANCE>(u => u.OrderStatus == (int)PFFlowInstanceOrderStatusEnum.未完成, filter);
            else if (code == (int)HomePageStatisticsEnum.当前待我审批数)
                count = this.GetCount<T_PF_FLOW_INSTANCE>(u => u.MakerList == "1" || u.MakerList.Contains(filter.Keyword), filter);


            statistic.Data.Val = count.ToString();
            statistic.Data.Unit = "个";

            return statistic;
        }
        /// <summary>
        /// 报警统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private StatisticsProps CalAlarmLog(KeywordFilter filter, int code)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };

            var count = 0;
            if (code == (int)HomePageStatisticsEnum.本月报警总数)
            {
                var dtStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                count = this.GetCount<T_KR_ALARM_LOG>(i => i.CREATE_TIME >= dtStart, filter);
            }
            else if (code == (int)HomePageStatisticsEnum.年度报警总数)
            {
                var dtStart = new DateTime(DateTime.Now.Year, 1, 1);
                count = this.GetCount<T_KR_ALARM_LOG>(i => i.CREATE_TIME >= dtStart, filter);
            }
            else if (code == (int)HomePageStatisticsEnum.未处理报警数)
                count = this.GetCount<T_KR_ALARM_LOG>(i => !i.IS_HANDLE, filter);

            statistic.Data.Val = count.ToString();
            statistic.Data.Unit = "条";

            return statistic;
        }
        /// <summary>
        /// 摊销总量/摊销总价/核销总量 统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private StatisticsProps CalAmortize(KeywordFilter filter, int code)
        {
            var statistic = new StatisticsProps { Code = code.ToString(), Name = ((HomePageStatisticsEnum)code).ToString() };
            var st = new DateTime();
            var et = new DateTime();
            if (code == (int)HomePageStatisticsEnum.本年摊销总量 || code == (int)HomePageStatisticsEnum.本年摊销总价 || code == (int)HomePageStatisticsEnum.本年核销总量)
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            Dictionary<string, decimal> dicAmortize = new Dictionary<string, decimal>();
            if (code == (int)HomePageStatisticsEnum.本月用电摊销总量 || code == (int)HomePageStatisticsEnum.本月用水摊销总量 || code == (int)HomePageStatisticsEnum.本月用气摊销总量)
            {
                var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
                List<Guid> varIds = new List<Guid>();
                baseFilter.SelectField = new string[] { "VAR_ID", "TIME", "AMORTIZE" };
                var amortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(x => x.TIME.Date >= st.Date && x.TIME.Date <= et.Date, baseFilter);
                varIds = amortizes.Select(x => x.VAR_ID).ToList();
                // var appids = nodes.Select(x => x.APPLIANCE_ID);
                baseFilter.SelectField = new string[] { "Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE", "VAR_ID", "Nav_VariableAttr" };
                var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点 &&
                                                                            varIds.Contains(x.VAR_ID), baseFilter);//器具属性           
                baseFilter.SelectField = new string[] { "CODE" };
                var energyType = this.GetEntities<T_BD_ENERGY_TYPE>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, baseFilter);//能源类型
                List<EnergyVid> energyVids = new List<EnergyVid>();
                foreach (var attr in attrs)
                {
                    energyVids.Add(new EnergyVid() { Code = attr.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE, Vid = attr.VAR_ID });
                }
                foreach (var item in energyType)
                {
                    List<Guid> vids = new List<Guid>();
                    vids.AddRange(energyVids.Where(x => x.Code == item.CODE).Select(x => x.Vid));
                    var total = amortizes.Where(x => vids.Contains(x.VAR_ID)).Sum(x => x.AMORTIZE);
                    if (!dicAmortize.ContainsKey(item.CODE))
                    {
                        dicAmortize.Add(item.CODE, total);
                    }
                }
            }
            decimal sum = 0;
            switch (code)
            {
                case (int)HomePageStatisticsEnum.本年摊销总量:
                    {
                        filter.SelectField = new string[] { "AMORTIZE" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME.Date >= st.Date && i.TIME.Date <= et.Date, filter);
                        sum = energyAmortizes.Sum(x => x.AMORTIZE);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月摊销总量:
                    {
                        filter.SelectField = new string[] { "AMORTIZE" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME.Date == st.Date, filter);
                        sum = energyAmortizes.Sum(x => x.AMORTIZE);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本年摊销总价:
                    {
                        filter.SelectField = new string[] { "AMORTIZE_PRICE" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_VAL_MONTH>(i => i.TIME.Date >= st.Date && i.TIME.Date <= et.Date, filter);
                        sum = energyAmortizes.Sum(x => x.AMORTIZE_PRICE);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月摊销总价:
                    {
                        filter.SelectField = new string[] { "AMORTIZE_PRICE" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_VAL_MONTH>(i => i.TIME.Date == st.Date, filter);
                        sum = energyAmortizes.Sum(x => x.AMORTIZE_PRICE);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月核销总量:
                    {
                        filter.SelectField = new string[] { "WRITE_OFF" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME.Date == st.Date, filter);
                        sum = energyAmortizes.Sum(x => x.WRITE_OFF);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本年核销总量:
                    {
                        filter.SelectField = new string[] { "WRITE_OFF" };
                        var energyAmortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(i => i.TIME.Date >= st.Date && i.TIME.Date <= et.Date, filter);
                        sum = energyAmortizes.Sum(x => x.WRITE_OFF);
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月用电摊销总量:
                    {
                        sum = dicAmortize["Electric"];
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月用水摊销总量:
                    {
                        sum = dicAmortize["Water"];
                        break;
                    }
                case (int)HomePageStatisticsEnum.本月用气摊销总量:
                    {
                        sum = dicAmortize["Gas"];
                        break;
                    }
            }
            statistic.Data.Val = Math.Round(sum, 2).ToString();
            if (code == (int)HomePageStatisticsEnum.本月摊销总价 || code == (int)HomePageStatisticsEnum.本年摊销总价)
            {
                statistic.Data.Unit = "元";
            }
            else
            {
                statistic.Data.Unit = " tce";
            }
            return statistic;
        }
        #endregion

        #region 计算图表区域

        /// <summary>
        /// 能耗统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalEnergyConStatistics(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            var appids = this.GetEntitiesByRedis<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var et = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var st = et.AddYears(-1);

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "CONS_DATA", "TIME" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et, baseFilter)
                : new List<T_EM_ENERGY_DOSAGE_MONTH>();

            var data = new List<RatioTypeModel>();
            var time = st;
            while (time <= et)
            {
                var item = new RatioTypeModel { Time = time.ToString("yyyy-MM") };
                item.Current = report.Where(x => x.TIME == time).Sum(x => x.CONS_DATA).ChangeDoubleToThree();
                item.MonthErlier =
                    report.Where(x => x.TIME == time.AddMonths(-1)).Sum(x => x.CONS_DATA).ChangeDoubleToThree();
                item.YearErlier =
                    report.Where(x => x.TIME == time.AddYears(-1)).Sum(x => x.CONS_DATA).ChangeDoubleToThree();
                item.MonthRatio = item.MonthErlier == 0
                    ? 0
                    : (((item.Current - item.MonthErlier) / item.MonthErlier) * 100).ChangeDoubleToTwo();
                item.YearRatio = item.YearErlier == 0
                    ? 0
                    : (((item.Current - item.YearErlier) / item.YearErlier) * 100).ChangeDoubleToTwo();

                data.Add(item);
                time = time.AddMonths(1);
            }

            var xAxis = data.Select(x => x.Time).ToList();
            var current = new ChartDataDetailModel
            {
                Name = "本期能耗",
                Color = "rgba(84, 216, 212, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.Current }).ToList()
            };

            var yearErlierData = new ChartDataModel();
            yearErlierData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            yearErlierData.Data.Add(new ChartDataDetailModel
            {
                Name = "同比能耗",
                Color = "rgba(2, 167, 240, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.YearErlier }).ToList()
            });
            yearErlierData.Data.Add(current);
            yearErlierData.Data.Add(new ChartDataDetailModel
            {
                Name = "同比百分比",
                Color = "rgba(255, 213, 106, 1)",
                ChartType = (int)PFChartTypeEnum.line,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.YearRatio }).ToList(),
                YAxisIndex = 1
            });
            yearErlierData.YAxis.Add(new ChartDataYAxisModel { Name = "tCe" });
            yearErlierData.YAxis.Add(new ChartDataYAxisModel { Name = "%" });
            model.Data.Add(new HomeChartDataModel { Name = "同比", Data = yearErlierData });

            var monthErlierData = new ChartDataModel();
            monthErlierData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            monthErlierData.Data.Add(new ChartDataDetailModel
            {
                Name = "环比能耗",
                Color = "rgba(2, 167, 240, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.MonthErlier }).ToList()
            });
            monthErlierData.Data.Add(current);
            monthErlierData.Data.Add(new ChartDataDetailModel
            {
                Name = "环比百分比",
                Color = "rgba(255, 213, 106, 1)",
                ChartType = (int)PFChartTypeEnum.line,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.MonthRatio }).ToList(),
                YAxisIndex = 1
            });
            monthErlierData.YAxis.Add(new ChartDataYAxisModel { Name = "tCe" });
            monthErlierData.YAxis.Add(new ChartDataYAxisModel { Name = "%" });
            model.Data.Add(new HomeChartDataModel { Name = "环比", Data = monthErlierData });

            return model;
        }

        /// <summary>
        /// 能源统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalEnergyStatistics(KeywordFilter filter, int code)
        {
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            baseFilter.SelectField = new string[] { "Nav_Energytype.NUM", "Nav_Energytype.NAME",
                "Nav_Appliance.Nav_EnergyClass.ENERGY_TYPE_ID","Nav_Energytype.Nav_UnitEnumItem.NAME_EN", "Nav_Energytype.UNIT_ENUM_ITEM_ID",
                "Nav_Appliance.Nav_EnergyClass.Nav_EnergyClass" };
            var nodes = this.GetEntities<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null, baseFilter);
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");

            var et = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var st = et.AddYears(-1);

            var appids = nodes.Select(x => x.APPLIANCE_ID);
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);


            baseFilter.SelectField = new string[] { "VAR_ID", "DATA", "TIME" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et, baseFilter)
                : new List<T_EM_ENERGY_DOSAGE_MONTH>();


            var xAxis = new List<DateTime>();
            while (st <= et)
            {
                xAxis.Add(st);
                st = st.AddMonths(1);
            }

            var groups = nodes.OrderBy(x => x.Nav_Energytype.NUM).GroupBy(x => x.Nav_Appliance.Nav_EnergyClass.ENERGY_TYPE_ID);
            var colors = new List<string> { "#00ADA9", "#295AD7", "#FFA569", "#A6008B", "#EC808D", "#02A7F0", "#8592BC", "#C280FF " };

            foreach (var type in groups)
            {
                var chartData = new ChartDataModel();
                chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis.Select(x => x.ToString("yyyy-MM")).ToList() });
                chartData.YAxis.Add(new ChartDataYAxisModel
                {
                    Name = type.First().Nav_Energytype.Nav_UnitEnumItem.NAME_EN
                });

                var groups2 = type.GroupBy(x => x.Nav_Appliance.ENERGY_CLASS_ID);
                var index = 0;
                foreach (var group in groups2)
                {
                    appids = group.Select(x => x.APPLIANCE_ID);
                    vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                    var values = new List<decimal>();
                    foreach (var item in xAxis)
                    {
                        var list = report.Where(x => vids.Contains(x.VAR_ID) && x.TIME == item);
                        values.Add(list.Sum(x => x.DATA));
                    }

                    chartData.Data.Add(new ChartDataDetailModel
                    {
                        Name = group.First().Nav_Appliance.Nav_EnergyClass.NAME,
                        Color = colors[index],
                        ChartType = (int)PFChartTypeEnum.bar,
                        Stack = "总量",
                        Data = values.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToThree() }).ToList()
                    });
                    index++;
                }

                model.Data.Add(new HomeChartDataModel { Name = $"用{type.First().Nav_Energytype.NAME}", Data = chartData });
            }

            return model;
        }

        /// <summary>
        /// 费用统计
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalPriceStatistics(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            var appids = this.GetEntitiesByRedis<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var et = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var st = et.AddYears(-1);

            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_VAL_MONTH>(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et,
                    new BaseFilter(filter.OrgId))
                : new List<T_EM_ENERGY_VAL_MONTH>();

            var xAxis = new List<DateTime>();
            var values = new List<decimal>();
            var ratios = new List<decimal>();
            while (st <= et)
            {
                xAxis.Add(st);
                var current = report.Where(x => x.TIME == st).Sum(x => x.PRICE);
                var last = report.Where(x => x.TIME == st.AddYears(-1)).Sum(x => x.PRICE);
                values.Add(current);
                ratios.Add(last == 0 ? 0 : (current - last) / last * 100);

                st = st.AddMonths(1);
            }

            var chartData = new ChartDataModel();
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis.Select(x => x.ToString("yyyy-MM")).ToList() });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "万元" });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "%" });

            chartData.Data.Add(new ChartDataDetailModel
            {
                Name = "总支出",
                Color = "rgba(2, 167, 240, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = values.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToW() }).ToList()
            });
            chartData.Data.Add(new ChartDataDetailModel
            {
                Name = "同比",
                Color = "rgba(255, 213, 106, 1)",
                ChartType = (int)PFChartTypeEnum.line,
                Data = ratios.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToTwo() }).ToList(),
                YAxisIndex = 1
            });

            model.Data.Add(new HomeChartDataModel { Data = chartData });

            return model;
        }

        /// <summary>
        /// 峰谷分析
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalPeakValley(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            var nodes = this.GetEntities<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null && x.Nav_Energytype.CODE == "Electric", filter, "Nav_Energytype.Nav_UnitEnumItem");
            var appids = nodes.Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var et = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var st = et.AddYears(-1);

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "AMOUNT", "TIME", "PEAK_VALLEY_TYPE" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_VAL_MONTH>(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st && x.TIME <= et, baseFilter)
                : new List<T_EM_ENERGY_VAL_MONTH>();

            var xAxis = new List<DateTime>();
            var dic = new Dictionary<BDElectricTypeEunm, List<decimal>>();
            while (st <= et)
            {
                xAxis.Add(st);
                foreach (BDElectricTypeEunm item in Enum.GetValues(typeof(BDElectricTypeEunm)))
                {
                    if (!dic.ContainsKey(item))
                        dic.Add(item, new List<decimal>());

                    var val = report.Where(x => x.TIME == st && x.PEAK_VALLEY_TYPE == (int)item).Sum(x => x.AMOUNT);
                    dic[item].Add(val);
                }
                st = st.AddMonths(1);
            }

            var chartData = new ChartDataModel();
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis.Select(x => x.ToString("yyyy-MM")).ToList() });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "万" + nodes.FirstOrDefault()?.Nav_Energytype?.Nav_UnitEnumItem.NAME_EN });

            var colors = new List<string> { "#ffc45e", "#389e0d", "#25c4ac", "#f9517d" };
            var index = 0;
            foreach (var it in dic)
            {
                chartData.Data.Add(new ChartDataDetailModel
                {
                    Name = it.Key.ToString(),
                    Color = colors[index],
                    ChartType = (int)PFChartTypeEnum.line,
                    Data = it.Value.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToW() }).ToList()
                });
                index++;
            }
            model.Data.Add(new HomeChartDataModel { Data = chartData });

            return model;
        }

        private ChartProps CalDataQualityChart(KeywordFilter filter, int code, string type)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            var st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            //var et = st.AddMonths(1);

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "APPLIANCE_ID", "TOTAL", "REPAIR", "OFFLINE", "Nav_Appliance.NAME" };
            var list = this.GetEntities<T_BD_DATA_QUALITY>(
                x => x.TIME >= st && x.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE == type, baseFilter);

            var groups = list.GroupBy(x => new { x.APPLIANCE_ID, x.Nav_Appliance.NAME });
            var data = new List<T_BD_DATA_QUALITY>();
            foreach (var item in groups)
            {
                var it = new T_BD_DATA_QUALITY { APPLIANCE_ID = item.Key.APPLIANCE_ID, Name = item.Key.NAME };
                it.TOTAL = item.Sum(x => x.TOTAL);
                it.REPAIR = item.Sum(x => x.REPAIR);
                it.OFFLINE = item.Sum(x => x.OFFLINE);
                if (it.TOTAL != 0)
                {
                    it.RepairRatio = it.REPAIR / (decimal)it.TOTAL * 100;
                    it.OfflineRatio = it.OFFLINE / (decimal)it.TOTAL * 100;
                }
                data.Add(it);
            }
            //数据修复
            var repairData = data.OrderByDescending(x => x.REPAIR).Take(10);
            var repairChart = new ChartDataModel();
            repairChart.XAxis.Add(new ChartDataXAxisModel { Data = repairData.Select(x => x.Name).ToList() });
            repairChart.YAxis.Add(new ChartDataYAxisModel { Name = "条" });
            repairChart.YAxis.Add(new ChartDataYAxisModel { Name = "%" });

            repairChart.Data.Add(new ChartDataDetailModel
            {
                Name = "修复数量",
                Color = "rgba(84, 216, 212, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = repairData.Select(x => new ChartDataValueModel { Value = x.REPAIR }).ToList()
            });
            repairChart.Data.Add(new ChartDataDetailModel
            {
                Name = "修复比例",
                Color = "rgba(255, 213, 106, 1)",
                ChartType = (int)PFChartTypeEnum.line,
                Data = repairData.Select(x => new ChartDataValueModel { Value = (double)x.RepairRatio.ChangeDoubleToTwo() }).ToList(),
                YAxisIndex = 1
            });
            model.Data.Add(new HomeChartDataModel { Name = "数据修复", Data = repairChart });

            //数据离线
            var offLineData = data.OrderByDescending(x => x.OFFLINE).Take(10); ;
            var offLineChart = new ChartDataModel();
            offLineChart.XAxis.Add(new ChartDataXAxisModel { Data = offLineData.Select(x => x.Name).ToList() });
            offLineChart.YAxis.Add(new ChartDataYAxisModel { Name = "条" });
            offLineChart.YAxis.Add(new ChartDataYAxisModel { Name = "%" });

            offLineChart.Data.Add(new ChartDataDetailModel
            {
                Name = "离线数量",
                Color = "rgba(2, 167, 240, 1)",
                ChartType = (int)PFChartTypeEnum.bar,
                Data = offLineData.Select(x => new ChartDataValueModel { Value = x.OFFLINE }).ToList()
            });
            offLineChart.Data.Add(new ChartDataDetailModel
            {
                Name = "离线比例",
                Color = "rgba(255, 213, 106, 1)",
                ChartType = (int)PFChartTypeEnum.line,
                Data = offLineData.Select(x => new ChartDataValueModel { Value = (double)x.OfflineRatio.ChangeDoubleToTwo() }).ToList(),
                YAxisIndex = 1
            });
            model.Data.Add(new HomeChartDataModel { Name = "数据离线", Data = offLineChart });

            return model;
        }

        private ChartProps CalWriteOffChart(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };

            var list = this.GetEntities<T_EA_ENERGY_WRITE_OFF_NODE>(null, filter, "Nav_MeterNode", "Nav_WriteOffNode.Nav_MeterAppliances");
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "APPLIANCE_ID", "VAR_ID", "Nav_Appliance.Nav_EnergyClass.ENERGY_TYPE_ID" };
            var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, baseFilter, "", "Nav_VariableAttr");

            baseFilter.SelectField = new string[] { "VAR_ID", "WRITE_OFF" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var reports = this.GetEntities<T_EM_ENERGY_VAL_MONTH>(i => i.TIME == time, baseFilter);

            var dic = new Dictionary<Guid, Dictionary<string, decimal>>();
            var groups = list.GroupBy(x => (x.WRITE_OFF_NODE_ID, x.Nav_WriteOffNode.NAME));
            foreach (var item in groups)
            {
                var appids = item.First().Nav_WriteOffNode.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID);
                if (appids.Any())
                {
                    var apps = attrs.Where(x => appids.Contains(x.APPLIANCE_ID));
                    var appGroup = apps.GroupBy(x => x.Nav_Appliance.Nav_EnergyClass.ENERGY_TYPE_ID);
                    foreach (var it in appGroup)
                    {
                        var vids = it.Select(x => x.VAR_ID);
                        var val = reports.Where(x => vids.Contains(x.VAR_ID)).Sum(x => x.WRITE_OFF).ChangeDoubleToThree();

                        if (!dic.ContainsKey(it.Key))
                        {
                            dic.Add(it.Key, new Dictionary<string, decimal>());
                        }

                        if (dic[it.Key].ContainsKey(item.Key.NAME))
                            dic[it.Key][item.Key.NAME] = val;
                        else
                            dic[it.Key].Add(item.Key.NAME, val);
                    }
                }
            }

            var colors = new List<string> { "#00ADA9", "#295AD7", "#FFA569", "#A6008B", "#EC808D", "#02A7F0", "#8592BC", "#C280FF " };
            var index = 0;
            foreach (var item in dic)
            {
                var type = this.GetEntityByRedis<T_BD_ENERGY_TYPE>(item.Key, filter.GetOrgId());
                var unit = this.GetEntityByRedis<T_FM_ENUM_ITEM>(type.UNIT_ENUM_ITEM_ID, filter.GetOrgId());

                var chartData = new ChartDataModel();
                chartData.XAxis.Add(new ChartDataXAxisModel { Data = item.Value.Select(x => x.Key).ToList() });
                chartData.YAxis.Add(new ChartDataYAxisModel
                {
                    Name = unit.NAME_EN
                });
                chartData.Data.Add(new ChartDataDetailModel
                {
                    Name = "核销量",
                    Color = colors[index],
                    ChartType = (int)PFChartTypeEnum.bar,
                    Data = item.Value.Select(x => new ChartDataValueModel { Value = (double)x.Value }).ToList()
                });
                model.Data.Add(new HomeChartDataModel { Name = type.NAME, Data = chartData });
            }

            return model;
        }

        /// <summary>
        /// 本月产量统计/年
        /// </summary>
        /// <returns></returns>
        private ChartProps CalProStatisticalChart(KeywordFilter filter, int code, FMTimeDimEnum type)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = DateTime.Now;
            var et = DateTime.Now;
            var xAxis = new List<string>();
            if (FMTimeDimEnum.月 == type)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
                for (DateTime t = st; t < et; t = t.AddDays(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM-dd"));
                }
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
                for (DateTime t = st; t < et; t = t.AddMonths(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM"));
                }
            }
            filter.SelectField = new string[] { "START_TIME", "END_TIME", "QTY" };
            var report = this.GetEntities<T_ED_PROD_RECORD>(x => x.START_TIME >= st && x.START_TIME <= et, filter);
            #region chartData       
            var chartData = new ChartDataModel();
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "个" });
            var unitData = new List<ChartDataValueModel>();
            foreach (var item in xAxis)
            {
                if (FMTimeDimEnum.月 == type)
                {
                    var prods = report.Where(x => x.START_TIME.Date == Convert.ToDateTime(item).Date);
                    if (prods != null && prods.Any())
                    {
                        unitData.Add(new ChartDataValueModel { Value = (double)prods.Sum(x => x.QTY) });
                    }
                    else
                    {
                        unitData.Add(new ChartDataValueModel { Value = 0 });
                    }
                }
                else
                {
                    var prods = report.Where(x => x.START_TIME.ToString("yyyy-MM") == item);
                    if (prods != null && prods.Any())
                    {
                        unitData.Add(new ChartDataValueModel { Value = (double)prods.Sum(x => x.QTY) });
                    }
                    else
                    {
                        unitData.Add(new ChartDataValueModel { Value = 0 });
                    }
                }

            }
            chartData.Data.Add(new ChartDataDetailModel { Name = "产品产量", Data = unitData, ChartType = (int)PFChartTypeEnum.bar, Color = "rgba(53, 128, 240, 1)" });
            model.Data.Add(new HomeChartDataModel { Data = chartData });
            #endregion
            return model;
        }
        /// <summary>
        /// 按时间单耗统计
        /// </summary>
        /// <returns></returns>
        private ChartProps CalUnitUseDataByTimeChart(KeywordFilter filter, int code, FMTimeDimEnum type, EDConsType eDCons)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = DateTime.Now;
            var et = DateTime.Now;
            var xAxis = new List<string>();
            if (FMTimeDimEnum.月 == type)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
                for (DateTime t = st; t < et; t = t.AddDays(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM-dd"));
                }
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
                for (DateTime t = st; t < et; t = t.AddMonths(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM"));
                }
            }
            filter.SelectField = new string[] { "CLASS_ID", "TEAM_ID", "Nav_Class.NAME", "Nav_Team.NAME", "TIME", "WORKTIME", "CONSDATA", "QTY" };
            var report = this.GetEntities<T_EM_ENERGY_CONSDATA_DAY>(x => x.TIME.Date >= st.Date && x.TIME <= et.Date, filter);
            var classTypes = report.Where(x => x.CLASS_ID != null).Distinct(x => x.CLASS_ID);
            var teamGroups = report.Where(x => x.TEAM_ID != null).GroupBy(x => x.TEAM_ID);
            List<TeamInfo> teams = new List<TeamInfo>();
            foreach (var teamGroup in teamGroups)
            {
                teams.Add(new TeamInfo() { teamID = (Guid)teamGroup.Key, teamName = teamGroup.FirstOrDefault().Nav_Team.NAME, consData = teamGroup.Sum(x => x.CONSDATA) });
            }
            var teamTypes = teams.OrderByDescending(x => x.consData).Take(5).ToList();
            // var teamTypes = report.Where(x => x.CLASS_ID != null).Distinct(x => x.TEAM_ID);
            #region 横坐标
            var chartData = new ChartDataModel();
            var chartTeamData = new ChartDataModel();
            Dictionary<object, List<ChartDataValueModel>> dicChartDataValue = new Dictionary<object, List<ChartDataValueModel>>();
            if (FMTimeDimEnum.月 == type)
            {
                foreach (var classTyp in classTypes)
                {
                    List<ChartDataValueModel> Data = new List<ChartDataValueModel>();
                    for (var i = st; i < et; i = i.AddDays(1))
                    {
                        var reportDay = report.Where(x => x.TIME.Date == i.Date && x.CLASS_ID == classTyp.CLASS_ID);
                        if (eDCons == EDConsType.时间统计)
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.CLASS_ID == classTyp.CLASS_ID && x.WORKTIME > 0).Sum(x => x.CONSDATA / x.WORKTIME), 6) };
                            Data.Add(dataValue);
                        }
                        else
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.CLASS_ID == classTyp.CLASS_ID && x.QTY > 0).Sum(x => x.CONSDATA / (x.QTY == 0 ? 1 : x.QTY)), 6) };
                            Data.Add(dataValue);
                        }
                    }
                    if (!dicChartDataValue.ContainsKey(classTyp.CLASS_ID.ToString()))
                    {
                        dicChartDataValue.Add(classTyp.CLASS_ID.ToString(), Data);
                    }
                }
                foreach (var teamTyp in teamTypes)
                {
                    List<ChartDataValueModel> Data = new List<ChartDataValueModel>();
                    for (var i = st; i < et; i = i.AddDays(1))
                    {
                        var reportDay = report.Where(x => x.TIME.Date == i.Date && x.TEAM_ID == teamTyp.teamID);
                        if (eDCons == EDConsType.时间统计)
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.TEAM_ID == teamTyp.teamID && x.WORKTIME > 0).Sum(x => x.CONSDATA / x.WORKTIME), 6) };
                            Data.Add(dataValue);
                        }
                        else
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.TEAM_ID == teamTyp.teamID && x.QTY > 0).Sum(x => x.CONSDATA / (x.QTY == 0 ? 1 : x.QTY)), 6) };
                            Data.Add(dataValue);
                        }

                    }
                    if (!dicChartDataValue.ContainsKey(teamTyp.teamID.ToString()))
                    {
                        dicChartDataValue.Add(teamTyp.teamID.ToString(), Data);
                    }
                }
            }
            else
            {
                foreach (var classTyp in classTypes)
                {
                    List<ChartDataValueModel> Data = new List<ChartDataValueModel>();
                    for (int i = 1; i <= 12; i++)
                    {
                        var reportDay = report.Where(x => x.TIME.Month == i && x.CLASS_ID == classTyp.CLASS_ID);
                        if (eDCons == EDConsType.时间统计)
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.CLASS_ID == classTyp.CLASS_ID && x.WORKTIME > 0).Sum(x => x.CONSDATA / x.WORKTIME), 6) };
                            Data.Add(dataValue);
                        }
                        else
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.CLASS_ID == classTyp.CLASS_ID && x.QTY > 0).Sum(x => x.CONSDATA / (x.QTY == 0 ? 1 : x.QTY)), 6) };
                            Data.Add(dataValue);
                        }

                    }
                    if (!dicChartDataValue.ContainsKey(classTyp.CLASS_ID.ToString()))
                    {
                        dicChartDataValue.Add(classTyp.CLASS_ID.ToString(), Data);
                    }
                }
                foreach (var teamTyp in teamTypes)
                {
                    List<ChartDataValueModel> Data = new List<ChartDataValueModel>();
                    for (int i = 1; i <= (et - st).Days; i++)
                    {
                        var reportDay = report.Where(x => x.TIME.Date.Month == i && x.TEAM_ID == teamTyp.teamID);
                        if (eDCons == EDConsType.时间统计)
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.TEAM_ID == teamTyp.teamID && x.WORKTIME > 0).Sum(x => x.CONSDATA / x.WORKTIME), 6) };
                            Data.Add(dataValue);
                        }
                        else
                        {
                            ChartDataValueModel dataValue = new ChartDataValueModel { Value = (double)Math.Round(reportDay.Where(x => x.TEAM_ID == teamTyp.teamID && x.QTY > 0).Sum(x => x.CONSDATA / (x.QTY == 0 ? 1 : x.QTY)), 6) };
                            Data.Add(dataValue);
                        }

                    }
                    if (!dicChartDataValue.ContainsKey(teamTyp.teamID.ToString()))
                    {
                        dicChartDataValue.Add(teamTyp.teamID.ToString(), Data);
                    }
                }
            }
            foreach (var classType in classTypes)
            {
                if (classType.Nav_Class != null)
                {
                    chartData.Data.Add(new ChartDataDetailModel
                    {
                        Name = classType.Nav_Class.NAME,
                        // Color = "#f9517d",
                        ChartType = (int)PFChartTypeEnum.bar,
                        Data = dicChartDataValue[classType.CLASS_ID.ToString()]
                    });
                }
                else
                {
                    chartData.Data.Add(new ChartDataDetailModel
                    {
                        Name = "班别",
                        // Color = "#f9517d",
                        ChartType = (int)PFChartTypeEnum.bar,
                        Data = dicChartDataValue[classType.CLASS_ID.ToString()]
                    });
                }
            }
            foreach (var teamTyp in teamTypes)
            {
                chartTeamData.Data.Add(new ChartDataDetailModel
                {
                    Name = teamTyp.teamName,
                    //Color = "#f9517d",
                    ChartType = (int)PFChartTypeEnum.bar,
                    Data = dicChartDataValue[teamTyp.teamID.ToString()]
                });
            }
            #endregion         
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "" });
            chartTeamData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartTeamData.YAxis.Add(new ChartDataYAxisModel { Name = "" }); ;
            model.Data.Add(new HomeChartDataModel { Name = "班别", Data = chartData });
            model.Data.Add(new HomeChartDataModel { Name = "班组", Data = chartTeamData });
            return model;
        }

        private ChartProps CalPeakValleyPie(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var isCost = code == (int)HomePageChartEnum.本月峰谷平费用 || code == (int)HomePageChartEnum.本年峰谷平费用;

            var st = new DateTime();
            var et = new DateTime();
            if (code == (int)HomePageChartEnum.本月峰谷平用量 || code == (int)HomePageChartEnum.本月峰谷平费用)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }

            var nodes = this.GetEntities<T_BD_ENERGY_NODE>(x => x.PARENT_ID == null && x.Nav_Energytype.CODE == "Electric", filter, "Nav_Energytype.Nav_UnitEnumItem");
            var appids = nodes.Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "AMOUNT", "PRICE", "PEAK_VALLEY_TYPE" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_VAL_MONTH>(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st && x.TIME <= et, baseFilter)
                : new List<T_EM_ENERGY_VAL_MONTH>();


            var chartData = new ChartDataModel();
            var xAxis = new List<string>();
            var data = new List<decimal>();
            foreach (BDElectricTypeEunm item in Enum.GetValues(typeof(BDElectricTypeEunm)))
            {
                xAxis.Add(item.ToString());
                var total = report.Where(x => x.PEAK_VALLEY_TYPE == (int)item).Sum(x => isCost ? x.PRICE : x.AMOUNT);
                data.Add(total);
            }
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.Data.Add(new ChartDataDetailModel
            {
                Name = isCost ? "费用" : "用量",
                ChartType = (int)PFChartTypeEnum.pie,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToTwo() }).ToList()
            });

            model.Data.Add(new HomeChartDataModel { Data = chartData });

            return model;
        }
        /// <summary>
        /// 能源分类摊销饼状图
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalAmortizePie(KeywordFilter filter, int code, FMTimeDimEnum type)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = DateTime.Now;
            var et = DateTime.Now;
            if (FMTimeDimEnum.月 == type)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            List<Guid> varIds = new List<Guid>();
            baseFilter.SelectField = new string[] { "VAR_ID", "TIME", "AMORTIZE" };
            var amortizes = this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(x => x.TIME.Date >= st.Date && x.TIME.Date <= et.Date, baseFilter);
            varIds = amortizes.Select(x => x.VAR_ID).ToList();
            // var appids = nodes.Select(x => x.APPLIANCE_ID);
            baseFilter.SelectField = new string[] { "Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE", "VAR_ID", "Nav_VariableAttr" };
            var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点 &&
                                                                        varIds.Contains(x.VAR_ID), baseFilter);//器具属性           
            baseFilter.SelectField = new string[] { "CODE", "NAME", "ID" };
            var energyType = this.GetEntities<T_BD_ENERGY_TYPE>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, baseFilter);//能源类型
            List<EnergyVid> energyVids = new List<EnergyVid>();
            foreach (var attr in attrs)
            {
                energyVids.Add(new EnergyVid() { Code = attr.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE, Vid = attr.VAR_ID });
            }
            var chartData = new ChartDataModel();
            var xAxis = new List<string>();
            var data = new List<decimal>();
            foreach (var item in energyType)
            {
                List<Guid> vids = new List<Guid>();
                vids.AddRange(energyVids.Where(x => x.Code == item.CODE).Select(x => x.Vid));
                xAxis.Add(item.NAME);
                var total = amortizes.Where(x => vids.Contains(x.VAR_ID)).Sum(x => x.AMORTIZE);
                data.Add(total);
            }
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.Data.Add(new ChartDataDetailModel
            {
                Name = "能源摊销",
                ChartType = (int)PFChartTypeEnum.pie,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToTwo() }).ToList()
            });
            model.Data.Add(new HomeChartDataModel { Data = chartData });

            return model;
        }

        /// <summary>
        /// 能源分类数据修复饼状图
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalRepairPie(KeywordFilter filter, int code, FMTimeDimEnum type)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = DateTime.Now;
            //var et = DateTime.Now;
            if (FMTimeDimEnum.月 == type)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                //et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                //et = st.AddYears(1);
            }
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            List<Guid> appliances = new List<Guid>();
            baseFilter.SelectField = new string[] { "APPLIANCE_ID", "TIME", "REPAIR" };
            var dataQualitys = this.GetEntities<T_BD_DATA_QUALITY>(x => x.TIME.Date >= st.Date , baseFilter);
            appliances = dataQualitys.Select(x => x.APPLIANCE_ID).ToList();
            baseFilter.SelectField = new string[] { "Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE", "APPLIANCE_ID" };
            var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点 &&
                                                                        appliances.Contains(x.APPLIANCE_ID), baseFilter);//器具属性           
            baseFilter.SelectField = new string[] { "CODE", "NAME", "ID" };
            var energyType = this.GetEntities<T_BD_ENERGY_TYPE>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, baseFilter);//能源类型
            List<EnergyVid> energyVids = new List<EnergyVid>();
            foreach (var attr in attrs)
            {
                energyVids.Add(new EnergyVid() { Code = attr.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE, Vid = attr.APPLIANCE_ID });
            }
            var chartData = new ChartDataModel();
            var xAxis = new List<string>();
            var data = new List<decimal>();
            foreach (var item in energyType)
            {
                List<Guid> applianceIds = new List<Guid>();
                applianceIds.AddRange(energyVids.Where(x => x.Code == item.CODE).Select(x => x.Vid));
                xAxis.Add(item.NAME);
                var total = dataQualitys.Where(x => applianceIds.Contains(x.APPLIANCE_ID)).Sum(x => x.REPAIR);
                data.Add(total);
            }
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.Data.Add(new ChartDataDetailModel
            {
                Name = "数据修复",
                ChartType = (int)PFChartTypeEnum.pie,
                Data = data.Select(x => new ChartDataValueModel { Value = (double)x.ChangeDoubleToTwo() }).ToList()
            });
            model.Data.Add(new HomeChartDataModel { Data = chartData });

            return model;
        }


        /// <summary>
        /// 年、月报警柱状图
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalAlarmNumChart(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = new DateTime();
            var et = new DateTime();
            var xAxis = new List<string>();
            if (code == (int)HomePageChartEnum.本月报警柱状图)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
                for (DateTime t = st; t <= et; t = t.AddDays(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM-dd"));
                }
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
                for (DateTime t = st; t < et; t = t.AddMonths(1))
                {
                    xAxis.Add(t.ToString("yyyy-MM"));
                }
            }
            filter.SelectField = new string[] { "CREATE_TIME" };
            var report = this.GetEntities<T_KR_ALARM_LOG>(x => x.CREATE_TIME >= st, filter);
            #region chartData       
            var chartData = new ChartDataModel();
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            chartData.YAxis.Add(new ChartDataYAxisModel { Name = "个" });
            var unitData = new List<ChartDataValueModel>();
            foreach (var item in xAxis)
            {
                if (code == (int)HomePageChartEnum.本月报警柱状图)
                {
                    var prods = report.Where(x => ((DateTime)x.CREATE_TIME).Date == Convert.ToDateTime(item).Date).Count();
                    unitData.Add(new ChartDataValueModel { Value = prods });
                }
                else
                {
                    var prods = report.Where(x => ((DateTime)x.CREATE_TIME).ToString("yyyy-MM") == item).Count();
                    unitData.Add(new ChartDataValueModel { Value = prods });
                }

            }
            chartData.Data.Add(new ChartDataDetailModel { Name = "报警数量", Data = unitData, ChartType = (int)PFChartTypeEnum.bar, Color = "rgba(53, 128, 240, 1)" });
            model.Data.Add(new HomeChartDataModel { Data = chartData });
            #endregion

            return model;
        }

        /// <summary>
        /// 年、月报警等级饼状图
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private ChartProps CalAlarmLevelChart(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var st = new DateTime();
            var et = new DateTime();
            var xAxis = new List<string>();
            xAxis.AddRange(new List<string> { "高", "中", "低" });
            if (code == (int)HomePageChartEnum.本月报警等级饼状图)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }
            filter.SelectField = new string[] { "ALARM_TASK_ID", "Nav_AlarmTask.LEVEL", "CREATE_TIME" };
            var report = this.GetEntities<T_KR_ALARM_LOG>(x => x.CREATE_TIME >= st, filter);
            #region chartData       
            var chartData = new ChartDataModel();
            chartData.XAxis.Add(new ChartDataXAxisModel { Data = xAxis });
            var unitData = new List<ChartDataValueModel>();
            foreach (var item in xAxis)
            {
                var prods = report.Where(x => Enum.GetName(typeof(KRAlarmLevelEnum), x.Nav_AlarmTask.LEVEL) == item).Count();
                unitData.Add(new ChartDataValueModel { Value = prods });
            }
            chartData.Data.Add(new ChartDataDetailModel { Name = "报警等级占比", Data = unitData, ChartType = (int)PFChartTypeEnum.pie });
            model.Data.Add(new HomeChartDataModel { Data = chartData });
            #endregion

            return model;
        }


        #endregion
        public class TeamInfo
        {
            public Guid teamID { get; set; }
            public string teamName { get; set; }
            public decimal consData { get; set; }
        }
        public class EnergyVid
        {
            public string Code { get; set; }
            public Guid Vid { get; set; }
        }
        #region 计算排名区域

        /// <summary>
        /// 本月能耗排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private RankingProps CalEnergyRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };

            var nodes = this.GetEntities<T_BD_METER_NODE>(x => x.NODE_TYPE == (int)BDNodeGenreEnum.主要生产 && x.NODE_PROP <= (int)BDProcessPropEnum.工序单元, filter, "Nav_MeterAppliances", "Nav_DeductAppliances");

            var appids = new List<Guid>();
            foreach (var node in nodes)
            {
                appids.AddRange(node.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID));
                appids.AddRange(node.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID));
            }
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "CONS_DATA" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(x => vids.Contains(x.VAR_ID) && x.TIME == time, baseFilter)
                : new List<T_EM_ENERGY_DOSAGE_MONTH>();

            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "生产节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "能耗（tCe）", key = "Value", dataIndex = "Value" });

            var dic = new Dictionary<string, decimal>();
            foreach (var node in nodes)
            {
                var meter = node.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID);
                var mvid = attrs.Where(x => meter.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var deduct = node.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID);
                var dvid = attrs.Where(x => deduct.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var val = report.Where(x => mvid.Contains(x.VAR_ID)).Sum(x => x.CONS_DATA) - report.Where(x => dvid.Contains(x.VAR_ID)).Sum(x => x.CONS_DATA);
                var name = string.IsNullOrEmpty(node.NAME) ? "未知节点" : node.NAME;
                if (!dic.ContainsKey(name))
                    dic.Add(name, 0);
                dic[name] = val;
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("F2") });
                index++;
            }

            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        /// <summary>
        /// 本月用量/费用排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private RankingProps CalDosageRanking(KeywordFilter filter, int code, string type)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            var isCost = code == (int)HomePageRankingEnum.本月电费排名 || code == (int)HomePageRankingEnum.本月水费排名 ||
                         code == (int)HomePageRankingEnum.本月气费排名;

            var nodes = this.GetEntities<T_BD_METER_NODE>(
                x => x.NODE_TYPE == (int)BDNodeGenreEnum.主要生产 && x.NODE_PROP <= (int)BDProcessPropEnum.工序单元, filter,
                "Nav_MeterAppliances.Nav_Appliance.Nav_EnergyClass",
                "Nav_DeductAppliances.Nav_Appliance.Nav_EnergyClass");

            var energyType = this.GetEntityByRedis<T_BD_ENERGY_TYPE>(type, filter.GetOrgId());
            if (energyType == null)
                return model;

            var unit = this.GetEntityByRedis<T_FM_ENUM_ITEM>(energyType.UNIT_ENUM_ITEM_ID, filter.GetOrgId());
            var appids = new List<Guid>();
            foreach (var node in nodes)
            {
                appids.AddRange(node.Nav_MeterAppliances
                    .Where(x => x.Nav_Appliance?.Nav_EnergyClass?.ENERGY_TYPE_ID == energyType.ID)
                    .Select(x => x.APPLIANCE_ID));
                appids.AddRange(node.Nav_DeductAppliances
                    .Where(x => x.Nav_Appliance?.Nav_EnergyClass?.ENERGY_TYPE_ID == energyType.ID)
                    .Select(x => x.APPLIANCE_ID));
            }
            filter.SelectField = new string[] { "APPLIANCE_ID", "VAR_ID" };
            var attrs = this.GetEntities<T_BD_APPLIANCE_ATTR>(x => appids.Contains(x.APPLIANCE_ID)
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter);
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "AMOUNT", "PRICE" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_VAL_MONTH>(x => vids.Contains(x.VAR_ID) && x.TIME == time, baseFilter)
                : new List<T_EM_ENERGY_VAL_MONTH>();

            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "生产节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column
            {
                title = isCost ? $"{energyType.NAME}费（万元）" : $"用{energyType.NAME}（{unit?.NAME_EN}）",
                key = "Value",
                dataIndex = "Value",
            });

            var dic = new Dictionary<string, decimal>();
            foreach (var node in nodes)
            {
                var meter = node.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID);
                var mvid = attrs.Where(x => meter.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var deduct = node.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID);
                var dvid = attrs.Where(x => deduct.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var val = report.Where(x => mvid.Contains(x.VAR_ID)).Sum(x => isCost ? x.PRICE : x.AMOUNT) - report.Where(x => dvid.Contains(x.VAR_ID)).Sum(x => isCost ? x.PRICE : x.AMOUNT);
                var name = string.IsNullOrEmpty(node.NAME) ? "未知节点" : node.NAME;
                if (!dic.ContainsKey(name))
                    dic.Add(name, 0);
                dic[name] = isCost ? val.ChangeDoubleToW() : val;
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("F2") });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        /// <summary>
        /// 损耗摊销排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private RankingProps CalAmortizeRanking(KeywordFilter filter, int code, string type)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            var energyType = this.GetEntityByRedis<T_BD_ENERGY_TYPE>(type, filter.GetOrgId());
            if (energyType == null)
                return model;

            var unit = this.GetEntityByRedis<T_FM_ENUM_ITEM>(energyType.UNIT_ENUM_ITEM_ID, filter.GetOrgId());
            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "NAME", "APPLIANCE_ID" };
            var nodes = this.GetEntities<T_BD_ENERGY_NODE>(x => x.ENERGY_TYPE_ID == energyType.ID, baseFilter);
            var appids = nodes.Select(x => x.APPLIANCE_ID);
            filter.SelectField = null;
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            baseFilter.SelectField = new string[] { "VAR_ID", "AMORTIZE" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_DOSAGE_MONTH>(x => vids.Contains(x.VAR_ID) && x.TIME == time, baseFilter)
                : new List<T_EM_ENERGY_DOSAGE_MONTH>();

            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "表计节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = $"摊销{energyType.NAME}（{unit?.NAME_EN}）", key = "Value", dataIndex = "Value" });

            var dic = new Dictionary<string, decimal>();
            foreach (var node in nodes)
            {
                var vid = attrs.Where(x => x.APPLIANCE_ID == node.APPLIANCE_ID).Select(x => x.VAR_ID);
                var val = report.Where(x => vid.Contains(x.VAR_ID)).Sum(x => x.AMORTIZE);
                var name = string.IsNullOrEmpty(node.NAME) ? "未知节点" : node.NAME;
                if (!dic.ContainsKey(name))
                    dic.Add(name, 0);
                dic[name] = val;
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("F2") });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        private RankingProps CalWriteOffRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };

            var list = this.GetEntities<T_EA_ENERGY_WRITE_OFF_NODE>(null, filter, "Nav_MeterNode", "Nav_WriteOffNode.Nav_MeterAppliances");
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
            && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "WRITE_OFF_PRICE" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var reports = this.GetEntities<T_EM_ENERGY_VAL_MONTH>(i => i.TIME == time, baseFilter);

            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "核销节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "核销费用（万元）", key = "Value", dataIndex = "Value" });

            var groups = list.GroupBy(x => (x.WRITE_OFF_NODE_ID, x.Nav_WriteOffNode.NAME));
            var dic = new Dictionary<string, decimal>();
            foreach (var item in groups)
            {
                var appids = item.First().Nav_WriteOffNode.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID); ;
                decimal price = 0;
                if (appids.Any())
                {
                    var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                    price += reports.Where(x => vids.Contains(x.VAR_ID)).Sum(x => x.WRITE_OFF_PRICE);
                }
                var name = string.IsNullOrEmpty(item.Key.NAME) ? "未知节点" : item.Key.NAME;
                if (!dic.ContainsKey(name))
                    dic.Add(name, 0);
                dic[name] = price.ChangeDoubleToW();
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("F2") });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }
        /// <summary>
        /// 修复数量排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private RankingProps RepairDataRanking(KeywordFilter filter, int code, string type)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            filter.SelectField = new string[] { "Nav_Appliance.NAME", "REPAIR" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            if (code == (int)HomePageRankingEnum.本年电表修复数排名
                || code == (int)HomePageRankingEnum.本年水表修复数排名
                || code == (int)HomePageRankingEnum.本年气表修复数排名)
            {
                time = new DateTime(DateTime.Now.Year, 1, 1);
            }
            var logs = this.GetEntities<T_BD_DATA_QUALITY>(i => i.TIME >= time && i.Nav_Appliance.Nav_EnergyClass.Nav_EnergyType.CODE == type, filter);
            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "器具", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "次数", key = "Value", dataIndex = "Value" });

            var groups = logs.GroupBy(x => x.APPLIANCE_ID);
            var dic = new Dictionary<string, decimal>();
            foreach (var item in groups)
            {
                var def = item.FirstOrDefault();
                var name = "未知器具";
                if (!string.IsNullOrEmpty(def.Nav_Appliance?.NAME))
                    name = def.Nav_Appliance?.NAME;
                dic[def.Nav_Appliance?.NAME] = item.Sum(i => i.REPAIR);
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString() });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        /// <summary>
        /// 离线数量排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private RankingProps OffLineDataRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            filter.SelectField = new string[] { "Nav_Appliance.NAME", "OFFLINE" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            if (code == (int)HomePageRankingEnum.本年器具离线数排名)
            {
                time = new DateTime(DateTime.Now.Year, 1, 1);
            }
            var logs = this.GetEntities<T_BD_DATA_QUALITY>(i => i.TIME >= time, filter);
            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "器具", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "次数", key = "Value", dataIndex = "Value" });

            var groups = logs.GroupBy(x => x.APPLIANCE_ID);
            var dic = new Dictionary<string, decimal>();
            foreach (var item in groups)
            {
                var def = item.FirstOrDefault();
                var name = "未知器具";
                if (!string.IsNullOrEmpty(def.Nav_Appliance?.NAME))
                    name = def.Nav_Appliance?.NAME;
                dic[def.Nav_Appliance?.NAME] = item.Sum(i => i.OFFLINE);
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString() });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        private RankingProps CalAlarmRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            filter.SelectField = new string[] { "APPLIANCE_ID", "Nav_Appliance.NAME" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            if (code == (int)HomePageRankingEnum.本年器具报警排名)
            {
                time = new DateTime(DateTime.Now.Year, 1, 1);
            }
            var logs = this.GetEntities<T_KR_ALARM_LOG>(i => i.CREATE_TIME >= time && i.APPLIANCE_ID != null, filter);
            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "器具", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "报警次数", key = "Value", dataIndex = "Value" });

            var groups = logs.GroupBy(x => x.APPLIANCE_ID);
            var dic = new Dictionary<string, decimal>();
            foreach (var item in groups)
            {
                var def = item.FirstOrDefault();
                var name = "未知器具";
                if (!string.IsNullOrEmpty(def.Nav_Appliance?.NAME))
                    name = def.Nav_Appliance?.NAME;
                dic[def.Nav_Appliance?.NAME] = item.Count();
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString() });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        private RankingProps CalAlarmTimeRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            filter.SelectField = new string[] { "APPLIANCE_ID", "Nav_Appliance.NAME", "HANDLE_TIME", "IS_HANDLE", "CREATE_TIME" };
            var time = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            if (code == (int)HomePageRankingEnum.本年报警处理时长排名)
            {
                time = new DateTime(DateTime.Now.Year, 1, 1);
            }
            var logs = this.GetEntities<T_KR_ALARM_LOG>(i => i.CREATE_TIME >= time && i.IS_HANDLE && i.APPLIANCE_ID != null && i.HANDLE_TIME != null, filter);
            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "器具", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "处理时长(小时)", key = "Value", dataIndex = "Value" });

            var groups = logs.GroupBy(x => x.APPLIANCE_ID);
            var dic = new Dictionary<string, double>();
            foreach (var item in groups)
            {
                var def = item.FirstOrDefault();
                var name = "未知器具";
                if (!string.IsNullOrEmpty(def.Nav_Appliance?.NAME))
                    name = def.Nav_Appliance?.NAME;
                if (!dic.ContainsKey(name))
                    dic[def.Nav_Appliance?.NAME] = item.Average(i => (i.HANDLE_TIME - i.CREATE_TIME).Value.TotalHours);
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("f2") });
                index++;
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }

        /// <summary>
        /// 获取节点能耗KPI分值和变化率排名
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private RankingProps GetMarkItemData([FromBody] KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };
            var timeDim = 0;
            var st = new DateTime(DateTime.Now.Year, 1, 1);
            if (code == (int)HomePageRankingEnum.本月节点KPI排名 || code == (int)HomePageRankingEnum.本月节点KPI分值变化率排名)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                timeDim = 1;
            }
            var et = DateTime.Now;
            var service = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IEDEnergyConsumeService>();
            if (et > DateTime.Now)
                et = timeDim == (int)FMTimeDimEnum.年 ? DateTime.Now.ToIMonth().FromITime().AddMonths(1) : DateTime.Today;

            var xAxis = new List<string>();
            var time = st;
            while (time < et)
            {
                if (timeDim == (int)FMTimeDimEnum.年)
                {
                    xAxis.Add(time.ToString("yyyy-MM"));
                    time = time.AddMonths(1);
                }
                else
                {
                    xAxis.Add(time.ToString("yyyy-MM-dd"));
                    time = time.AddDays(1);
                }
            }
            var node = new T_BD_METER_NODE();
            var result = service.CalPlantData(filter, node, st, et, timeDim, xAxis, EDUnitSetOrder.按时间);
            var columns = new List<Column>
            {
                new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" },
                new Column { title = "节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH  }
            };
            var data = new List<HomePageTableData>();
            var dicData = new ChartDataModel();
            if (code == (int)HomePageRankingEnum.本年节点KPI排名 || code == (int)HomePageRankingEnum.本月节点KPI排名)
            {
                columns.Add(new Column { title = "KPI分值", key = "Value", dataIndex = "Value" });
                dicData = result.chartKpiModel;
            }
            else
            {
                columns.Add(new Column { title = "KPI分值变化率", key = "Value", dataIndex = "Value" });
                dicData = result.chartKpiChangeModel;

            }
            var index = 1;
            if (dicData != null && dicData.Data[0].Data.Count > 0)
            {
                foreach (var item in dicData.Data[0].Data.Take(10))
                {
                    data.Add(new HomePageTableData { Ranking = index, Name = dicData.XAxis[0].Data[index - 1], Value = item.Value.ToString() });
                    index++;
                }
            }
            model.Data = new HomePageTableModel { columns = columns, dataSource = data };
            return model;
        }

        private RankingProps CalCostRanking(KeywordFilter filter, int code)
        {
            var model = new RankingProps { Code = code.ToString(), Name = ((HomePageRankingEnum)code).ToString() };

            var nodes = this.GetEntities<T_BD_METER_NODE>(x => x.NODE_TYPE == (int)BDNodeGenreEnum.主要生产 && x.NODE_PROP <= (int)BDProcessPropEnum.工序单元, filter, "Nav_MeterAppliances", "Nav_DeductAppliances");
            var appids = new List<Guid>();
            foreach (var node in nodes)
            {
                appids.AddRange(node.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID));
                appids.AddRange(node.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID));
            }
            var attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, filter, "", "Nav_VariableAttr");
            var vids = attrs.Where(x => appids.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);

            var st = new DateTime();
            var et = new DateTime();
            if (code == (int)HomePageRankingEnum.本月用能费用排名)
            {
                st = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                et = st.AddMonths(1);
            }
            else
            {
                st = new DateTime(DateTime.Now.Year, 1, 1);
                et = st.AddYears(1);
            }

            var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
            baseFilter.SelectField = new string[] { "VAR_ID", "PRICE" };
            var report = vids.Any()
                ? this.GetEntities<T_EM_ENERGY_VAL_MONTH>(x => vids.Contains(x.VAR_ID) && x.TIME >= st && x.TIME < et, baseFilter)
                : new List<T_EM_ENERGY_VAL_MONTH>();

            var columns = new List<Column>();
            columns.Add(new Column { title = "排名", key = "Ranking", dataIndex = "Ranking" });
            columns.Add(new Column { title = "生产节点", key = "Name", dataIndex = "Name", width = RANK_NAME_WIDTH });
            columns.Add(new Column { title = "费用（万元）", key = "Value", dataIndex = "Value" });

            var dic = new Dictionary<string, decimal>();
            foreach (var node in nodes)
            {
                var meter = node.Nav_MeterAppliances.Select(x => x.APPLIANCE_ID);
                var mvid = attrs.Where(x => meter.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var deduct = node.Nav_DeductAppliances.Select(x => x.APPLIANCE_ID);
                var dvid = attrs.Where(x => deduct.Contains(x.APPLIANCE_ID)).Select(x => x.VAR_ID);
                var val = report.Where(x => mvid.Contains(x.VAR_ID)).Sum(x => x.PRICE) - report.Where(x => dvid.Contains(x.VAR_ID)).Sum(x => x.PRICE);
                var name = string.IsNullOrEmpty(node.NAME) ? "未知节点" : node.NAME;
                if (!dic.ContainsKey(name))
                    dic.Add(name, 0);
                dic[name] = val.ChangeDoubleToW();
            }

            var data = new List<HomePageTableData>();
            var index = 1;
            foreach (var item in dic.OrderByDescending(x => x.Value).Take(10))
            {
                data.Add(new HomePageTableData { Ranking = index, Name = item.Key, Value = item.Value.ToString("F2") });
                index++;
            }

            model.Data = new HomePageTableModel { columns = columns, dataSource = data };

            return model;
        }


        #endregion

        private static void SetStatisticRedis<T>(T statistic, string redisKey)
        {
            var redisStatistics = new HomePageCheckSeeting();
            redisStatistics.Time = DateTime.Now;
            redisStatistics.Prop = statistic;
            CsRedisManager.GetClient().Set(redisKey, redisStatistics);
        }

        private void CalEnergyTotal(KeywordFilter filter, BaseFilter baseFilter, List<T_BD_METER_NODE> allNodes,
            List<T_BD_APPLIANCE> allApplice, List<T_BD_ENERGY_CLASS> energyClassList, Guid typeId,
            out List<T_BD_DEDUCT_APPLIANCE> deApplicances, out List<T_BD_METER_APPLIANCE> application, out List<T_BD_APPLIANCE_ATTR> attrs)
        {
            baseFilter.SelectField = new string[] { };
            var eleApps = new List<T_BD_APPLIANCE>();
            foreach (var app in allApplice)
            {
                var energyClass = energyClassList.FirstOrDefault(i => i.ID == app.ENERGY_CLASS_ID);
                if (energyClass != null)
                {
                    app.Nav_EnergyClass = energyClass;
                    eleApps.Add(app);
                }
            }
            var appIds = eleApps.Select(i => i.ID).ToArray();
            var meterApplicances = this.GetEntitiesByRedis<T_BD_METER_APPLIANCE>(null, baseFilter);

            deApplicances = this.GetEntitiesByRedis<T_BD_DEDUCT_APPLIANCE>(null, baseFilter);
            foreach (var node in allNodes)
            {
                node.Nav_MeterAppliances = meterApplicances.Where(i => i.NODE_ID == node.ID && appIds.Contains(i.APPLIANCE_ID)).ToList();
                foreach (var appliance in node.Nav_MeterAppliances)
                {
                    appliance.Nav_Appliance = allApplice.FirstOrDefault(i => i.ID == appliance.APPLIANCE_ID);
                }
                node.Nav_DeductAppliances = deApplicances.Where(i => i.NODE_ID == node.ID && appIds.Contains(i.APPLIANCE_ID)).ToList();
                foreach (var appliance in node.Nav_DeductAppliances)
                {
                    appliance.Nav_Appliance = allApplice.FirstOrDefault(i => i.ID == appliance.APPLIANCE_ID);
                }
            }
            var meterNodeserice = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IBDMeterNodeService>();
            var nodes = meterNodeserice.GetCalMeterAllAppliance(null, typeId, filter.GetOrgId(), allNodes);
            application = nodes.SelectMany(i => i.Nav_MeterAppliances).ToList();
            var deApplication = nodes.SelectMany(i => i.Nav_DeductAppliances).ToList();
            attrs = new List<T_BD_APPLIANCE_ATTR>();
            if (application.Count > 20)
            {
                attrs = this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
                && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点,
                    baseFilter, "", "Nav_VariableAttr");
            }
            else
            {
                foreach (var app in application)
                {
                    attrs.AddRange(this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
                    && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, baseFilter, app.APPLIANCE_ID.ToString(), "Nav_Appliance", "Nav_VariableAttr").ToList());
                }
                foreach (var app in deApplication)
                {
                    attrs.AddRange(this.GetEntitiesByRedis<T_BD_APPLIANCE_ATTR>(x => x.Nav_VariableAttr != null
                    && x.Nav_VariableAttr.VAR_ATTR_TYPE == (int)BDVarAttrType.计量点, baseFilter, app.APPLIANCE_ID.ToString(), "Nav_Appliance", "Nav_VariableAttr").ToList());
                }
            }
        }

        /// <summary>
        /// 获取首页配置属性
        /// Keyword:用户id
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("GetConf")]
        public async Task<JsonActionResult<HomePageModel>> GetConf([FromBody] KeywordFilter filter)
        {
            return base.SafeExecute(() =>
            {
                return GetRedisConfig(filter);
            });
        }

        /// <summary>
        /// 获取用户Redis配置
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        private HomePageModel GetRedisConfig(KeywordFilter filter)
        {
            var fields = typeof(HomePageModel).GetProperties();
            List<dynamic> attrs = new List<dynamic>();
            var redisKey = RedisCacheKey.HomePageUserSetting
                      + "_" + filter.Keyword;
            List<string> homePageFilter = new List<string>();
            Dictionary<string, string[]> filterArray = new Dictionary<string, string[]>();
            if (!string.IsNullOrEmpty(filter.Parameter1))
            {
                redisKey += "_" + filter.Parameter1;
                var form = this.GetEntityByRedis<T_PF_FORM>(filter.Parameter1, filter.GetOrgId());
                if (form != null)
                {
                    //var pageCustom = this.GetEntityByRedis<T_PF_PAGE_CUSTOM>(form.ID, filter.GetOrgId());
                    //if (pageCustom != null && !string.IsNullOrEmpty(pageCustom.CUSTOM_PARAMS))
                    //{
                    //    filterArray = pageCustom.CUSTOM_PARAMS.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries);

                    //}
                    var statatics = this.GetEntitiesByRedis<T_PF_FORM_HOME_STATISTIC>(null, new BaseFilter(filter.GetOrgId()), form.ID.ToString()).Select(i => i.VALUE.ToString()).ToArray();
                    filterArray.Add("HomePageStatisticsEnum", statatics);

                    var charts = this.GetEntitiesByRedis<T_PF_FORM_HOME_CHART>(null, filter, form.ID.ToString()).Select(i => i.VALUE.ToString()).ToArray();
                    filterArray.Add("HomePageChartEnum", charts);

                    var rankings = this.GetEntitiesByRedis<T_PF_FORM_HOME_RANKING>(null, filter, form.ID.ToString()).Select(i => i.VALUE.ToString()).ToArray();
                    filterArray.Add("HomePageRankingEnum", rankings);

                    var hmis = this.GetEntitiesByRedis<T_PF_FORM_HOME_HMI>(null, filter, form.ID.ToString()).Select(i => i.HMI_ID.ToString()).ToArray();
                    filterArray.Add("HomePageHmiEnum", hmis);

                }

            }
            var redisConfig = CsRedisManager.GetClient().Get<HomePageModel>(redisKey);
            bool isRedis = true;
            bool isRedisUpdate = false;
            if (redisConfig == null)
            {
                redisConfig = new HomePageModel();
                redisConfig.UserId = new Guid(filter.Keyword);
                isRedis = false;
                isRedisUpdate = true;
            }
            foreach (var fi in fields)
            {

                var enumName = fi.GetAttribute<EnumNameAttribute>();
                if (enumName != null)
                {
                    var enumType = ReflectHelper.FindTypeInCurrentDomain(enumName.EnumName);
                    var enums = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
                    homePageFilter.Clear();
                    if (filterArray != null && filterArray.ContainsKey(enumName.EnumName))
                    {
                        homePageFilter = filterArray[enumName.EnumName].ToList();
                    }

                    if (isRedis)
                    {
                        var redisItems = fi.GetValue(redisConfig) as List<dynamic>;
                        if (redisItems == null)
                            redisItems = new List<dynamic>();
                        if (homePageFilter.Any())//过滤枚举
                        {
                            for (var x = redisItems.Count - 1; x >= 0; x--)
                            {
                                if (!homePageFilter.Any(i => i == Convert.ToString(redisItems[x].Code)))
                                {
                                    redisItems.RemoveAt(x);
                                    isRedisUpdate = true;
                                }

                            }
                        }
                        if (enumName.EnumName != "HomePageHmiEnum")
                        {
                            foreach (var em in enums)
                            {
                                var emVal = (Convert.ToInt32(em.GetValue(null))).ToString();
                                if (!redisItems.Any(i => i.Code == emVal) && homePageFilter.Any(i => i == emVal))
                                {
                                    dynamic propBase = new System.Dynamic.ExpandoObject();
                                    propBase.Code = emVal;
                                    propBase.Name = em.Name;
                                    propBase.IsCheck = true;
                                    redisItems.Add(propBase);
                                    isRedisUpdate = true;
                                }
                                if (redisItems.Any(i => i.Code == emVal) && !homePageFilter.Any(i => i == emVal))
                                {

                                    dynamic it = redisItems.FirstOrDefault(i => i.Code == emVal);
                                    redisItems.Remove(it);
                                    isRedisUpdate = true;

                                }
                            }
                        }
                        else
                        {
                            foreach (var hmi in homePageFilter)
                            {
                                var hmiObj = this.GetEntityByRedis<T_BD_HMI>(hmi, filter.GetOrgId());
                                if (hmiObj != null)
                                {
                                    var def = redisItems.FirstOrDefault(i => i.Code == hmiObj.ID.ToString());
                                    if (def == null)
                                    {

                                        dynamic propBase = new System.Dynamic.ExpandoObject();
                                        propBase.Code = hmiObj.ID.ToString();
                                        propBase.Name = hmiObj.NAME;
                                        propBase.IsCheck = true;
                                        redisItems.Add(propBase);
                                        isRedisUpdate = true;
                                    }
                                }
                            }

                        }

                        fi.SetValue(redisConfig, redisItems);
                    }
                    else
                    {
                        var redisItems = new List<dynamic>();
                        if (enumName.EnumName != "HomePageHmiEnum")
                        {
                            foreach (var em in enums)
                            {
                                var emVal = (Convert.ToInt32(em.GetValue(null))).ToString();

                                if (!redisItems.Any(i => i.Code == emVal) && homePageFilter.Any(i => i == emVal))
                                {

                                    dynamic propBase = new System.Dynamic.ExpandoObject();
                                    propBase.Code = emVal;
                                    propBase.Name = em.Name;
                                    propBase.IsCheck = true;
                                    redisItems.Add(propBase);
                                }
                            }

                        }
                        else
                        {
                            foreach (var hmi in homePageFilter)
                            {
                                var hmiObj = this.GetEntityByRedis<T_BD_HMI>(hmi, filter.GetOrgId());
                                if (hmiObj != null)
                                {
                                    dynamic propBase = new System.Dynamic.ExpandoObject();
                                    propBase.Code = hmiObj.ID.ToString();
                                    propBase.Name = hmiObj.NAME;
                                    propBase.IsCheck = true; ;
                                    redisItems.Add(propBase);
                                }
                            }
                        }

                        fi.SetValue(redisConfig, redisItems);

                    }


                }
                if (isRedisUpdate)
                    CsRedisManager.GetClient().Set(redisKey, redisConfig);
            }
            return redisConfig;
        }


        /// <summary>
        /// 设置首页配置属性
        /// Keyword:用户id
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("SetConf")]
        public async Task<JsonActionResult<bool>> SetConf([FromBody] HomePageModel setting)
        {
            return SafeExecute<bool>(() =>
            {
                var redisKey = RedisCacheKey.HomePageUserSetting
                          + "_" + setting.UserId;
                if (!string.IsNullOrEmpty(setting.FromCode))
                    redisKey += "_" + setting.FromCode;
                return CsRedisManager.GetClient().Set(redisKey, setting);

            });
        }


    }
}
