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
{
    /// 
    /// 系统日志
    /// 
    [Route("api/PF/HomePage")]
    public partial class HomePageController : AuthorizeApiController
    {
        private const int RANK_NO_WIDTH = 30;
        private const int RANK_VAL_WIDTH = 50;
        private const int RANK_NAME_WIDTH = 100;
        /// 
        /// 首页显示
        /// Keyword:用户id
        /// Parameter1:表单编码
        /// 
        /// 首页显示实体数据
        [HttpPost, Route("Show")]
        public JsonActionResult 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(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(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(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 计算统计区域
        /// 
        /// 计算总能耗
        /// 
        /// 
        /// 
        /// 
        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(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            List 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(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(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 GetApplicaceAttr(KeywordFilter filter, IEnumerable appids)
        {
            var APP_COUNT = 20;
            List appAttrs = new List();
            List meterAppliances = new List();
            var varAttrs = this.GetEntitiesByRedis(null, filter);
            if (appids.Count() < APP_COUNT)
            {
                foreach (var id in appids)
                {
                    var appList = this.GetEntitiesByRedis(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(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(type, filter.GetOrgId());
            if (energyType == null)
                return statistic;
            var appids = this.GetEntitiesByRedis(x => x.PARENT_ID == null && x.ENERGY_TYPE_ID == energyType.ID, filter).Select(x => x.APPLIANCE_ID);
            //var attrs = this.GetEntitiesByRedis(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(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(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(
                x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.IS_VIRTUAL == false, filter, "", "Nav_EnergyClass.Nav_EnergyType");
            var applianceAttrs = this.GetEntitiesByRedis(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 appInfoList = new List();
            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(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(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;
        }
        /// 
        /// 流程统计
        /// 
        /// 
        /// 
        /// 
        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(i => i.CreateUserId == filter.Keyword && i.CreateDate >= dtStart, filter);
            if (code == (int)HomePageStatisticsEnum.本月发起流程总数)
                count = this.GetCount(i => i.CreateDate >= dtStart, filter);
            else if (code == (int)HomePageStatisticsEnum.本月我审批流程)
                count = this.GetCount(u => u.TransitionHistorys.Any(x => x.CreateUserId == filter.Keyword && x.CreateDate >= dtStart), filter);
            else if (code == (int)HomePageStatisticsEnum.当前待审批单据)
                count = this.GetCount(u => u.OrderStatus == (int)PFFlowInstanceOrderStatusEnum.未完成, filter);
            else if (code == (int)HomePageStatisticsEnum.当前待我审批数)
                count = this.GetCount(u => u.MakerList == "1" || u.MakerList.Contains(filter.Keyword), filter);
            statistic.Data.Val = count.ToString();
            statistic.Data.Unit = "个";
            return statistic;
        }
        /// 
        /// 报警统计
        /// 
        /// 
        /// 
        /// 
        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(i => i.CREATE_TIME >= dtStart, filter);
            }
            else if (code == (int)HomePageStatisticsEnum.年度报警总数)
            {
                var dtStart = new DateTime(DateTime.Now.Year, 1, 1);
                count = this.GetCount(i => i.CREATE_TIME >= dtStart, filter);
            }
            else if (code == (int)HomePageStatisticsEnum.未处理报警数)
                count = this.GetCount(i => !i.IS_HANDLE, filter);
            statistic.Data.Val = count.ToString();
            statistic.Data.Unit = "条";
            return statistic;
        }
        /// 
        /// 摊销总量/摊销总价/核销总量 统计
        /// 
        /// 
        /// 
        /// 
        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 dicAmortize = new Dictionary();
            if (code == (int)HomePageStatisticsEnum.本月用电摊销总量 || code == (int)HomePageStatisticsEnum.本月用水摊销总量 || code == (int)HomePageStatisticsEnum.本月用气摊销总量)
            {
                var baseFilter = new BaseFilter(filter.GetOrgId()) { DataRule = filter.DataRule };
                List varIds = new List();
                baseFilter.SelectField = new string[] { "VAR_ID", "TIME", "AMORTIZE" };
                var amortizes = this.GetEntities(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(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(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, baseFilter);//能源类型
                List energyVids = new List();
                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 vids = new List();
                    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(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(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(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(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(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(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 计算图表区域
        /// 
        /// 能耗统计
        /// 
        /// 
        /// 
        /// 
        private ChartProps CalEnergyConStatistics(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var appids = this.GetEntitiesByRedis(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis(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(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et, baseFilter)
                : new List();
            var data = new List();
            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;
        }
        /// 
        /// 能源统计
        /// 
        /// 
        /// 
        /// 
        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(x => x.PARENT_ID == null, baseFilter);
            var attrs = this.GetEntitiesByRedis(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(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et, baseFilter)
                : new List();
            var xAxis = new List();
            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 { "#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();
                    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;
        }
        /// 
        /// 费用统计
        /// 
        /// 
        /// 
        /// 
        private ChartProps CalPriceStatistics(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var appids = this.GetEntitiesByRedis(x => x.PARENT_ID == null, filter).Select(x => x.APPLIANCE_ID);
            var attrs = this.GetEntitiesByRedis(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(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st.AddYears(-1) && x.TIME <= et,
                    new BaseFilter(filter.OrgId))
                : new List();
            var xAxis = new List();
            var values = new List();
            var ratios = new List();
            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;
        }
        /// 
        /// 峰谷分析
        /// 
        /// 
        /// 
        /// 
        private ChartProps CalPeakValley(KeywordFilter filter, int code)
        {
            var model = new ChartProps { Code = code.ToString(), Name = ((HomePageChartEnum)code).ToString() };
            var nodes = this.GetEntities(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(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(
                    x => vids.Contains(x.VAR_ID) && x.TIME >= st && x.TIME <= et, baseFilter)
                : new List();
            var xAxis = new List();
            var dic = new Dictionary>();
            while (st <= et)
            {
                xAxis.Add(st);
                foreach (BDElectricTypeEunm item in Enum.GetValues(typeof(BDElectricTypeEunm)))
                {
                    if (!dic.ContainsKey(item))
                        dic.Add(item, new List());
                    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 { "#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(
                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();
            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(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(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(i => i.TIME == time, baseFilter);
            var dic = new Dictionary>();
            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());
                        }
                        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 { "#00ADA9", "#295AD7", "#FFA569", "#A6008B", "#EC808D", "#02A7F0", "#8592BC", "#C280FF " };
            var index = 0;
            foreach (var item in dic)
            {
                var type = this.GetEntityByRedis(item.Key, filter.GetOrgId());
                var unit = this.GetEntityByRedis(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;
        }
        /// 
        /// 本月产量统计/年
        /// 
        /// 
        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();
            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(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();
            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;
        }
        /// 
        /// 按时间单耗统计
        /// 
        /// 
        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();
            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(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 teams = new List();
            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