using Microsoft.AspNetCore.Mvc;
using Siger.ApiTPM.Result;
using Siger.ApiTPM.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Repository.Data.Tpm;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Request;
using Siger.Middlelayer.TpmRepository.Response;
using Siger.Middlelayer.Utility.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Siger.ApiTPM.Controllers
{
    /// <summary>
    /// Tpm统计分析
    /// </summary>
    public class StatisticsController : BaseController
    {
        private readonly IRepairRepository _repairRepository;
        private readonly ISparepartRepository _sparepartRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectMachineTypeRepository _machineTypeRepository;
        private readonly ISigerProjectLevelSectionMachineRepository _levelSectionRepository;
        private readonly IPlanRecordRepository _planRecordRepository;
        private readonly IPlanSignRepository _planSignRepository;
        private readonly IFaultTypeRepository _faultTypeRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly IRepairListRepository _repairListRepository;
        private readonly ISigerProjectLevelSectionRepository _projectLevelSectionRepository;
        private readonly ISigerProjectUserGroupRepository _userGroupRepository;
        private readonly ISigerProjectSectionRepository _projectSectionRepository;
        private readonly ISigerAndonExpectionTypeRepository _expectionTypeRepository;

        /// <inheritdoc />
        public StatisticsController(IRepairRepository repairRepository, ISparepartRepository sparepartRepository,
            ISigerProjectMachineRepository machineRepository, ISigerProjectLevelSectionMachineRepository levelSectionRepository,
            ISigerProjectMachineTypeRepository machineTypeRepository, IPlanRecordRepository planRecordRepository,
            IPlanSignRepository planSignRepository, IFaultTypeRepository faultTypeRepository, ISigerProjectMachineAttributionRepository machineAttributionRepository,
            ISigerProjectUserRepository userRepository, IRepairListRepository repairListRepository, ISigerProjectLevelSectionRepository projectLevelSectionRepository
            , ISigerProjectUserGroupRepository userGroupRepository, ISigerProjectSectionRepository projectSectionRepository, ISigerAndonExpectionTypeRepository expectionTypeRepository)
        {
            _repairRepository = repairRepository;
            _sparepartRepository = sparepartRepository;
            _machineRepository = machineRepository;
            _levelSectionRepository = levelSectionRepository;
            _machineTypeRepository = machineTypeRepository;
            _planRecordRepository = planRecordRepository;
            _planSignRepository = planSignRepository;
            _faultTypeRepository = faultTypeRepository;
            _machineAttributionRepository = machineAttributionRepository;
            _userRepository = userRepository;
            _repairListRepository = repairListRepository;
            _projectLevelSectionRepository = projectLevelSectionRepository;
            _userGroupRepository = userGroupRepository;
            _projectSectionRepository = projectSectionRepository;
            _expectionTypeRepository = expectionTypeRepository;
        }

        /// <summary>
        /// 综合统计
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> FaultFrequencyAnalysis([FromBody]RequestFaultFrequencyAnalysis request)
        {
            var sectionList = request.sectionId.Split(',');

            //if (request.machineidarr == null || !request.machineidarr.Any())
            //{
            //    throw new BadRequestException(RequestEnum.MachineNotFound);
            //}

            var machineIds = new List<int>();
            foreach(var section in sectionList)
            {
                var mids = _machineRepository.GetLevelSectionMachineIds(section.ToInt(), ProjectId).ToList();
                machineIds.AddRange(mids);
            }
            if (string.IsNullOrWhiteSpace(request.starttime) || string.IsNullOrWhiteSpace(request.endtime))
            {
                throw new ServerException(200099);
            }

            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var machineType = request.machinetype.ToInt();
            if (machineType > 0)
            {
                var machineTypes = _machineTypeRepository.GetSonMachineTypes(machineType, ProjectId).Select(s => s.id).ToList();
                machineTypes.Add(machineType);
                if (machineTypes.Any())
                {
                    var machineIDs = _machineRepository.GetList(t => machineTypes.Contains(t.typeid) && t.projectid == ProjectId &&
                        t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    machineIds = machineIds.Where(t => machineIDs.Contains(t)).ToList();
                }
            }

            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);

            var queryable = _repairRepository.GetList(q => q.createtime >= unixStartTime && q.createtime <= unixEndTime && q.projectid == ProjectId
                && q.status == (int)MachineRepairStatus.Completed && q.checktime > 0 /*&& q.offlinestatus == 1*/);
            //if (!string.IsNullOrWhiteSpace(request.offlinestatus))
            //{
            //    queryable = queryable.Where(q => q.offlinestatus == request.offlinestatus.ToInt());
            //}
            //var expections = new List<int>();
            //foreach (var expection in request.expections)
            //{
            //    var ids = _expectionTypeRepository.GetExpectionSonSelfLevel(expection, ProjectId).Select(s => s.id);
            //    if (ids.Any())
            //    {
            //        expections.AddRange(ids);
            //    }
            //}
            //if (expections.Any())
            //{
            //    expections = expections.Distinct().ToList();
            //    queryable = queryable.Where(f => expections.Contains(f.expection_id));
            //}

            var result = new FaultFrequencyAnalysisResult();
            if (request.x_type == "1")
            {
                switch (request.x_id.ToLower())
                {
                    case "a":
                        request.x_id = "0";
                        break;
                    case "b":
                        request.x_id = "1";
                        break;
                    case "c":
                        request.x_id = "2";
                        break;
                    default:
                        request.x_id = "0";
                        break;
                }
            }
            //0：日 1：月 2：年
            var xid = request.x_id.ToInt();
            var xType = request.x_type.ToInt();
            var repaires = queryable.Where(q => machineIds.Contains(q.machineid)).ToList();
            if (xType == 1) //时间
            {
                var interal = DateTimeHelper.GetInteral(xid);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, xid);
                for (var i = 0; i < dates.Count; i++)
                {
                    DateTime start;
                    DateTime end;
                    //if (xid == 0 || xid == 1)
                    //{
                    //    start = dates[i];
                    //    end = dates[i].AddDays(interal).AddSeconds(-1);
                    //    result.x.Add(start.ToString(ParameterConstant.DateFormat));
                    //}
                    //else
                    //{
                    //    start = dates[i].AddDays(1 - dates[i].Day);
                    //    end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                    //    result.x.Add(start.ToString("yyyy-MM"));
                    //}
                    if(xid==0)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        result.x.Add(start.ToString(ParameterConstant.DateFormat));
                    }
                    else if (xid==1)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        result.x.Add($"{ start.Year}W{DateTimeHelper.GetWeekOfYear(start)}");
                    }
                    else
                    {
                        start = dates[i].AddDays(1 - dates[i].Day);
                        end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                        result.x.Add(start.ToString("yyyy-MM"));
                    }


                    if (request.onetype == "1" || request.onetype == "2")
                    {
                        var res = await GetMachineFaultRadioByTime(start, end, repaires, machineIds);
                        result.y1.Add(res.machineCount);
                        var radio = request.onetype == "1" ? res.radio : 100 - res.radio;
                        result.y2.Add(Math.Round(radio / interal, 2));
                    }

                    else if (request.onetype == "3") //故障频次
                    {
                        var res = await GetMachineFaultCount(start, end, repaires);
                        result.y1.Add(res.machineCount);
                        result.y2.Add(res.radio);
                    }
                    else if (request.onetype == "4") //备件价格
                    {
                        var res = await GetSparepartPrice(start, end, repaires);
                        result.y1.Add(res.machineCount);
                        result.y2.Add(res.radio);
                    }
                }
            }
            else //产线层级
            {

                foreach (var item in sectionList)
                {
                    var sectiondata = _projectLevelSectionRepository.Get(f => f.id == item.ToInt());
                    var levels = _projectLevelSectionRepository.GetSectionFamilyList(item.ToInt(), ProjectId);
                    if (sectiondata != null)
                    {
                        levels.Add(sectiondata);
                    }
                    if (levels.Any())
                    {
                        levels = levels.Where(f => f.levelid == request.x_id.ToInt()).ToList();

                        foreach (var levelSection in levels)
                        {
                            result.x.Add(levels.Where(q => q.id == levelSection.id).Select(s => s.title).FirstOrDefault());
                            var machines = _machineRepository.GetAttributionMachineIds(levelSection.id, ProjectId);//_machineRepository.GetAttributionMachineList(new List<int> { levelSection.id }, ProjectId, new List<int> { 1 }).Select(s => s.id)
                            //    .Where(q => request.machineidarr.Contains(q)).ToList();
                            if (!machines.Any())
                            {
                                result.y1.Add(0);
                                result.y2.Add(0);
                            }

                            var machineRepaires = repaires.Where(q => machines.Contains(q.machineid)).ToList();
                            if (request.onetype == "1" || request.onetype == "2")
                            {
                                var res = await GetMachineFaultRadioBySection(dtStart, dtEnd, machineRepaires, machines);
                                result.y1.Add(res.machineCount);
                                var radio = request.onetype == "1" ? res.radio : 100 - res.radio;
                                result.y2.Add(Math.Round(radio, 2));
                            }

                            else if (request.onetype == "3") //故障频次
                            {
                                var res = await GetMachineFaultCount(dtStart, dtEnd, machineRepaires);
                                result.y1.Add(res.machineCount);
                                result.y2.Add(res.radio);
                            }
                            else if (request.onetype == "4") //备件价格
                            {
                                var res = await GetSparepartPrice(dtStart, dtEnd, machineRepaires);
                                result.y1.Add(res.machineCount);
                                result.y2.Add(res.radio);
                            }
                        }
                    }
                }
            }

            return new ObjectResult(result);
        }

        /// <summary>
        /// 综合统计SKF
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> FaultFrequencyAnalysisSkf([FromBody]RequestFaultFrequencyAnalysis request)
        {
            if (request.machineidarr == null || !request.machineidarr.Any())
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            if (string.IsNullOrWhiteSpace(request.starttime) || string.IsNullOrWhiteSpace(request.endtime))
            {
                throw new ServerException(200099);
            }

            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var machineType = request.machinetype.ToInt();
            if (machineType > 0)
            {
                var machineTypes = _machineTypeRepository.GetList(t => t.parentid == machineType && t.projectid == ProjectId &&
                    t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                machineTypes.Add(machineType);
                if (machineTypes.Any())
                {
                    var machineIDs = _machineRepository.GetList(t => machineTypes.Contains(t.typeid) && t.projectid == ProjectId &&
                        t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    request.machineidarr = request.machineidarr.Where(t => machineIDs.Contains(t));
                }
            }

            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);



            Expression<Func<siger_project_repair, bool>> funFaultid = f => true;
            var faultids = new List<int>();
            if (request.fault_type != 0)
            {
                var ids = _faultTypeRepository.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.fault_type.Equals(request.fault_type)).Select(s => s.id).ToList();
                if (ids.Any())
                {
                    faultids = ids;
                }
            }
            if (request.fault_id != 0)
            {
                faultids = new List<int> { request.fault_id };
            }
            if (faultids.Any())
            {
                funFaultid = f => faultids.Contains(f.faultid);
            }
            Expression<Func<siger_project_repair, bool>> funCommon = q => q.createtime >= unixStartTime && q.createtime <= unixEndTime && q.projectid == ProjectId
               && q.status == (int)MachineRepairStatus.Completed && q.checktime > 0;
            var predicate = funFaultid.And(funCommon);
            var queryable = _repairRepository.GetList(predicate, "id");
            if (!string.IsNullOrWhiteSpace(request.offlinestatus))
            {
                queryable = queryable.Where(q => q.offlinestatus == request.offlinestatus.ToInt());
            }

            var result = new FaultFrequencyAnalysisResult();
            var xid = request.x_id.ToInt();
            var xType = request.x_type.ToInt();
            var repaires = queryable.Where(q => request.machineidarr.Contains(q.machineid)).ToList();
            var dailyRep = new DailySliceSateRepository(CompanyId, ProjectId);
            var sliceSates = await dailyRep.GetCncDailySliceSatesAsync(request.machineidarr, dtStart, dtEnd);
            if (xType == 1) //时间
            {
                var interal = DateTimeHelper.GetInteral(xid);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, xid);
                for (var i = 0; i < dates.Count; i++)
                {
                    DateTime start;
                    DateTime end;
                    if (xid == 0 || xid == 1)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        result.x.Add(start.ToString(ParameterConstant.DateFormat));
                    }
                    else
                    {
                        start = dates[i].AddDays(1 - dates[i].Day);
                        end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                        result.x.Add(start.ToString("yyyy-MM"));
                    }

                    if (request.onetype == "2")
                    {
                        var diff = UnixTimeHelper.GetUnixByShortDate(end.ToStr()) - UnixTimeHelper.GetUnixByShortDate(start.ToStr());
                        var SliceSates = sliceSates.Where(f => f.date >= start && f.date <= end).ToList();
                        var data = SliceSates.Sum(s => s.run) / diff;
                        result.y1.Add(SliceSates.Select(t => t.machineID).Count());
                        result.y2.Add(Math.Round(data, 4) * 100);
                    }

                    if (request.onetype == "1")
                    {
                        var res = await GetMachineFaultRadioByTime(start, end, repaires, request.machineidarr);
                        result.y1.Add(res.machineCount);
                        var radio = request.onetype == "1" ? res.radio : 100 - res.radio;
                        result.y2.Add(Math.Round(radio, 2));
                    }

                    else if (request.onetype == "3") //故障频次
                    {
                        var res = await GetMachineFaultCount(start, end, repaires);
                        result.y1.Add(res.machineCount);
                        result.y2.Add(res.radio);
                    }
                    else if (request.onetype == "4") //备件价格
                    {
                        var res = await GetSparepartPrice(start, end, repaires);
                        result.y1.Add(res.machineCount);
                        result.y2.Add(res.radio);
                    }
                }
            }
            else //产线层级
            {
                var sections = _machineRepository.GetLevelSections(request.level_id, ProjectId);
                var levels = sections.Where(q => q.levelid == xid).ToList();
                var diff = UnixTimeHelper.GetUnixByShortDate(dtEnd.ToStr()) - UnixTimeHelper.GetUnixByShortDate(dtStart.ToStr());
                if (levels.Any())
                {
                    result.x = levels.Select(m => m.title).ToList();
                    foreach (var levelSection in levels)
                    {
                        var machines = _machineRepository.GetLevelSectionMachineIds(levelSection.id, ProjectId)
                            .Where(q => request.machineidarr.Contains(q)).ToList();
                        if (!machines.Any())
                        {
                            result.y1.Add(0);
                            result.y2.Add(0);
                        }

                        if (request.onetype == "2")
                        {
                            var SliceSates = sliceSates.Where(f => machines.Contains(f.machineID)).ToList();
                            var data = SliceSates.Sum(s => s.run) / diff;
                            result.y1.Add(SliceSates.Select(t => t.machineID).Count());
                            result.y2.Add(Math.Round(data, 4) * 100);
                        }

                        var machineRepaires = repaires.Where(q => machines.Contains(q.machineid)).ToList();
                        if (request.onetype == "1")
                        {
                            var res = await GetMachineFaultRadioBySection(dtStart, dtEnd, machineRepaires, sections.Select(t => t.id));
                            result.y1.Add(res.machineCount);
                            var radio = request.onetype == "1" ? res.radio : 100 - res.radio;
                            result.y2.Add(Math.Round(radio, 2));
                        }

                        else if (request.onetype == "3") //故障频次
                        {
                            var res = await GetMachineFaultCount(dtStart, dtEnd, machineRepaires);
                            result.y1.Add(res.machineCount);
                            result.y2.Add(res.radio);
                        }
                        else if (request.onetype == "4") //备件价格
                        {
                            var res = await GetSparepartPrice(dtStart, dtEnd, machineRepaires);
                            result.y1.Add(res.machineCount);
                            result.y2.Add(res.radio);
                        }
                    }
                }
            }

            return new ObjectResult(result);
        }

        /// <summary>
        /// 故障率和使用率 按时间
        /// </summary>
        /// <returns></returns>
        private async Task<FaultFrequency> GetMachineFaultRadioByTime(DateTime start, DateTime end, IEnumerable<siger_project_repair> list, IEnumerable<int> machineIdArr)
        {
            var response = new FaultFrequency();
            if (!list.Any())
            {
                return response;
            }
            var dtStart = UnixTimeHelper.ConvertDataTimeLong(start);
            var dtEnd = UnixTimeHelper.ConvertDataTimeLong(end);

            return await Task.Run(() =>
            {
                var repairs = list.Where(q => q.createtime >= dtStart && q.createtime <= dtEnd);
                var machineIds = repairs.Select(m => m.machineid).Distinct();
                if (!machineIds.Any())
                {
                    return response;
                }
                double totalNormalSeconds = 0;
                foreach (var machineId in machineIds)
                {
                    var machineRepairs = repairs.Where(q => q.machineid == machineId).OrderBy(m => m.createtime)
                        .ToList();
                    if (machineRepairs.Any())
                    {
                        if (machineRepairs.Count == 1)
                        {
                            totalNormalSeconds = machineRepairs[0].checktime > dtEnd
                                ? (dtEnd - machineRepairs[0].createtime > 0 ? dtEnd - machineRepairs[0].createtime : 0)
                                : machineRepairs[0].checktime
                                  - machineRepairs[0].createtime;
                        }
                        else
                        {
                            totalNormalSeconds = machineRepairs[0].createtime > dtStart
                                ? machineRepairs[0].checktime - machineRepairs[0].createtime
                                : machineRepairs[0].checktime - dtStart;
                            totalNormalSeconds += machineRepairs[0].createtime - dtStart;
                            for (int i = 0; i < machineRepairs.Count - 1; i++)
                            {
                                //排除被包含的记录
                                if (machineRepairs[i + 1].checktime > machineRepairs[i].checktime
                                    && machineRepairs[i + 1].createtime > machineRepairs[i].checktime)
                                {
                                    var times = machineRepairs[i].checktime - machineRepairs[i + 1].createtime;
                                    if (times > 0)
                                    {
                                        totalNormalSeconds += times;
                                    }
                                }
                            }
                            totalNormalSeconds += machineRepairs[machineRepairs.Count - 1].checktime >= dtEnd
                                ? 0
                                : machineRepairs[machineRepairs.Count - 1].checktime - machineRepairs[machineRepairs.Count - 1].createtime;
                        }
                    }
                }

                response.machineCount = machineIds.Count();
                response.radio = Math.Round((totalNormalSeconds / (86400 * machineIds.Count())) * 100, 2);
                return response;
            });
        }

        /// <summary>
        /// 故障率和使用率 按产线层级
        /// </summary>
        /// <returns></returns>
        private async Task<FaultFrequency> GetMachineFaultRadioBySection(DateTime start, DateTime end, IEnumerable<siger_project_repair> list, IEnumerable<int> machineIdArr)
        {
            var response = new FaultFrequency();
            if (!list.Any())
            {
                return response;
            }
            var dtStart = UnixTimeHelper.ConvertDataTimeLong(start);
            var dtEnd = UnixTimeHelper.ConvertDataTimeLong(end);

            return await Task.Run(() =>
            {
                var repairs = list.Where(q => q.createtime >= dtStart && q.createtime <= dtEnd);
                var machineIds = repairs.Select(m => m.machineid).Distinct();
                if (!machineIds.Any())
                {
                    return response;
                }
                double totalNormalSeconds = 0;
                foreach (var machineId in machineIds)
                {
                    var machineRepairs = repairs.Where(q => q.machineid == machineId).OrderBy(m => m.createtime)
                        .ToList();
                    if (machineRepairs.Any())
                    {
                        if (machineRepairs.Count == 1)
                        {
                            totalNormalSeconds = machineRepairs[0].checktime > dtEnd
                                ? (dtEnd - machineRepairs[0].createtime > 0 ? dtEnd - machineRepairs[0].createtime : 0)
                                : machineRepairs[0].checktime
                                  - machineRepairs[0].createtime;
                        }
                        else
                        {
                            totalNormalSeconds = machineRepairs[0].createtime > dtStart
                                ? machineRepairs[0].checktime - machineRepairs[0].createtime
                                : machineRepairs[0].checktime - dtStart;
                            totalNormalSeconds += machineRepairs[0].createtime - dtStart;
                            for (int i = 0; i < machineRepairs.Count - 1; i++)
                            {
                                //排除被包含的记录
                                if (machineRepairs[i + 1].checktime > machineRepairs[i].checktime
                                    && machineRepairs[i + 1].createtime > machineRepairs[i].checktime)
                                {
                                    var times = machineRepairs[i].checktime - machineRepairs[i + 1].createtime;
                                    if (times > 0)
                                    {
                                        totalNormalSeconds += times;
                                    }
                                }
                            }
                            totalNormalSeconds += machineRepairs[machineRepairs.Count - 1].checktime >= dtEnd
                                ? 0
                                : machineRepairs[machineRepairs.Count - 1].checktime - machineRepairs[machineRepairs.Count - 1].createtime;
                        }
                    }
                }

                response.machineCount = machineIds.Count();
                response.radio = Math.Round((totalNormalSeconds / ((dtEnd - dtStart) * machineIds.Count())) * 100, 2);
                return response;
            });
        }

        /// <summary>
        /// 故障频次
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private async Task<FaultFrequency> GetMachineFaultCount(DateTime start, DateTime end, IEnumerable<siger_project_repair> list)
        {
            var response = new FaultFrequency();
            if (!list.Any())
            {
                return response;
            }
            var dtStart = UnixTimeHelper.ConvertDataTimeLong(start);
            var dtEnd = UnixTimeHelper.ConvertDataTimeLong(end);

            return await Task.Run(() =>
            {
                var repairs = list.Where(q => q.createtime > dtStart && q.createtime <= dtEnd);
                response.machineCount = repairs.Select(m => m.machineid).Distinct().Count();
                response.radio = repairs.Count();
                return response;
            });
        }

        private async Task<FaultFrequency> GetSparepartPrice(DateTime start, DateTime end, IEnumerable<siger_project_repair> list)
        {
            var response = new FaultFrequency();
            if (!list.Any())
            {
                return response;
            }
            var dtStart = UnixTimeHelper.ConvertDataTimeLong(start);
            var dtEnd = UnixTimeHelper.ConvertDataTimeLong(end);

            return await Task.Run(() =>
            {
                double totalPrice = 0;
                var repairs = list.Where(q => q.checktime > dtStart && q.checktime <= dtEnd);
                if (!repairs.Any())
                {
                    return response;
                }
                response.machineCount = repairs.Select(m => m.machineid).Distinct().Count();
                foreach (var repair in repairs)
                {
                    var sp = repair.sparepartid.Split(',');
                    foreach (var spsl in sp)
                    {
                        var sps = spsl.Split('*');
                        if (sps.Length == 2)
                        {
                            var spEntity = _sparepartRepository.Get(q =>
                                q.id == int.Parse(sps[0]) && q.projectid == ProjectId && q.status == (int)RowState.Valid);
                            if (spEntity != null)
                            {
                                totalPrice += spEntity.price * int.Parse(sps[1]);
                            }
                        }
                    }
                }

                response.radio = totalPrice;

                return response;
            });
        }

        /// <summary>
        /// 工单数据统计
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult RepairWorkOrderSum([FromBody]RequestRepairWorkOrderSum request)
        {
            if (string.IsNullOrWhiteSpace(request.starttime) || string.IsNullOrWhiteSpace(request.endtime))
            {
                throw new ServerException(200099);
            }

            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var result = new FaultFrequencyAnalysisResult();
            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);
            var machines = _machineRepository.GetAttributionMachineIds(request.level_id, ProjectId);
            //为了让设备类型生效
            var machineType = request.machinetype.ToInt();
            if (machineType > 0)
            {
                var machineTypes = _machineTypeRepository.GetSonMachineTypes(machineType, ProjectId).Select(s => s.id).ToList();
                machineTypes.Add(machineType);
                if (machineTypes.Any())
                {
                    var machineIDs = _machineRepository.GetList(t => machineTypes.Contains(t.typeid) && t.projectid == ProjectId &&
                        t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    machines = machines.Where(t => machineIDs.Contains(t));
                }
            }

            Expression<Func<siger_project_repair, bool>> funCommon = q => q.createtime >= unixStartTime && q.createtime <= unixEndTime && q.projectid == ProjectId
                && q.status >= (int)MachineRepairStatus.WaitingForRenew && q.status != (int)MachineRepairStatus.Deleted && machines.Contains(q.machineid)
                //&& q.offlinestatus == 1
                ;
            Expression<Func<siger_project_repair, bool>> funFault = f => true;
            var faultids = new List<int>();
            if (request.fault_type != 0)
            {
                var ids = _faultTypeRepository.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.fault_type.Equals(request.fault_type)).Select(s => s.id).ToList();
                if (ids.Any())
                {
                    faultids = ids;
                }
            }
            if (request.fault_id != 0)
            {
                faultids = new List<int> { request.fault_id };
            }
            if (faultids.Any())
            {
                funFault = f => faultids.Contains(f.faultid);
            }
            var predicate = funFault.And(funCommon);
            var queryable = _repairRepository.GetList(predicate);


            //if (!string.IsNullOrWhiteSpace(request.offlinestatus))
            //{
            //    queryable = queryable.Where(q => q.offlinestatus == request.offlinestatus.ToInt());
            //}
            var expections = new List<int>();
            foreach (var expection in request.expections)
            {
                var ids = _expectionTypeRepository.GetExpectionSonSelfLevel(expection, ProjectId).Select(s => s.id);
                if (ids.Any())
                {
                    expections.AddRange(ids);
                }
            }
            if (expections.Any())
            {
                expections = expections.Distinct().ToList();
                queryable = queryable.Where(f => expections.Contains(f.expection_id));
            }
            var repaires = queryable.ToList();
            var xid = request.x_id.ToUpper();
            var xType = request.x_type.ToInt();
            if (xType == 1) //时间
            {
                var totalCount = repaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                if (xid == "A") //天
                {
                    var start = unixStartTime - unixStartTime % 86400;
                    var end = unixEndTime + 86400;
                    end = end - end % 86400;
                    for (int i = start; i <= end; i = i + 86400)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 86400);
                        double faultCount = machineRepaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.DateFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 2));
                    }
                }
                else if (xid == "B") //周
                {
                    var start = unixStartTime - unixStartTime % 604800;
                    var end = unixEndTime + 604800;
                    end = end - end % 604800;
                    for (int i = start; i <= end; i = i + 604800)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 604800);
                        double faultCount = machineRepaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.DateFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 2));
                    }
                }
                else if (xid == "C") //月
                {
                    var start = unixStartTime - unixStartTime % 2592000;
                    var end = unixEndTime + 2592000;
                    end = end - end % 2592000;
                    for (int i = start; i <= end; i = i + 2592000)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 2592000);
                        double faultCount = machineRepaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.YearMonthFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 2));
                    }
                }

            }
            else //产线
            {
                var sectiondata = _projectLevelSectionRepository.Get(f => f.id == request.sectionId);
                var levels = _projectLevelSectionRepository.GetSectionFamilyList(request.sectionId, ProjectId);
                var totalCount = repaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                if (sectiondata != null)
                    levels.Add(sectiondata);
                if (levels.Any())
                {
                    levels = levels.Where(f => f.levelid == request.x_id.ToInt()).ToList();
                    foreach (var level in levels)
                    {
                        result.x.Add(level.title);
                        var mids = _machineRepository.GetAttributionMachineList(new List<int> { level.id }, ProjectId, new List<int> { 1 }).Select(s => s.id).ToList();
                        var machineRepaires = repaires.Where(q => mids.Contains(q.machineid));
                        double faultCount = machineRepaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 2));
                    }
                }
            }
            return new ObjectResult(result);
        }

        /// <summary>
        /// 工单数据统计
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult RepairWorkOrderSumEx([FromBody]RequestRepairWorkOrderSum request)
        {
            if (string.IsNullOrWhiteSpace(request.starttime) || string.IsNullOrWhiteSpace(request.endtime))
            {
                throw new ServerException(200099);
            }

            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var result = new FaultFrequencyAnalysisResult();
            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);
            var machines = _machineRepository.GetAttributionMachineIds(request.level_id, ProjectId);
            //为了让设备类型生效
            var machineType = request.machinetype.ToInt();
            if (machineType > 0)
            {
                var machineTypes = _machineTypeRepository.GetSonMachineTypes(machineType, ProjectId).Select(s => s.id).ToList();
                machineTypes.Add(machineType);
                if (machineTypes.Any())
                {
                    var machineIDs = _machineRepository.GetList(t => machineTypes.Contains(t.typeid) && t.projectid == ProjectId &&
                        t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    machines = machines.Where(t => machineIDs.Contains(t));
                }
            }

            Expression<Func<siger_project_repair, bool>> funCommon = q => q.createtime >= unixStartTime && q.createtime <= unixEndTime && q.projectid == ProjectId
                && q.status >= (int)MachineRepairStatus.WaitingForRenew && q.status != (int)MachineRepairStatus.Deleted && machines.Contains(q.machineid)
                //&& q.offlinestatus == 1
                ;
            Expression<Func<siger_project_repair, bool>> funFault = f => true;
            var faultids = new List<int>();
            if (request.fault_type != 0)
            {
                var ids = _faultTypeRepository.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.fault_type.Equals(request.fault_type)).Select(s => s.id).ToList();
                if (ids.Any())
                {
                    faultids = ids;
                }
            }
            if (request.fault_id != 0)
            {
                faultids = new List<int> { request.fault_id };
            }
            if (faultids.Any())
            {
                funFault = f => faultids.Contains(f.faultid);
            }
            var predicate = funFault.And(funCommon);
            var queryable = _repairRepository.GetList(predicate);


            //if (!string.IsNullOrWhiteSpace(request.offlinestatus))
            //{
            //    queryable = queryable.Where(q => q.offlinestatus == request.offlinestatus.ToInt());
            //}
            var expections = new List<int>();
            foreach (var expection in request.expections)
            {
                var ids = _expectionTypeRepository.GetExpectionSonSelfLevel(expection, ProjectId).Select(s => s.id);
                if (ids.Any())
                {
                    expections.AddRange(ids);
                }
            }
            if (expections.Any())
            {
                expections = expections.Distinct().ToList();
                queryable = queryable.Where(f => expections.Contains(f.expection_id));
            }
            var repaires = queryable.ToList();
            var xid = request.x_id.ToUpper();
            var xType = request.x_type.ToInt();
            if (xType == 1) //时间
            {
                var totalCount = repaires.Count();
                if (xid == "A") //天
                {
                    var start = unixStartTime - unixStartTime % 86400;
                    var end = unixEndTime + 86400;
                    end = end - end % 86400;
                    for (int i = start; i <= end; i = i + 86400)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 86400);
                        double faultCount = machineRepaires.Count();
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.DateFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 3));
                    }
                }
                else if (xid == "B") //周
                {
                    var start = unixStartTime - unixStartTime % 604800;
                    var end = unixEndTime + 604800;
                    end = end - end % 604800;
                    for (int i = start; i <= end; i = i + 604800)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 604800);
                        double faultCount = machineRepaires.Count();
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.DateFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 3));
                    }
                }
                else if (xid == "C") //月
                {
                    var start = unixStartTime - unixStartTime % 2592000;
                    var end = unixEndTime + 2592000;
                    end = end - end % 2592000;
                    for (int i = start; i <= end; i = i + 2592000)
                    {
                        var machineRepaires = repaires.Where(q => q.createtime >= i && q.createtime < i + 2592000);
                        double faultCount = machineRepaires.Count();
                        result.x.Add(UnixTimeHelper.ConvertStringDateTime(i.ToStr()).ToString(ParameterConstant.YearMonthFormat));
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 3));
                    }
                }

            }
            else //产线
            {
                var sectiondata = _projectLevelSectionRepository.Get(f => f.id == request.sectionId);
                var levels = _projectLevelSectionRepository.GetSectionFamilyList(request.sectionId, ProjectId);
                var totalCount = repaires.Select(s => s.completetime - s.signtime).Where(f => f > 0).Sum() / 60;
                levels.Add(sectiondata);
                if (levels.Any())
                {
                    levels = levels.Where(f => f.levelid == request.x_id.ToInt()).ToList();
                    foreach (var level in levels)
                    {
                        result.x.Add(level.title);
                        var mids = _machineRepository.GetAttributionMachineList(new List<int> { level.id }, ProjectId, new List<int> { 1 }).Select(s => s.id).ToList();
                        var machineRepaires = repaires.Where(q => mids.Contains(q.machineid));
                        double faultCount = machineRepaires.Count();
                        result.y1.Add(faultCount);
                        result.y2.Add(totalCount == 0 ? 0 : Math.Round(faultCount / totalCount, 3));
                    }
                }
            }
            return new ObjectResult(result);
        }


        /// <summary>
        /// 维修指标趋势
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult RepairDataTrendMTTR([FromBody]RequestRepairDataTrendMTTR request)
        {
            if (string.IsNullOrWhiteSpace(request.x_id))
            {
                throw new ServerException(500133);
            }
            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var machineTypeIds = new List<int>();
            var machineIds = _machineRepository.GetAttributionMachineIds(request.sectionId, ProjectId);
            if (!machineIds.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var startTime = UnixTimeHelper.GetUnixByShortDate(request.starttime);
            var endTime = UnixTimeHelper.GetUnixByShortDate(request.endtime);
            //GetPagedRepairList
            var repairs = _repairRepository.GetRepairsForMTTR(new RequestRepairDataTrendMTTREx { mids = machineIds.ToList(), start = startTime, end = endTime, department = request.department, mid = request.mid ,offlinestatus=request.offlinestatus}, ProjectId);
            //condition
            if (!string.IsNullOrEmpty(request.offlinestatus))
            {
                repairs = repairs.Where(f => f.offlinestatus == request.offlinestatus.ToInt()).ToList();
            }
            if (request.mid != 0)
            {
                repairs = repairs.Where(f => f.name.Equals(request.mid.ToStr()));
            }
            if (request.department != 0)
            {
                var uids = _userRepository.GetList(f => f.sectionid == request.department && f.projectid == ProjectId).Select(s => s.mid.ToStr());
                repairs = repairs.Where(f => f.mids.Intersect(uids).Any()).ToList();
            }
            var y2List = new List<RepairListForMTTR>();
            var stations = _machineRepository.GetMachineStationInfos(machineIds, ProjectId).ToList();
            foreach (var repair in repairs)
            {
                var spars = repair.sparepartid.Split(',');
                var sparInfos = new List<string>();
                foreach (var spar in spars)
                {
                    var sps = spar.Split('*');
                    if (sps.Length == 2)
                    {
                        var sp = _sparepartRepository.Get(int.Parse(sps[0]));
                        if (sp.status == (int)RowState.Valid)
                        {
                            sparInfos.Add($"{sp.title}({sp.code})*{sps[1]}");
                        }
                    }
                }
                var station = stations.FirstOrDefault(q => q.machineId == repair.machineid);
                y2List.Add(new RepairListForMTTR
                {
                    date = UnixTimeHelper.ConvertIntDate(repair.createtime),
                    fault_content = repair.fault_content,
                    fault_description = _faultTypeRepository.Get(f => f.id == repair.fault_description.ToInt())?.title ?? "",
                    id = repair.id,
                    real_faultid_desc = _faultTypeRepository.Get(f => f.id == repair.real_faultid_desc.ToInt())?.title ?? "",
                    remark = repair.remark,
                    repair_process = repair.repair_process,
                    repairtime = repair.repairtime / 60,
                    reporttime = UnixTimeHelper.ConvertStringDateTime(repair.createtime.ToString())
                        .ToString(ParameterConstant.YearMonthDayHourMinute),
                    createtime = repair.checktime,
                    sparepart = string.Join(',', sparInfos),
                    name = $"{_userRepository.Get(f => f.mid == repair.repairmid).name} ",
                    //$"{ _repairRepository.GetUserNames(repair.name.Split(','))}",
                    levelname = station == null ? "" : station.section_name + "-" + station.station_name,
                    workorder = repair.workorder
                });
            }
            var result = new RepairDataTrendMTTRResult
            {
                y2 = y2List
            };
            var xtype = request.type_id.ToInt();
            if (xtype == 1)//部门
            {
                var sections = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).ToList();

                var interal = dtEnd.Subtract(dtStart).Days;
                foreach (var section in sections)
                {
                    var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.sectionid == section.id).Select(s => s.mid.ToStr()).ToList();
                    if (!users.Any())
                    {
                        continue;
                    }
                    var entities = repairs.Where(f => users.Contains(f.repairmid.ToStr())).ToList();
                    if (!entities.Any())
                    {
                        continue;
                    }
                    result.x.Add(section.title);
                    var mttr = entities.Sum(s => s.repairtime) / entities.Count();
                    result.y1.Add(Math.Round((double)mttr / 60, 1));
                }
            }
            else if (xtype == 2)//执行人
            {
                var interal = dtEnd.Subtract(dtStart).Days;
                var section = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).Select(s => s.id).ToList();
                var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && section.Contains(f.sectionid)).Select(s => s.mid.ToStr()).ToList();
                if (request.mid != 0)
                {
                    users = users.Where(f => f == request.mid.ToStr()).ToList();
                }
                foreach (var user in users)
                {
                    var entities = repairs.Where(f => user == f.repairmid.ToStr()).ToList();
                    //var entities = repairs.Where(f => f.mids.Intersect(users).Any()).ToList();
                    if (!entities.Any())
                    {
                        continue;
                    }
                    result.x.Add(_userRepository.Get(f => f.mid.ToStr() == user).name);
                    var mttr = entities.Sum(s => s.repairtime) / entities.Count();
                    result.y1.Add(Math.Round((double)mttr / 60, 1));
                }
            }
            else if (xtype == 3)//时间
            {
                var xid = request.time;
                var interal = DateTimeHelper.GetInteral(xid);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, xid);
                for (var i = 0; i < dates.Count; i++)
                {
                    DateTime start;
                    DateTime end;
                    if (xid == 0 || xid == 1)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        result.x.Add(start.ToString(ParameterConstant.DateFormat));
                    }
                    else
                    {
                        start = dates[i].AddDays(1 - dates[i].Day);
                        end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                        result.x.Add(start.ToString("yyyy-MM"));
                    }
                    var entities = repairs.Where(f => f.createtime >= UnixTimeHelper.ConvertDataTimeLong(start) && f.createtime <= UnixTimeHelper.ConvertDataTimeLong(end)).ToList();
                    if (entities.Any())
                    {
                        var mttr = entities.Sum(s => s.repairtime) / entities.Count();
                        result.y1.Add(Math.Round((double)mttr / 60, 1));
                    }
                    else
                    {
                        result.y1.Add(0);
                    }
                }
            }
            else if (xtype == 4)//产线
            {
                var interal = dtEnd.Subtract(dtStart).Days;
                var sectiondata = _projectLevelSectionRepository.Get(f => f.id == request.sectionId);
                var levels = _projectLevelSectionRepository.GetSectionFamilyList(request.sectionId, ProjectId);
                if (sectiondata != null)
                    levels.Add(sectiondata);
                var datas = new List<StatisticalModel>();
                if (levels.Any())
                {
                    levels = levels.Where(f => f != null && f.levelid == request.level).ToList();
                    foreach (var level in levels)
                    {
                        var mids = _machineRepository.GetAttributionMachineList(new List<int> { level.id }, ProjectId, new List<int> { 1 }).Select(s => s.id);
                        var entities = repairs.Where(f => mids.Contains(f.machineid)).ToList();
                        result.x.Add(level.title);
                        if (entities.Any())
                        {
                            var mttr = entities.Sum(s => s.repairtime) / entities.Count();
                            result.y1.Add(Math.Round((double)mttr / 60, 1));
                        }
                        else
                        {
                            result.y1.Add(0);
                        }
                    }
                }
            }
            return new ObjectResult(result);
        }

        /// <summary>
        /// 维修指标趋势
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult RepairDataTrendMTBF([FromBody]RequestRepairDataTrendMTTR request)
        {
            if (string.IsNullOrWhiteSpace(request.x_id))
            {
                throw new ServerException(500133);
            }
            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var machineIds = _machineRepository.GetAttributionMachineIds(request.level_id, ProjectId);
            if (!machineIds.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //取设备
            var machineType = request.machinetype.ToInt();
            if (machineType > 0)
            {
                var machineTypes = _machineTypeRepository.GetSonMachineTypes(machineType, ProjectId).Select(s => s.id).ToList();
                machineTypes.Add(machineType);
                if (machineTypes.Any())
                {
                    var machineIDs = _machineRepository.GetList(t => machineTypes.Contains(t.typeid) && t.projectid == ProjectId &&
                        t.status == (int)RowState.Valid).Select(t => t.id).ToList();
                    machineIds = machineIds.Where(t => machineIDs.Contains(t));
                }
            }

            var startTime = UnixTimeHelper.GetUnixByShortDate(request.starttime);
            var endTime = UnixTimeHelper.GetUnixByShortDate(request.endtime);
            var repairs = _repairRepository.GetRepairsForMTTR(machineIds, startTime, endTime,
                request.faulttype_id.ToInt(), request.fault_id.ToInt(), 1, ProjectId);
            var expections = new List<int>();
            foreach (var expection in request.expections)
            {
                var ids = _expectionTypeRepository.GetExpectionSonSelfLevel(expection, ProjectId).Select(s => s.id);
                if (ids.Any())
                {
                    expections.AddRange(ids);
                }
            }
            if (expections.Any())
            {
                expections = expections.Distinct().ToList();
                repairs = repairs.Where(f => expections.Contains(f.id)).ToList();
            }

            var data = new List<MtbfList>();
            if (request.x_type == "1")
            {
                switch (request.x_id.ToLower())
                {
                    case "a":
                        request.x_id = "0";
                        break;
                    case "b":
                        request.x_id = "1";
                        break;
                    case "c":
                        request.x_id = "2";
                        break;
                    default:
                        request.x_id = "0";
                        break;
                }
                var xid = request.x_id.ToInt();
                var interal = DateTimeHelper.GetInteral(xid);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, xid);
                for (var i = 0; i < dates.Count; i++)
                {
                    DateTime start;
                    DateTime end;
                    if (xid == 0 || xid == 1)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        var mtbf = MachineMTTRBFHelper.GetMachineMTTRBF(start, end, repairs, interal, 2);
                        //补充mtbf为0的情况
                        if (mtbf == 0)
                        {
                            if (xid == 0)
                            {
                                mtbf = 1440;
                            }
                            else
                            {
                                mtbf = 1440 * 7;
                            }
                        }
                        data.Add(new MtbfList { time = start.ToString(ParameterConstant.DateFormat), mtbf = mtbf });
                    }
                    else
                    {
                        start = dates[i].AddDays(1 - dates[i].Day);
                        end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                        var mtbf = MachineMTTRBFHelper.GetMachineMTTRBF(start, end, repairs, interal, 2);
                        if (mtbf == 0)
                        {
                            mtbf = 1440 * 30;
                        }
                        data.Add(new MtbfList { time = start.ToString("yyyy-MM"), mtbf = mtbf });
                    }
                }
            }
            else
            {
                var sectiondata = _projectLevelSectionRepository.Get(f => f.id == request.sectionId);
                var levels = _projectLevelSectionRepository.GetSectionFamilyList(request.sectionId, ProjectId);
                levels.Add(sectiondata);
                if (levels.Any())
                {
                    levels = levels.Where(f => f.levelid == request.x_id.ToInt()).ToList();
                    var interal = (endTime - startTime) / 86400;
                    foreach (var item in levels)
                    {
                        var mids = _machineRepository.GetAttributionMachineList(new List<int> { item.id }, ProjectId, new List<int> { 1 }).Select(s => s.id);
                        var tempmids = mids.Where(f => machineIds.Contains(f));
                        repairs = _repairRepository.GetRepairsForMTTR(tempmids, startTime, endTime,
                                                                    request.faulttype_id.ToInt(), request.fault_id.ToInt(), 1, ProjectId);
                        var mtbf = MachineMTTRBFHelper.GetMachineMTTRBF(UnixTimeHelper.ConvertStringDateTime(startTime.ToStr()), UnixTimeHelper.ConvertStringDateTime(endTime.ToStr()), repairs, interal, 2);
                        if (mtbf == 0)
                        {
                            mtbf = 1440;
                        }
                        data.Add(new MtbfList { time = item.title, mtbf = mtbf });
                    }
                }
            }
            if (data.Any())
            {
                var result = new RepairDataTrendMTBFResult() { y2 = data, x = data.Select(s => s.time).ToList(), y1 = data.Select(s => s.mtbf).ToList() };
                return new ObjectResult(result);
            }
            return new ObjectResult(new RepairDataTrendMTBFResult());
        }

        /// <summary>
        /// 维修有效性评价
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetRepairPersonTime([FromBody]RequestGetRepairPersonTime request)
        {
            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var machineTypeIds = new List<int>();
            var machineIds = _machineRepository.GetLevelSectionMachineIds(request.level_id.ToInt(), ProjectId);
            if (!machineIds.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            //取设备
            if (!string.IsNullOrWhiteSpace(request.type_id) && string.IsNullOrWhiteSpace(request.concrete_id))
            {
                machineTypeIds = _machineTypeRepository
                    .GetList(q => q.parentid == request.type_id.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid)
                    .Select(m => m.id).ToList();

                machineIds = _machineRepository.GetList(q =>
                    machineIds.Contains(q.id) && machineTypeIds.Contains(q.typeid) && q.status == (int)RowState.Valid
                    && q.projectid == ProjectId).Select(m => m.id).ToList();
            }
            else if (!string.IsNullOrWhiteSpace(request.concrete_id))
            {
                machineTypeIds = _machineTypeRepository
                    .GetList(q => q.id == request.concrete_id.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid)
                    .Select(m => m.id).ToList();

                machineIds = _machineRepository.GetList(q =>
                    machineIds.Contains(q.id) && machineTypeIds.Contains(q.typeid) && q.status == (int)RowState.Valid
                    && q.projectid == ProjectId).Select(m => m.id).ToList();
            }

            var startTime = UnixTimeHelper.GetUnixByShortDate(request.starttime);
            var endTime = UnixTimeHelper.GetUnixByShortDate(request.endtime);

            var repairs = _repairRepository.GetRepairsForMTTR(machineIds, startTime, endTime,
                request.faulttype_id.ToInt(), request.fault_id.ToInt(), request.offlinestatus.ToInt(), ProjectId);

            //按维修人员拆分维修工单
            var newRepairs = new List<RepairListForMTTR>();
            foreach (var repair in repairs)
            {
                var addMids = repair.name.Split(',');
                foreach (var addMid in addMids)
                {
                    newRepairs.Add(new RepairListForMTTR
                    {
                        checktime = repair.checktime,
                        createtime = repair.createtime,
                        machineid = repair.machineid,
                        id = repair.id,
                        name = addMid
                    });
                }
            }

            var userIds = newRepairs.Select(m => m.name).Distinct();
            var names = new List<string>();
            foreach (var userId in userIds)
            {
                names.Add(_repairRepository.GetUserNames(new List<string> { userId }));
            }
            var result = new RepairPersonTimeResult
            {
                effective_time = names,
                name = names
            };

            //mttr
            foreach (var userId in userIds)
            {
                var times = new List<double>();
                var repirs = newRepairs.Where(q => q.name == userId);
                foreach (var repir in repirs)
                {
                    times.Add((repir.checktime - repir.createtime) / 60);
                }
                result.time.Add(times);

                //mtbf
                var noFaultTimes = new List<double>();
                var repairMachineIds = newRepairs.Select(m => m.machineid).Distinct();
                foreach (var machineId in repairMachineIds)
                {
                    var machineRepirs = newRepairs.Where(q => q.machineid == machineId && q.name == userId).OrderBy(q => q.createtime).ToList();
                    for (int i = 0; i < machineRepirs.Count - 1; i++)
                    {
                        var time = machineRepirs[i + 1].createtime - machineRepirs[i].checktime;
                        if (time > 0)
                        {
                            noFaultTimes.Add(time / 60);
                        }
                    }
                }
                result.fault_analysis.Add(noFaultTimes);
            }

            return new ObjectResult(result);
        }

        /// <summary>
        /// 计划维护时间统计
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult PlanTimeAnalysis([FromBody]RequestPlanTimeAnalysis request)
        {
            var sectionId = request.sectionid.ToInt();
            var machineIds = _machineRepository.GetAttributionMachineIds(sectionId, ProjectId).ToList();
            if (!machineIds.Any())
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            if (string.IsNullOrWhiteSpace(request.starttime) || string.IsNullOrWhiteSpace(request.endtime))
            {
                throw new ServerException(200099);
            }

            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            if (dtStart.ToShortDateString() == dtEnd.ToShortDateString())
            {
                throw new ServerException(200101);
            }

            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);

            var queryable = _planRecordRepository.GetRecordListEx(machineIds, unixStartTime, unixEndTime,
                    request.mode.ToInt(), ProjectId).ToList();
            var result = new PlanTimeAnalysisResult();
            var xid = request.x_id.ToInt();
            var xType = request.Xtype.ToInt();
            var datas = new List<PlanTimeCount>();
            if (xType == 1) //时间
            {
                switch (request.x_id.ToUpper())
                {
                    case "A":
                        xid = 0;
                        break;
                    case "B":
                        xid = 1;
                        break;
                    case "C":
                        xid = 2;
                        break;
                    default:
                        break;
                }

                var interal = DateTimeHelper.GetInteral(xid);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, xid);
                for (var i = 0; i < dates.Count; i++)
                {
                    var model = new PlanTimeCount();
                    DateTime start;
                    DateTime end;
                    if (xid == 0 || xid == 1)
                    {
                        start = dates[i];
                        end = dates[i].AddDays(interal).AddSeconds(-1);
                        var unixSt = UnixTimeHelper.ConvertDataTimeLong(start);
                        var unixEt = UnixTimeHelper.ConvertDataTimeLong(end);
                        var records = queryable.Where(t => t.create_time <= unixEt && t.create_time >= unixSt).ToList();
                        if (records.Any())
                        {
                            var standardtime = records.Sum(s => s.standard_time);
                            var actualtime = records.Sum(s => s.actual_standard_time);
                            datas.Add(new PlanTimeCount { name = start.ToString(ParameterConstant.DateFormat), standardtime = Math.Round((double)standardtime / 1, 2), actualtime = Math.Round((double)actualtime / 1, 2) });
                        }
                        else
                        {
                            datas.Add(new PlanTimeCount { name = start.ToString(ParameterConstant.DateFormat), standardtime = 0, actualtime = 0 });
                        }
                    }
                    else
                    {
                        start = dates[i].AddDays(1 - dates[i].Day);
                        end = dates[i].AddDays(1 - dates[i].Day).Date.AddMonths(1).AddSeconds(-1); //到月底
                        var unixSt = UnixTimeHelper.ConvertDataTimeLong(start);
                        var unixEt = UnixTimeHelper.ConvertDataTimeLong(end);
                        var records = queryable.Where(t => t.create_time <= unixEt && t.create_time >= unixSt).ToList();
                        if (records.Any())
                        {
                            var standardtime = records.Sum(s => s.standard_time);
                            var actualtime = records.Sum(s => s.actual_standard_time);
                            datas.Add(new PlanTimeCount { name = start.ToString("yyyy-MM"), standardtime = Math.Round((double)standardtime / 1, 2), actualtime = Math.Round((double)actualtime / 1, 2) });
                        }
                        else
                        {
                            datas.Add(new PlanTimeCount { name = start.ToString("yyyy-MM"), standardtime = 0, actualtime = 0 });
                        }
                    }
                }
                result.planTimeCounts = datas;
            }
            else
            {
                var sectiondata = _projectLevelSectionRepository.Get(f => f.id == request.sectionId);
                var levels = _projectLevelSectionRepository.GetSectionFamilyList(request.sectionId, ProjectId);
                if (sectiondata != null)
                    levels.Add(sectiondata);
                if (levels.Any())
                {
                    levels = levels.Where(f => f != null && f.levelid == request.x_id.ToInt()).ToList();
                    foreach (var level in levels)
                    {
                        var mids = _machineRepository.GetAttributionMachineList(new List<int> { level.id }, ProjectId, new List<int> { 1 }).Select(s => s.id);
                        var temp = queryable.Where(f => mids.Contains(f.machineid)).ToList();
                        if (temp.Any())
                        {
                            var standardtime = temp.Sum(s => s.standard_time);
                            var actualtime = temp.Sum(s => s.actual_standard_time);
                            datas.Add(new PlanTimeCount { name = level.title, standardtime = Math.Round((double)standardtime / 1, 2), actualtime = Math.Round((double)actualtime / 1, 2) });
                        }
                        else
                        {
                            datas.Add(new PlanTimeCount { name = level.title, standardtime = 0, actualtime = 0 });
                        }
                    }
                }
                result.planTimeCounts = datas;
            }
            if (result.planTimeCounts.Any())
            {
                result.x = result.planTimeCounts.Select(s => s.name).ToList();
                result.y1 = result.planTimeCounts.Select(s => s.actualtime).ToList();
                result.y2 = result.planTimeCounts.Select(s => s.standardtime).ToList();
            }
            return new ObjectResult(result);
        }

        /// <summary>
        /// 维修通过率
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetRepairPassRate([FromBody] RequestGetRepairPassRate request)
        {
            var success = DateTime.TryParse(request.starttime, out var dtStart);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            success = DateTime.TryParse(request.endtime, out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            if (dtStart >= dtEnd)
            {
                throw new ServerException(200100);
            }

            //获取用户
            var userIds = new List<int>();
            if (request.user_id.ToInt() != 0)
            {
                userIds.Add(request.user_id.ToInt());
            }
            else if (request.usergroup_id.ToInt() != 0)
            {
                userIds = _userRepository.GetList(q => q.usergroupid == request.usergroup_id && q.status == (int)RowState.Valid).Select(m => m.mid).ToList();
            }
            else if (request.department.ToInt() != 0)
            {
                userIds = _userRepository.GetList(q => q.sectionid == request.department.ToInt() && q.status == (int)RowState.Valid).Select(m => m.mid).ToList();
            }
            else
            {
                userIds = _userRepository.GetList(q => q.status == (int)RowState.Valid).Select(m => m.mid).ToList();
            }

            var result = new GetRepairPassRateResult
            {
                onepass = new RepairPassRate
                {
                    count = 0,
                    percent = "0%"
                },
                twopass = new RepairPassRate
                {
                    count = 0,
                    percent = "0%"
                },
                mutipass = new RepairPassRate
                {
                    count = 0,
                    percent = "0%"
                }
            };
            var unixStartTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var unixEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd);

            var finishedRepairIds = _repairRepository.GetList(q => userIds.Contains(q.repairmid) && q.checktime >= unixStartTime && q.checktime <= unixEndTime
                                                                   && q.status >= 5).Select(m => m.id).ToList();
            if (!finishedRepairIds.Any())
            {
                return new ObjectResult(result);
            }
            var userRepairs = _repairListRepository.GetList(q => q.creattime >= unixStartTime && q.creattime <= unixEndTime
                                                                   && finishedRepairIds.Contains(q.repairid)).ToList();
            var repairsIds = finishedRepairIds.Distinct();
            var total = 0;
            var onePass = 0;
            var twoPass = 0;
            var mutiPass = 0;

            var onePassRepaireIds = new List<int>();
            foreach (var repairsId in repairsIds)
            {
                var repairs = userRepairs.Where(q => q.repairid == repairsId);
                var count = repairs.Count(m => m.title.ToInt() == (int)RepairListStatus.UnderRepair);
                if (count == 0)
                {
                    continue;
                }

                if (count == 1)
                {
                    onePass++;
                    onePassRepaireIds.Add(repairsId);
                }

                if (count == 2)
                {
                    twoPass++;
                }

                if (count > 2)
                {
                    mutiPass++;
                }
                total++;
            }

            if (total == 0)
            {
                return new ObjectResult(result);
            }

            if (onePassRepaireIds.Any())
            {
                var user = _repairRepository.GetList(q => onePassRepaireIds.Contains(q.id)).GroupBy(m => m.repairmid)
                    .Select(m => new
                    {
                        mid = m.Key,
                        score = m.Sum(q => q.appraise)
                    })
                    .OrderByDescending(q => q.score)
                    .FirstOrDefault();
                var repaireCount = _repairRepository.GetList(q => onePassRepaireIds.Contains(q.id) && q.repairmid == user.mid).Count();
                var userName = _userRepository.Get(q => q.mid == user.mid).name;
                if (repaireCount > 0)
                {
                    result.feedback = new Feedback
                    {
                        count = repaireCount,
                        score = Math.Round((double)user.score / repaireCount, 1),
                        repair_name = userName
                    };
                }
            }

            result.onepass = new RepairPassRate
            {
                count = onePass,
                percent = onePass / total * 100 + "%"
            };
            result.twopass = new RepairPassRate
            {
                count = twoPass,
                percent = twoPass / total * 100 + "%"
            };
            result.mutipass = new RepairPassRate
            {
                count = mutiPass,
                percent = mutiPass / total * 100 + "%"
            };

            return new ObjectResult(result);
        }
        /// <summary>
        /// workload
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetWorkLoad([FromBody] RequestRepairDataTrendMTTR request)
        {
            var ret = new ResponseWorkLoad();
            var temp = new List<ResponseWorkLoadEx>();
            var start = UnixTimeHelper.ConvertDataTimeLong(request.starttime);
            var end = UnixTimeHelper.ConvertDataTimeLong(request.endtime);
            Expression<Func<siger_project_repair, bool>> funCommon = f => f.projectid == ProjectId && f.status != 0 && f.createtime >= start && f.createtime <= end && f.status >= 6;//已完成
            var predicate = funCommon;
            var repairList = _repairRepository.GetList(predicate).ToList();
            //init repairdata
            var repairdata = repairList.Select(s => new
            {
                mids = new List<int> { s.signmid, s.takemid, s.completemid },
                s.add_repairmid,
                response = (s.taketime - s.createtime) > 0 ? (s.taketime - s.createtime) / 60 : 0,
                sign = (s.signtime - s.taketime) > 0 ? (s.signtime - s.taketime) / 60 : 0,
                repair = (s.completetime - s.signtime) > 0 ? (s.completetime - s.signtime) / 60 : 0,
                complete = (s.checktime - s.completetime) > 0 ? (s.checktime - s.completetime) / 60 : 0,
            }).ToList();
            foreach (var repair in repairdata)
            {
                var ids = repair.add_repairmid.Split(',');
                foreach (var id in ids)
                {
                    var mid = id.ToInt();
                    if (mid == 0)
                    {
                        continue;
                    }
                    repair.mids.Add(mid);
                }
            }
            if (request.x_id.ToInt() == 1)//岗位
            {
                var sections = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).ToList();
                if (request.department != 0)
                {
                    sections = sections.Where(f => f.id == request.department).ToList();
                }
                //var usergroups = _userGroupRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && section.Contains(f.sectionid)).ToList();
                //if (request.department != 0)
                //{
                //    usergroups = usergroups.Where(f => f.sectionid == request.department).ToList();
                //}
                foreach (var section in sections)
                {
                    var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.sectionid == section.id).Select(s => s.mid).ToList();
                    if (!users.Any())
                    {
                        continue;
                    }
                    var entities = repairdata.Where(f => f.mids.Intersect(users).Any()).ToList();
                    if (!entities.Any() && request.department == 0)
                    {
                        temp.Add(new ResponseWorkLoadEx
                        {
                            response = 0,
                            sign = 0,
                            repair = 0,
                            complete = 0,
                            name = section.title
                        });
                        continue;
                    }

                    temp.Add(new ResponseWorkLoadEx
                    {
                        response = (int)Math.Round((double)entities.Sum(s => s.response), 0),
                        sign = (int)Math.Round((double)entities.Sum(s => s.sign), 0),
                        repair = (int)Math.Round((double)entities.Sum(s => s.repair), 0),
                        complete = (int)Math.Round((double)entities.Sum(s => s.complete), 0),
                        name = section.title
                    });
                }
            }
            if (request.x_id.ToInt() == 2)//执行人
            {
                var section = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).Select(s => s.id).ToList();
                var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && section.Contains(f.sectionid)).ToList();
                if (request.mids.Any())
                {
                    users = users.Where(f => request.mids.Contains(f.mid)).ToList();
                }
                foreach (var user in users)
                {
                    var entities = repairdata.Where(f => f.mids.Contains(user.mid));
                    if (!entities.Any() && request.mid == 0)
                    {
                        continue;
                    }
                    temp.Add(new ResponseWorkLoadEx { response = entities.Sum(s => s.response), sign = entities.Sum(s => s.sign), repair = entities.Sum(s => s.repair), complete = entities.Sum(s => s.complete), name = user.name });
                }
            }
            var y = temp.Select(s => s.name).ToList();
            ret.dataY.AddRange(y);
            var resp = temp.Select(s => s.response).ToList();
            ret.dataXList.Add(resp);
            var sig = temp.Select(s => s.sign).ToList();
            ret.dataXList.Add(sig);
            var rep = temp.Select(s => s.repair).ToList();
            ret.dataXList.Add(rep);
            var com = temp.Select(s => s.complete).ToList();
            ret.dataXList.Add(com);
            ret.avg = 0;
            if (y.Count > 0)
            {
                ret.avg = (resp.Sum() + sig.Sum() + rep.Sum() + com.Sum()) / y.Count;
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// workloadAvg
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetWorkLoadAvg([FromBody] RequestRepairDataTrendMTTR request)
        {
            var ret = new ResponseWorkLoad();
            var temp = new List<ResponseWorkLoadEx>();
            var start = UnixTimeHelper.ConvertDataTimeLong(request.starttime);
            var end = UnixTimeHelper.ConvertDataTimeLong(request.endtime);
            Expression<Func<siger_project_repair, bool>> funCommon = f => f.projectid == ProjectId && f.status != 0 && f.createtime >= start && f.createtime <= end && f.status >= 6;//已完成
            var predicate = funCommon;
            var repairList = _repairRepository.GetList(predicate).ToList();
            //init repairdata
            var repairdata = repairList.Select(s => new
            {
                mids = new List<int> { s.signmid, s.takemid, s.completemid },
                s.add_repairmid,
                response = (s.taketime - s.createtime) > 0 ? (s.taketime - s.createtime) / (double)60 : 0,
                sign = (s.signtime - s.taketime) > 0 ? (s.signtime - s.taketime) / (double)60 : 0,
                repair = (s.completetime - s.signtime) > 0 ? (s.completetime - s.signtime) / (double)60 : 0,
                complete = (s.checktime - s.completetime) > 0 ? (s.checktime - s.completetime) / (double)60 : 0,
            }).ToList();
            foreach (var repair in repairdata)
            {
                var ids = repair.add_repairmid.Split(',');
                foreach (var id in ids)
                {
                    var mid = id.ToInt();
                    if (mid == 0)
                    {
                        continue;
                    }
                    repair.mids.Add(mid);
                }
            }
            if (request.x_id.ToInt() == 1)//岗位
            {
                var sections = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).ToList();
                if (request.department != 0)
                {
                    sections = sections.Where(f => f.id == request.department).ToList();
                }

                foreach (var section in sections)
                {
                    var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.sectionid == section.id).Select(s => s.mid).ToList();
                    if (!users.Any())
                    {
                        continue;
                    }
                    var entities = repairdata.Where(f => f.mids.Intersect(users).Any()).ToList();
                    if (!entities.Any() && request.department == 0)
                    {
                        temp.Add(new ResponseWorkLoadEx
                        {
                            response = 0,
                            sign = 0,
                            repair = 0,
                            complete = 0,
                            name = section.title
                        });
                        continue;
                    }

                    temp.Add(new ResponseWorkLoadEx
                    {
                        response = Math.Round(entities.Sum(s => s.response) / entities.Count(), 2),
                        sign = Math.Round(entities.Sum(s => s.sign) / entities.Count(), 2),
                        repair = Math.Round(entities.Sum(s => s.repair) / entities.Count(), 2),
                        complete = Math.Round(entities.Sum(s => s.complete) / entities.Count(), 2),
                        name = section.title
                    });
                }
            }
            if (request.x_id.ToInt() == 2)//执行人
            {
                var section = _projectSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && f.type == 2).Select(s => s.id).ToList();
                var users = _userRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && section.Contains(f.sectionid)).ToList();
                if (request.mids.Any())
                {
                    users = users.Where(f => request.mids.Contains(f.mid)).ToList();
                }
                foreach (var user in users)
                {
                    var entities = repairdata.Where(f => f.mids.Contains(user.mid));
                    if (!entities.Any() && request.mid == 0)
                    {
                        continue;
                    }
                    temp.Add(new ResponseWorkLoadEx
                    {
                        response = Math.Round(entities.Sum(s => s.response) / entities.Count(), 2),
                        sign = Math.Round(entities.Sum(s => s.sign) / entities.Count(), 2),
                        repair = Math.Round(entities.Sum(s => s.repair) / entities.Count(), 2),
                        complete = Math.Round(entities.Sum(s => s.complete) / entities.Count(), 2),
                        name = user.name
                    });
                }
            }
            var y = temp.Select(s => s.name).ToList();
            ret.dataY.AddRange(y);
            var resp = temp.Select(s => s.response).ToList();
            ret.dataXList.Add(resp);
            var sig = temp.Select(s => s.sign).ToList();
            ret.dataXList.Add(sig);
            var rep = temp.Select(s => s.repair).ToList();
            ret.dataXList.Add(rep);
            var com = temp.Select(s => s.complete).ToList();
            ret.dataXList.Add(com);
            ret.avg = 0;
            if (y.Count > 0)
            {
                ret.avg = (resp.Sum() + sig.Sum() + rep.Sum() + com.Sum()) / y.Count;
            }
            return new ObjectResult(ret);
        }
    }

}