指定设备提前预约

This commit is contained in:
Jerry Yan 2025-02-05 14:31:31 +08:00
parent 1eb636d402
commit a016622cc9
27 changed files with 471 additions and 103 deletions

View File

@ -0,0 +1,192 @@
package com.ycwl.basic.biz;
import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.mobile.goods.VideoTaskStatusVO;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.task.req.TaskReqQuery;
import com.ycwl.basic.model.pc.task.resp.TaskRespVO;
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.repository.TemplateRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Component
public class TaskStatusBiz {
public static final String TASK_STATUS_USER_CACHE_KEY = "task:status:user:%s:face:%s";
public static final String TASK_STATUS_FACE_CACHE_KEY = "task:status:face:%s";
public static final String TASK_STATUS_FACE_CACHE_KEY_CUT = "task:status:face:%s:cut";
public static final String TASK_STATUS_FACE_CACHE_KEY_TEMPLATE = "task:status:face:%s:tpl:%s";
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private FaceRepository faceRepository;
@Autowired
private TemplateRepository templateRepository;
@Autowired
private FaceMapper faceMapper;
@Autowired
private TaskMapper taskMapper;
@Autowired
private VideoMapper videoMapper;
@Autowired
private TemplateBiz templateBiz;
public boolean getUserHaveFace(Long userId, Long faceId) {
if (userId == null || faceId == null) {
return false;
}
if (redisTemplate.hasKey(String.format(TASK_STATUS_USER_CACHE_KEY, userId, faceId))) {
return true;
}
FaceEntity face = faceRepository.getFace(faceId);
if (face == null) {
return false;
}
if (face.getMemberId().equals(userId)) {
redisTemplate.opsForValue().set(String.format(TASK_STATUS_USER_CACHE_KEY, userId, faceId), "1", 3600, TimeUnit.SECONDS);
return true;
} else {
return false;
}
}
public void setFaceCutStatus(Long faceId, int status) {
redisTemplate.opsForValue().set(String.format(TASK_STATUS_FACE_CACHE_KEY_CUT, faceId), String.valueOf(status), 3600, TimeUnit.SECONDS);
}
public void setFaceTemplateStatus(Long faceId, Long templateId, Long videoId) {
redisTemplate.opsForValue().set(String.format(TASK_STATUS_FACE_CACHE_KEY_TEMPLATE, faceId, templateId), String.valueOf(videoId), 3600, TimeUnit.SECONDS);
}
public VideoTaskStatusVO getScenicUserStatus(Long scenicId, Long userId) {
FaceRespVO lastFace = faceMapper.findLastFaceByScenicAndUserId(scenicId, userId);
VideoTaskStatusVO response = new VideoTaskStatusVO();
if (lastFace == null) {
response.setStatus(-1);
return response;
}
return getFaceStatus(lastFace.getId());
}
public VideoTaskStatusVO getFaceStatus(Long faceId) {
FaceEntity face = faceRepository.getFace(faceId);
VideoTaskStatusVO response = new VideoTaskStatusVO();
if (face == null) {
response.setStatus(-1);
return response;
}
response.setScenicId(face.getScenicId());
response.setFaceId(faceId);
List<TemplateRespVO> templateList = templateRepository.getTemplateListByScenicId(face.getScenicId());
response.setMaxCount(templateList.size());
int alreadyFinished = 0;
for (TemplateRespVO template : templateList) {
response.setTemplateId(template.getId());
long videoId = getFaceTemplateVideoId(faceId, template.getId());
if (videoId <= 0) {
response.setStatus(2);
} else {
response.setVideoId(videoId);
alreadyFinished++;
}
}
response.setCount(alreadyFinished);
if (alreadyFinished == 0) {
response.setStatus(0);
} else {
response.setStatus(1);
}
if (alreadyFinished == 0) {
int faceCutStatus = getFaceCutStatus(faceId);
if (faceCutStatus != 1) {
// 正在切片
if (templateBiz.determineTemplateCanGenerate(templateList.get(0).getId(), faceId, false)) {
response.setStatus(2);
} else {
response.setStatus(0);
}
}
}
return response;
}
public VideoTaskStatusVO getFaceTemplateStatus(Long faceId, Long templateId) {
FaceEntity face = faceRepository.getFace(faceId);
VideoTaskStatusVO response = new VideoTaskStatusVO();
if (face == null) {
response.setStatus(-1);
return response;
}
response.setScenicId(face.getScenicId());
response.setFaceId(faceId);
response.setTemplateId(templateId);
long videoId = getFaceTemplateVideoId(faceId, templateId);
if (videoId < 0) {
int faceCutStatus = getFaceCutStatus(faceId);
if (faceCutStatus != 1) {
// 正在切片
response.setStatus(2);
return response;
}
} else if (videoId == 0) {
response.setStatus(2);
} else {
response.setVideoId(videoId);
response.setStatus(1);
}
return response;
}
public int getFaceCutStatus(Long faceId) {
if (redisTemplate.hasKey(String.format(TASK_STATUS_FACE_CACHE_KEY_CUT, faceId))) {
String status = redisTemplate.opsForValue().get(String.format(TASK_STATUS_FACE_CACHE_KEY_CUT, faceId));
if (status != null) {
return Integer.parseInt(status);
}
}
return 1;
}
public long getFaceTemplateVideoId(Long faceId, Long templateId) {
if (redisTemplate.hasKey(String.format(TASK_STATUS_FACE_CACHE_KEY_TEMPLATE, faceId, templateId))) {
String status = redisTemplate.opsForValue().get(String.format(TASK_STATUS_FACE_CACHE_KEY_TEMPLATE, faceId, templateId));
if (status != null) {
return Long.parseLong(status);
}
}
TaskReqQuery taskReqQuery = new TaskReqQuery();
taskReqQuery.setFaceId(faceId);
taskReqQuery.setTemplateId(templateId);
List<TaskRespVO> list = taskMapper.list(taskReqQuery);
Optional<TaskRespVO> min = list.stream().min(Comparator.comparing(TaskRespVO::getCreateTime));
if (min.isPresent()) {
TaskRespVO task = min.get();
long taskStatus = 0;
if (task.getStatus() == 1) {
// 已完成
VideoEntity video = videoMapper.findByTaskId(task.getId());
if (video != null) {
taskStatus = video.getId();
}
}
setFaceTemplateStatus(faceId, templateId, taskStatus);
} else {
// 从来没生成过
setFaceTemplateStatus(faceId, templateId, -1L);
return -1;
}
return 0;
}
}

