using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Web;
using AlarmCSharpDemo;
using Dapper;

namespace DigitalSchoolApi.Controllers
{
    public static class HKAttendanceController
    {
        private static string _misConnection =
            ConfigurationManager.ConnectionStrings["ConnectionPfcMisDBString"].ConnectionString;

        private static string _coreConnection =
            ConfigurationManager.ConnectionStrings["CoreDBString"].ConnectionString;
        //海康考勤机回调
        public static CHCNetSDK.LoginResultCallBack LoginCallBack = null;
        private static CHCNetSDK.EXCEPYIONCALLBACK m_fExceptionCB = null;
        private static CHCNetSDK.MSGCallBack_V31 m_falarmData_V31 = null;

        /// <summary>
        /// 自动考勤
        /// </summary>
        public static void BeginLeaderAttendance()
        {
            try
            {
                using (IDbConnection connmis = new SqlConnection(_misConnection))
                {
                    var attendancerulEntity = connmis.QuerySingleOrDefault<ADR_RestrictionEntity>("select * from ADR_Restriction where REnable=1");
                    if (attendancerulEntity != null)
                    {
                        string datenow = DateTime.Now.ToString("yyyy-MM-dd");
                        //上班时间
                        DateTime workDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.WorkTime);
                        //下班时间
                        DateTime offworkDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.CloseTime);
                        //中午下班时间
                        DateTime offworkDateTimelunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.NoonCloseTime);
                        //中午上班时间
                        DateTime workDateTimelunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.NoonWorkTime);
                        //找出自动打卡人员
                        using (IDbConnection conncore = new SqlConnection(_coreConnection))
                        {
                            string AutoAttendanceRoleId = ConfigurationManager.AppSettings["AutoAttendance"];
                            var userlist = conncore.Query<LR_Base_UserRelationEntity>(
                                "select a.*,b.F_Account as EmpNo from LR_Base_UserRelation a left join LR_Base_User b on a.F_UserId=b.F_UserId where a.F_ObjectId='" + AutoAttendanceRoleId +
                                "' and a.F_Category=1 and b.F_EnabledMark=1 and b.F_DeleteMark=0");
                            foreach (var useritem in userlist)
                            {
                                //开始自动打卡
                                //删除今日考勤
                                connmis.Execute("delete from ADR_Record where ADYear='"+ workDateTime.Year + "' and ADMonth='" + workDateTime.Month.ToString().PadLeft(2,'0') + "' and ADDay='"+ workDateTime.Day.ToString().PadLeft(2,'0') + "' and UserNo='"+ useritem.EmpNo + "'");
                                //上午上班
                                ADR_RecordEntity adrRecordEntity = new ADR_RecordEntity();
                                adrRecordEntity.Create();
                                adrRecordEntity.UserNo = useritem.EmpNo;
                                adrRecordEntity.ADType = "1";
                                adrRecordEntity.ADTime = workDateTime.AddMinutes(-10);
                                adrRecordEntity.ClockTime = workDateTime.AddMinutes(-10);
                                adrRecordEntity.ClockStatus = "1";
                                adrRecordEntity.ClockPlace = "知行楼";
                                adrRecordEntity.ADYear = workDateTime.Year.ToString();
                                adrRecordEntity.ADMonth = workDateTime.Month.ToString().PadLeft(2, '0');
                                adrRecordEntity.ADDay = workDateTime.Day.ToString().PadLeft(2, '0');
                                adrRecordEntity.ADPhoto = "";
                                //考勤记录
                                connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                if (attendancerulEntity.ClockTime == "四次打卡")
                                {
                                    //上午下班
                                    adrRecordEntity.Create();
                                    adrRecordEntity.ADType = "8";
                                    adrRecordEntity.ADTime = offworkDateTimelunch.AddMinutes(10);
                                    adrRecordEntity.ClockTime = offworkDateTimelunch.AddMinutes(10);
                                    connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                    "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                    "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                    "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                    //下午上班
                                    adrRecordEntity.Create();
                                    adrRecordEntity.ADType = "7";
                                    adrRecordEntity.ADTime = workDateTimelunch.AddMinutes(-10);
                                    adrRecordEntity.ClockTime = workDateTimelunch.AddMinutes(-10);
                                    connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                    "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                    "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                    "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                }
                                //下午下班
                                adrRecordEntity.Create();
                                adrRecordEntity.ADType = "2";
                                //adrRecordEntity.ADTime = offworkDateTime.AddMinutes(10);
                                //adrRecordEntity.ClockTime = offworkDateTime.AddMinutes(10);
                                //liangkun 2021-05-06 应客户要求改为下午6：00下班
                                adrRecordEntity.ADTime = Convert.ToDateTime(datenow + " 18:00"); 
                                adrRecordEntity.ClockTime = Convert.ToDateTime(datenow + " 18:00");
                                connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                conncore.Execute(
                                    "insert into LR_Base_Log(F_LogId,F_CategoryId,F_SourceObjectId,F_SourceContentJson,F_OperateTime) values(newid(),4,'自动考勤服务','" + useritem.EmpNo + "自动打卡成功',getdate())");
                            }
                        }
                    }
                    else
                    {
                        using (IDbConnection conncore = new SqlConnection(_coreConnection))
                            conncore.Execute(
                                "insert into LR_Base_Log(F_LogId,F_CategoryId,F_SourceObjectId,F_SourceContentJson,F_OperateTime) values(newid(),4,'自动考勤服务','由于考勤规则未设置，自动打卡失败',getdate())");
                    }
                }
            }
            catch (Exception e)
            {
                using (IDbConnection conncore = new SqlConnection(_coreConnection))
                    conncore.Execute(
                        "insert into LR_Base_Log(F_LogId,F_CategoryId,F_SourceObjectId,F_SourceContentJson,F_OperateTime) values(newid(),4,'自动考勤服务','自动打卡失败，发生异常：" + e.Message + "，详细：" + e.StackTrace + "',getdate())");
            }
        }

        public static void EndConnect()
        {
            using (IDbConnection connmis = new SqlConnection(_misConnection))
            {
                //获取设备
                var devicelist = connmis.Query<ADR_DeviceEntity>("select * from ADR_Device where F_EnabledMark=1");
                //登录设备
                foreach (var deviceEntity in devicelist)
                {
                    if (!string.IsNullOrEmpty(deviceEntity.DlUserID))
                    {
                        var result = CHCNetSDK.NET_DVR_CloseAlarmChan_V30(Convert.ToInt32(deviceEntity.DlUserID));
                        if (!result)
                        {
                            string iLastErr = "撤防失败，错误号：" + CHCNetSDK.NET_DVR_GetLastError(); //撤防失败，输出错误号
                            connmis.Execute("insert into ADR_DeviceLog(LogId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                            "newid(),'2','" + iLastErr + "设备IP：" + deviceEntity.IpAddress + "',getdate(),'system','自动化服务')");
                        }
                        else
                        {
                            connmis.Execute("insert into ADR_DeviceLog(LogId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                            "newid(),'0','设备撤防成功。设备IP：" + deviceEntity.IpAddress + "',getdate(),'system','自动化服务')");
                        }
                    }
                }
            }
        }

        public static void StartConnect()
        {
            #region 海康考勤机对接
            //判断考勤规则
            using (IDbConnection connmis = new SqlConnection(_misConnection))
            {
                var restrictionlist = connmis.Query<ADR_RestrictionEntity>("select * from ADR_Restriction where REnable=1");
                if (restrictionlist.Count() == 0)
                {
                    connmis.Execute("insert into ADR_DeviceLog(LogId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                    "newid(),'1','警告：考勤规则未配置，与考勤机连接操作未启动',getdate(),'system','自动化服务')");
                    return;
                }
            }

            //初始化SDK
            bool m_bInitSDK = CHCNetSDK.NET_DVR_Init();
            if (m_bInitSDK)
            {
                //保存SDK日志 To save the SDK log
                CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\HKSdkLog\\", true);

                //设置透传报警信息类型
                CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struLocalCfg = new CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();
                struLocalCfg.byAlarmJsonPictureSeparate = 1;//控制JSON透传报警数据和图片是否分离，0-不分离(COMM_VCA_ALARM返回)，1-分离（分离后走COMM_ISAPI_ALARM回调返回）

                Int32 nSize = Marshal.SizeOf(struLocalCfg);
                IntPtr ptrLocalCfg = Marshal.AllocHGlobal(nSize);
                Marshal.StructureToPtr(struLocalCfg, ptrLocalCfg, false);

                if (!CHCNetSDK.NET_DVR_SetSDKLocalCfg(17, ptrLocalCfg))  //NET_DVR_LOCAL_CFG_TYPE_GENERAL
                {
                    string strErr = "海康NET_DVR_SetSDKLocalCfg 失败, error code= " + CHCNetSDK.NET_DVR_GetLastError();
                    ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                    adrDeviceLogEntity.Create();
                    adrDeviceLogEntity.LogData = strErr;
                    adrDeviceLogEntity.LogType = "2";
                    //写入数据库
                    using (IDbConnection connmis = new SqlConnection(_misConnection))
                    {
                        connmis.Execute("insert into ADR_DeviceLog(LogId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                             "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.LogType + "'," +
                                             "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                    }
                }
                Marshal.FreeHGlobal(ptrLocalCfg);

                //设置异常消息回调函数
                if (m_fExceptionCB == null)
                {
                    m_fExceptionCB = new CHCNetSDK.EXCEPYIONCALLBACK(cbExceptionCB);
                }
                CHCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, IntPtr.Zero, m_fExceptionCB, IntPtr.Zero);

                //设置报警回调函数
                if (m_falarmData_V31 == null)
                {
                    m_falarmData_V31 = new CHCNetSDK.MSGCallBack_V31(MsgCallback_V31);
                }
                CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(m_falarmData_V31, IntPtr.Zero);
                using (IDbConnection connmis = new SqlConnection(_misConnection))
                {
                    //获取设备
                    var devicelist = connmis.Query<ADR_DeviceEntity>("select * from ADR_Device where F_EnabledMark=1");
                    //登录设备
                    foreach (var deviceEntity in devicelist)
                    {
                        CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();

                        //设备IP地址或者域名
                        byte[] byIP = System.Text.Encoding.Default.GetBytes(deviceEntity.IpAddress);
                        struLogInfo.sDeviceAddress = new byte[129];
                        byIP.CopyTo(struLogInfo.sDeviceAddress, 0);

                        //设备用户名
                        byte[] byUserName = System.Text.Encoding.Default.GetBytes(deviceEntity.AdminAccount);
                        struLogInfo.sUserName = new byte[64];
                        byUserName.CopyTo(struLogInfo.sUserName, 0);

                        //设备密码
                        byte[] byPassword = System.Text.Encoding.Default.GetBytes(deviceEntity.AdminPwd);
                        struLogInfo.sPassword = new byte[64];
                        byPassword.CopyTo(struLogInfo.sPassword, 0);

                        struLogInfo.wPort = ushort.Parse(deviceEntity.PortNumber.ToString());//设备服务端口号
                                                                                             //用户数据，回调时可用
                                                                                             //获取大小
                                                                                             //uint dwSize = (uint)Marshal.SizeOf(deviceEntity);
                                                                                             ////分配内存
                                                                                             //IntPtr ptrCond = Marshal.AllocHGlobal((int)dwSize);
                                                                                             ////写入内存
                                                                                             //Marshal.StructureToPtr(deviceEntity, ptrCond, false);
                                                                                             ////用户数据，回调时可用
                                                                                             //struLogInfo.pUser = ptrCond;
                                                                                             //struLogInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是 
                                                                                             //struLogInfo.cbLoginResult = new CHCNetSDK.LoginResultCallBack(AsynLoginMsgCallback);//注册回调函数;

                        struLogInfo.byLoginMode = 0; //0-Private, 1-ISAPI, 2-自适应
                        struLogInfo.byHttps = 0; //0-不适用tls，1-使用tls 2-自适应

                        CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();
                        DeviceInfo.struDeviceV30.sSerialNumber = new byte[CHCNetSDK.SERIALNO_LEN];
                        //登录设备 Login the device
                        var lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);
                        //释放内存
                        //Marshal.FreeHGlobal(ptrCond);
                        //同步登录方法
                        string strLoginCallBack = "";
                        if (lUserID < 0)
                        {
                            uint iErrCode = CHCNetSDK.NET_DVR_GetLastError();
                            strLoginCallBack = "登录设备失败，lUserID：" + lUserID + "，错误号:" + iErrCode;
                            ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                            adrDeviceLogEntity.Create();
                            if (!string.IsNullOrEmpty(deviceEntity.Id))
                            {
                                adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                strLoginCallBack += "，设备IP：" + deviceEntity.IpAddress;
                            }
                            adrDeviceLogEntity.LogData = strLoginCallBack;
                            adrDeviceLogEntity.LogType = "2";
                            connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                 "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                 "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                        }
                        else
                        {
                            //登录成功
                            strLoginCallBack = "登录设备成功，lUserID：" + lUserID;
                            ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                            adrDeviceLogEntity.Create();
                            if (!string.IsNullOrEmpty(deviceEntity.Id))
                            {
                                adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                strLoginCallBack += "，设备IP：" + deviceEntity.IpAddress;
                            }
                            adrDeviceLogEntity.LogData = strLoginCallBack;
                            adrDeviceLogEntity.LogType = "0";
                            connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                 "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                 "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                            //设备布防
                            CHCNetSDK.NET_DVR_SETUPALARM_PARAM struAlarmParam = new CHCNetSDK.NET_DVR_SETUPALARM_PARAM();
                            struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
                            struAlarmParam.byLevel = 1; //0- 一级布防,1- 二级布防
                            struAlarmParam.byAlarmInfoType = 1;//智能交通设备有效，新报警信息类型
                            struAlarmParam.byDeployType = 0;
                            struAlarmParam.byFaceAlarmDetection = 1;//1-人脸侦测
                            var m_lUserID = CHCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, ref struAlarmParam);
                            if (m_lUserID < 0)
                            {
                                string strErr = "布防失败，错误号：" + CHCNetSDK.NET_DVR_GetLastError(); //布防失败，输出错误号
                                adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                adrDeviceLogEntity.Create();
                                if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                {
                                    adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                    strErr += "，设备IP：" + deviceEntity.IpAddress;
                                }
                                adrDeviceLogEntity.LogData = strErr;
                                adrDeviceLogEntity.LogType = "2";
                                connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                     "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                     "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                //更新设备状态
                                deviceEntity.DOnlineStatus = false;
                            }
                            else
                            {
                                adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                adrDeviceLogEntity.Create();
                                string strNotice = "布防成功";
                                if (!string.IsNullOrEmpty(deviceEntity.Id))
                                {
                                    adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                    strNotice += "，设备IP：" + deviceEntity.IpAddress;
                                }
                                adrDeviceLogEntity.LogData = strNotice;
                                adrDeviceLogEntity.LogType = "0";
                                connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                     "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                     "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                //更新设备状态
                                deviceEntity.DOnlineStatus = true;
                            }
                            //更新设备状态
                            connmis.Execute("update ADR_Device set DOnlineStatus=" + Convert.ToInt32(deviceEntity.DOnlineStatus) + ",DConnectDate=getdate(),DlUserID='" + lUserID + "' where Id='" + deviceEntity.Id + "'");
                        }

                    }
                }
            }
            else//初始化失败
            {
                ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                adrDeviceLogEntity.Create();
                adrDeviceLogEntity.LogData = "海康SDK初始化失败";
                adrDeviceLogEntity.LogType = "2";
                using (IDbConnection connmis = new SqlConnection(_misConnection))
                {
                    connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                         "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                         "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                }
            }
            #endregion
        }
        /// <summary>
        /// 海康异常回调
        /// </summary>
        /// <param name = "dwType" ></ param >
        /// < param name="lUserID"></param>
        /// <param name = "lHandle" ></ param >
        /// < param name="pUser"></param>
        public static void cbExceptionCB(uint dwType, int lUserID, int lHandle, IntPtr pUser)
        {
            try
            {
                //异常消息信息类型
                string stringAlarm = "海康异常消息回调，信息类型：0x" + Convert.ToString(dwType, 16) + ", lUserID:" + lUserID + ", lHandle:" + lHandle;
                using (IDbConnection connmis = new SqlConnection(_misConnection))
                {
                    var deviceEntity = connmis.QuerySingleOrDefault<ADR_DeviceEntity>("select * from ADR_Device where DlUserID='" + lUserID + "'");
                    ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                    adrDeviceLogEntity.Create();
                    if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                    {
                        adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                        stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                    }
                    adrDeviceLogEntity.LogData = stringAlarm;
                    adrDeviceLogEntity.LogType = "2";
                    connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                    "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                    "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                }
            }
            catch (Exception e)
            {
                using (IDbConnection conncore = new SqlConnection(_coreConnection))
                {
                    conncore.Execute(
                        "insert into LR_Base_Log(F_LogId,F_CategoryId,F_SourceObjectId,F_SourceContentJson,F_OperateTime) values(newid(),4,'海康考勤机','海康考勤机海康异常回调异常" + e.Message + ",详细" + e.StackTrace + "',getdate())");
                }
            }
        }

        /// <summary>
        /// 海康报警事件回调
        /// </summary>
        /// <param name = "lCommand" ></ param >
        /// < param name="pAlarmer"></param>
        /// <param name = "pAlarmInfo" ></ param >
        /// < param name="dwBufLen"></param>
        /// <param name = "pUser" ></ param >
        /// < returns ></ returns >
        public static bool MsgCallback_V31(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            try
            {
                if (lCommand == 0x5002) //门禁主机报警上传
                {
                    using (IDbConnection connmis = new SqlConnection(_misConnection))
                    {
                        var deviceEntity = connmis.QuerySingleOrDefault<ADR_DeviceEntity>("select * from ADR_Device where DlUserID='" + pAlarmer.lUserID + "'");
                        var datetimenow = DateTime.Now;
                        if (deviceEntity != null)
                        {
                            //更新设备状态
                            deviceEntity.DConnectDate = datetimenow;
                            connmis.Execute("update ADR_Device set DOnlineStatus=1,DConnectDate=getdate() where Id='" + deviceEntity.Id + "'");
                        }
                        //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
                        CHCNetSDK.NET_DVR_ACS_ALARM_INFO struAcsAlarm = new CHCNetSDK.NET_DVR_ACS_ALARM_INFO();
                        uint dwSize = (uint)Marshal.SizeOf(struAcsAlarm);
                        struAcsAlarm = (CHCNetSDK.NET_DVR_ACS_ALARM_INFO)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_DVR_ACS_ALARM_INFO));
                        //报警时间：年月日时分秒
                        string strTimeYear = (struAcsAlarm.struTime.dwYear).ToString();
                        string strTimeMonth = (struAcsAlarm.struTime.dwMonth).ToString("d2");
                        string strTimeDay = (struAcsAlarm.struTime.dwDay).ToString("d2");
                        string strTimeHour = (struAcsAlarm.struTime.dwHour).ToString("d2");
                        string strTimeMinute = (struAcsAlarm.struTime.dwMinute).ToString("d2");
                        string strTimeSecond = (struAcsAlarm.struTime.dwSecond).ToString("d2");
                        string strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
                                         strTimeMinute + ":" + strTimeSecond;
                        string stringAlarm = "门禁主机报警信息，dwMajor：0x" + Convert.ToString(struAcsAlarm.dwMajor, 16) +
                                             "，dwMinor：0x" +
                                             Convert.ToString(struAcsAlarm.dwMinor, 16) + "，卡号：" + System.Text.Encoding.UTF8
                                                 .GetString(struAcsAlarm.struAcsEventInfo.byCardNo).TrimEnd('\0')
                                             + "，读卡器编号：" + struAcsAlarm.struAcsEventInfo.dwCardReaderNo + "，报警触发时间：" +
                                             strTime +
                                             "，事件流水号：" + struAcsAlarm.struAcsEventInfo.dwSerialNo;
                        //这里判断是为了只获取刷脸的信息
                        if (struAcsAlarm.dwMajor == 0x5 && struAcsAlarm.dwMinor == 0x4b)//主事件0x5 代表EVENT，次事件0x4b 代表MINOR_FACE_VERIFY_PASS人脸认证通过
                        {
                            //报警设备IP地址
                            string strIP = System.Text.Encoding.UTF8.GetString(pAlarmer.sDeviceIP).TrimEnd('\0');
                            //抓拍图片路径
                            string str = "";
                            //保存抓拍图片
                            if ((struAcsAlarm.dwPicDataLen != 0) && (struAcsAlarm.pPicData != IntPtr.Zero))
                            {
                                string path = ConfigurationManager.AppSettings["AttendancePhotoPath"];
                                string datepath = DateTime.Now.ToString("yyyy-MM-dd");
                                if (!Directory.Exists(path + "\\" + datepath))
                                {
                                    Directory.CreateDirectory(path + "\\" + datepath);
                                }

                                str = path + "\\Device_Acs_CapturePic_[" + strIP + "]_lUerID_[" + pAlarmer.lUserID + "]_" +
                                     CreateNo() + ".jpg";
                                FileStream fs = new FileStream(str, FileMode.Create);
                                int iLen = (int)struAcsAlarm.dwPicDataLen;
                                byte[] by = new byte[iLen];
                                Marshal.Copy(struAcsAlarm.pPicData, by, 0, iLen);
                                fs.Write(by, 0, iLen);
                                fs.Close();
                            }
                            //如果能取到详细信息
                            if (struAcsAlarm.byAcsEventInfoExtend == 1)
                            {
                                CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND struInfoExtend = new CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND();
                                uint dwSizeEx = (uint)Marshal.SizeOf(struInfoExtend);
                                struInfoExtend = (CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND)Marshal.PtrToStructure(struAcsAlarm.pAcsEventInfoExtend, typeof(CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND));
                                stringAlarm += ", 人员类型:" + struInfoExtend.byUserType;
                            }

                            //考勤记录
                            //首先获取考勤规则
                            var attendancerulEntity = connmis.QuerySingleOrDefault<ADR_RestrictionEntity>("select * from ADR_Restriction where REnable=1");
                            if (attendancerulEntity != null)
                            {
                                //员工卡号
                                string EmpNo = System.Text.Encoding.UTF8.GetString(struAcsAlarm.struAcsEventInfo.byCardNo).TrimEnd('\0');
                                //考勤状态
                                string ADType = "0";
                                //考勤结果
                                string ClockStatus = "1";
                                //当前服务器日期
                                var datenow = DateTime.Now.ToString("yyyy-MM-dd");
                                //设备事件时间
                                DateTime devicetime = Convert.ToDateTime(strTime);
                                //掉线补传数据时间判断
                                //设备时间小于当前时间，判断为补传历史时间数据
                                if (devicetime.Date != DateTime.Now.Date)
                                {
                                    datenow = devicetime.ToString("yyyy-MM-dd");
                                }
                                //上班时间
                                DateTime workDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.WorkTime);
                                //下班时间
                                DateTime offworkDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.CloseTime);

                                #region  二次打卡
                                //判断打卡次数
                                if (attendancerulEntity.ClockTime == "二次打卡")
                                {
                                    //迟到判断
                                    if (devicetime <= workDateTime)//正常
                                    {
                                        ADType = "1";//上班
                                        ClockStatus = "1";//正常
                                    }
                                    else//迟到
                                    {
                                        //签到与签退判断
                                        if (devicetime >= offworkDateTime)//如果签到时间大于下班时间则为签退状态
                                        {
                                            ADType = "2";//下班
                                            ClockStatus = "1";//正常
                                        }
                                        else//小于下班时间
                                        {
                                            //首先判断是上班还是下班
                                            //该用户当日有签到记录视为下班签退
                                            var attendancerecord = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "' and ADType='1'");
                                            if (attendancerecord.Count() > 0)//如果存在上班考勤记录
                                            {
                                                //判断为下班早退
                                                if (attendancerulEntity.LeaveOverTime.HasValue && attendancerulEntity.LeaveOverTime != 0)//如果允许早退，获取范围
                                                {
                                                    //最早签退时间
                                                    DateTime offworkDateTimeFree = offworkDateTime.AddMinutes(-Convert.ToDouble(attendancerulEntity.LeaveOverTime));
                                                    if (devicetime >= offworkDateTimeFree)//在允许早退范围内记为正常
                                                    {
                                                        ADType = "2";//下班
                                                        ClockStatus = "1";//正常
                                                    }
                                                    else//超出早退范围视为早退
                                                    {
                                                        ADType = "2";//下班
                                                        ClockStatus = "3";//早退
                                                    }
                                                }
                                                else//不允许早退直接视为早退
                                                {
                                                    ADType = "2";//下班
                                                    ClockStatus = "3";//早退
                                                }
                                            }
                                            else//判断为上班迟到
                                            {
                                                if (attendancerulEntity.LateOvertime.HasValue && attendancerulEntity.LateOvertime != 0)//如果允许迟到，获取范围
                                                {
                                                    //最晚签到时间
                                                    DateTime workDateTimeFree = workDateTime.AddMinutes(Convert.ToDouble(attendancerulEntity.LateOvertime));
                                                    if (devicetime <= workDateTimeFree)//在允许迟到范围内记为正常
                                                    {
                                                        ADType = "1";//上班
                                                        ClockStatus = "1";//正常
                                                    }
                                                    else
                                                    {
                                                        ADType = "1";//上班
                                                        ClockStatus = "2";//迟到
                                                    }
                                                }
                                                else
                                                {
                                                    ADType = "1";//上班
                                                    ClockStatus = "2";//迟到
                                                }
                                            }
                                        }

                                    }
                                    ADR_RecordEntity adrRecordEntity = new ADR_RecordEntity();
                                    adrRecordEntity.Create();
                                    adrRecordEntity.UserNo = EmpNo;
                                    adrRecordEntity.ADType = ADType;
                                    adrRecordEntity.ADTime = datetimenow;
                                    adrRecordEntity.ClockTime = devicetime;
                                    adrRecordEntity.ClockStatus = ClockStatus;
                                    if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.DName))
                                    {
                                        adrRecordEntity.ClockPlace = deviceEntity.DName;
                                    }
                                    else
                                    {
                                        adrRecordEntity.ClockPlace = "未知";
                                    }
                                    adrRecordEntity.ADYear = strTimeYear;
                                    adrRecordEntity.ADMonth = strTimeMonth;
                                    adrRecordEntity.ADDay = strTimeDay;
                                    adrRecordEntity.ADPhoto = str;
                                    //记录日志
                                    ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                    adrDeviceLogEntity.Create();
                                    if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                    {
                                        adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                        stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                                    }

                                    adrDeviceLogEntity.LogData = stringAlarm;
                                    adrDeviceLogEntity.LogType = "0";
                                    connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                    "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                    "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                    //去重
                                    //获取当日考勤记录
                                    var attendancerecordlist = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "'");
                                    //签到去重
                                    if (adrRecordEntity.ADType == "1" && attendancerecordlist.Count(m => m.ADType == "1") > 0)//签过到了
                                    {
                                        //每日保留第一次签到记录
                                        return true;
                                    }
                                    //签退去重
                                    if (adrRecordEntity.ADType == "2" && attendancerecordlist.Count(m => m.ADType == "2") > 0)//签过退了
                                    {
                                        //更新签退时间，签退状态
                                        var firstoffworkentity = attendancerecordlist.FirstOrDefault(m => m.ADType == "2");
                                        firstoffworkentity.ADTime = datetimenow;
                                        firstoffworkentity.ClockTime = devicetime;
                                        firstoffworkentity.ClockStatus = ClockStatus;
                                        firstoffworkentity.ADPhoto = str;
                                        connmis.Execute("update ADR_Record set ADTime='" + firstoffworkentity.ADTime + "',ClockTime='" + firstoffworkentity.ClockTime + "',ClockStatus='" + firstoffworkentity.ClockStatus + "',ADPhoto='" + firstoffworkentity.ADPhoto + "' where ID='" + firstoffworkentity.ID + "'");
                                        return true;
                                    }
                                    //考勤记录
                                    connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                         "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                         "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                         "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                    return true;
                                }
                                #endregion

                                #region  四次打卡
                                else//四次打卡
                                {
                                    //中午下班时间
                                    DateTime offworkDateTimelunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.NoonCloseTime);
                                    //中午上班时间
                                    DateTime workDateTimelunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.NoonWorkTime);
                                    //中午下班考勤时间段
                                    DateTime offworkstartlunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.SignOutStartTime2);
                                    DateTime offworkendlunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.SignOutEndTime2);
                                    //中午上班考勤时间段
                                    DateTime workstartlunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.SignInStartTime2);
                                    DateTime workendlunch = Convert.ToDateTime(datenow + " " + attendancerulEntity.SignInEndTime2);
                                    //首先判断是否在中午考勤时间段
                                    //如果在中午下班考勤时间段
                                    if (offworkstartlunch <= devicetime && devicetime <= offworkendlunch)
                                    {
                                        //早退判断
                                        if (devicetime < offworkDateTimelunch)
                                        {
                                            //早退
                                            //允许早退判断
                                            if (attendancerulEntity.LeaveOverTime.HasValue && attendancerulEntity.LeaveOverTime != 0)
                                            {
                                                //中午下班最早签退时间
                                                DateTime offworkDateTimeFree = offworkDateTimelunch.AddMinutes(-Convert.ToDouble(attendancerulEntity.LeaveOverTime));
                                                if (devicetime > offworkDateTimeFree)
                                                {
                                                    //正常
                                                    ADType = "8";//中午下班
                                                    ClockStatus = "1";//正常
                                                }
                                                else
                                                {
                                                    //早退
                                                    ADType = "8";//中午下班
                                                    ClockStatus = "3";//早退
                                                }
                                            }
                                            else
                                            {
                                                //早退
                                                ADType = "8";//中午下班
                                                ClockStatus = "3";//早退
                                            }
                                        }
                                        else
                                        {
                                            //正常
                                            ADType = "8";//中午下班
                                            ClockStatus = "1";//正常
                                        }
                                        //写入考勤数据
                                        ADR_RecordEntity adrRecordEntity = new ADR_RecordEntity();
                                        adrRecordEntity.Create();
                                        adrRecordEntity.UserNo = EmpNo;
                                        adrRecordEntity.ADType = ADType;
                                        adrRecordEntity.ADTime = datetimenow;
                                        adrRecordEntity.ClockTime = devicetime;
                                        adrRecordEntity.ClockStatus = ClockStatus;
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.DName))
                                        {
                                            adrRecordEntity.ClockPlace = deviceEntity.DName;
                                        }
                                        else
                                        {
                                            adrRecordEntity.ClockPlace = "未知";
                                        }
                                        adrRecordEntity.ADYear = strTimeYear;
                                        adrRecordEntity.ADMonth = strTimeMonth;
                                        adrRecordEntity.ADDay = strTimeDay;
                                        adrRecordEntity.ADPhoto = str;
                                        //记录日志
                                        ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                        adrDeviceLogEntity.Create();
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                        {
                                            adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                            stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                                        }

                                        adrDeviceLogEntity.LogData = stringAlarm;
                                        adrDeviceLogEntity.LogType = "0";
                                        connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                        "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                        "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                        //考勤记录
                                        //去重
                                        var attendancerecordlist = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "'");
                                        if (attendancerecordlist.Count(m => m.ADType == "8") > 0)//存在中午下班记录更新记录
                                        {
                                            var firstoffworkentity = attendancerecordlist.FirstOrDefault(m => m.ADType == "8");
                                            firstoffworkentity.ADTime = datetimenow;
                                            firstoffworkentity.ClockTime = devicetime;
                                            firstoffworkentity.ClockStatus = ClockStatus;
                                            firstoffworkentity.ADPhoto = str;
                                            connmis.Execute("update ADR_Record set ADTime='" + firstoffworkentity.ADTime + "',ClockTime='" + firstoffworkentity.ClockTime + "',ClockStatus='" + firstoffworkentity.ClockStatus + "',ADPhoto='" + firstoffworkentity.ADPhoto + "' where ID='" + firstoffworkentity.ID + "'");
                                            return true;
                                        }
                                        else
                                        {
                                            connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                            "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                            "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                            "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                            return true;
                                        }
                                    }
                                    //如果在中午上班考勤时间段
                                    else if (workstartlunch <= devicetime && devicetime <= workendlunch)
                                    {
                                        //迟到判断
                                        if (devicetime > workDateTimelunch)
                                        {
                                            //迟到
                                            //允许迟到判断
                                            if (attendancerulEntity.LateOvertime.HasValue && attendancerulEntity.LateOvertime != 0)
                                            {
                                                //中午上班最晚签到时间
                                                DateTime workDateTimeFree = workDateTimelunch.AddMinutes(Convert.ToDouble(attendancerulEntity.LateOvertime));
                                                if (devicetime < workDateTimeFree)
                                                {
                                                    //正常
                                                    ADType = "7";//中午上班
                                                    ClockStatus = "1";//正常
                                                }
                                                else
                                                {
                                                    //迟到
                                                    ADType = "7";//中午上班
                                                    ClockStatus = "2";//迟到
                                                }
                                            }
                                            else
                                            {
                                                //迟到
                                                ADType = "7";//中午上班
                                                ClockStatus = "2";//迟到
                                            }
                                        }
                                        else
                                        {
                                            //正常
                                            ADType = "7";//中午下班
                                            ClockStatus = "1";//正常
                                        }
                                        //写入考勤数据
                                        ADR_RecordEntity adrRecordEntity = new ADR_RecordEntity();
                                        adrRecordEntity.Create();
                                        adrRecordEntity.UserNo = EmpNo;
                                        adrRecordEntity.ADType = ADType;
                                        adrRecordEntity.ADTime = datetimenow;
                                        adrRecordEntity.ClockTime = devicetime;
                                        adrRecordEntity.ClockStatus = ClockStatus;
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.DName))
                                        {
                                            adrRecordEntity.ClockPlace = deviceEntity.DName;
                                        }
                                        else
                                        {
                                            adrRecordEntity.ClockPlace = "未知";
                                        }
                                        adrRecordEntity.ADYear = strTimeYear;
                                        adrRecordEntity.ADMonth = strTimeMonth;
                                        adrRecordEntity.ADDay = strTimeDay;
                                        adrRecordEntity.ADPhoto = str;
                                        //记录日志
                                        ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                        adrDeviceLogEntity.Create();
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                        {
                                            adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                            stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                                        }

                                        adrDeviceLogEntity.LogData = stringAlarm;
                                        adrDeviceLogEntity.LogType = "0";
                                        connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                        "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                        "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                        //考勤记录
                                        //去重
                                        var attendancerecordlist = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "'");
                                        if (attendancerecordlist.Count(m => m.ADType == "7") == 0)
                                        {
                                            connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                        "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                        "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                        "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                        }
                                        return true;
                                    }
                                    else//不在中午考勤时间段判断迟到早退
                                    {
                                        //迟到判断
                                        if (devicetime <= workDateTime)//正常
                                        {
                                            ADType = "1";//上班
                                            ClockStatus = "1";//正常
                                        }
                                        else//迟到
                                        {
                                            //签到与签退判断
                                            if (devicetime >= offworkDateTime)//如果签到时间大于下班时间则为签退状态
                                            {
                                                ADType = "2";//下班
                                                ClockStatus = "1";//正常
                                            }
                                            //迟到状态
                                            else
                                            {
                                                //首先判断是否中午时间段
                                                if (devicetime > offworkDateTimelunch && devicetime < workDateTimelunch)
                                                {
                                                    //无效打卡
                                                    //记录日志
                                                    ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                                                    adrDeviceLogEntity.Create();
                                                    if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                                    {
                                                        adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                                        stringAlarm += "，设备IP：" + deviceEntity.IpAddress + "不在考勤时间范围内，打卡无效";
                                                    }

                                                    adrDeviceLogEntity.LogData = stringAlarm;
                                                    adrDeviceLogEntity.LogType = "1";
                                                    connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                                    "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                                                    "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                                                    return true;
                                                }
                                                else
                                                {
                                                    //该用户当日有签到记录视为下班签退
                                                    var attendancerecord = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "'");
                                                    //首先判断上午考勤还是下午考勤
                                                    //如果小于中午下班时间
                                                    if (devicetime < offworkDateTimelunch)
                                                    {
                                                        //迟到
                                                        //无上班记录视为迟到
                                                        if (attendancerecord.Count(m => m.ADType == "1") == 0)
                                                        {
                                                            //上班迟到 
                                                            //获取迟到范围
                                                            if (attendancerulEntity.LateOvertime.HasValue && attendancerulEntity.LateOvertime != 0)
                                                            {
                                                                DateTime workDateTimeFree = workDateTime.AddMinutes(Convert.ToDouble(attendancerulEntity.LateOvertime));
                                                                if (devicetime <= workDateTimeFree)//在允许迟到范围内记为正常
                                                                {
                                                                    ADType = "1";//上班
                                                                    ClockStatus = "1";//正常
                                                                }
                                                                else
                                                                {
                                                                    ADType = "1";//上班
                                                                    ClockStatus = "2";//迟到
                                                                }
                                                            }
                                                            else
                                                            {
                                                                ADType = "1";//上班
                                                                ClockStatus = "2";//迟到
                                                            }
                                                        }
                                                        //早退
                                                        //有签到记录视为早退
                                                        else
                                                        {
                                                            //获取早退范围
                                                            if (attendancerulEntity.LeaveOverTime.HasValue && attendancerulEntity.LeaveOverTime != 0)
                                                            {
                                                                //最早签退时间
                                                                DateTime offworkDateTimeFree = offworkDateTime.AddMinutes(-Convert.ToDouble(attendancerulEntity.LeaveOverTime));
                                                                if (devicetime >= offworkDateTimeFree)//在允许早退范围内记为正常
                                                                {
                                                                    ADType = "8";//中午下班
                                                                    ClockStatus = "1";//正常
                                                                }
                                                                else//超出早退范围视为早退
                                                                {
                                                                    ADType = "8";//中午下班
                                                                    ClockStatus = "3";//早退
                                                                }
                                                            }
                                                            else
                                                            {
                                                                ADType = "8";//中午下班
                                                                ClockStatus = "3";//早退
                                                            }

                                                        }
                                                    }
                                                    else if (devicetime > workDateTimelunch)//如果大于中午上班时间，且上级if判断小于下班时间
                                                                                            //判断为下午上班打卡迟到或早退
                                                    {
                                                        //如果存在中午签到记录
                                                        //判断为下班早退
                                                        if (attendancerecord.Count(m => m.ADType == "7") > 0)
                                                        {
                                                            //早退判断
                                                            //获取早退范围
                                                            if (attendancerulEntity.LeaveOverTime.HasValue && attendancerulEntity.LeaveOverTime != 0)
                                                            {
                                                                DateTime offworkDateTimeFree = offworkDateTime.AddMinutes(-Convert.ToDouble(attendancerulEntity.LeaveOverTime));
                                                                if (devicetime >= offworkDateTimeFree)//在允许早退范围内记为正常
                                                                {
                                                                    ADType = "2";//下班
                                                                    ClockStatus = "1";//正常
                                                                }
                                                                else//超出早退范围视为早退
                                                                {
                                                                    ADType = "2";//下班
                                                                    ClockStatus = "3";//早退
                                                                }
                                                            }
                                                            else
                                                            {
                                                                ADType = "2";//下班
                                                                ClockStatus = "3";//早退
                                                            }
                                                        }
                                                        else
                                                        {
                                                            //获取迟到范围
                                                            if (attendancerulEntity.LateOvertime.HasValue && attendancerulEntity.LateOvertime != 0)
                                                            {
                                                                //最晚签到时间
                                                                DateTime workDateTimeFree = workDateTimelunch.AddMinutes(Convert.ToDouble(attendancerulEntity.LateOvertime));
                                                                if (devicetime <= workDateTimeFree)//在允许迟到范围内记为正常
                                                                {
                                                                    ADType = "7";//中午上班
                                                                    ClockStatus = "1";//正常
                                                                }
                                                                else
                                                                {
                                                                    ADType = "7";//中午上班
                                                                    ClockStatus = "2";//迟到
                                                                }
                                                            }
                                                            else
                                                            {
                                                                ADType = "7";//中午上班
                                                                ClockStatus = "2";//迟到
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        ADR_RecordEntity adrRecordEntity = new ADR_RecordEntity();
                                        adrRecordEntity.Create();
                                        adrRecordEntity.UserNo = EmpNo;
                                        adrRecordEntity.ADType = ADType;
                                        adrRecordEntity.ADTime = datetimenow;
                                        adrRecordEntity.ClockTime = devicetime;
                                        adrRecordEntity.ClockStatus = ClockStatus;
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.DName))
                                        {
                                            adrRecordEntity.ClockPlace = deviceEntity.DName;
                                        }
                                        else
                                        {
                                            adrRecordEntity.ClockPlace = "未知";
                                        }
                                        adrRecordEntity.ADYear = strTimeYear;
                                        adrRecordEntity.ADMonth = strTimeMonth;
                                        adrRecordEntity.ADDay = strTimeDay;
                                        adrRecordEntity.ADPhoto = str;
                                        //记录日志
                                        ADR_DeviceLogEntity adrDeviceLogEntitylateorleave = new ADR_DeviceLogEntity();
                                        adrDeviceLogEntitylateorleave.Create();
                                        if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                                        {
                                            adrDeviceLogEntitylateorleave.DeviceId = deviceEntity.Id;
                                            stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                                        }

                                        adrDeviceLogEntitylateorleave.LogData = stringAlarm;
                                        adrDeviceLogEntitylateorleave.LogType = "0";
                                        connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                                        "'" + adrDeviceLogEntitylateorleave.LogId + "','" + adrDeviceLogEntitylateorleave.DeviceId + "','" + adrDeviceLogEntitylateorleave.LogType + "'," +
                                                        "'" + adrDeviceLogEntitylateorleave.LogData + "','" + adrDeviceLogEntitylateorleave.F_CreateDate + "','system','自动化服务')");
                                        //去重
                                        //获取当日考勤记录
                                        var attendancerecordlist = connmis.Query<ADR_RecordEntity>("select * from ADR_Record where ADYear='" + strTimeYear + "' and ADMonth='" + strTimeMonth + "' and ADDay='" + strTimeDay + "' and UserNo='" + EmpNo + "'");
                                        //签到去重
                                        if (adrRecordEntity.ADType == "1" && attendancerecordlist.Count(m => m.ADType == "1") > 0)//签过到了
                                        {
                                            //每日保留第一次签到记录
                                            return true;
                                        }
                                        //中午签到去重
                                        if (adrRecordEntity.ADType == "7" && attendancerecordlist.Count(m => m.ADType == "7") > 0)//中午签过到了
                                        {
                                            //每日保留第一次中午签到记录
                                            return true;
                                        }
                                        //中午签退去重
                                        if (adrRecordEntity.ADType == "8" && attendancerecordlist.Count(m => m.ADType == "8") > 0)//中午签过退了
                                        {
                                            //更新签退时间，签退状态
                                            var firstoffworkentity = attendancerecordlist.FirstOrDefault(m => m.ADType == "8");
                                            firstoffworkentity.ADTime = datetimenow;
                                            firstoffworkentity.ClockTime = devicetime;
                                            firstoffworkentity.ClockStatus = ClockStatus;
                                            firstoffworkentity.ADPhoto = str;
                                            connmis.Execute("update ADR_Record set ADTime='" + firstoffworkentity.ADTime + "',ClockTime='" + firstoffworkentity.ClockTime + "',ClockStatus='" + firstoffworkentity.ClockStatus + "',ADPhoto='" + firstoffworkentity.ADPhoto + "' where ID='" + firstoffworkentity.ID + "'");
                                            return true;
                                        }
                                        //签退去重
                                        if (adrRecordEntity.ADType == "2" && attendancerecordlist.Count(m => m.ADType == "2") > 0)//签过退了
                                        {
                                            //更新签退时间，签退状态
                                            var firstoffworkentity = attendancerecordlist.FirstOrDefault(m => m.ADType == "2");
                                            firstoffworkentity.ADTime = datetimenow;
                                            firstoffworkentity.ClockTime = devicetime;
                                            firstoffworkentity.ClockStatus = ClockStatus;
                                            firstoffworkentity.ADPhoto = str;
                                            connmis.Execute("update ADR_Record set ADTime='" + firstoffworkentity.ADTime + "',ClockTime='" + firstoffworkentity.ClockTime + "',ClockStatus='" + firstoffworkentity.ClockStatus + "',ADPhoto='" + firstoffworkentity.ADPhoto + "' where ID='" + firstoffworkentity.ID + "'");
                                            return true;
                                        }
                                        //考勤记录
                                        connmis.Execute("insert into ADR_Record(ID, UserNo, ADType, ADTime, ClockTime, ClockStatus, ClockPlace, ADYear, ADMonth, ADDay, ADPhoto) values(" +
                                                             "'" + adrRecordEntity.ID + "','" + adrRecordEntity.UserNo + "','" + adrRecordEntity.ADType + "','" + adrRecordEntity.ADTime + "'," +
                                                             "'" + adrRecordEntity.ClockTime + "','" + adrRecordEntity.ClockStatus + "','" + adrRecordEntity.ClockPlace + "','" + adrRecordEntity.ADYear + "'," +
                                                             "'" + adrRecordEntity.ADMonth + "','" + adrRecordEntity.ADDay + "','" + adrRecordEntity.ADPhoto + "')");
                                        return true;
                                    }

                                }
                                #endregion
                            }
                        }
                        else
                        {
                            //记录日志
                            ADR_DeviceLogEntity adrDeviceLogEntity = new ADR_DeviceLogEntity();
                            adrDeviceLogEntity.Create();
                            if (deviceEntity != null && !string.IsNullOrEmpty(deviceEntity.Id))
                            {
                                adrDeviceLogEntity.DeviceId = deviceEntity.Id;
                                stringAlarm += "，设备IP：" + deviceEntity.IpAddress;
                            }

                            adrDeviceLogEntity.LogData = stringAlarm;
                            adrDeviceLogEntity.LogType = "0";
                            connmis.Execute("insert into ADR_DeviceLog(LogId,DeviceId, LogType, LogData, F_CreateDate, F_CreateUserId, F_CreateUserName) values(" +
                                            "'" + adrDeviceLogEntity.LogId + "','" + adrDeviceLogEntity.DeviceId + "','" + adrDeviceLogEntity.LogType + "'," +
                                            "'" + adrDeviceLogEntity.LogData + "','" + adrDeviceLogEntity.F_CreateDate + "','system','自动化服务')");
                            return true;
                        }
                    }
                }
                return true; //回调函数需要有返回，表示正常接收到数据
            }
            catch (Exception e)
            {
                using (IDbConnection conncore = new SqlConnection(_coreConnection))
                {
                    conncore.Execute(
                        "insert into LR_Base_Log(F_LogId,F_CategoryId,F_SourceObjectId,F_SourceContentJson,F_OperateTime) values(newid(),4,'海康考勤机','海康考勤机报警事件回调异常" + e.Message + ",详细" + e.StackTrace + "',getdate())");
                }
                return true;
            }
        }

        #region  考勤结构体
        /// <summary>
        /// 考勤设备日志
        /// </summary>
        public class ADR_DeviceLogEntity
        {
            #region 实体成员

            public string LogId { get; set; }

            public string DeviceId { get; set; }

            public string LogType { get; set; }

            public string LogData { get; set; }

            public DateTime? F_CreateDate { get; set; }

            public string F_CreateUserId { get; set; }

            public string F_CreateUserName { get; set; }

            public DateTime? F_ModifyDate { get; set; }

            public string F_ModifyUserId { get; set; }

            public string F_ModifyUserName { get; set; }
            #endregion

            #region 扩展操作
            /// <summary>
            /// 新增调用
            /// </summary>
            public void Create()
            {
                this.LogId = Guid.NewGuid().ToString();
                this.F_CreateDate = DateTime.Now;
            }
            /// <summary>
            /// 编辑调用
            /// </summary>
            /// <param name="keyValue"></param>
            public void Modify(string keyValue)
            {
                this.LogId = keyValue;
                this.F_ModifyDate = DateTime.Now;
            }
            #endregion
        }
        /// <summary>
        /// 考勤设备管理
        /// </summary>
        public class ADR_DeviceEntity
        {
            #region 实体成员
            /// <summary>
            /// Id
            /// </summary>
            public string Id { get; set; }
            /// <summary>
            /// DName
            /// </summary>
            public string DName { get; set; }
            /// <summary>
            /// DCode
            /// </summary>
            public string DCode { get; set; }
            /// <summary>
            /// IpAddress
            /// </summary>
            public string IpAddress { get; set; }
            /// <summary>
            /// PortNumber
            /// </summary>
            public int? PortNumber { get; set; }
            /// <summary>
            /// AdminAccount
            /// </summary>
            public string AdminAccount { get; set; }
            /// <summary>
            /// AdminPwd
            /// </summary>
            public string AdminPwd { get; set; }
            /// <summary>
            /// F_EnabledMark
            /// </summary>
            public int? F_EnabledMark { get; set; }
            /// <summary>
            /// 布防状态
            /// </summary>
            public bool? DOnlineStatus { get; set; }
            /// <summary>
            /// 设备最后通讯时间
            /// </summary>
            public DateTime? DConnectDate { get; set; }
            /// <summary>
            /// 设备lUserID
            /// </summary>
            public string DlUserID { get; set; }
            /// <summary>
            /// F_CreateDate
            /// </summary>
            public DateTime? F_CreateDate { get; set; }
            /// <summary>
            /// F_CreateUserId
            /// </summary>
            public string F_CreateUserId { get; set; }
            /// <summary>
            /// F_CreateUserName
            /// </summary>
            public string F_CreateUserName { get; set; }
            /// <summary>
            /// F_ModifyDate
            /// </summary>
            public DateTime? F_ModifyDate { get; set; }
            /// <summary>
            /// F_ModifyUserId
            /// </summary>
            public string F_ModifyUserId { get; set; }
            /// <summary>
            /// F_ModifyUserName
            /// </summary>
            public string F_ModifyUserName { get; set; }
            #endregion

            #region 扩展操作
            /// <summary>
            /// 新增调用
            /// </summary>
            public void Create()
            {
                this.Id = Guid.NewGuid().ToString();
                this.F_CreateDate = DateTime.Now;
            }
            /// <summary>
            /// 编辑调用
            /// </summary>
            /// <param name="keyValue"></param>
            public void Modify(string keyValue)
            {
                this.Id = keyValue;
                this.F_ModifyDate = DateTime.Now;
            }
            #endregion
        }
        /// <summary>
        /// 版 本 Learun-ADMS V7.0.6 力软敏捷开发框架
        /// Copyright (c) 2013-2020 力软信息技术（苏州）有限公司
        /// 创 建：超级管理员
        /// 日 期：2020-09-03 14:57
        /// 描 述：考勤限制
        /// </summary>
        public class ADR_RestrictionEntity
        {
            #region 实体成员
            /// <summary>
            /// 编号
            /// </summary>
            public string ID { get; set; }
            /// <summary>
            /// 上班时间
            /// </summary>
            public string WorkTime { get; set; }
            /// <summary>
            /// 下班时间
            /// </summary>
            public string CloseTime { get; set; }
            /// <summary>
            /// 签到时间开始
            /// </summary>
            public string SignInStartTime { get; set; }
            /// <summary>
            /// 签到时间结束
            /// </summary>
            public string SignInEndTime { get; set; }
            /// <summary>
            /// 签退时间开始
            /// </summary>
            public string SignOutStartTime { get; set; }
            /// <summary>
            /// 签退时间结束
            /// </summary>
            public string SignOutEndTime { get; set; }
            /// <summary>
            /// 打卡次数
            /// </summary>
            public string ClockTime { get; set; }
            /// <summary>
            /// 中午签到开始时间
            /// </summary>
            public string SignInStartTime2 { get; set; }
            /// <summary>
            /// 中午签到结束时间
            /// </summary>
            public string SignInEndTime2 { get; set; }
            /// <summary>
            /// 中午签退开始时间
            /// </summary>
            public string SignOutStartTime2 { get; set; }
            /// <summary>
            /// 中午签退结束时间
            /// </summary>
            public string SignOutEndTime2 { get; set; }
            /// <summary>
            /// 中午签到时间
            /// </summary>
            public string NoonWorkTime { get; set; }
            /// <summary>
            /// 中午签退时间
            /// </summary>
            public string NoonCloseTime { get; set; }
            /// <summary>
            /// 迟到超时
            /// </summary>
            public int? LateOvertime { get; set; }
            /// <summary>
            /// 早退超时
            /// </summary>
            public int? LeaveOverTime { get; set; }
            /// <summary>
            /// 未签到，记为
            /// </summary>
            public int? NoSignIn { get; set; }
            /// <summary>
            /// 未签退，记为
            /// </summary>
            public int? NoSignOut { get; set; }
            /// <summary>
            /// 是否启用
            /// </summary>
            public bool? REnable { get; set; }
            #endregion

            #region 扩展操作
            /// <summary>
            /// 新增调用
            /// </summary>
            public void Create()
            {
                this.ID = Guid.NewGuid().ToString();
            }
            /// <summary>
            /// 编辑调用
            /// </summary>
            /// <param name="keyValue"></param>
            public void Modify(string keyValue)
            {
                this.ID = keyValue;
            }
            #endregion
        }

        /// <summary>
        /// 版 本 Learun-ADMS V7.0.6 力软敏捷开发框架
        /// Copyright (c) 2013-2020 力软信息技术（苏州）有限公司
        /// 创 建：超级管理员
        /// 日 期：2020-08-28 18:09
        /// 描 述：考勤记录
        /// </summary>
        public class ADR_RecordEntity
        {
            #region 实体成员
            /// <summary>
            /// 编号
            /// </summary>
            public string ID { get; set; }
            /// <summary>
            /// 员工名字
            /// </summary>
            public string UserName { get; set; }
            /// <summary>
            /// 员工编号
            /// </summary>
            public string UserNo { get; set; }
            /// <summary>
            /// 部门
            /// </summary>
            public string Department { get; set; }
            /// <summary>
            /// 考勤类型 0-未定义,1-上班，2-下班，3-开始休息，4-结束休息，5-开始加班，6-结束加班
            /// </summary>
            public string ADType { get; set; }
            /// <summary>
            /// 考勤时间（服务器时间）
            /// </summary>
            public DateTime? ADTime { get; set; }
            /// <summary>
            /// 打卡时间（考勤机时间）
            /// </summary>
            public DateTime? ClockTime { get; set; }
            /// <summary>
            /// 打卡结果 1正常,2迟到，3早退,4上班补签，5下班补签
            /// </summary>
            public string ClockStatus { get; set; }
            /// <summary>
            /// 打卡地点 
            /// </summary>
            public string ClockPlace { get; set; }
            /// <summary>
            /// 考勤年
            /// </summary>
            public string ADYear { get; set; }
            /// <summary>
            /// 考勤月
            /// </summary>
            public string ADMonth { get; set; }
            /// <summary>
            /// 考勤日
            /// </summary>
            public string ADDay { get; set; }
            /// <summary>
            /// 考勤照片
            /// </summary>
            public string ADPhoto { get; set; }
            #endregion

            #region 扩展操作
            /// <summary>
            /// 新增调用
            /// </summary>
            public void Create()
            {
                this.ID = Guid.NewGuid().ToString();
            }
            /// <summary>
            /// 编辑调用
            /// </summary>
            /// <param name="keyValue"></param>
            public void Modify(string keyValue)
            {
                this.ID = keyValue;
            }
            #endregion
        }

        /// <summary>
        /// 用户角色结构
        /// </summary>
        public class LR_Base_UserRelationEntity
        {
            public string F_UserRelationId { get; set; }
            public string F_UserId { get; set; }
            public int? F_Category { get; set; }
            public string F_ObjectId { get; set; }
            public string EmpNo { get; set; }
        }

        #endregion

        public static string CreateNo()
        {
            Random random = new Random();
            string strRandom = random.Next(1000, 10000).ToString(); //生成编号 
            string code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如
            return code;
        }
    }
}