From 118af81ac6438d4093bed824634639f217c967b4 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 12 Dec 2024 14:38:15 +0800 Subject: [PATCH] =?UTF-8?q?GA/T=201400=E5=8D=8F=E8=AE=AE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/task/TaskTaskController.java | 2 + .../basic/controller/viid/ViidController.java | 269 ++++++++++++++++++ .../ycwl/basic/mapper/pc/DeviceMapper.java | 6 + .../model/pc/device/entity/DeviceEntity.java | 11 + .../model/pc/device/resp/DeviceRespVO.java | 5 + .../model/viid/entity/DeviceIdObject.java | 14 + .../model/viid/entity/FaceListObject.java | 12 + .../basic/model/viid/entity/FaceObject.java | 169 +++++++++++ .../viid/entity/ResponseStatusObject.java | 21 ++ .../model/viid/entity/SubImageInfoObject.java | 28 ++ .../basic/model/viid/entity/SubImageList.java | 13 + .../model/viid/entity/SystemTimeObject.java | 18 ++ .../basic/model/viid/req/FaceUploadReq.java | 11 + .../basic/model/viid/req/KeepaliveReq.java | 11 + .../basic/model/viid/req/RegisterReq.java | 11 + .../basic/model/viid/req/UnRegisterReq.java | 12 + .../basic/model/viid/resp/SystemTimeResp.java | 13 + .../basic/model/viid/resp/VIIDBaseResp.java | 15 + .../impl/task/TaskFaceServiceImpl.java | 7 +- .../com/ycwl/basic/utils/AliFaceUtil.java | 21 ++ .../java/com/ycwl/basic/utils/ImageUtils.java | 79 +++++ .../java/com/ycwl/basic/utils/IpUtils.java | 175 ++++++++++++ src/main/resources/mapper/pc/DeviceMapper.xml | 23 +- .../resources/mapper/pc/FaceSampleMapper.xml | 10 +- src/main/resources/mapper/pc/SourceMapper.xml | 8 +- 25 files changed, 953 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/controller/viid/ViidController.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java create mode 100644 src/main/java/com/ycwl/basic/utils/AliFaceUtil.java create mode 100644 src/main/java/com/ycwl/basic/utils/ImageUtils.java create mode 100644 src/main/java/com/ycwl/basic/utils/IpUtils.java diff --git a/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java b/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java index 3585405..335c5b9 100644 --- a/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java +++ b/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java @@ -7,6 +7,7 @@ import com.ycwl.basic.model.task.req.WorkerAuthReqVo; import com.ycwl.basic.model.task.resp.TaskSyncRespVo; import com.ycwl.basic.service.task.TaskService; import com.ycwl.basic.utils.ApiResponse; +import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; @IgnoreToken @RestController +@Api(tags = "渲染端对接接口") @RequestMapping("/task/v1/") public class TaskTaskController { diff --git a/src/main/java/com/ycwl/basic/controller/viid/ViidController.java b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java new file mode 100644 index 0000000..80550bd --- /dev/null +++ b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java @@ -0,0 +1,269 @@ +package com.ycwl.basic.controller.viid; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.ycwl.basic.annotation.IgnoreToken; +import com.ycwl.basic.mapper.pc.DeviceMapper; +import com.ycwl.basic.mapper.pc.FaceSampleMapper; +import com.ycwl.basic.mapper.pc.SourceMapper; +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.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.service.task.TaskFaceService; +import com.ycwl.basic.utils.AliFaceUtil; +import com.ycwl.basic.utils.ImageUtils; +import com.ycwl.basic.utils.IpUtils; +import com.ycwl.basic.utils.OssUtil; +import com.ycwl.basic.utils.SnowFlakeUtil; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +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.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +@IgnoreToken +@RestController +@Api(tags = "摄像头对接接口") +@RequestMapping("/VIID") +@Slf4j +public class ViidController { + @Autowired + private DeviceMapper deviceMapper; + private static final String serverId = "00000000000000000001"; + @Autowired + private SourceMapper sourceMapper; + + // 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); + // 保存设备注册时间 + DeviceEntity device = deviceMapper.getByDeviceNo(deviceIdObject.getDeviceId()); + if (device == null) { + device = new DeviceEntity(); + device.setName("未配置设备"); + device.setNo(deviceIdObject.getDeviceId()); + 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); + } + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(serverId, "/VIID/System/Register", "0", "注册成功", sdfTime.format(new Date())) + ); + } + + /** + * 保活接口 + * + * @param req 保活的设备信息 + * @param request 请求 + * @return 返回 + */ + @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 = deviceMapper.getByDeviceNo(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); + } else { + device.setOnline(1); + device.setKeepaliveAt(new Date()); + deviceMapper.updateEntity(device); + } + log.info("已经解析过的心跳信息:{}", keepaliveObject); + + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(deviceId, "/VIID/System/UnRegister", "0", "注销成功", sdfTime.format(new Date())) + ); + } + + /** + * 注销设备 + * + * @param req 参数 + * @return 返回 + */ + @RequestMapping(value = "/System/UnRegister", method = RequestMethod.POST) + public VIIDBaseResp unRegister(@RequestBody UnRegisterReq req) { + // 获取设备id + DeviceIdObject unRegisterObject = req.getUnRegisterObject(); + String deviceId = unRegisterObject.getDeviceId(); + log.info("获取的注销的请求参数:{}", unRegisterObject); + + // 首先查询该设备是否存在 + DeviceEntity device = deviceMapper.getByDeviceNo(deviceId); + // 判断 + if (device != null) { + device.setOnline(0); + device.setKeepaliveAt(new Date()); + int update = deviceMapper.updateEntity(device); + } + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + 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; + @Autowired + private OssUtil ossUtil; + + + /** + * 批量新增人脸 + */ + @RequestMapping(value = "/Faces", method = RequestMethod.POST) + public VIIDBaseResp faces(@RequestBody FaceUploadReq req) { + log.info("收到的人脸上报信息:{}",req); + FaceListObject faceListObject = req.getFaceListObject(); + List faceObject = faceListObject.getFaceObject(); + String faceId = null; + // 遍历人脸列表 + for (FaceObject face : faceObject) { + // 设置FaceId + faceId = face.getFaceID(); + Long newFaceSampleId = SnowFlakeUtil.getLongId(); + // 获取图片信息 + SubImageList subImageList = face.getSubImageList(); + // 判断人脸对象中的列表是否为空 + String deviceID = face.getDeviceID(); + DeviceEntity device = deviceMapper.getByDeviceNo(deviceID); + if (device == null) { + continue; + } + Long scenicId = device.getScenicId(); + if (scenicId == null) { + continue; + } + if (ObjectUtil.isNotEmpty(subImageList) && CollUtil.isNotEmpty(subImageList.getSubImageInfoObject())) { + // 遍历每个图片对象 + for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) { + // base64转换成MultipartFIle + MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData()); + String ext = subImage.getFileFormat(); + if (ext.equalsIgnoreCase("jpeg")) { + ext = "jpg"; + } + // Type=11 人脸 + if (subImage.getType().equals("11")) { + // 上传oss + FaceSampleEntity faceSample = new FaceSampleEntity(); + faceSample.setId(newFaceSampleId); + faceSample.setScenicId(scenicId); + faceSample.setDeviceId(device.getId()); + faceSample.setStatus(0); + faceSample.setCreateAt(new Date()); + String url; + try { + url = ossUtil.uploadFile(file.getInputStream(), AliFaceUtil.generateEntityId(faceSample) + "." + ext); + } catch (IOException e) { + log.error("文件上传失败!", e); + continue; + } + faceSample.setFaceUrl(url); + faceSampleMapper.add(faceSample); + log.info("人脸信息入库成功!"); + taskFaceService.addFaceSample(faceSample.getId()); + } + // Type=14 场景图 + else if (subImage.getType().equals("14")) { + SourceEntity source = new SourceEntity(); + source.setId(SnowFlakeUtil.getLongId()); + source.setDeviceId(device.getId()); + source.setScenicId(device.getScenicId()); + source.setFaceSampleId(newFaceSampleId); + source.setType(2); + // 上传oss + String url; + try { + url = ossUtil.uploadFile(file.getInputStream(), "user-photo/", newFaceSampleId + "." + ext); + } catch (IOException e) { + log.error("文件上传失败!", e); + continue; + } + source.setUrl(url); + sourceMapper.add(source); + } + } + } + log.info("设备ID:{}", deviceID); + } + + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date())) + ); + } + +} diff --git a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java index b21bfcd..f73994d 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java @@ -33,4 +33,10 @@ public interface DeviceMapper { DeviceConfigEntity getConfigByDeviceId(Long deviceId); int addConfig(DeviceConfigEntity deviceConfigEntity); int updateConfig(DeviceConfigEntity deviceConfigEntity); + + DeviceEntity getByDeviceNo(String deviceNo); + + int updateEntity(DeviceEntity device); + + int addEntity(DeviceEntity device); } diff --git a/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java index 873a1b6..054f256 100644 --- a/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; /** @@ -27,6 +28,14 @@ public class DeviceEntity { * 设备编号 */ private String no; + /** + * 经度 + */ + private BigDecimal longitude; + /*** + * 纬度 + */ + private BigDecimal latitude; /** * 是否启用,0不启用,1启用 */ @@ -35,6 +44,8 @@ public class DeviceEntity { * 是否在线,0不在线,1在线 */ private Integer online; + private String ipAddr; + private Date keepaliveAt; private Date createAt; private Date updateAt; } diff --git a/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java b/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java index bca82c8..b39c363 100644 --- a/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java @@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; /** @@ -22,6 +23,10 @@ public class DeviceRespVO { private String name; @ApiModelProperty("设备编号") private String no; + @ApiModelProperty("经度") + private BigDecimal longitude; + @ApiModelProperty("纬度") + private BigDecimal latitude; @ApiModelProperty("是否启用,0不启用,1启用") private Integer status; @ApiModelProperty("是否在线,0不在线,1在线") diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java new file mode 100644 index 0000000..bf0bde1 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java @@ -0,0 +1,14 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class DeviceIdObject implements Serializable { + + @JsonProperty("DeviceID") + private String deviceId; + +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java new file mode 100644 index 0000000..cab924a --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java @@ -0,0 +1,12 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class FaceListObject { + @JsonProperty("FaceObject") + private List faceObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java new file mode 100644 index 0000000..88b35ed --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java @@ -0,0 +1,169 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class FaceObject { + @JsonProperty("FaceID") + private String FaceID; + @JsonProperty("InfoKind") + private Integer InfoKind; + @JsonProperty("SourceID") + private String SourceID; + @JsonProperty("DeviceID") + private String DeviceID; + @JsonProperty("LeftTopX") + private Integer LeftTopX; + @JsonProperty("LeftTopY") + private Integer LeftTopY; + @JsonProperty("RightBtmX") + private Integer RightBtmX; + @JsonProperty("RightBtmY") + private Integer RightBtmY; + @JsonProperty("IDNumber") + private String IDNumber; + @JsonProperty("Name") + private String Name; + @JsonProperty("UsedName") + private String UsedName; + @JsonProperty("Alias") + private String Alias; + @JsonProperty("AgeUpLimit") + private Integer AgeUpLimit; + @JsonProperty("AgeLowerLimit") + private Integer AgeLowerLimit; + @JsonProperty("EthicCode") + private String EthicCode; + @JsonProperty("NationalityCode") + private String NationalityCode; + @JsonProperty("NativeCityCode") + private String NativeCityCode; + @JsonProperty("ResidenceAdminDivision") + private String ResidenceAdminDivision; + @JsonProperty("ChineseAccentCode") + private String ChineseAccentCode; + @JsonProperty("JobCategory") + private String JobCategory; + @JsonProperty("AccompanyNumber") + private Integer AccompanyNumber; + @JsonProperty("SkinColor") + private String SkinColor; + @JsonProperty("FaceStyle") + private String FaceStyle; + @JsonProperty("FacialFeature") + private String FacialFeature; + @JsonProperty("PhysicalFeature") + private String PhysicalFeature; + @JsonProperty("IsDriver") + private Integer IsDriver; + @JsonProperty("IsForeigner") + private Integer IsForeigner; + @JsonProperty("ImmigrantTypeCode") + private String ImmigrantTypeCode; + @JsonProperty("IsSuspectedTerrorist") + private Integer IsSuspectedTerrorist; + @JsonProperty("SuspectedTerroristNumber") + private String SuspectedTerroristNumber; + @JsonProperty("IsCriminalInvolved") + private Integer IsCriminalInvolved; + @JsonProperty("CriminalInvolvedSpecilisationCode") + private String CriminalInvolvedSpecilisationCode; + @JsonProperty("BodySpeciallMark") + private String BodySpeciallMark; + @JsonProperty("CrimeMethod") + private String CrimeMethod; + @JsonProperty("CrimeCharacterCode") + private String CrimeCharacterCode; + @JsonProperty("EscapedCriminalNumber") + private String EscapedCriminalNumber; + @JsonProperty("IsDetainees") + private Integer IsDetainees; + @JsonProperty("DetentionHouseCode") + private String DetentionHouseCode; + @JsonProperty("DetaineesSpecialIdentity") + private String DetaineesSpecialIdentity; + @JsonProperty("MemberTypeCode") + private String MemberTypeCode; + @JsonProperty("IsVictim") + private String IsVictim; + @JsonProperty("VictimType") + private String VictimType; + @JsonProperty("CorpseConditionCode") + private String CorpseConditionCode; + @JsonProperty("IsSuspiciousPerson") + private String IsSuspiciousPerson; + @JsonProperty("Attitude") + private String Attitude; + @JsonProperty("Similaritydegree") + private String Similaritydegree; + @JsonProperty("EyebrowStyle") + private String EyebrowStyle; + @JsonProperty("NoseStyle") + private String NoseStyle; + @JsonProperty("MustacheStyle") + private String MustacheStyle; + @JsonProperty("LipStyle") + private String LipStyle; + @JsonProperty("WrinklePouch") + private String WrinklePouch; + @JsonProperty("AcneStain") + private String AcneStain; + @JsonProperty("FreckleBirthmark") + private String FreckleBirthmark; + @JsonProperty("ScarDimple") + private String ScarDimple; + @JsonProperty("TabID") + private String TabID; + @JsonProperty("OtherFeature") + private String OtherFeature; + @JsonProperty("Maritalstatus") + private String Maritalstatus; + @JsonProperty("FamilyAddress") + private String FamilyAddress; + @JsonProperty("CollectorOrg") + private String CollectorOrg; + @JsonProperty("CollectorID") + private String CollectorID; + @JsonProperty("DeviceSNNo") + private String DeviceSNNo; + @JsonProperty("APSId") + private String APSId; + @JsonProperty("LocationMarkTime") + private String LocationMarkTime; + @JsonProperty("FaceAppearTime") + private String FaceAppearTime; + @JsonProperty("FaceDisAppearTime") + private String FaceDisAppearTime; + @JsonProperty("ShotTime") + private String ShotTime; + @JsonProperty("IDType") + private String IDType; + @JsonProperty("GenderCode") + private String GenderCode; + @JsonProperty("HairStyle") + private String HairStyle; + @JsonProperty("HairColor") + private String HairColor; + @JsonProperty("RespiratorColor") + private String RespiratorColor; + @JsonProperty("CapStyle") + private String CapStyle; + @JsonProperty("CapColor") + private String CapColor; + @JsonProperty("GlassStyle") + private String GlassStyle; + @JsonProperty("GlassColor") + private String GlassColor; + @JsonProperty("PassportType") + private String PassportType; + @JsonProperty("DetaineesIdentity") + private String DetaineesIdentity; + @JsonProperty("InjuredDegree") + private String InjuredDegree; + @JsonProperty("EntryTime") + private String EntryTime; + @JsonProperty("SubImageList") + private SubImageList subImageList; + +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java new file mode 100644 index 0000000..695ad50 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java @@ -0,0 +1,21 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class ResponseStatusObject { + + @JsonProperty("Id") + private String id; + @JsonProperty("RequestURL") + private String requestUrl; + @JsonProperty("StatusCode") + private String statusCode; + @JsonProperty("StatusString") + private String statusString; + @JsonProperty("LocalTime") + private String localTime; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java new file mode 100644 index 0000000..71284d7 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java @@ -0,0 +1,28 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class SubImageInfoObject { + @JsonProperty("ImageID") + private String ImageID; + @JsonProperty("EventSort") + private Integer EventSort; + @JsonProperty("DeviceID") + private String DeviceID; + @JsonProperty("StoragePath") + private String StoragePath; + @JsonProperty("Type") + private String Type; + @JsonProperty("FileFormat") + private String FileFormat; + @JsonProperty("Width") + private String Width; + @JsonProperty("Height") + private String Height; + @JsonProperty("ShotTime") + private String ShotTime; + @JsonProperty("Data") + private String Data; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java new file mode 100644 index 0000000..2723a04 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class SubImageList { + + @JsonProperty("SubImageInfoObject") + private List subImageInfoObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java new file mode 100644 index 0000000..5630729 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java @@ -0,0 +1,18 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SystemTimeObject { + @JsonProperty("VIIDServerID") + private String viidServerId; + @JsonProperty("TimeMode") + private String timeMode; + @JsonProperty("LocalTime") + private String localTime; + @JsonProperty("TimeZone") + private String timezone; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java b/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java new file mode 100644 index 0000000..d801527 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.FaceListObject; +import lombok.Data; + +@Data +public class FaceUploadReq { + @JsonProperty("FaceListObject") + private FaceListObject faceListObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java b/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java new file mode 100644 index 0000000..efb3204 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class KeepaliveReq { + @JsonProperty("KeepaliveObject") + private DeviceIdObject keepaliveObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java b/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java new file mode 100644 index 0000000..98e6ca1 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class RegisterReq { + @JsonProperty("RegisterObject") + private DeviceIdObject registerObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java b/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java new file mode 100644 index 0000000..89051e5 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java @@ -0,0 +1,12 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class UnRegisterReq { + + @JsonProperty("UnRegisterObject") + private DeviceIdObject unRegisterObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java b/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java new file mode 100644 index 0000000..f07801e --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.model.viid.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.SystemTimeObject; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SystemTimeResp { + @JsonProperty("SystemTimeObject") + private SystemTimeObject systemTimeObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java b/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java new file mode 100644 index 0000000..6fe80ae --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java @@ -0,0 +1,15 @@ +package com.ycwl.basic.model.viid.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.ResponseStatusObject; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class VIIDBaseResp { + + @JsonProperty("ResponseStatusObject") + private ResponseStatusObject responseStatusObject; + +} diff --git a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java index b38418b..371bc5f 100644 --- a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java @@ -25,6 +25,7 @@ import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import com.ycwl.basic.model.task.resp.AddFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.service.task.TaskFaceService; +import com.ycwl.basic.utils.AliFaceUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -102,8 +103,7 @@ public class TaskFaceServiceImpl implements TaskFaceService { FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId); AddFaceEntityRequest request = new AddFaceEntityRequest(); request.setDbName(faceSampleRespVO.getScenicId().toString()); - SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); - String entityId = faceSampleRespVO.getDeviceId().toString() + "_" + sdf.format(faceSampleRespVO.getCreateAt()); + String entityId = AliFaceUtil.generateEntityId(faceSampleRespVO); request.setEntityId(entityId); IAcsClient client = getClient(); try { @@ -150,9 +150,8 @@ public class TaskFaceServiceImpl implements TaskFaceService { query.setStartTime(dayStart); query.setEndTime(dayEnd); IAcsClient client = getClient(); - SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); faceSampleMapper.list(query).forEach(faceSampleEntity -> { - String entityId = faceSampleEntity.getDeviceId().toString() + "_" + sdf.format(faceSampleEntity.getCreateAt()); + String entityId = AliFaceUtil.generateEntityId(faceSampleEntity); DeleteFaceEntityRequest request = new DeleteFaceEntityRequest(); request.setDbName(scenicId.toString()); request.setEntityId(entityId); diff --git a/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java b/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java new file mode 100644 index 0000000..658307f --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java @@ -0,0 +1,21 @@ +package com.ycwl.basic.utils; + +import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; +import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; + +import java.text.SimpleDateFormat; + +public class AliFaceUtil { + private static final String DATE_FORMAT="yyyyMMddHHmmssSSS"; + + public static String generateEntityId(FaceSampleEntity entity) { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); + String entityId = entity.getDeviceId().toString() + "_" + sdf.format(entity.getCreateAt()); + return entityId; + } + public static String generateEntityId(FaceSampleRespVO entity) { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); + String entityId = entity.getDeviceId().toString() + "_" + sdf.format(entity.getCreateAt()); + return entityId; + } +} diff --git a/src/main/java/com/ycwl/basic/utils/ImageUtils.java b/src/main/java/com/ycwl/basic/utils/ImageUtils.java new file mode 100644 index 0000000..1bca534 --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/ImageUtils.java @@ -0,0 +1,79 @@ +package com.ycwl.basic.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; + +public class ImageUtils { + public static MultipartFile base64ToMultipartFile(String base64) { + String[] baseStrs = base64.split(","); + byte[] b; + b = Base64.getDecoder().decode(baseStrs[0]); + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) { + b[i] += 256; + } + } + return new Base64DecodedMultipartFile(b, baseStrs[0]); + } + public static class Base64DecodedMultipartFile implements MultipartFile { + + private final byte[] imgContent; + private final String header; + + public Base64DecodedMultipartFile(byte[] imgContent, String header) { + this.imgContent = imgContent; + this.header = header.split(";")[0]; + } + + @Override + public String getName() { + // TODO - implementation depends on your requirements + return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1]; + } + + @Override + public String getOriginalFilename() { + // TODO - implementation depends on your requirements + return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1]; + } + + @Override + public String getContentType() { + // TODO - implementation depends on your requirements + return header.split(":")[0]; + } + + @Override + public boolean isEmpty() { + return imgContent == null || imgContent.length == 0; + } + + @Override + public long getSize() { + return imgContent.length; + } + + @Override + public byte[] getBytes() { + return imgContent; + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(imgContent); + } + + @Override + public void transferTo(File dest) throws IOException, IllegalStateException { + new FileOutputStream(dest).write(imgContent); + } + + } + +} diff --git a/src/main/java/com/ycwl/basic/utils/IpUtils.java b/src/main/java/com/ycwl/basic/utils/IpUtils.java new file mode 100644 index 0000000..b4dc6a7 --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/IpUtils.java @@ -0,0 +1,175 @@ +package com.ycwl.basic.utils; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 获取IP方法 + * + * @author tsingeye + */ +public class IpUtils { + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + if (request == null) { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) { + if (text.length() == 0) { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\." , -1); + try { + long l; + int i; + switch (elements.length) { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } catch (NumberFormatException e) { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) { + if (false == isUnknown(subIp)) { + ip = subIp; + break; + } + } + } + return ip; + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } +} \ No newline at end of file diff --git a/src/main/resources/mapper/pc/DeviceMapper.xml b/src/main/resources/mapper/pc/DeviceMapper.xml index 15e7374..5685564 100644 --- a/src/main/resources/mapper/pc/DeviceMapper.xml +++ b/src/main/resources/mapper/pc/DeviceMapper.xml @@ -8,6 +8,10 @@ insert into device_config(id, device_id, create_time) values (#{id}, #{deviceId}, now()) + + insert into device(id, name, no, status, online, ip_addr, keepalive_at, create_at, update_at) + values (#{id}, #{name}, #{no}, 0, #{online}, #{ipAddr}, #{keepaliveAt}, now(), now()) + update device set scenic_id = #{scenicId}, name = #{name}, no = #{no}, longitude = #{longitude}, latitude = #{latitude}, update_at = now() where id = #{id} @@ -34,11 +38,21 @@ cut_post = #{cutPost} where id = #{id} + + update device + set name = #{name}, + no = #{no}, + online = #{online}, + ip_addr = #{ipAddr}, + keepalive_at = #{keepaliveAt}, + update_at = now() + where id = #{id} + delete from device where id = #{id} + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/FaceSampleMapper.xml b/src/main/resources/mapper/pc/FaceSampleMapper.xml index 0cba491..a70ba85 100644 --- a/src/main/resources/mapper/pc/FaceSampleMapper.xml +++ b/src/main/resources/mapper/pc/FaceSampleMapper.xml @@ -2,8 +2,8 @@ - insert into face_sample(id, scenic_id, device_id, source_id, face_url, match_sample_ids, first_match_rate, match_result,`status`) - values (#{id}, #{scenicId}, #{deviceId}, #{sourceId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult},#{status}) + insert into face_sample(id, scenic_id, device_id, source_id, face_url, match_sample_ids, first_match_rate, match_result,`status`, create_at) + values (#{id}, #{scenicId}, #{deviceId}, #{sourceId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult},#{status},#{createAt}) update face_sample @@ -32,6 +32,10 @@ `status` = #{status}, + + `score` = #{score}, + + update_at = now(), where id = #{id} @@ -81,7 +85,7 @@ diff --git a/src/main/resources/mapper/pc/SourceMapper.xml b/src/main/resources/mapper/pc/SourceMapper.xml index 7f3e714..b454508 100644 --- a/src/main/resources/mapper/pc/SourceMapper.xml +++ b/src/main/resources/mapper/pc/SourceMapper.xml @@ -2,7 +2,8 @@ - insert into source(id, scenic_id, device_id, member_id, url) values (#{id}, #{scenicId}, #{deviceId}, #{memberId}, #{url}) + insert into source(id, scenic_id, device_id, member_id, url, video_url, `type`, face_sample_id) + values (#{id}, #{scenicId}, #{deviceId}, #{memberId}, #{url}, #{videoUrl}, #{type}, #{faceSampleId}) update source @@ -11,7 +12,10 @@ device_id = #{deviceId}, member_id = #{memberId}, url = #{url}, + video_url = #{videoUrl}, is_buy = #{isBuy}, + `type` = #{type}, + face_sample_id = #{faceSampleId}, where id = #{id} @@ -20,7 +24,7 @@