GA/T 1400协议支持

This commit is contained in:
Jerry Yan 2024-12-12 14:38:15 +08:00
parent 68dbd6c38b
commit 118af81ac6
25 changed files with 953 additions and 11 deletions

View File

@ -7,6 +7,7 @@ import com.ycwl.basic.model.task.req.WorkerAuthReqVo;
import com.ycwl.basic.model.task.resp.TaskSyncRespVo; import com.ycwl.basic.model.task.resp.TaskSyncRespVo;
import com.ycwl.basic.service.task.TaskService; import com.ycwl.basic.service.task.TaskService;
import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.ApiResponse;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
@IgnoreToken @IgnoreToken
@RestController @RestController
@Api(tags = "渲染端对接接口")
@RequestMapping("/task/v1/") @RequestMapping("/task/v1/")
public class TaskTaskController { public class TaskTaskController {

View File

@ -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> 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()))
);
}
}

View File

@ -33,4 +33,10 @@ public interface DeviceMapper {
DeviceConfigEntity getConfigByDeviceId(Long deviceId); DeviceConfigEntity getConfigByDeviceId(Long deviceId);
int addConfig(DeviceConfigEntity deviceConfigEntity); int addConfig(DeviceConfigEntity deviceConfigEntity);
int updateConfig(DeviceConfigEntity deviceConfigEntity); int updateConfig(DeviceConfigEntity deviceConfigEntity);
DeviceEntity getByDeviceNo(String deviceNo);
int updateEntity(DeviceEntity device);
int addEntity(DeviceEntity device);
} }

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
/** /**
@ -27,6 +28,14 @@ public class DeviceEntity {
* 设备编号 * 设备编号
*/ */
private String no; private String no;
/**
* 经度
*/
private BigDecimal longitude;
/***
* 纬度
*/
private BigDecimal latitude;
/** /**
* 是否启用0不启用1启用 * 是否启用0不启用1启用
*/ */
@ -35,6 +44,8 @@ public class DeviceEntity {
* 是否在线0不在线1在线 * 是否在线0不在线1在线
*/ */
private Integer online; private Integer online;
private String ipAddr;
private Date keepaliveAt;
private Date createAt; private Date createAt;
private Date updateAt; private Date updateAt;
} }

View File

