TimeLimitDomainService.cs 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. using Hotline.Caching.Interfaces;
  2. using Hotline.Share.Dtos.Settings;
  3. using Hotline.Share.Enums.FlowEngine;
  4. using Hotline.Share.Enums.Order;
  5. using Hotline.Share.Enums.Settings;
  6. using MapsterMapper;
  7. using System.ComponentModel;
  8. using XF.Domain.Constants;
  9. using XF.Domain.Dependency;
  10. using XF.Domain.Exceptions;
  11. using XF.Domain.Repository;
  12. using XF.Utility.EnumExtensions;
  13. using Hotline.Settings.TimeLimitDomain;
  14. namespace Hotline.Settings.TimeLimits
  15. {
  16. public class TimeLimitDomainService : ITimeLimitDomainService, IScopeDependency
  17. {
  18. private readonly ITimeLimitRepository _timeLimitRepository;
  19. private readonly IDaySettingRepository _daySettingRepository;
  20. private List<CalcTimeSetting> timeSettingList;
  21. private readonly IRepository<SystemSetting> _systemSettingRepository;
  22. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  23. private readonly IMapper _mapper;
  24. private List<CalcTimeSetting> sourceSettingList;
  25. public TimeLimitDomainService(ITimeLimitRepository timeLimitRepository, IDaySettingRepository daySettingRepository,
  26. IRepository<SystemSetting> systemSettingRepository, ISystemSettingCacheManager systemSettingCacheManager,
  27. IMapper mapper)
  28. {
  29. _timeLimitRepository = timeLimitRepository;
  30. _daySettingRepository = daySettingRepository;
  31. _systemSettingRepository = systemSettingRepository;
  32. _systemSettingCacheManager = systemSettingCacheManager;
  33. _mapper = mapper;
  34. //初始化常量TODO
  35. timeSettingList = new List<CalcTimeSetting>();
  36. CalcTimeSetting setting1 = new CalcTimeSetting() { BusCode = "10", BusName = "咨询", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne =50};
  37. timeSettingList.Add(setting1);
  38. CalcTimeSetting setting2 = new CalcTimeSetting() { BusCode = "30", BusName = "举报", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne = 50};
  39. timeSettingList.Add(setting2);
  40. CalcTimeSetting setting3 = new CalcTimeSetting() { BusCode = "35", BusName = "投诉", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne =50 };
  41. timeSettingList.Add(setting3);
  42. CalcTimeSetting setting4 = new CalcTimeSetting() { BusCode = "20", BusName = "求助", TimeType = ETimeType.WorkDay, TimeValue = 5, Percentage = 80 , PercentageOne =50 };
  43. timeSettingList.Add(setting4);
  44. CalcTimeSetting setting5 = new CalcTimeSetting() { BusCode = "15", BusName = "建议", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
  45. timeSettingList.Add(setting5);
  46. CalcTimeSetting setting6 = new CalcTimeSetting() { BusCode = "1", BusName = "意见", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
  47. timeSettingList.Add(setting6);
  48. CalcTimeSetting setting7 = new CalcTimeSetting() { BusCode = "2", BusName = "惠民帮助", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 ,PercentageOne = 50 };
  49. timeSettingList.Add(setting7);
  50. //CalcTimeSetting setting8 = new CalcTimeSetting() { BugCode = "3", BusName = "大气污染举报", TimeType = ETimeType.WorkDay, TimeValue = 5 };
  51. //timeSettingList.Add(setting8);
  52. CalcTimeSetting setting9 = new CalcTimeSetting() { BusCode = "25", BusName = "表扬", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 ,PercentageOne = 50 };
  53. timeSettingList.Add(setting9);
  54. CalcTimeSetting setting10 = new CalcTimeSetting() { BusCode = "40", BusName = "其他", TimeType = ETimeType.WorkDay, TimeValue = 3, Percentage = 80 , PercentageOne = 50 };
  55. timeSettingList.Add(setting10);
  56. }
  57. ///// <summary>
  58. ///// 获取办理时限配置
  59. ///// </summary>
  60. ///// <param name="code"></param>
  61. ///// <param name="iscanter"></param>
  62. ///// <returns></returns>
  63. //public int GetOrderTimeLimitConfig(string? code)
  64. //{
  65. // if (string.IsNullOrEmpty(code))
  66. // {
  67. // return int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.BackCenterTimeSetting).SettingValue[0]);
  68. // }
  69. // else
  70. // {
  71. // return timeSettingList.FirstOrDefault(x => x.BugCode == code)?.TimeValue ?? 3;
  72. // }
  73. //}
  74. /// <summary>
  75. /// 获取办理时限配置
  76. /// 2024-08-28 过期了,不再使用和维护;
  77. /// 请调用 <inheritdoc cref="ICalcExpireTime.GetOrderTimeLimitConfig"/>IExpireTime.GetOrderTimeLimitConfig
  78. /// </summary>
  79. /// <param name="code"></param>
  80. /// <returns></returns>
  81. [Obsolete("新的方法 -> IExpireTime.GetOrderTimeLimitConfig")]
  82. public TimeConfig GetOrderTimeLimitConfig(string? code = null)
  83. {
  84. if (string.IsNullOrEmpty(code))
  85. {
  86. return new TimeConfig(
  87. int.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.BackCenterTimeSetting).SettingValue[0]),
  88. ETimeType.WorkDay);
  89. }
  90. else
  91. {
  92. var timeSetting = timeSettingList.FirstOrDefault(x => x.BusCode == code);
  93. return new TimeConfig(timeSetting.TimeValue, timeSetting.TimeType);
  94. }
  95. }
  96. public async Task<string> AddAsync(TimeLimit model, CancellationToken cancellationToken)
  97. {
  98. return await _timeLimitRepository.AddAsync(model, cancellationToken);
  99. }
  100. public async Task UpdateAsync(TimeLimit model, CancellationToken cancellationToken)
  101. {
  102. var dbModel = await _timeLimitRepository.GetAsync(model.Id, cancellationToken);
  103. if (dbModel == null)
  104. {
  105. throw new UserFriendlyException("无效数据");
  106. }
  107. await _timeLimitRepository.UpdateAsync(model, cancellationToken);
  108. }
  109. /// <summary>
  110. /// 2024-08-28 过期了,不再使用和维护;
  111. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcEndTime"/>IExpireTime.CalcEndTime
  112. /// </summary>
  113. /// <param name="flowDirection"></param>
  114. /// <param name="Percentage"></param>
  115. /// <param name="PercentageOne"></param>
  116. /// <param name="timeType"></param>
  117. /// <param name="timeValue"></param>
  118. /// <returns></returns>
  119. /// <exception cref="UserFriendlyException"></exception>
  120. /// <exception cref="ArgumentOutOfRangeException"></exception>
  121. [Obsolete("新的方法 -> IExpireTime.CalcEndTime")]
  122. public TimeResult? CalcEndTime(EFlowDirection flowDirection, int Percentage,int PercentageOne, ETimeType? timeType = null, int? timeValue = null)
  123. {
  124. switch (flowDirection)
  125. {
  126. case EFlowDirection.CenterToOrg:
  127. if (!timeType.HasValue || !timeValue.HasValue)
  128. throw new UserFriendlyException("无效参数");
  129. return CalcEndTime(DateTime.Now, timeType.Value, timeValue.Value,Percentage,PercentageOne);
  130. case EFlowDirection.OrgToCenter:
  131. //todo 根据配置
  132. return CalcEndTime(DateTime.Now, ETimeType.Day, 1, Percentage,PercentageOne);
  133. default:
  134. throw new ArgumentOutOfRangeException(nameof(flowDirection), flowDirection, null);
  135. }
  136. }
  137. /// <summary>
  138. /// 计算期满时间
  139. /// 2024-08-28 过期了,不再使用和维护;
  140. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcExpiredTime"/>IExpireTime.CalcExpiredTime
  141. /// </summary>
  142. [Obsolete("新的方法 -> IExpireTime.CalcExpiredTime")]
  143. public ExpiredTimeWithConfig CalcExpiredTime(DateTime beginTime, EFlowDirection flowDirection, string? acceptTypeCode)
  144. {
  145. if (flowDirection is EFlowDirection.CenterToOrg && string.IsNullOrEmpty(acceptTypeCode))
  146. throw new UserFriendlyException("中心派至部门的工单期满时间需受理类型参数");
  147. var timeConfig = flowDirection switch
  148. {
  149. EFlowDirection.CenterToOrg => GetOrderTimeLimitConfig(acceptTypeCode),
  150. EFlowDirection.OrgToCenter => GetOrderTimeLimitConfig(),
  151. EFlowDirection.CenterToCenter => new TimeConfig(1, ETimeType.WorkDay),
  152. _ => throw new ArgumentOutOfRangeException(nameof(flowDirection), flowDirection, null)
  153. };
  154. return CalcEndTime(beginTime, timeConfig, acceptTypeCode);
  155. }
  156. /// <summary>
  157. /// 计算工作时间天数
  158. /// 2024-08-28 过期了,不再使用和维护;
  159. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeToDecimal"/>IExpireTime.CalcWorkTimeToDecimal
  160. /// </summary>
  161. /// <param name="beginTime"></param>
  162. /// <param name="endTime"></param>
  163. /// <param name="isCenter"></param>
  164. /// <returns></returns>
  165. [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeToDecimal")]
  166. public decimal CalcWorkTimeToDecimal(DateTime beginTime,DateTime endTime,bool isCenter)
  167. {
  168. var min = CalcWorkTime(beginTime, endTime, isCenter);
  169. if (min!=0)
  170. {
  171. if (isCenter)
  172. {
  173. return Math.Round((decimal)min / 60 / 60 / 24, 2);
  174. }
  175. else
  176. {
  177. var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
  178. if (workTime != null)
  179. {
  180. DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  181. DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  182. TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  183. //总时差分钟数
  184. int minutes = (int)minuteSpan.TotalMinutes;
  185. return Math.Round(((decimal)min/60) / minutes, 2);
  186. }
  187. return 0;
  188. }
  189. }
  190. return 0;
  191. }
  192. /// <summary>
  193. /// 计算工作时间小时
  194. /// 2024-08-28 过期了,不再使用和维护;
  195. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeToHour"/>IExpireTime.CalcWorkTimeToHour
  196. /// </summary>
  197. /// <param name="beginTime"></param>
  198. /// <param name="endTime"></param>
  199. /// <param name="isCenter"></param>
  200. /// <returns></returns>
  201. [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeToHour")]
  202. public decimal CalcWorkTimeToHour(DateTime beginTime, DateTime endTime, bool isCenter)
  203. {
  204. var min = CalcWorkTime(beginTime, endTime, isCenter);
  205. if (min != 0)
  206. {
  207. if (isCenter)
  208. {
  209. return Math.Round((decimal)min / 60 / 60 / 24, 2);
  210. }
  211. else
  212. {
  213. var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
  214. if (workTime != null)
  215. {
  216. //DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  217. //DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  218. //TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  219. ////总时差分钟数
  220. //int minutes = (int)minuteSpan.TotalMinutes;
  221. return Math.Round((decimal)min / 60 / 60 , 2);
  222. }
  223. return 0;
  224. }
  225. }
  226. return 0;
  227. }
  228. /// <summary>
  229. /// 计算工作时间分钟数(已改返回秒)
  230. /// 2024-08-28 过期了,不再使用和维护;
  231. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTime"/>IExpireTime.CalcWorkTimeToHour
  232. /// </summary>
  233. /// <param name="beginTime"></param>
  234. /// <param name="endTime"></param>
  235. /// <param name="isCenter"></param>
  236. /// <returns></returns>
  237. [Obsolete("新的方法 -> IExpireTime.CalcWorkTime")]
  238. public int CalcWorkTime(DateTime beginTime, DateTime endTime, bool isCenter)
  239. {
  240. if (isCenter)
  241. {
  242. //如果是中心,采用中心计算方式
  243. //计算时间差
  244. TimeSpan minuteSpan = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  245. //总时差分钟数
  246. int minutes = (int)minuteSpan.TotalMinutes;
  247. //计算开始时间是否计算在工作时间内
  248. if (!IsWorkDay(beginTime))
  249. {
  250. var newBeginTime = beginTime.AddDays(1).Date;
  251. TimeSpan beginTimeMinuteSpan = new TimeSpan(newBeginTime.Ticks - beginTime.Ticks);
  252. int beginTimeMinute = (int)beginTimeMinuteSpan.TotalMinutes;
  253. minutes = minutes - beginTimeMinute;
  254. }
  255. //计算结束时间是否计算在工作时间内
  256. if (!IsWorkDay(endTime))
  257. {
  258. var newEndTime = endTime.Date;
  259. TimeSpan endTimeMinuteSpan = new TimeSpan(endTime.Ticks - newEndTime.Ticks);
  260. int endTimeMinute = (int)endTimeMinuteSpan.TotalMinutes;
  261. minutes = minutes - endTimeMinute;
  262. }
  263. //计算整天时间是否在工作时间内
  264. int days = minuteSpan.Days;
  265. for (int i = 0; i < days; i++)
  266. {
  267. var newDay = beginTime.AddDays(i + 1);
  268. if (newDay.Date == endTime.Date)
  269. {
  270. continue;
  271. }
  272. if (!IsWorkDay(beginTime.AddDays(i + 1)))
  273. {
  274. minutes = minutes - 1440;
  275. }
  276. }
  277. return minutes==0 ? 1: minutes*60;
  278. }
  279. else
  280. {
  281. //如果不是中心(则是部门计算方式)
  282. //
  283. var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
  284. if (workTime != null)
  285. {
  286. //DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  287. //DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  288. DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  289. DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  290. //处理开始时间
  291. if (beginTime.Date == WorkBeginTime.Date && beginTime < WorkBeginTime)
  292. {
  293. beginTime = WorkBeginTime;
  294. }
  295. else
  296. {
  297. if (beginTime > WorkEndTime)
  298. {
  299. beginTime = WorkBeginTime.AddDays(1);
  300. }
  301. }
  302. if (beginTime>=endTime)
  303. {
  304. return 1;
  305. }
  306. if (endTime.Date == WorkEndTime.Date && endTime < WorkBeginTime)
  307. {
  308. endTime = WorkBeginTime;
  309. }
  310. else
  311. {
  312. if (endTime> WorkEndTime && endTime < WorkBeginTime.AddDays(1))
  313. {
  314. endTime = WorkBeginTime.AddDays(1);
  315. }
  316. }
  317. while (true)
  318. {
  319. if (!IsWorkDay(endTime))
  320. {
  321. endTime = DateTime.Parse(endTime.AddDays(1).ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  322. }
  323. else
  324. {
  325. break;
  326. }
  327. }
  328. int minutes = 0;
  329. int i = 0;
  330. while (true)
  331. {
  332. i++;
  333. //如果是工作日
  334. if (IsWorkDay(beginTime))
  335. {
  336. //最后一天
  337. if (beginTime.Date == endTime.Date)
  338. {
  339. if (endTime > WorkEndTime)
  340. {
  341. if (i != 1)
  342. {
  343. TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  344. minutes += (int)sp.TotalMinutes;
  345. }
  346. else
  347. {
  348. TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
  349. minutes += (int)sp.TotalMinutes;
  350. }
  351. }
  352. else
  353. {
  354. if (i != 1)
  355. {
  356. TimeSpan sp = new TimeSpan(endTime.Ticks - WorkBeginTime.Ticks);
  357. minutes += (int)sp.TotalMinutes;
  358. }
  359. else
  360. {
  361. TimeSpan sp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  362. minutes += (int)sp.TotalMinutes;
  363. }
  364. }
  365. return minutes == 0 ? 1 : minutes*60;
  366. }
  367. //如果不是当天完成
  368. else
  369. {
  370. if (i == 1)
  371. {
  372. TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
  373. minutes += (int)sp.TotalMinutes;
  374. }
  375. else
  376. {
  377. if (endTime.Date == WorkEndTime.Date)
  378. {
  379. if (endTime > WorkEndTime)
  380. {
  381. TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  382. minutes += (int)sp.TotalMinutes;
  383. }
  384. else
  385. {
  386. TimeSpan sp = new TimeSpan(endTime.Ticks - WorkBeginTime.Ticks);
  387. minutes += (int)sp.TotalMinutes;
  388. }
  389. return minutes == 0 ? 1 : minutes * 60;
  390. }
  391. else
  392. {
  393. TimeSpan sp = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  394. minutes += (int)sp.TotalMinutes;
  395. }
  396. }
  397. }
  398. }
  399. beginTime = beginTime.AddDays(1);
  400. WorkEndTime = WorkEndTime.AddDays(1);
  401. WorkBeginTime = WorkBeginTime.AddDays(1);
  402. }
  403. }
  404. return 0;
  405. }
  406. }
  407. /// <summary>
  408. /// 计算工作时间分钟数(已改返回秒)
  409. /// 2024-08-28 过期了,不再使用和维护;
  410. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcWorkTimeEx"/>IExpireTime.CalcWorkTimeEx
  411. /// </summary>
  412. /// <param name="beginTime"></param>
  413. /// <param name="endTime"></param>
  414. /// <param name="isCenter"></param>
  415. /// <returns></returns>
  416. [Obsolete("新的方法 -> IExpireTime.CalcWorkTimeEx")]
  417. public int CalcWorkTimeEx(DateTime beginTime, DateTime endTime, bool isCenter)
  418. {
  419. if (isCenter)
  420. {
  421. //如果是中心,采用中心计算方式
  422. //计算时间差
  423. TimeSpan minuteSpan = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  424. //总时差分钟数
  425. int minutes = (int)minuteSpan.TotalMinutes;
  426. //计算开始时间是否计算在工作时间内
  427. if (!IsWorkDay(beginTime))
  428. {
  429. var newBeginTime = beginTime.AddDays(1).Date;
  430. TimeSpan beginTimeMinuteSpan = new TimeSpan(newBeginTime.Ticks - beginTime.Ticks);
  431. int beginTimeMinute = (int)beginTimeMinuteSpan.TotalMinutes;
  432. minutes = minutes - beginTimeMinute;
  433. }
  434. //计算结束时间是否计算在工作时间内
  435. if (!IsWorkDay(endTime))
  436. {
  437. var newEndTime = endTime.Date;
  438. TimeSpan endTimeMinuteSpan = new TimeSpan(endTime.Ticks - newEndTime.Ticks);
  439. int endTimeMinute = (int)endTimeMinuteSpan.TotalMinutes;
  440. minutes = minutes - endTimeMinute;
  441. }
  442. //计算整天时间是否在工作时间内
  443. int days = minuteSpan.Days;
  444. for (int i = 0; i < days; i++)
  445. {
  446. var newDay = beginTime.AddDays(i + 1);
  447. if (newDay.Date == endTime.Date)
  448. {
  449. continue;
  450. }
  451. if (!IsWorkDay(beginTime.AddDays(i + 1)))
  452. {
  453. minutes = minutes - 1440;
  454. }
  455. }
  456. return minutes == 0 ? 1 : minutes * 60;
  457. }
  458. else
  459. {
  460. //如果不是中心(则是部门计算方式)
  461. //
  462. var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTimeOrg);
  463. if (workTime != null)
  464. {
  465. //DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  466. //DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  467. DateTime MornWorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  468. DateTime MornWorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  469. DateTime AfterWorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[2] + ":00");
  470. DateTime AfterWorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTime.SettingValue[3] + ":00");
  471. //处理开始时间
  472. if (beginTime.Date == MornWorkBeginTime.Date && beginTime < MornWorkBeginTime)
  473. {
  474. beginTime = MornWorkBeginTime;
  475. }
  476. else if(beginTime.Date == MornWorkBeginTime.Date && beginTime > MornWorkEndTime && beginTime< AfterWorkBeginTime)
  477. {
  478. beginTime = AfterWorkBeginTime;
  479. }
  480. else
  481. {
  482. if (beginTime > AfterWorkEndTime)
  483. {
  484. beginTime = MornWorkBeginTime.AddDays(1);
  485. MornWorkBeginTime = MornWorkBeginTime.AddDays(1);
  486. MornWorkEndTime = MornWorkEndTime.AddDays(1);
  487. AfterWorkBeginTime = AfterWorkBeginTime.AddDays(1);
  488. AfterWorkEndTime = AfterWorkEndTime.AddDays(1);
  489. }
  490. }
  491. if (beginTime >= endTime)
  492. {
  493. return 1;
  494. }
  495. if (endTime.Date == AfterWorkEndTime.Date && endTime < MornWorkBeginTime)
  496. {
  497. endTime = MornWorkBeginTime;
  498. }
  499. else if(endTime.Date == AfterWorkEndTime.Date && endTime> MornWorkEndTime && endTime< AfterWorkBeginTime)
  500. {
  501. endTime = MornWorkEndTime;
  502. }
  503. else
  504. {
  505. if (endTime > AfterWorkEndTime && endTime < MornWorkBeginTime.AddDays(1))
  506. {
  507. endTime = AfterWorkEndTime;//MornWorkBeginTime.AddDays(1);
  508. }
  509. }
  510. while (true)
  511. {
  512. if (!IsWorkDay(endTime))
  513. {
  514. endTime = DateTime.Parse(endTime.AddDays(1).ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  515. }
  516. else
  517. {
  518. break;
  519. }
  520. }
  521. //计算午休时差
  522. var restMinutes = 0;
  523. TimeSpan restSp = new TimeSpan(AfterWorkBeginTime.Ticks - MornWorkEndTime.Ticks);
  524. restMinutes = (int)restSp.TotalMinutes;
  525. int minutes = 0;
  526. int i = 0;
  527. while (true)
  528. {
  529. i++;
  530. //如果是工作日
  531. if (IsWorkDay(beginTime))
  532. {
  533. //最后一天
  534. if (beginTime.Date == endTime.Date)
  535. {
  536. if (endTime > AfterWorkEndTime)
  537. {
  538. if (i != 1)
  539. {
  540. TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
  541. minutes += (int)sp.TotalMinutes- restMinutes;
  542. }
  543. //最后一天就是当天
  544. else
  545. {
  546. TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - beginTime.Ticks);
  547. minutes += (int)sp.TotalMinutes;
  548. if (beginTime>MornWorkEndTime)
  549. {
  550. minutes = minutes - restMinutes;
  551. }
  552. }
  553. }
  554. else
  555. {
  556. if (i != 1)
  557. {
  558. TimeSpan sp = new TimeSpan(endTime.Ticks - MornWorkBeginTime.Ticks);
  559. minutes += (int)sp.TotalMinutes;
  560. if (endTime>AfterWorkBeginTime)
  561. {
  562. minutes = minutes - restMinutes;
  563. }
  564. }
  565. else
  566. {
  567. TimeSpan sp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  568. minutes += (int)sp.TotalMinutes;
  569. if (endTime> AfterWorkBeginTime && beginTime< MornWorkEndTime )
  570. {
  571. minutes = minutes - restMinutes;
  572. }
  573. }
  574. }
  575. return minutes == 0 ? 1 : minutes * 60;
  576. }
  577. //如果不是当天完成
  578. else
  579. {
  580. if (i == 1)
  581. {
  582. TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - beginTime.Ticks);
  583. minutes += (int)sp.TotalMinutes;
  584. if (beginTime>MornWorkEndTime)
  585. {
  586. minutes = minutes - restMinutes;
  587. }
  588. }
  589. else
  590. {
  591. if (endTime.Date == AfterWorkEndTime.Date)
  592. {
  593. if (endTime > AfterWorkEndTime)
  594. {
  595. TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
  596. minutes += (int)sp.TotalMinutes - restMinutes;
  597. }
  598. else
  599. {
  600. TimeSpan sp = new TimeSpan(endTime.Ticks - MornWorkBeginTime.Ticks);
  601. minutes += (int)sp.TotalMinutes;
  602. if (endTime> AfterWorkBeginTime)
  603. {
  604. minutes = minutes - restMinutes;
  605. }
  606. }
  607. return minutes == 0 ? 1 : minutes * 60;
  608. }
  609. else
  610. {
  611. TimeSpan sp = new TimeSpan(AfterWorkEndTime.Ticks - MornWorkBeginTime.Ticks);
  612. minutes += (int)sp.TotalMinutes-restMinutes;
  613. }
  614. }
  615. }
  616. }
  617. beginTime = beginTime.AddDays(1);
  618. AfterWorkEndTime = AfterWorkEndTime.AddDays(1);
  619. MornWorkBeginTime = MornWorkBeginTime.AddDays(1);
  620. MornWorkEndTime = MornWorkEndTime.AddDays(1);
  621. AfterWorkBeginTime = AfterWorkBeginTime.AddDays(1);
  622. }
  623. }
  624. return 0;
  625. }
  626. }
  627. /// <summary>
  628. /// 计算工作日
  629. /// 2024-08-28 过期了,不再使用和维护;
  630. /// 请调用 <inheritdoc cref="ICalcExpireTime.CalcEndTime"/>IExpireTime.CalcEndTime
  631. /// </summary>
  632. /// <param name="beginTime"></param>
  633. /// <param name="busCode"></param>
  634. /// <param name="isCenter"></param>
  635. /// <returns></returns>
  636. [Obsolete("新的方法 -> IExpireTime.CalcEndTime")]
  637. public ExpiredTimeWithConfig? CalcEndTime(DateTime beginTime, string busCode)
  638. {
  639. var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
  640. if (setting != null)
  641. {
  642. var result = CalcEndTime(beginTime, setting.TimeType, setting.TimeValue, setting.Percentage, setting.PercentageOne);
  643. var expiredTimeWithConfig = new ExpiredTimeWithConfig();
  644. expiredTimeWithConfig.TimeText = setting.TimeValue+"个"+setting.TimeType.GetDescription();
  645. expiredTimeWithConfig.TimeType = setting.TimeType;
  646. expiredTimeWithConfig.Count = setting.TimeValue;
  647. expiredTimeWithConfig.ExpiredTime = result.EndTime;
  648. expiredTimeWithConfig.NearlyExpiredTime = result.NearlyExpiredTime;
  649. expiredTimeWithConfig.NearlyExpiredTimeOne = result.NearlyExpiredTimeOne;
  650. return expiredTimeWithConfig;
  651. }
  652. return null;
  653. }
  654. public ExpiredTimeWithConfig CalcEndTime(DateTime beginTime, TimeConfig timeConfig,string busCode)
  655. {
  656. var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
  657. if (setting!=null)
  658. {
  659. var result = CalcEndTime(beginTime, timeConfig.TimeType, timeConfig.Count, setting.Percentage,setting.PercentageOne);
  660. var expiredTimeWithConfig = _mapper.Map<ExpiredTimeWithConfig>(timeConfig);
  661. expiredTimeWithConfig.ExpiredTime = result.EndTime;
  662. expiredTimeWithConfig.NearlyExpiredTime = result.NearlyExpiredTime;
  663. expiredTimeWithConfig.NearlyExpiredTimeOne = result.NearlyExpiredTimeOne;
  664. return expiredTimeWithConfig;
  665. }
  666. return null;
  667. }
  668. public TimeResult CalcEndTime(DateTime beginTime, ETimeType timeType, int timeValue, string busCode)
  669. {
  670. var setting = timeSettingList.FirstOrDefault(x => x.BusCode == busCode);
  671. if (setting!=null)
  672. {
  673. var result = CalcEndTime(beginTime, timeType, timeValue, setting.Percentage,setting.PercentageOne);
  674. return result;
  675. }
  676. return null;
  677. }
  678. /// <summary>
  679. /// 计算工作日
  680. /// </summary>
  681. /// <param name="beginTime"></param>
  682. /// <param name="timeType"></param>
  683. /// <param name="timeValue"></param>
  684. /// <param name="Percentage">即将超期百分比</param>
  685. /// <param name="PercentageOne">超期百分比第一级</param>
  686. /// <returns></returns>
  687. public TimeResult CalcEndTime(DateTime beginTime, ETimeType timeType, int timeValue,int Percentage,int PercentageOne)
  688. {
  689. DateTime startTime = beginTime;
  690. DateTime startTimeOne = beginTime;
  691. //如果是部门,采用部门计算方式
  692. switch (timeType)
  693. {
  694. #region 小时计算
  695. //新增对应小时
  696. //case ETimeType.Hour:
  697. //if (isCenter)
  698. //{
  699. // //中心计算自然时间
  700. // return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
  701. //}
  702. //else
  703. //{
  704. // //部门计算工作时间
  705. // //查询统一部门工作时间
  706. // var workTime = _systemSettingRepository.Get(x => x.Code == "WorkTime");
  707. // if (workTime != null)
  708. // {
  709. // //计算一天工作时间(分钟)
  710. // DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  711. // DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  712. // TimeSpan minuteSpan = new TimeSpan(WorkEndTime.Ticks - WorkBeginTime.Ticks);
  713. // //一天工作时间(分钟)
  714. // int minutes = (int)minuteSpan.TotalMinutes;
  715. // //延期总时间(分钟)
  716. // int timeValueMinutes = timeValue * 60;
  717. // //判断开始时间不在工时间段修正时间复位至当天或者第二天的开始时间(如果大于结束时间则复位至第二天的开始时间)
  718. // if (beginTime < WorkBeginTime)
  719. // {
  720. // beginTime = WorkBeginTime;
  721. // }
  722. // else
  723. // {
  724. // if (beginTime > WorkEndTime)
  725. // {
  726. // beginTime = WorkBeginTime.AddDays(1);
  727. // }
  728. // }
  729. // //判断第一天时间是否足够
  730. // TimeSpan firstMinuteSpan = new TimeSpan(WorkEndTime.Ticks - beginTime.Ticks);
  731. // //计算开始时间的第一天时间
  732. // int firstMinute = (int)firstMinuteSpan.TotalMinutes;
  733. // //判断第一天时间是否足够
  734. // if (firstMinute > timeValueMinutes)
  735. // {
  736. // //足够
  737. // bool canWhile = true;
  738. // while (canWhile)
  739. // {
  740. // //判断开始时间是否在工作日
  741. // if (IsWorkDay(beginTime))
  742. // {
  743. // return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
  744. // }
  745. // else
  746. // {
  747. // //如果不是工作日就加一天
  748. // beginTime = beginTime.AddDays(1);
  749. // }
  750. // }
  751. // return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
  752. // }
  753. // else
  754. // {
  755. // //不够
  756. // bool canWhile = true;
  757. // while (canWhile)
  758. // {
  759. // //判断开始时间是否在工作日
  760. // if (IsWorkDay(beginTime))
  761. // {
  762. // //在工作日
  763. // timeValueMinutes = timeValueMinutes - minutes;
  764. // if (timeValueMinutes > 0)
  765. // {
  766. // beginTime = beginTime.AddDays(1);
  767. // }
  768. // else
  769. // {
  770. // return new TimeResult { EndTime = beginTime.AddMinutes(timeValueMinutes), RuleStr = timeValue + "小时" };
  771. // }
  772. // }
  773. // else
  774. // {
  775. // //如果不是工作日
  776. // beginTime = beginTime.AddDays(1);
  777. // }
  778. // }
  779. // }
  780. // }
  781. // return new TimeResult { EndTime = beginTime.AddHours(timeValue), RuleStr = timeValue + "小时" };
  782. //}
  783. // return null;
  784. #endregion
  785. //新增工作日
  786. case ETimeType.WorkDay:
  787. //检查时间段内是否存在休息日或者工作日
  788. //查询统一部门工作时间
  789. var workTimeWorkDay = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
  790. if (workTimeWorkDay != null)
  791. {
  792. //计算一天工作时间(分钟)
  793. DateTime WorkBeginTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00");
  794. DateTime WorkEndTime = DateTime.Parse(beginTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00");
  795. //计算一天多少个工作小时
  796. var duration = WorkEndTime - WorkBeginTime;
  797. double workMinutes = duration.TotalMinutes;
  798. double totalWorkMinutes = (workMinutes * timeValue) * (Percentage/100.00);
  799. double totalWorkMinutesOne = (workMinutes * timeValue) * (PercentageOne / 100.00);
  800. //判断开始时间不在工时间段修正时间复位至当天或者第二天的开始时间(如果大于结束时间则复位至第二天的开始时间)
  801. if (beginTime < WorkBeginTime)
  802. {
  803. beginTime = WorkBeginTime;
  804. }
  805. else
  806. {
  807. if (beginTime > WorkEndTime)
  808. {
  809. beginTime = WorkBeginTime.AddDays(1);
  810. }
  811. }
  812. while (true)
  813. {
  814. if(IsWorkDay(beginTime))
  815. {
  816. break;
  817. }
  818. beginTime = beginTime.AddDays(1);
  819. }
  820. int day = 1;
  821. for (int i = 1; i < timeValue + 1; i++)
  822. {
  823. if (IsWorkDay(beginTime.AddDays(day)))
  824. {
  825. beginTime = beginTime.AddDays(day);
  826. if (totalWorkMinutes >= workMinutes)
  827. {
  828. startTime = startTime.AddDays(day);
  829. totalWorkMinutes = totalWorkMinutes - workMinutes;
  830. }
  831. else if(totalWorkMinutes < workMinutes && totalWorkMinutes != 0)
  832. {
  833. if (startTime.AddMinutes(totalWorkMinutes)> DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00"))
  834. {
  835. totalWorkMinutes = totalWorkMinutes - ((DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00") - startTime).TotalMinutes);
  836. startTime = startTime.AddDays(day);
  837. startTime = DateTime.Parse(startTime.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00").AddMinutes(totalWorkMinutes);
  838. totalWorkMinutes = 0;
  839. }
  840. else
  841. {
  842. startTime = startTime.AddMinutes(totalWorkMinutes);
  843. }
  844. }
  845. if (totalWorkMinutesOne >= workMinutes)
  846. {
  847. startTimeOne = startTimeOne.AddDays(day);
  848. totalWorkMinutesOne = totalWorkMinutesOne - workMinutes;
  849. }
  850. else if(totalWorkMinutesOne < workMinutes && totalWorkMinutesOne!=0)
  851. {
  852. if (startTimeOne.AddMinutes(totalWorkMinutesOne)> DateTime.Parse(startTimeOne.ToShortDateString()+" "+ workTimeWorkDay.SettingValue[1]+":00"))
  853. {
  854. totalWorkMinutesOne = totalWorkMinutesOne - ((DateTime.Parse(startTimeOne.ToShortDateString() + " " + workTimeWorkDay.SettingValue[1] + ":00") - startTimeOne).TotalMinutes);
  855. startTimeOne = startTimeOne.AddDays(day);
  856. startTimeOne = DateTime.Parse(startTimeOne.ToShortDateString() + " " + workTimeWorkDay.SettingValue[0] + ":00").AddMinutes(totalWorkMinutesOne);
  857. totalWorkMinutesOne = 0;
  858. }
  859. else
  860. {
  861. startTimeOne = startTimeOne.AddMinutes(totalWorkMinutesOne);
  862. }
  863. }
  864. day = 1;
  865. }
  866. else
  867. {
  868. i--;
  869. day++;
  870. }
  871. }
  872. }
  873. //TimeSpan duration = beginTime - startTime;
  874. //double percentage = 0.8 * duration.TotalHours;
  875. //DateTime resultTime = startTime + TimeSpan.FromHours((int)(percentage));
  876. //bool isWhile = true;
  877. //while (isWhile)
  878. //{
  879. // if (IsWorkDay(resultTime))
  880. // {
  881. // isWhile = false;
  882. // }
  883. // else
  884. // {
  885. // resultTime = resultTime.AddDays(1);
  886. // }
  887. //}
  888. return new TimeResult { EndTime = beginTime, RuleStr = timeValue + "个工作日", NearlyExpiredTime = startTime , NearlyExpiredTimeOne = startTimeOne };
  889. //新增自然日
  890. case ETimeType.Day:
  891. return new TimeResult { EndTime = beginTime.AddDays(timeValue), RuleStr = timeValue + "个自然日", NearlyExpiredTime = beginTime };
  892. default:
  893. return null;
  894. }
  895. }
  896. /// <summary>
  897. /// 计算时间间隔
  898. /// </summary>
  899. /// <param name="beginTime"></param>
  900. /// <param name="endTime"></param>
  901. /// <param name="isCenter"></param>
  902. /// <returns></returns>
  903. public string CalcTimeInterval(DateTime beginTime, DateTime endTime, bool isCenter)
  904. {
  905. if (isCenter)
  906. {
  907. //如果是中心按24小时制
  908. TimeSpan centerIntervalSp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  909. double re = Math.Round(((double)centerIntervalSp.Microseconds / (24 * 60)), 1);
  910. if (re > 0)
  911. {
  912. return re + "天后超期";
  913. }
  914. else
  915. {
  916. return "已超期" + Math.Abs(re) + "天";
  917. }
  918. }
  919. else
  920. {
  921. //如果是部门按工作时间 8小时制
  922. TimeSpan centerIntervalSp = new TimeSpan(endTime.Ticks - beginTime.Ticks);
  923. double re = Math.Round(((double)centerIntervalSp.Microseconds / (8 * 60)), 1);
  924. if (re > 0)
  925. {
  926. return re + "天后超期";
  927. }
  928. else
  929. {
  930. return "已超期" + Math.Abs(re) + "天";
  931. }
  932. return "";
  933. }
  934. }
  935. public bool IsWorkDay(DateTime date)
  936. {
  937. return _daySettingRepository.IsWorkDay(date).GetAwaiter().GetResult();
  938. }
  939. /// <summary>
  940. /// 判断当前时间是否是工作日 返回一个工作日
  941. /// </summary>
  942. /// <param name="date"></param>
  943. /// <returns></returns>
  944. [Obsolete("新的方法 -> IExpireTime.WorkDay")]
  945. public DateTime WorkDay(DateTime date)
  946. {
  947. var workTime = _systemSettingRepository.Get(x => x.Code == SettingConstants.WorkTime);
  948. if (IsWorkDay(date))
  949. {
  950. DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  951. DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  952. if (date < WorkBeginTime || date > WorkEndTime)
  953. {
  954. date = DateTime.Parse(date.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  955. }
  956. }
  957. else {
  958. while (!IsWorkDay(date))
  959. {
  960. date = date.AddDays(1);
  961. }
  962. DateTime WorkBeginTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  963. DateTime WorkEndTime = DateTime.Parse(DateTime.Now.ToShortDateString() + " " + workTime.SettingValue[1] + ":00");
  964. if (date < WorkBeginTime || date > WorkEndTime)
  965. {
  966. date = DateTime.Parse(date.ToShortDateString() + " " + workTime.SettingValue[0] + ":00");
  967. }
  968. }
  969. return date;
  970. }
  971. /// <summary>
  972. /// 倒推工作日
  973. /// </summary>
  974. /// <param name="date"></param>
  975. /// <returns></returns>
  976. [Obsolete()]
  977. public DateTime CalcWorkTimeReduce(DateTime date,int timeValue)
  978. {
  979. for (int i = 0; i < timeValue; i++)
  980. {
  981. if (IsWorkDay(date))
  982. {
  983. date = date.AddDays(-1);
  984. }
  985. else
  986. {
  987. date = date.AddDays(-1);
  988. i--;
  989. }
  990. }
  991. return date;
  992. }
  993. }
  994. }