using BBWYB.Common.Models; using BBWYB.Server.Model; namespace BBWYB.Server.Business { public class TimeLimitRules : IDenpendency { /// /// 计算到期时间算法字典 /// private IDictionary> calculateExpirationTimeAlgorithmDictionary; public TimeLimitRules() { calculateExpirationTimeAlgorithmDictionary = new Dictionary>() { { Enums.TimeLimitTaskType.采购任务, CalculateExpirationTimeFor5WorkHour }, { Enums.TimeLimitTaskType.合格证拟定任务, CalculateExpirationTimeFor8WorkHour }, { Enums.TimeLimitTaskType.待核算任务, CalculateExpirationTimeFor8WorkHour }, { Enums.TimeLimitTaskType.待议价任务, CalculateExpirationTimeFor8WorkHour }, { Enums.TimeLimitTaskType.合格证补充任务, CalculateExpirationTimeFor2WorkHour } }; } /// /// 计算到期时间 /// /// 任务类型 /// 起点计算时间 /// public DateTime CalculateExpirationTime(Enums.TimeLimitTaskType timeLimitTaskType, DateTime startTime) { return calculateExpirationTimeAlgorithmDictionary[timeLimitTaskType](startTime); } /// /// 计算需要追加的天数,周六追加2天,周日追加1天 /// /// /// private int CalculateAddDay(DayOfWeek dayOfWeek) { if (dayOfWeek == DayOfWeek.Saturday) return 2; return 1; } /// /// 8小时工作时计算到期时间 /// /// 起点时间 /// private DateTime CalculateExpirationTimeFor8WorkHour(DateTime startTime) { int addDay = 0, addHour = 0, addSeconds = 0; //先确定是否为周日 if (startTime.DayOfWeek == DayOfWeek.Sunday) { addDay = 1; addHour = 18; } else { if (startTime.Hour < 9) addHour = 18; else if (startTime.Hour >= 9 && startTime.Hour < 12) { //计算从起点时间的9点开始到当前时间的时差 var timeSpan = startTime - startTime.Date.AddHours(9); if (timeSpan.TotalMinutes <= 5) { //从9点开始小于5分钟以内,以当天18点结束 addHour = 18; } else { addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 9; addSeconds = (int)timeSpan.TotalSeconds; } } else if (startTime.Hour >= 12 && startTime.Hour < 13) { //下一个工作日的12点结束 addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 12; } else if (startTime.Hour >= 13 && startTime.Hour < 18) { var timeSpan = startTime - startTime.Date.AddHours(13); //到下一个工作日的当前时间结束 addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 13; addSeconds = (int)timeSpan.TotalSeconds; } else if (startTime.Hour >= 18) { //下一个工作日的18点结束 addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 18; } } return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds); } /// /// 2小时工作时计算到期时间 /// /// 起点时间 /// private DateTime CalculateExpirationTimeFor2WorkHour(DateTime startTime) { int addDay = 0, addHour = 0, addSeconds = 0; //先确定是否为周日 if (startTime.DayOfWeek == DayOfWeek.Sunday) { addDay = 1; addHour = 11; } else { if (startTime.Hour < 9) addHour = 11; else if (startTime.Hour >= 9 && startTime.Hour < 12) { //如果在10点钟以前,则加两个小时 if (startTime.Hour < 10) { addHour = 11; addSeconds = Convert.ToInt32((startTime - startTime.Date.AddHours(9)).TotalSeconds); } else { addHour = 13; var to12senconds = Convert.ToInt32((startTime.Date.AddHours(12) - startTime).TotalSeconds); addSeconds = 7200 - to12senconds; } } else if (startTime.Hour >= 12 && startTime.Hour < 13) { addHour = 15; } else if (startTime.Hour >= 13 && startTime.Hour < 18) { if (startTime.Hour < 16) { addHour = startTime.Hour + 2; addSeconds = startTime.Minute * 60 + startTime.Second; } else if (startTime.Hour == 16 && startTime.Minute <= 5) { //从16点开始小于5分钟以内,以当天18点结束 addHour = 18; } else { addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 9; var to18senconds = Convert.ToInt32((startTime.Date.AddHours(18) - startTime).TotalSeconds); addSeconds = 7200 - to18senconds; } } else if (startTime.Hour >= 18) { //下一个工作日的18点结束 addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 11; } } return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds); } private DateTime CalculateExpirationTimeFor5WorkHour(DateTime startTime) { int addDay = 0, addHour = 0, addSeconds = 0; //先确定是否为周日 if (startTime.DayOfWeek == DayOfWeek.Sunday) { addDay = 1; addHour = 15; } else { if (startTime.Hour < 9) addHour = 15; else if (startTime.Hour >= 9 && startTime.Hour < 12) { addHour = 13; var to12senconds = Convert.ToInt32((startTime.Date.AddHours(12) - startTime).TotalSeconds); addSeconds = 18000 - to12senconds; } else if (startTime.Hour >= 12 && startTime.Hour < 13) { addHour = 18; } else if (startTime.Hour >= 13 && startTime.Hour < 18) { if (startTime.Hour == 13 && startTime.Minute <= 5) { //从16点开始小于5分钟以内,以当天18点结束 addHour = 18; } else { addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 9; var to18senconds = Convert.ToInt32((startTime.Date.AddHours(18) - startTime).TotalSeconds); addSeconds = 18000 - to18senconds; if (addSeconds > 10800) { //到第二天9点开始也超过3个小时,就从下午13点开始计算 addHour = 13; addSeconds -= 10800; } } } else if (startTime.Hour >= 18) { //下一个工作日的18点结束 addDay = CalculateAddDay(startTime.DayOfWeek); addHour = 15; } } return startTime.Date.AddDays(addDay).AddHours(addHour).AddSeconds(addSeconds); } /// /// 计算剩余任务时间(秒) /// /// /// public long CalculateLessTimeForWorkHour(DateTime expirationTime) { if (DateTime.Now >= expirationTime) return 0; //强制过期时间在工作时间点内 if (expirationTime.Hour < 9) expirationTime = expirationTime.Date.AddHours(9); else if (expirationTime.Hour >= 12 && expirationTime.Minute > 0 && expirationTime.Hour < 13) //排除整点结束的到期时间 expirationTime = expirationTime.Date.AddHours(12); else if (expirationTime.Hour >= 18 && expirationTime.Minute > 0) //排除整点结束的到期时间 expirationTime = expirationTime.Date.AddDays(CalculateAddDay(expirationTime.DayOfWeek)).AddHours(9); var startTime = DateTime.Now; long lessTime = 0; while (true) { //把非工作时间段转换成工作时间段 if (startTime.DayOfWeek == DayOfWeek.Sunday) { startTime = startTime.Date.AddDays(1).AddHours(9); } else { if (startTime.Hour < 9) startTime = startTime.Date.AddHours(9); else if (startTime.Hour >= 12 && startTime.Hour < 13) startTime = startTime.Date.AddHours(13); else if (startTime.Hour >= 18 && startTime.Minute > 0) startTime = startTime.Date.AddDays(CalculateAddDay(startTime.DayOfWeek)).AddHours(9); } //计算上午工作时间段 if (startTime.Hour >= 9 && startTime.Hour < 12) { if (expirationTime <= startTime.Date.AddHours(12)) { lessTime += Convert.ToInt32((expirationTime - startTime).TotalSeconds); break; } else { lessTime += 10800; startTime = startTime.Date.AddHours(13); } } //计算下午工作时间段 if (startTime.Hour >= 13 && startTime.Hour < 18) { if (expirationTime <= startTime.Date.AddHours(18)) { lessTime += Convert.ToInt32((expirationTime - startTime).TotalSeconds); break; } else { lessTime += 18000; startTime = startTime.Date.AddDays(CalculateAddDay(startTime.DayOfWeek)).AddHours(9); } } } return lessTime; } } }