using Edu.Common.API; using Edu.Common.Enum.User; using Edu.Common.Plugin; using Edu.Model.CacheModel; using Edu.Model.Entity.User; using Edu.Model.Public; using Edu.Model.ViewModel.User; using Edu.Repository.User; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using VT.FW.DB; namespace Edu.Module.User { /// /// 考勤处理类 /// public class AttendanceRecodModule { private readonly Rb_attendanceRepository respository = new Rb_attendanceRepository(); private readonly Rb_attendance_wayRepository AWrespository = new Rb_attendance_wayRepository(); private readonly Rb_workdaysetingRepository WDrespository = new Rb_workdaysetingRepository(); private readonly Rb_technicaldatesRepository TDrespository = new Rb_technicaldatesRepository(); private readonly Rb_attendance_recordRepository attendRecordRespository = new Rb_attendance_recordRepository(); /// /// 获取打卡信息 /// /// 员工id /// 部门id /// 打卡日期 /// public JObject GetAttendRecod(int empId, int RB_Department_Id, string date) { if (Convert.ToDateTime(date).Date > DateTime.Now.Date) { return null; } RB_Attendance_Extend attendance = respository.GetAttendanceByEmpId(empId); if (attendance != null) { if (attendance.CreateTime.Date > Convert.ToDateTime(date).Date) { return null; } } else { return null; } //打卡记录信息 RB_Attendance_Record_Extend recode = attendRecordRespository.GetAttendRecod(empId, date); JObject result = new JObject(); //先查询特殊日期打卡时间 //RB_Technicaldates_Extend technical = TDrespository.GetSpecialDate(empId, RB_Department_Id, date); var technicalList = TDrespository.GetSpecialDateList(empId, date);// ld 2020-05-25调整 RB_Technicaldates_Extend technical = null; if (technicalList.Any()) { if (technicalList.Where(x => x.EmployeeId > 0).Any() && technicalList.Where(x => x.EmployeeId == empId).Any()) { technical = technicalList.Where(x => x.EmployeeId == empId).FirstOrDefault(); } else if (technicalList.Where(x => x.RB_Department_Id > 0).Any() && technicalList.Where(x => x.RB_Department_Id == RB_Department_Id).Any()) { technical = technicalList.Where(x => x.RB_Department_Id == RB_Department_Id).FirstOrDefault(); } else { if (technicalList.Where(x => x.RB_Department_Id == 0 && x.EmployeeId == 0).Any()) { technical = technicalList.Where(x => x.RB_Department_Id == 0 && x.EmployeeId == 0).FirstOrDefault(); } } } if (technical != null) { if (technical.Type == (int)TechnicalTypeEnum.PunchCard) { result["onTime"] = technical.BeOnDutyTime; result["offTime"] = technical.OffDutyTime; } else { //特殊日期不打卡 return null; } } else { //正常打卡日期 RB_WorkdaySeting_Extend workDay = WDrespository.GetWorkDay(empId, StringHelper.GetWeek(Convert.ToDateTime(date))); if (workDay != null) { result["onTime"] = workDay.BeOnDutyTime; result["offTime"] = workDay.OffDutyTime; } else { return null; } } if (recode != null) { if (!string.IsNullOrEmpty(recode.BeOnTime)) { result["onTime"] = recode.BeOnTime; } if (!string.IsNullOrEmpty(recode.OffTime)) { result["offTime"] = recode.OffTime; } result["id"] = recode.Id; result["onStatus"] = (int)recode.BeOnStatus; result["onPunshCardTime"] = recode.BeOnDutyTime == null ? "" : recode.BeOnDutyTime.Value.ToString("HH:mm"); result["onPunshCardAddress"] = recode.BeOnVerifyAddress; result["isLackCard"] = recode.BeOnStatus == AttendanceEnum.QK; result["offStatus"] = (int)recode.OffStatus; result["offPunshCardTime"] = recode.OffDutyTime?.ToString("HH:mm"); result["offPunshCardAddress"] = recode.OffVerifyAddress; } else { result["id"] = 0; result["onStatus"] = 0; result["onPunshCardTime"] = null; result["onPunshCardAddress"] = ""; result["isLackCard"] = false; result["offStatus"] = 0; result["offPunshCardTime"] = null; result["offPunshCardAddress"] = ""; } string[] tempTypeStr = WFTTemplateTypeEnum.ReissueCard.ToName().Split('|'); result["cmd"] = tempTypeStr[3];//请求表单cmd result["submitCmd"] = tempTypeStr[4];//提交表单cmd return result; } /// /// 验证是否在打卡范围 /// /// 员工id /// 经纬度(维度,经度) /// mac地址 /// 原始wifiMac /// 公司考勤方式 /// public bool VerifyPunchCard(int empId, string latAndLong, string wifiMac, string oldWifiMac, out List wayList) { //verifyAddress合法类型名称 //type合法类型 1 地点 2 wifi wayList = AWrespository.GetWayByEmployeeId(empId); return IsRange(empId, latAndLong, wifiMac, oldWifiMac, out int type, out string verifyAddress); } /// /// App考勤打卡 /// /// 员工id /// 部门id /// 经纬度(维度,经度) /// mac地址 /// 原始mac /// 手机唯一id /// 打卡地址 /// 打卡地址 /// 1上班,2下班 /// 是否验证wifi /// public string PunchCard(int empId, int RB_Department_Id, string latAndLong, string wifiMac, string oldWifiMac, string phoneId, string address, string PhoneName, out int PunchCardType, bool isNotVerifyVifi = false) { PunchCardType = 1; string date = DateTime.Now.ToShortDateString(); //打卡记录信息 RB_Attendance_Record_Extend recode = attendRecordRespository.GetAttendRecod(empId, date); //根据手机标识码获取打卡记录信息 RB_Attendance_Record_Extend phoneIdRecode = attendRecordRespository.GetAttendRecodByPhoneId(phoneId, date); string onTime = ""; string offTime = ""; //先查询特殊日期打卡时间 #region 获取打卡时间 //RB_Technicaldates_Extend technical = TDrespository.GetSpecialDate(empId, RB_Department_Id, date); var technicalList = TDrespository.GetSpecialDateList(empId, date);// ld 2020-01-25 调整 RB_Technicaldates_Extend technical = null; if (technicalList.Any()) { if (technicalList.Where(x => x.EmployeeId > 0).Any() && technicalList.Where(x => x.EmployeeId == empId).Any()) { technical = technicalList.Where(x => x.EmployeeId == empId).FirstOrDefault(); } else if (technicalList.Where(x => x.RB_Department_Id > 0).Any() && technicalList.Where(x => x.RB_Department_Id == RB_Department_Id).Any()) { technical = technicalList.Where(x => x.RB_Department_Id == RB_Department_Id).FirstOrDefault(); } else { if (technicalList.Where(x => x.RB_Department_Id == 0 && x.EmployeeId == 0).Any()) { technical = technicalList.Where(x => x.RB_Department_Id == 0 && x.EmployeeId == 0).FirstOrDefault(); } } } if (technical != null) { if (technical.Type == (int)TechnicalTypeEnum.PunchCard) { onTime = technical.BeOnDutyTime; offTime = technical.OffDutyTime; } else { //特殊日期不打卡 return "ok"; } } else { //正常打卡日期 RB_WorkdaySeting_Extend workDay = WDrespository.GetWorkDay(empId, StringHelper.GetWeek(Convert.ToDateTime(date))); if (workDay != null) { onTime = workDay.BeOnDutyTime; offTime = workDay.OffDutyTime; } else { return "今天休息,无需打卡"; } } #endregion #region 验证打卡方式 //type合法类型 1 地点 2 wifi //是否在范围 int type = 2; string verifyAddress = ""; bool isRange = isNotVerifyVifi ? isNotVerifyVifi : IsRange(empId, latAndLong, wifiMac, oldWifiMac, out type, out verifyAddress); if (!isRange && string.IsNullOrWhiteSpace(latAndLong)) { type = 2; } #endregion #region 打卡 if (recode == null)//上班打卡 { if (phoneIdRecode != null && phoneIdRecode.EmployeeId != empId) { return "一台手机一天不能为多个账号打卡"; } else { RB_Attendance_Record dbRecord = new RB_Attendance_Record { EmployeeId = empId, BeOnAddress = address, BeOnDutyTime = DateTime.Now, BeOnType = type, BeOnVerifyAddress = verifyAddress }; if (dbRecord.BeOnType == 1) { dbRecord.BeOnTargetAddress = latAndLong; } else { dbRecord.BeOnTargetAddress = wifiMac; } dbRecord.PhoneId = phoneId; dbRecord.PhoneName = PhoneName; dbRecord.Date = DateTime.Now; dbRecord.BeOnTime = onTime; //string punchCardTime = dbRecord.BeOnDutyTime.ToShortTimeString(); DateTime punchCardDateTime = DateTime.Now;//打卡时间 DateTime onDateTime = Convert.ToDateTime(onTime);//上班时间 if (isRange) { if (punchCardDateTime.AddMinutes(-1) <= onDateTime) { dbRecord.BeOnStatus = AttendanceEnum.ZC; } else { dbRecord.BeOnStatus = AttendanceEnum.CD; TimeSpan timeSpan = punchCardDateTime - onDateTime; dbRecord.BeLateTime = (int)timeSpan.TotalMinutes;//迟到分钟数 } } else { return "不在打卡范围"; } attendRecordRespository.Insert(dbRecord); return "ok"; } } else { if (phoneIdRecode != null && phoneIdRecode.Id != recode.Id) { return "一台手机一天不能为多个账号打卡"; } else { RB_Attendance_Record dbRecord = recode.RefMapperTo(); dbRecord.OffAddress = address; if (dbRecord.BeOnType == 1) { dbRecord.OffTargetAddress = latAndLong; } else { dbRecord.OffTargetAddress = wifiMac; } dbRecord.OffDutyTime = DateTime.Now; dbRecord.OffType = type; dbRecord.PhoneId = phoneId; dbRecord.PhoneName = PhoneName; dbRecord.OffVerifyAddress = verifyAddress; dbRecord.OffTime = offTime; //string punchCardTime = dbRecord.BeOnDutyTime.ToShortTimeString(); DateTime punchCardDateTime = DateTime.Now;//打卡时间 DateTime offDateTime = Convert.ToDateTime(offTime);//下班时间 if (isRange) { if (punchCardDateTime >= offDateTime) { dbRecord.OffStatus = AttendanceEnum.ZC; PunchCardType = 2; } else { return "没到下班时间,打卡失败"; } } else { return "不在打卡范围"; } attendRecordRespository.Update(dbRecord); return "ok"; } } #endregion } /// /// 验证打卡范围 /// /// /// /// /// /// 合法类型 1 地点 2 wifi /// 合法类型 名称 /// private bool IsRange(int empId, string latAndLong, string wifiMac, string oldWifiMac, out int type, out string verifyAddress) { type = 1; verifyAddress = ""; List wayList = AWrespository.GetWayByEmployeeId(empId); if (wayList != null && wayList.Count() > 0) { if (!string.IsNullOrWhiteSpace(wifiMac)) { List wifiWay = wayList.Where(t => t.Type == (int)AttendWayTypeEnum.Wifi && (t.TargetAddress.ToLower() == wifiMac || t.TargetAddress.ToLower() == oldWifiMac)).ToList(); if (wifiWay != null && wifiWay.Count() > 0) { verifyAddress = wifiWay.FirstOrDefault().Name; type = 2; return true; } } if (!string.IsNullOrWhiteSpace(latAndLong)) { List addressList = wayList.Where(t => t.Type == (int)AttendWayTypeEnum.Address).ToList(); if (addressList != null && addressList.Count() > 0) { foreach (var item in addressList) { double distance = MapHelper.GetPointDistance(item.TargetAddress, latAndLong); if (distance <= item.Scope) { verifyAddress = item.Name; type = 1; return true; } } } } return false; } else { return false; } } /// /// 获取打卡信息统计 /// /// 员工id /// 获取日期(年-月-日) /// public List PunchCardStatistical(int empId, string date) { //打卡记录信息 List recodeList = attendRecordRespository.PunchCardStatistical(empId, date); List result = new List(); #region 出勤天数 { JObject attendance = new JObject { ["name"] = $"出勤天数", ["day"] = $"{recodeList.Count} 天" }; if (recodeList.Count > 0) { attendance["color"] = "black"; } else { attendance["color"] = "gray"; } List dataList = new List(); foreach (var item in recodeList) { dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); } attendance["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(attendance); } #endregion #region 休息天数 { JObject rest = new JObject { ["name"] = $"休息天数" }; DateTime searchDate = Convert.ToDateTime(date); List dataList = new List(); if (DateTime.Now.ToString("yyyy-MM") == searchDate.ToString("yyyy-MM"))//本月 { TimeSpan timeSpan = DateTime.Now - new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); int days = timeSpan.Days + 1; rest["day"] = $"{days - recodeList.Count()} 天"; rest["color"] = "gray"; for (int i = 1; i <= days; i++) { DateTime dt = new DateTime(searchDate.Year, searchDate.Month, i); if (recodeList.Where(t => t.Date.ToShortDateString() == dt.ToShortDateString()).Count() == 0) { dataList.Add($"{dt.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(dt.Date)})"); } } //foreach (var item in recodeList) //{ // dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); //} } else { int days = DateTime.DaysInMonth(searchDate.Year, searchDate.Month); rest["day"] = $"{days - recodeList.Count } 天"; rest["color"] = "black"; for (int i = 1; i <= days; i++) { DateTime dt = new DateTime(searchDate.Year, searchDate.Month, i); if (recodeList.Where(t => t.Date.ToShortDateString() == dt.ToShortDateString()).Count() == 0) { dataList.Add($"{dt.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(dt.Date)})"); } } } rest["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(rest); } #endregion #region 迟到 { JObject late = new JObject { ["name"] = $"迟到" }; List lateRecodeList = recodeList.Where(t => t.BeOnStatus == AttendanceEnum.CD).ToList(); late["day"] = $"{lateRecodeList.Count} 天"; if (recodeList.Count > 0) { late["color"] = "black"; } else { late["color"] = "gray"; } List dataList = new List(); foreach (var item in lateRecodeList) { dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); } late["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(late); } #endregion #region 缺卡 { JObject lackOfCard = new JObject { ["name"] = $"缺卡" }; List lackOfCardRecodeList = recodeList.Where(t => t.BeOnStatus != AttendanceEnum.QK && t.OffStatus == AttendanceEnum.QK).ToList(); lackOfCard["day"] = $"{lackOfCardRecodeList.Count} 天"; if (lackOfCardRecodeList.Count > 0) { lackOfCard["color"] = "black"; } else { lackOfCard["color"] = "gray"; } List dataList = new List(); foreach (var item in lackOfCardRecodeList) { dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); } lackOfCard["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(lackOfCard); } #endregion #region 旷工 { JObject absenteeism = new JObject { ["name"] = $"旷工" }; List absenteeismRecodeList = recodeList.Where(t => t.BeOnStatus == AttendanceEnum.QK && t.OffStatus == AttendanceEnum.QK).ToList(); absenteeism["day"] = $"{absenteeismRecodeList.Count} 天"; if (absenteeismRecodeList.Count > 0) { absenteeism["color"] = "red"; } else { absenteeism["color"] = "gray"; } List dataList = new List(); foreach (var item in absenteeismRecodeList) { dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); } absenteeism["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(absenteeism); } #endregion #region 外勤 { JObject field = new JObject { ["name"] = $"外勤" }; List fieldRecodeList = recodeList.Where(t => t.BeOnStatus == AttendanceEnum.WQ || t.OffStatus == AttendanceEnum.WQ).ToList(); field["day"] = $"{fieldRecodeList.Count} 天"; if (fieldRecodeList.Count > 0) { field["color"] = "black"; } else { field["color"] = "gray"; } List dataList = new List(); foreach (var item in fieldRecodeList) { dataList.Add($"{item.Date.ToShortDateString().Replace("/", "-")}({StringHelper.GetWeekChar(item.Date)})"); } field["dataList"] = JsonConvert.SerializeObject(dataList); result.Add(field); } #endregion return result; } /// /// 获取打卡月历 /// /// 员工id /// 获取日期(年-月-日) /// public List PunchCardCalendar(int empId, string date) { //打卡记录信息 List recodeList = attendRecordRespository.PunchCardStatistical(empId, date); List result = new List(); DateTime searchDate = Convert.ToDateTime(date); List dataList = new List(); int days = DateTime.DaysInMonth(searchDate.Year, searchDate.Month); for (int i = 1; i <= days; i++) { DateTime dt = new DateTime(searchDate.Year, searchDate.Month, i); if (dt.Date < DateTime.Now.Date) { JObject data = new JObject { ["day"] = i }; RB_Attendance_Record_Extend recode = recodeList.Where(t => t.Date.ToShortDateString() == dt.ToShortDateString()).FirstOrDefault(); if (recode != null) { data["id"] = recode.Id; data["rest"] = false; if (recode.BeOnStatus == AttendanceEnum.ZC && recode.OffStatus == AttendanceEnum.ZC) { data["stateColor"] = "#09D49D";//正常 } else if (recode.BeOnStatus == AttendanceEnum.CD) { data["stateColor"] = "#FF7D4C";//迟到 } else if (recode.BeOnStatus == AttendanceEnum.QK || recode.OffStatus == AttendanceEnum.QK) { data["stateColor"] = "#FF6868";//缺卡 } else if (recode.BeOnStatus == AttendanceEnum.WQ || recode.OffStatus == AttendanceEnum.WQ) { data["stateColor"] = "#548DFF";//外勤 } else if (recode.BeOnStatus == AttendanceEnum.QJ || recode.OffStatus == AttendanceEnum.QJ) { data["stateColor"] = "#FF7D4C";//请假 } else if (recode.BeOnStatus == AttendanceEnum.BK || recode.OffStatus == AttendanceEnum.BK) { data["stateColor"] = "#37CCE7";//补卡 } else { data["stateColor"] = "#FF6868";//异常 } } else { data["rest"] = true; data["stateColor"] = "#CCCCCC"; } result.Add(data); } else { break; } } return result; } } }