/// <summary>
        /// 缓存方式获取项目的生产汇总数据
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        public async Task <Dictionary <string, object> > GetProjectProcessSummary(Project project)
        {
            var cacheKey = $"{project.Id}@{project.TenantId}";

            return(await CacheManager.GetCache <string, Dictionary <string, object> >("ProjectProcessSummary").GetAsync(cacheKey, async o => {
                var processTypeManager = Resolve <ProcessTypeManager>();
                var processTaskManager = Resolve <ProcessTaskManager>();
                var dic = new Dictionary <string, object>()
                {
                    { "Id", project.Id },
                    { "ProjectSN", project.ProjectSN },
                    { "ProjectCharger", project.GetPropertyValue <string>("ProjectCharger") },
                    { "ProjectName", project.ProjectName }
                };
                var processTypes = await processTypeManager.GetAllList();

                var feeTotal = 0M;
                var innerFeeTotal = 0M;
                var outerFeeTotal = 0M;
                var hoursTotal = 0M;
                var taskNumberTotal = 0;
                var NGNumberTotal = 0;
                var delayNumberTotal = 0;
                foreach (var processType in processTypes)
                {
                    var taskQuery = processTaskManager.GetAll()
                                    .Where(t => t.Part.ProjectId == project.Id && t.ProcessTypeId == processType.Id && t.ProcessTaskStatus != ProcessTaskStatus.Inputed);
                    //强制回单的增加查询条件
                    //if (mustReturnFile)
                    //{
                    //    taskQuery = taskQuery.Where($"Status!=null and Status.Object.Contains(\"{ProcessTask.Status_Verify}\")");
                    //}
                    // .WhereIf(mustReturnFile, t =>t.Status!=null && t.Status.Object!=null && t.Status.Object.Contains(ProcessTask.Status_Verify))
                    //获取实际金额
                    var fee = taskQuery.Sum(t => t.Fee);
                    feeTotal += fee ?? 0;
                    dic.Add("ProcessType_" + processType.Id + "_Fee", fee?.ToString("0.00"));
                    //厂内金额
                    var innerFee = taskQuery.Where($"Status.Contains(\"{ProcessTask.Status_Inner}\")").Sum(t => t.Fee);
                    innerFeeTotal += innerFee ?? 0;
                    dic.Add("ProcessType_" + processType.Id + "_InnerFee", innerFee?.ToString("0.00"));
                    //厂外金额
                    outerFeeTotal += ((fee ?? 0) - (innerFee ?? 0));
                    dic.Add("ProcessType_" + processType.Id + "_OuterFee", ((fee ?? 0) - (innerFee ?? 0)).ToString("0.00"));
                    //实际工时
                    var hours = taskQuery.Sum(t => t.ActualHours);
                    hoursTotal += hours ?? 0;
                    dic.Add("ProcessType_" + processType.Id + "_ActualHours", hours?.ToString("0.00"));
                    //总数
                    var taskNumber = taskQuery.Count();
                    taskNumberTotal += taskNumber;
                    dic.Add("ProcessType_" + processType.Id + "_TaskNumber", taskNumber.ToString());
                    //不合格数
                    var NGNumber = taskQuery.Where(t => MESDbContext.GetJsonValueNumber(t.Property, "$.QuanlityType") == 2).Count();
                    NGNumberTotal += NGNumber;
                    dic.Add("ProcessType_" + processType.Id + "_NGNumber", NGNumber.ToString());
                    //延迟数
                    //var delayNumber = taskQuery.Where("(Convert.ToDateTime(RequireDate)-Convert.ToDateTime(EndDate==null?DateTime.Now.ToString():EndDate.ToString())).TotalDays<0  and RequireDate!=null").Count();
                    //貌似不能直接用ef core查询
                    var delayNumber = await DynamicQuery.SingleAsync <int?>($"select sum(datediff( case when enddate is null then NOW() else enddate end,requiredate)) from {nameof(ProcessTask)} where requiredate is not null and datediff( case when enddate is null then NOW() else enddate end,requiredate)>0 and ProcessTaskStatus!=0 and processTypeId={processType.Id} and partid in (select id from part where projectid={project.Id} and isdeleted=0) and isdeleted=0");
                    //var delayNumber = taskQuery.Where("(Convert.ToDateTime(RequireDate)-Convert.ToDateTime(EndDate)).TotalDays<0  and RequireDate!=null and EndDate!=null").Sum(o=> (o.EndDate.Value-o.StartDate.Value).TotalDays);
                    delayNumberTotal += delayNumber ?? 0;
                    dic.Add("ProcessType_" + processType.Id + "_DelayNumber", delayNumber.ToString());
                }
                dic.Add("FeeTotal", feeTotal.ToString("0.00"));
                dic.Add("InnerFeeTotal", innerFeeTotal.ToString("0.00"));
                dic.Add("OuterFeeTotal", outerFeeTotal.ToString("0.00"));
                dic.Add("HoursTotal", hoursTotal.ToString("0.00"));
                dic.Add("TaskNumberTotal", taskNumberTotal.ToString());
                dic.Add("NGNumberTotal", NGNumberTotal.ToString());
                dic.Add("DelayNumberTotal", delayNumberTotal.ToString("0"));

                return dic;
            }));
        }