package com.gzlh.device.face.hkutils; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONException; import cn.hutool.json.JSONObject; import com.gzlh.config.hksdk.HCNetSDK; import com.gzlh.constans.AjaxError; import com.gzlh.entity.AddFaceBO; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Date; /** * 功能:人脸下发、查询、删除、人员计划模板配置 */ @Service @Slf4j public class UserManage { @Resource private HCNetSDK hcNetSDK; /** * 添加人员 * * @param lUserID 登录句柄 * @param employeeNo 工号 * @throws UnsupportedEncodingException * @throws InterruptedException * @throws JSONException */ public void AddUserInfo(int lUserID, AddFaceBO addFaceBO) throws UnsupportedEncodingException, InterruptedException, JSONException { HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024); //数组 //"POST /ISAPI/AccessControl/UserInfo/Record?format=json" 此URL也是下发人员 String strInBuffer = "PUT /ISAPI/AccessControl/UserInfo/SetUp?format=json"; System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length());//字符串拷贝到数组中 ptrByteArray.write(); String name=addFaceBO.getName(); String employeeNo=addFaceBO.getNo(); int lHandler = hcNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(), strInBuffer.length(), null, null); if (lHandler < 0) { log.error("AddUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + hcNetSDK.NET_DVR_GetLastError()); throw new AjaxError("添加失败"); } else { byte[] Name = name.getBytes(StandardCharsets.UTF_8); //根据iCharEncodeType判断,如果iCharEncodeType返回6,则是UTF-8编码。 //如果是0或者1或者2,则是GBK编码 //将中文字符编码之后用数组拷贝的方式,避免因为编码导致的长度问题 Date now = new Date(); String nowTime = DateUtil.formatDate(now) + "T" + DateUtil.formatTime(now); String expireTime = StrUtil.replace(addFaceBO.getExpireTime(), " ","T"); String strInBuffer1 = "{\"UserInfo\":{\"Valid\":{\"beginTime\":\"" + nowTime + "\",\"enable\":true,\"endTime\":" + "\""+expireTime+"\"}," + "\"checkUser\":false,\"belongGroup \":\"1\",\"doorRight\":\"1\",\"RightPlan\":[{\"doorNo\": 1,\"planTemplateNo\": \"1,3,5\"}]," + "\"employeeNo\":\"" + employeeNo + "\",\"floorNumber\":2,\"maxOpenDoorTime\":0,\"name\":\""; String strInBuffer2 = "\",\"openDelayEnabled\":false,\"password\":\"\",\"roomNumber\":4,\"userType\":\"normal\"}}"; int iStringSize = Name.length + strInBuffer1.length() + strInBuffer2.length(); HCNetSDK.BYTE_ARRAY ptrByte = new HCNetSDK.BYTE_ARRAY(iStringSize); System.arraycopy(strInBuffer1.getBytes(), 0, ptrByte.byValue, 0, strInBuffer1.length()); System.arraycopy(Name, 0, ptrByte.byValue, strInBuffer1.length(), Name.length); System.arraycopy(strInBuffer2.getBytes(), 0, ptrByte.byValue, strInBuffer1.length() + Name.length, strInBuffer2.length()); ptrByte.write(); log.info(new String(ptrByte.byValue)); HCNetSDK.BYTE_ARRAY ptrOutuff = new HCNetSDK.BYTE_ARRAY(1024); IntByReference pInt = new IntByReference(0); while (true) { int dwState = hcNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, ptrByte.getPointer(), iStringSize, ptrOutuff.getPointer(), 1024, pInt); //读取返回的json并解析 ptrOutuff.read(); String strResult = new String(ptrOutuff.byValue).trim(); log.info("dwState:" + dwState + ",strResult:" + strResult); JSONObject jsonResult = new JSONObject(strResult); int statusCode = jsonResult.getInt("statusCode"); String statusString = jsonResult.getStr("statusString"); if (statusString.equals("OK")) { break; } if (dwState == -1) { log.info("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); break; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) { log.info("配置等待"); Thread.sleep(10); continue; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) { log.info("下发人员失败, json retun:" + jsonResult.toString()); throw new AjaxError("下发人员" + employeeNo + "失败"); } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) { log.info("下发人员异常, json retun:" + jsonResult.toString()); throw new AjaxError("下发人员" + employeeNo + "失败"); } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) {//返回NET_SDK_CONFIG_STATUS_SUCCESS代表流程走通了,但并不代表下发成功,比如有些设备可能因为人员已存在等原因下发失败,所以需要解析Json报文 if (statusCode != 1) { log.info("下发人员成功,但是有异常情况:" + jsonResult.toString()); throw new AjaxError("下发人员" + employeeNo + "失败"); } else { log.info("下发人员成功: json retun:" + jsonResult.toString()); } } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) { //下发人员时:dwState其实不会走到这里,因为设备不知道我们会下发多少个人,所以长连接需要我们主动关闭 log.info("下发人员完成"); break; } } if (!hcNetSDK.NET_DVR_StopRemoteConfig(lHandler)) { log.info("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); } else { log.info("NET_DVR_StopRemoteConfig接口成功"); } } } public void SearchUserInfo(int userID, String employeeNo) throws JSONException { HCNetSDK.BYTE_ARRAY ptrByteArray = new HCNetSDK.BYTE_ARRAY(1024); //数组 String strInBuffer = "POST /ISAPI/AccessControl/UserInfo/Search?format=json"; System.arraycopy(strInBuffer.getBytes(), 0, ptrByteArray.byValue, 0, strInBuffer.length());//字符串拷贝到数组中 ptrByteArray.write(); int lHandler = hcNetSDK.NET_DVR_StartRemoteConfig(userID, HCNetSDK.NET_DVR_JSON_CONFIG, ptrByteArray.getPointer(), strInBuffer.length(), null, null); if (lHandler < 0) { log.info("SearchUserInfo NET_DVR_StartRemoteConfig 失败,错误码为" + hcNetSDK.NET_DVR_GetLastError()); return; } else { //组装查询的JSON报文,这边查询的是所有的人员 JSONObject jsonObject = new JSONObject(); JSONObject jsonSearchCond = new JSONObject(); //如果需要查询指定的工号人员信息,把下面注释的内容去除掉即可 JSONArray EmployeeNoList = new JSONArray(); JSONObject employeeNo1 = new JSONObject(); employeeNo1.set("employeeNo", employeeNo); EmployeeNoList.put(employeeNo1); jsonSearchCond.set("EmployeeNoList", EmployeeNoList); jsonSearchCond.set("searchID", RandomUtil.randomNumbers(12)); jsonSearchCond.set("searchResultPosition", 0); jsonSearchCond.set("maxResults", 50); jsonObject.set("UserInfoSearchCond", jsonSearchCond); String strInbuff = jsonObject.toString(); log.info("查询的json报文:{},{}", employeeNo, strInbuff); //把string传递到Byte数组中,后续用.getPointer()方法传入指针地址中。 HCNetSDK.BYTE_ARRAY ptrInbuff = new HCNetSDK.BYTE_ARRAY(strInbuff.length()); System.arraycopy(strInbuff.getBytes(), 0, ptrInbuff.byValue, 0, strInbuff.length()); ptrInbuff.write(); //定义接收结果的结构体 HCNetSDK.BYTE_ARRAY ptrOutuff = new HCNetSDK.BYTE_ARRAY(10 * 1024); IntByReference pInt = new IntByReference(0); while (true) { int dwState = hcNetSDK.NET_DVR_SendWithRecvRemoteConfig(lHandler, ptrInbuff.getPointer(), strInbuff.length(), ptrOutuff.getPointer(), 10 * 1024, pInt); if (dwState == -1) { log.info("NET_DVR_SendWithRecvRemoteConfig接口调用失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); break; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_NEED_WAIT) { log.info("配置等待"); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } continue; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FAILED) { log.info("查询人员失败"); break; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_EXCEPTION) { log.info("查询人员异常"); break; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_SUCCESS) { ptrOutuff.read(); log.info("查询人员成功, json:" + new String(ptrOutuff.byValue).trim()); break; } else if (dwState == HCNetSDK.NET_SDK_CONFIG_STATUS_FINISH) { log.info("获取人员完成"); break; } } if (!hcNetSDK.NET_DVR_StopRemoteConfig(lHandler)) { log.info("NET_DVR_StopRemoteConfig接口调用失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); } else { log.info("NET_DVR_StopRemoteConfig接口成功"); lHandler = -1; } } } public boolean deleteUserInfo(int userID, String employeeNo) throws JSONException { //删除单个人员 String deleteUserjson = "{\n" + "\t\"UserInfoDetail\": {\t\n" + "\t\t\"mode\": \"byEmployeeNo\",\t\n" + "\t\t\"EmployeeNoList\": [\t\n" + "\t\t\t{\n" + "\t\t\t\t\"employeeNo\": \"" + employeeNo + "\"\t\n" + "\t\t\t}\n" + "\t\t]\n" + "\n" + "\t}\n" + "}"; //删除所有人员 // String deleteUserjson = "{\n" + // "\t\"UserInfoDetail\": {\t\n" + // "\t\t\"mode\": \"all\",\t\n" + // "\t\t\"EmployeeNoList\": [\t\n" + // "\t\t]\n" + // "\n" + // "\t}\n" + // "}"; String deleteUserUrl = "PUT /ISAPI/AccessControl/UserInfoDetail/Delete?format=json"; String result = transIsapi.put_isapi(userID, deleteUserUrl, deleteUserjson, hcNetSDK); log.info(result); //获取删除进度 while (true) { String getDeleteProcessUrl = "GET /ISAPI/AccessControl/UserInfoDetail/DeleteProcess?format=json"; String deleteResult = transIsapi.get_isapi(userID, getDeleteProcessUrl, hcNetSDK); JSONObject jsonObject = new JSONObject(deleteResult); JSONObject jsonObject1 = jsonObject.getJSONObject("UserInfoDetailDeleteProcess"); String process = jsonObject1.getStr("status"); log.info("process =" + process); if (process.equals("processing")) { log.info("正在删除"); continue; } else if (process.equals("success")) { log.info("删除成功"); break; } else if (process.equals("failed")) { throw new AjaxError("删除" + employeeNo + "失败"); } } return false; } /** * 人员计划模板配置 * * @param userID 用户登录句柄 * @param iPlanTemplateNumber 计划模板编号,从1开始,最大值从门禁能力集获取 */ public void SetCardTemplate(int userID, int iPlanTemplateNumber) { //设置卡权限计划模板参数 HCNetSDK.NET_DVR_PLAN_TEMPLATE_COND struPlanCond = new HCNetSDK.NET_DVR_PLAN_TEMPLATE_COND(); struPlanCond.dwSize = struPlanCond.size(); struPlanCond.dwPlanTemplateNumber = iPlanTemplateNumber;//计划模板编号,从1开始,最大值从门禁能力集获取 struPlanCond.wLocalControllerID = 0;//就地控制器序号[1,64],0表示门禁主机 struPlanCond.write(); HCNetSDK.NET_DVR_PLAN_TEMPLATE struPlanTemCfg = new HCNetSDK.NET_DVR_PLAN_TEMPLATE(); struPlanTemCfg.dwSize = struPlanTemCfg.size(); struPlanTemCfg.byEnable = 1; //是否使能:0- 否,1- 是 struPlanTemCfg.dwWeekPlanNo = 2;//周计划编号,0表示无效 struPlanTemCfg.dwHolidayGroupNo[0] = 0;//假日组编号,按值表示,采用紧凑型排列,中间遇到0则后续无效 byte[] byTemplateName; try { byTemplateName = "CardTemplatePlan_2".getBytes("GBK"); //计划模板名称 for (int i = 0; i < HCNetSDK.NAME_LEN; i++) { struPlanTemCfg.byTemplateName[i] = 0; } System.arraycopy(byTemplateName, 0, struPlanTemCfg.byTemplateName, 0, byTemplateName.length); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } struPlanTemCfg.write(); IntByReference pInt = new IntByReference(0); Pointer lpStatusList = pInt.getPointer(); if (false == hcNetSDK.NET_DVR_SetDeviceConfig(userID, HCNetSDK.NET_DVR_SET_CARD_RIGHT_PLAN_TEMPLATE_V50, 1, struPlanCond.getPointer(), struPlanCond.size(), lpStatusList, struPlanTemCfg.getPointer(), struPlanTemCfg.size())) { log.info("NET_DVR_SET_CARD_RIGHT_PLAN_TEMPLATE_V50失败,错误号:" + hcNetSDK.NET_DVR_GetLastError()); return; } log.info("NET_DVR_SET_CARD_RIGHT_PLAN_TEMPLATE_V50成功!"); //获取卡权限周计划参数 HCNetSDK.NET_DVR_WEEK_PLAN_COND struWeekPlanCond = new HCNetSDK.NET_DVR_WEEK_PLAN_COND(); struWeekPlanCond.dwSize = struWeekPlanCond.size(); struWeekPlanCond.dwWeekPlanNumber = 2; struWeekPlanCond.wLocalControllerID = 0; HCNetSDK.NET_DVR_WEEK_PLAN_CFG struWeekPlanCfg = new HCNetSDK.NET_DVR_WEEK_PLAN_CFG(); struWeekPlanCond.write(); struWeekPlanCfg.write(); Pointer lpCond = struWeekPlanCond.getPointer(); Pointer lpInbuferCfg = struWeekPlanCfg.getPointer(); if (false == hcNetSDK.NET_DVR_GetDeviceConfig(userID, HCNetSDK.NET_DVR_GET_CARD_RIGHT_WEEK_PLAN_V50, 1, lpCond, struWeekPlanCond.size(), lpStatusList, lpInbuferCfg, struWeekPlanCfg.size())) { log.info("NET_DVR_GET_CARD_RIGHT_WEEK_PLAN_V50失败,错误号:" + hcNetSDK.NET_DVR_GetLastError()); return; } struWeekPlanCfg.read(); struWeekPlanCfg.byEnable = 1; //是否使能:0- 否,1- 是 /**避免时间段交叉,先初始化, 七天八小时*/ for (int i = 0; i < 7; i++) { for (int j = 0; j < 8; j++) { struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].byEnable = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struBeginTime.byHour = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struBeginTime.byMinute = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struBeginTime.bySecond = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struEndTime.byHour = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struEndTime.byMinute = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[j].struTimeSegment.struEndTime.bySecond = 0; } } /**一周7天,全天24小时*/ for (int i = 0; i < 7; i++) { struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].byEnable = 1; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.byHour = 21; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.byMinute = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.bySecond = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.byHour = 23; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.byMinute = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.bySecond = 0; } /**一周7天,每天设置2个时间段*/ /*for(int i=0;i<7;i++) { struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].byEnable = 1; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.byHour = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.byMinute = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struBeginTime.bySecond = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.byHour = 11; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.byMinute = 59; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[0].struTimeSegment.struEndTime.bySecond = 59; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].byEnable = 1; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struBeginTime.byHour = 13; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struBeginTime.byMinute = 30; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struBeginTime.bySecond = 0; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struEndTime.byHour = 19; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struEndTime.byMinute = 59; struWeekPlanCfg.struPlanCfg[i].struPlanCfgDay[1].struTimeSegment.struEndTime.bySecond = 59; }*/ struWeekPlanCfg.write(); //设置卡权限周计划参数 if (false == hcNetSDK.NET_DVR_SetDeviceConfig(userID, HCNetSDK.NET_DVR_SET_CARD_RIGHT_WEEK_PLAN_V50, 1, lpCond, struWeekPlanCond.size(), lpStatusList, lpInbuferCfg, struWeekPlanCfg.size())) { log.info("NET_DVR_SET_CARD_RIGHT_WEEK_PLAN_V50失败,错误号:" + hcNetSDK.NET_DVR_GetLastError()); } else { log.info("NET_DVR_SET_CARD_RIGHT_WEEK_PLAN_V50成功!"); } } }