You've already forked FrameTour-BE
refactor(storage): 移除不再使用的人脸存储路径常量
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good
- 删除 StorageConstant 中的 VIID_FACE 常量定义 - 移除 FaceCleaner 中对 VIID_FACE 的引用和相关文件清理逻辑 - 清理相关的导入语句和静态引用
This commit is contained in:
@@ -5,6 +5,5 @@ public class StorageConstant {
|
||||
public static final String VIDEO_PIECE_PATH = "source_video";
|
||||
public static final String PHOTO_PATH = "source_photo";
|
||||
public static final String PHOTO_WATERMARKED_PATH = "photo_w";
|
||||
public static final String VIID_FACE = "viid_face";
|
||||
public static final String USER_FACE = "user_face";
|
||||
public static final String USER_FACE = "user_face";
|
||||
}
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
package com.ycwl.basic.controller.viid;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.thread.ThreadFactoryBuilder;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import com.ycwl.basic.annotation.IgnoreLogReq;
|
||||
import com.ycwl.basic.annotation.IgnoreToken;
|
||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||
import com.ycwl.basic.facebody.entity.AddFaceResp;
|
||||
import com.ycwl.basic.integration.device.service.DeviceIntegrationService;
|
||||
import com.ycwl.basic.integration.device.dto.device.CreateDeviceRequest;
|
||||
import com.ycwl.basic.integration.device.dto.device.UpdateDeviceRequest;
|
||||
import com.ycwl.basic.integration.device.dto.device.DeviceV2DTO;
|
||||
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.DeviceCropConfig;
|
||||
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.ImageUploadReq;
|
||||
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.pc.ScenicService;
|
||||
import com.ycwl.basic.service.task.TaskFaceService;
|
||||
import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||
import com.ycwl.basic.storage.utils.StorageUtil;
|
||||
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 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 jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.awt.image.RasterFormatException;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.ycwl.basic.constant.StorageConstant.PHOTO_PATH;
|
||||
import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
|
||||
|
||||
@IgnoreToken
|
||||
@RestController
|
||||
// 摄像头对接接口
|
||||
@RequestMapping("/VIID")
|
||||
@Slf4j
|
||||
public class ViidController {
|
||||
@Autowired
|
||||
private DeviceIntegrationService deviceIntegrationService;
|
||||
private static final String serverId = "00000000000000000001";
|
||||
@Autowired
|
||||
private SourceMapper sourceMapper;
|
||||
@Autowired
|
||||
private DeviceRepository deviceRepository;
|
||||
@Autowired
|
||||
private TaskFaceService taskFaceService;
|
||||
private final Map<Long, ThreadPoolExecutor> executors = new ConcurrentHashMap<>();
|
||||
@Autowired
|
||||
private ScenicService scenicService;
|
||||
|
||||
private ThreadPoolExecutor getExecutor(Long scenicId) {
|
||||
return executors.computeIfAbsent(scenicId, k -> {
|
||||
ThreadFactory threadFactory = new ThreadFactoryBuilder()
|
||||
.setNamePrefix("VIID-" + scenicId + "-t")
|
||||
.build();
|
||||
return new ThreadPoolExecutor(
|
||||
8, 32, 10L, TimeUnit.SECONDS, // 核心2个线程,最大20个线程,空闲60秒回收
|
||||
new ArrayBlockingQueue<>(1024), // 队列大小从1024降至100
|
||||
threadFactory,
|
||||
new ThreadPoolExecutor.CallerRunsPolicy() // 队列满时由调用线程执行,提供背压控制
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// 通过zt-device服务创建新设备
|
||||
CreateDeviceRequest createRequest = new CreateDeviceRequest();
|
||||
createRequest.setName(device.getName());
|
||||
createRequest.setNo(device.getNo());
|
||||
createRequest.setType("IPC"); // 默认类型为IPC
|
||||
createRequest.setIsActive(0);
|
||||
createRequest.setScenicId(0L);
|
||||
createRequest.setSort(0);
|
||||
try {
|
||||
DeviceV2DTO createdDevice = deviceIntegrationService.createDevice(createRequest);
|
||||
device.setId(createdDevice.getId());
|
||||
} catch (Exception e) {
|
||||
log.warn("创建设备失败,设备编号: {}, 错误: {}", deviceId, e.getMessage());
|
||||
}
|
||||
}
|
||||
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));
|
||||
// 通过zt-device服务创建新设备
|
||||
CreateDeviceRequest createRequest = new CreateDeviceRequest();
|
||||
createRequest.setName(device.getName());
|
||||
createRequest.setNo(device.getNo());
|
||||
createRequest.setType("IPC"); // 默认类型为IPC
|
||||
createRequest.setIsActive(0);
|
||||
createRequest.setScenicId(0L);
|
||||
createRequest.setSort(0);
|
||||
try {
|
||||
DeviceV2DTO createdDevice = deviceIntegrationService.createDevice(createRequest);
|
||||
device.setId(createdDevice.getId());
|
||||
} catch (Exception e) {
|
||||
log.warn("创建设备失败,设备编号: {}, 错误: {}", deviceId, e.getMessage());
|
||||
}
|
||||
} 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;
|
||||
|
||||
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> 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;
|
||||
}
|
||||
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(device.getId());
|
||||
DeviceConfigEntity deviceConfigEntity = deviceRepository.getDeviceConfig(device.getId());
|
||||
if (deviceConfig == null) {
|
||||
log.warn("设备配置不存在:" + deviceID);
|
||||
return new VIIDBaseResp(
|
||||
new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date()))
|
||||
);
|
||||
}
|
||||
Integer viidMode = deviceConfig.getInteger("viid_mode", 0);
|
||||
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();
|
||||
} else if (!DateUtil.isSameDay(shotTime, new Date())) {
|
||||
log.warn("时间不是今天,使用当前时间。错误entity:{}", face);
|
||||
shotTime = new Date();
|
||||
}
|
||||
if (Math.abs(shotTime.getTime() - System.currentTimeMillis()) > 3600 * 1000) {
|
||||
String jsonString = JacksonUtil.toJSONStringCompat(req);
|
||||
log.warn("时间差超过1小时。device:{},错误entity:{}", device, jsonString);
|
||||
}
|
||||
Long scenicId = device.getScenicId();
|
||||
if (scenicId == null) {
|
||||
continue;
|
||||
}
|
||||
IStorageAdapter scenicStorageAdapter = scenicService.getScenicStorageAdapter(scenicId);
|
||||
IFaceBodyAdapter faceBodyAdapter = scenicService.getScenicFaceBodyAdapter(scenicId);
|
||||
if (faceBodyAdapter == null) {
|
||||
log.warn("人脸上传适配器不存在:" + scenicId);
|
||||
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<SubImageInfoObject> type14ImageList = subImageList.getSubImageInfoObject().stream().filter(subImage -> "14".equals(subImage.getType())).toList();
|
||||
for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) {
|
||||
// base64转换成MultipartFIle
|
||||
MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData());
|
||||
String ext;
|
||||
if (subImage.getFileFormat().equalsIgnoreCase("jpeg")) {
|
||||
ext = "jpg";
|
||||
} else {
|
||||
ext = subImage.getFileFormat();
|
||||
}
|
||||
IStorageAdapter adapter = StorageFactory.use("faces");
|
||||
// Type=11 人脸
|
||||
if (subImage.getType().equals("11")) {
|
||||
// 上传oss
|
||||
Long newFaceSampleId = SnowFlakeUtil.getLongId();
|
||||
if (Integer.valueOf(1).equals(device.getStatus())) {
|
||||
FaceSampleEntity faceSample = new FaceSampleEntity();
|
||||
faceSample.setId(newFaceSampleId);
|
||||
faceSample.setScenicId(scenicId);
|
||||
faceSample.setDeviceId(device.getId());
|
||||
faceSample.setStatus(0);
|
||||
faceSample.setCreateAt(shotTime);
|
||||
String url = adapter.uploadFile(file, VIID_FACE, UUID.randomUUID() + "." + ext);
|
||||
faceSample.setFaceUrl(url);
|
||||
faceSampleMapper.add(faceSample);
|
||||
ThreadPoolExecutor executor = getExecutor(scenicId);
|
||||
executor.execute(() -> {
|
||||
taskFaceService.assureFaceDb(faceBodyAdapter, scenicId.toString());
|
||||
AddFaceResp addFaceResp;
|
||||
try {
|
||||
addFaceResp = faceBodyAdapter.addFace(scenicId.toString(), faceSample.getId().toString(), url, newFaceSampleId.toString());
|
||||
} catch (Exception e) {
|
||||
log.error("人脸添加失败:{}", e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (addFaceResp != null) {
|
||||
faceSample.setScore(addFaceResp.getScore());
|
||||
faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore());
|
||||
|
||||
}
|
||||
if (Integer.valueOf(1).equals(deviceConfig.getInteger("enable_pre_book"))) {
|
||||
DynamicTaskGenerator.addTask(faceSample.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (SubImageInfoObject _subImage : type14ImageList) {
|
||||
facePosition.setImgHeight(_subImage.getHeight());
|
||||
facePosition.setImgWidth(_subImage.getWidth());
|
||||
SourceEntity source = new SourceEntity();
|
||||
source.setDeviceId(device.getId());
|
||||
source.setScenicId(device.getScenicId());
|
||||
source.setFaceSampleId(newFaceSampleId);
|
||||
source.setCreateTime(shotTime);
|
||||
source.setType(2);
|
||||
// 上传oss
|
||||
MultipartFile _file = ImageUtils.base64ToMultipartFile(_subImage.getData());
|
||||
ThreadPoolExecutor executor = getExecutor(scenicId);
|
||||
executor.execute(() -> {
|
||||
List<DeviceCropConfig> cropConfigs = deviceConfigEntity._getCropConfig();
|
||||
for (DeviceCropConfig cropConfig : cropConfigs) {
|
||||
source.setId(SnowFlakeUtil.getLongId());
|
||||
String filename = StorageUtil.joinPath(PHOTO_PATH, UUID.randomUUID() + "." + ext);
|
||||
MultipartFile _finalFile = _file;
|
||||
if (cropConfig.getCropType() == 1) {
|
||||
// 按固定位置截图
|
||||
try {
|
||||
_finalFile = ImageUtils.cropImage(_file, cropConfig.getTargetX(), cropConfig.getTargetY(), cropConfig.getTargetWidth(), cropConfig.getTargetHeight());
|
||||
} catch (IOException e) {
|
||||
log.error("裁切图片失败!", e);
|
||||
} catch (RasterFormatException e) {
|
||||
log.error("裁切图片出错!", e);
|
||||
}
|
||||
} else if (cropConfig.getCropType() == 2) {
|
||||
// 按人脸位置
|
||||
try {
|
||||
int targetX = facePosition.getLtX() - (cropConfig.getTargetWidth() - facePosition.getWidth())/2;
|
||||
int targetY = facePosition.getLtY() - (cropConfig.getTargetHeight() - facePosition.getHeight())/2;
|
||||
_finalFile = ImageUtils.cropImage(_file, targetX, targetY, cropConfig.getTargetWidth(), cropConfig.getTargetHeight());
|
||||
} catch (IOException e) {
|
||||
log.error("裁切图片失败!", e);
|
||||
} catch (RasterFormatException e) {
|
||||
log.error("裁切图片出错!", e);
|
||||
}
|
||||
facePosition.setImgHeight(cropConfig.getTargetHeight());
|
||||
facePosition.setImgWidth(cropConfig.getTargetWidth());
|
||||
}
|
||||
String _sourceUrl = scenicStorageAdapter.uploadFile(_finalFile, filename);
|
||||
scenicStorageAdapter.setAcl(StorageAcl.PUBLIC_READ, filename);
|
||||
source.setUrl(_sourceUrl);
|
||||
source.setPosJson(JacksonUtil.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
|
||||
if (Integer.valueOf(1).equals(device.getStatus())) {
|
||||
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, VIID_FACE, UUID.randomUUID() + "." + ext);
|
||||
faceSample.setFaceUrl(url);
|
||||
faceSampleMapper.add(faceSample);
|
||||
DynamicTaskGenerator.addTask(faceSample.getId());
|
||||
ThreadPoolExecutor executor = getExecutor(scenicId);
|
||||
executor.execute(() -> {
|
||||
taskFaceService.assureFaceDb(faceBodyAdapter, scenicId.toString());
|
||||
AddFaceResp addFaceResp;
|
||||
try {
|
||||
addFaceResp = faceBodyAdapter.addFace(scenicId.toString(), faceSample.getId().toString(), url, newFaceSampleId.toString());
|
||||
} catch (Exception e) {
|
||||
log.error("人脸添加失败:{}", e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (addFaceResp != null) {
|
||||
faceSample.setScore(addFaceResp.getScore());
|
||||
faceSampleMapper.updateScore(faceSample.getId(), addFaceResp.getScore());
|
||||
if (Integer.valueOf(1).equals(deviceConfig.getInteger("enable_pre_book"))) {
|
||||
DynamicTaskGenerator.addTask(faceSample.getId());
|
||||
}
|
||||
}
|
||||
});
|
||||
log.info("模式1人脸信息入库成功!设备ID:{}", deviceID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new VIIDBaseResp(
|
||||
new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date()))
|
||||
);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/Images", method = RequestMethod.POST)
|
||||
@IgnoreLogReq
|
||||
public VIIDBaseResp images(HttpServletRequest request, @RequestBody ImageUploadReq req) throws IOException {
|
||||
return new VIIDBaseResp(
|
||||
new ResponseStatusObject("1", "/VIID/Images", "0", "OK", sdfTime.format(new Date()))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.ycwl.basic.model.viid.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FacePositionObject {
|
||||
private Integer imgWidth;
|
||||
private Integer imgHeight;
|
||||
private Integer ltX;
|
||||
private Integer ltY;
|
||||
private Integer rbX;
|
||||
private Integer rbY;
|
||||
@JsonProperty("width")
|
||||
public Integer getWidth(){
|
||||
return rbX - ltX;
|
||||
}
|
||||
@JsonProperty("height")
|
||||
public Integer getHeight(){
|
||||
return rbY - ltY;
|
||||
}
|
||||
|
||||
public Integer centerX(){
|
||||
return (ltX + rbX) / 2;
|
||||
}
|
||||
public Integer centerY(){
|
||||
return (ltY + rbY) / 2;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.ycwl.basic.model.viid.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ImageInfoObject {
|
||||
@JsonProperty("ContentDescription")
|
||||
private String contentDescription;
|
||||
|
||||
@JsonProperty("EventSort")
|
||||
private int eventSort;
|
||||
|
||||
@JsonProperty("FileFormat")
|
||||
private String fileFormat;
|
||||
|
||||
@JsonProperty("FileSize")
|
||||
private long fileSize;
|
||||
|
||||
@JsonProperty("Height")
|
||||
private int height;
|
||||
|
||||
@JsonProperty("ImageID")
|
||||
private String imageID;
|
||||
|
||||
@JsonProperty("ImageSource")
|
||||
private String imageSource;
|
||||
|
||||
@JsonProperty("InfoKind")
|
||||
private int infoKind;
|
||||
|
||||
@JsonProperty("SecurityLevel")
|
||||
private String securityLevel;
|
||||
|
||||
@JsonProperty("ShotPlaceFullAdress")
|
||||
private String shotPlaceFullAdress;
|
||||
|
||||
@JsonProperty("ShotTime")
|
||||
private String shotTime;
|
||||
|
||||
@JsonProperty("Title")
|
||||
private String title;
|
||||
|
||||
@JsonProperty("Width")
|
||||
private int width;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.ycwl.basic.model.viid.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ImageListObject {
|
||||
@JsonProperty("Image")
|
||||
private List<ImageObject> imageObject;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.ycwl.basic.model.viid.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ImageObject {
|
||||
@JsonProperty("Data")
|
||||
private String data;
|
||||
|
||||
@JsonProperty("FaceList")
|
||||
private FaceListObject faceListObject;
|
||||
|
||||
@JsonProperty("ImageInfo")
|
||||
private ImageInfoObject imageInfoObject;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
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 Integer Width;
|
||||
@JsonProperty("Height")
|
||||
private Integer Height;
|
||||
@JsonProperty("ShotTime")
|
||||
private String ShotTime;
|
||||
@JsonProperty("Data")
|
||||
private String Data;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.ycwl.basic.model.viid.req;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.ycwl.basic.model.viid.entity.ImageListObject;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ImageUploadReq {
|
||||
@JsonProperty("ImageListObject")
|
||||
private ImageListObject imageListObject;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -38,7 +38,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
||||
import static com.ycwl.basic.constant.StorageConstant.VIID_FACE;
|
||||
|
||||
@Component
|
||||
@EnableScheduling
|
||||
@@ -229,19 +228,8 @@ public class FaceCleaner {
|
||||
log.info("开始清理人脸文件");
|
||||
List<FaceSampleRespVO> list = faceSampleMapper.list(new FaceSampleReqQuery());
|
||||
IStorageAdapter adapter = StorageFactory.use("faces");
|
||||
List<StorageFileObject> fileObjectList = adapter.listDir(VIID_FACE);
|
||||
fileObjectList.parallelStream().forEach(fileObject -> {
|
||||
if (fileObject.getModifyTime() != null) {
|
||||
// 如果是一天以内修改的,则跳过
|
||||
if (DateUtil.between(fileObject.getModifyTime(), new Date(), DateUnit.DAY) < 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(list.parallelStream().noneMatch(faceSampleRespVO -> faceSampleRespVO.getFaceUrl().contains(fileObject.getName()))){
|
||||
log.info("删除人脸文件:{}", fileObject);
|
||||
adapter.deleteFile(fileObject.getFullPath());
|
||||
}
|
||||
});
|
||||
// VIID相关功能已移除,不再清理VIID_FACE目录
|
||||
log.info("VIID人脸文件清理功能已移除");
|
||||
}
|
||||
public void cleanSourceOss() {
|
||||
log.info("开始清理源视频素材文件");
|
||||
|
||||
Reference in New Issue
Block a user