View File

@ -1,6 +1,7 @@
package com.ycwl.basic.controller.mobile; package com.ycwl.basic.controller.mobile;
import com.ycwl.basic.annotation.IgnoreToken; import com.ycwl.basic.annotation.IgnoreToken;
import com.ycwl.basic.biz.TaskStatusBiz;
import com.ycwl.basic.constant.BaseContextHandler; import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.exception.CheckTokenException; import com.ycwl.basic.exception.CheckTokenException;
import com.ycwl.basic.model.jwt.JwtInfo; import com.ycwl.basic.model.jwt.JwtInfo;
@ -31,6 +32,8 @@ public class AppGoodsController {
private GoodsService goodsService; private GoodsService goodsService;
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@Autowired
private TaskStatusBiz taskStatusBiz;
@ApiOperation("商品列表") @ApiOperation("商品列表")
@PostMapping("/goodsList") @PostMapping("/goodsList")

View File

@ -1,6 +1,7 @@
package com.ycwl.basic.controller.mobile; package com.ycwl.basic.controller.mobile;
import com.ycwl.basic.annotation.IgnoreLogReq; import com.ycwl.basic.annotation.IgnoreLogReq;
import com.ycwl.basic.biz.TaskStatusBiz;
import com.ycwl.basic.model.jwt.JwtInfo; import com.ycwl.basic.model.jwt.JwtInfo;
import com.ycwl.basic.model.mobile.goods.VideoTaskReq; import com.ycwl.basic.model.mobile.goods.VideoTaskReq;
import com.ycwl.basic.model.mobile.goods.VideoTaskStatusVO; import com.ycwl.basic.model.mobile.goods.VideoTaskStatusVO;
@ -24,6 +25,8 @@ public class AppTaskController {
private GoodsService goodsService; private GoodsService goodsService;
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@Autowired
private TaskStatusBiz taskStatusBiz;
@GetMapping("/face/{faceId}") @GetMapping("/face/{faceId}")
@IgnoreLogReq @IgnoreLogReq

View File

@ -273,7 +273,9 @@ public class ViidController {
faceSampleMapper.add(faceSample); faceSampleMapper.add(faceSample);
new Thread(() -> { new Thread(() -> {
taskFaceService.addFaceSample(faceSample.getId()); taskFaceService.addFaceSample(faceSample.getId());
if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) {
DynamicTaskGenerator.addTask(faceSample.getId()); DynamicTaskGenerator.addTask(faceSample.getId());
}
}).start(); }).start();
for (SubImageInfoObject _subImage : type14ImageList) { for (SubImageInfoObject _subImage : type14ImageList) {
facePosition.setImgHeight(_subImage.getHeight()); facePosition.setImgHeight(_subImage.getHeight());
@ -318,7 +320,12 @@ public class ViidController {
faceSample.setFaceUrl(url); faceSample.setFaceUrl(url);
faceSampleMapper.add(faceSample); faceSampleMapper.add(faceSample);
DynamicTaskGenerator.addTask(faceSample.getId()); DynamicTaskGenerator.addTask(faceSample.getId());
new Thread(() -> {
taskFaceService.addFaceSample(faceSample.getId()); taskFaceService.addFaceSample(faceSample.getId());
if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) {
DynamicTaskGenerator.addTask(faceSample.getId());
}
}).start();
log.info("模式1人脸信息入库成功设备ID{}", deviceID); log.info("模式1人脸信息入库成功设备ID{}", deviceID);
} }
} }

View File

