CaseFileCompareController.cs 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142
  1. using AntDesign;
  2. using DocumentFormat.OpenXml.InkML;
  3. using DynamicExpresso;
  4. using Microsoft.AspNetCore.Authorization;
  5. using Microsoft.AspNetCore.Http;
  6. using Microsoft.AspNetCore.Mvc;
  7. using Microsoft.EntityFrameworkCore;
  8. using Microsoft.EntityFrameworkCore.Query;
  9. using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Data;
  14. using System.Diagnostics;
  15. using System.Dynamic;
  16. using System.Linq;
  17. using System.Linq.Expressions;
  18. using System.Text.RegularExpressions;
  19. using wispro.sp.api.AppealHandler;
  20. using wispro.sp.api.Job;
  21. using wispro.sp.api.Services;
  22. using wispro.sp.entity;
  23. using wispro.sp.entity.CompareCase;
  24. using wispro.sp.share;
  25. using static OneOf.Types.TrueFalseOrNull;
  26. namespace wispro.sp.api.Controllers
  27. {
  28. [Route("api/[controller]/[action]")]
  29. [ApiController]
  30. public class CaseFileCompareController : ControllerBase
  31. {
  32. spDbContext Context;
  33. IFileTaskService fileTaskService;
  34. public CaseFileCompareController(spDbContext context, IFileTaskService _fileTaskService)
  35. {
  36. Context = context;
  37. fileTaskService = _fileTaskService;
  38. }
  39. [Authorize]
  40. public ApiSaveResponse Save(CaseInfo caseInfo)
  41. {
  42. ApiSaveResponse ret = new ApiSaveResponse();
  43. ret.Success = true;
  44. using (Context.Database.BeginTransaction())
  45. {
  46. try
  47. {
  48. #region 客户处理
  49. if (caseInfo.Customer != null && !string.IsNullOrEmpty(caseInfo.Customer.Name))
  50. {
  51. var temCustomer = Context.Customers.Where<Customer>(c => c.Name == caseInfo.Customer.Name).FirstOrDefault();
  52. if (temCustomer == null)
  53. {
  54. temCustomer = new Customer() { Name = caseInfo.Customer.Name };
  55. //item.Customer.Id = 0;
  56. Context.Customers.Add(temCustomer);
  57. Context.SaveChanges();
  58. caseInfo.Customer = temCustomer;
  59. //item.CustomerId = item.Customer.Id;
  60. }
  61. else
  62. {
  63. caseInfo.Customer = temCustomer;
  64. }
  65. caseInfo.CustomerId = caseInfo.Customer.Id;
  66. caseInfo.Customer = null;
  67. }
  68. else
  69. {
  70. caseInfo.Customer = null;
  71. }
  72. #endregion
  73. #region 审核人
  74. if (caseInfo.Reviewer != null && !string.IsNullOrEmpty(caseInfo.Reviewer.Name))
  75. {
  76. var temReviewer = Context.Staffs.Where<Staff>(c => c.Name == caseInfo.Reviewer.Name).FirstOrDefault();
  77. if (temReviewer == null)
  78. {
  79. temReviewer = new Staff() { Name = caseInfo.Reviewer.Name };
  80. //item.Customer.Id = 0;
  81. Context.Staffs.Add(temReviewer);
  82. Context.SaveChanges();
  83. caseInfo.Reviewer = temReviewer;
  84. //item.CustomerId = item.Customer.Id;
  85. }
  86. else
  87. {
  88. caseInfo.Reviewer = temReviewer;
  89. }
  90. caseInfo.ReviewerId = caseInfo.Reviewer.Id;
  91. caseInfo.Reviewer = null;
  92. }
  93. else
  94. {
  95. caseInfo.Reviewer = null;
  96. }
  97. #endregion
  98. if (caseInfo.DRRAbstract != null) {
  99. Context.CaseCompareResults.Add(caseInfo.DRRAbstract);
  100. Context.SaveChanges();
  101. caseInfo.DRRAbstractId = caseInfo.DRRAbstract.Id;
  102. caseInfo.DRRAbstract = null;
  103. }
  104. if (caseInfo.DRRCalim != null)
  105. {
  106. Context.CaseCompareResults.Add(caseInfo.DRRCalim);
  107. Context.SaveChanges();
  108. caseInfo.DRRCalimId = caseInfo.DRRCalim.Id;
  109. caseInfo.DRRCalim = null;
  110. }
  111. if (caseInfo.DRRFulltext != null)
  112. {
  113. Context.CaseCompareResults.Add(caseInfo.DRRFulltext);
  114. Context.SaveChanges();
  115. caseInfo.DRRFulltextId = caseInfo.DRRFulltext.Id;
  116. caseInfo.DRRFulltext = null;
  117. }
  118. if (caseInfo.DRRAll != null)
  119. {
  120. Context.CaseCompareResults.Add(caseInfo.DRRAll);
  121. Context.SaveChanges();
  122. caseInfo.DRRAllId = caseInfo.DRRAll.Id;
  123. caseInfo.DRRAll = null;
  124. }
  125. if (caseInfo.RFRAbstract != null)
  126. {
  127. Context.CaseCompareResults.Add(caseInfo.RFRAbstract);
  128. Context.SaveChanges();
  129. caseInfo.RFRAbstractId = caseInfo.RFRAbstract.Id;
  130. caseInfo.RFRAbstract = null;
  131. }
  132. if (caseInfo.RFRCalim != null)
  133. {
  134. Context.CaseCompareResults.Add(caseInfo.RFRCalim);
  135. Context.SaveChanges();
  136. caseInfo.RFRCalimId = caseInfo.RFRCalim.Id;
  137. caseInfo.RFRCalim = null;
  138. }
  139. if (caseInfo.RFRFulltext != null)
  140. {
  141. Context.CaseCompareResults.Add(caseInfo.RFRFulltext);
  142. Context.SaveChanges();
  143. caseInfo.RFRFulltextId = caseInfo.RFRFulltext.Id;
  144. caseInfo.RFRFulltext = null;
  145. }
  146. if (caseInfo.RFRAll != null)
  147. {
  148. Context.CaseCompareResults.Add(caseInfo.RFRAll);
  149. Context.SaveChanges();
  150. caseInfo.RFRAllId = caseInfo.RFRAll.Id;
  151. caseInfo.RFRAll = null;
  152. }
  153. Context.CaseInfos.Add(caseInfo);
  154. Context.SaveChanges();
  155. Context.Database.CommitTransaction();
  156. }
  157. catch (Exception ex)
  158. {
  159. ret.Success = false;
  160. ret.ErrorMessage = ex.Message;
  161. Context.Database.RollbackTransaction();
  162. }
  163. }
  164. return ret;
  165. }
  166. public ListApiResponse<CaseInfo> QueryFilter(QueryFilter queryFilter)
  167. {
  168. ListApiResponse<CaseInfo> ret = new ListApiResponse<CaseInfo>();
  169. IQueryable<CaseInfo> response = NewMethod(queryFilter);
  170. int totals = response.Count();
  171. if (totals > 0 && totals < (queryFilter.PageIndex) * queryFilter.PageSize)
  172. {
  173. response = response
  174. .Include(pi => pi.DRRCalim)
  175. .Include(pi => pi.DRRAbstract)
  176. .Include(pi => pi.DRRFulltext)
  177. .Include(pi => pi.DRRAll)
  178. .Include(pi => pi.RFRCalim)
  179. .Include(pi => pi.RFRAbstract)
  180. .Include(pi => pi.RFRFulltext)
  181. .Include(pi => pi.RFRAll)
  182. .Include(pi => pi.Customer)
  183. .Include(pi => pi.Reviewer)
  184. .OrderConditions<CaseInfo>(queryFilter.Sorts)
  185. .Skip((queryFilter.PageIndex - 1) * queryFilter.PageSize)
  186. .Take(totals - (queryFilter.PageIndex - 1) * queryFilter.PageSize);
  187. //.Pager<PerformanceItem>(1, queryFilter.PageSize, out totals);
  188. }
  189. else
  190. {
  191. response = response
  192. .Include(pi => pi.DRRCalim)
  193. .Include(pi => pi.DRRAbstract)
  194. .Include(pi => pi.DRRFulltext)
  195. .Include(pi=>pi.DRRAll)
  196. .Include(pi => pi.RFRCalim)
  197. .Include(pi => pi.RFRAbstract)
  198. .Include(pi => pi.RFRFulltext)
  199. .Include(pi => pi.RFRAll)
  200. .Include(pi => pi.Customer)
  201. .Include(pi => pi.Reviewer)
  202. .OrderConditions<CaseInfo>(queryFilter.Sorts)
  203. .Skip((queryFilter.PageIndex - 1) * queryFilter.PageSize)
  204. .Take(queryFilter.PageSize);
  205. }
  206. ret.TotalCount = totals;
  207. var retList = response.ToList<CaseInfo>();
  208. #region 将某些属性设为null,避免循环取值造成返回json过大
  209. foreach (CaseInfo item in retList)
  210. {
  211. if (item.Customer != null)
  212. {
  213. item.Customer.PerformanceItems = null;
  214. item.Customer.ResponseMan = null;
  215. }
  216. if (item.Reviewer != null)
  217. {
  218. item.Reviewer.Customers = null;
  219. item.Reviewer.ExternalHandlerItems = null;
  220. item.Reviewer.ItemStaffs = null;
  221. item.Reviewer.AllocationRatios = null;
  222. item.Reviewer.ReviewerItems = null;
  223. }
  224. }
  225. #endregion
  226. ret.Results = retList.ToList();
  227. return ret;
  228. }
  229. public bool CaseExist(string caseNo)
  230. {
  231. return Context.CaseInfos.Where(p => p.CaseNo == caseNo.Trim()).Count() > 0;
  232. }
  233. public static (double, double) UpdateStatistics(int n, double mean, double variance, double newValue)
  234. {
  235. double newMean = (n * mean + newValue) / (n + 1);
  236. double newVariance = Math.Sqrt((n * (mean - newMean) * (mean - newMean) + (newValue - newMean) * (newValue - newMean) + n * variance * variance) / (n + 1));
  237. return (newMean, newVariance);
  238. }
  239. /// <summary>
  240. /// 计算指定日期之前一年的指定客户的平均权利要求差异度和标准方差
  241. /// </summary>
  242. /// <param name="endDate">结束日期</param>
  243. /// /// <param name="customerName">客户名称,默认不指定,获取所有客户的平均权利要求差异度和标准方差</param>
  244. /// <returns></returns>
  245. private List<CustomerCompareStatistics> getLaseYearMean_Variance(DateTime endDate,string customerName=null)
  246. {
  247. IIncludableQueryable<CaseInfo, CompareResult> caseList;
  248. if (customerName != null) {
  249. caseList = Context.CaseInfos.Where<CaseInfo>(
  250. p => p.CreateTime >= endDate.AddYears(-1) && p.CreateTime <= endDate && p.Customer.Name == customerName)
  251. .Include(p => p.Customer)
  252. .Include(p => p.Reviewer)
  253. .Include(p => p.DRRAbstract)
  254. .Include(p => p.DRRAbstract)
  255. .Include(p => p.DRRCalim)
  256. .Include(p => p.DRRFulltext)
  257. .Include(p => p.DRRAll)
  258. .Include(p => p.RFRAbstract)
  259. .Include(p => p.RFRCalim)
  260. .Include(p => p.RFRFulltext)
  261. .Include(p => p.RFRAll);
  262. }
  263. else
  264. {
  265. caseList = Context.CaseInfos.Where<CaseInfo>(
  266. p => p.CreateTime >= endDate.AddYears(-1) && p.CreateTime <= endDate)
  267. .Include(p => p.Customer)
  268. .Include(p => p.Reviewer)
  269. .Include(p => p.DRRAbstract)
  270. .Include(p => p.DRRAbstract)
  271. .Include(p => p.DRRCalim)
  272. .Include(p => p.DRRFulltext)
  273. .Include(p => p.DRRAll)
  274. .Include(p => p.RFRAbstract)
  275. .Include(p => p.RFRCalim)
  276. .Include(p => p.RFRFulltext)
  277. .Include(p => p.RFRAll);
  278. }
  279. List < CustomerCompareStatistics > retList = new List < CustomerCompareStatistics >();
  280. foreach ( var item in caseList)
  281. {
  282. var temObj = retList.Where(p=>p.CustomerName == item.Customer.Name).FirstOrDefault<CustomerCompareStatistics>();
  283. if(temObj == null) {
  284. temObj = new CustomerCompareStatistics();
  285. temObj.CustomerName = item.Customer.Name;
  286. retList.Add(temObj);
  287. }
  288. temObj.CaseCount += 1;
  289. if (item.DRRCalim != null)
  290. {
  291. if (temObj.Diff_FinalDrafted_Claims_Count > 0) {
  292. var retStatistics = UpdateStatistics(temObj.Diff_Drafted_Claims_Count, temObj.Diff_Drafted_Claims_Avg, temObj.Diff_Drafted_Claims_Std, item.DRRCalim.diffRate);
  293. temObj.Diff_Drafted_Claims_Std = retStatistics.Item2;
  294. temObj.Diff_Drafted_Claims_Avg = retStatistics.Item1;
  295. temObj.Diff_Drafted_Claims_Count += 1;
  296. }
  297. else
  298. {
  299. temObj.Diff_Drafted_Claims_Std = 0.0;
  300. temObj.Diff_Drafted_Claims_Avg = item.DRRCalim.diffRate;
  301. temObj.Diff_Drafted_Claims_Count = 1;
  302. }
  303. }
  304. if (item.RFRCalim != null)
  305. {
  306. if (temObj.Diff_FinalDrafted_Claims_Count > 0)
  307. {
  308. var retStatistics = UpdateStatistics(temObj.Diff_FinalDrafted_Claims_Count, temObj.Diff_FinalDrafted_Claims_Avg, temObj.Diff_FinalDrafted_Claims_Std, item.RFRCalim.diffRate);
  309. temObj.Diff_FinalDrafted_Claims_Std = retStatistics.Item2;
  310. temObj.Diff_FinalDrafted_Claims_Avg = retStatistics.Item1;
  311. temObj.Diff_FinalDrafted_Claims_Count += 1;
  312. }
  313. else
  314. {
  315. temObj.Diff_FinalDrafted_Claims_Std = 0.0;
  316. temObj.Diff_FinalDrafted_Claims_Avg = item.RFRCalim.diffRate;
  317. temObj.Diff_FinalDrafted_Claims_Count = 1;
  318. }
  319. }
  320. }
  321. return retList;
  322. }
  323. /// <summary>
  324. /// 获取指定时间内客户的权要修改差异率最高的10各案件
  325. /// </summary>
  326. /// <param name="start">开始日期</param>
  327. /// <param name="end">结束日期</param>
  328. /// <param name="customerName">客户名称</param>
  329. /// <param name="type">类型:
  330. /// 0:外部核稿差异率,默认值,
  331. /// 1:内部核稿差异率
  332. /// </param>
  333. /// <returns></returns>
  334. private List<CaseInfo> getTop10DiffRateCases(DateTime start, DateTime end,string customerName,int type=0)
  335. {
  336. if (type == 0) {
  337. var top10Case = Context.CaseInfos.Where<CaseInfo>(
  338. p => p.CreateTime >= start &&
  339. p.CreateTime <= end &&
  340. p.Customer.Name == customerName
  341. )
  342. .Include(p => p.Customer)
  343. .Include(p => p.Reviewer)
  344. .Include(p => p.DRRCalim)
  345. .Include(p => p.RFRCalim)
  346. .AsEnumerable()
  347. .OrderByDescending(p => p.RFRCalim?.diffRate);
  348. return top10Case.Take(10).ToList();
  349. }
  350. else
  351. {
  352. var top10Case = Context.CaseInfos.Where<CaseInfo>(
  353. p => p.CreateTime >= start &&
  354. p.CreateTime <= end &&
  355. p.Customer.Name == customerName
  356. )
  357. .Include(p => p.Customer)
  358. .Include(p => p.Reviewer)
  359. .Include(p => p.DRRCalim)
  360. .Include(p => p.RFRCalim)
  361. .AsEnumerable()
  362. .OrderByDescending(p => p.DRRCalim?.diffRate);
  363. return top10Case.Take(10).ToList();
  364. }
  365. }
  366. /// <summary>
  367. /// 获取指定时间内客户权要修改差异度计算出的异常案件
  368. /// </summary>
  369. /// <param name="start">开始日期</param>
  370. /// <param name="end">结束日期</param>
  371. /// <param name="customerName">客户名称</param>
  372. /// <returns></returns>
  373. private List<CaseInfo> GetAbnormalCases(DateTime start, DateTime end, string customerName)
  374. {
  375. var customerStatics = getLaseYearMean_Variance(end, customerName);
  376. var cStatics = customerStatics.Where(s => s.CustomerName == customerName).FirstOrDefault();
  377. return _GetAbnormalCases(start, end, customerName, cStatics);
  378. }
  379. private List<CaseInfo> _GetAbnormalCases(DateTime start, DateTime end, string customerName, CustomerCompareStatistics cStatics)
  380. {
  381. if (cStatics != null)
  382. {
  383. var caseList = Context.CaseInfos.Where<CaseInfo>(
  384. p => p.CreateTime >= start &&
  385. p.CreateTime <= end &&
  386. p.Customer.Name == customerName
  387. )
  388. .Include(p => p.Customer)
  389. .Include(p => p.Reviewer)
  390. .Include(p => p.DRRAbstract)
  391. .Include(p => p.DRRAbstract)
  392. .Include(p => p.DRRCalim)
  393. .Include(p => p.DRRFulltext)
  394. .Include(p => p.DRRAll)
  395. .Include(p => p.RFRAbstract)
  396. .Include(p => p.RFRCalim)
  397. .Include(p => p.RFRFulltext)
  398. .Include(p => p.RFRAll);
  399. var retList = new List<CaseInfo>();
  400. foreach (var item in caseList)
  401. {
  402. double first = item.DRRCalim == null ? 0.0 : item.DRRCalim.diffRate;
  403. double second = item.RFRCalim == null ? 0.0 : item.RFRCalim.diffRate;
  404. double score1 = (first - cStatics.Diff_Drafted_Claims_Avg) / cStatics.Diff_Drafted_Claims_Std;
  405. double score2 = (second - cStatics.Diff_FinalDrafted_Claims_Avg) / cStatics.Diff_FinalDrafted_Claims_Std;
  406. double score = Math.Sqrt(score1 * score1 + score2 * score2);
  407. if (score > 3.0)
  408. {
  409. if (score2 > 0)
  410. {
  411. if (score1 < 0)
  412. {
  413. item.AbnormalMessage = "内部核稿修改相对少,外部修改相对很多!【核稿人不给力/沟通有问题?】";
  414. }
  415. else
  416. {
  417. item.AbnormalMessage = "内部核稿相对多,外部修改也相对多!【沟通有问题?】";
  418. }
  419. }
  420. else
  421. {
  422. //if (score1 < 0)
  423. //{
  424. // item.AbnormalMessage = "内部核稿修改相对少,外部修改相对少!【撰稿人给力】";
  425. //}
  426. //else
  427. //{
  428. // item.AbnormalMessage = "内部核稿相对多,外部修改也相对少!【核稿人给力】";
  429. //}
  430. }
  431. retList.Add(item);
  432. }
  433. }
  434. return retList;
  435. }
  436. else
  437. {
  438. return new List<CaseInfo>();
  439. }
  440. }
  441. internal class mailCaseInfo
  442. {
  443. public CustomerCompareStatistics CustomerCompareStatistics { get; set; }
  444. public List<CaseInfo> Top10Cases { get; set; } = new List<CaseInfo>();
  445. public List<CaseInfo> AbnormalCases { get; set; }= new List<CaseInfo>();
  446. }
  447. public void getMailCaseInfo(DateTime start, DateTime end)
  448. {
  449. List<string> defaultStaffNames = new List<string>() { "罗才洋","李庆波","钟子敏"};
  450. var DefaultEmailAccounts = Context.Staffs.Where(p => defaultStaffNames.Contains(p.Name)).ToList();
  451. var customerStatics = getLaseYearMean_Variance(end);
  452. Hashtable staffMailInfo = new Hashtable();
  453. foreach (var cStatics in customerStatics)
  454. {
  455. if(cStatics.CaseCount < 20)
  456. {
  457. continue;
  458. }
  459. //var cStatics = customerStatics.Where(s => s.CustomerName == item.Customer.Name).FirstOrDefault();
  460. var Top10Cases =getTop10DiffRateCases(start, end, cStatics.CustomerName);
  461. foreach (var caseInfo in Top10Cases)
  462. {
  463. foreach (Staff staff in DefaultEmailAccounts)
  464. {
  465. AddtoHashTable(caseInfo, 0, staff, staffMailInfo, cStatics);
  466. }
  467. if (caseInfo.Reviewer != null)
  468. {
  469. AddtoHashTable(caseInfo,0, caseInfo.Reviewer,staffMailInfo,cStatics);
  470. }
  471. if (caseInfo.Customer.ResponseManId != null)
  472. {
  473. Staff respMan = Context.Staffs.FirstOrDefault<Staff>(p => p.Id == caseInfo.Customer.ResponseManId);
  474. if (respMan != null)
  475. {
  476. AddtoHashTable(caseInfo, 0, respMan, staffMailInfo, cStatics);
  477. }
  478. }
  479. }
  480. var AbnormalCases = _GetAbnormalCases(start,end, cStatics.CustomerName, cStatics);
  481. foreach (var caseInfo in AbnormalCases)
  482. {
  483. foreach(Staff staff in DefaultEmailAccounts)
  484. {
  485. AddtoHashTable(caseInfo, 1, staff, staffMailInfo, cStatics);
  486. }
  487. if (caseInfo.Reviewer != null)
  488. {
  489. AddtoHashTable(caseInfo, 1, caseInfo.Reviewer, staffMailInfo, cStatics);
  490. }
  491. if (caseInfo.Customer.ResponseManId != null)
  492. {
  493. Staff respMan = Context.Staffs.FirstOrDefault<Staff>(p => p.Id == caseInfo.Customer.ResponseManId);
  494. if (respMan != null)
  495. {
  496. AddtoHashTable(caseInfo, 1, respMan, staffMailInfo, cStatics);
  497. }
  498. }
  499. }
  500. }
  501. if (staffMailInfo.Count > 0) {
  502. foreach (var key in staffMailInfo.Keys)
  503. {
  504. Staff staff = key as Staff;
  505. List<mailCaseInfo> mailCases = (List<mailCaseInfo>)staffMailInfo[key];
  506. string strMessage = string.Empty ;
  507. foreach(var m in mailCases)
  508. {
  509. if ((m.Top10Cases != null && m.Top10Cases.Count > 0) || (m.AbnormalCases != null && m.AbnormalCases.Count > 0))
  510. {
  511. strMessage += $"<div><b>{m.CustomerCompareStatistics.CustomerName}:</b>";
  512. strMessage += $"<br/>一年内案件数量:{m.CustomerCompareStatistics.CaseCount}";
  513. strMessage += $"<br/>内部核稿平均修改率:{m.CustomerCompareStatistics.Diff_Drafted_Claims_Avg}&nbsp;&nbsp;内部核稿修改率标准方差:{m.CustomerCompareStatistics.Diff_Drafted_Claims_Std}";
  514. strMessage += $"<br/>外部部核稿平均修改率:{m.CustomerCompareStatistics.Diff_FinalDrafted_Claims_Avg}&nbsp;&nbsp;外部核稿修改率标准方差:{m.CustomerCompareStatistics.Diff_FinalDrafted_Claims_Std}</div>";
  515. if (m.Top10Cases != null && m.Top10Cases.Count > 0)
  516. {
  517. strMessage += $"<div>外部核稿修改率前10名案件清单:</div>";
  518. strMessage += "<table><thead><td>案号</td><td>案件名称</td><td>处理人</td><td>核稿人</td><td>内部核稿修改率</td><td>外部核稿修改率</td></thead><body>";
  519. foreach (var c in m.Top10Cases)
  520. {
  521. strMessage += $"<tr><td><a href=\"{($"http://1.116.113.26/CompareFile/detail/{c.CaseNo}")}\">{c.CaseNo}</a></td><td>{c.CaseName}</td><td>{c.Handlers}</td><td>{(c.Reviewer == null ? "" : c.Reviewer.Name)}</td><td>{(c.DRRCalim == null ? "" : c.DRRCalim.diffRate.ToString("0.0000"))}</td><td>{(c.RFRCalim == null ? "" : c.RFRCalim.diffRate.ToString("0.0000"))}</td></tr>";
  522. }
  523. strMessage += "</body></table>";
  524. }
  525. if (m.AbnormalCases != null && m.AbnormalCases.Count > 0)
  526. {
  527. strMessage += $"<div>疑似异常案件清单:</div>";
  528. strMessage += "<table><thead><td>案号</td><td>案件名称</td><td>处理人</td><td>核稿人</td><td>内部核稿修改率</td><td>外部核稿修改率</td></thead><body>";
  529. foreach (var c in m.Top10Cases)
  530. {
  531. strMessage += $"<tr><td><a href=\"{($"http://1.116.113.26/CompareFile/detail/{c.CaseNo}")}\">{c.CaseNo}</a></td><td>{c.CaseName}</td><td>{c.Handlers}</td><td>{(c.Reviewer == null ? "" : c.Reviewer.Name)}</td><td>{(c.DRRCalim == null ? "" : c.DRRCalim.diffRate.ToString("0.0000"))}</td><td>{(c.RFRCalim == null ? "" : c.RFRCalim.diffRate.ToString("0.0000"))}</td></tr>";
  532. }
  533. strMessage += "</body></table>";
  534. }
  535. strMessage += "</div>";
  536. }
  537. }
  538. string strBody = $"<div style=\"position:absolute;margin-top:20px;margin-left:20px;margin-right:20px;box-shadow:0px 0px 3px 3px #ccc \"><div style= \"margin-top: 20px; margin-left:20px;;font-size:14px; \">{staff.Name},你好!</div><div style= \"margin-top: 25px; margin-left:20px;font-size:14px; \">{strMessage}<div style= \"margin-top: 100px;margin-right:15px; padding-bottom: 20px; font-size:14px;color:#888888;float:right; \">小美集团绩效管理系统</div></div>";
  539. staff.Mail = "luocaiyang@china-wispro.com";
  540. _ = QuartzUtil.AddMailJob($"{start.ToString("yyyyMMdd")}-{end.ToString("yyyyMMdd")}申请文件比较邮件", strBody, staff.Name, staff.Mail);
  541. }
  542. }
  543. }
  544. private void AddtoHashTable(CaseInfo caseInfo, int v, Staff staff, Hashtable staffMailInfo,CustomerCompareStatistics cStatics)
  545. {
  546. var staffCaseMailInfo = new mailCaseInfo()
  547. {
  548. CustomerCompareStatistics = cStatics,
  549. };
  550. List<mailCaseInfo> staffCaseMailInfos = new List<mailCaseInfo>();
  551. if (staffMailInfo.ContainsKey(staff))
  552. {
  553. staffCaseMailInfos = (List<mailCaseInfo>)staffMailInfo[staff];
  554. }
  555. else
  556. {
  557. staffMailInfo.Add(staff,staffCaseMailInfos);
  558. }
  559. var temObj = staffCaseMailInfos.Where(p => p.CustomerCompareStatistics.CustomerName == caseInfo.Customer.Name).FirstOrDefault();
  560. if (temObj != null)
  561. {
  562. staffCaseMailInfo = temObj;
  563. }
  564. else
  565. {
  566. staffCaseMailInfos.Add(staffCaseMailInfo);
  567. }
  568. if (v == 0)
  569. {
  570. staffCaseMailInfo.Top10Cases.Add(caseInfo);
  571. }
  572. else
  573. {
  574. staffCaseMailInfo.AbnormalCases.Add(caseInfo);
  575. }
  576. }
  577. /// <summary>
  578. /// 计算案件的zScore
  579. /// </summary>
  580. /// <param name="start">定稿日开始时间</param>
  581. /// <param name="end">定稿日结束时间</param>
  582. /// <param name="type">
  583. /// 0:基于文本相似度计算,
  584. /// 1:基于文本修改差异度计算
  585. /// 2:基于权要权重70说明书30计算
  586. /// 3:基于权要文本相似度计算
  587. /// 4: 基于权要文字修改差异度计算
  588. /// </param>
  589. /// <returns></returns>
  590. public IList<Object> CalCustomer_mean(DateTime start,DateTime end,int type=0)
  591. {
  592. var caseList = Context.CaseInfos.Where<CaseInfo>(
  593. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end)
  594. .Include(p=>p.Customer)
  595. .Include(p=>p.Reviewer)
  596. .Include(p=>p.DRRAbstract)
  597. .Include(p => p.DRRAbstract)
  598. .Include(p => p.DRRCalim)
  599. .Include(p => p.DRRFulltext)
  600. .Include(p => p.DRRAll)
  601. .Include(p => p.RFRAbstract)
  602. .Include(p => p.RFRCalim)
  603. .Include(p => p.RFRFulltext)
  604. .Include(p => p.RFRAll);
  605. int iTotals = caseList.Count();
  606. int iIndex = 0;
  607. List<Object> retList = new List<Object>();
  608. #region 计算客户相似度平均值和标准方差
  609. List<CustomerAvg_Std> avg_std1 = new List<CustomerAvg_Std>();
  610. List<CustomerAvg_Std> avg_std2 = new List<CustomerAvg_Std>();
  611. foreach (var caseInfo in caseList)
  612. {
  613. iIndex++;
  614. Debug.WriteLine($"{iIndex}/{iTotals}\t{caseInfo.CaseNo}\t{caseInfo.DRRAbstractId},{caseInfo.DRRCalimId},{caseInfo.DRRFulltextId},{caseInfo.DRRAllId},{caseInfo.RFRAbstractId},{caseInfo.RFRCalimId},{caseInfo.RFRFulltextId},{caseInfo.RFRAllId}");
  615. string tmpCustomerName = "未知";
  616. if(caseInfo.Customer!= null)
  617. {
  618. tmpCustomerName = caseInfo.Customer.Name;
  619. }
  620. var one = avg_std1.Where<CustomerAvg_Std>(p => p.Name == tmpCustomerName).FirstOrDefault();
  621. if (one == null)
  622. {
  623. one = new CustomerAvg_Std() { Name = tmpCustomerName };
  624. avg_std1.Add(one);
  625. }
  626. var two = avg_std2.Where<CustomerAvg_Std>(p => p.Name == tmpCustomerName).FirstOrDefault();
  627. if (two == null)
  628. {
  629. two = new CustomerAvg_Std() { Name = tmpCustomerName };
  630. avg_std2.Add(two);
  631. }
  632. double? oneTmp = getCalValue(caseInfo, type, 0);
  633. if(oneTmp != null)
  634. {
  635. one.Sum += oneTmp.Value;
  636. one.SquareSum += oneTmp.Value * oneTmp.Value;
  637. one.count += 1;
  638. }
  639. double? twoTmp = getCalValue(caseInfo, type, 1);
  640. if (twoTmp != null)
  641. {
  642. two.Sum += twoTmp.Value;
  643. two.SquareSum += twoTmp.Value * twoTmp.Value;
  644. two.count += 1;
  645. }
  646. }
  647. #endregion
  648. System.Data.DataTable dt = new System.Data.DataTable();
  649. dt.Columns.Add("我方文号");
  650. dt.Columns.Add("案件名称");
  651. dt.Columns.Add("客户");
  652. dt.Columns.Add("处理人");
  653. dt.Columns.Add("核稿人");
  654. dt.Columns.Add("内部核稿相似度或差异度");
  655. dt.Columns.Add("内部客户平均值");
  656. dt.Columns.Add("内部客户标准偏差");
  657. dt.Columns.Add("内部核稿分数");
  658. dt.Columns.Add("外部核稿相似度或差异度");
  659. dt.Columns.Add("外部客户平均值");
  660. dt.Columns.Add("外部客户标准偏差");
  661. dt.Columns.Add("外部核稿分数");
  662. dt.Columns.Add("备注");
  663. foreach (var item in caseList)
  664. {
  665. string tmpCustomerName = "未知";
  666. if (item.Customer != null)
  667. {
  668. tmpCustomerName = item.Customer.Name;
  669. }
  670. var one = avg_std1.Where<CustomerAvg_Std>(p => p.Name == tmpCustomerName).FirstOrDefault();
  671. var two = avg_std2.Where<CustomerAvg_Std>(p => p.Name == tmpCustomerName).FirstOrDefault();
  672. double? oneSim = getCalValue(item,type,0);
  673. double? twoSim = getCalValue(item, type, 1); ;
  674. DataRow row = dt.NewRow();
  675. row["我方文号"] = item.CaseNo;
  676. row["案件名称"] = item.CaseName;
  677. row["客户"] = item.Customer?.Name;
  678. row["核稿人"] = item.Reviewer?.Name;
  679. row["处理人"] = item.Handlers;
  680. double? zScoreA = null;
  681. if (oneSim != null)
  682. {
  683. zScoreA = (oneSim - one.Average) / one.Std_Deviation;
  684. }
  685. row["内部核稿分数"] = zScoreA;
  686. row["内部核稿相似度或差异度"] = oneSim;
  687. row["内部客户平均值"] = one.Average;
  688. row["内部客户标准偏差"] = one.Std_Deviation;
  689. row["外部核稿相似度或差异度"] = twoSim;
  690. row["外部客户平均值"] = two.Average;
  691. row["外部客户标准偏差"] = two.Std_Deviation;
  692. double? zScoreB = null;
  693. if (twoSim != null)
  694. {
  695. zScoreB = (twoSim - two.Average) / two.Std_Deviation;
  696. }
  697. row["外部核稿分数"] = zScoreB;
  698. if (zScoreA != null && zScoreB != null)
  699. {
  700. var distince = Math.Sqrt(zScoreB.Value * zScoreB.Value + zScoreA.Value * zScoreA.Value);
  701. if (type == 0 || type == 2 || type==3)
  702. {
  703. if (distince > 3)
  704. {
  705. if (zScoreA.Value > 0 && zScoreB.Value > 0)
  706. {
  707. row["备注"] = "内部核稿、外部核稿修改都较少![撰稿人给力或客户友好]";
  708. }
  709. if (zScoreA.Value > 0 && zScoreB.Value < 0)
  710. {
  711. row["备注"] = "内部核稿较少、外部核稿修改较多![核稿人没有尽责!]";
  712. }
  713. if (zScoreA.Value < 0 && zScoreB.Value > 0)
  714. {
  715. row["备注"] = "内部核稿较多、外部核稿修改都较少![核稿人给力]";
  716. }
  717. if (zScoreA.Value < 0 && zScoreB.Value < 0)
  718. {
  719. row["备注"] = "内部核稿和外部核稿修改都较多![案件沟通问题?]";
  720. }
  721. }
  722. }
  723. else
  724. {
  725. if (distince > 3)
  726. {
  727. if (zScoreA.Value > 0 && zScoreB.Value > 0)
  728. {
  729. row["备注"] = "内部核稿和外部核稿修改都较多![案件沟通问题?]";
  730. }
  731. if (zScoreA.Value > 0 && zScoreB.Value < 0)
  732. {
  733. row["备注"] = "内部核稿较多、外部核稿修改都较少![核稿人给力]";
  734. }
  735. if (zScoreA.Value < 0 && zScoreB.Value > 0)
  736. {
  737. row["备注"] = "内部核稿较少、外部核稿修改较多![核稿人没有尽责!]";
  738. }
  739. if (zScoreA.Value < 0 && zScoreB.Value < 0)
  740. {
  741. row["备注"] = "内部核稿、外部核稿修改都较少![撰稿人给力或客户友好]";
  742. }
  743. }
  744. }
  745. }
  746. dt.Rows.Add(row);
  747. retList.Add(
  748. new
  749. {
  750. Id = item.Id,
  751. CaseNo = item.CaseNo,
  752. CaseName = item.CaseName,
  753. Customer = item.Customer,
  754. Reviewer = item.Reviewer,
  755. Handlers = item.Handlers,
  756. zScoreA = (oneSim - one.Average) / one.Std_Deviation,
  757. zScoreB = (twoSim - two.Average) / two.Std_Deviation
  758. }
  759. );
  760. }
  761. wispro.sp.utility.NPOIExcel.DataTableToExcel(dt,$"c:\\temp\\{DateTime.Now.ToString("yyyyMMdd")}-内部核稿外部核稿情况案件清单_{typeName(type)}.xlsx");
  762. return retList;
  763. }
  764. private double? getCalValue(CaseInfo caseInfo,int type,int stage)
  765. {
  766. double? calValue = null;
  767. switch (type)
  768. {
  769. case 0:
  770. if(stage == 0)
  771. {
  772. if(caseInfo.DRRFulltext != null && caseInfo.DRRAbstract != null)
  773. {
  774. calValue = caseInfo.DRRAll.TextSimilarity;
  775. }
  776. else
  777. {
  778. if(caseInfo.DRRCalim != null)
  779. {
  780. calValue = caseInfo.DRRCalim.TextSimilarity;
  781. }
  782. }
  783. }
  784. else
  785. {
  786. if (caseInfo.RFRFulltext != null && caseInfo.RFRAbstract != null)
  787. {
  788. calValue = caseInfo.RFRAll.TextSimilarity;
  789. }
  790. else
  791. {
  792. if (caseInfo.RFRCalim != null)
  793. {
  794. calValue = caseInfo.RFRCalim.TextSimilarity;
  795. }
  796. }
  797. }
  798. break;
  799. case 1:
  800. if (stage == 0)
  801. {
  802. if (caseInfo.DRRFulltext != null && caseInfo.DRRAbstract != null)
  803. {
  804. calValue = caseInfo.DRRAll.diffRate;
  805. }
  806. else
  807. {
  808. if (caseInfo.DRRCalim != null)
  809. {
  810. calValue = caseInfo.DRRCalim.diffRate;
  811. }
  812. }
  813. }
  814. else
  815. {
  816. if (caseInfo.RFRFulltext != null && caseInfo.RFRAbstract != null)
  817. {
  818. calValue = caseInfo.RFRAll.diffRate;
  819. }
  820. else
  821. {
  822. if (caseInfo.RFRCalim != null)
  823. {
  824. calValue = caseInfo.RFRCalim.diffRate;
  825. }
  826. }
  827. }
  828. break;
  829. case 2:
  830. if (stage == 0)
  831. {
  832. if(caseInfo.DRRFulltext != null && caseInfo.DRRCalim!= null)
  833. {
  834. calValue = caseInfo.DRRCalim.TextSimilarity * 0.7 + caseInfo.DRRFulltext.TextSimilarity * 0.3;
  835. }
  836. else
  837. {
  838. if( caseInfo.DRRCalim != null)
  839. {
  840. calValue = caseInfo.DRRCalim.TextSimilarity;
  841. }
  842. else
  843. {
  844. if(caseInfo.DRRAll != null)
  845. {
  846. calValue = caseInfo.DRRAll.TextSimilarity;
  847. }
  848. }
  849. }
  850. }
  851. else
  852. {
  853. if (caseInfo.RFRFulltext != null && caseInfo.RFRCalim != null)
  854. {
  855. calValue = caseInfo.RFRCalim.TextSimilarity * 0.7 + caseInfo.RFRFulltext.TextSimilarity * 0.3;
  856. }
  857. else
  858. {
  859. if (caseInfo.RFRCalim != null)
  860. {
  861. calValue = caseInfo.RFRCalim.TextSimilarity;
  862. }
  863. else
  864. {
  865. if (caseInfo.RFRAll != null)
  866. {
  867. calValue = caseInfo.RFRAll.TextSimilarity;
  868. }
  869. }
  870. }
  871. }
  872. break;
  873. case 3:
  874. if (stage == 0)
  875. {
  876. if (caseInfo.DRRCalim != null)
  877. {
  878. calValue = caseInfo.DRRCalim.TextSimilarity;
  879. }
  880. }
  881. else
  882. {
  883. if (caseInfo.RFRCalim != null)
  884. {
  885. calValue = caseInfo.RFRCalim.TextSimilarity;
  886. }
  887. }
  888. break;
  889. case 4:
  890. if (stage == 0)
  891. {
  892. if (caseInfo.DRRCalim != null)
  893. {
  894. calValue = caseInfo.DRRCalim.diffRate;
  895. }
  896. }
  897. else
  898. {
  899. if (caseInfo.RFRCalim != null)
  900. {
  901. calValue = caseInfo.RFRCalim.diffRate;
  902. }
  903. }
  904. break;
  905. }
  906. return calValue;
  907. }
  908. private string typeName(int type)
  909. {
  910. switch (type)
  911. {
  912. case 0:
  913. return "文本相似度计算";
  914. case 1:
  915. return "字符修改计算";
  916. case 2:
  917. return "权要权重70说明书30";
  918. case 3:
  919. return "权要相似度计算";
  920. }
  921. return "";
  922. }
  923. public IList<Object> CalMean_Std(DateTime start,DateTime end)
  924. {
  925. double AverageA = Context.CaseInfos.Where<CaseInfo>(
  926. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end && p.DRRCalim!= null)
  927. .Average(x=>x.DRRCalim.TextSimilarity);
  928. double AverageB = Context.CaseInfos.Where<CaseInfo>(
  929. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end && p.RFRAll != null)
  930. .Average(x => x.RFRAll.TextSimilarity);
  931. double stdA = Math.Sqrt( Context.CaseInfos.Where<CaseInfo>(
  932. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end)
  933. .Average((x => (x.DRRCalim.TextSimilarity - AverageA) * (x.DRRCalim.TextSimilarity - AverageA))));
  934. double stdB = Math.Sqrt(Context.CaseInfos.Where<CaseInfo>(
  935. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end)
  936. .Average((x => (x.RFRAll.TextSimilarity - AverageB) * (x.RFRAll.TextSimilarity - AverageB))));
  937. var response2 = Context.CaseInfos.Where<CaseInfo>(
  938. p => p.FinalVersionDate >= start && p.FinalVersionDate <= end)
  939. .Include(p=>p.DRRCalim)
  940. .Include(p=>p.RFRAll);
  941. IList<Object> results = new List<Object>();
  942. foreach(var item in response2.ToList())
  943. {
  944. results.Add(
  945. new {
  946. Id = item.Id,
  947. CaseNo = item.CaseNo,
  948. CaseName = item.CaseName,
  949. Customer = item.Customer,
  950. Reviewer = item.Reviewer,
  951. Handlers = item.Handlers,
  952. zScoreA = (item.DRRCalim?.TextSimilarity -AverageA)/stdA,
  953. zScoreB = (item.RFRAll?.TextSimilarity - AverageB) /stdB
  954. }
  955. );
  956. }
  957. return results;
  958. }
  959. private string GetExpress(IList<FieldCondition> conditions)
  960. {
  961. string str = "";
  962. foreach (var c in conditions)
  963. {
  964. if (string.IsNullOrEmpty(str))
  965. {
  966. str = c.ToExpressString("s");
  967. }
  968. else
  969. {
  970. if (c.LogicOperate == LogicEnum.And)
  971. {
  972. str = $"({str}) && {c.ToExpressString("s")}";
  973. }
  974. else
  975. {
  976. str = $"({str}) || {c.ToExpressString("s")}";
  977. }
  978. }
  979. }
  980. return str;
  981. }
  982. private IQueryable<CaseInfo> NewMethod(QueryFilter queryFilter)
  983. {
  984. string strExpress = "";
  985. if (queryFilter.ConditionTree != null)
  986. {
  987. strExpress = GetExpress(queryFilter.ConditionTree);
  988. }
  989. var interpreter = new Interpreter();
  990. if (string.IsNullOrEmpty(strExpress))
  991. {
  992. return new spDbContext().CaseInfos.Where<CaseInfo>(p=>(p.Id>0));
  993. }
  994. else
  995. {
  996. Expression<Func<CaseInfo, bool>> dynamicWhere = interpreter.ParseAsExpression<Func<CaseInfo, bool>>(strExpress, "s");
  997. IQueryable<CaseInfo> response = new spDbContext().CaseInfos.Where<CaseInfo>(dynamicWhere);
  998. return response;
  999. }
  1000. }
  1001. }
  1002. }