@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
/** /**
@ -22,6 +23,10 @@ public class DeviceRespVO {
private String name; private String name;
@ApiModelProperty("设备编号") @ApiModelProperty("设备编号")
private String no; private String no;
@ApiModelProperty("经度")
private BigDecimal longitude;
@ApiModelProperty("纬度")
private BigDecimal latitude;
@ApiModelProperty("是否启用0不启用1启用") @ApiModelProperty("是否启用0不启用1启用")
private Integer status; private Integer status;
@ApiModelProperty("是否在线0不在线1在线") @ApiModelProperty("是否在线0不在线1在线")

View File

@ -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;
}

View File

@ -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> faceObject;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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> subImageInfoObject;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.AddFaceRespVo;
import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import com.ycwl.basic.service.task.TaskFaceService; import com.ycwl.basic.service.task.TaskFaceService;
import com.ycwl.basic.utils.AliFaceUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -102,8 +103,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId); FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId);
AddFaceEntityRequest request = new AddFaceEntityRequest(); AddFaceEntityRequest request = new AddFaceEntityRequest();
request.setDbName(faceSampleRespVO.getScenicId().toString()); request.setDbName(faceSampleRespVO.getScenicId().toString());
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); String entityId = AliFaceUtil.generateEntityId(faceSampleRespVO);
String entityId = faceSampleRespVO.getDeviceId().toString() + "_" + sdf.format(faceSampleRespVO.getCreateAt());
request.setEntityId(entityId); request.setEntityId(entityId);
IAcsClient client = getClient(); IAcsClient client = getClient();
try { try {
@ -150,9 +150,8 @@ public class TaskFaceServiceImpl implements TaskFaceService {
query.setStartTime(dayStart); query.setStartTime(dayStart);
query.setEndTime(dayEnd); query.setEndTime(dayEnd);
IAcsClient client = getClient(); IAcsClient client = getClient();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
faceSampleMapper.list(query).forEach(faceSampleEntity -> { faceSampleMapper.list(query).forEach(faceSampleEntity -> {
String entityId = faceSampleEntity.getDeviceId().toString() + "_" + sdf.format(faceSampleEntity.getCreateAt()); String entityId = AliFaceUtil.generateEntityId(faceSampleEntity);
DeleteFaceEntityRequest request = new DeleteFaceEntityRequest(); DeleteFaceEntityRequest request = new DeleteFaceEntityRequest();
request.setDbName(scenicId.toString()); request.setDbName(scenicId.toString());
request.setEntityId(entityId); request.setEntityId(entityId);

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -8,6 +8,10 @@
insert into device_config(id, device_id, create_time) insert into device_config(id, device_id, create_time)
values (#{id}, #{deviceId}, now()) values (#{id}, #{deviceId}, now())
</insert> </insert>
<insert id="addEntity">
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())
</insert>
<update id="update"> <update id="update">
update device set scenic_id = #{scenicId}, name = #{name}, no = #{no}, longitude = #{longitude}, latitude = #{latitude}, update_at = now() where id = #{id} update device set scenic_id = #{scenicId}, name = #{name}, no = #{no}, longitude = #{longitude}, latitude = #{latitude}, update_at = now() where id = #{id}
</update> </update>
@ -34,11 +38,21 @@
cut_post = #{cutPost} cut_post = #{cutPost}
where id = #{id} where id = #{id}
</update> </update>
<update id="updateEntity">
update device
set name = #{name},
no = #{no},
online = #{online},
ip_addr = #{ipAddr},
keepalive_at = #{keepaliveAt},
update_at = now()
where id = #{id}
</update>
<delete id="deleteById"> <delete id="deleteById">
delete from device where id = #{id} delete from device where id = #{id}
</delete> </delete>
<select id="list" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO"> <select id="list" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO">
select d.id, scenic_id, d.name, no, d.status, create_at, d.update_at, s.name scenic_name select d.id, scenic_id, d.name, no, d.longitude, d.latitude, d.status, create_at, d.update_at, s.name scenic_name
from device d from device d
left join scenic s on d.scenic_id = s.id left join scenic s on d.scenic_id = s.id
<where> <where>
@ -63,7 +77,7 @@
</where> </where>
</select> </select>
<select id="getById" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO"> <select id="getById" resultType="com.ycwl.basic.model.pc.device.resp.DeviceRespVO">
select d.id, scenic_id, d.name, no, d.status, create_at, d.update_at, s.name scenic_name select d.id, scenic_id, d.name, no, d.longitude, d.latitude, d.status, create_at, d.update_at, s.name scenic_name
from device d from device d
left join scenic s on d.scenic_id = s.id left join scenic s on d.scenic_id = s.id
where d.id = #{id} where d.id = #{id}
@ -97,4 +111,9 @@
from device from device
where id = #{deviceId} where id = #{deviceId}
</select> </select>
<select id="getByDeviceNo" resultType="com.ycwl.basic.model.pc.device.entity.DeviceEntity">
select *
from device
where no = #{deviceNo}
</select>
</mapper> </mapper>

View File

@ -2,8 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ycwl.basic.mapper.pc.FaceSampleMapper"> <mapper namespace="com.ycwl.basic.mapper.pc.FaceSampleMapper">
<insert id="add"> <insert id="add">
insert into face_sample(id, scenic_id, device_id, source_id, face_url, match_sample_ids, first_match_rate, match_result,`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}) values (#{id}, #{scenicId}, #{deviceId}, #{sourceId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult},#{status},#{createAt})
</insert> </insert>
<update id="update"> <update id="update">
update face_sample update face_sample
@ -32,6 +32,10 @@
<if test="status!= null "> <if test="status!= null ">
`status` = #{status}, `status` = #{status},
</if> </if>
<if test="score!= null ">
`score` = #{score},
</if>
update_at = now(),
</set> </set>
where id = #{id} where id = #{id}
</update> </update>
@ -81,7 +85,7 @@
</where> </where>
</select> </select>
<select id="getById" resultType="com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO"> <select id="getById" resultType="com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO">
select id, scenic_id, device_id, face_url, match_sample_ids, first_match_rate, source_id, match_result,`status` select id, scenic_id, device_id, face_url, match_sample_ids, first_match_rate, source_id, match_result,`status`, create_at
from face_sample from face_sample
where id = #{id} where id = #{id}
</select> </select>

View File

@ -2,7 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ycwl.basic.mapper.pc.SourceMapper"> <mapper namespace="com.ycwl.basic.mapper.pc.SourceMapper">
<insert id="add"> <insert id="add">
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})
</insert> </insert>
<update id="update"> <update id="update">
update source update source
@ -11,7 +12,10 @@
<if test="deviceId!= null">device_id = #{deviceId}, </if> <if test="deviceId!= null">device_id = #{deviceId}, </if>
<if test="memberId!= null">member_id = #{memberId}, </if> <if test="memberId!= null">member_id = #{memberId}, </if>
<if test="url!= null">url = #{url}, </if> <if test="url!= null">url = #{url}, </if>
<if test="videoUrl!= null">video_url = #{videoUrl}, </if>
<if test="isBuy!=null">is_buy = #{isBuy}, </if> <if test="isBuy!=null">is_buy = #{isBuy}, </if>
<if test="type!=null">`type` = #{type}, </if>
<if test="faceSampleId!= null">face_sample_id = #{faceSampleId}, </if>
</set> </set>
where id = #{id} where id = #{id}
</update> </update>
@ -20,7 +24,7 @@
</delete> </delete>
<select id="list" resultType="com.ycwl.basic.model.pc.source.resp.SourceRespVO"> <select id="list" resultType="com.ycwl.basic.model.pc.source.resp.SourceRespVO">
select so.id, scenic_id, device_id, member_id, url, so.create_time, so.update_time,sc.`name` as scenicName select so.id, scenic_id, device_id, member_id, url, so.create_time, so.update_time,sc.`name` as scenicName, so.video_url, so.`type`, so.face_sample_id
from source so from source so
left join scenic sc on sc.id = so.scenic_id left join scenic sc on sc.id = so.scenic_id
<where> <where>