Преглед на файлове

添加缓存
修正个人难度系数为NAN问题
添加按字数计算和按件计算的优先选择
修正OPPO绩效计算的问题

luocaiyang преди 3 години
родител
ревизия
ba29918aab

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

@@ -117,7 +117,7 @@ namespace wispro.sp.api.Controllers
 
             var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:Key"]));
             var credential = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
-            var expireTime = DateTime.Now.AddMinutes(20);
+            var expireTime = DateTime.Now.AddHours(5);
             
             var token = new JwtSecurityToken(
                 issuer: Configuration["jwt:Issuer"],

+ 51 - 0
wispro.sp.api/Controllers/AppealController.cs

@@ -507,6 +507,57 @@ namespace wispro.sp.api.Controllers
             return result.ToList();
         }
 
+        public ApiSaveResponse ChangeRecordReviewer(int RecordId,int ReviewerId)
+        {
+            var data = Context.AppealRecords.FirstOrDefault<AppealRecord>(ar => ar.Id == RecordId);
+
+            if(data != null)
+            {
+                var reviewer = Context.Staffs.FirstOrDefault(s => s.Id == ReviewerId);
+
+                var CurrentUser = Context.Staffs.FirstOrDefault(s=>s.Name == User.Identity.Name);
+
+                if ((CurrentUser.Id == data.CreaterId || CurrentUser.Id == data.ReviewerId) && data.State ==0)
+                {
+
+                    if (reviewer != null)
+                    {
+                        data.ReviewerId = ReviewerId;
+                        Context.SaveChanges();
+
+                        return new ApiSaveResponse()
+                        {
+                            Success = true
+                        };
+                    }
+                    else
+                    {
+                        return new ApiSaveResponse()
+                        {
+                            Success = false,
+                            ErrorMessage = "指定的审核人不存在"
+                        };
+                    }
+                }
+                else
+                {
+                    return new ApiSaveResponse()
+                    {
+                        Success = false,
+                        ErrorMessage = "只有申诉人和审核人在未审核状态时才能变更审核人"
+                    };
+                }
+            }
+            else
+            {
+                return new ApiSaveResponse()
+                {
+                    Success = false,
+                    ErrorMessage = "指定的申诉记录不存在"
+                };
+            }
+        }
+
         
     }
 }

+ 630 - 81
wispro.sp.api/Controllers/PerformanceItemController.cs

@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.StaticFiles;
 using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Hosting;
 using System;
 using System.Collections.Generic;
