using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
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;

        public static void StartConnect()
        {
            #region 海康考勤机对接
            //初始化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)
        {
            //异常消息信息类型
            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','自动化服务')");
            }
        }

        /// <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);
                                //上班时间
                                DateTime workDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.WorkTime);
                                //下班时间
                                DateTime offworkDateTime = Convert.ToDateTime(datenow + " " + attendancerulEntity.CloseTime);
                                //迟到判断
                                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;
                            }
                        }
                        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 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
        }
        #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;
        }
    }
}