最近公司有个项目需要对接设备扫粤康码!
管理层选择了大华, 拿回来了大华的1台设备给我调试, 因健康码不允许转发 大华那边无法帮我处理, 所以只能申请数字平台后自己对接, 目前我这边的业务流程是:
二维码:
一般ASI 基线刷二维码相当于刷卡,步骤如下:
1) 客户发加密方式和秘钥给设备;
2) 客户发卡给设备;
3) 客户根据秘钥和卡号生成二维码字符串;
4) 客户通过公有的二维码生成方法把二维码字符串转化为二维码;
5) 在设备上刷这个二维码的时候,就相当于刷卡,与刷卡开门方式等同。
注意:普通用户二维码的有效时间为10分钟,访客类型用户的二维码有效时间为下发访客用户时设置的有效时间。
最后调粤省事解码SDK
大华官网下载sdk
https://support.dahuatech.com/tools/sdkExploit
将sdk导入idea后发现
1. JAVASE项目
2. 只能使用mian方法启动
3. 不能直接调用demo、module里方法
4. 官网代码是java swing图形界面开发方式
5. 需搭建springboot框架, 再把sdk用到的代码整合进来
springboot版本
下发用户 卡号 人脸
controller
/**
* 卡管理控制器
*
*/
@RestController
@RequestMapping("/card")
@Api(tags = "卡管理")
@Valid
public class CardController {
@Resource
private CardService cardService;
@Resource
private FileUploadUtils fileUploadUtils;
@Resource
private AccessRecordUtils accessRecordUtils;
@ApiOperation("获取卡列表")
@RequestMapping(value = "/getList", method = RequestMethod.POST)
public Result<List<CardDto>> getList(@ApiParam(value = "设备唯一id", required = true) @NotBlank String deviceNo, @ApiParam("卡号") String cardNo) {
List<CardDto> list = cardService.getList(deviceNo, cardNo);
return ResultUtil.data(list);
}
@ApiOperation("添加卡")
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Result add(String deviceNo,
CardDto cardDto) throws IOException {
Result<String> uploadResult = fileUploadUtils.upload(cardDto.getFace());
if (Boolean.FALSE.equals(uploadResult.isSuccess())) {
return ResultUtil.error("文件上传失败");
}
String picPath = uploadResult.getResult();
Memory memory = ToolKits.readPictureFile(picPath);
//先发送请求到设备
Result add = cardService.add(deviceNo, cardDto, memory);
//删除文件
fileUploadUtils.delete(picPath);
return add;
}
@ApiOperation("修改卡")
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Result update(String deviceNo,
CardDto cardDto,
HttpServletRequest request) throws IOException {
Result<String> uploadResult = fileUploadUtils.upload(cardDto.getFace());
if (Boolean.FALSE.equals(uploadResult.isSuccess())) {
return ResultUtil.error("文件上传失败");
}
String picPath = uploadResult.getResult();
Memory memory = ToolKits.readPictureFile(picPath);
//先发送请求到设备
Result update = cardService.update(deviceNo, cardDto, memory);
//再删除文件
fileUploadUtils.delete(picPath);
return update;
}
@PostMapping("/updateFace")
@ApiOperation("修改人脸照片")
public Result updateFace(String deviceNo,
String userId,
MultipartFile face) throws IOException {
Result<String> uploadResult = fileUploadUtils.upload(face);
if (Boolean.FALSE.equals(uploadResult.isSuccess())) {
return ResultUtil.error("文件上传失败");
}
String picPath = uploadResult.getResult();
Memory memory = ToolKits.readPictureFile(picPath);
//先发送请求到设备
Result update = cardService.updateFace(deviceNo, userId, memory);
//再删除文件
fileUploadUtils.delete(picPath);
return update;
}
@PostMapping("/delete")
@ApiOperation("删除卡")
public Result delete(@ApiParam(value = "设备唯一id", required = true) @NotBlank String deviceNo,
@ApiParam(value = "记录集编号", required = true) @NotBlank String recordNo,
@ApiParam(value = "用户id", required = true) @NotBlank String userId) {
return cardService.delete(deviceNo, recordNo, userId);
}
@PostMapping("/getAccessRecords")
@ApiOperation("获取出入记录列表")
public Result<List<AccessRecord>> getAccessRecords(@ApiParam(value = "设备唯一id", required = true) @NotBlank String deviceNo,
@ApiParam(value = "卡号") String cardNo,
@ApiParam(value = "起始时间") String startTime,
@ApiParam(value = "结束时间") String endTime) throws UnsupportedEncodingException {
return accessRecordUtils.findRecords(deviceNo, cardNo, startTime, endTime);
}
}
service
/**
* 卡操作功能实现
*
*/
@Service
public class CardServiceImpl implements CardService {
@Override
public List<CardDto> getList(String deviceNo, String cardNo) {
List<CardDto> cardDtoList = new LinkedList<>();
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return cardDtoList;
}
// 卡号: 为空,查询所有的卡信息
// 获取查询句柄
if (!GateModule.findCard(cardNo)) {
return cardDtoList;
}
int count = 0;
int index;
int nFindCount = 10;
// 查询具体信息
while (true) {
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARD[] pstRecord = GateModule.findNextCard(nFindCount);
if (pstRecord == null) {
break;
}
for (int i = 0; i < pstRecord.length; i++) {
index = i + count * nFindCount;
try {
CardDto cardDto = new CardDto();
// 序号
cardDto.setSerialNumber(String.valueOf(index + 1));
// 卡号
cardDto.setCardNo(new String(pstRecord[i].szCardNo).trim());
// 卡名
cardDto.setCardName(new String(pstRecord[i].szCardName, "GBK").trim());
// 用户ID
cardDto.setUserId(new String(pstRecord[i].szUserID).trim());
// 卡密码
cardDto.setCardPasswd(new String(pstRecord[i].szPsw).trim());
// 卡状态
cardDto.setCardStatus(pstRecord[i].emStatus);
cardDto.setCardStatusName(Res.string().getCardStatus(pstRecord[i].emStatus));
// 卡类型
cardDto.setCardType(pstRecord[i].emType);
cardDto.setCardTypeName(Res.string().getCardType(pstRecord[i].emType));
// 使用次数
cardDto.setUseTimes(String.valueOf(pstRecord[i].nUserTime));
// 是否首卡
cardDto.setFirstEnter(pstRecord[i].bFirstEnter);
// 是否有效
cardDto.setEnable(pstRecord[i].bIsValid);
// 有效开始时间
cardDto.setStartTime(pstRecord[i].stuValidStartTime.toStringTimeEx());
// 有效结束时间
cardDto.setEndTime(pstRecord[i].stuValidEndTime.toStringTimeEx());
cardDto.setRecordNo(pstRecord[i].nRecNo);
cardDtoList.add(cardDto);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (pstRecord.length < nFindCount) {
break;
} else {
count++;
}
}
// 关闭查询接口
GateModule.findCardClose();
return cardDtoList;
}
@Override
public Result add(String deviceNo, CardDto cardDto, Memory memory) {
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
if (ObjectUtil.isEmpty(cardDto.getCardNo())) {
return ResultUtil.error(Res.string().getInputCardNo());
}
if (ObjectUtil.isEmpty(cardDto.getUserId())) {
return ResultUtil.error(Res.string().getInputUserId());
}
if (ObjectUtil.isEmpty(cardDto.getCardName())) {
return ResultUtil.error("Please input cardName");
}
if (ObjectUtil.isEmpty(cardDto.getCardPasswd())) {
return ResultUtil.error("Please input cardPasswd");
}
if (memory == null) {
return ResultUtil.error(Res.string().getSelectPicture());
}
try {
if (cardDto.getCardNo().length() > 31) {
return ResultUtil.error(Res.string().getCardNoExceedLength() + "(31)");
}
if (cardDto.getUserId().length() > 31) {
return ResultUtil.error(Res.string().getUserIdExceedLength() + "(31)");
}
if (cardDto.getCardName().length() > 63) {
return ResultUtil.error(Res.string().getCardNameExceedLength() + "(63)");
}
if (cardDto.getCardPasswd().length() > 63) {
return ResultUtil.error(Res.string().getCardPasswdExceedLength() + "(63)");
}
} catch (Exception e1) {
e1.printStackTrace();
}
// 先添加卡,卡添加成功后,再添加图片
int useTimes;
if (StrUtil.isBlank(cardDto.getUseTimes())) {
useTimes = 0;
} else {
useTimes = Integer.parseInt(cardDto.getUseTimes());
}
boolean bCardFlags = GateModule.insertCard(cardDto.getCardNo(), cardDto.getUserId(), cardDto.getCardName(),
cardDto.getCardPasswd(), cardDto.getCardStatus(),
cardDto.getCardType(), useTimes,
cardDto.getFirstEnter(), cardDto.getEnable(), cardDto.getStartTime(), cardDto.getEndTime());
String cardError = "";
if (!bCardFlags) {
cardError = ToolKits.getErrorCodeShow();
}
boolean bFaceFalgs = GateModule.addFaceInfo(cardDto.getUserId(), memory);
String faceError = "";
if (!bFaceFalgs) {
faceError = ToolKits.getErrorCodeShow();
}
// 添加卡信息和人脸成功
if (bCardFlags && bFaceFalgs) {
return ResultUtil.success(Res.string().getSucceedAddCardAndPerson());
}
// 添加卡信息和人脸失败
if (!bCardFlags && !bFaceFalgs) {
return ResultUtil.error(Res.string().getFailedAddCard() + " : " + cardError);
}
// 添加卡信息成功,添加人脸失败
if (bCardFlags) {
return ResultUtil.error(Res.string().getSucceedAddCardButFailedAddPerson() + " : " + faceError);
}
// 卡信息已存在,添加人脸成功
return ResultUtil.error(Res.string().getCardExistedSucceedAddPerson());
}
@Override
public Result update(String deviceNo, CardDto cardDto, Memory memory) {
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
if (ObjectUtil.isEmpty(cardDto.getCardNo())) {
return ResultUtil.error(Res.string().getInputCardNo());
}
if (ObjectUtil.isEmpty(cardDto.getUserId())) {
return ResultUtil.error(Res.string().getInputUserId());
}
if (ObjectUtil.isEmpty(cardDto.getCardName())) {
return ResultUtil.error("Please input cardName");
}
if (ObjectUtil.isEmpty(cardDto.getCardPasswd())) {
return ResultUtil.error("Please input cardPasswd");
}
if (memory == null) {
return ResultUtil.error(Res.string().getSelectPicture());
}
try {
if (cardDto.getCardNo().length() > 31) {
return ResultUtil.error(Res.string().getCardNoExceedLength() + "(31)");
}
if (cardDto.getUserId().length() > 31) {
return ResultUtil.error(Res.string().getUserIdExceedLength() + "(31)");
}
if (cardDto.getCardName().length() > 63) {
return ResultUtil.error(Res.string().getCardNameExceedLength() + "(63)");
}
if (cardDto.getCardPasswd().length() > 63) {
return ResultUtil.error(Res.string().getCardPasswdExceedLength() + "(63)");
}
} catch (Exception e1) {
e1.printStackTrace();
}
// 先修改卡,卡修改成功后,再修改图片
int useTimes;
if (StrUtil.isBlank(cardDto.getUseTimes())) {
useTimes = 0;
} else {
useTimes = Integer.parseInt(cardDto.getUseTimes());
}
boolean bCardFlags = GateModule.modifyCard(cardDto.getRecordNo(), cardDto.getCardNo(),
cardDto.getUserId(), cardDto.getCardName(),
cardDto.getCardPasswd(), cardDto.getCardStatus(),
cardDto.getCardType(), useTimes,
cardDto.getFirstEnter(), cardDto.getEnable(), cardDto.getStartTime(), cardDto.getEndTime());
if (Boolean.FALSE.equals(bCardFlags)) {
return ResultUtil.error(Res.string().getFailedModifyCard() + " : " + ToolKits.getErrorCodeShow());
}
boolean bFaceFalgs = GateModule.modifyFaceInfo(cardDto.getUserId(), memory);
if (Boolean.FALSE.equals(bFaceFalgs)) {
return ResultUtil.error(Res.string().getSucceedModifyCardButFailedModifyPerson() + " : " + ToolKits.getErrorCodeShow());
}
return ResultUtil.success(Res.string().getSucceedModifyCardAndPerson());
}
@Override
public Result updateFace(String deviceNo,String userId, Memory memory) {
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
boolean bFaceFalgs = GateModule.modifyFaceInfo(userId, memory);
if (Boolean.FALSE.equals(bFaceFalgs)) {
return ResultUtil.error("修改人脸失败");
}
return ResultUtil.success("更新人脸成功");
}
@Override
public Result delete(String deviceNo, String recordNo, String userId) {
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
boolean deleteFaceInfo = GateModule.deleteFaceInfo(userId);
boolean deleteCard = GateModule.deleteCard(Integer.parseInt(recordNo));
// 删除人脸和卡信息
if (deleteFaceInfo && deleteCard) {
return ResultUtil.success(Res.string().getSucceed());
}
return ResultUtil.error(ToolKits.getErrorCodeShow());
}
}
postman测试
{
"success": true,
"message": "添加卡信息和人脸成功",
"code": 200,
"timestamp": 1653442376178,
"result": null
}
查验 (已下发到大华设备)
二维码Controller
import com.netsdk.bean.Result;
import com.netsdk.demo.module.QRModule;
import com.netsdk.lib.ToolKits;
import com.netsdk.utils.DeviceUtils;
import com.netsdk.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("/qr")
@Api(tags = "二维码")
@Valid
public class QRController {
/**
* @param deviceNo 设备
* @param key 密钥
* @return
*/
@ApiOperation("设置二维码的解码信息")
@RequestMapping(value = "/setQrcode", method = RequestMethod.POST)
public Result setQrcode(String deviceNo, String key) {
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
boolean bRet = QRModule.setQrcode(key);
if(bRet) {
return ResultUtil.data("设置二维码的解码信息成功");
} else {
return ResultUtil.error("设置二维码的解码信息失败: "+ToolKits.getErrorCodePrint());
}
}
/**
* @param card 卡号
* @param key 密钥
* @return
*/
@ApiOperation("根据秘钥和卡号生成二维码字符串")
@RequestMapping(value = "/strCreate", method = RequestMethod.POST)
public Result strCreate(String card, String key) {
String stOut = QRModule.strCreate(card, key);
if(!StringUtils.isEmpty(stOut)) {
return ResultUtil.data("加密后的字符串:" + stOut);
} else {
return ResultUtil.error("加密失败: "+ToolKits.getErrorCodePrint());
}
}
/**
* @param str 字符串
* @return
*/
@ApiOperation("生成二维码")
@RequestMapping(value = "/createQR", method = RequestMethod.POST)
public Result createQR(String str){
String result = QRModule.createQR(str);
if (!StringUtils.isEmpty(result)) {
return ResultUtil.data("生成二维码成功: " + result);
} else {
return ResultUtil.error("生成二维码失败");
}
}
/**
* @param deviceNo 设备
* @return
*/
@ApiOperation("订阅")
@RequestMapping(value = "/realLoadPicture", method = RequestMethod.POST)
public Result realLoadPicture(String deviceNo){
// 先退出登录,再登录,避免达到最大连接
DeviceUtils.logout();
boolean login = DeviceUtils.login(deviceNo);
if (!login) {
return ResultUtil.error("设备通讯故障");
}
boolean b = QRModule.realLoadPicture();
if (b) {
return ResultUtil.data("智能订阅成功");
} else {
return ResultUtil.error("智能订阅失败: "+ToolKits.getErrorCodePrint());
}
}
}
测试: 刷二维码
有需要大华sdk转springboot版本的请移步下载
https://download.csdn.net/download/weixin_43652507/85454365
swagger接口文档
http://ip:端口/doc.html
发送内容: "大华sdk"