@@ -28,6 +29,8 @@ namespace wispro.sp.api.Controllers
     {
         spDbContext Context;
         IFileTaskService fileTaskService;
+        
+
         public PerformanceItemController(spDbContext context, IFileTaskService _fileTaskService)
         {
             Context = context;
@@ -187,7 +190,7 @@ namespace wispro.sp.api.Controllers
             ApiSaveResponse ret = new ApiSaveResponse();
             ret.Success = true;
 
-            var item = Context.PerformanceItems.FirstOrDefault<PerformanceItem>(p => p.Id == id);
+            var item = Context.PerformanceItems.Include(p=>p.Customer).FirstOrDefault<PerformanceItem>(p => p.Id == id);
 
             if (item == null)
             {
@@ -397,84 +400,104 @@ namespace wispro.sp.api.Controllers
 
         public double DegreeOfDifficulty(int year,int month, int? userId = null)
         {
-            IDictionary<string, double> CaseXiShu = new Dictionary<string, double>();
-            var list = Context.CaseCeoffcients;
-
-            foreach(var cx in list.ToList<CaseCeoffcient>())
+            string strKey = $"DegreeOfDifficulty:{year}-{month}-{userId}";
+            object cacheEntry;
+            if (!MyMemoryCache.TryGetValue(strKey, out cacheEntry))
             {
-                CaseXiShu.Add(cx.Ceoffcient, cx.Value);
-            }
 
-            var results = Context.PerformanceItems.Where<PerformanceItem>(p => p.CalMonth.Year == year && p.CalMonth.Month == month && ((p.Type == "新申请" && p.BasePoint > 0) || p.Type == "专案") && p.BasePoint > 0.0);
+                IDictionary<string, double> CaseXiShu = new Dictionary<string, double>();
+                var list = Context.CaseCeoffcients;
 
-            if(userId != null)
-            {
-                results = Context.PerformanceItems.Where<PerformanceItem>(p => 
-                p.CalMonth.Year == year && p.CalMonth.Month == month && ((p.Type == "新申请" && p.BasePoint >0) || p.Type == "专案") && 
-                (p.ItemStaffs.Where<ItemStaff>(s=>s.DoPerson.Id == userId).Count ()>0 ) && p.BasePoint >0.0);
-            }
+                foreach (var cx in list.ToList<CaseCeoffcient>())
+                {
+                    CaseXiShu.Add(cx.Ceoffcient, cx.Value);
+                }
 
-            #region 循环计算
-            int iCount = 0;
-            double d = 0.0;
-            var retList = results.ToList();
+                var results = Context.PerformanceItems.Where<PerformanceItem>(p => p.CalMonth.Year == year && p.CalMonth.Month == month && ((p.Type == "新申请" && p.BasePoint > 0) || p.Type == "专案") && p.BasePoint > 0.0);
 
-            foreach(var item in retList)
-            {
-                string strCaseCeoffcient = item.CaseCoefficient;
+                if (userId != null)
+                {
+                    results = Context.PerformanceItems.Where<PerformanceItem>(p =>
+                    p.CalMonth.Year == year && p.CalMonth.Month == month && ((p.Type == "新申请" && p.BasePoint > 0) || p.Type == "专案") &&
+                    (p.ItemStaffs.Where<ItemStaff>(s => s.DoPerson.Id == userId).Count() > 0 || p.ReviewerId == userId ) && p.BasePoint > 0.0);
+                }
+
+                #region 循环计算
+                int iCount = 0;
+                double d = 0.0;
+                var retList = results.ToList();
 
-                if(item.isDanger() && string.IsNullOrEmpty(item.OverDueMemo))
+                foreach (var item in retList)
                 {
-                    switch (item.CaseCoefficient)
+                    string strCaseCeoffcient = item.CaseCoefficient;
+
+                    #region 严重延期降系数
+                    if (item.isDanger() && string.IsNullOrEmpty(item.OverDueMemo))
                     {
-                        case "S":
-                            strCaseCeoffcient = "A";
-                            break;
-                        case "A":
-                            strCaseCeoffcient = "B";
-                            break;
-                        case "B":
-                            strCaseCeoffcient = "C";
-                            break;
-                        case "C":
-                            strCaseCeoffcient = "D";
-                            break;
+                        switch (item.CaseCoefficient)
+                        {
+                            case "S":
+                                strCaseCeoffcient = "A";
+                                break;
+                            case "A":
+                                strCaseCeoffcient = "B";
+                                break;
+                            case "B":
+                                strCaseCeoffcient = "C";
+                                break;
+                            case "C":
+                                strCaseCeoffcient = "D";
+                                break;
+                        }
+                    }
+                    #endregion
+
+                    if (CaseXiShu.ContainsKey(strCaseCeoffcient))
+                    {
+                        d += CaseXiShu[strCaseCeoffcient];
+                        iCount += 1;
                     }
-                }
 
-                if (CaseXiShu.ContainsKey(strCaseCeoffcient))
-                {
-                    d += CaseXiShu[strCaseCeoffcient];
-                    iCount += 1;
                 }
+                #endregion
 
-            }
-            #endregion
+                #region 统计计算
+                //var groupResult = results.GroupBy(x => x.CaseCoefficient).Select(g=> new { 
+                //    CaseCeoffcient = g.Key,
+                //    count = g.Count()
+                //});
 
-            #region 统计计算
-            //var groupResult = results.GroupBy(x => x.CaseCoefficient).Select(g=> new { 
-            //    CaseCeoffcient = g.Key,
-            //    count = g.Count()
-            //});
+                //int iCount = 0;
+                //double d = 0.0;
+                //foreach(var g in groupResult)
+                //{
+                //    if (!string.IsNullOrEmpty(g.CaseCeoffcient))
+                //    {
 
-            //int iCount = 0;
-            //double d = 0.0;
-            //foreach(var g in groupResult)
-            //{
-            //    if (!string.IsNullOrEmpty(g.CaseCeoffcient))
-            //    {
 
+                //        if (CaseXiShu.ContainsKey(g.CaseCeoffcient))
+                //        {
+                //            d += g.count * CaseXiShu[g.CaseCeoffcient];
+                //            iCount += g.count;
+                //        }
+                //    }
+                //}
+                #endregion
+
+                cacheEntry = d / (double)iCount;
 
-            //        if (CaseXiShu.ContainsKey(g.CaseCeoffcient))
-            //        {
-            //            d += g.count * CaseXiShu[g.CaseCeoffcient];
-            //            iCount += g.count;
-            //        }
-            //    }
-            //}
-            #endregion
+                // Set cache options.
+                
+                // Save data in cache.
+                MyMemoryCache.SetValue(strKey, cacheEntry);
 
-            return d /(double)iCount;
+
+                return (double)cacheEntry;
+            }
+            else
+            {
+                return (double)cacheEntry;
+            }
         }
 
         public List<string> GetFeedbackString(int itemId)
@@ -491,6 +514,7 @@ namespace wispro.sp.api.Controllers
         private List<StaffStatistics> _CalMyStatistics(CalMonth calMonth, int? userid = null)
         {
 
+
             double gspjXS = DegreeOfDifficulty(calMonth.Year, calMonth.Month);
 
             //未归档,从绩效记录中统计数据
@@ -621,7 +645,7 @@ namespace wispro.sp.api.Controllers
 
         public ApiSaveResponse RefreshFromIPEasyById(int itemId)
         {
-            var Item = Context.PerformanceItems.FirstOrDefault(p => p.Id == itemId);
+            var Item = Context.PerformanceItems.Include(p=>p.Customer).FirstOrDefault(p => p.Id == itemId);
             if (Item != null)
             {
                 new Job.UpdateJXDataFromIPEasyJob().UpdateFromIPEasy(Item, Context);
@@ -632,9 +656,20 @@ namespace wispro.sp.api.Controllers
                 Success = true
             };
         }
+
+        public ApiSaveResponse RefreshFromIPEasy_Batch(int type)
+        {
+            new Job.UpdateJXDataFromIPEasyJob().RefreshFromIPEasy(type);
+
+            return new ApiSaveResponse()
+            {
+                Success = true
+            };
+        }
+
         public ApiSaveResponse RefreshFromIPEasy(string CaseNo,string DoItem,string caseStage)
         {
-            var Item = Context.PerformanceItems.FirstOrDefault(p=>p.CaseNo == CaseNo && p.DoItem == DoItem && p.CaseStage == caseStage);
+            var Item = Context.PerformanceItems.Include(p=>p.Customer).FirstOrDefault(p=>p.CaseNo == CaseNo && p.DoItem == DoItem && p.CaseStage == caseStage);
             if(Item != null)
             {
                 new Job.UpdateJXDataFromIPEasyJob().UpdateFromIPEasy(Item,Context);
@@ -646,8 +681,501 @@ namespace wispro.sp.api.Controllers
             };
         }
 
+        public ApiSaveResponse CompareExcel2DB()
+        {
+
+            System.Threading.Thread t = new Thread(new ThreadStart(_CompareExcel2DB));
+            t.Start();
+            
+            return new ApiSaveResponse()
+            {
+                Success = true
+            };
+        }
+
+
+        private void _CompareExcel2DB()
+        {
+           
+            DataTable excelDT = NPOIExcel.ExcelToDataTable("c:\\temp\\220112-工程师绩效总表-12月-v2F.xlsx", true, true, 0,2);
+            DataTable retTable = new DataTable();
+            retTable.Columns.Add("我方文号");
+            retTable.Columns.Add("申请类型");
+            retTable.Columns.Add("业务类型");
+            retTable.Columns.Add("备注(填表注意事项)");
+            retTable.Columns.Add("备注(填表注意事项)【系统】");
+            retTable.Columns.Add("处理事项");
+            retTable.Columns.Add("处理事项【系统】");
+            retTable.Columns.Add("案件阶段");
+            retTable.Columns.Add("案件阶段【系统】");
+            retTable.Columns.Add("案件系数");
+            retTable.Columns.Add("案件系数【系统】");
+            retTable.Columns.Add("处理事项系数");
+            retTable.Columns.Add("处理事项系数【系统】");
+            retTable.Columns.Add("处理人等级");
+            retTable.Columns.Add("处理人等级【系统】");
+            retTable.Columns.Add("处理人系数");
+            retTable.Columns.Add("处理人系数【系统】");            
+            retTable.Columns.Add("基本点数");
+            retTable.Columns.Add("基本点数【系统】");
+            retTable.Columns.Add("核稿系数");
+            retTable.Columns.Add("核稿系数【系统】");
+            retTable.Columns.Add("核稿绩效");
+            retTable.Columns.Add("核稿绩效【系统】");
+            retTable.Columns.Add("处理人");
+            retTable.Columns.Add("处理人【系统】");
+            retTable.Columns.Add("核稿人");
+            retTable.Columns.Add("核稿人【系统】");
+            retTable.Columns.Add("严重超期备注原因");
+            retTable.Columns.Add("严重超期备注原因【系统】");
+
+            retTable.Columns.Add("是否一致");
+            retTable.Columns.Add("不一致原因");
+
+            spDbContext spDb = new spDbContext();
+            List<PerformanceItem> items = spDb.PerformanceItems
+                .Include(p=>p.Reviewer).ThenInclude(p=>p.StaffGrade)
+                .Include(p=>p.Customer)
+                .Include(p=>p.ItemStaffs).ThenInclude(s=>s.DoPerson).ThenInclude(s=>s.StaffGrade)
+                .Where(p=>p.CalMonth.Status ==0 && !p.CaseNo.StartsWith("J")).OrderBy(p=>p.CaseNo).ThenBy(p=>p.DoItem).ToList();
+
+            excelDT.DefaultView.Sort = "我方文号,处理事项";
+            DataTable temDt = excelDT.DefaultView.ToTable();
+
+            int iTable = 0;
+            int iList = 0;
+
+            CalMonth calMonth = spDb.CalMonths.FirstOrDefault(p=>p.Status ==0);
+            var verifyCoefficients = spDb.VerifyCoefficients.ToList();
+            var Rules = spDb.BasePointRules.ToList();
+            while (iTable < temDt.Rows.Count && iList < items.Count)
+            {
+                System.Diagnostics.Debug.WriteLine($"Excel:{iTable}/{temDt.Rows.Count}\t{iList}/{items.Count}");
+
+                DataRow row = temDt.Rows[iTable];
+                PerformanceItem item = items[iList];
+
+                if(row["我方文号"].ToString() == item.CaseNo && (row["处理事项"].ToString() == item.DoItem || (row["备注(填表注意事项)"].ToString()== "发明一次OA授权" && item.DoItem == "发明一次OA授权")))
+                {
+                    var temRow = retTable.NewRow();
+
+                    int iBegin = iTable;
+                    int iEnd = iTable;
+
+                    #region 判断是否有重复记录,并将Excel表中的记录生成临时表中的一行记录
+                    if (iEnd < temDt.Rows.Count - 1)
+                    {
+                        while (temDt.Rows[iEnd]["我方文号"].ToString() == temDt.Rows[iEnd + 1]["我方文号"].ToString() &&
+                            temDt.Rows[iEnd]["处理事项"].ToString() == temDt.Rows[iEnd + 1]["处理事项"].ToString())
+                        {
+                            iEnd++;
+                        }
+                    }
+
+                    temRow["我方文号"] = temDt.Rows[iTable]["我方文号"];
+                    temRow["处理事项"] = temDt.Rows[iTable]["处理事项"];
+                    temRow["申请类型"] = temDt.Rows[iTable]["申请类型"];
+                    temRow["业务类型"] = temDt.Rows[iTable]["业务类型"];
+                    temRow["案件阶段"] = temDt.Rows[iTable]["案件阶段"];
+                    temRow["案件系数"] = temDt.Rows[iTable]["案件系数"];
+                    temRow["处理事项系数"] = temDt.Rows[iTable]["处理事项系数"];
+                    temRow["核稿人"] = temDt.Rows[iTable]["核稿人"];
+                    temRow["备注(填表注意事项)"] = temDt.Rows[iTable]["备注(填表注意事项)"];
+
+                    temRow["处理人等级"] = temDt.Rows[iTable]["处理人等级"];
+                    temRow["基本点数"] = temDt.Rows[iTable]["基本点数"];
+                    temRow["核稿系数"] = temDt.Rows[iTable]["核稿系数"];
+                    temRow["处理人"] = temDt.Rows[iTable]["处理人"];
+                    
+                    temRow["严重超期备注原因"] = temDt.Rows[iTable]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"];
+
+                    for (int i = iBegin; i <= iEnd; i++)
+                    {
+                        temRow["备注(填表注意事项)"] =string.IsNullOrEmpty(temRow["备注(填表注意事项)"].ToString()) ?temDt.Rows[i]["备注(填表注意事项)"] :$"{temRow["备注(填表注意事项)"]}{temDt.Rows[i]["备注(填表注意事项)"]}";
+
+                        //temRow["基本点数"] = string.IsNullOrEmpty(temRow["基本点数"].ToString()) ? temDt.Rows[i]["基本点数"] : $"{temRow["基本点数"]},{temDt.Rows[i]["基本点数"]}";
+                        temRow["核稿系数"] = string.IsNullOrEmpty(temRow["核稿系数"].ToString()) ? temDt.Rows[i]["核稿系数"] : $"{temRow["核稿系数"]},{temDt.Rows[i]["核稿系数"]}";
+                        if (!temRow["处理人"].ToString().Contains(temDt.Rows[i]["处理人"].ToString()))
+                        {
+                            temRow["处理人"] = string.IsNullOrEmpty(temRow["处理人"].ToString()) ? temDt.Rows[i]["处理人"] : $"{temRow["处理人"]},{temDt.Rows[i]["处理人"]}";
+                            temRow["处理人等级"] = string.IsNullOrEmpty(temRow["处理人等级"].ToString()) ? temDt.Rows[i]["处理人等级"] : $"{temRow["处理人等级"]},{temDt.Rows[i]["处理人等级"]}";
+                        }
+                        temRow["严重超期备注原因"] = string.IsNullOrEmpty(temRow["严重超期备注原因"].ToString()) ? temDt.Rows[i]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"] : $"{temRow["严重超期备注原因"]}{temDt.Rows[i]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"]}";
+                    }
+
+                    iTable = iEnd;
+                    #endregion
+
+                    Utility.Utility.CalBasePoint(item, Rules);
+
+                    List<StaffStatistics> retPoints = new List<StaffStatistics>();
+                    try
+                    {
+                        retPoints = _calItemJX(calMonth, verifyCoefficients, item, spDb);
+                    }
+                    catch { }
+                     
+                    
+                    temRow["案件阶段【系统】"] = item.CaseStage;
+                    temRow["案件系数【系统】"] = item.CaseCoefficient;
+                    temRow["处理事项系数【系统】"] = item.DoItemCoefficient;
+                    temRow["核稿人【系统】"] = item.Reviewer?.Name;
+                    temRow["备注(填表注意事项)【系统】"] = item.AgentFeedbackMemo;
+                    temRow["基本点数【系统】"] = item.BasePoint?.ToString();
+                    temRow["严重超期备注原因"] = item.OverDueMemo;
+
+                    if (retPoints != null && retPoints.Count > 0)
+                    {
+                        temRow["核稿绩效【系统】"] = retPoints.FirstOrDefault(p => p.StaffId == item.ReviewerId && p.jxType.Contains("审核"))?.totalBasePoint;
+
+                        foreach (var itemStaff in item.ItemStaffs)
+                        {
+                            //temRow["基本点数【系统】"] = string.IsNullOrEmpty(temRow["基本点数【系统】"].ToString()) ? retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint.ToString() : $"{temRow["基本点数【系统】"]},{retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint}";
+
+                            temRow["处理人等级【系统】"] = string.IsNullOrEmpty(temRow["处理人等级【系统】"].ToString()) ? itemStaff.DoPerson.StaffGrade?.Grade : $"{temRow["处理人等级【系统】"]},{itemStaff.DoPerson.StaffGrade?.Grade }";
+                            temRow["处理人【系统】"] = string.IsNullOrEmpty(temRow["处理人【系统】"].ToString()) ? itemStaff.DoPerson.Name : $"{temRow["处理人【系统】"]},{itemStaff.DoPerson.Name}";
+
+                            if (item.ReviewerId != null)
+                            {
+                                #region 取审核人等级审核等级系数
+                                VerifyCoefficient vcoefficient
+                                    = verifyCoefficients.Where<VerifyCoefficient>(v =>
+                                        v.CheckerId == item.Reviewer.StaffGradeId
+                                        && v.DoPersonId == itemStaff.DoPerson.StaffGradeId)
+                                .FirstOrDefault<VerifyCoefficient>();
+                                #endregion
+
+                                if (vcoefficient != null)
+                                {
+                                    temRow["核稿系数【系统】"] = string.IsNullOrEmpty(temRow["核稿系数【系统】"].ToString()) ? vcoefficient.Coefficient.ToString() : $"{temRow["核稿系数【系统】"]},{vcoefficient.Coefficient}";
+                                }
+                            }
+
+                        }
+                    }
+
+                    temRow["是否一致"] = "";
+                    temRow["不一致原因"] = "";
+
+                    if(temRow["案件阶段【系统】"].ToString().Trim() != temRow["案件阶段"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "案件阶段" : $"{temRow["不一致原因"]},案件阶段";
+                    }
+                    if (temRow["案件系数【系统】"].ToString().Trim() != temRow["案件系数"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "案件系数" : $"{temRow["不一致原因"]},案件系数";
+                    }
+                    if (temRow["处理事项系数【系统】"].ToString().Trim() != temRow["处理事项系数"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "处理事项系数" : $"{temRow["不一致原因"]},处理事项系数";
+                    }
+                    if (temRow["核稿人【系统】"].ToString().Trim() != temRow["核稿人"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "核稿人" : $"{temRow["不一致原因"]},核稿人";
+                    }
+
+                    if (temRow["基本点数【系统】"].ToString().Trim() != temRow["基本点数"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "基本点数" : $"{temRow["不一致原因"]},基本点数";
+                    }
+                    if (temRow["严重超期备注原因【系统】"].ToString().Trim() != temRow["严重超期备注原因"].ToString().Trim())
+                    {
+                        temRow["不一致原因"] = string.IsNullOrEmpty(temRow["不一致原因"].ToString()) ? "严重超期备注原因" : $"{temRow["不一致原因"]},严重超期备注原因";
+                    }
+
+                    if (!string.IsNullOrEmpty(temRow["不一致原因"].ToString()))
+                    {
+                        temRow["是否一致"] = "不一致";
+                    }
+
+                    retTable.Rows.Add(temRow);
+
+                    iTable++;
+                    iList++;
+                }
+                else
+                {
+                    string strDT = $"{row["我方文号"]}-{row["处理事项"]}";
+                    string strList = $"{item.CaseNo}-{item.DoItem}";
+
+                    if (strDT.CompareTo(strList) > 0)
+                    {
+                        var temRow = retTable.NewRow();
+
+                        Utility.Utility.CalBasePoint(item, Rules);
+
+                        List<StaffStatistics> retPoints = new List<StaffStatistics>();
+                        try
+                        {
+                            retPoints = _calItemJX(calMonth, verifyCoefficients, item, spDb);
+                        }
+                        catch { }
+
+                        temRow["我方文号"] = item.CaseNo;
+                        temRow["处理事项"] = item.DoItem;
+                        temRow["申请类型"] = item.ApplicationType;
+                        temRow["业务类型"] = item.BusinessType;
+                        temRow["案件阶段【系统】"] = item.CaseStage;
+                        temRow["案件系数【系统】"] = item.CaseCoefficient;
+                        temRow["处理事项系数【系统】"] = item.DoItemCoefficient;
+                        temRow["核稿人【系统】"] = item.Reviewer?.Name;
+                        temRow["备注(填表注意事项)【系统】"] = item.AgentFeedbackMemo;
+                        temRow["基本点数【系统】"] = item.BasePoint?.ToString();
+                        temRow["严重超期备注原因"] = item.OverDueMemo;
+
+                        if (item.ReviewerId != null)
+                        {
+                            temRow["核稿绩效【系统】"] = retPoints.FirstOrDefault(p => p.StaffId == item.ReviewerId)?.totalBasePoint;
+                        }
+
+                        foreach (var itemStaff in item.ItemStaffs)
+                        {
+                            //if (itemStaff.DoPerson.Status != "试用期")
+                            //{
+                            //    if (retPoints != null && retPoints.Count > 0)
+                            //    {
+                            //        temRow["基本点数【系统】"] = string.IsNullOrEmpty(temRow["基本点数【系统】"].ToString()) ? retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint.ToString() : $"{temRow["基本点数【系统】"]},{retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint}";
+                            //    }
+                            //}
+
+
+                            temRow["处理人等级【系统】"] = string.IsNullOrEmpty(temRow["处理人等级【系统】"].ToString()) ? itemStaff.DoPerson.StaffGrade?.Grade : $"{temRow["处理人等级【系统】"]},{itemStaff.DoPerson.StaffGrade?.Grade }";
+                            temRow["处理人系数【系统】"] = string.IsNullOrEmpty(temRow["处理人系数【系统】"].ToString()) ? itemStaff.DoPerson.StaffGrade?.Coefficient : $"{temRow["处理人系数【系统】"]},{itemStaff.DoPerson.StaffGrade?.Coefficient}";
+                            temRow["处理人【系统】"] = string.IsNullOrEmpty(temRow["处理人【系统】"].ToString()) ? itemStaff.DoPerson.Name : $"{temRow["处理人【系统】"]},{itemStaff.DoPerson.Name}";
+
+                            if (item.ReviewerId != null)
+                            {
+                                #region 取审核人等级审核等级系数
+                                VerifyCoefficient vcoefficient
+                                    = verifyCoefficients.Where<VerifyCoefficient>(v =>
+                                        v.CheckerId == item.Reviewer.StaffGradeId
+                                        && v.DoPersonId == itemStaff.DoPerson.StaffGradeId)
+                                .FirstOrDefault<VerifyCoefficient>();
+                                #endregion
+
+                                if (vcoefficient != null)
+                                {
+                                    temRow["核稿系数【系统】"] = string.IsNullOrEmpty(temRow["核稿系数【系统】"].ToString()) ? vcoefficient.Coefficient.ToString() : $"{temRow["核稿系数【系统】"]},{vcoefficient.Coefficient}";
+                                }
+                            }
+
+                        }
+
+                        temRow["是否一致"] = "不一致";
+                        temRow["不一致原因"] = "Excel中没有,系统中有";
+
+                        retTable.Rows.Add(temRow);
+
+                        iList++;
+                    }
+                    else
+                    {
+                        var temRow = retTable.NewRow();
+
+                        int iBegin = iTable;
+                        int iEnd = iTable;
+
+                        #region 判断是否有重复记录,并将Excel表中的记录生成临时表中的一行记录
+                        if (iEnd < temDt.Rows.Count - 1)
+                        {
+                            while (temDt.Rows[iEnd]["我方文号"].ToString() == temDt.Rows[iEnd + 1]["我方文号"].ToString() &&
+                            temDt.Rows[iEnd]["处理事项"].ToString() == temDt.Rows[iEnd + 1]["处理事项"].ToString())
+                            {
+                                iEnd++;
+                            }
+                        }
+
+                        temRow["我方文号"] = temDt.Rows[iTable]["我方文号"];
+                        temRow["处理事项"] = temDt.Rows[iTable]["处理事项"];
+                        temRow["申请类型"] = temDt.Rows[iTable]["申请类型"];
+                        temRow["业务类型"] = temDt.Rows[iTable]["业务类型"];
+                        temRow["案件阶段"] = temDt.Rows[iTable]["案件阶段"];
+                        temRow["案件系数"] = temDt.Rows[iTable]["案件系数"];
+                        temRow["处理事项系数"] = temDt.Rows[iTable]["处理事项系数"];
+                        temRow["核稿人"] = temDt.Rows[iTable]["核稿人"];
+                        temRow["备注(填表注意事项)"] = temDt.Rows[iTable]["备注(填表注意事项)"];
+
+                        temRow["处理人等级"] = temDt.Rows[iTable]["处理人等级"];
+                        temRow["基本点数"] = temDt.Rows[iTable]["基本点数"];
+                        temRow["核稿系数"] = temDt.Rows[iTable]["核稿系数"];
+                        temRow["核稿绩效"] = temDt.Rows[iTable]["核稿绩效"];
+                        temRow["处理人"] = temDt.Rows[iTable]["处理人"];
+                        
+                        temRow["严重超期备注原因"] = temDt.Rows[iTable]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"];
+
+                        for (int i = iBegin+1; i <= iEnd; i++)
+                        {
+                            temRow["备注(填表注意事项)"] = string.IsNullOrEmpty(temRow["备注(填表注意事项)"].ToString()) ? temDt.Rows[i]["备注(填表注意事项)"] : $"{temRow["备注(填表注意事项)"]}{temDt.Rows[i]["备注(填表注意事项)"]}";
+
+                            //temRow["基本点数"] = string.IsNullOrEmpty(temRow["基本点数"].ToString()) ? temDt.Rows[i]["基本点数"] : $"{temRow["基本点数"]},{temDt.Rows[i]["基本点数"]}";
+
+                            temRow["核稿绩效"] = string.IsNullOrEmpty(temRow["核稿绩效"].ToString()) ? temDt.Rows[i]["核稿绩效"] : $"{temRow["核稿绩效"]},{temDt.Rows[i]["核稿绩效"]}";
+                            if (!temRow["处理人"].ToString().Contains(temDt.Rows[i]["处理人"].ToString()))
+                            {
+                                temRow["处理人"] = string.IsNullOrEmpty(temRow["处理人"].ToString()) ? temDt.Rows[i]["处理人"] : $"{temRow["处理人"]},{temDt.Rows[i]["处理人"]}";
+                                temRow["处理人等级"] = string.IsNullOrEmpty(temRow["处理人等级"].ToString()) ? temDt.Rows[i]["处理人等级"] : $"{temRow["处理人等级"]},{temDt.Rows[i]["处理人等级"]}";
+                            }
+                            temRow["严重超期备注原因"] = string.IsNullOrEmpty(temRow["严重超期备注原因"].ToString()) ? temDt.Rows[i]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"] : $"{temRow["严重超期备注原因"]}{temDt.Rows[i]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"]}";
+                        }
+
+                        iTable = iEnd;
+                        #endregion
+
+                        temRow["是否一致"] = "不一致";
+                        temRow["不一致原因"] = "系统中没有,Excel中有";
+                        retTable.Rows.Add(temRow);
+                        iTable++;
+                    }
+
+                }
+            }
+
+            if (iList <=items.Count)
+            {
+                while(iList <items.Count){
+                    var item = items[iList];
+                    var temRow = retTable.NewRow();
+
+                    Utility.Utility.CalBasePoint(item, Rules);
+
+                    List<StaffStatistics> retPoints = new List<StaffStatistics>();
+                    try
+                    {
+                        retPoints = _calItemJX(calMonth, verifyCoefficients, item, spDb);
+                    }
+                    catch { }
+
+                    temRow["我方文号"] = item.CaseNo;
+                    temRow["处理事项"] = item.DoItem;
+                    temRow["申请类型"] = item.ApplicationType;
+                    temRow["业务类型"] = item.BusinessType;
+                    temRow["案件阶段【系统】"] = item.CaseStage;
+                    temRow["案件系数【系统】"] = item.CaseCoefficient;
+                    temRow["处理事项系数【系统】"] = item.DoItemCoefficient;
+                    temRow["核稿人【系统】"] = item.Reviewer?.Name;
+                    temRow["备注(填表注意事项)【系统】"] = item.AgentFeedbackMemo;
+                    temRow["基本点数【系统】"] = "";// item.BasePoint?.ToString();
+                    temRow["严重超期备注原因"] = item.OverDueMemo;
+
+                    if (item.ReviewerId != null)
+                    {
+                        temRow["核稿绩效【系统】"] = retPoints.FirstOrDefault(p => p.StaffId == item.ReviewerId)?.totalBasePoint;
+                    }
+
+                    foreach (var itemStaff in item.ItemStaffs)
+                    {
+                        //if (itemStaff.DoPerson.Status != "试用期")
+                        //{
+                        //    if (retPoints != null && retPoints.Count > 0)
+                        //    {
+                        //        temRow["基本点数【系统】"] = string.IsNullOrEmpty(temRow["基本点数【系统】"].ToString()) ? retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint.ToString() : $"{temRow["基本点数【系统】"]},{retPoints.FirstOrDefault(p => p.StaffId == itemStaff.DoPersonId)?.totalBasePoint}";
+                        //    }
+                        //}
+
+
+                        temRow["处理人等级【系统】"] = string.IsNullOrEmpty(temRow["处理人等级【系统】"].ToString()) ? itemStaff.DoPerson.StaffGrade?.Grade : $"{temRow["处理人等级【系统】"]},{itemStaff.DoPerson.StaffGrade?.Grade }";
+                        temRow["处理人系数【系统】"] = string.IsNullOrEmpty(temRow["处理人系数【系统】"].ToString()) ? itemStaff.DoPerson.StaffGrade?.Coefficient : $"{temRow["处理人系数【系统】"]},{itemStaff.DoPerson.StaffGrade?.Coefficient}";
+                        temRow["处理人【系统】"] = string.IsNullOrEmpty(temRow["处理人【系统】"].ToString()) ? itemStaff.DoPerson.Name : $"{temRow["处理人【系统】"]},{itemStaff.DoPerson.Name}";
+
+                        if (item.ReviewerId != null)
+                        {
+                            #region 取审核人等级审核等级系数
+                            VerifyCoefficient vcoefficient
+                                = verifyCoefficients.Where<VerifyCoefficient>(v =>
+                                    v.CheckerId == item.Reviewer.StaffGradeId
+                                    && v.DoPersonId == itemStaff.DoPerson.StaffGradeId)
+                            .FirstOrDefault<VerifyCoefficient>();
+                            #endregion
+
+                            if (vcoefficient != null)
+                            {
+                                temRow["核稿系数【系统】"] = string.IsNullOrEmpty(temRow["核稿系数【系统】"].ToString()) ? vcoefficient.Coefficient.ToString() : $"{temRow["核稿系数【系统】"]},{vcoefficient.Coefficient}";
+                            }
+                        }
+
+                    }
+
+                    temRow["是否一致"] = "不一致";
+                    temRow["不一致原因"] = "Excel中没有,系统中有";
+
+                    iList++;
+                    retTable.Rows.Add(temRow);
+
+                }
+            }
+            else
+            {
+                while (iTable  < temDt.Rows.Count)
+                {
+                    var temRow = retTable.NewRow();
+
+                    int iBegin = iTable;
+                    int iEnd = iTable;
+
+                    #region 判断是否有重复记录,并将Excel表中的记录生成临时表中的一行记录
+                    while (temDt.Rows[iTable]["我方文号"].ToString() == temDt.Rows[iTable + 1]["我方文号"].ToString() &&
+                        temDt.Rows[iTable]["处理事项"].ToString() == temDt.Rows[iTable + 1]["处理事项"].ToString())
+                    {
+                        iEnd++;
+                    }
+
+                    temRow["我方文号"] = temDt.Rows[iTable]["我方文号"];
+                    temRow["处理事项"] = temDt.Rows[iTable]["处理事项"];
+                    temRow["申请类型"] = temDt.Rows[iTable]["申请类型"];
+                    temRow["业务类型"] = temDt.Rows[iTable]["业务类型"];
+                    temRow["案件阶段"] = temDt.Rows[iTable]["案件阶段"];
+                    temRow["案件系数"] = temDt.Rows[iTable]["案件系数"];
+                    temRow["处理事项系数"] = temDt.Rows[iTable]["处理事项系数"];
+                    temRow["核稿人"] = temDt.Rows[iTable]["核稿人"];
+                    temRow["备注(填表注意事项)"] = temDt.Rows[iTable]["备注(填表注意事项)"];
+
+                    temRow["处理人等级"] = temDt.Rows[iTable]["处理人等级"];
+                    temRow["基本点数"] = temDt.Rows[iTable]["基本点数"];
+                    temRow["核稿系数"] = temDt.Rows[iTable]["核稿系数"];
+                    temRow["核稿绩效"] = temDt.Rows[iTable]["核稿绩效"];
+                    temRow["处理人"] = temDt.Rows[iTable]["处理人"];
+
+                    temRow["严重超期备注原因"] = temDt.Rows[iTable]["备注(发文严重超期是否属客观原因,若为否,请填写原因)"];
+
+                    for (int i = iBegin + 1; i <= iEnd; i++)
+                    {
+                        temRow["备注(填表注意事项)"] = string.IsNullOrEmpty(temRow["备注(填表注意事项)"].ToString()) ? temDt.Rows[i]["备注(填表注意事项)"] : $"{temRow["备注(填表注意事项)"]}{temDt.Rows[i]["备注(填表注意事项)"]}";
+
+                        //temRow["基本点数"] = string.IsNullOrEmpty(temRow["基本点数"].ToString()) ? temDt.Rows[i]["基本点数"] : $"{temRow["基本点数"]},{temDt.Rows[i]["基本点数"]}";
+
+                        temRow["核稿绩效"] = string.IsNullOrEmpty(temRow["核稿绩效"].ToString()) ? temDt.Rows[i]["核稿绩效"] : $"{temRow["核稿绩效"]},{temDt.Rows[i]["核稿绩效"]}";
+
+                        if (!temRow["处理人"].ToString().Contains(temDt.Rows[i]["处理人"].ToString()))
+                        {
+                            temRow["处理人"] = string.IsNullOrEmpty(temRow["处理人"].ToString()) ? temDt.Rows[i]["处理人"] : $"{temRow["处理人"]},{temDt.Rows[i]["处理人"]}";
+                            temRow["处理人等级"] = string.IsNullOrEmpty(temRow["处理人等级"].ToString()) ? temDt.Rows[i]["处理人等级"] : $"{temRow["处理人等级"]},{temDt.Rows[i]["处理人等级"]}";
+                        }
+
+                        temRow["严重超期备注原因"] = string.IsNullOrEmpty(temRow["严重超期备注原因"].ToString()) ? temDt.Rows[i]["严重超期备注原因"] : $"{temRow["严重超期备注原因"]}{temDt.Rows[i]["严重超期备注原因"]}";
+                    }
+
+                    iTable = iEnd;
+                    #endregion
+
+                    temRow["是否一致"] = "不一致";
+                    temRow["不一致原因"] = "系统中没有,Excel中有";
+                    retTable.Rows.Add(temRow);
+                    iTable++;
+                }
+            }
+
+
+            NPOIExcel.DataTableToExcel(retTable, "c:\\temp\\202112-系统线下绩效记录对比.xlsx");
+
+            
+        }
+
         private List<StaffStatistics> _calItemJX(CalMonth calMonth, List<VerifyCoefficient> verifyCoefficients, PerformanceItem item,spDbContext spDb)
         {
+            //if(item.CaseNo == "PACN2116373")
+            //{
+            //    System.Diagnostics.Debug.WriteLine("");
+            //}
             System.Collections.Hashtable doPersonsBL = new System.Collections.Hashtable();
 
             bool isPJFP = true;
@@ -676,7 +1204,7 @@ namespace wispro.sp.api.Controllers
                 //spDb.Entry(itemStaff.DoPerson).Reference(b => b.StaffGrade).Load();
 
                 #region 计算审核人绩效点数,核稿人绩效点数按照核稿人与个处理人的核稿系数计算后加总,没有找到核稿系数(比如同级别),核稿系数为0
-                if (item.ReviewerId != null && item.Type != "专案")
+                if (item.ReviewerId != null && item.Type != "专案" && item.ItemStaffs.FirstOrDefault(s=>s.DoPersonId == item.ReviewerId) == null)
                 {
 
                     #region 取审核人等级审核等级系数
@@ -868,31 +1396,52 @@ namespace wispro.sp.api.Controllers
         /// <returns></returns>
         public List<StaffStatistics> CalMyStatistics(int year,int month, int? userid=null)
         {
-            CalMonth calMonth = Context.CalMonths.Where<CalMonth>(c => c.Month == month && c.Year == year).FirstOrDefault();
+            object retList;
+            string strKey = $"CalMyStatistics:{year}-{month}-{userid}";
             
-            if(calMonth == null)
-            {
-                return null;
-            }
-            else
+            if(!MyMemoryCache.TryGetValue(strKey,out retList))
             {
-                if(calMonth.Status  == 4)
+                CalMonth calMonth = Context.CalMonths.Where<CalMonth>(c => c.Month == month && c.Year == year).FirstOrDefault();
+
+                if (calMonth == null)
+                {
+                    return null;
+                }
+                else
                 {
-                    //已归档,归档数据库中直接取出记录
-                    if (userid == null)
+                    if (calMonth.Status == 4)
                     {
-                        return Context.StaffStatistics.Where<StaffStatistics>(s => s.CalMonthId == calMonth.Id).ToList<StaffStatistics>();
+                        //已归档,归档数据库中直接取出记录
+                        if (userid == null)
+                        {
+                            retList = Context.StaffStatistics.Where<StaffStatistics>(s => s.CalMonthId == calMonth.Id).ToList<StaffStatistics>();
+                        }
+                        else
+                        {
+                            retList = Context.StaffStatistics.Where<StaffStatistics>(s => s.CalMonthId == calMonth.Id && s.StaffId == userid).ToList<StaffStatistics>();
+                        }
                     }
                     else
                     {
-                        return Context.StaffStatistics.Where<StaffStatistics>(s => s.CalMonthId == calMonth.Id && s.StaffId == userid).ToList<StaffStatistics>();
+                        retList = _CalMyStatistics(calMonth, userid);
                     }
-                }
-                else
-                {
-                    return _CalMyStatistics(calMonth, userid);
+
+                    // Set cache options.
+                    var cacheEntryOptions = new MemoryCacheEntryOptions()
+                        // Keep in cache for this time, reset time if accessed.
+                        .SetSlidingExpiration(TimeSpan.FromHours(1));
+
+                    // Save data in cache.
+                    MyMemoryCache.SetValue(strKey, retList);
+
+                    return (List<StaffStatistics>)retList;
                 }
             }
+            else
+            {
+                return (List<StaffStatistics>)retList;
+            }
+           
         }
         
         private string GetExpress(IList<FieldCondition> conditions)
@@ -1338,7 +1887,7 @@ namespace wispro.sp.api.Controllers
 
         public PerformanceItem GetItemInfoByCaseStage(string CaseNo, string DoItem,string caseStage)
         {
-            var retObj = Context.PerformanceItems.FirstOrDefault<PerformanceItem>(p => p.CaseNo == CaseNo.Trim() 
+            var retObj = Context.PerformanceItems.Include(p=>p.Customer).FirstOrDefault<PerformanceItem>(p => p.CaseNo == CaseNo.Trim() 
             && p.DoItem == DoItem.Trim() && p.CaseStage == caseStage);
 
             if (retObj == null)

+ 19 - 5
wispro.sp.api/Controllers/StaffController.cs

@@ -263,7 +263,7 @@ namespace wispro.sp.api.Controllers
                         editObject.Memo = saveUser.staff.Memo;
                         editObject.Mobile = saveUser.staff.Mobile;
                         editObject.Name = saveUser.staff.Name;
-                        editObject.Password = saveUser.staff.Password;
+                        editObject.Password = utility.MD5Utility.GetMD5(saveUser.staff.Password);
                         editObject.Sex = saveUser.staff.Sex;
                         editObject.StaffGradeId = saveUser.staff.StaffGradeId;
                         editObject.Status = saveUser.staff.Status;
@@ -326,13 +326,27 @@ namespace wispro.sp.api.Controllers
                         }
                         else
                         {
+                            
+
+                            if(string.IsNullOrEmpty(staff.Account) || string.IsNullOrEmpty(staff.Password))
+                            {
+                                ret.Success = false;
+                                ret.ErrorMessage = $"用户名或密码没有设定";
+
+                                return ret;
+                            }
+                            else
+                            {
+                                staff.Password = utility.MD5Utility.GetMD5(staff.Password);
+                            }
+
                             Context.Staffs.Add(staff);
                             Context.SaveChanges();
 
                             DepartmentPosition dp = new DepartmentPosition();
                             dp.departmentId = saveUser.deptId;
                             dp.PositionId = saveUser.deptId;
-                            dp.StaffId = temStaff.Id;
+                            dp.StaffId = staff.Id;
                             Context.DepartmentPositions.Add(dp);
                         }
                     }
@@ -351,7 +365,7 @@ namespace wispro.sp.api.Controllers
                             editObject.Memo = staff.Memo;
                             editObject.Mobile = staff.Mobile;
                             editObject.Name = staff.Name;
-                            editObject.Password = staff.Password;
+                            editObject.Password = utility.MD5Utility.GetMD5(staff.Password); 
                             editObject.Sex = staff.Sex;
                             editObject.StaffGradeId = staff.StaffGradeId;
                             editObject.Status = staff.Status;
@@ -424,7 +438,7 @@ namespace wispro.sp.api.Controllers
                         temStaff.Memo = staff.Memo;
                         temStaff.Mobile = staff.Mobile;
                         temStaff.Name = staff.Name;
-                        temStaff.Password = staff.Password;
+                        temStaff.Password = utility.MD5Utility.GetMD5(staff.Password);
                         temStaff.Sex = staff.Sex;
                         temStaff.StaffGradeId = staff.StaffGradeId;
                         temStaff.Status = staff.Status;
@@ -456,7 +470,7 @@ namespace wispro.sp.api.Controllers
                         editObject.Memo = staff.Memo;
                         editObject.Mobile = staff.Mobile;
                         editObject.Name = staff.Name;
-                        editObject.Password = staff.Password;
+                        editObject.Password = utility.MD5Utility.GetMD5(staff.Password); //staff.Password;
                         editObject.Sex = staff.Sex;
                         editObject.StaffGradeId = staff.StaffGradeId;
                         editObject.Status = staff.Status;

+ 5 - 2
wispro.sp.api/Job/ImportReportJob.cs

@@ -147,7 +147,7 @@ namespace wispro.sp.api.Job
             string filename = $"{ReportName.Trim()}.xlsx";
             string strFilePath = System.IO.Path.Combine(strFileSavePath, filename);
             string strFinalPath = System.IO.Path.Combine(strFileSavePath, $"{calMonth.Year}{calMonth.Month}-{filename}");
-            InputPerformanceItem(strFilePath, true, false, 1, calMonth, isFirstOA);
+            InputPerformanceItem(strFinalPath, true, false, 1, calMonth, isFirstOA);
             System.IO.File.Move(strFilePath, strFinalPath);
         }
 
@@ -283,6 +283,7 @@ namespace wispro.sp.api.Job
             return Items;
         }
 
+
         private Task InputPerformanceItem(string strExcelFile, bool isColumnName, bool ignorHideRows = false, int ColumnNameRow = 0, CalMonth calMonth = null, bool isFirstOAFile = false)
         {
             DataTable dt = NPOIExcel.ExcelToDataTable(strExcelFile, isColumnName, ignorHideRows, ColumnNameRow);
@@ -323,7 +324,9 @@ namespace wispro.sp.api.Job
                 {
                     if (!InValidDoItem.Contains(item.DoItem))
                     {
-                        SavePerformanceItem(item,rules);
+                        
+                        SavePerformanceItem(item, rules);
+                        
                         strDebug = $"{strDebug}\t保存成功";
                     }
                     else

+ 74 - 2
wispro.sp.api/Job/UpdateJXDataFromIPEasyJob.cs

@@ -4,6 +4,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
 using wispro.sp.entity;
 
@@ -189,7 +190,77 @@ namespace wispro.sp.api.Job
             }
 
         }
-        
+
+        public void RefreshFromIPEasy(int type)
+        {
+            System.Threading.Thread t = new Thread(new ParameterizedThreadStart(RefreshFromIPEasy_BatchThread));
+            t.Start(type);
+        }
+        /// <summary>
+        /// 批量从IPEasy中更新数据
+        /// </summary>
+        /// <param name="type">
+        /// 0:所有;
+        /// 1:BasePoint为空记录;
+        /// 2:新申请案件系数为空记录;
+        /// 3:BasePoint为空记录 或者 新申请案件系数为空记录
+        /// </param>
+        /// <returns></returns>
+        private void RefreshFromIPEasy_BatchThread(object type)
+        {
+            spDbContext spDb = new spDbContext();
+
+            var Results = spDb.PerformanceItems.Include(p=>p.Customer).Where(p => 
+                (p.AgentFeedbackMemo != "已算绩效" || p.AgentFeedbackMemo == null) 
+                && p.CalMonth.Status == 0 
+                && !p.CaseNo.StartsWith("J"));
+
+            switch (type.ToString())
+            {
+                case "1":
+                    Results = Results.Where(p => p.BasePoint == null);
+                    break;
+                case "2":
+                    Results = Results.Where(p => p.Type == "新申请" && p.CaseCoefficient == "");
+                    break;
+                case "3":
+                    Results = Results.Where(p => p.BasePoint == null || (p.DoItem == "新申请" && p.CaseCoefficient == ""));
+                    break;
+            }
+
+            var listItems = Results.ToList();
+            int i = 0;
+            foreach (var Item in listItems)
+            {
+
+                int iTryCount = 0;
+            TryAgain:
+                try
+                {
+                    iTryCount++;
+
+                    UpdateFromIPEasy(Item, spDb);
+
+                    Log($"{DateTime.Now}\t{++i}/{listItems.Count}\t{Item.CaseNo}");
+                    System.Diagnostics.Debug.WriteLine($"{DateTime.Now}\t{i}/{listItems.Count}\t{Item.CaseNo}");
+                    //}
+                }
+                catch (Exception ex)
+                {
+                    if (iTryCount <= 3)
+                    {
+                        goto TryAgain;
+                    }
+
+                    System.Diagnostics.Debug.WriteLine(ex.ToString());
+                    Log($"{DateTime.Now}\t{++i}/{listItems.Count}\t{Item.CaseNo}\t更新失败!");
+                }
+                
+            }
+
+
+        }
+
         public Task Execute(IJobExecutionContext context)
         {
             spDbContext spDb = new spDbContext();
@@ -198,6 +269,7 @@ namespace wispro.sp.api.Job
                 ((p.AgentFeedbackMemo != "已算绩效" || p.AgentFeedbackMemo==null ) && p.CalMonth.Status == 0 && !p.CaseNo.StartsWith("J")))
                 .Include(p=>p.Reviewer)
                 .Include(p=>p.CalMonth)
+                .Include(p=>p.Customer)
                 .ToList<PerformanceItem>();
            
 
@@ -238,7 +310,7 @@ namespace wispro.sp.api.Job
         private void Log(string strMessage)
         {
             StreamWriter sw = File.AppendText("c:\\temp\\log.txt");
-            sw.Write($"{strMessage}\r\n");
+            sw.WriteLine($"{strMessage}");
             sw.Flush();
             sw.Close();
             sw.Dispose();

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

@@ -74,6 +74,8 @@ namespace wispro.sp.api
 
             services.AddSingleton<IFileTaskService, FileTaskCacheService>();
 
+            services.AddMemoryCache();
+
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

+ 27 - 0
wispro.sp.api/Utility/MyMemeryCache.cs

@@ -0,0 +1,27 @@
+using Microsoft.Extensions.Caching.Memory;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.api.Utility
+{
+    public class MyMemoryCache
+    {
+        static IMemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
+
+        public static bool TryGetValue(string strKey,out object outValue)
+        {
+            return _cache.TryGetValue(strKey, out outValue);
+        }
+
+        public static void SetValue(string strKey,object value)
+        {
+            var cacheEntryOptions = new MemoryCacheEntryOptions()
+                    // Keep in cache for this time, reset time if accessed.
+                    .SetSlidingExpiration(TimeSpan.FromHours(1));
+
+            _cache.Set(strKey, value,cacheEntryOptions);
+        }
+    }
+}

+ 42 - 29
wispro.sp.api/Utility/Utility.cs

@@ -26,37 +26,70 @@ namespace wispro.sp.api.Utility
                 var interpreter = new Interpreter(options)
                     .Reference(typeof(System.Linq.Enumerable));
 
-                //System.Diagnostics.Debug.WriteLine(rule.Rule);
+                
 
                 try
                 {
                     //item.ApplicationType
-                    Func<PerformanceItem, bool> func = interpreter.ParseAsDelegate<Func<PerformanceItem, bool>>(rule.Rule, "p");
+                    Func<PerformanceItem,Customer, bool> func = interpreter.ParseAsDelegate<Func<PerformanceItem,Customer,bool>>(rule.Rule, "p","Customer");
 
-                    bool result = func.Invoke(item);
+                    bool result = func.Invoke(item,item.Customer);
 
                     if (result)
                     {
+                        if (((item.Customer.Name.Contains("OPPO") && (item.CaseNo.StartsWith("PAUS") || item.ApplicationType=="实用新型")) || rule.PointExpress.Contains("p.WordCount")) && item.DoItem == "新申请")
+                        {
+                            System.Diagnostics.Debug.WriteLine("");
+                        }
                         var temString = rule.PointExpress;
                         if (!rule.PointExpress.Contains("."))
                         {
                             temString = $"{rule.PointExpress.Trim()}.0";
                         }
 
-                        //if (temString.Contains("p."))
-                        //{
-                        //    System.Diagnostics.Debug.WriteLine(temString);
-                        //}
-
                         var target = new Interpreter().SetVariable("p", item);
+                        //target.SetVariable("Customer", item.Customer);
+
+                        
+
                         double? temPoint = (double?)target.Eval(temString);
 
+                        if(temString.Contains("p.WordCount") && item.DoItem == "新申请" && temPoint.HasValue)
+                        {
+                            switch (item.DoItemCoefficient)
+                            {
+                                case "中-德":
+                                    if (1.9 > temPoint.Value)
+                                    {
+                                        rule.Type = "新申请";
+                                        temPoint = 1.9;
+                                    }
+                                   
+                                    break;
+                                case "中-英":
+                                    if (1.8 > temPoint.Value)
+                                    {
+                                        rule.Type = "新申请";
+                                        temPoint = 1.8;
+                                    }
+                                    break;
+                                case "英-中":
+                                    if (1.5 > temPoint.Value)
+                                    {
+                                        rule.Type = "新申请";
+                                        temPoint = 1.5;
+                                    }
+                                    break;
+
+                            }
+                        }
+
                         if(item.BasePoint != temPoint)
                         {
                             item.BasePoint = temPoint;
+                            item.Type = rule.Type;
                         }
                         
-                        item.Type = rule.Type;
                         break;
                     }
                 }
@@ -65,26 +98,6 @@ namespace wispro.sp.api.Utility
                 }
             }
             #endregion
-
-            //if(item.DoItem =="处理审查意见" && item.ApplicationType == "发明" && item.PreOastaffId != null)
-            //{
-            //    if(item.ItemStaffs.Where<ItemStaff>(s=>s.DoPersonId == item.PreOastaffId).Count() == 0)
-            //    {
-            //        switch (item.DoItemCoefficient)
-            //        {
-            //            case "实质":
-            //                item.BasePoint = 0.5;
-            //                break;
-            //            case "形式":
-            //                item.BasePoint = 0.2;
-            //                break;
-            //            case "非实质":
-            //                item.BasePoint = 0.3;
-            //                break;
-
-            //        }
-            //    }
-            //}
         }
 
         public static List<string> GetDoItemCeofficient(PerformanceItem item, List<BasePointRule> rules)

+ 2 - 2
wispro.sp.api/appsettings.json

@@ -11,7 +11,7 @@
     "DefaultConnect": "Data Source=(local);Initial Catalog=spDB;User ID=sa;Password=Lqftiu807005"
   },
 
-  "UpdateScheduleSetting": "00 15 09 1,2,3,4,5,6,7,8, * ? *",
+  "UpdateScheduleSetting": "00 03 09 *, * ? *",
 
   "ValidAudience": "StaffPerformance",
   "ValidIssuer": "http://localhost:39476",
@@ -28,7 +28,7 @@
     "Account": "caiyangl",
     "Password": "j)wx*lier*@3",
     "ChormeDriverPath": "D:\\source\\repos\\StaffPerformance\\packages\\ChormeDriver\\97.0.4692.71",
-    "ScheduleSetting": "00 55 10 3 * ? *",
+    "ScheduleSetting": "00 22 14 * * ? *",
     "IPEasyWeb": "http://47.106.221.167/Login.aspx"
   },
 

+ 1 - 1
wispro.sp.api/spDbContext.cs

@@ -99,7 +99,7 @@ namespace wispro.sp.api
                 //ConfigurationManager.AppSettings["ValidAudience"]
             }
 
-            _ = optionsBuilder.UseLoggerFactory(LoggerFactory);
+            //_ = optionsBuilder.UseLoggerFactory(LoggerFactory);
         }
 
         protected override void OnModelCreating(ModelBuilder modelBuilder)

+ 1 - 0
wispro.sp.api/wispro.sp.api.csproj

@@ -19,6 +19,7 @@
     <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
     <PackageReference Include="Quartz" Version="3.3.3" />
     <PackageReference Include="Svg" Version="3.3.0" />
+    <PackageReference Include="System.Runtime.Caching" Version="6.0.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 2 - 2
wispro.sp.utility/NPOIExcle.cs

@@ -21,7 +21,7 @@ namespace wispro.sp.utility
         /// <param name="ColumnNameRow">列名的所在行,0为第一行</param>
         /// <param name="IgnoreZeroHightRow">是否忽略隐藏行</param>
         /// <returns>返回datatable</returns>
-        public static DataTable ExcelToDataTable(string filePath, bool isColumnName,bool IgnoreZeroHightRow = false,int ColumnNameRow=0)
+        public static DataTable ExcelToDataTable(string filePath, bool isColumnName,bool IgnoreZeroHightRow = false,int ColumnNameRow=0,int iSheet=0)
         {
             DataTable dataTable = null;
             FileStream fs = null;
@@ -45,7 +45,7 @@ namespace wispro.sp.utility
 
                     if (workbook != null)
                     {
-                        sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
+                        sheet = workbook.GetSheetAt(iSheet);//读取第一个sheet,当然也可以循环读取每个sheet
                         dataTable = new DataTable();
                         if (sheet != null)
                         {

+ 148 - 0
wispro.sp.web/Components/SSTable.razor

@@ -0,0 +1,148 @@
+@using Microsoft.Extensions.Configuration
+@inject IConfiguration configuration
+
+@if (Datas != null)
+{
+    <AntDesign.Table @ref="table" @bind-PageIndex="_pageIndex" @bind-PageSize="_pageSize"
+                     TItem="AppealRecord"
+                     Loading="_loading"
+                     DataSource="@Datas"
+                     OnRow="OnRow"
+                     Total="_total"
+                     ScrollX="1150" Size="TableSize.Small" Bordered
+                     >
+        <ChildContent>
+            <AntDesign.Column Title="序号" TData="string" Width="80">
+                <center> @serialNumber(_pageIndex, _pageSize, context)</center>
+            </AntDesign.Column>
+            <AntDesign.Column Title="申诉时间"  Width="150" @bind-Field="@context.CreateTime" Format="yyyy-MM-dd hh:mm:ss" Sortable Filterable />
+            <AntDesign.Column Title="申诉类型"  Width="160" DataIndex="Type.Name" TData="string" Sortable Filterable />
+            <AntDesign.Column Title="申诉人" Width="90" DataIndex="Creater.Name" TData="string" Sortable Filterable />
+            <AntDesign.Column Title="案号" Width="100" DataIndex="Item.CaseNo" TData="string" Sortable Filterable />
+            <AntDesign.Column Title="案件名称" Width="300" DataIndex="Item.CaseName" TData="string" Sortable Filterable />
+            <AntDesign.Column Title="审核人" Width="90" DataIndex="Reviewer.Name" TData="string" Sortable Filterable />
+            <AntDesign.Column Title="状态"  Width="80" TData="string" Sortable>
+                <Template>
+                    @if (context.State == 0)
+                    {
+                        <span>待审核</span>
+                    }
+                    else
+                    {
+                        <span>已审核</span>
+                    }
+                </Template>
+            </AntDesign.Column>
+            @if (ShowAction) { 
+            <ActionColumn>
+                <Space>
+                    @if (context.State == 0 && context.ReviewerId == UserId)
+                    {
+                        <SpaceItem><Button Type="@ButtonType.Link" OnClick="() => _OnReview(context)">审核</Button></SpaceItem>
+                    }
+                    @if (context.State == 0 && (context.ReviewerId == UserId || context.CreaterId == UserId))
+                    {
+                        <SpaceItem><Button Type="@ButtonType.Link" OnClick="() => _OnChangeReviewer(context)">变更审核人</Button></SpaceItem>
+                    }
+                </Space>
+            </ActionColumn>
+            }
+        </ChildContent>
+        <PaginationTemplate>
+            <div style="display: flex; align-items: center">
+                <Pagination Class="my-custom-pagination"
+                            Total="@_total"
+                            PageSize="@_pageSize"
+                            Current="@_pageIndex"
+                            ShowSizeChanger="@true"
+                            OnChange="HandlePageChange" />
+            </div>
+        </PaginationTemplate>
+    </AntDesign.Table>
+}
+else
+{
+    <Spin></Spin>
+}
+
+<Drawer Width="600" Visible="_ShowDetail" Placement="right" Title='("申诉详情")' OnClose="_=>CloseDetail()">
+
+
+    @if (CurrentAppealRecord != null && CurrentAppealRecord.Item != null)
+    {
+
+        <div>
+            <Row>
+                <AntDesign.Col Span="4"><b>我方文号:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@CurrentAppealRecord.Item.CaseNo</AntDesign.Col>
+                <AntDesign.Col Span="4"><b>处理事项:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@CurrentAppealRecord.Item.DoItem</AntDesign.Col>
+            </Row>
+
+            <Row>
+                <AntDesign.Col Span="4"><b>案件名称:</b></AntDesign.Col>
+                <AntDesign.Col Span="20">@CurrentAppealRecord.Item.CaseName</AntDesign.Col>
+            </Row>
+        </div>
+
+    }
+
+
+    @if (_FieldValues != null)
+    {
+        <Divider Orientation="left" Style="font-weight:bold">申诉人:@CurrentAppealRecord.Creater.Name  申诉时间:@CurrentAppealRecord.CreateTime.ToString("yyyy-MM-dd")  </Divider>
+
+        foreach (InputFieldValue temValue in _FieldValues)
+        {
+            <Row>
+                <AntDesign.Col Span="2"></AntDesign.Col>
+                <AntDesign.Col Span="8"><b>@temValue.InputField.FieldName:</b></AntDesign.Col>
+                <AntDesign.Col Span="14">@temValue.Value</AntDesign.Col>
+            </Row>
+        }
+    }
+    <Divider />
+
+    @if (_ReviewValues != null)
+    {
+        <Divider Orientation="left" Style="font-weight:bold">审核人:@CurrentAppealRecord.Reviewer.Name  审核时间:@CurrentAppealRecord.ReviewTime?.ToString("yyyy-MM-dd")  </Divider>
+        foreach (InputFieldValue temValue in _ReviewValues)
+        {
+            <Row>
+                <AntDesign.Col Span="2"></AntDesign.Col>
+                <AntDesign.Col Span="8"><b>@temValue.InputField.FieldName:</b></AntDesign.Col>
+                <AntDesign.Col Span="14">@temValue.Value</AntDesign.Col>
+            </Row>
+        }
+    }
+
+    @if (attachFiles != null && attachFiles.Count > 0)
+    {
+        <Divider Orientation="left" Style="font-weight:bold">附件</Divider>
+
+        <Row>
+            <AntDesign.Col Span="2"></AntDesign.Col>
+            <AntDesign.Col Span="14">文件名称</AntDesign.Col>
+            <AntDesign.Col Span="8">上传人</AntDesign.Col>
+        </Row>
+        @foreach (AttachFile file in attachFiles)
+        {
+            <Row>
+                <AntDesign.Col Span="2"></AntDesign.Col>
+                <AntDesign.Col Span="14"><a href="@($"{configuration.GetValue<string>("APIUrl")}AttachFiles/Download?id={file.Id}")">@file.Name </a></AntDesign.Col>
+                <AntDesign.Col Span="8">@file.UploadUser.Name</AntDesign.Col>
+            </Row>
+        }
+    }
+</Drawer>
+
+<style>
+    .my-custom-pagination {
+        margin: 15px 0;
+    }
+
+        .my-custom-pagination .ant-pagination-item,
+        .my-custom-pagination .ant-pagination-item-link {
+            border-radius: 100%;
+        }
+</style>

+ 141 - 0
wispro.sp.web/Components/SSTable.razor.cs

@@ -0,0 +1,141 @@
+using AntDesign;
+using AntDesign.TableModels;
+using Microsoft.AspNetCore.Components;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+using wispro.sp.web.Models;
+using wispro.sp.web.Services;
+
+namespace wispro.sp.web.Components
+{
+    public partial class SSTable
+    {
+        protected AntDesign.Table<AppealRecord> table;
+        AntDesign.Column<AppealRecord> column;
+        int _total;
+        int _pageIndex=1;
+        int _pageSize=10;
+        bool _loading;
+        
+        [Parameter]
+        public List<AppealRecord> Datas { get; set; }
+
+        //[Inject] protected UserService _userService { get; set; }
+
+        [Inject] protected AppealTypeService _atService { get; set; }
+
+        [Parameter]
+        public bool ShowAction { get; set; } = true;
+
+        [Parameter]
+        public int? UserId { get; set; }
+
+        AppealRecord CurrentAppealRecord;
+        bool _ShowDetail;
+        List<InputFieldValue> _FieldValues;
+        List<InputFieldValue> _ReviewValues;
+        List<AttachFile> attachFiles;
+        async Task ShowDetail(AppealRecord appealRecord)
+        {
+            
+            CurrentAppealRecord = appealRecord;
+            _FieldValues = await _atService.GetInputFieldValues(appealRecord.Id, 0);
+            attachFiles = await _atService.GetAppealRecordAttachFiles(CurrentAppealRecord.Id);
+
+            if (appealRecord.State > 0)
+            {
+                _ReviewValues = await _atService.GetInputFieldValues(appealRecord.Id, 1);
+            }
+
+            _ShowDetail = true;
+            StateHasChanged();
+        }
+
+        void CloseDetail()
+        {
+            _ShowDetail = false;
+        }
+
+        Dictionary<string, object> OnRow(RowData<AppealRecord> row) => new()
+        {
+            ["id"] = row.Data.Id,
+            ["onclick"] = ((Action)delegate
+            {
+                _ = ShowDetail(row.Data);
+            })
+        };
+
+        //CurrentUser currentUser;
+
+        [Parameter]
+        public EventCallback<AppealRecord> OnReview { get; set; }
+
+        [Parameter]
+        public EventCallback<AppealRecord> OnChangeReviewer { get; set; }
+
+        protected override void OnParametersSet()
+        {
+            _total = Datas.Count;
+            base.OnParametersSet();
+        }
+
+        public int serialNumber(int pageIndex, int pageSize, AppealRecord appealRecord)
+        {
+            //int iIndex = 0;
+            //foreach (AppealRecord sf in Datas)
+            //{
+            //    iIndex++;
+
+            //    if (sf == appealRecord)
+            //    {
+            //        break;
+            //    }
+            //}
+
+            var queryModel = table.GetQueryModel();
+
+            if (table.SortDirections.Count() > 0)
+            {
+                Console.WriteLine(table.SortDirections[0].Name);
+                Console.WriteLine(table.SortDirections[0].Value);
+            }
+
+            return Datas.IndexOf(appealRecord) + 1;
+
+            //return iIndex;
+        }
+
+        private void HandlePageChange(PaginationEventArgs args)
+        {
+            if (_pageIndex != args.Page)
+            {
+                _pageIndex = args.Page;
+            }
+
+            if (_pageSize != args.PageSize)
+            {
+                _pageSize = args.PageSize;
+            }
+        }
+
+        private async void _OnReview(AppealRecord appealRecord)
+        {
+            if (OnReview.HasDelegate)
+            {
+                await OnReview.InvokeAsync(appealRecord);
+            }
+        }
+        
+
+        private async void _OnChangeReviewer(AppealRecord appealRecord)
+        {
+            if (OnChangeReviewer.HasDelegate)
+            {
+                await OnChangeReviewer.InvokeAsync(appealRecord);
+            }
+        }
+    }
+}

+ 3 - 2
wispro.sp.web/Pages/AppCase/AppealRecords.razor

@@ -103,7 +103,8 @@ RenderFragment avatar = @<Avatar Src="https://zos.alipayobjects.com/rmsportal/OD
         </Collapse>
     </Content>
     <ChildContent>
-        <div style="height:600px;width:100%;overflow:auto;background:#FFFFFF;" id="div-Container">
+        <wispro.sp.web.Components.SSTable Datas="@showRecords" ShowAction="false"></wispro.sp.web.Components.SSTable>
+        @*<div style="height:600px;width:100%;overflow:auto;background:#FFFFFF;" id="div-Container">
             <AntList DataSource="@showRecords" TItem="AppealRecord">
                 <ListItem OnClick="()=>ShowDetail(context)">
                     <ListItemMeta AvatarTemplate="avatar" Description="@GetDescription(context)">
@@ -184,7 +185,7 @@ RenderFragment avatar = @<Avatar Src="https://zos.alipayobjects.com/rmsportal/OD
                     }
                 }
             </Drawer>
-        </div>
+        </div>*@
 
     </ChildContent>
 </PageContainer>

+ 10 - 4
wispro.sp.web/Pages/Organization/Department.razor

@@ -130,8 +130,14 @@
     <Form Model="EditingStaff" LabelColSpan="6"
           WrapperColSpan="16">
         <FormItem Label="姓名">
-            <wispro.sp.web.Components.StaffAutoComplete OnSelected="UserSelected" @bind-SelectName="@context.Name" />
-            @*<Input @bind-Value="@context.Name" />*@
+            @if (_isAdd)
+            {
+                <Input @bind-Value="@context.Name" />
+            }
+            else
+            {
+                <wispro.sp.web.Components.StaffAutoComplete OnSelected="UserSelected" @bind-SelectName="@context.Name" />
+            }
         </FormItem>
         <FormItem Label="岗位状态">
             <Input @bind-Value="@context.Status" />
@@ -167,7 +173,7 @@
         </FormItem>
 
         <FormItem Label="邮箱">
-            <DatePicker @bind-Value="@context.Mail" />
+            <Input @bind-Value="@context.Mail" />
         </FormItem>
 
         <FormItem Label="入职时间">
@@ -184,7 +190,7 @@
                 <Input @bind-Value="@context.Account" />
             </FormItem>
 
-            <FormItem Label="账号">
+            <FormItem Label="密码">
                 <Input @bind-Value="@context.Password" Type="password" />
             </FormItem>
         }

+ 18 - 39
wispro.sp.web/Pages/Welcome.razor

@@ -51,45 +51,10 @@
                             <TabPane Key="1">
                                 <TabTemplate>信息动态</TabTemplate>
                                 <ChildContent>
-                                    <AntList TItem="AppealRecord" DataSource="@AppealRecords" 
-                                                       Class="activitiesList"
-                                                       Size="large"
-                                                       ItemLayout="ListItemLayout.Horizontal">
-                                        <ListItem>
-                                            <ListItemMeta Avatar="@context.Creater.Name" Description="@(context.ReviewTime.HasValue?context.ReviewTime.Value.ToFriendlyDisplay():context.CreateTime.ToFriendlyDisplay())">
-                                                <TitleTemplate>
-                                                    <span>
-                                                        <span class="event">
-                                                            @if (context.ReviewTime.HasValue)
-                                                            {
-                                                                if (context.CreaterId == _CurrentUser.Userid)
-                                                                {
-                                                                    <span>(@context.Reviewer.Name 在 @context.ReviewTime.Value.ToFriendlyDisplay() 审核了你提交的 @(context.Item==null?"":context.Item.CaseNo) @context.Type.Name")</span> }
-                                                                else
-                                                                {
-                                                                    if (context.ReviewerId != _CurrentUser.Userid)
-                                                                    {
-                                                                        <span>(您在 @context.CreateTime.ToFriendlyDisplay()提交的 @(context.Item==null?"":context.Item.CaseNo) @context.Type.Name,@context.Reviewer.Name 已于 @context.ReviewTime.Value.ToFriendlyDisplay() 审核完成"</span>
-                                                                    }
-                                                                }
-                                                            }
-                                                            else
-                                                            {
-                                                                if (context.CreaterId == _CurrentUser.Userid)
-                                                                {
-                                                                    <span>您在 @context.CreateTime.ToFriendlyDisplay() 提交的 @(context.Item==null?"":context.Item.CaseNo) @context.Type.Name ,正在等待 @context.Reviewer.Name 审核!"</span>}
-                                                                else
-                                                                {
-                                                                    <span>@context.Creater.Name 在 @context.CreateTime.ToFriendlyDisplay() 提交的 @(context.Item==null?"":context.Item.CaseNo) @context.Type.Name ,请您尽快<Button Danger Type="@ButtonType.Link" OnClick="()=>ShowModel(context)">审核</Button>!</span>
-                                                                }
-
-                                                            }
-                                                        </span>
-                                                    </span>
-                                                </TitleTemplate>
-                                            </ListItemMeta>
-                                        </ListItem>
-                                    </AntList>
+                                    @if (AppealRecords != null && AppealRecords.Count > 0)
+                                    {
+                                        <SSTable UserId="@_CurrentUser.Userid" Datas="@AppealRecords" OnReview="ShowModel" OnChangeReviewer="ShowChangeReviewer"></SSTable>
+                                    }
                                 </ChildContent>
                             </TabPane>
                             @if (WaitingReviewProjects != null && WaitingReviewProjects.Count > 0)
@@ -131,3 +96,17 @@
         </Row>
     </ChildContent>
 </PageContainer>
+
+<Modal Title="变更审核人"
+       Visible="@_visible"
+       OnOk="@HandleOk"
+       OnCancel="@HandleCancel">
+
+    <Form Model="_ChangedRecord" LabelColSpan="6"
+          WrapperColSpan="16">
+        <FormItem Label="审核人变更为">
+            <StaffSelect @bind-StaffId="@_ChangedRecord.ReviewerId" StaffLists="_Staffs" />
+        </FormItem>
+    </Form>
+
+</Modal>

+ 74 - 3
wispro.sp.web/Pages/Welcome.razor.cs

@@ -9,6 +9,7 @@ using System.Text.Json;
 using AntDesign;
 using System;
 using wispro.sp.share;
+using Microsoft.AspNetCore.Components.Web;
 
 namespace wispro.sp.web.Pages
 {
@@ -48,9 +49,15 @@ namespace wispro.sp.web.Pages
         
         CalMonth HandlingMonth = null;
 
+        protected AntDesign.Table<AppealRecord> table;
+
+        int _total;
+        int _pageIndex = 1;
+        int _pageSize = 10;
+
         protected override async System.Threading.Tasks.Task OnInitializedAsync()
         {
-            await base.OnInitializedAsync();
+            //await base.OnInitializedAsync();
             _CurrentUser =await _userService.GetUser();
             //_user = _CurrentUser;
 
@@ -71,7 +78,7 @@ namespace wispro.sp.web.Pages
             if (_CurrentUser != null)
             {
                 AppealRecords = await _atService.GetUserAppeals(_CurrentUser.Userid);
-                
+                _total = AppealRecords.Count;
             }
 
             WaitingReviewProjects = await ProjectService.GetWaitingReviewProjects();
@@ -81,7 +88,37 @@ namespace wispro.sp.web.Pages
             
         }
 
-        async Task ShowModel(AppealRecord appealRecord)
+        private int serialNumber(int pageIndex, int pageSize, AppealRecord appealRecord)
+        {
+            int iIndex = 0;
+            foreach (AppealRecord sf in AppealRecords)
+            {
+                iIndex++;
+
+                if (sf == appealRecord)
+                {
+                    break;
+                }
+            }
+
+            return (pageIndex - 1) * pageSize + iIndex;
+        }
+
+        private void HandlePageChange(PaginationEventArgs args)
+        {
+            if (_pageIndex != args.Page)
+            {
+                _pageIndex = args.Page;
+            }
+
+            if (_pageSize != args.PageSize)
+            {
+                _pageSize = args.PageSize;
+            }
+        }
+
+        
+        async void ShowModel(AppealRecord appealRecord)
         {
             
             var templateOptions = new Models.ReviewerAppealModel();
@@ -167,6 +204,40 @@ namespace wispro.sp.web.Pages
             return i;
         }
 
+        #region 审核人变更
+        bool _visible;
+        List<Staff> _Staffs;
+        AppealRecord _ChangedRecord;
+
+        async Task ShowChangeReviewer(AppealRecord appealRecord)
+        {
+            _Staffs = await _userService.GetReviewers(appealRecord.ItemId, appealRecord.TypeId);
+            _ChangedRecord = appealRecord;
+            _visible = true;
+        }
+
+        private async System.Threading.Tasks.Task HandleOk(MouseEventArgs e)
+        {
+            var response = await _atService.ChangeReviewer(_ChangedRecord);
+
+            if (response.Success)
+            {
+                AppealRecords = await _atService.GetUserAppeals(_CurrentUser.Userid);
+
+                StateHasChanged();
+                _visible = false;
+            }
+            else
+            {
+                await _msgService.Error(response.ErrorMessage);
+            }
+        }
+
+        private void HandleCancel(MouseEventArgs e)
+        {
+            _visible = false;
+        }
+        #endregion
 
     }
 }

+ 1 - 1
wispro.sp.web/Program.cs

@@ -22,7 +22,7 @@ namespace wispro.sp.web
             builder.Services.AddAntDesign();
             builder.Services.Configure<ProSettings>(builder.Configuration.GetSection("ProSettings"));
 
-            builder.Services.AddScoped<IChartService, ChartService>();
+            //builder.Services.AddScoped<IChartService, ChartService>();
             builder.Services.AddScoped<IProjectService, ProjectService>();
             builder.Services.AddScoped<IUserService, UserService>();
             

+ 6 - 2
wispro.sp.web/Services/AppealTypeService.cs

@@ -201,7 +201,11 @@ namespace wispro.sp.web.Services
             //    throw new Exception(strContent);
             //}
         }
-        
-        
+
+        public async Task<ApiSaveResponse> ChangeReviewer(AppealRecord changedRecord)
+        {
+            var data = await _httpClient.Get<ApiSaveResponse>($"Appeal/ChangeRecordReviewer?RecordId={changedRecord.Id}&ReviewerId={changedRecord.ReviewerId}");
+            return data;
+        }
     }
 }

+ 78 - 131
wispro.sp.winClient/Form1.cs

@@ -188,7 +188,24 @@ namespace wispro.sp.winClient
        
         private async void button3_Click(object sender, EventArgs e)
         {
-            await RefreshPerformanceItem();
+            await Compare2DB();
+            //await RefreshPerformanceItem(1);
+
+            //await RefreshPerformanceItem(2);
+
+            //await RefreshPerformanceItem(3);
+
+            //await UserField2String(lstAJQL);
+
+            //await UserField2String(lstAJXS);
+
+            //await UserField2String(lstDoItemXS);
+
+            //await UserField2String(lstJXBL);
+
+            //await UserField2String(lstRXSX);
+
+            //await UserField2String(lstYZCQ);
 
             //await ImportUsers();
             //await InputPerformanceItem("c:\\temp\\21.01-21.11 工程师绩效报表-总表.xlsx", true, false, 0);
@@ -533,169 +550,99 @@ namespace wispro.sp.winClient
             }
 
         }
-
-        private async Task RefreshPerformanceItem()
+        private  async Task Compare2DB()
         {
+           
             if (Token == null)
             {
                 await Login();
             }
 
-            await RefreshItemAsync();
+            HttpClient http = CreateHttp();
+            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", Token.Token);
+            var data = await http.GetFromJsonAsync<PerformanceItem>($"{strAPIBaseUri}/api/PerformanceItem/CompareExcel2DB");
+
 
-            await GetDoItemInfo("PACN2027395", "处理审查意见", "一通");
+            //await GetDoItemInfo("PACN2027395", "处理审查意见", "一通");
 
         }
 
-        private async Task UserField2String()
+        private async Task RefreshPerformanceItem(int Type)
         {
             if (Token == null)
             {
                 await Login();
             }
 
-            //List<Staff> Reviewers = await getReviewers(14232, 1);
-
-            //Reviewers = await getReviewers(14232, 5);
+            await RefreshItemAsync(Type);
 
-            List<Staff> Staffs = await GetStaffsAsync();
+            //await GetDoItemInfo("PACN2027395", "处理审查意见", "一通");
 
-            List<UserField> lstUsers = new List<UserField>();
-
-
-            
-
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("柳芳", Staffs).ToString()
-            });
-
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("杨超", Staffs).ToString()
-            });
+        }
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("何倚雯", Staffs).ToString()
-            });
+        List<string> lstJXBL = new List<string>() {
+            "柳芳","杨超","何倚雯","李姣","张庆玲","李建民","李申","李莉","刘桂兰"
+            ,"唐双","瞿璨","张鹏","钟锦光","翁旋艺","钟子敏"
+        };
+        List<string> lstAJXS = new List<string>() {
+            "柳芳","杨超","何倚雯","李姣","张庆玲","李建民","李申","李莉","刘桂兰"
+            ,"唐双","瞿璨","张鹏","钟锦光","翁旋艺","钟子敏","邢丽霞",
+            "李庆波","黄瑜","程利","黎坚怡","舒丽亚","管自英","张晓薇","刘希"
+        };
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("李姣", Staffs).ToString()
-            });
+        List<string> lstDoItemXS = new List<string>() {
+            "吴继红","赖玲玲","郭竟微","陈鹤","王本鼎","高凌云","周煜祥","何丹风",
+            "田婵玉","孙心洁","陈舒敏","邢丽霞"
+        };
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("张庆玲", Staffs).ToString()
-            });
+        List<string> lstAJQL = new List<string>() {
+            "柳芳","杨超","何倚雯","李姣","张庆玲","李建民","李申","李莉","刘桂兰"
+            ,"唐双","瞿璨","张鹏","钟锦光","翁旋艺","吴继红","赖玲玲","郭竟微","陈鹤",
+            "王本鼎","高凌云","周煜祥","何丹风","田婵玉","孙心洁","陈舒敏","钟子敏",
+            "李庆波","黄瑜","程利","黎坚怡","舒丽亚","管自英","张晓薇","刘希"
+        };
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("李申", Staffs).ToString()
-            });
+        List<string> lstYZCQ = new List<string>() {
+            "吴继红","赖玲玲","郭竟微","陈鹤","王本鼎","高凌云","周煜祥","何丹风",
+            "田婵玉","孙心洁","陈舒敏"
+        };
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("李莉", Staffs).ToString()
-            });
+        List<string> lstRXSX = new List<string>() {
+            "夏敏","柳芳","杨超","何倚雯","李姣","张庆玲","李建民","李申","李莉","刘桂兰"
+            ,"唐双","瞿璨","张鹏","钟锦光","翁旋艺","钟子敏","李庆波","黄瑜","程利",
+            "黎坚怡","舒丽亚","管自英","张晓薇","刘希"
+        };
 