@ -12,8 +12,9 @@ public enum StatisticEnum {
REFUND(5,"退款"), REFUND(5,"退款"),
MESSAGE_PUSH(6,"消息推送"), MESSAGE_PUSH(6,"消息推送"),
DOWNLOAD(8,"下载"), DOWNLOAD(8,"下载"),
CLICK_ON_PAYMENT(9,"点击支付、购买"), CLICK_PAY(9,"点击支付"),
OTHER_ENTER(10,"其他渠道进入"), OTHER_ENTER(10,"其他渠道进入"),
SUBMIT_PAYMENT(11,"点击支付"),
SCAN_MARKED_CODE(20,"扫描特殊标记码"), SCAN_MARKED_CODE(20,"扫描特殊标记码"),
; ;

View File

@ -66,7 +66,7 @@ public class AuthInterceptor extends HandlerInterceptorAdapter {
// 获取 token // 获取 token
String token = getToken(request); String token = getToken(request);
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
log.error("==> 请求 header 缺少 Token [{}]", token); log.error("==> 请求 header 缺少 Token [{}], URL [{}]", token, request.getRequestURL());
throw new MissTokenException("请求头缺少token"); throw new MissTokenException("请求头缺少token");
} }

View File

@ -24,11 +24,12 @@ public interface FaceMapper {
int deleteByIds(@Param("list") List<Long> ids); int deleteByIds(@Param("list") List<Long> ids);
int update(FaceEntity face); int update(FaceEntity face);
FaceRespVO getByMemberId(@Param("userId") Long userId, @Param("scenicId") Long scenicId); FaceRespVO getLatestByMemberId(@Param("userId") Long userId, @Param("scenicId") Long scenicId);
int finishedJourney(Long faceId); int finishedJourney(Long faceId);
FaceRespVO findLastFaceByUserId(String userId); FaceRespVO findLastFaceByUserId(String userId);
FaceRespVO findLastFaceByScenicAndUserId(Long scenicId, Long userId);
List<FaceRespVO> listByScenicAndUserId(String scenicId, Long userId); List<FaceRespVO> listByScenicAndUserId(String scenicId, Long userId);
} }

View File

@ -26,5 +26,5 @@ public interface FaceSampleMapper {
List<FaceSampleEntity> listByIds(List<Long> list); List<FaceSampleEntity> listByIds(List<Long> list);
FaceSampleEntity getEntity(Long faceSampleId); FaceSampleEntity getEntity(Long faceSampleId);
List<FaceSampleEntity> listEntity(Long scenicId, Date endDate); List<FaceSampleEntity> listEntityBeforeDate(Long scenicId, Date endDate);
} }

View File

@ -57,4 +57,5 @@ public class DeviceConfigEntity {
* 切割时取人脸后多少秒的视频 * 切割时取人脸后多少秒的视频
*/ */
private BigDecimal cutPost; private BigDecimal cutPost;
private Integer enablePreBook;
} }

View File

