MyTask.java
35.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
package com.example.dahua;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.dahua.bean.*;
import com.example.dahua.dao.UserDao;
import com.example.dahua.enums.EnumDeviceType;
import com.example.dahua.enums.EnumSendFaceType;
import com.example.dahua.enums.EnumSzBusinessType;
import com.example.dahua.lib.NetSDKLib;
import com.example.dahua.lib.ToolKits;
import com.example.dahua.lib.Utils;
import com.example.dahua.module.AutoRegisterModule;
import com.example.dahua.module.GateModule;
import com.example.dahua.module.LoginModule;
import com.example.dahua.mqtt.MqttManager;
import com.example.dahua.service.AttendanceService;
import com.example.dahua.utils.DateUtils;
import com.example.dahua.utils.FileUtils;
import com.example.dahua.utils.JsonUtils;
import com.example.dahua.xiananDao.SearchMapper;
import com.example.dahua.xiananDao.SendRecordDao;
import com.example.dahua.xstDao.MessageDao;
import com.google.gson.Gson;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
@Component
@Slf4j
public class MyTask implements ApplicationRunner {
//设备登录账号
public static String strUser = "admin";
//设备登密码
public static String password = "q12345678";
//在线设备信息集合
private static List<DeviceInfoBean> deviceInfoBeans = new ArrayList<>();
//存放登录句柄
public static Map<String, NetSDKLib.LLong> lLongMap = new HashMap<>();
//订阅句柄
public static Map<String, NetSDKLib.LLong> attachLongMap = new HashMap<>();
//下发设备句柄
public static Map<String, NetSDKLib.LLong> lLongSendMap = new HashMap<>();
//设备记录集
public static List<CDevInfo> devInfo =new ArrayList<>();
//断线设备
public static List<String> discDeviceIds = new ArrayList<>();
public static List<CDevInfo> discDevInfo =new ArrayList<>();
//判断首次是否有新设备上线
public static boolean isHasNewDevice = false;
//设备断线
public static boolean isFirstAutoRegister = false;
@Override
public void run(ApplicationArguments args) throws Exception {
DisconnectCallback disConnect = DisconnectCallback.getInstance();
HaveReconnectCallback haveReConnect = HaveReconnectCallback.getInstance();
// 打开工程,初始化
LoginModule.init(disConnect, haveReConnect);
//自注册
autoRegister();
}
/**
* 静态方法调用非静态接口层(Service层)
*/
public static MyTask myTaskUtil;
@PostConstruct
public void init() {
myTaskUtil = this;
myTaskUtil.sendRecordDao = this.sendRecordDao;
myTaskUtil.searchMapper = this.searchMapper;
myTaskUtil.userDao = this.userDao;
myTaskUtil.messageDao = this.messageDao;
myTaskUtil.attendanceService = this.attendanceService;
}
@Autowired
SendRecordDao sendRecordDao;
@Autowired
SearchMapper searchMapper;
@Autowired
UserDao userDao;
@Autowired
MessageDao messageDao;
@Autowired
AttendanceService attendanceService;
/**
* 设备自注册
*/
private void autoRegister() {
//回调
ServiceCallback serviceCallback = ServiceCallback.getInstance();
/**
* 开启监听服务
*/
log.info("new Utils().getHostAddress(): " + new Utils().getHostAddress());
AutoRegisterModule.startServer(new Utils().getHostAddress(), 9500, serviceCallback);
}
// 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数
private static class DisconnectCallback implements NetSDKLib.fDisConnect {
private static DisconnectCallback instance = new DisconnectCallback();
private DisconnectCallback() {}
public static DisconnectCallback getInstance() {
return instance;
}
public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
String deviceId = getDeviceId(pchDVRIP, nDVRPort);
log.info("DisConnect Device: {}, IP: {}, Port: {}",deviceId,pchDVRIP,nDVRPort);
if (!StringUtils.isEmpty(deviceId)) {
String inTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//保存设备
saveAttendanceService(deviceId,pchDVRIP,nDVRPort,0);
GateModule.stopRealLoadPic(attachLongMap.get(deviceId));
//移除在线
removeDevice(deviceId);
//处理断线设备
handleDiscDevice(deviceId);
//断线队列
discDeviceIds.add(deviceId);
isFirstAutoRegister = true;
}
}
}
// 网络连接恢复,设备重连成功回调
// 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数
private static class HaveReconnectCallback implements NetSDKLib.fHaveReConnect {
private static HaveReconnectCallback instance = new HaveReconnectCallback();
private HaveReconnectCallback() {}
public static HaveReconnectCallback getInstance() {
return instance;
}
public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
// 重连提示
String deviceId = getDeviceId(pchDVRIP, nDVRPort);
log.info("ReConnect Device: {},IP: {},Port: {}", deviceId,pchDVRIP, nDVRPort);
if (!StringUtils.isEmpty(deviceId)) {
String inTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//保存设备
saveAttendanceService(deviceId,pchDVRIP,nDVRPort,1);
DeviceInfoBean deviceInfoBean = new DeviceInfoBean();
deviceInfoBean.setDevcieId(deviceId);
deviceInfoBean.setDeviceIp(pchDVRIP);
deviceInfoBean.setDevicePort(nDVRPort);
deviceInfoBean.setLoginHandle(m_hLoginHandle);
deviceInfoBean.setPassword(password);
deviceInfoBean.setUsername(strUser);
deviceInfoBeans.add(deviceInfoBean);
lLongMap.put(deviceId, m_hLoginHandle);
lLongSendMap.put(deviceId, m_hLoginHandle);
}
}
}
/**
* 侦听服务器回调函数
*/
public static class ServiceCallback implements NetSDKLib.fServiceCallBack {
private static ServiceCallback instance = new ServiceCallback();
private ServiceCallback() {}
public static ServiceCallback getInstance() {
return instance;
}
@Override
public int invoke(NetSDKLib.LLong lHandle, final String pIp, final int wPort,
int lCommand, Pointer pParam1, int dwParamLen,
Pointer dwUserData) {
// 将 pParam 转化为序列号
byte[] buffer1 = new byte[dwParamLen];
pParam1.read(0, buffer1, 0, dwParamLen);
//设备id
String deviceId = "";
try {
deviceId = new String(buffer1, "UTF-8").trim();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
switch (lCommand) {
case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_DISCONNECT: { // 验证期间设备断线回调
log.info("Disconnect Device Info Device address: {},port: {},DeviceID: {}", pIp, wPort, deviceId);
log.info("EM_LISTEN_TYPE:验证期间设备断线回调");
//移除在线
removeDevice(deviceId);
//处理断线设备
handleDiscDevice(deviceId);
//断线队列
discDeviceIds.add(deviceId);
isFirstAutoRegister = true;
break;
}
case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_SERIAL_RETURN: { // 设备注册携带序列号
log.info("Register Device Info Device address: {},port: {},DeviceID: {}", pIp, wPort, deviceId);
log.info("EM_LISTEN_TYPE:设备注册携带序列号");
//保存设备
saveAttendanceService(deviceId,pIp,wPort,1);
CDevInfo dev = new CDevInfo();
System.arraycopy(pIp.getBytes(),0,dev.address,0,pIp.getBytes().length);
dev.port=wPort;
System.arraycopy(deviceId.getBytes(),0,dev.szSN,0,deviceId.getBytes().length);
if(isFirstAutoRegister){
if(discDeviceIds.size()>0){
Iterator<String> it =discDeviceIds.iterator();
while(it.hasNext()){
String a = it.next();
if(a.equals(deviceId)) {
it.remove();
discDevInfo.add(dev);
}
}
}else{
discDevInfo.add(dev);
}
break;
}
devInfo.add(dev);
//新设备上线
isHasNewDevice = true;
break;
}
default:
break;
}
return 1;
}
}
/**
* 需要下发的结构体请使用基本数据类型,避免使用String
*/
public static class CDevInfo extends NetSDKLib.SdkStructure {
public byte[] address=new byte[30];
public int port;
// 设备序列号
public byte[] szSN = new byte[32];
//登录句柄
public NetSDKLib.LLong hLogin;
public int nChannel;
@Override
public String toString() {
return "CDevInfo [szSN=" + new String(szSN).trim() + ", hLogin=" + hLogin.longValue() + ", nChannel=" + nChannel + "]";
}
}
/**
* 需要传到dwUser中的结构体请不要使用局部变量,容易被jvm回收。为了不被jvm回收,可以使用成员变量或让该变量被其他成员变量持有
* 登录设备(主动注册登陆二代接口)
* add by xuquan
*/
public void login(){
isHasNewDevice = false;
if((devInfo !=null && devInfo.size()>0)){
log.info("设备登入,设备总数:"+ devInfo.size());
Iterator<CDevInfo> it =devInfo.iterator();
while(it.hasNext()){
CDevInfo dev = it.next();
String szNo = new String(dev.szSN).trim();
if(!lLongMap.containsKey(szNo)){
doLogin(dev);
}
}
}
}
/**
* 断线设备登入
*/
public void DisLogin(){
isFirstAutoRegister = false;
//断线设备
if(discDevInfo !=null && discDevInfo.size()>0){
log.info("设备断线重连,断线设备总数:"+ discDevInfo.size());
Iterator<CDevInfo> it =discDevInfo.iterator();
while(it.hasNext()){
CDevInfo dev = it.next();
String szNo = new String(dev.szSN).trim();
if(!lLongMap.containsKey(szNo)){
doLogin(dev);
}
}
discDevInfo.clear();
}
}
public synchronized static void doLogin(CDevInfo dev) {
String address = new String(dev.address).trim();
int port = dev.port;
String deviceId = new String(dev.szSN).trim();
Pointer pointer = ToolKits.GetGBKStringToPointer(deviceId);
//0:tcp登入2:主动注册登入
final int nSpecCap = 2;
final IntByReference error = new IntByReference();
final NetSDKLib.NET_DEVICEINFO_Ex deviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
/************************************************* 登录设备 ************************************************/
//登录设备
NetSDKLib.LLong m_hLoginHandle = LoginModule.netsdk.CLIENT_LoginEx2(address, (short)port,strUser, password,nSpecCap,pointer,deviceInfo, error);
if(m_hLoginHandle.longValue() == 0) {
log.error("Login Device Failed ! deviceID: {},address: {},port: {},Last Error: {}",deviceId,address, port, ToolKits.getErrorCodePrint());
return;
}
log.info("登录设备成功,设备ID: {}",deviceId);
dev.nChannel = deviceInfo.byChanNum;
dev.hLogin=m_hLoginHandle;
/************************************************* 订阅设备 ************************************************/
//回调函数
AnalyzerDataCallBack analyzerDataCallBack = AnalyzerDataCallBack.getInstance();
int bNeedPicture = 1; // 是否需要图片
dev.write();
NetSDKLib.LLong hAttach = LoginModule.netsdk.CLIENT_RealLoadPictureEx(dev.hLogin, 0, NetSDKLib.EVENT_IVS_ALL, bNeedPicture,analyzerDataCallBack, dev.getPointer(),null);
dev.read();
if (hAttach.longValue() == 0) {
log.error("Failed to realLoad pic. deviceId;{}",deviceId);
return;
}
log.info("订阅成功,设备ID: {}",deviceId);
attachLongMap.put(deviceId,hAttach);
//登录句柄
lLongMap.put(deviceId, m_hLoginHandle);
//下发句柄
lLongSendMap.put(deviceId, m_hLoginHandle);
addDeviceInfo(deviceId,address,port,m_hLoginHandle);
}
private static void addDeviceInfo(String deviceId,String pIp,int wPort,NetSDKLib.LLong m_hLoginHandle){
DeviceInfoBean deviceInfoBean = new DeviceInfoBean();
deviceInfoBean.setDevcieId(deviceId);
deviceInfoBean.setDeviceIp(pIp);
deviceInfoBean.setDevicePort(wPort);
deviceInfoBean.setLoginHandle(m_hLoginHandle);
deviceInfoBeans.add(deviceInfoBean);
}
/**
* 订阅回调
*/
private static class AnalyzerDataCallBack implements NetSDKLib.fAnalyzerDataCallBack {
private static AnalyzerDataCallBack instance = new AnalyzerDataCallBack();
private AnalyzerDataCallBack() {}
public static AnalyzerDataCallBack getInstance() {
return instance;
}
private BufferedImage gateBufferedImage = null;
public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType,
Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
Pointer dwUser, int nSequence, Pointer reserved) {
if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) {
return -1;
}
byte[] bufferBytes = new byte[dwBufSize];
pBuffer.read(0, bufferBytes, 0, dwBufSize);
File path = new File(".\\FaceRecoder");
if (!path.exists()) {
path.mkdir();
}
//设备ID
CDevInfo data = new CDevInfo();
ToolKits.GetPointerData(dwUser, data);
String szSn = new String(data.szSN).trim();
///< 门禁事件
if (dwAlarmType == NetSDKLib.EVENT_IVS_ACCESS_CTL) {
NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg = new NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO();
ToolKits.GetPointerData(pAlarmInfo, msg);
//卡号
String card = new String(msg.szCardNo).trim();
//开门用户
String userId = new String(msg.szUserID).trim();
//开门错误码
int messageCode = msg.nErrorCode;
//处理心跳
saveAttendanceService(szSn,"",0,1);
String newCard = "";
try {
if (!StringUtils.isEmpty(card)) {
//根据卡号获取卡身份信息
CardBean cardBean = myTaskUtil.userDao.getCards(card);
if(cardBean ==null){
newCard = cardNo(card);
cardBean = myTaskUtil.userDao.getCards(newCard);
}
if(cardBean ==null){
log.info("卡号有误!!设备ID: 【{}】,上报卡号: 【{}】",szSn,card);
return -1;
}
// 缓存抓拍人脸
String fileName = StringUtils.isEmpty(userId)? card + ".png" : userId + ".png";
String snapPicPath = path + "\\" + fileName;
byte[] buffer = pBuffer.getByteArray(0, dwBufSize);
ByteArrayInputStream byteArrInputGlobal = new ByteArrayInputStream(buffer);
gateBufferedImage = ImageIO.read(byteArrInputGlobal);
if (gateBufferedImage != null) {
ImageIO.write(gateBufferedImage, "png", new File(snapPicPath));
}
snapPicPath = snapPicPath.replaceFirst("\\.", "http://121.40.109.21:8991");
snapPicPath = snapPicPath.replace("FaceRecoder", "image");
//关联设备信息
AttendanceBean attendanceBean = myTaskUtil.userDao.getTypeByClint_id(szSn);
if(attendanceBean !=null){
if(!StringUtils.isEmpty(attendanceBean.getSchool_id())){
int schoolId = Integer.parseInt(attendanceBean.getSchool_id());
String clintName = attendanceBean.getName();
//门禁进出类型:1进0出
int eventType = 0;
if(StringUtils.isEmpty(attendanceBean.getOutOrIn())){
eventType = EnumSzBusinessType.EnumDeviceInAndOut.OUT.code;
}else{
eventType = Integer.parseInt(attendanceBean.getOutOrIn());
}
//刷卡时间
String eventTime = DateUtils.date2String(new Date(), DateUtils.format2);
//老师
TeacherBean teacherBean = null;
if (cardBean.getType() == 0) {
//老师人脸信息,保存人脸记录表
teacherBean = myTaskUtil.userDao.getTeacherWithId(cardBean.getUser_id());
// log.info("设备信息【{}】,学生卡信息【{}】",new Gson().toJson(attendanceBean),new Gson().toJson(teacherBean));
myTaskUtil.sendRecordDao.addFaceRecoder(szSn, teacherBean.getUser_id(), teacherBean.getName(), snapPicPath,eventType,
eventTime, card,messageCode ==20?EnumSendFaceType.TIME_INTERVAL_ERROR.message:"",schoolId);
}
UserInfoBean userInfoBean = null;
if (cardBean.getType() == 2) {
//学生人脸信息,保存人脸记录表
userInfoBean = myTaskUtil.userDao.getStudentWithid(cardBean.getUser_id());
myTaskUtil.sendRecordDao.addFaceRecoder(szSn, userInfoBean.getUser_id(), userInfoBean.getName(), snapPicPath,eventType,
eventTime, card,messageCode ==20?EnumSendFaceType.TIME_INTERVAL_ERROR.message:"",schoolId);
}
//刷卡结果,1表示成功, 0表示失败
int status = msg.bStatus;
String result = status == 1 ? "开门成功" : "开门失败";
String openMsg = eventType ==1 ? "进" : "出" ;
if(szSn.startsWith("ytj")) {
log.info("出入信息:学校【{}】,开门方向:【{}】",schoolId,status);
// 艺校考勤OA
if(schoolId == 12 && status ==1){
int intOrOut = eventType ==1 ? 1 : 2;
if(userInfoBean !=null){
log.info("【{}】出入信息:方向【{}】,开门结果【{}】",userInfoBean.getName(),openMsg,result);
sendRecordToSXYX(userInfoBean.getName(),userInfoBean.getUser_id(),intOrOut,eventTime,"");
}
if(teacherBean != null){
sendRecordToSXYX(teacherBean.getName(),teacherBean.getUser_id(),intOrOut,eventTime,getScene(clintName));
}
}else{
// if(schoolId == 489){
// eventTime = DateUtils.date2String(DateUtils.getDateByTime(-5,new Date()), DateUtils.format2);
//// log.info("设备ID: {},刷卡结果:{},开门方向: {}, 开门用户: {}, 开门卡号: {}",szSn,result,openMsg,userInfoBean.getName(),userInfoBean.getStudent_num());
// }
//保存考勤记录
kaoQinRecord(status, eventType, card, szSn, eventTime,lAnalyzerHandle);
}
}
}
}
}
} catch (IOException e2) {
e2.printStackTrace();
}
}
return 0;
}
}
private static String getScene(String sceneName){
if(sceneName.contains("B")){
return "B";
}
if(sceneName.contains("C")){
return "C";
}
if(sceneName.contains("D")){
return "D";
}
return "";
}
/**
* 根据ip和port获取设备id
*
* @param pchDVRIP
* @param nDVRPort
* @return
*/
private static String getDeviceId(String pchDVRIP, int nDVRPort) {
for (DeviceInfoBean deviceInfoBean : deviceInfoBeans) {
if (pchDVRIP.equals(deviceInfoBean.getDeviceIp()) && nDVRPort == deviceInfoBean.getDevicePort()) {
return deviceInfoBean.getDevcieId();
}
}
return "";
}
/**
* 移除设备
*
* @param deviceId
*/
private static void removeDevice(String deviceId) {
DeviceInfoBean deviceInfoBean = null;
for (DeviceInfoBean dev : deviceInfoBeans) {
if (dev.getDevcieId().equals(deviceId)) deviceInfoBean = dev;
}
if (null != deviceInfoBean){
deviceInfoBeans.remove(deviceInfoBean);
}
}
/**
* 处理断线设备
* @param deviceId
*/
private static void handleDiscDevice(String deviceId){
//判断下发设备中是否存在断线设备,若存在则删除,重新添加新句柄
Iterator<String> iterator = lLongSendMap.keySet().iterator();
while (iterator.hasNext()){
String key = iterator.next();// 键
if(key.equals(deviceId)) {
iterator.remove();
}
}
Iterator<String> iterator2 = lLongMap.keySet().iterator();
while (iterator2.hasNext()){
String key = iterator2.next();// 键
if(key.equals(deviceId)) {
iterator2.remove();
}
}
Iterator<String> iterator3 = attachLongMap.keySet().iterator();
while (iterator3.hasNext()){
String key = iterator3.next();// 键
if(key.equals(deviceId)) {
iterator3.remove();
}
}
if(devInfo.size()>0){
Iterator<CDevInfo> it =devInfo.iterator();
while(it.hasNext()){
CDevInfo dev = it.next();
String id = new String(dev.szSN).trim();
if(id.equals(deviceId)) {
it.remove();
}
}
}
if(discDevInfo.size()>0){
Iterator<CDevInfo> it =discDevInfo.iterator();
while(it.hasNext()){
CDevInfo dev = it.next();
String id = new String(dev.szSN).trim();
if(id.equals(deviceId)) {
it.remove();
}
}
}
}
/**
* 保存联网设备并更新联网状态
* @param deviceId
* @param ip
* @param port
*/
public static void saveAttendanceService(String deviceId, String ip, int port,int status){
String inTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
String clintType = String.valueOf(EnumDeviceType.DH_FACE.deviceType);
if(deviceId.startsWith("ytj")){
clintType = String.valueOf(EnumDeviceType.DH_FACE_YTJ.deviceType);
}
myTaskUtil.attendanceService.insert(deviceId,clintType, ip,String.valueOf(port), inTime, "-1",1,status);
}
/**
* 卡号两两取反
*
* @param cardDex
* @return
*/
public static String cardNo(String cardDex) {
String cardR = "";
int length = cardDex.length();
if (length != 8) {
System.out.println("卡号格式不正确:" + cardDex);
return cardDex;
}
while (length > 0) {
length -= 2;
cardR += cardDex.substring(length, length + 2);
}
return cardR;
}
private static MqttManager mqttManager;
/**
* 大华设备考勤记录
* @param status
* @param eventType
* @param cardNo
* @param deviceId
* @param eventTime
*/
public static void kaoQinRecord(int status,int eventType,String cardNo,String deviceId,String eventTime,NetSDKLib.LLong lLong) {
if (status == 1) {
//有效刷卡调考勤存储过程
CheckIn checkIn = new CheckIn();
checkIn.setDeviceId(deviceId);
checkIn.setCardNo(cardNo);
checkIn.setFunNo(8);
checkIn.setFlag(eventType == EnumSzBusinessType.EnumDeviceInAndOut.INT.code ? 0:1);
checkIn.setCheckTime(eventTime);
myTaskUtil.searchMapper.checkIn(checkIn);
if (checkIn.getIsSuccess() == 1) {
log.info("考勤成功: checkIn: {}, 方向:{}",JsonUtils.nonDefaultMapper().toJson(checkIn),eventType == 1 ? "进门" : "出门");
//考勤成功
String content = "考勤成功!,设备:" + deviceId + "卡号:" + cardNo + "方向:" + (eventType == 1 ? "进门" : "出门") + "______" + eventTime;
//开始推送看板
sendMQMess(deviceId,cardNo,eventType);
//记录学生考勤签到记录
FileUtils.getInstance().writeLogs(content, FileUtils.qiandaoSuccess);
} else {
log.info("考勤失败: checkIn: {}, 方向:{}",JsonUtils.nonDefaultMapper().toJson(checkIn),eventType == 1 ? "进门" : "出门");
//考勤失败
String content = "考勤失败!,设备:" + deviceId + "卡号:" + cardNo + "---" + checkIn.getOut();
//记录学生考勤签到记录
FileUtils.getInstance().writeLogs(content, FileUtils.qiandaoErr);
}
} else {
//判断是否请假
String studentNum = myTaskUtil.userDao.checkLeave(cardNo);
if (org.apache.commons.lang.StringUtils.isNotBlank(studentNum)) {
//短信信息
Message mobileMessage = myTaskUtil.userDao.selectByParentMobile(cardNo);
if (mobileMessage.getSchoolId() == 4) {
//才发送短信
ShortMsg shortMsg = new ShortMsg();
String tableSuffix = DateUtils.date2String(new Date(), DateUtils.format);
shortMsg.setTableName("smsNew" + tableSuffix);
shortMsg.setSchoolId(mobileMessage.getSchoolId());
shortMsg.setMobile(mobileMessage.getParentMobile());
if (eventType == 2) {
//出门
shortMsg.setMsg(mobileMessage.getName() + "家长您好,你的孩子于" + DateUtils.date2String(new Date(), DateUtils.format2) + "请假后出校,请知晓;");
} else {
shortMsg.setMsg(mobileMessage.getName() + "家长您好,你的孩子于" + DateUtils.date2String(new Date(), DateUtils.format2) + "请假后进校,请知晓;");
}
myTaskUtil.messageDao.insertMessage(shortMsg.getTableName(),shortMsg.getSchoolId()+"",shortMsg.getMobile(),shortMsg.getMsg());
/**
* 远程开门
*/
openDoor(lLong);
}
} else {
//若即不成功,也不是请假,则按刷卡异常处理
List<User> users = myTaskUtil.userDao.selectUserByCardNum(cardNo);
if(users.size()<1){
log.warn("考勤记录:卡号: {},没找到对应学生或老师,考勤时间: {}",cardNo,DateUtils.date2String(new Date(), DateUtils.format2));
return;
}
User user = users.get(0);
String out = eventType == EnumSzBusinessType.EnumDeviceInAndOut.INT.code ? "进校":"出校";
//刷卡异常
String content = "考勤异常,刷脸时,人脸认证失败!,用户:"+ user.getName() + " 设备:" + deviceId + "卡号:" + cardNo + "方向:" + out + "______" + eventTime;
//刷卡异常
FileUtils.getInstance().writeLogs(content, FileUtils.qiandaoErr);
}
}
}
/**
* 消息发送
* @param deviceId
* @param cardNum
* @param eventType
*/
public static void sendMQMess(String deviceId,String cardNum,int eventType) {
//一体机设备,抓拍到人脸,将人脸发送数据看板
if(null == mqttManager){
mqttManager = new MqttManager();
mqttManager.init();
}
// inOrOut:1出门0进门
String inOrOut = eventType == 1 ? "0" : "1";
//获取设备关联的场景id
String placeId = myTaskUtil.userDao.getPlaceIdWithKaoqinDevid(deviceId);
if (null != placeId) {
//关联的显示看板设备
List<String> kanbanIds = myTaskUtil.userDao.getKanBanIdWithPlaceId(placeId);
if(kanbanIds.size()<1){
log.info("设备id: {},关联placeId: {},未查询到关联看板设备。",deviceId,placeId);
return;
}
// log.info("设备ID集: "+ JsonUtils.nonDefaultMapper().toJson(kanbanIds));
for (String kanbanId : kanbanIds) {
String data = "{\"cmd\":\"" + 34 + "\",\"clientId\":\"" + kanbanId + "\",\"data\":{\"cardNum\":\"" + cardNum + "\",\"inOrOut\":\"" + inOrOut + "\"}}";
// log.info("====== 开始推送看板======, kanbanId = {}, cardNum = {},content ={}",kanbanId,cardNum,data);
mqttManager.sendMqQD(kanbanId, data);
}
} else {
String schoolId = myTaskUtil.userDao.getSchoolIdWidthCardNum(cardNum);
if(StringUtils.isEmpty(schoolId)||Integer.parseInt(schoolId) <=0){
log.info("卡号未查询到对应学校。卡号: {}",cardNum);
return;
}
//查询学校看板设备ID
List<String> clintIds = myTaskUtil.userDao.getClintIds(schoolId);
if(clintIds.size()<1){
log.info("学校下未查询到看板信息,学校id: {}",schoolId);
return;
}
// log.info("设备ID集: "+ JsonUtils.nonDefaultMapper().toJson(clintIds));
for (int i = 0; i < clintIds.size(); i++) {
String clintId = clintIds.get(i);
String data = "{\"cmd\":\"" + 34 + "\",\"clientId\":\"" + clintId + "\",\"data\":{\"cardNum\":\"" + cardNum + "\",\"inOrOut\":\"" + inOrOut + "\"}}";
// log.info("====== 开始推送看板======, deviceId = {}, cardNum = {},content ={}",clintId,cardNum,data);
mqttManager.sendMqQD(clintId, data);
}
}
}
/**
* 远程开门
*/
private static NetSDKLib.NET_CTRL_ACCESS_OPEN open = new NetSDKLib.NET_CTRL_ACCESS_OPEN();
public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
public static boolean openDoor(NetSDKLib.LLong lLong) {
open.nChannelID = 0;
open.write();
boolean openSuccess = LoginModule.netsdk.CLIENT_ControlDeviceEx(lLong, NetSDKLib.CtrlType.CTRLTYPE_CTRL_ACCESS_OPEN, open.getPointer(), null, 5000);
open.read();
if (!openSuccess) {
log.warn("open Door error: 0x: "+ Long.toHexString(LoginModule.netsdk.CLIENT_GetLastError()));
return false;
}
return true;
}
public static void sendRecordToSXYX(String name,String userId,int intOrOut,String eventTime,String scene) {
try {
String api = "http://yixiao.198.hmkj.com.cn/index.php/Attend/send";
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("name", name);
map.add("xuehao", userId);
map.add("time", eventTime);
map.add("state", intOrOut);
map.add("loudong", scene);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> param = new HttpEntity<>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity(api, param, String.class);
String body = response.getBody();
log.info("请求艺校OA,用户名称【{}】,返回信息【{}】 ",name,body);
} catch (Exception e) {
sendRecordToSXYX(name,userId,intOrOut,eventTime,scene);
}
}
}