Quellcode durchsuchen

导出清单修改为异步任务模式

luocaiyang vor 3 Jahren
Ursprung
Commit
19ee573819

+ 1 - 1
wispro.sp.api/AppealHandler/MissingCaseReviewHandler.cs

@@ -62,7 +62,7 @@ namespace wispro.sp.api.AppealHandler
                     }
                 }
 
-                var itemControler = new PerformanceItemController((spDbContext)spContext);
+                var itemControler = new PerformanceItemController((spDbContext)spContext,new Services.FileTaskCacheService());
 
                 
                 PerformanceItem Item = itemControler.GetItemInfoByCaseStage(strCaseNo,strDoItem, strCaseStage);

+ 1 - 1
wispro.sp.api/Controllers/AppealController.cs

@@ -338,7 +338,7 @@ namespace wispro.sp.api.Controllers
 
         public List<AppealRecord> GetAppealRecords(int userId)
         {
-            var data = Context.AppealRecords.Where<AppealRecord>(ar => ar.CreaterId == userId || (ar.ReviewerId == userId && ar.State !=1));
+            var data = Context.AppealRecords.Where<AppealRecord>(ar => (ar.CreaterId == userId || (ar.ReviewerId == userId && ar.State !=1)) && ar.Type.NeedReview ==true);
 
             var retList = data.Include(p => p.Reviewer)
                 .Include(p => p.Creater)

+ 73 - 0
wispro.sp.api/Controllers/FileProcesTaskController.cs

@@ -0,0 +1,73 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.api.Controllers
+{
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    public class FileProcesTaskController : ControllerBase
+    {
+        Services.IFileTaskService fileTaskService;
+
+        public FileProcesTaskController(Services.IFileTaskService _fileTaskService)
+        {
+            fileTaskService = _fileTaskService;
+        }
+
+        public share.FileProcessTask Get(string Id)
+        {
+            return fileTaskService.Get(Id);
+        }
+
+        [HttpGet, DisableRequestSizeLimit]
+        public async Task<IActionResult> Download(string Id)
+        {
+            
+            var filename = fileTaskService.Get(Id);
+
+            if (filename != null)
+            {
+                var attachfileSavePath = utility.ConfigHelper.GetSectionValue("AttachFileSavePath");
+                var filePath = filename.FilePath;
+
+                var context = HttpContext;
+
+                if (System.IO.File.Exists(filePath))
+                {
+                    var memory = new MemoryStream();
+                    await using (var stream = new FileStream(filePath, FileMode.Open))
+                    {
+                        await stream.CopyToAsync(memory);
+                    }
+                    memory.Position = 0;
+                    return File(memory, GetContentType(filename.FilePath), filename.FileName);
+                }
+                else
+                    return NotFound();
+            }
+            else
+            {
+                return NotFound();
+            }
+        }
+
+        private string GetContentType(string path)
+        {
+            var provider = new FileExtensionContentTypeProvider();
+            string contentType;
+
+            if (!provider.TryGetContentType(path, out contentType))
+            {
+                contentType = "application/octet-stream";
+            }
+
+            return contentType;
+        }
+    }
+}

+ 399 - 191
wispro.sp.api/Controllers/PerformanceItemController.cs

@@ -2,12 +2,18 @@
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
 using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Hosting;
 using System;
 using System.Collections.Generic;
+using System.Data;
+using System.IO;
 using System.Linq;
 using System.Linq.Expressions;
+using System.Threading;
 using System.Threading.Tasks;
+using wispro.sp.api.Services;
 using wispro.sp.api.Utility;
 using wispro.sp.entity;
 using wispro.sp.share;
@@ -21,11 +27,14 @@ namespace wispro.sp.api.Controllers
     public class PerformanceItemController : ControllerBase
     {
         spDbContext Context;
-
-        public PerformanceItemController(spDbContext context)
+        IFileTaskService fileTaskService;
+        public PerformanceItemController(spDbContext context, IFileTaskService _fileTaskService)
         {
             Context = context;
+            fileTaskService = _fileTaskService;
+
         }
+
         public ApiSaveResponse New(PerformanceItem item)
         {
             ApiSaveResponse ret = new ApiSaveResponse();
@@ -413,8 +422,8 @@ namespace wispro.sp.api.Controllers
         }
         private List<StaffStatistics> _CalMyStatistics(CalMonth calMonth, int? userid = null)
         {
-            
-            double gspjXS = DegreeOfDifficulty(calMonth.Year , calMonth.Month);
+
+            double gspjXS = DegreeOfDifficulty(calMonth.Year, calMonth.Month);
 
             //未归档,从绩效记录中统计数据
             var results = Context.PerformanceItems.Where<PerformanceItem>(s => s.CalMonth.Id == calMonth.Id);
@@ -439,172 +448,23 @@ namespace wispro.sp.api.Controllers
 
             foreach (PerformanceItem item in ItemList)
             {
-                
+
 
 
 
                 //if (item.BasePoint == null)
                 //{
-                    
-                    Utility.Utility.CalBasePoint(item,Rules);
 
-                    Context.SaveChanges();
+                //Utility.Utility.CalBasePoint(item,Rules);
+
+                //Context.SaveChanges();
                 //}
 
                 if (item.BasePoint != null && item.BasePoint.Value > 0)
                 {
                     double doPersonBasePoint = item.BasePoint.Value;
 
-                    System.Collections.Hashtable doPersonsBL = new System.Collections.Hashtable();
-
-                    bool isPJFP = true;
-                    double total = item.ItemStaffs.Count();
-                    if (item.ItemStaffs.Where<ItemStaff>(p => p.PerformancePoint != null || p.PerformancePoint == 0).Count() > 0)
-                    {
-                        total = item.ItemStaffs.Select(i => i.PerformancePoint.Value).Sum();
-                        isPJFP = false;
-                    }
-
-                    List<StaffStatistics> itemStatistics = new List<StaffStatistics>();
-
-                    if (item.Reviewer != null)
-                    {
-                        Context.Entry(item.Reviewer).Reference(b => b.StaffGrade).Load();
-                    }
-
-                    foreach (ItemStaff itemStaff in item.ItemStaffs)
-                    {
-                        Context.Entry(itemStaff).Reference(b => b.DoPerson).Load();
-                        Context.Entry(itemStaff.DoPerson).Reference(b => b.StaffGrade).Load();
-
-                        #region 计算审核人绩效点数,核稿人绩效点数按照核稿人与个处理人的核稿系数计算后加总,没有找到核稿系数(比如同级别),核稿系数为0
-                        if (item.ReviewerId != null && item.Type !="专案")
-                        {
-                            
-                            #region 取审核人等级审核等级系数
-                            VerifyCoefficient vcoefficient 
-                                = verifyCoefficients.Where<VerifyCoefficient>(v =>
-                                    v.CheckerId == item.Reviewer.StaffGrade.Id
-                                    && v.DoPersonId == itemStaff.DoPerson.StaffGradeId)
-                            .FirstOrDefault<VerifyCoefficient>();
-                            #endregion
-
-                            if (vcoefficient != null)
-                            {
-                                double reviewerBasePoint = item.BasePoint.Value * vcoefficient.Coefficient;
-
-
-                                string temJxType = $"{item.Type}审核";
-
-                                var temReviewerStatic = itemStatistics.Where<StaffStatistics>(s => s.StaffId == item.ReviewerId && s.jxType == temJxType && s.CalMonth.Id == calMonth.Id).FirstOrDefault();
-                                if (temReviewerStatic != null)
-                                {
-                                    temReviewerStatic.totalBasePoint += reviewerBasePoint;
-                                }
-                                else
-                                {
-                                    if (item.Reviewer.IsOnJob && itemStaff.DoPerson.Status != "试用期")  //判断是否在职
-                                    {
-                                        temReviewerStatic = new StaffStatistics()
-                                        {
-                                            CalMonth = calMonth,
-                                            CalMonthId = calMonth.Id,
-                                            StaffId = item.ReviewerId.Value,
-                                            totalBasePoint = reviewerBasePoint,
-                                            jxType = temJxType
-                                        };
-
-                                        itemStatistics.Add(temReviewerStatic);
-                                    }
-                                }
-                            }
-                        }
-                        #endregion
-
-                        #region 计算各处理人的绩效点数
-                        double handlerBasePoint;
-                        if (item.Type != "专案")
-                        {
-                            if (isPJFP)
-                            {
-                                handlerBasePoint = item.BasePoint.Value * 1.0 / total;
-                            }
-                            else
-                            {
-                                handlerBasePoint = item.BasePoint.Value * itemStaff.PerformancePoint.Value / total;
-                            }
-                        }
-                        else
-                        {
-                            handlerBasePoint = itemStaff.PerformancePoint.Value;
-                        }
-
-                        string handlerJxType = $"{item.Type}处理";
-                        var temStatic = itemStatistics.Where<StaffStatistics>(s => s.StaffId == itemStaff.DoPersonId && s.jxType == handlerJxType && s.CalMonth.Id == calMonth.Id).FirstOrDefault();
-                        if (temStatic != null)
-                        {
-                            if (item.Type != "专案")
-                            {
-                                temStatic.totalBasePoint += handlerBasePoint * itemStaff.DoPerson.StaffGrade.Coefficient;
-                            }
-                            else
-                            {
-                                temStatic.totalBasePoint += handlerBasePoint;
-                            }
-                        }
-                        else
-                        {
-                            if (itemStaff.DoPerson.StaffGrade != null && itemStaff.DoPerson.IsOnJob)
-                            {
-                                if (item.Type != "专案")
-                                {
-                                    if (itemStaff.DoPerson.Status == "试用期" && item.Reviewer != null)
-                                    {
-                                        temStatic = new StaffStatistics()
-                                        {
-                                            CalMonth = calMonth,
-                                            CalMonthId = calMonth.Id,
-                                            StaffId = item.Reviewer.Id,
-                                            totalBasePoint = handlerBasePoint * item.Reviewer.StaffGrade.Coefficient,
-                                            jxType = handlerJxType
-                                        };
-
-
-                                        itemStatistics.Add(temStatic);
-                                    }
-                                    else
-                                    {
-                                        temStatic = new StaffStatistics()
-                                        {
-                                            CalMonth = calMonth,
-                                            CalMonthId = calMonth.Id,
-                                            StaffId = itemStaff.DoPersonId,
-                                            totalBasePoint = handlerBasePoint * itemStaff.DoPerson.StaffGrade.Coefficient,
-                                            jxType = handlerJxType
-                                        };
-
-
-                                        itemStatistics.Add(temStatic);
-                                    }
-                                }
-                                else
-                                {
-                                    temStatic = new StaffStatistics()
-                                    {
-                                        CalMonth = calMonth,
-                                        CalMonthId = calMonth.Id,
-                                        StaffId = itemStaff.DoPersonId,
-                                        totalBasePoint = handlerBasePoint ,
-                                        jxType = handlerJxType
-                                    };
-
-
-                                    itemStatistics.Add(temStatic);
-                                }
-                            }
-                        }
-                        #endregion
-                    }
+                    List<StaffStatistics> itemStatistics = _calItemJX(calMonth, verifyCoefficients, item,Context);
 
                     List<StaffStatistics> temItemStatics;
 
@@ -633,7 +493,7 @@ namespace wispro.sp.api.Controllers
 
             }
 
-            if(userid != null)
+            if (userid != null)
             {
                 retList = retList.Where<StaffStatistics>(s => s.StaffId == userid.Value).ToList();
             }
@@ -645,7 +505,7 @@ namespace wispro.sp.api.Controllers
                 {
                     if (!staffXiShu.ContainsKey(ss.StaffId))
                     {
-                        staffXiShu.Add(ss.StaffId, DegreeOfDifficulty(calMonth.Year ,calMonth.Month, ss.StaffId));
+                        staffXiShu.Add(ss.StaffId, DegreeOfDifficulty(calMonth.Year, calMonth.Month, ss.StaffId));
                     }
 
                     ss.totalActuallyPoint = ss.totalBasePoint * staffXiShu[ss.StaffId] / gspjXS;
@@ -660,8 +520,171 @@ namespace wispro.sp.api.Controllers
 
 
             return retList;
+
+        }
+
+        private List<StaffStatistics> _calItemJX(CalMonth calMonth, List<VerifyCoefficient> verifyCoefficients, PerformanceItem item,spDbContext spDb)
+        {
+            System.Collections.Hashtable doPersonsBL = new System.Collections.Hashtable();
+
+            bool isPJFP = true;
+            double total = item.ItemStaffs.Count();
+            if (item.ItemStaffs.Where<ItemStaff>(p => p.PerformancePoint != null || p.PerformancePoint == 0).Count() > 0)
+            {
+                total = item.ItemStaffs.Select(i => i.PerformancePoint.Value).Sum();
+                isPJFP = false;
+            }
+
+            List<StaffStatistics> itemStatistics = new List<StaffStatistics>();
+
+            if (item.ReviewerId  != null)
+            {
+                item.Reviewer  = spDb.Staffs.Include(s => s.StaffGrade).FirstOrDefault(p => p.Id == item.ReviewerId);
+                //spDb.Entry(item.Reviewer).Reference(b => b.StaffGrade).Load();
+            }
+
+            foreach (ItemStaff itemStaff in item.ItemStaffs)
+            {
+                if(itemStaff.DoPerson == null)
+                {
+                    itemStaff.DoPerson = spDb.Staffs.Include(s=>s.StaffGrade).FirstOrDefault(p=>p.Id==itemStaff.DoPersonId);
+                }
+                //spDb.Entry(itemStaff).Reference(b => b.DoPerson).Load();
+                //spDb.Entry(itemStaff.DoPerson).Reference(b => b.StaffGrade).Load();
+
+                #region 计算审核人绩效点数,核稿人绩效点数按照核稿人与个处理人的核稿系数计算后加总,没有找到核稿系数(比如同级别),核稿系数为0
+                if (item.ReviewerId != null && item.Type != "专案")
+                {
+
+                    #region 取审核人等级审核等级系数
+                    VerifyCoefficient vcoefficient
+                        = verifyCoefficients.Where<VerifyCoefficient>(v =>
+                            v.CheckerId == item.Reviewer.StaffGrade.Id
+                            && v.DoPersonId == itemStaff.DoPerson.StaffGradeId)
+                    .FirstOrDefault<VerifyCoefficient>();
+                    #endregion
+
+                    if (vcoefficient != null)
+                    {
+                        double reviewerBasePoint = item.BasePoint.Value * vcoefficient.Coefficient;
+
+
+                        string temJxType = $"{item.Type}审核";
+
+                        var temReviewerStatic = itemStatistics.Where<StaffStatistics>(s => s.StaffId == item.ReviewerId && s.jxType == temJxType && s.CalMonth.Id == calMonth.Id).FirstOrDefault();
+                        if (temReviewerStatic != null)
+                        {
+                            temReviewerStatic.totalBasePoint += reviewerBasePoint;
+                        }
+                        else
+                        {
+                            if (item.Reviewer.IsOnJob && itemStaff.DoPerson.Status != "试用期")  //判断是否在职
+                            {
+                                temReviewerStatic = new StaffStatistics()
+                                {
+                                    CalMonth = calMonth,
+                                    CalMonthId = calMonth.Id,
+                                    StaffId = item.ReviewerId.Value,
+                                    totalBasePoint = reviewerBasePoint,
+                                    jxType = temJxType
+                                };
+
+                                itemStatistics.Add(temReviewerStatic);
+                            }
+                        }
+                    }
+                }
+                #endregion
+
+                #region 计算各处理人的绩效点数
+                double handlerBasePoint;
+                if (item.Type != "专案")
+                {
+                    if (isPJFP)
+                    {
+                        handlerBasePoint = item.BasePoint.Value * 1.0 / total;
+                    }
+                    else
+                    {
+                        handlerBasePoint = item.BasePoint.Value * itemStaff.PerformancePoint.Value / total;
+                    }
+                }
+                else
+                {
+                    handlerBasePoint = itemStaff.PerformancePoint.Value;
+                }
+
+                string handlerJxType = $"{item.Type}处理";
+                var temStatic = itemStatistics.Where<StaffStatistics>(s => s.StaffId == itemStaff.DoPersonId && s.jxType == handlerJxType && s.CalMonth.Id == calMonth.Id).FirstOrDefault();
+                if (temStatic != null)
+                {
+                    if (item.Type != "专案")
+                    {
+                        temStatic.totalBasePoint += handlerBasePoint * itemStaff.DoPerson.StaffGrade.Coefficient;
+                    }
+                    else
+                    {
+                        temStatic.totalBasePoint += handlerBasePoint;
+                    }
+                }
+                else
+                {
+                    if (itemStaff.DoPerson.StaffGrade != null && itemStaff.DoPerson.IsOnJob)
+                    {
+                        if (item.Type != "专案")
+                        {
+                            if (itemStaff.DoPerson.Status == "试用期" && item.Reviewer != null)
+                            {
+                                temStatic = new StaffStatistics()
+                                {
+                                    CalMonth = calMonth,
+                                    CalMonthId = calMonth.Id,
+                                    StaffId = item.Reviewer.Id,
+                                    totalBasePoint = handlerBasePoint * item.Reviewer.StaffGrade.Coefficient,
+                                    jxType = handlerJxType
+                                };
+
+
+                                itemStatistics.Add(temStatic);
+                            }
+                            else
+                            {
+                                temStatic = new StaffStatistics()
+                                {
+                                    CalMonth = calMonth,
+                                    CalMonthId = calMonth.Id,
+                                    StaffId = itemStaff.DoPersonId,
+                                    totalBasePoint = handlerBasePoint * itemStaff.DoPerson.StaffGrade.Coefficient,
+                                    jxType = handlerJxType
+                                };
+
+
+                                itemStatistics.Add(temStatic);
+                            }
+                        }
+                        else
+                        {
+                            temStatic = new StaffStatistics()
+                            {
+                                CalMonth = calMonth,
+                                CalMonthId = calMonth.Id,
+                                StaffId = itemStaff.DoPersonId,
+                                totalBasePoint = handlerBasePoint,
+                                jxType = handlerJxType
+                            };
+
+
+                            itemStatistics.Add(temStatic);
+                        }
+                    }
+                }
+                #endregion
+            }
+
+            return itemStatistics;
         }
 
+
         /// <summary>
         /// 计算指定用户,指定年月的绩效统计信息
         /// </summary>
@@ -723,55 +746,198 @@ namespace wispro.sp.api.Controllers
 
             return str;
         }
+
+        [HttpGet,HttpPost]
+        public FileProcessTask ExportData(QueryFilter queryFilter)
+        {
+            var filename = $"{DateTime.Now.ToString("yyyyMMddhhmmss")}-绩效数据下载.xlsx";
+            var attachfileSavePath = utility.ConfigHelper.GetSectionValue("AttachFileSavePath");
+            var filePath = Path.Combine(attachfileSavePath, filename);
+
+            var fileTask = new FileProcessTask()
+            {
+                Id = Guid.NewGuid().ToString(),
+                FileName = filename,
+                FilePath = filePath,
+                Processed = 0
+            };
+
+            fileTaskService.Add(fileTask);
+            ThreadObject threadObject = new ThreadObject()
+            {
+                queryFilter = queryFilter,
+                fileTask = fileTask
+            };
+
+            System.Threading.Thread t = new System.Threading.Thread(new ParameterizedThreadStart(ExportDataThread));
+            t.Start(threadObject);
+
+            return fileTask;
+        }
+
+        internal class ThreadObject
+        {
+            public QueryFilter queryFilter { get; set; }
+            public FileProcessTask fileTask { get; set; }
+        }
         
-        [HttpPost]
-        public ListApiResponse<PerformanceItem> QueryFilter(QueryFilter queryFilter)
+        private void ExportDataThread(object  tObj)
         {
+            QueryFilter queryFilter = ((ThreadObject)tObj).queryFilter;
+            FileProcessTask fileTask = ((ThreadObject)tObj).fileTask;
 
-            ListApiResponse<PerformanceItem> ret = new ListApiResponse<PerformanceItem>();
+            IQueryable<PerformanceItem> response = NewMethod(queryFilter);
+
+            var retList = response
+                .Include(p=>p.Customer)
+                .Include(p=>p.ItemStaffs).ThenInclude(p=>p.DoPerson).ThenInclude(p=>p.StaffGrade)
+                .Include(p=>p.Reviewer).ThenInclude(p=>p.StaffGrade)
+                .Include(p=>p.PreOastaff)
+                .Include(p=>p.CalMonth)
+                .ToList<PerformanceItem>();
 
-            string strExpress = "";
             
 
-            if (!string.IsNullOrEmpty(strExpress))
-            {
-                strExpress = $"{strExpress} && s.CalMonth.Status == {Convert.ToInt32(queryFilter.jxType)}";
-            }
-            else
-            {
-                strExpress = $"s.CalMonth.Status == {Convert.ToInt32(queryFilter.jxType)}";
-            }
+            DataTable dt = new DataTable();
+            #region 添加栏位
+            dt.Columns.Add("我方文号",typeof(string));
+            dt.Columns.Add("申请类型", typeof(string));
+            dt.Columns.Add("业务类型", typeof(string));
+            dt.Columns.Add("备注(填表注意事项)", typeof(string));
+            dt.Columns.Add("处理事项", typeof(string));
+            dt.Columns.Add("案件阶段", typeof(string));
+            dt.Columns.Add("案件系数", typeof(string));
+            dt.Columns.Add("处理事项系数", typeof(string));
+            dt.Columns.Add("前一次OA处理事项系数", typeof(string));
+            dt.Columns.Add("前一次OA处理人", typeof(string));
+            dt.Columns.Add("处理人等级", typeof(string));
+            dt.Columns.Add("基本点数", typeof(string));
+            dt.Columns.Add("核稿系数", typeof(string));
+            dt.Columns.Add("核稿绩效", typeof(string));
+            dt.Columns.Add("处理人", typeof(string));
+            dt.Columns.Add("核稿人", typeof(string));
+            dt.Columns.Add("客户名称", typeof(string));
+            dt.Columns.Add("申请人", typeof(string));
+            dt.Columns.Add("处理事项完成日", typeof(string));
+            dt.Columns.Add("定稿日", typeof(string));
+            dt.Columns.Add("返稿日", typeof(string));
+            dt.Columns.Add("案件类型", typeof(string));
+            dt.Columns.Add("案件状态", typeof(string));
+            dt.Columns.Add("处理事项备注", typeof(string));
+            dt.Columns.Add("处理状态", typeof(string));
+            dt.Columns.Add("案件名称", typeof(string));
+            dt.Columns.Add("委案日期", typeof(string));
+            dt.Columns.Add("客户期限", typeof(string));
+            dt.Columns.Add("内部期限", typeof(string));
+            dt.Columns.Add("初稿日", typeof(string));
+            dt.Columns.Add("备注(发文严重超期是否属客观原因,若为否,请填写原因)", typeof(string));
+            dt.Columns.Add("备注", typeof(string));
+            #endregion
 
-            if (queryFilter.ConditionTree != null)
+            List<VerifyCoefficient> verifyCoefficients = new spDbContext().VerifyCoefficients.ToList();
+            fileTask.Size = retList.Count;
+
+            foreach (var item in retList)
             {
-                string strTem = GetExpress(queryFilter.ConditionTree);
+                fileTask.Processed += 1;
 
-                if (!string.IsNullOrEmpty(strTem))
+                if (item.CaseNo.StartsWith("J"))
                 {
-                    strExpress = $"{strExpress} && ({strTem})";
+                    continue;
                 }
-            }
 
-            
+                try
+                {
 
-            var interpreter = new Interpreter();
-            Expression<Func<PerformanceItem, bool>> dynamicWhere = interpreter.ParseAsExpression<Func<PerformanceItem, bool>>(strExpress, "s");
+                    if (item.CaseNo == "")
+                    {
+                        System.Diagnostics.Debug.WriteLine(item.CaseNo);
+                    }
+                    var row = dt.NewRow();
+                    row["我方文号"] = item.CaseNo;
+                    row["申请类型"] = item.ApplicationType;
+                    row["业务类型"] = item.BusinessType;
+                    row["备注(填表注意事项)"] = item.AgentFeedbackMemo;
+                    row["处理事项"] = item.DoItem;
+                    row["案件阶段"] = item.CaseStage;
+                    row["案件系数"] = item.CaseCoefficient;
+                    row["处理事项系数"] = item.DoItemCoefficient;
+                    row["前一次OA处理事项系数"] = "";
+
+                    if (item.PreOastaffId.HasValue)
+                    {
+                        row["前一次OA处理人"] = item.PreOastaff?.Name;
+                    }
 
-            IQueryable<PerformanceItem> response;
-            if (queryFilter.userId > 0)
-            {
-                response = Context.PerformanceItems.Where<PerformanceItem>(dynamicWhere).Where(s => (s.ItemStaffs.Where<ItemStaff>(iStaff => iStaff.DoPerson.Id == queryFilter.userId).Count() > 0));// || s.ReviewerId == queryFilter.userId));
+                    string strISLevels = "";
+                    string strISNames = "";
 
-            }
-            else
-            {
-                 response = Context.PerformanceItems.Where<PerformanceItem>(dynamicWhere);
+                    foreach (var istaff in item.ItemStaffs)
+                    {
+                        strISLevels = string.IsNullOrEmpty(strISLevels) ? istaff.DoPerson.StaffGrade.Grade : $"{strISLevels},{istaff.DoPerson.StaffGrade.Grade}";
+                        strISNames = string.IsNullOrEmpty(strISNames) ? istaff.DoPerson.Name : $"{strISNames},{istaff.DoPerson.Name}";
+                    }
+
+                    row["处理人等级"] = strISLevels;
+                    row["基本点数"] = item.BasePoint;
+                    row["处理人"] = strISNames;
+                    row["核稿人"] = item.Reviewer?.Name;
+
+                    if (item.ReviewerId != null && item.BasePoint.HasValue)
+                    {
+                        var jxList = _calItemJX(item.CalMonth, verifyCoefficients, item, new spDbContext());
+
+                        row["核稿系数"] = "";
+                        var temJx = jxList.FirstOrDefault<StaffStatistics>(s => s.jxType.Contains("审核") && s.StaffId == item.ReviewerId);
+                        if (temJx != null)
+                        {
+                            row["核稿绩效"] = temJx.totalBasePoint;
+                        }
+                    }
 
+                    row["客户名称"] = item.Customer?.Name;
+                    row["申请人"] = item.ApplicationName;
+                    row["处理事项完成日"] = item.FinishedDate?.ToString("yyyy-MM-dd");
+                    row["定稿日"] = item.FinalizationDate?.ToString("yyyy-MM-dd");
+                    row["返稿日"] = item.ReturnDate?.ToString("yyyy-MM-dd");
+                    row["案件类型"] = item.CaseType;
+                    row["案件状态"] = item.CaseState;
+                    row["处理事项备注"] = item.DoItemState;
+                    row["处理状态"] = item.DoItemState;
+                    row["案件名称"] = item.CaseName;
+                    row["委案日期"] = item.EntrustingDate?.ToString("yyyy-MM-dd");
+                    row["客户期限"] = item.CustomerLimitDate?.ToString("yyyy-MM-dd");
+                    row["内部期限"] = item.InternalDate?.ToString("yyyy-MM-dd"); ;
+                    row["初稿日"] = item.FirstDraftDate?.ToString("yyyy-MM-dd");
+                    row["备注(发文严重超期是否属客观原因,若为否,请填写原因)"] = item.OverDueMemo;
+                    row["备注"] = item.DoItemMemo;
+
+                    dt.Rows.Add(row);
+                }
+                catch(Exception ex)
+                {
+                    throw ex;
+                }
             }
+           
+            utility.NPOIExcel.DataTableToExcel(dt,fileTask.FilePath);
+
+
+            fileTask.Finished = true;
+        }
+
+        [HttpPost]
+        public ListApiResponse<PerformanceItem> QueryFilter(QueryFilter queryFilter)
+        {
+
+            ListApiResponse<PerformanceItem> ret = new ListApiResponse<PerformanceItem>();
+
+            IQueryable<PerformanceItem> response = NewMethod(queryFilter);
 
             int totals = response.ToList<PerformanceItem>().Count;
 
-            if (totals > 0 && totals < (queryFilter.PageIndex - 1) * queryFilter.PageSize) {
+            if (totals > 0 && totals < (queryFilter.PageIndex - 1) * queryFilter.PageSize)
+            {
                 response = response
                     .Include(pi => pi.ItemStaffs).ThenInclude(iStaff => iStaff.DoPerson)
                     .Include(pi => pi.Reviewer)
@@ -792,7 +958,7 @@ namespace wispro.sp.api.Controllers
             }
             ret.TotalCount = totals;
 
-            
+
 
             var retList = response.ToList<PerformanceItem>();
 
@@ -831,7 +997,49 @@ namespace wispro.sp.api.Controllers
 
             return ret;
         }
-        
+
+        private IQueryable<PerformanceItem> NewMethod(QueryFilter queryFilter)
+        {
+            string strExpress = "";
+
+
+            if (!string.IsNullOrEmpty(strExpress))
+            {
+                strExpress = $"{strExpress} && s.CalMonth.Status == {Convert.ToInt32(queryFilter.jxType)}";
+            }
+            else
+            {
+                strExpress = $"s.CalMonth.Status == {Convert.ToInt32(queryFilter.jxType)}";
+            }
+
+            if (queryFilter.ConditionTree != null)
+            {
+                string strTem = GetExpress(queryFilter.ConditionTree);
+
+                if (!string.IsNullOrEmpty(strTem))
+                {
+                    strExpress = $"{strExpress} && ({strTem})";
+                }
+            }
+
+            var interpreter = new Interpreter();
+            Expression<Func<PerformanceItem, bool>> dynamicWhere = interpreter.ParseAsExpression<Func<PerformanceItem, bool>>(strExpress, "s");
+
+            IQueryable<PerformanceItem> response;
+            if (queryFilter.userId > 0)
+            {
+                response = new spDbContext().PerformanceItems.Where<PerformanceItem>(dynamicWhere).Where(s => (s.ItemStaffs.Where<ItemStaff>(iStaff => iStaff.DoPerson.Id == queryFilter.userId).Count() > 0));// || s.ReviewerId == queryFilter.userId));
+
+            }
+            else
+            {
+                response = new spDbContext().PerformanceItems.Where<PerformanceItem>(dynamicWhere);
+
+            }
+
+            return response;
+        }
+
         public ApiSaveResponse AddProjectPerformance(ProjectPointRecord pointRecord)
         {
             ApiSaveResponse retResponse = new ApiSaveResponse();

+ 1 - 1
wispro.sp.api/Job/GetPerformanceItemJob.cs

@@ -16,7 +16,7 @@ namespace wispro.sp.api.Job
             string DoItem = context.JobDetail.JobDataMap.Get("DoItem").ToString();
             string caseStage = context.JobDetail.JobDataMap.Get("CaseStage").ToString();
 
-            new PerformanceItemController(new spDbContext()).GetItemInfoByCaseStage(CaseNo,DoItem,caseStage);
+            _ = new PerformanceItemController(new spDbContext(),new Services.FileTaskCacheService()).GetItemInfoByCaseStage(CaseNo, DoItem, caseStage);
             return Task.CompletedTask;
         }
     }

+ 1 - 1
wispro.sp.api/Job/ImportReportJob.cs

@@ -313,7 +313,7 @@ namespace wispro.sp.api.Job
             try
             {
                 Utility.Utility.CalBasePoint(item, rules);
-                var ret= new Controllers.PerformanceItemController(spDb).New(item);
+                var ret= new Controllers.PerformanceItemController(spDb,new Services.FileTaskCacheService()).New(item);
                 if (ret.Success == false)
                 {
                     System.Diagnostics.Debug.WriteLine(ret.ErrorMessage);

+ 15 - 14
wispro.sp.api/Job/UpdateJXDataFromIPEasyJob.cs

@@ -194,26 +194,27 @@ namespace wispro.sp.api.Job
                             Item.CaseType = retObj.CaseType;
                         }
 
-                        if (Item.FinishedDate.HasValue && 
-                            Item.FinishedDate.Value.ToString("yyyy-MM") != DateTime.Parse($"{Item.CalMonth.Year}-{Item.CalMonth.Month}-01").ToString("yyyy-MM"))
-                        {
-                            var ItemStaffs = spDb.ItemStaffs.Where(p => p.ItemId == Item.Id).ToList();
-                            foreach(var itemstaff in ItemStaffs)
-                            {
-                                spDb.Remove(itemstaff);
-                            }
-                            spDb.PerformanceItems.Remove(Item);
-                            spDb.SaveChanges();
+                        //if (Item.FinishedDate.HasValue && 
+                        //    Item.FinishedDate.Value.ToString("yyyy-MM") != DateTime.Parse($"{Item.CalMonth.Year}-{Item.CalMonth.Month}-01").ToString("yyyy-MM"))
+                        //{
+                        //    //删除完成日变成下一个月的记录
+                        //    var ItemStaffs = spDb.ItemStaffs.Where(p => p.ItemId == Item.Id).ToList();
+                        //    foreach(var itemstaff in ItemStaffs)
+                        //    {
+                        //        spDb.Remove(itemstaff);
+                        //    }
+                        //    spDb.PerformanceItems.Remove(Item);
+                        //    spDb.SaveChanges();
 
-                        }
-                        else
-                        {
+                        //}
+                        //else
+                        //{
                             if (spDb.Entry(Item).State != EntityState.Unchanged)
                             {
                                 Utility.Utility.CalBasePoint(Item, spDb.BasePointRules.ToList());
                                 spDb.SaveChanges();
                             }
-                        }
+                        //}
                     }
                     catch(Exception ex)
                     {

+ 64 - 0
wispro.sp.api/Services/FileTaskCacheService.cs

@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.share;
+
+namespace wispro.sp.api.Services
+{
+    public interface IFileTaskService
+    {
+        public share.FileProcessTask Get(string Id);
+
+        public bool Add(share.FileProcessTask processTask);
+
+        public bool Remove(string Id);
+    }
+
+    public class FileTaskCacheService : IFileTaskService
+    {
+        List<share.FileProcessTask> lstFileTask = new List<FileProcessTask>();
+
+        public bool Add(FileProcessTask processTask)
+        {
+            if(processTask != null)
+            {
+                var temObj = lstFileTask.FirstOrDefault(s=>s.Id == processTask.Id);
+
+                if(temObj == null)
+                {
+                    lstFileTask.Add(processTask);
+
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        public FileProcessTask Get(string Id)
+        {
+            var temObj = lstFileTask.FirstOrDefault(s => s.Id == Id);
+
+            return temObj;
+        }
+
+        public bool Remove(string Id)
+        {
+            var temObj = lstFileTask.FirstOrDefault(s => s.Id == Id);
+
+            if (temObj == null)
+            {
+                lstFileTask.Remove(temObj);
+
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+
+           
+        }
+    }
+}

+ 3 - 0
wispro.sp.api/Startup.cs

@@ -13,6 +13,7 @@ using System;
 using System.Text;
 using System.Text.Json.Serialization;
 using wispro.sp.api.Job;
+using wispro.sp.api.Services;
 
 namespace wispro.sp.api
 {
@@ -68,6 +69,8 @@ namespace wispro.sp.api
 
             services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
 
+            services.AddSingleton<IFileTaskService, FileTaskCacheService>();
+
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

+ 23 - 0
wispro.sp.share/FileProcessTask.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.share
+{
+    public class FileProcessTask
+    {
+        public string Id { get; set; }
+
+        public string FileName { get; set; }
+
+        public string FilePath { get; set; }
+
+        public int Size { get; set; }
+
+        public int Processed { get; set; }
+
+        public bool Finished { get; set; }
+    }
+}

+ 1 - 0
wispro.sp.web/Components/FlowChart.razor.cs

@@ -56,6 +56,7 @@ namespace wispro.sp.web.Components
         {
             Refresh();
         }
+        
 
         public void Refresh()
         {

+ 9 - 0
wispro.sp.web/Components/WatingDownload.razor

@@ -0,0 +1,9 @@
+@inherits FeedbackComponent<share.FileProcessTask>
+
+<div>
+    @if (processTask.Finished) { 
+
+    }
+    else{
+    }
+</div>

+ 35 - 0
wispro.sp.web/Components/WatingDownload.razor.cs

@@ -0,0 +1,35 @@
+using AntDesign;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Components
+{
+    public partial class WatingDownload
+    {
+        private share.FileProcessTask processTask;
+        private IFeedbackRef feedbackRef;
+
+        protected override  Task OnInitializedAsync()
+        {
+            processTask = base.Options ?? new share.FileProcessTask();
+            base.OnInitialized();
+            feedbackRef = base.FeedbackRef;
+            return base.OnInitializedAsync();
+        }
+
+        string _ErrorMessage;
+
+        private async void OnFinish()
+        {
+            await base.OnFeedbackOkAsync(new ModalClosingEventArgs() { Cancel = true });
+        }
+
+        private void OnCancel()
+        {
+            base.OnFeedbackCancelAsync(new ModalClosingEventArgs() { Cancel = true });
+            //_ = feedbackRef.CloseAsync();
+        }
+    }
+}

+ 12 - 2
wispro.sp.web/Pages/AppCase/MyCaselist.razor

@@ -35,14 +35,22 @@
                         <PageHeaderTitle>基础点数统计</PageHeaderTitle>
                         <PageHeaderExtra>
                             <AuthorizeView Roles="@strAddProjectJX">
-                                
-                            <Button Type="@ButtonType.Primary" OnClick="()=>goAssignPoint()">添加项目绩效</Button>
+
+                                <Button Type="@ButtonType.Primary" OnClick="()=>goAssignPoint()">添加项目绩效</Button>
                             </AuthorizeView>
                             @foreach (AppealType at in apTypeService.GetItems(1))
                             {
                                 <Button Type="@ButtonType.Primary" OnClick="()=>ShowModel(null,at)">@at.Name</Button>
                             }
 
+                            @if (isDownloading)
+                            {
+                                <Button Icon="download" Type="@ButtonType.Text" Loading>导出</Button>
+                            }
+                            else
+                            {
+                                <Button Icon="download" Type="@ButtonType.Text" OnClick="() => ExportDataAsync(jxType.doing)">导出</Button>
+                            }
                         </PageHeaderExtra>
                         <PageHeaderContent>
                             <div style="border:1px solid #000000">
@@ -284,3 +292,5 @@
 </style>
 
 
+
+

+ 39 - 14
wispro.sp.web/Pages/AppCase/MyCaselist.razor.cs

@@ -4,6 +4,8 @@ using AntDesign.TableModels;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Components;
 using Microsoft.AspNetCore.Components.Web;
+using Microsoft.Extensions.Configuration;
+using Microsoft.JSInterop;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -33,15 +35,15 @@ namespace wispro.sp.web.Pages.AppCase
             new() { Text = "C", Value = "C" },
             new() { Text = "D", Value = "D" }
         };
-        
+
         [Inject]
         protected AppealTypeService apTypeService { get; set; }
 
         private List<PerformanceItem> _Datas;
         private List<StaffStatistics> MyStatistics;
-        IEnumerable<PerformanceItem> selectedItems= new List<PerformanceItem>();
+        IEnumerable<PerformanceItem> selectedItems = new List<PerformanceItem>();
         private CalMonth HandlingCalMonth;
-        
+
 
         int _pageIndex = 1;
         int _pageSize = 10;
@@ -51,7 +53,7 @@ namespace wispro.sp.web.Pages.AppCase
         bool _visible = false;
         bool _isAdd = false;
 
-        List<TabPaneItem> tabList = new List<TabPaneItem>() { 
+        List<TabPaneItem> tabList = new List<TabPaneItem>() {
             new TabPaneItem(){ Key ="myList", Tab ="本月待确认绩效" },
             new TabPaneItem(){  Key ="myAll", Tab ="往期已计算绩效"},
         };
@@ -67,13 +69,13 @@ namespace wispro.sp.web.Pages.AppCase
         private bool isFirstInit = true;
         private Table<PerformanceItem> table;
         private CurrentUser _user;
-        private  string strAddProjectJX ="";
+        private string strAddProjectJX = "";
         protected async override Task OnInitializedAsync()
         {
             if (isFirstInit)
             {
                 var Roles = await _authService.GetRoles("AddProjectJX");
-                foreach(var role in Roles)
+                foreach (var role in Roles)
                 {
                     strAddProjectJX = (string.IsNullOrEmpty(strAddProjectJX)) ? role : $"{strAddProjectJX},{role}";
                 }
@@ -87,7 +89,7 @@ namespace wispro.sp.web.Pages.AppCase
 
             isFirstInit = false;
             await apTypeService.GetItems();
-            _user =await _userService.GetUser();
+            _user = await _userService.GetUser();
             StateHasChanged();
         }
 
@@ -106,10 +108,10 @@ namespace wispro.sp.web.Pages.AppCase
                     NavigationManager.NavigateTo("/LoginPages");
                 }
             }
-            
+
         }
 
-        private string GetStatistics(string strType,bool isBasePoint=false)
+        private string GetStatistics(string strType, bool isBasePoint = false)
         {
             try
             {
@@ -140,7 +142,7 @@ namespace wispro.sp.web.Pages.AppCase
                             return "";
                         }
                     }
-                    
+
                 }
                 else
                 {
@@ -182,7 +184,7 @@ namespace wispro.sp.web.Pages.AppCase
             if (_CurrentKey == tabList[0].Key)
             {
                 _loading = true;
-                
+
                 var data = await _ItemService.Query(_user.Userid.Value, jxType.doing, queryModel);
 
                 _Datas = data.Results;
@@ -201,9 +203,31 @@ namespace wispro.sp.web.Pages.AppCase
                 StateHasChanged();
             }
 
-            
+
         }
 
+        [Inject] IJSRuntime JSRuntime { get; set; }
+
+        [Inject] IConfiguration _configuration { get; set; }
+
+        bool isDownloading = false;
+        private async Task ExportDataAsync(jxType jxType)
+        {
+            isDownloading = true;
+            var fileData =await  _ItemService.ExportData(_user.Userid.Value, jxType);
+
+            while(!fileData.Finished)
+            {
+                fileData =await  _ItemService.getExportDataProcessing(fileData.Id);
+                await Task.Delay(20);
+            }
+
+            NavigationManager.NavigateTo($"{_configuration.GetValue<string>("APIUrl")}FileProcesTask/Download?Id={fileData.Id}");
+
+            isDownloading = false;
+
+        } 
+
         private void OnsubShensu(PerformanceItem Item)
         {
             EditingItem = Item;
@@ -233,9 +257,10 @@ namespace wispro.sp.web.Pages.AppCase
             {
 
                 var respone =await _ItemService.SaveFieldChange(EditingItem.Id, strAgentFeedbackMemo, EditingItem.AgentFeedbackMemo);
-                EditingItem = await _ItemService.GetPerformancItem(EditingItem.Id) ;
+                var item = await _ItemService.GetPerformancItem(EditingItem.Id) ;
+                EditingItem.BasePoint = item.BasePoint;
                 _ = RefreshMyStatistics();
-                StateHasChanged();
+                
                 EditingItem = null;
                 //table.ReloadData();
             }

+ 13 - 12
wispro.sp.web/Pages/Welcome.razor

@@ -21,28 +21,29 @@
                     @(_CurrentUser.Name)好, 祝您一天愉快!
                 </div>
                 <div>
-                    合伙人 | 深圳威世博代理事务所 | 工作地:深圳
+                    
+                    深圳威世博代理事务所 | 工作地:深圳
                 </div>
                 }
             </div>
         </div>
     </Content>
     <ExtraContent>
-        <div class="extraContent">
+        @if (HandlingMonth != null)
+        {
             <div class="statItem">
-                <Statistic Title="@("当月绩效数据")" Value="12" />
-            </div>
-            <div class="statItem">
-                <Statistic Title="@("本月绩效排名")" Value="3" Suffix="@("/ 280")" />
-            </div>
-            <div class="statItem">
-                <Statistic Title="@("总绩效数据")" Value="2223" />
+                <span>【@HandlingMonth.Year-@HandlingMonth.Month】月数据正在处理中,您有<a href="/MyCaseList">@waitingHandleItems</a>笔绩效数据需要处理!</span>
             </div>
+
+        }
+
+        <div class="statItem">
+            <span>您的总绩效数据有:<a href="/MyCaseList">@allItems </a> </span>
         </div>
     </ExtraContent>
     <ChildContent>
         <Row Gutter="24">
-            <AntDesign.Col Xl="16" Lg="24" Md="24" Sm="24" Xs="24">
+            <AntDesign.Col Xl="24" Lg="24" Md="24" Sm="24" Xs="24">
                 <Card BodyStyle="padding: 0px;"
                       Class="activeCard"
                       Title="信息动态">
@@ -89,14 +90,14 @@
                     </AntList>
                 </Card>
             </AntDesign.Col>
-            <AntDesign.Col Xl="8" Lg="24" Md="24" Sm="24" Xs="24">
+            @*<AntDesign.Col Xl="8" Lg="24" Md="24" Sm="24" Xs="24">
                 <Card Style="margin-bottom: 24px;"
                       Title="绩效数据统计">
                     <div class="chart">
                         <wispro.sp.web.Components.Radar HasLegend="false" />
                     </div>
                 </Card>
-            </AntDesign.Col>
+            </AntDesign.Col>*@
         </Row>
     </ChildContent>
 </PageContainer>

+ 25 - 52
wispro.sp.web/Pages/Welcome.razor.cs

@@ -8,6 +8,7 @@ using wispro.sp.entity;
 using System.Text.Json;
 using AntDesign;
 using System;
+using wispro.sp.share;
 
 namespace wispro.sp.web.Pages
 {
@@ -37,47 +38,41 @@ namespace wispro.sp.web.Pages
 
         [Inject] MessageService _msgService { get; set; }
         private Models.CurrentUser _user;
+        [Inject] PerformanceItemServices _ItemService { get; set; }
+
+        [Inject] CalMonthServices CalMonthServices { get; set; }
+
+        int waitingHandleItems = 0;
+        int allItems = 0;
         
+        CalMonth HandlingMonth = null;
 
         protected override async System.Threading.Tasks.Task OnInitializedAsync()
         {
             await base.OnInitializedAsync();
             _CurrentUser =await _userService.GetUser();
+            //_user = _CurrentUser;
 
+            HandlingMonth = await CalMonthServices.GetHandlingMonth();
 
-            if (_CurrentUser != null)
+            if (HandlingMonth != null)
             {
-                //_projectNotice = await ProjectService.GetProjectNoticeAsync();
-                //_activities = await ProjectService.GetActivitiesAsync();
-                AppealRecords = await _atService.GetUserAppeals(_CurrentUser.Userid);
-                if (AppealRecords != null)
-                {
-                    //try
-                    //{
-                    //    //_user = await _userService.GetUser();
-                    //    //AppealRecords.Sort((a, b) =>
-                    //    //{
-                    //    //    var sd = (a.ReviewTime == null) ? a.ReviewTime : a.CreateTime;
-                    //    //    var ed = (b.ReviewTime == null) ? b.ReviewTime : b.CreateTime;
-
-                    //    //    if (ed > sd)
-                    //    //    {
-                    //    //        return 1;
-                    //    //    }
-                    //    //    else
-                    //    //    {
-                    //    //        return -1;
-                    //    //    }
-
-                    //    //});
-                    //}
-                    //catch { }
-                }
+                //Console.WriteLine(System.Text.Json.JsonSerializer.Serialize())
+                
+                var data = await _ItemService.Query(_CurrentUser.Userid.Value, jxType.doing
+                    ,null);
+                waitingHandleItems = data.TotalCount;
             }
-            else
+
+            var data1 = await _ItemService.GetMyList(_CurrentUser.Userid.Value, jxType.all);
+            allItems = data1.TotalCount;
+
+            if (_CurrentUser != null)
             {
-                //NavigationManager.
+                AppealRecords = await _atService.GetUserAppeals(_CurrentUser.Userid);
+                
             }
+            
 
             StateHasChanged();
             
@@ -99,7 +94,7 @@ namespace wispro.sp.web.Pages
 
 
             _modalRef = await _ModalService
-                .CreateModalAsync<Components.ReviewerAppeal, Models.ReviewerAppealModel>(modalConfig, templateOptions);
+                .CreateModalAsync<ReviewerAppeal, Models.ReviewerAppealModel>(modalConfig, templateOptions);
 
             _modalRef.OnOpen = () =>
             {
@@ -115,28 +110,6 @@ namespace wispro.sp.web.Pages
                     await _modalRef.CloseAsync();
 
                     AppealRecords = await _atService.GetUserAppeals(_CurrentUser.Userid);
-                    //AppealRecords.Sort((a, b) =>
-                    //{
-                    //    try
-                    //    {
-                    //        var sd = (a.ReviewTime == null) ? a.ReviewTime : a.CreateTime;
-                    //        var ed = (b.ReviewTime == null) ? b.ReviewTime : b.CreateTime;
-
-                    //        if (ed > sd)
-                    //        {
-                    //            return 1;
-                    //        }
-                    //        else
-                    //        {
-                    //            return -1;
-                    //        }
-                    //    }
-                    //    catch
-                    //    {
-                    //        return 0;
-                    //    }
-
-                    //});
 
                     StateHasChanged();
 

+ 4 - 1
wispro.sp.web/Pages/Workflow/WorkflowDefine.razor.cs

@@ -41,12 +41,15 @@ namespace wispro.sp.web.Pages.Workflow
 
         [Inject] protected NavigationManager navigation { get; set; }
 
+
         protected override async System.Threading.Tasks.Task OnInitializedAsync()
         {
             await base.OnInitializedAsync();
             workflows = await workflowService.getAllWorkflows();
         }
 
+
+
         private void AddNew()
         {
             isAdd = true;
@@ -73,7 +76,7 @@ namespace wispro.sp.web.Pages.Workflow
 
                     workflows = await workflowService.getAllWorkflows();
                     _visible = false;
-                    StateHasChanged();
+                    //StateHasChanged();
                 }
                 else
                 {

+ 2 - 2
wispro.sp.web/Pages/Workflow/WorkflowDetail.razor.cs

@@ -131,7 +131,7 @@ namespace wispro.sp.web.Pages.Workflow
                 ActionModalShow = true;
             }
             Console.WriteLine($"BeginEditAction-End:{System.Text.Json.JsonSerializer.Serialize(EditAction)}");
-            StateHasChanged();
+            //StateHasChanged();
         }
 
         void OnDblClickTransfer(entity.workflowDefine.TrasferCondition transfer)
@@ -333,7 +333,7 @@ namespace wispro.sp.web.Pages.Workflow
         {
             chart.Refresh();
 
-            StateHasChanged();
+            //StateHasChanged();
         }
 
         [Inject] ModalService _modalService { get; set; }

+ 57 - 1
wispro.sp.web/Services/HttpService.cs

@@ -22,6 +22,8 @@ namespace wispro.sp.web.Services
     {
         Task<T> Get<T>(string uri);
         Task<T> Post<T>(string uri, object value);
+
+        Task<byte[]> Post(string uri, object value);
     }
 
     public class HttpService:IHttpService
@@ -50,7 +52,6 @@ namespace wispro.sp.web.Services
 
         public async Task<T> Get<T>(string uri)
         {
-            
             var request = new HttpRequestMessage(HttpMethod.Get, $"{_configuration.GetValue<string>("APIUrl")}{uri}");
             return await sendRequest<T>(request);
         }
@@ -62,6 +63,61 @@ namespace wispro.sp.web.Services
             return await sendRequest<T>(request);
         }
 
+        public async Task<byte[]> Post(string uri, object value)
+        {
+            var request = new HttpRequestMessage(HttpMethod.Post, $"{_configuration.GetValue<string>("APIUrl")}{uri}");
+            //request.Headers.Add("Content-Type", "application/json");
+            request.Content = new StringContent(JsonSerializer.Serialize(value), Encoding.UTF8, "application/json");
+            var data =await snedRequestNotReturn(request);
+
+            return data;
+
+        }
+
+        private async Task<byte[]> snedRequestNotReturn(HttpRequestMessage request)
+        {
+            // add jwt auth header if user is logged in and request is to the api url
+            try
+            {
+                var user = await _localStorageService.GetItemAsync<userToken>("authToken");
+                var isApiUrl = !request.RequestUri.IsAbsoluteUri;
+
+                if (user != null) // && isApiUrl)
+                {
+                    //request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", user.Token);
+
+                    //將token取出轉為claim
+                    var claims = JwtParser.ParseClaimsFromJwt(user.Token);
+
+                    //在每次request的header中帶入bearer token
+                    _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", user.Token);
+                }
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(ex.ToString());
+            }
+
+            using HttpResponseMessage response = await _httpClient.SendAsync(request);
+
+            // auto logout on 401 response
+            if (response.StatusCode == HttpStatusCode.Unauthorized)
+            {
+                _httpClient.DefaultRequestHeaders.Authorization = null;
+                await _localStorageService.RemoveItemAsync("authToken");
+                ((JwtAuthenticationStateProvider)authenticationStateProvider).NotifyUserLogOut();
+            }
+
+            // throw exception on error response
+            if (!response.IsSuccessStatusCode)
+            {
+                //var error = await response.Content.ReadFromJsonAsync<Dictionary<string, string>>();
+                throw new Exception("Error");
+            }
+
+            return await response.Content.ReadAsByteArrayAsync();
+        }
+
         private async Task<T> sendRequest<T>(HttpRequestMessage request)
         {
             // add jwt auth header if user is logged in and request is to the api url

+ 101 - 61
wispro.sp.web/Services/PerformanceItemServices.cs

@@ -48,84 +48,120 @@ namespace wispro.sp.web.Services
             return data;
         }
 
-        public async Task<ListApiResponse<PerformanceItem>> Query(int userid, jxType type, QueryModel<PerformanceItem> queryModel)
+        public async Task<FileProcessTask> ExportData(int userid, jxType jxType)
         {
             QueryFilter query = new QueryFilter();
             query.userId = userid;
-            query.jxType = type;
-            query.PageIndex = queryModel.PageIndex;
-            query.PageSize = queryModel.PageSize;
+            query.jxType = jxType;
 
+            query.PageIndex = 1;
+            query.PageSize = 1;
             query.ConditionTree = new List<FieldCondition>();
+            query.Sorts = new List<OrderField>();
+
+            var fileData = await  _httpClient.Post<FileProcessTask>($"PerformanceItem/ExportData", query);
+
+            return fileData;
+        }
+
+        public async Task<FileProcessTask> getExportDataProcessing(string id)
+        {
+            var fileData = await _httpClient.Get<FileProcessTask>($"FileProcesTask/Get?Id={id}");
+
+            return fileData;
+        }
+
+        public async Task<ListApiResponse<PerformanceItem>> Query(int userid, jxType type, QueryModel<PerformanceItem> queryModel)
+        {
+            QueryFilter query = new QueryFilter();
+            query.userId = userid;
+            query.jxType = type;
 
-            foreach(var filter in queryModel.FilterModel)
+            if (queryModel != null)
             {
-                foreach(var f in filter.Filters)
+
+                query.PageIndex = queryModel.PageIndex;
+                query.PageSize = queryModel.PageSize;
+
+                query.ConditionTree = new List<FieldCondition>();
+
+                foreach (var filter in queryModel.FilterModel)
                 {
-                    FieldCondition condition = new FieldCondition() { FieldName = filter.FieldName};
-                    condition.Value = f.Value.ToString();
-                    condition.ValueType = typeof(PerformanceItem).GetProperty(filter.FieldName).PropertyType.ToString();
-                    switch (f.FilterCompareOperator)
+                    foreach (var f in filter.Filters)
                     {
-                        case AntDesign.TableFilterCompareOperator.Contains:
-                            condition.Operator = OperatorEnum.Contains;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.EndsWith:
-                            condition.Operator = OperatorEnum.EndWith;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.Equals:
-                            condition.Operator = OperatorEnum.EndWith;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.GreaterThan:
-                            condition.Operator = OperatorEnum.Greater ;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.GreaterThanOrEquals:
-                            condition.Operator = OperatorEnum.GreaterEqual;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.LessThan:
-                            condition.Operator = OperatorEnum.Less;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.LessThanOrEquals:
-                            condition.Operator = OperatorEnum.LessEqual;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.NotContains:
-                            condition.Operator = OperatorEnum.NotContains;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.NotEquals:
-                            condition.Operator = OperatorEnum.NotEqual;
-                            break;
-                        case AntDesign.TableFilterCompareOperator.StartsWith:
-                            condition.Operator = OperatorEnum.StartsWith;
-                            break;
-                        
+                        FieldCondition condition = new FieldCondition() { FieldName = filter.FieldName };
+                        condition.Value = f.Value.ToString();
+                        condition.ValueType = typeof(PerformanceItem).GetProperty(filter.FieldName).PropertyType.ToString();
+                        switch (f.FilterCompareOperator)
+                        {
+                            case AntDesign.TableFilterCompareOperator.Contains:
+                                condition.Operator = OperatorEnum.Contains;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.EndsWith:
+                                condition.Operator = OperatorEnum.EndWith;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.Equals:
+                                condition.Operator = OperatorEnum.EndWith;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.GreaterThan:
+                                condition.Operator = OperatorEnum.Greater;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.GreaterThanOrEquals:
+                                condition.Operator = OperatorEnum.GreaterEqual;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.LessThan:
+                                condition.Operator = OperatorEnum.Less;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.LessThanOrEquals:
+                                condition.Operator = OperatorEnum.LessEqual;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.NotContains:
+                                condition.Operator = OperatorEnum.NotContains;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.NotEquals:
+                                condition.Operator = OperatorEnum.NotEqual;
+                                break;
+                            case AntDesign.TableFilterCompareOperator.StartsWith:
+                                condition.Operator = OperatorEnum.StartsWith;
+                                break;
+
+                        }
+
+                        switch (f.FilterCondition)
+                        {
+                            case AntDesign.TableFilterCondition.And:
+                                condition.LogicOperate = LogicEnum.And;
+                                break;
+                            case AntDesign.TableFilterCondition.Or:
+                                condition.LogicOperate = LogicEnum.Or;
+                                break;
+                            default:
+                                condition.LogicOperate = LogicEnum.And;
+                                break;
+                        }
+
+                        query.ConditionTree.Add(condition);
+
                     }
+                }
 
-                    switch (f.FilterCondition)
+                query.Sorts = new List<OrderField>();
+                foreach (var sort in queryModel.SortModel)
+                {
+                    if (!string.IsNullOrEmpty(sort.Sort))
                     {
-                        case AntDesign.TableFilterCondition.And:
-                            condition.LogicOperate = LogicEnum.And;
-                             break;
-                        case AntDesign.TableFilterCondition.Or:
-                            condition.LogicOperate = LogicEnum.Or;
-                            break;
-                        default:
-                            condition.LogicOperate = LogicEnum.And;
-                            break;
+                        query.Sorts.Add(new OrderField() { FieldName = sort.FieldName, Sort = (sort.Sort == "descend" ? 1 : 0) });
                     }
-
-                    query.ConditionTree.Add(condition);
-                    
                 }
             }
-
-            query.Sorts =new  List<OrderField>();
-            foreach(var sort in queryModel.SortModel)
+            else
             {
-                if (!string.IsNullOrEmpty(sort.Sort))
-                {
-                    query.Sorts.Add(new OrderField() { FieldName = sort.FieldName, Sort = (sort.Sort == "descend" ? 1 : 0) });
-                }
+                query.PageIndex = 1;
+                query.PageSize = 1;
+                query.ConditionTree = new List<FieldCondition>();
+                query.Sorts = new List<OrderField>();
             }
+
             var data = await _httpClient.Post<ListApiResponse<PerformanceItem>>($"PerformanceItem/QueryFilter",query);
             //Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(queryModel));
             return data;
@@ -137,12 +173,16 @@ namespace wispro.sp.web.Services
             return data;
         }
 
+        
+
         public async  Task<PerformanceItem> GetProjectInfo(string caseNo)
         {
             var data = await _httpClient.Get<PerformanceItem>($"PerformanctItem/GetCaseInfo?CaseNo={caseNo}");
             return data;
         }
 
+        
+
         public async Task<ApiSaveResponse> AddProjectPerformanctItem(ProjectPointRecord projectPoint)
         {
             var data = await _httpClient.Post<ApiSaveResponse>($"PerformanceItem/AddProjectPerformance",projectPoint);

+ 30 - 0
wispro.sp.web/helper.ts

@@ -0,0 +1,30 @@
+function clickElement(element: HTMLElement): void {
+    element.click();
+}
+
+function downloadFromUrl(options: { url: string, fileName?: string }): void {
+    const anchorElement = document.createElement('a');
+    anchorElement.href = options.url;
+    anchorElement.download = options.fileName ?? '';
+    anchorElement.click();
+    anchorElement.remove();
+}
+
+function downloadFromByteArray(options: { byteArray: Uint8Array | string, fileName: string, contentType: string }): void {
+
+    const url = typeof (options.byteArray) === 'string' ?
+
+        // .NET 5 or earlier, the byte array in .NET is encoded to base64 string when it passes to JavaScript.
+        // In that case, that base64 encoded string can be pass to the browser as a "data URL" directly.
+        "data:" + options.contentType + ";base64," + options.byteArray :
+
+        // .NET 6 or later, the byte array in .NET is passed to JavaScript as an UInt8Array efficiently.
+        // - https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/6.0/byte-array-interop
+        // In that case, the UInt8Array can be converted to an object URL and passed to the browser.
+        // But don't forget to revoke the object URL when it is no longer needed.
+        URL.createObjectURL(new Blob([options.byteArray], { type: options.contentType }))
+
+    downloadFromUrl({ url: url, fileName: options.fileName });
+
+    if (typeof (options.byteArray) !== 'string') URL.revokeObjectURL(url);
+}

+ 2 - 0
wispro.sp.web/wispro.sp.web.csproj

@@ -22,6 +22,8 @@
     <Content Remove="Pages\Project\ProjectList.razor" />
     <Content Remove="Pages\Project\ReadAssignPointMsg.razor" />
     <Content Remove="Pages\Project\ReadMessage.razor" />
+    <Content Remove="wwwroot\scripts\Helper.js.map" />
+    <Content Remove="wwwroot\scripts\Helper.ts" />
   </ItemGroup>
 
   <ItemGroup>

+ 1 - 1
wispro.sp.web/wwwroot/index.html

@@ -225,7 +225,7 @@
     <script src="_content/AntDesign/js/ant-design-blazor.js"></script>
     <script src="_content/AntDesign.Charts/ant-design-charts-blazor.js"></script>
     <script src="_framework/blazor.webassembly.js"></script>
-    <!--<script src="saveSvgAsPng.js"></script>-->
+    <script src="script/helper.js"></script>
 </body>
 
 </html>

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 3392
wispro.sp.web/wwwroot/saveSvgAsPng.js


+ 26 - 0
wispro.sp.web/wwwroot/scripts/Helper.js

@@ -0,0 +1,26 @@
+"use strict";
+function clickElement(element) {
+    element.click();
+}
+function downloadFromUrl(options) {
+    var _a;
+    var anchorElement = document.createElement('a');
+    anchorElement.href = options.url;
+    anchorElement.download = (_a = options.fileName) !== null && _a !== void 0 ? _a : '';
+    anchorElement.click();
+    anchorElement.remove();
+}
+function downloadFromByteArray(options) {
+    var url = typeof (options.byteArray) === 'string' ?
+        // .NET 5 or earlier, the byte array in .NET is encoded to base64 string when it passes to JavaScript.
+        // In that case, that base64 encoded string can be pass to the browser as a "data URL" directly.
+        "data:" + options.contentType + ";base64," + options.byteArray :
+        // .NET 6 or later, the byte array in .NET is passed to JavaScript as an UInt8Array efficiently.
+        // - https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/6.0/byte-array-interop
+        // In that case, the UInt8Array can be converted to an object URL and passed to the browser.
+        // But don't forget to revoke the object URL when it is no longer needed.
+        URL.createObjectURL(new Blob([options.byteArray], { type: options.contentType }));
+    downloadFromUrl({ url: url, fileName: options.fileName });
+    if (typeof (options.byteArray) !== 'string')
+        URL.revokeObjectURL(url);
+}