FrameTour-BE/src/main/java/com/ycwl/basic/task/FaceCleaner.java
2025-04-15 03:17:32 +08:00

290 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ycwl.basic.task;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.constant.StorageConstant;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.model.pc.faceSample.req.FaceSampleReqQuery;
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
import com.ycwl.basic.model.pc.source.resp.SourceRespVO;
import com.ycwl.basic.model.pc.video.req.VideoReqQuery;
import com.ycwl.basic.model.pc.video.resp.VideoRespVO;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.IStorageAdapter;
import com.ycwl.basic.storage.entity.StorageFileObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
@Component
@EnableScheduling
@Slf4j
@Profile("prod")
public class FaceCleaner {
@Autowired
private ScenicMapper scenicMapper;
@Autowired
private FaceSampleMapper faceSampleMapper;
@Autowired
private SourceMapper sourceMapper;
@Autowired
private VideoMapper videoMapper;
@Autowired
private ScenicRepository scenicRepository;
@Autowired
private FaceMapper faceMapper;
@Autowired
private ScenicService scenicService;
@Scheduled(cron = "0 0 1 * * ?")
public void deleteExpireSample(){
ScenicReqQuery scenicQuery = new ScenicReqQuery();
List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery);
scenicList.parallelStream().forEach(scenic -> {
log.info("当前景区{},开始删除人脸样本", scenic.getId());
IFaceBodyAdapter adapter = scenicService.getScenicFaceBodyAdapter(scenic.getId());
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenic.getId());
Integer sampleStoreDay = scenicConfig.getSampleStoreDay();
if (sampleStoreDay == null) {
log.info("当前景区{}人脸样本保存天数未设置默认7天", scenic.getId());
sampleStoreDay = 7;
}
Date sampleEndDate = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -sampleStoreDay);
List<FaceSampleEntity> faceSampleList = faceSampleMapper.listEntityBeforeDate(scenic.getId(), sampleEndDate);
if (faceSampleList.isEmpty()) {
log.info("当前景区{},人脸样本为空", scenic.getId());
return;
}
faceSampleList.forEach(faceSample -> {
boolean success = adapter.deleteFace(String.valueOf(scenic.getId()), faceSample.getId().toString());
if (success) {
log.info("当前景区{}人脸样本ID{},删除成功", scenic.getId(), faceSample.getId());
faceSampleMapper.deleteById(faceSample.getId());
} else {
log.info("当前景区{}人脸样本ID{},删除失败", scenic.getId(), faceSample.getId());
}
});
});
}
@Scheduled(cron = "0 45 2 * * ?")
public void deleteExpireFace() {
ScenicReqQuery scenicQuery = new ScenicReqQuery();
List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery);
scenicList.parallelStream().forEach(scenic -> {
log.info("当前景区{},开始删除用户人脸", scenic.getId());
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenic.getId());
IFaceBodyAdapter adapter = scenicService.getScenicFaceBodyAdapter(scenic.getId());
Integer faceStoreDay = scenicConfig.getFaceStoreDay();
if (faceStoreDay == null) {
log.info("当前景区{}人脸样本保存天数未设置默认3天", scenic.getName());
faceStoreDay = 3;
}
FaceReqQuery req = new FaceReqQuery();
req.setScenicId(scenic.getId());
req.setUpdateEndTime(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -faceStoreDay));
List<FaceRespVO> list = faceMapper.list(req);
list.forEach(face -> {
boolean result = adapter.deleteFace(USER_FACE_DB_NAME+face.getScenicId(), face.getId().toString());
if (result) {
log.info("当前景区{}人脸样本ID{},删除成功", scenic.getId(), face.getId());
faceMapper.deleteById(face.getId());
} else {
log.info("当前景区{}人脸样本ID{},删除失败", scenic.getId(), face.getId());
}
});
});
}
@Scheduled(cron = "0 0 3 * * ?")
public void deleteNotBuySource(){
ScenicReqQuery scenicQuery = new ScenicReqQuery();
List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery);
scenicList.parallelStream().forEach(scenic -> {
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenic.getId());
if (scenicConfig == null) {
log.info("当前景区{},无配置信息", scenic.getName());
return;
}
if (scenicConfig.getUserSourceExpireDay() == null) {
log.info("当前景区{},人脸样本过期天数未设置", scenic.getName());
return;
}
int expireDay = scenicConfig.getUserSourceExpireDay();
Date endDate = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -expireDay);
int deleteCount = sourceMapper.deleteNotBuyRelations(scenic.getId(), endDate);
log.info("当前景区{},删除关联素材{}个", scenic.getName(), deleteCount);
});
}
@Scheduled(cron = "0 15 3 * * ?")
public void deleteNotBuyVideos(){
ScenicReqQuery scenicQuery = new ScenicReqQuery();
List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery);
scenicList.parallelStream().forEach(scenic -> {
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenic.getId());
if (scenicConfig == null) {
log.info("当前景区{},无配置信息", scenic.getName());
return;
}
if (scenicConfig.getVideoStoreDay() == null) {
log.info("当前景区{}VLOG过期天数未设置", scenic.getName());
return;
}
int expireDay = scenicConfig.getVideoStoreDay();
Date endDate = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -expireDay);
int deleteCount = videoMapper.deleteNotBuyRelations(scenic.getId(), endDate);
log.info("当前景区{}删除VLOG{}个", scenic.getName(), deleteCount);
});
}
@Scheduled(cron = "0 30 3 * * ?")
public void deleteExpiredSource(){
ScenicReqQuery scenicQuery = new ScenicReqQuery();
List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery);
scenicList.parallelStream().forEach(scenic -> {
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenic.getId());
if (scenicConfig == null) {
log.info("当前景区{},无配置信息", scenic.getName());
return;
}
int imageSourceExpireDay = 7;
int videoSourceExpireDay = 7;
if (scenicConfig.getImageSourceStoreDay() != null) {
imageSourceExpireDay = scenicConfig.getImageSourceStoreDay();
} else {
log.info("当前景区{}原始素材保存天数未设置默认7天", scenic.getName());
}
if (scenicConfig.getVideoSourceStoreDay() != null) {
videoSourceExpireDay = scenicConfig.getVideoSourceStoreDay();
} else {
log.info("当前景区{}原始素材保存天数未设置默认7天", scenic.getName());
}
if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceVideo())) {
return;
}
if (Integer.valueOf(1).equals(scenicConfig.getDisableSourceImage())) {
return;
}
log.info("当前景区{},开始删除原始素材", scenic.getName());
Date endDate = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -videoSourceExpireDay);
int deleteVideoSourceCount = sourceMapper.deleteNotRelateSource(1, endDate);
log.info("当前景区{},删除原始视频素材{}个", scenic.getName(), deleteVideoSourceCount);
log.info("当前景区{},开始删除原始图片素材", scenic.getName());
Date endDate2 = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -imageSourceExpireDay);
int deleteImageSourceCount = sourceMapper.deleteNotRelateSource(2, endDate2);
log.info("当前景区{},删除原始图片素材{}个", scenic.getName(), deleteImageSourceCount);
});
}
@Scheduled(cron = "0 0 1 * * ?")
public void clearOss(){
cleanFaceSampleOss();
cleanSourceOss();
cleanVideoOss();
}
private void cleanFaceSampleOss() {
log.info("开始清理人脸文件");
List<FaceSampleRespVO> faceSampleRespVOS = faceSampleMapper.list(new FaceSampleReqQuery());
IStorageAdapter adapter = StorageFactory.use("faces");
List<StorageFileObject> fileObjectList = adapter.listDir("user-face");
fileObjectList.parallelStream().forEach(fileObject -> {
if (fileObject.getModifyTime() != null) {
// 如果是一天以内修改的,则跳过
if (DateUtil.between(fileObject.getModifyTime(), new Date(), DateUnit.DAY) < 1) {
return;
}
}
if(faceSampleRespVOS.parallelStream().noneMatch(faceSampleRespVO -> faceSampleRespVO.getFaceUrl().contains(fileObject.getFullPath()))){
log.info("删除人脸文件:{}", fileObject);
adapter.deleteFile(fileObject.getFullPath());
}
});
}
private void cleanSourceOss() {
log.info("开始清理源视频素材文件");
List<SourceRespVO> list = sourceMapper.list(new SourceReqQuery());
scenicMapper.list(new ScenicReqQuery()).forEach(scenic -> {
IStorageAdapter adapter = scenicService.getScenicStorageAdapter(scenic.getId());
log.info("开始清理视频文件");
List<StorageFileObject> fileObjectList = adapter.listDir(StorageConstant.VIDEO_PIECE_PATH);
fileObjectList.parallelStream().forEach(fileObject -> {
if (fileObject.getModifyTime() != null) {
// 如果是一天以内修改的,则跳过
if (DateUtil.between(fileObject.getModifyTime(), new Date(), DateUnit.DAY) <= 1) {
return;
}
}
if (list.parallelStream().filter(videoRespVO -> Objects.nonNull(videoRespVO.getVideoUrl())).noneMatch(videoRespVO -> videoRespVO.getVideoUrl().contains(fileObject.getFullPath()))){
log.info("删除文件:{}", fileObject);
adapter.deleteFile(fileObject.getFullPath());
} else {
log.info("文件存在关系:{},未删除", fileObject);
}
});
log.info("开始清理图片文件");
fileObjectList = adapter.listDir(StorageConstant.PHOTO_PATH);
fileObjectList.parallelStream().forEach(fileObject -> {
if (fileObject.getModifyTime() != null) {
// 如果是一天以内修改的,则跳过
if (DateUtil.between(fileObject.getModifyTime(), new Date(), DateUnit.DAY) <= 1) {
return;
}
}
if (list.parallelStream().filter(videoRespVO -> Objects.nonNull(videoRespVO.getUrl())).noneMatch(videoRespVO -> videoRespVO.getUrl().contains(fileObject.getFullPath()))){
log.info("删除文件:{}", fileObject);
adapter.deleteFile(fileObject.getFullPath());
} else {
log.info("文件存在关系:{},未删除", fileObject);
}
});
});
}
private void cleanVideoOss() {
log.info("开始清理视频文件");
List<VideoRespVO> list = videoMapper.list(new VideoReqQuery());
scenicMapper.list(new ScenicReqQuery()).forEach(scenic -> {
IStorageAdapter adapter = scenicService.getScenicStorageAdapter(scenic.getId());
log.info("开始清理视频文件");
List<StorageFileObject> fileObjectList = adapter.listDir(StorageConstant.VLOG_PATH);
fileObjectList.parallelStream().forEach(fileObject -> {
if (fileObject.getModifyTime() != null) {
// 如果是一天以内修改的,则跳过
if (DateUtil.between(fileObject.getModifyTime(), new Date(), DateUnit.DAY) <= 1) {
return;
}
}
if (list.parallelStream().filter(videoRespVO -> Objects.nonNull(videoRespVO.getVideoUrl())).noneMatch(videoRespVO -> videoRespVO.getVideoUrl().contains(fileObject.getFullPath()))){
log.info("删除文件:{}", fileObject);
adapter.deleteFile(fileObject.getFullPath());
} else {
log.info("文件存在关系:{},未删除", fileObject);
}
});
});
}
}