-            lstUsers.Add(new UserField()
+        private async Task UserField2String(List<string> lstList)
+        {
+            if (Token == null)
             {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("刘桂兰", Staffs).ToString()
-            });
+                await Login();
+            }
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("唐双", Staffs).ToString()
-            });
+            //List<Staff> Reviewers = await getReviewers(14232, 1);
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("瞿璨", Staffs).ToString()
-            });
+            //Reviewers = await getReviewers(14232, 5);
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("张鹏", Staffs).ToString()
-            });
+            List<Staff> Staffs = await GetStaffsAsync();
 
+            List<UserField> lstUsers = new List<UserField>();
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("钟锦光", Staffs).ToString()
-            });
-            lstUsers.Add(new UserField()
+            foreach(var name in lstList)
             {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("李建民", Staffs).ToString()
-            });
+                lstUsers.Add(new UserField()
+                {
+                    UserConditionType = UserConditionType.Staff,
+                    UserType = UserType.Staff,
+                    UserValue = GetStaff(name, Staffs).ToString()
+                });
+            }
+            
 
             JsonSerializerOptions options = new() { IgnoreNullValues = true };
             var strJson = System.Text.Json.JsonSerializer.Serialize(lstUsers, lstUsers.GetType(), options);
 
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("夏敏", Staffs).ToString()
-            });
-
-            
-            strJson = System.Text.Json.JsonSerializer.Serialize(lstUsers, lstUsers.GetType(), options);
-
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("钟子敏", Staffs).ToString()
-            });
-
-            strJson = System.Text.Json.JsonSerializer.Serialize(lstUsers, lstUsers.GetType(), options);
-
             System.Diagnostics.Debug.WriteLine(strJson);
