package com.ycwl.basic.controller.viid; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.ycwl.basic.annotation.IgnoreLogReq; import com.ycwl.basic.annotation.IgnoreToken; import com.ycwl.basic.annotation.RequestToFile; import com.ycwl.basic.mapper.DeviceMapper; import com.ycwl.basic.mapper.FaceSampleMapper; import com.ycwl.basic.mapper.SourceMapper; import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; import com.ycwl.basic.model.pc.device.entity.DeviceEntity; import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.viid.entity.DeviceIdObject; import com.ycwl.basic.model.viid.entity.FaceListObject; import com.ycwl.basic.model.viid.entity.FaceObject; import com.ycwl.basic.model.viid.entity.FacePositionObject; import com.ycwl.basic.model.viid.entity.ResponseStatusObject; import com.ycwl.basic.model.viid.entity.SubImageInfoObject; import com.ycwl.basic.model.viid.entity.SubImageList; import com.ycwl.basic.model.viid.entity.SystemTimeObject; import com.ycwl.basic.model.viid.req.FaceUploadReq; import com.ycwl.basic.model.viid.req.KeepaliveReq; import com.ycwl.basic.model.viid.req.RegisterReq; import com.ycwl.basic.model.viid.req.UnRegisterReq; import com.ycwl.basic.model.viid.resp.SystemTimeResp; import com.ycwl.basic.model.viid.resp.VIIDBaseResp; import com.ycwl.basic.repository.DeviceRepository; import com.ycwl.basic.service.task.TaskFaceService; import com.ycwl.basic.storage.StorageFactory; import com.ycwl.basic.storage.adapters.IStorageAdapter; import com.ycwl.basic.task.DynamicTaskGenerator; import com.ycwl.basic.utils.ImageUtils; import com.ycwl.basic.utils.IpUtils; import com.ycwl.basic.utils.SnowFlakeUtil; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.TimeZone; import java.util.UUID; import java.util.stream.Collectors; @IgnoreToken @RestController @Api(tags = "摄像头对接接口") @RequestMapping("/VIID") @Slf4j public class ViidController { @Autowired private DeviceMapper deviceMapper; private static final String serverId = "00000000000000000001"; @Autowired private SourceMapper sourceMapper; @Autowired private DeviceRepository deviceRepository; // region 注册注销基础接口 /** * 注册接口 * * @param req 注册的信息 * @param request 请求 * @return 返回 */ @RequestMapping(value = "/System/Register", method = RequestMethod.POST) public VIIDBaseResp register(@RequestBody RegisterReq req, HttpServletRequest request) { DeviceIdObject deviceIdObject = req.getRegisterObject(); log.info("注册的设备信息:{}", deviceIdObject); // 保存设备注册时间 String deviceId = deviceIdObject.getDeviceId(); DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceId); if (device == null) { device = new DeviceEntity(); device.setName("未配置设备"); device.setNo(deviceId); device.setOnline(1); } device.setKeepaliveAt(new Date()); device.setIpAddr(IpUtils.getIpAddr(request)); if (device.getId() != null) { deviceMapper.updateEntity(device); } else { device.setId(SnowFlakeUtil.getLongId()); deviceMapper.addEntity(device); deviceRepository.clearDeviceCache(deviceId); } return new VIIDBaseResp( new ResponseStatusObject(serverId, "/VIID/System/Register", "0", "注册成功", sdfTime.format(new Date())) ); } /** * 保活接口 * * @param req 保活的设备信息 * @param request 请求 * @return 返回 */ @IgnoreLogReq @RequestMapping(value = "/System/Keepalive", method = RequestMethod.POST) public VIIDBaseResp keepalive(@RequestBody KeepaliveReq req, HttpServletRequest request) { DeviceIdObject keepaliveObject = req.getKeepaliveObject(); // log.info("对方发送的心跳的信息:{}", keepaliveObject); String deviceId = keepaliveObject.getDeviceId(); DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceId); // 判断设备状态 if (device == null) { // 不存在设备就注册 device = new DeviceEntity(); device.setName("未配置设备"); device.setNo(deviceId); device.setOnline(1); device.setKeepaliveAt(new Date()); device.setIpAddr(IpUtils.getIpAddr(request)); device.setId(SnowFlakeUtil.getLongId()); deviceMapper.addEntity(device); deviceRepository.clearDeviceCache(deviceId); } else { deviceRepository.updateOnlineStatus(device.getId(), IpUtils.getIpAddr(request), 1, new Date()); } // log.info("已经解析过的心跳信息:{}", keepaliveObject); return new VIIDBaseResp( new ResponseStatusObject(deviceId, "/VIID/System/Keepalive", "0", "保活", sdfTime.format(new Date())) ); } /** * 注销设备 * * @param req 参数 * @return 返回 */ @RequestMapping(value = "/System/UnRegister", method = RequestMethod.POST) public VIIDBaseResp unRegister(@RequestBody UnRegisterReq req, HttpServletRequest request) { // 获取设备id DeviceIdObject unRegisterObject = req.getUnRegisterObject(); String deviceId = unRegisterObject.getDeviceId(); log.info("获取的注销的请求参数:{}", unRegisterObject); // 首先查询该设备是否存在 DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceId); // 判断 if (device != null) { deviceRepository.updateOnlineStatus(device.getId(), IpUtils.getIpAddr(request), 0, new Date()); } return new VIIDBaseResp( new ResponseStatusObject(deviceId, "/VIID/System/UnRegister", "0", "注销成功", sdfTime.format(new Date())) ); } /** * 校时接口 * * @return 返回 */ @RequestMapping(value = "/System/Time", method = RequestMethod.GET) public SystemTimeResp time() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); return new SystemTimeResp( new SystemTimeObject(serverId, "2", sdf.format(new Date()), TimeZone.getTimeZone("Asia/Shanghai").toString()) ); } // endregion @Autowired private FaceSampleMapper faceSampleMapper; @Autowired private TaskFaceService taskFaceService; private final SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); /** * 批量新增人脸 */ @RequestMapping(value = "/Faces", method = RequestMethod.POST) @IgnoreLogReq public VIIDBaseResp faces(@RequestBody FaceUploadReq req) { FaceListObject faceListObject = req.getFaceListObject(); List faceObject = faceListObject.getFaceObject(); String faceId = null; // 遍历人脸列表 for (FaceObject face : faceObject) { // 设置FaceId faceId = face.getFaceID(); // 获取图片信息 SubImageList subImageList = face.getSubImageList(); // 判断人脸对象中的列表是否为空 String deviceID = face.getDeviceID(); DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceID); if (device == null) { continue; } DeviceConfigEntity deviceConfig = deviceRepository.getDeviceConfig(device.getId()); int viidMode = 0; if (deviceConfig != null && deviceConfig.getViidType() != null) { viidMode = deviceConfig.getViidType(); } Date shotTime = null; if (StringUtils.isNotBlank(face.getShotTime())) { try { shotTime = sdfTime.parse(face.getShotTime()); } catch (ParseException e) { log.warn("拍摄时间时间转换失败,使用当前时间。错误entity:{}", face); } } if (shotTime == null) { if (StringUtils.isNotBlank(face.getFaceAppearTime())) { try { shotTime = sdfTime.parse(face.getFaceAppearTime()); } catch (ParseException e) { log.warn("拍摄时间时间转换失败,使用当前时间。错误entity:{}", face); } } } if (shotTime == null) { shotTime = new Date(); } Long scenicId = device.getScenicId(); if (scenicId == null) { continue; } FacePositionObject facePosition = new FacePositionObject(); facePosition.setLtY(face.getLeftTopY()); facePosition.setLtX(face.getLeftTopX()); facePosition.setRbY(face.getRightBtmY()); facePosition.setRbX(face.getRightBtmX()); if (ObjectUtil.isNotEmpty(subImageList) && CollUtil.isNotEmpty(subImageList.getSubImageInfoObject())) { if (viidMode == 0) { // 遍历每个图片对象 // 先找到type14的图片 List type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).collect(Collectors.toList()); for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) { // base64转换成MultipartFIle MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData()); String ext = subImage.getFileFormat(); if (ext.equalsIgnoreCase("jpeg")) { ext = "jpg"; } IStorageAdapter adapter = StorageFactory.use("faces"); // Type=11 人脸 if (subImage.getType().equals("11")) { // 上传oss FaceSampleEntity faceSample = new FaceSampleEntity(); Long newFaceSampleId = SnowFlakeUtil.getLongId(); faceSample.setId(newFaceSampleId); faceSample.setScenicId(scenicId); faceSample.setDeviceId(device.getId()); faceSample.setStatus(0); faceSample.setCreateAt(shotTime); String url = adapter.uploadFile(file, "user-face", UUID.randomUUID() + "." + ext); faceSample.setFaceUrl(url); faceSampleMapper.add(faceSample); DynamicTaskGenerator.addTask(faceSample.getId()); taskFaceService.addFaceSample(faceSample.getId()); for (SubImageInfoObject _subImage : type14ImageList) { facePosition.setImgHeight(_subImage.getHeight()); facePosition.setImgWidth(_subImage.getWidth()); SourceEntity source = new SourceEntity(); source.setId(SnowFlakeUtil.getLongId()); source.setDeviceId(device.getId()); source.setScenicId(device.getScenicId()); source.setFaceSampleId(newFaceSampleId); source.setCreateTime(shotTime); source.setType(2); // 上传oss MultipartFile _file = ImageUtils.base64ToMultipartFile(_subImage.getData()); String _sourceUrl = adapter.uploadFile(_file, "user-photo", UUID.randomUUID() + "." + ext); source.setUrl(_sourceUrl); source.setPosJson(JSON.toJSONString(facePosition)); sourceMapper.add(source); } log.info("人脸信息及原图{}张入库成功!设备ID:{}", type14ImageList.size(), deviceID); } } } else if (viidMode == 1) { for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) { // base64转换成MultipartFIle MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData()); String ext = subImage.getFileFormat(); if (ext.equalsIgnoreCase("jpeg")) { ext = "jpg"; } IStorageAdapter adapter = StorageFactory.use("faces"); // Type=14 人脸,传™的,有这么传的嘛 if (subImage.getType().equals("14")) { // 上传oss FaceSampleEntity faceSample = new FaceSampleEntity(); Long newFaceSampleId = SnowFlakeUtil.getLongId(); faceSample.setId(newFaceSampleId); faceSample.setScenicId(scenicId); faceSample.setDeviceId(device.getId()); faceSample.setStatus(0); faceSample.setCreateAt(shotTime); String url = adapter.uploadFile(file, "user-face", UUID.randomUUID() + "." + ext); faceSample.setFaceUrl(url); faceSampleMapper.add(faceSample); DynamicTaskGenerator.addTask(faceSample.getId()); taskFaceService.addFaceSample(faceSample.getId()); log.info("模式1人脸信息入库成功!设备ID:{}", deviceID); } } } } } return new VIIDBaseResp( new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date())) ); } }