@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest; import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest;
import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse; import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.ycwl.basic.model.pc.faceDetectLog.resp.MatchLocalRecord; import com.ycwl.basic.model.pc.faceDetectLog.resp.MatchLocalRecord;
@ -31,6 +32,9 @@ public class FaceDetectLog {
private String matchLocalRecord; private String matchLocalRecord;
@TableField(exist = false)
private List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> matchRawRecord;
public static FaceDetectLog quickCreate(String reason) { public static FaceDetectLog quickCreate(String reason) {
FaceDetectLog log = new FaceDetectLog(); FaceDetectLog log = new FaceDetectLog();
log.reason = reason; log.reason = reason;

View File

@ -7,6 +7,7 @@ import java.util.Date;
@Data @Data
public class MatchLocalRecord { public class MatchLocalRecord {
private Long faceSampleId; private Long faceSampleId;
private String deviceName;
private String faceUrl; private String faceUrl;
private Float score; private Float score;
private Float confidence; private Float confidence;

View File

@ -43,6 +43,7 @@ public class ScenicConfigEntity {
* 预约流程1-预约2-在线3-全部 * 预约流程1-预约2-在线3-全部
*/ */
private Integer bookRoutine; private Integer bookRoutine;
private Integer forceFinishTime;
/** /**
* 样本保存时间 * 样本保存时间
*/ */

View File

@ -5,28 +5,36 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class FixedRateLimiter { public class FixedRateLimiter implements IRateLimiter {
private final Semaphore semaphore = new Semaphore(1); private final Semaphore semaphore = new Semaphore(1);
private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
public FixedRateLimiter(int rate, TimeUnit timeUnit) { public FixedRateLimiter(int rate, TimeUnit timeUnit) {
// 启动一个线程每0.5秒释放一个许可 // 启动一个线程每0.5秒释放一个许可
scheduler.scheduleAtFixedRate(() -> { scheduler.scheduleAtFixedRate(() -> {
synchronized (semaphore) {
if (semaphore.availablePermits() < 1) { if (semaphore.availablePermits() < 1) {
semaphore.release(1); semaphore.release(1);
} }
}
}, rate, rate, timeUnit); }, rate, rate, timeUnit);
} }
@Override
public void acquire() throws InterruptedException { public void acquire() throws InterruptedException {
synchronized (semaphore) {
semaphore.acquire(); semaphore.acquire();
} }
}
@Override
public void shutdown() { public void shutdown() {
scheduler.shutdown(); scheduler.shutdown();
} }
@Override
public boolean tryAcquire() {
return semaphore.tryAcquire();
}
@Override
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {
return semaphore.tryAcquire(timeout, unit);
}
} }

View File

@ -0,0 +1,10 @@
package com.ycwl.basic.ratelimiter;
import java.util.concurrent.TimeUnit;
public interface IRateLimiter {
void acquire() throws InterruptedException;
void shutdown();
boolean tryAcquire();
boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException;
}

View File

@ -6,25 +6,45 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class SlidingWindowRateLimiter { public class SlidingWindowRateLimiter implements IRateLimiter {
private final Semaphore semaphore; private final Semaphore semaphore;
private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
public SlidingWindowRateLimiter(int maxRequestsPerSecond) { public SlidingWindowRateLimiter(int maxRequestsPerSecond) {
this.semaphore = new Semaphore(maxRequestsPerSecond); this.semaphore = new Semaphore(maxRequestsPerSecond);
int rate = 1000000 / maxRequestsPerSecond;
scheduler.scheduleAtFixedRate(() -> { scheduler.scheduleAtFixedRate(() -> {
if (semaphore.availablePermits() < maxRequestsPerSecond) { if (semaphore.availablePermits() < maxRequestsPerSecond) {
semaphore.release(1); semaphore.release(maxRequestsPerSecond - semaphore.availablePermits());
} }
}, rate, rate, TimeUnit.MICROSECONDS); }, 1, 1, TimeUnit.SECONDS);
} }
public SlidingWindowRateLimiter(int maxRequests, int perSecond) {
this.semaphore = new Semaphore(maxRequests);
scheduler.scheduleAtFixedRate(() -> {
if (semaphore.availablePermits() < maxRequests) {
semaphore.release(maxRequests - semaphore.availablePermits());
}
}, perSecond, perSecond, TimeUnit.SECONDS);
}
@Override
public void acquire() throws InterruptedException { public void acquire() throws InterruptedException {
semaphore.acquire(); semaphore.acquire();
} }
@Override
public void shutdown() { public void shutdown() {
scheduler.shutdown(); scheduler.shutdown();
} }
@Override
public boolean tryAcquire() {
return semaphore.tryAcquire();
}
@Override
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {
return semaphore.tryAcquire(timeout, unit);
}
} }

View File

@ -346,7 +346,7 @@ public class GoodsServiceImpl implements GoodsService {
@Override @Override
public VideoTaskStatusVO getTaskStatusByScenicId(Long userId, Long scenicId) { public VideoTaskStatusVO getTaskStatusByScenicId(Long userId, Long scenicId) {
FaceRespVO faceVO = faceMapper.getByMemberId(userId, scenicId); FaceRespVO faceVO = faceMapper.getLatestByMemberId(userId, scenicId);
VideoTaskStatusVO response = new VideoTaskStatusVO(); VideoTaskStatusVO response = new VideoTaskStatusVO();
response.setScenicId(scenicId); response.setScenicId(scenicId);
if (faceVO == null) { if (faceVO == null) {

View File

@ -326,14 +326,6 @@ public class OrderServiceImpl implements OrderService {
return ApiResponse.fail("订单添加失败"); return ApiResponse.fail("订单添加失败");
} }
//点击支付按钮统计 //点击支付按钮统计
OrderRespVO orderRespVO = orderMapper.getById(orderId);
StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
statisticsRecordAddReq.setMemberId(orderRespVO.getMemberId());
statisticsRecordAddReq.setType(StatisticEnum.CLICK_ON_PAYMENT.code);
statisticsRecordAddReq.setScenicId(orderRespVO.getScenicId());
statisticsRecordAddReq.setMorphId(orderId);
statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
WxPayRespVO wxPayRespVO = initiatePayment(order, orderItems); WxPayRespVO wxPayRespVO = initiatePayment(order, orderItems);
return ApiResponse.success(wxPayRespVO); return ApiResponse.success(wxPayRespVO);

View File

@ -1,9 +1,7 @@
package com.ycwl.basic.service.task.impl; package com.ycwl.basic.service.task.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.facebody.model.v20191230.AddFaceEntityRequest; import com.aliyuncs.facebody.model.v20191230.AddFaceEntityRequest;
import com.aliyuncs.facebody.model.v20191230.AddFaceRequest; import com.aliyuncs.facebody.model.v20191230.AddFaceRequest;
import com.aliyuncs.facebody.model.v20191230.AddFaceResponse; import com.aliyuncs.facebody.model.v20191230.AddFaceResponse;
@ -16,7 +14,6 @@ import com.aliyuncs.facebody.model.v20191230.ListFaceEntitiesRequest;
import com.aliyuncs.facebody.model.v20191230.ListFaceEntitiesResponse; import com.aliyuncs.facebody.model.v20191230.ListFaceEntitiesResponse;
import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest; import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest;
import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse; import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ycwl.basic.biz.OrderBiz; import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.config.FaceDetectConfig; import com.ycwl.basic.config.FaceDetectConfig;
import com.ycwl.basic.constant.FaceConstant; import com.ycwl.basic.constant.FaceConstant;
@ -27,22 +24,20 @@ import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.ScenicMapper; import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.SourceMapper; import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO; import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.face.entity.FaceEntity; import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO; import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLog; import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLog;
import com.ycwl.basic.model.pc.faceDetectLog.resp.MatchLocalRecord; import com.ycwl.basic.model.pc.faceDetectLog.resp.MatchLocalRecord;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; 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.faceSample.resp.FaceSampleRespVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; 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.entity.MemberSourceEntity; import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo; import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo;
import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import com.ycwl.basic.ratelimiter.FixedRateLimiter; import com.ycwl.basic.ratelimiter.FixedRateLimiter;
import com.ycwl.basic.ratelimiter.SlidingWindowRateLimiter; import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.repository.FaceRepository; import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.repository.ScenicRepository; import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.service.task.TaskFaceService; import com.ycwl.basic.service.task.TaskFaceService;
@ -55,7 +50,6 @@ 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;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient; import com.aliyuncs.IAcsClient;
@ -103,6 +97,8 @@ public class TaskFaceServiceImpl implements TaskFaceService {
@Autowired @Autowired
private ScenicRepository scenicRepository; private ScenicRepository scenicRepository;
@Autowired
private DeviceRepository deviceRepository;
private IAcsClient getClient() { private IAcsClient getClient() {
DefaultProfile profile = DefaultProfile.getProfile( DefaultProfile profile = DefaultProfile.getProfile(
@ -195,29 +191,13 @@ public class TaskFaceServiceImpl implements TaskFaceService {
if (matchList.get(0).getFaceItems().isEmpty()) { if (matchList.get(0).getFaceItems().isEmpty()) {
return respVo; return respVo;
} }
List<MatchLocalRecord> records = matchList.get(0).getFaceItems().stream() List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> records = matchList.get(0).getFaceItems();
.map(item -> { log.setMatchRawRecord(records);
MatchLocalRecord record = new MatchLocalRecord();
record.setIdStr(item.getExtraData());
record.setFaceSampleId(Long.parseLong(item.getExtraData()));
if (StringUtils.isNumeric(item.getDbName())) {
FaceSampleEntity faceSample = faceRepository.getFaceSample(record.getFaceSampleId());
if (faceSample != null) {
record.setFaceUrl(faceSample.getFaceUrl());
record.setShotDate(faceSample.getCreateAt());
}
} else {
record.setFaceUrl(getFaceUrl(record.getFaceSampleId()));
}
record.setScore(item.getScore());
record.setConfidence(item.getConfidence());
return record;
})
.collect(Collectors.toList());
log.matchLocalRecord(records);
List<Long> faceSampleIds = records.stream() List<Long> faceSampleIds = records.stream()
.filter(record -> record.getScore() > 0.525F) .filter(record -> record.getScore() > 0.525F)
.map(MatchLocalRecord::getFaceSampleId) .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData)
.filter(StringUtils::isNumeric)
.map(Long::valueOf)
.collect(Collectors.toList()); .collect(Collectors.toList());
respVo.setFirstMatchRate(matchList.get(0).getFaceItems().get(0).getScore()); respVo.setFirstMatchRate(matchList.get(0).getFaceItems().get(0).getScore());
respVo.setSampleListIds(faceSampleIds); respVo.setSampleListIds(faceSampleIds);
@ -227,7 +207,33 @@ public class TaskFaceServiceImpl implements TaskFaceService {
e.printStackTrace(); e.printStackTrace();
throw new BaseException(e.getMessage()); throw new BaseException(e.getMessage());
} finally { } finally {
new Thread(() -> {
if (log.getMatchRawRecord() != null) {
List<MatchLocalRecord> collect = log.getMatchRawRecord().parallelStream().map(item -> {
MatchLocalRecord record = new MatchLocalRecord();
record.setIdStr(item.getExtraData());
record.setFaceSampleId(Long.parseLong(item.getExtraData()));
if (StringUtils.isNumeric(item.getDbName())) {
FaceSampleEntity faceSample = faceRepository.getFaceSample(record.getFaceSampleId());
if (faceSample != null) {
DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId());
if (device != null) {
record.setDeviceName(device.getName());
}
record.setFaceUrl(faceSample.getFaceUrl());
record.setShotDate(faceSample.getCreateAt());
}
} else {
record.setFaceUrl(getFaceUrl(record.getFaceSampleId()));
}
record.setScore(item.getScore());
record.setConfidence(item.getConfidence());
return record;
}).collect(Collectors.toList());
log.setMatchLocalRecord(JSON.toJSONString(collect));
}
logMapper.insert(log); logMapper.insert(log);
}).start();
} }
} }
@ -289,20 +295,6 @@ public class TaskFaceServiceImpl implements TaskFaceService {
sampleStoreDay = 7; sampleStoreDay = 7;
} }
Date endDate = DateUtils.addDateDays(new Date(), -(sampleStoreDay + 1)); Date endDate = DateUtils.addDateDays(new Date(), -(sampleStoreDay + 1));
List<FaceSampleEntity> faceSampleList = faceSampleMapper.listEntity(scenicId, endDate);
if (faceSampleList.isEmpty()) {
log.info("当前景区{},人脸样本为空", scenicId);
return;
}
faceSampleList.forEach(faceSample -> {
boolean success = deleteFaceSample(String.valueOf(scenicId), generateEntityId(faceSample));
if (success) {
log.info("当前景区{}人脸样本ID{},删除成功", scenicId, faceSample.getId());
faceSampleMapper.deleteById(faceSample.getId());
} else {
log.info("当前景区{}人脸样本ID{},删除失败", scenicId, faceSample.getId());
}
});
ListFaceEntitiesRequest listFaceEntitiesRequest = new ListFaceEntitiesRequest(); ListFaceEntitiesRequest listFaceEntitiesRequest = new ListFaceEntitiesRequest();
listFaceEntitiesRequest.setDbName(String.valueOf(scenicId)); listFaceEntitiesRequest.setDbName(String.valueOf(scenicId));
listFaceEntitiesRequest.setOrder("asc"); listFaceEntitiesRequest.setOrder("asc");
@ -342,6 +334,20 @@ public class TaskFaceServiceImpl implements TaskFaceService {
} }
} catch (Exception ignored) { } catch (Exception ignored) {
} }
List<FaceSampleEntity> faceSampleList = faceSampleMapper.listEntityBeforeDate(scenicId, endDate);
if (faceSampleList.isEmpty()) {
log.info("当前景区{},人脸样本为空", scenicId);
return;
}
faceSampleList.forEach(faceSample -> {
boolean success = deleteFaceSample(String.valueOf(scenicId), generateEntityId(faceSample));
if (success) {
log.info("当前景区{}人脸样本ID{},删除成功", scenicId, faceSample.getId());
faceSampleMapper.deleteById(faceSample.getId());
} else {
log.info("当前景区{}人脸样本ID{},删除失败", scenicId, faceSample.getId());
}
});
} }
@Override @Override

View File

@ -345,7 +345,8 @@ public class TaskTaskServiceImpl implements TaskService {
if (templateList == null || templateList.isEmpty()) { if (templateList == null || templateList.isEmpty()) {
return; return;
} }
if (Integer.valueOf(3).equals(scenicConfig.getBookRoutine())) { if (Integer.valueOf(3).equals(scenicConfig.getBookRoutine()) || Integer.valueOf(4).equals(scenicConfig.getBookRoutine())) {
// 生成全部视频的逻辑
templateList.forEach(template -> { templateList.forEach(template -> {
createTaskByFaceIdAndTempalteId(faceId, template.getId(), 1); createTaskByFaceIdAndTempalteId(faceId, template.getId(), 1);
}); });

View File

@ -90,7 +90,7 @@ public class DynamicTaskGenerator {
queue.add(new Task(faceSampleId, createTime)); queue.add(new Task(faceSampleId, createTime));
} }
@Scheduled(fixedDelay = 500L) @Scheduled(fixedDelay = 1000L)
public void doTask() { public void doTask() {
Task task = queue.poll(); Task task = queue.poll();
if (task == null) { if (task == null) {
@ -111,7 +111,7 @@ public class DynamicTaskGenerator {
log.debug("当前景区{},无配置", faceSample.getScenicId()); log.debug("当前景区{},无配置", faceSample.getScenicId());
return; return;
} }
if (!Integer.valueOf(1).equals(scenicConfig.getBookRoutine()) && !Integer.valueOf(3).equals(scenicConfig.getBookRoutine())) { if (!Integer.valueOf(5).equals(scenicConfig.getBookRoutine())) {
log.debug("当前景区{}未启用预约流程,跳过", faceSample.getScenicId()); log.debug("当前景区{}未启用预约流程,跳过", faceSample.getScenicId());
return; return;
} }

View File

@ -3,10 +3,15 @@ package com.ycwl.basic.task;
import com.ycwl.basic.mapper.FaceSampleMapper; import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.ScenicMapper; import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.SourceMapper; import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.pc.faceSample.req.FaceSampleReqQuery; import com.ycwl.basic.model.pc.faceSample.req.FaceSampleReqQuery;
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; 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.req.ScenicReqQuery;
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO; import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
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.task.TaskFaceService; import com.ycwl.basic.service.task.TaskFaceService;
import com.ycwl.basic.storage.StorageFactory; import com.ycwl.basic.storage.StorageFactory;
import com.ycwl.basic.storage.adapters.IStorageAdapter; import com.ycwl.basic.storage.adapters.IStorageAdapter;
@ -31,6 +36,10 @@ public class FaceCleaner {
private FaceSampleMapper faceSampleMapper; private FaceSampleMapper faceSampleMapper;
@Autowired @Autowired
private SourceMapper sourceMapper; private SourceMapper sourceMapper;
@Autowired
private VideoMapper videoMapper;
@Autowired
private ScenicRepository scenicRepository;
@Scheduled(cron = "0 0 4 * * ?") @Scheduled(cron = "0 0 4 * * ?")
public void clean(){ public void clean(){
@ -44,11 +53,43 @@ public class FaceCleaner {
@Scheduled(cron = "0 0 3 * * ?") @Scheduled(cron = "0 0 3 * * ?")
public void deleteExpiredSource(){ 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());
});
} }
@Scheduled(cron = "0 0 5 * * ?") @Scheduled(cron = "0 0 5 * * ?")
public void clear(){ public void clearOss(){
cleanFaceSampleOss();
cleanSourceOss();
cleanVideoOss();
}
private void cleanFaceSampleOss() {
log.info("开始清理人脸文件"); log.info("开始清理人脸文件");
List<FaceSampleRespVO> faceSampleRespVOS = faceSampleMapper.list(new FaceSampleReqQuery()); List<FaceSampleRespVO> faceSampleRespVOS = faceSampleMapper.list(new FaceSampleReqQuery());
IStorageAdapter adapter = StorageFactory.use("faces"); IStorageAdapter adapter = StorageFactory.use("faces");
@ -60,4 +101,20 @@ public class FaceCleaner {
} }
}); });
} }
private void cleanSourceOss() {
}
private void cleanVideoOss() {
log.info("开始清理视频文件");
List<VideoRespVO> videoRespVOS = videoMapper.list(new VideoReqQuery());
IStorageAdapter adapter = StorageFactory.use("video");
List<StorageFileObject> fileObjectList = adapter.listDir("");
fileObjectList.parallelStream().forEach(fileObject -> {
if (videoRespVOS.parallelStream().noneMatch(videoRespVO -> videoRespVO.getVideoUrl().contains(fileObject.getFullPath()))){
log.info("删除视频文件:{}", fileObject);
adapter.deleteFile(fileObject.getFullPath());
} else {
log.info("视频文件存在关系:{},未删除", fileObject);
}
});
}
} }

View File

@ -1,18 +1,17 @@
package com.ycwl.basic.task; package com.ycwl.basic.task;
import com.ycwl.basic.biz.OrderBiz; import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.biz.TaskStatusBiz;
import com.ycwl.basic.device.DeviceFactory; import com.ycwl.basic.device.DeviceFactory;
import com.ycwl.basic.device.entity.common.FileObject; import com.ycwl.basic.device.entity.common.FileObject;
import com.ycwl.basic.device.operator.IDeviceStorageOperator; import com.ycwl.basic.device.operator.IDeviceStorageOperator;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.repository.DeviceRepository; import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper; import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.SourceMapper; import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO; import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity; import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity; import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.repository.TemplateRepository; import com.ycwl.basic.repository.TemplateRepository;
@ -34,7 +33,6 @@ import java.io.InputStreamReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@ -57,6 +55,8 @@ public class VideoPieceGetter {
private OrderBiz orderBiz; private OrderBiz orderBiz;
@Autowired @Autowired
private TemplateRepository templateRepository; private TemplateRepository templateRepository;
@Autowired
private TaskStatusBiz taskStatusBiz;
@Data @Data
public static class Task { public static class Task {
@ -97,6 +97,9 @@ public class VideoPieceGetter {
} else { } else {
templatePlaceholder = null; templatePlaceholder = null;
} }
if (task.faceId != null) {
taskStatusBiz.setFaceCutStatus(task.faceId, 0);
}
AtomicBoolean invoke = new AtomicBoolean(false); AtomicBoolean invoke = new AtomicBoolean(false);
List<String> currentPlaceholder = new ArrayList<>(); List<String> currentPlaceholder = new ArrayList<>();
List<FaceSampleEntity> list = faceSampleMapper.listByIds(task.getFaceSampleIds()); List<FaceSampleEntity> list = faceSampleMapper.listByIds(task.getFaceSampleIds());
@ -113,7 +116,7 @@ public class VideoPieceGetter {
.stream() .stream()
.parallel() .parallel()
.forEach(faceSampleList -> { .forEach(faceSampleList -> {
faceSampleList.forEach(faceSample -> { faceSampleList.parallelStream().forEach(faceSample -> {
DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId()); DeviceEntity device = deviceRepository.getDevice(faceSample.getDeviceId());
DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId()); DeviceConfigEntity config = deviceRepository.getDeviceConfig(faceSample.getDeviceId());
@ -245,6 +248,9 @@ public class VideoPieceGetter {
} }
}); });
}); });
if (task.faceId != null) {
taskStatusBiz.setFaceCutStatus(task.faceId, 1);
}
if (null != task.getCallback()) { if (null != task.getCallback()) {
if (!invoke.get()) { if (!invoke.get()) {
invoke.set(true); invoke.set(true);

View File

@ -4,10 +4,14 @@ import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.biz.TemplateBiz; import com.ycwl.basic.biz.TemplateBiz;
import com.ycwl.basic.mapper.FaceMapper; import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper; import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.ScenicMapper;
import com.ycwl.basic.mapper.TemplateMapper; import com.ycwl.basic.mapper.TemplateMapper;
import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO; import com.ycwl.basic.model.mobile.scenic.content.ContentPageVO;
import com.ycwl.basic.model.pc.face.req.FaceReqQuery; import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO; import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
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.task.resp.SearchFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import com.ycwl.basic.repository.ScenicRepository; import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.TemplateRepository; import com.ycwl.basic.repository.TemplateRepository;
@ -20,6 +24,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -38,18 +43,41 @@ public class VideoTaskGenerator {
private TaskTaskServiceImpl taskTaskService; private TaskTaskServiceImpl taskTaskService;
@Autowired @Autowired
private TemplateMapper templateMapper; private TemplateMapper templateMapper;
@Autowired
private ScenicMapper scenicMapper;
@Autowired
private ScenicRepository scenicRepository;
// TODO: 可配置现在赶时间暂时写死 // TODO: 可配置现在赶时间暂时写死
@Scheduled(cron = "0 0 18 * * *") @Scheduled(cron = "0 0 * * * *")
public void generateVideoTask() { public void generateVideoTask() {
// 指定获取指定日期的未完成人脸样本并生成任务 List<ScenicRespVO> scenicList = scenicMapper.list(new ScenicReqQuery());
Long scenicId = 3946669713328836608L; if (scenicList.isEmpty()) {
return;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
calendar.clear();
scenicList.parallelStream().forEach(scenic -> {
Long scenicId = scenic.getId();
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
if (scenicConfig == null) {
log.info("当前景区{},无配置信息", scenic.getName());
return;
}
if (Integer.valueOf(1).equals(scenicConfig.getBookRoutine()) || Integer.valueOf(3).equals(scenicConfig.getBookRoutine())) {
Integer hour = scenicConfig.getForceFinishTime();
if (hour != currentHour) {
return;
}
// 定时逻辑
List<ContentPageVO> contentList = templateMapper.listFor(scenicId); List<ContentPageVO> contentList = templateMapper.listFor(scenicId);
if (contentList.isEmpty()) { if (contentList.isEmpty()) {
return; return;
} }
Long templateId = contentList.get(0).getTemplateId();
FaceReqQuery query = new FaceReqQuery(); FaceReqQuery query = new FaceReqQuery();
query.setScenicId(scenicId); query.setScenicId(scenicId);
query.setStartTime(DateUtil.beginOfDay(new Date())); query.setStartTime(DateUtil.beginOfDay(new Date()));
@ -57,6 +85,10 @@ public class VideoTaskGenerator {
List<FaceRespVO> list = faceMapper.list(query); List<FaceRespVO> list = faceMapper.list(query);
list.stream().parallel().forEach(face -> { list.stream().parallel().forEach(face -> {
taskFaceService.searchFace(face.getId()); taskFaceService.searchFace(face.getId());
if (Integer.valueOf(3).equals(scenicConfig.getBookRoutine())) {
// 全部生成
contentList.forEach(content -> {
Long templateId = content.getTemplateId();
boolean canAutoGenerate = templateBiz.determineTemplateCanAutoGenerate(templateId, face.getId(), false); boolean canAutoGenerate = templateBiz.determineTemplateCanAutoGenerate(templateId, face.getId(), false);
if (canAutoGenerate) { if (canAutoGenerate) {
log.info("task callback: 自动生成"); log.info("task callback: 自动生成");
@ -65,5 +97,18 @@ public class VideoTaskGenerator {
log.info("task callback: 不自动生成"); log.info("task callback: 不自动生成");
} }
}); });
} else {
Long templateId = contentList.get(0).getTemplateId();
boolean canAutoGenerate = templateBiz.determineTemplateCanAutoGenerate(templateId, face.getId(), false);
if (canAutoGenerate) {
log.info("task callback: 自动生成");
taskTaskService.forceCreateTaskByFaceIdAndTempalteId(face.getId(), templateId);
} else {
log.info("task callback: 不自动生成");
}
}
});
}
});
} }
} }

View File

@ -36,7 +36,8 @@
online_check = #{onlineCheck}, online_check = #{onlineCheck},
online_max_interval = #{onlineMaxInterval}, online_max_interval = #{onlineMaxInterval},
cut_pre = #{cutPre}, cut_pre = #{cutPre},
cut_post = #{cutPost} cut_post = #{cutPost},
enable_pre_book = #{enablePreBook}
where id = #{id} where id = #{id}
</update> </update>
<update id="updateEntity"> <update id="updateEntity">

View File

@ -70,7 +70,7 @@
from face from face
where id = #{id} where id = #{id}
</select> </select>
<select id="getByMemberId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> <select id="getLatestByMemberId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO">
select id, scenic_id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result, create_at, update_at select id, scenic_id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result, create_at, update_at
from face from face
where member_id = #{userId} and scenic_id = #{scenicId} where member_id = #{userId} and scenic_id = #{scenicId}
@ -100,4 +100,11 @@
where member_id = #{userId} and scenic_id = #{scenicId} where member_id = #{userId} and scenic_id = #{scenicId}
order by update_at desc order by update_at desc
</select> </select>
<select id="findLastFaceByScenicAndUserId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO">
select id, scenic_id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result, create_at, update_at
from face
where member_id = #{userId} and scenic_id = #{scenicId}
order by update_at desc
limit 1
</select>
</mapper> </mapper>

View File

@ -101,7 +101,7 @@
from face_sample from face_sample
where id = #{id} where id = #{id}
</select> </select>
<select id="listEntity" resultType="com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity"> <select id="listEntityBeforeDate" resultType="com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity">
select * select *
from face_sample from face_sample
where scenic_id = #{scenicId} and create_at &lt;= #{endDate} where scenic_id = #{scenicId} and create_at &lt;= #{endDate}

View File

@ -94,7 +94,8 @@
disable_source_video=#{disableSourceVideo}, disable_source_video=#{disableSourceVideo},
disable_source_image=#{disableSourceImage}, disable_source_image=#{disableSourceImage},
video_source_store_day=#{videoSourceStoreDay}, video_source_store_day=#{videoSourceStoreDay},
image_source_store_day=#{imageSourceStoreDay} image_source_store_day=#{imageSourceStoreDay},
force_finish_time=#{forceFinishTime}
</set> </set>
where id = #{id} where id = #{id}
</update> </update>