You've already forked FrameTour-BE
							
							指定设备提前预约
This commit is contained in:
		
							
								
								
									
										192
									
								
								src/main/java/com/ycwl/basic/biz/TaskStatusBiz.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								src/main/java/com/ycwl/basic/biz/TaskStatusBiz.java
									
									
									
									
									
										Normal 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; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| package com.ycwl.basic.controller.mobile; | ||||
|  | ||||
| import com.ycwl.basic.annotation.IgnoreToken; | ||||
| import com.ycwl.basic.biz.TaskStatusBiz; | ||||
| import com.ycwl.basic.constant.BaseContextHandler; | ||||
| import com.ycwl.basic.exception.CheckTokenException; | ||||
| import com.ycwl.basic.model.jwt.JwtInfo; | ||||
| @@ -31,6 +32,8 @@ public class AppGoodsController { | ||||
|     private GoodsService goodsService; | ||||
|     @Autowired | ||||
|     private TaskService taskService; | ||||
|     @Autowired | ||||
|     private TaskStatusBiz taskStatusBiz; | ||||
|  | ||||
|     @ApiOperation("商品列表") | ||||
|     @PostMapping("/goodsList") | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package com.ycwl.basic.controller.mobile; | ||||
|  | ||||
| import com.ycwl.basic.annotation.IgnoreLogReq; | ||||
| import com.ycwl.basic.biz.TaskStatusBiz; | ||||
| import com.ycwl.basic.model.jwt.JwtInfo; | ||||
| import com.ycwl.basic.model.mobile.goods.VideoTaskReq; | ||||
| import com.ycwl.basic.model.mobile.goods.VideoTaskStatusVO; | ||||
| @@ -24,6 +25,8 @@ public class AppTaskController { | ||||
|     private GoodsService goodsService; | ||||
|     @Autowired | ||||
|     private TaskService taskService; | ||||
|     @Autowired | ||||
|     private TaskStatusBiz taskStatusBiz; | ||||
|  | ||||
|     @GetMapping("/face/{faceId}") | ||||
|     @IgnoreLogReq | ||||
|   | ||||
| @@ -273,7 +273,9 @@ public class ViidController { | ||||
|                             faceSampleMapper.add(faceSample); | ||||
|                             new Thread(() -> { | ||||
|                                 taskFaceService.addFaceSample(faceSample.getId()); | ||||
|                                 if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) { | ||||
|                                     DynamicTaskGenerator.addTask(faceSample.getId()); | ||||
|                                 } | ||||
|                             }).start(); | ||||
|                             for (SubImageInfoObject _subImage : type14ImageList) { | ||||
|                                 facePosition.setImgHeight(_subImage.getHeight()); | ||||
| @@ -318,7 +320,12 @@ public class ViidController { | ||||
|                             faceSample.setFaceUrl(url); | ||||
|                             faceSampleMapper.add(faceSample); | ||||
|                             DynamicTaskGenerator.addTask(faceSample.getId()); | ||||
|                             new Thread(() -> { | ||||
|                                 taskFaceService.addFaceSample(faceSample.getId()); | ||||
|                                 if (deviceConfig != null && Integer.valueOf(1).equals(deviceConfig.getEnablePreBook())) { | ||||
|                                     DynamicTaskGenerator.addTask(faceSample.getId()); | ||||
|                                 } | ||||
|                             }).start(); | ||||
|                             log.info("模式1人脸信息入库成功!设备ID:{}", deviceID); | ||||
|                         } | ||||
|                     } | ||||
|   | ||||
| @@ -12,8 +12,9 @@ public enum StatisticEnum { | ||||
|     REFUND(5,"退款"), | ||||
|     MESSAGE_PUSH(6,"消息推送"), | ||||
|     DOWNLOAD(8,"下载"), | ||||
|     CLICK_ON_PAYMENT(9,"点击支付、购买"), | ||||
|     CLICK_PAY(9,"点击支付"), | ||||
|     OTHER_ENTER(10,"其他渠道进入"), | ||||
|     SUBMIT_PAYMENT(11,"点击支付"), | ||||
|     SCAN_MARKED_CODE(20,"扫描特殊标记码"), | ||||
|  | ||||
|     ; | ||||
|   | ||||
| @@ -66,7 +66,7 @@ public class AuthInterceptor extends HandlerInterceptorAdapter { | ||||
|         // 获取 token | ||||
|         String token = getToken(request); | ||||
|         if (StringUtils.isEmpty(token)) { | ||||
|             log.error("==>  请求 header 缺少 Token [{}]", token); | ||||
|             log.error("==>  请求 header 缺少 Token [{}], URL [{}]", token, request.getRequestURL()); | ||||
|             throw new MissTokenException("请求头缺少token"); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -24,11 +24,12 @@ public interface FaceMapper { | ||||
|     int deleteByIds(@Param("list") List<Long> ids); | ||||
|     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); | ||||
|  | ||||
|     FaceRespVO findLastFaceByUserId(String userId); | ||||
|     FaceRespVO findLastFaceByScenicAndUserId(Long scenicId, Long userId); | ||||
|  | ||||
|     List<FaceRespVO> listByScenicAndUserId(String scenicId, Long userId); | ||||
| } | ||||
|   | ||||
| @@ -26,5 +26,5 @@ public interface FaceSampleMapper { | ||||
|     List<FaceSampleEntity> listByIds(List<Long> list); | ||||
|  | ||||
|     FaceSampleEntity getEntity(Long faceSampleId); | ||||
|     List<FaceSampleEntity> listEntity(Long scenicId, Date endDate); | ||||
|     List<FaceSampleEntity> listEntityBeforeDate(Long scenicId, Date endDate); | ||||
| } | ||||
|   | ||||
| @@ -57,4 +57,5 @@ public class DeviceConfigEntity { | ||||
|      * 切割时,取人脸后多少秒的视频 | ||||
|      */ | ||||
|     private BigDecimal cutPost; | ||||
|     private Integer enablePreBook; | ||||
| } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; | ||||
| import com.aliyuncs.facebody.model.v20191230.SearchFaceRequest; | ||||
| import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse; | ||||
| import com.baomidou.mybatisplus.annotation.IdType; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import com.ycwl.basic.model.pc.faceDetectLog.resp.MatchLocalRecord; | ||||
| @@ -31,6 +32,9 @@ public class FaceDetectLog { | ||||
|  | ||||
|     private String matchLocalRecord; | ||||
|  | ||||
|     @TableField(exist = false) | ||||
|     private List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> matchRawRecord; | ||||
|  | ||||
|     public static FaceDetectLog quickCreate(String reason) { | ||||
|         FaceDetectLog log = new FaceDetectLog(); | ||||
|         log.reason = reason; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import java.util.Date; | ||||
| @Data | ||||
| public class MatchLocalRecord { | ||||
|     private Long faceSampleId; | ||||
|     private String deviceName; | ||||
|     private String faceUrl; | ||||
|     private Float score; | ||||
|     private Float confidence; | ||||
|   | ||||
| @@ -43,6 +43,7 @@ public class ScenicConfigEntity { | ||||
|      * 预约流程,1-预约,2-在线,3-全部 | ||||
|      */ | ||||
|     private Integer bookRoutine; | ||||
|     private Integer forceFinishTime; | ||||
|     /** | ||||
|      * 样本保存时间 | ||||
|      */ | ||||
|   | ||||
| @@ -5,28 +5,36 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; | ||||
| import java.util.concurrent.Semaphore; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| public class FixedRateLimiter { | ||||
| public class FixedRateLimiter implements IRateLimiter { | ||||
|     private final Semaphore semaphore = new Semaphore(1); | ||||
|     private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); | ||||
|  | ||||
|     public FixedRateLimiter(int rate, TimeUnit timeUnit) { | ||||
|         // 启动一个线程每0.5秒释放一个许可 | ||||
|         scheduler.scheduleAtFixedRate(() -> { | ||||
|             synchronized (semaphore) { | ||||
|             if (semaphore.availablePermits() < 1) { | ||||
|                 semaphore.release(1); | ||||
|             } | ||||
|             } | ||||
|         }, rate, rate, timeUnit); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void acquire() throws InterruptedException { | ||||
|         synchronized (semaphore) { | ||||
|         semaphore.acquire(); | ||||
|     } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void 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); | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								src/main/java/com/ycwl/basic/ratelimiter/IRateLimiter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/main/java/com/ycwl/basic/ratelimiter/IRateLimiter.java
									
									
									
									
									
										Normal 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; | ||||
| } | ||||
| @@ -6,25 +6,45 @@ import java.util.concurrent.Semaphore; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
|  | ||||
| public class SlidingWindowRateLimiter { | ||||
| public class SlidingWindowRateLimiter implements IRateLimiter { | ||||
|     private final Semaphore semaphore; | ||||
|     private final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); | ||||
|  | ||||
|     public SlidingWindowRateLimiter(int maxRequestsPerSecond) { | ||||
|         this.semaphore = new Semaphore(maxRequestsPerSecond); | ||||
|         int rate = 1000000 / maxRequestsPerSecond; | ||||
|         scheduler.scheduleAtFixedRate(() -> { | ||||
|             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 { | ||||
|         semaphore.acquire(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void 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); | ||||
|     } | ||||
| } | ||||
| @@ -346,7 +346,7 @@ public class GoodsServiceImpl implements GoodsService { | ||||
|  | ||||
|     @Override | ||||
|     public VideoTaskStatusVO getTaskStatusByScenicId(Long userId, Long scenicId) { | ||||
|         FaceRespVO faceVO = faceMapper.getByMemberId(userId, scenicId); | ||||
|         FaceRespVO faceVO = faceMapper.getLatestByMemberId(userId, scenicId); | ||||
|         VideoTaskStatusVO response = new VideoTaskStatusVO(); | ||||
|         response.setScenicId(scenicId); | ||||
|         if (faceVO == null) { | ||||
|   | ||||
| @@ -326,14 +326,6 @@ public class OrderServiceImpl implements OrderService { | ||||
|             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); | ||||
|         return ApiResponse.success(wxPayRespVO); | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| package com.ycwl.basic.service.task.impl; | ||||
|  | ||||
| import cn.hutool.core.date.DateUtil; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import com.aliyuncs.exceptions.ClientException; | ||||
| import com.aliyuncs.exceptions.ServerException; | ||||
| import com.aliyuncs.facebody.model.v20191230.AddFaceEntityRequest; | ||||
| import com.aliyuncs.facebody.model.v20191230.AddFaceRequest; | ||||
| 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.SearchFaceRequest; | ||||
| 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.config.FaceDetectConfig; | ||||
| 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.SourceMapper; | ||||
| 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.resp.FaceRespVO; | ||||
| import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLog; | ||||
| 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.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.entity.MemberSourceEntity; | ||||
| import com.ycwl.basic.model.pc.source.entity.SourceEntity; | ||||
| import com.ycwl.basic.model.task.resp.AddFaceSampleRespVo; | ||||
| import com.ycwl.basic.model.task.resp.SearchFaceRespVo; | ||||
| 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.ScenicRepository; | ||||
| import com.ycwl.basic.service.task.TaskFaceService; | ||||
| @@ -55,7 +50,6 @@ import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.redis.core.RedisTemplate; | ||||
| import org.springframework.scheduling.annotation.Scheduled; | ||||
| import org.springframework.stereotype.Service; | ||||
| import com.aliyuncs.DefaultAcsClient; | ||||
| import com.aliyuncs.IAcsClient; | ||||
| @@ -103,6 +97,8 @@ public class TaskFaceServiceImpl implements TaskFaceService { | ||||
|  | ||||
|     @Autowired | ||||
|     private ScenicRepository scenicRepository; | ||||
|     @Autowired | ||||
|     private DeviceRepository deviceRepository; | ||||
|  | ||||
|     private IAcsClient getClient() { | ||||
|         DefaultProfile profile = DefaultProfile.getProfile( | ||||
| @@ -195,29 +191,13 @@ public class TaskFaceServiceImpl implements TaskFaceService { | ||||
|             if (matchList.get(0).getFaceItems().isEmpty()) { | ||||
|                 return respVo; | ||||
|             } | ||||
|             List<MatchLocalRecord> records = matchList.get(0).getFaceItems().stream() | ||||
|                     .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) { | ||||
|                                 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<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> records = matchList.get(0).getFaceItems(); | ||||
|             log.setMatchRawRecord(records); | ||||
|             List<Long> faceSampleIds = records.stream() | ||||
|                     .filter(record -> record.getScore() > 0.525F) | ||||
|                     .map(MatchLocalRecord::getFaceSampleId) | ||||
|                     .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData) | ||||
|                     .filter(StringUtils::isNumeric) | ||||
|                     .map(Long::valueOf) | ||||
|                     .collect(Collectors.toList()); | ||||
|             respVo.setFirstMatchRate(matchList.get(0).getFaceItems().get(0).getScore()); | ||||
|             respVo.setSampleListIds(faceSampleIds); | ||||
| @@ -227,7 +207,33 @@ public class TaskFaceServiceImpl implements TaskFaceService { | ||||
|             e.printStackTrace(); | ||||
|             throw new BaseException(e.getMessage()); | ||||
|         } 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); | ||||
|             }).start(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -289,20 +295,6 @@ public class TaskFaceServiceImpl implements TaskFaceService { | ||||
|             sampleStoreDay = 7; | ||||
|         } | ||||
|         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.setDbName(String.valueOf(scenicId)); | ||||
|         listFaceEntitiesRequest.setOrder("asc"); | ||||
| @@ -342,6 +334,20 @@ public class TaskFaceServiceImpl implements TaskFaceService { | ||||
|             } | ||||
|         } 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 | ||||
|   | ||||
| @@ -345,7 +345,8 @@ public class TaskTaskServiceImpl implements TaskService { | ||||
|         if (templateList == null || templateList.isEmpty()) { | ||||
|             return; | ||||
|         } | ||||
|         if (Integer.valueOf(3).equals(scenicConfig.getBookRoutine())) { | ||||
|         if (Integer.valueOf(3).equals(scenicConfig.getBookRoutine()) || Integer.valueOf(4).equals(scenicConfig.getBookRoutine())) { | ||||
|             // 生成全部视频的逻辑 | ||||
|             templateList.forEach(template -> { | ||||
|                 createTaskByFaceIdAndTempalteId(faceId, template.getId(), 1); | ||||
|             }); | ||||
|   | ||||
| @@ -90,7 +90,7 @@ public class DynamicTaskGenerator { | ||||
|         queue.add(new Task(faceSampleId, createTime)); | ||||
|     } | ||||
|  | ||||
|     @Scheduled(fixedDelay = 500L) | ||||
|     @Scheduled(fixedDelay = 1000L) | ||||
|     public void doTask() { | ||||
|         Task task = queue.poll(); | ||||
|         if (task == null) { | ||||
| @@ -111,7 +111,7 @@ public class DynamicTaskGenerator { | ||||
|             log.debug("当前景区{},无配置", faceSample.getScenicId()); | ||||
|             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()); | ||||
|             return; | ||||
|         } | ||||
|   | ||||
| @@ -3,10 +3,15 @@ package com.ycwl.basic.task; | ||||
| 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.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.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.storage.StorageFactory; | ||||
| import com.ycwl.basic.storage.adapters.IStorageAdapter; | ||||
| @@ -31,6 +36,10 @@ public class FaceCleaner { | ||||
|     private FaceSampleMapper faceSampleMapper; | ||||
|     @Autowired | ||||
|     private SourceMapper sourceMapper; | ||||
|     @Autowired | ||||
|     private VideoMapper videoMapper; | ||||
|     @Autowired | ||||
|     private ScenicRepository scenicRepository; | ||||
|  | ||||
|     @Scheduled(cron = "0 0 4 * * ?") | ||||
|     public void clean(){ | ||||
| @@ -44,11 +53,43 @@ public class FaceCleaner { | ||||
|  | ||||
|     @Scheduled(cron = "0 0 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()); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Scheduled(cron = "0 0 5 * * ?") | ||||
|     public void clear(){ | ||||
|     public void clearOss(){ | ||||
|         cleanFaceSampleOss(); | ||||
|         cleanSourceOss(); | ||||
|         cleanVideoOss(); | ||||
|     } | ||||
|     private void cleanFaceSampleOss() { | ||||
|         log.info("开始清理人脸文件"); | ||||
|         List<FaceSampleRespVO> faceSampleRespVOS = faceSampleMapper.list(new FaceSampleReqQuery()); | ||||
|         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); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,18 +1,17 @@ | ||||
| package com.ycwl.basic.task; | ||||
|  | ||||
| import com.ycwl.basic.biz.OrderBiz; | ||||
| import com.ycwl.basic.biz.TaskStatusBiz; | ||||
| import com.ycwl.basic.device.DeviceFactory; | ||||
| import com.ycwl.basic.device.entity.common.FileObject; | ||||
| import com.ycwl.basic.device.operator.IDeviceStorageOperator; | ||||
| import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; | ||||
| import com.ycwl.basic.repository.DeviceRepository; | ||||
| import com.ycwl.basic.mapper.DeviceMapper; | ||||
| import com.ycwl.basic.mapper.FaceSampleMapper; | ||||
| import com.ycwl.basic.mapper.SourceMapper; | ||||
| 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.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.SourceEntity; | ||||
| import com.ycwl.basic.repository.TemplateRepository; | ||||
| @@ -34,7 +33,6 @@ import java.io.InputStreamReader; | ||||
| import java.math.BigDecimal; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.Comparator; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| @@ -57,6 +55,8 @@ public class VideoPieceGetter { | ||||
|     private OrderBiz orderBiz; | ||||
|     @Autowired | ||||
|     private TemplateRepository templateRepository; | ||||
|     @Autowired | ||||
|     private TaskStatusBiz taskStatusBiz; | ||||
|  | ||||
|     @Data | ||||
|     public static class Task { | ||||
| @@ -97,6 +97,9 @@ public class VideoPieceGetter { | ||||
|         } else { | ||||
|             templatePlaceholder = null; | ||||
|         } | ||||
|         if (task.faceId != null) { | ||||
|             taskStatusBiz.setFaceCutStatus(task.faceId, 0); | ||||
|         } | ||||
|         AtomicBoolean invoke = new AtomicBoolean(false); | ||||
|         List<String> currentPlaceholder = new ArrayList<>(); | ||||
|         List<FaceSampleEntity> list = faceSampleMapper.listByIds(task.getFaceSampleIds()); | ||||
| @@ -113,7 +116,7 @@ public class VideoPieceGetter { | ||||
|                 .stream() | ||||
|                 .parallel() | ||||
|                 .forEach(faceSampleList -> { | ||||
|                     faceSampleList.forEach(faceSample -> { | ||||
|                     faceSampleList.parallelStream().forEach(faceSample -> { | ||||
|                         DeviceEntity device = deviceRepository.getDevice(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 (!invoke.get()) { | ||||
|                 invoke.set(true); | ||||
|   | ||||
| @@ -4,10 +4,14 @@ import cn.hutool.core.date.DateUtil; | ||||
| import com.ycwl.basic.biz.TemplateBiz; | ||||
| import com.ycwl.basic.mapper.FaceMapper; | ||||
| import com.ycwl.basic.mapper.FaceSampleMapper; | ||||
| import com.ycwl.basic.mapper.ScenicMapper; | ||||
| import com.ycwl.basic.mapper.TemplateMapper; | ||||
| 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.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.repository.ScenicRepository; | ||||
| 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.stereotype.Component; | ||||
|  | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -38,18 +43,41 @@ public class VideoTaskGenerator { | ||||
|     private TaskTaskServiceImpl taskTaskService; | ||||
|     @Autowired | ||||
|     private TemplateMapper templateMapper; | ||||
|     @Autowired | ||||
|     private ScenicMapper scenicMapper; | ||||
|     @Autowired | ||||
|     private ScenicRepository scenicRepository; | ||||
|  | ||||
|     // TODO: 可配置,现在赶时间暂时写死 | ||||
|  | ||||
|     @Scheduled(cron = "0 0 18 * * *") | ||||
|     @Scheduled(cron = "0 0 * * * *") | ||||
|     public void generateVideoTask() { | ||||
|         // 指定,获取指定日期的未完成人脸样本,并生成任务 | ||||
|         Long scenicId = 3946669713328836608L; | ||||
|         List<ScenicRespVO> scenicList = scenicMapper.list(new ScenicReqQuery()); | ||||
|         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); | ||||
|                 if (contentList.isEmpty()) { | ||||
|                     return; | ||||
|                 } | ||||
|         Long templateId = contentList.get(0).getTemplateId(); | ||||
|                 FaceReqQuery query = new FaceReqQuery(); | ||||
|                 query.setScenicId(scenicId); | ||||
|                 query.setStartTime(DateUtil.beginOfDay(new Date())); | ||||
| @@ -57,6 +85,10 @@ public class VideoTaskGenerator { | ||||
|                 List<FaceRespVO> list = faceMapper.list(query); | ||||
|                 list.stream().parallel().forEach(face -> { | ||||
|                     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); | ||||
|                             if (canAutoGenerate) { | ||||
|                                 log.info("task callback: 自动生成"); | ||||
| @@ -65,5 +97,18 @@ public class VideoTaskGenerator { | ||||
|                                 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: 不自动生成"); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -36,7 +36,8 @@ | ||||
|             online_check = #{onlineCheck}, | ||||
|             online_max_interval = #{onlineMaxInterval}, | ||||
|             cut_pre = #{cutPre}, | ||||
|             cut_post = #{cutPost} | ||||
|             cut_post = #{cutPost}, | ||||
|             enable_pre_book = #{enablePreBook} | ||||
|         where id = #{id} | ||||
|     </update> | ||||
|     <update id="updateEntity"> | ||||
|   | ||||
| @@ -70,7 +70,7 @@ | ||||
|         from face | ||||
|         where id = #{id} | ||||
|     </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 | ||||
|         from face | ||||
|         where member_id = #{userId} and scenic_id = #{scenicId} | ||||
| @@ -100,4 +100,11 @@ | ||||
|         where member_id = #{userId} and scenic_id = #{scenicId} | ||||
|         order by update_at desc | ||||
|     </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> | ||||
|   | ||||
| @@ -101,7 +101,7 @@ | ||||
|         from face_sample | ||||
|         where id = #{id} | ||||
|     </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 * | ||||
|         from face_sample | ||||
|         where scenic_id = #{scenicId} and create_at <= #{endDate} | ||||
|   | ||||
| @@ -94,7 +94,8 @@ | ||||
|             disable_source_video=#{disableSourceVideo}, | ||||
|             disable_source_image=#{disableSourceImage}, | ||||
|             video_source_store_day=#{videoSourceStoreDay}, | ||||
|             image_source_store_day=#{imageSourceStoreDay} | ||||
|             image_source_store_day=#{imageSourceStoreDay}, | ||||
|             force_finish_time=#{forceFinishTime} | ||||
|         </set> | ||||
|         where id = #{id} | ||||
|     </update> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user