-
-            lstUsers = new List<UserField>();
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Department,
-                Department = "1"
-            });
-
-            lstUsers.Add(new UserField()
-            {
-                UserConditionType = UserConditionType.Staff,
-                UserType = UserType.Staff,
-                UserValue = GetStaff("邢丽霞", Staffs).ToString()
-            });
-
-            strJson = System.Text.Json.JsonSerializer.Serialize(lstUsers, lstUsers.GetType(), options);
-
             
         }
         private int? GetStaff(string v, List<Staff> staffs)
@@ -822,7 +769,7 @@ namespace wispro.sp.winClient
             return retStr;
         }
 
-        string strAPIBaseUri = "https://47.106.221.167"; // "http://localhost:39476";//
+        string strAPIBaseUri = "http://localhost:39476";// "https://47.106.221.167"; //
 
         userToken Token;
         public async Task Login()
@@ -986,11 +933,11 @@ namespace wispro.sp.winClient
 
         }
 
-        private async Task<PerformanceItem> RefreshItemAsync()
+        private async Task<PerformanceItem> RefreshItemAsync(int type)
         {
             HttpClient http = CreateHttp();
             http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", Token.Token);
-            var data = await http.GetFromJsonAsync<PerformanceItem>($"{strAPIBaseUri}/api/PerformanceItem/RefreshBasePoint");
+            var data = await http.GetFromJsonAsync<PerformanceItem>($"{strAPIBaseUri}/api/PerformanceItem/RefreshFromIPEasy_Batch?type={type}");
 
             return data;
         }