You've already forked FrameTour-BE
							
							获取人脸对应视频流程,自动删除源视频流程,自动创建任务渲染流程,自动删除人脸数据逻辑
This commit is contained in:
		
							
								
								
									
										45
									
								
								src/main/java/com/ycwl/basic/device/DeviceFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/main/java/com/ycwl/basic/device/DeviceFactory.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | package com.ycwl.basic.device; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.checker.IDeviceStatusChecker; | ||||||
|  | import com.ycwl.basic.device.checker.impl.AliOssDeviceChecker; | ||||||
|  | import com.ycwl.basic.device.checker.impl.AlwaysOnDeviceChecker; | ||||||
|  | import com.ycwl.basic.device.enums.DeviceStoreTypeEnum; | ||||||
|  | import com.ycwl.basic.device.operator.IDeviceStorageOperator; | ||||||
|  | import com.ycwl.basic.device.operator.impl.AliOssStorageOperator; | ||||||
|  | import com.ycwl.basic.device.operator.impl.LocalStorageOperator; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceEntity; | ||||||
|  |  | ||||||
|  | public class DeviceFactory { | ||||||
|  |     public static IDeviceStorageOperator getDeviceStorageOperator(DeviceEntity device, DeviceConfigEntity config) { | ||||||
|  |         IDeviceStorageOperator operator = null; | ||||||
|  |         if (config.getStoreType() == DeviceStoreTypeEnum.ALI_OSS.getType()) { | ||||||
|  |             operator = new AliOssStorageOperator(config.getStoreConfigJson()); | ||||||
|  |         } else if (config.getStoreType() == DeviceStoreTypeEnum.LOCAL.getType()) { | ||||||
|  |             operator = new LocalStorageOperator(config.getStoreConfigJson()); | ||||||
|  |         } | ||||||
|  |         if (operator == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         operator.setDevice(device); | ||||||
|  |         operator.setDeviceConfig(config); | ||||||
|  |         return operator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static IDeviceStatusChecker getDeviceStatusChecker(DeviceEntity device, DeviceConfigEntity config) { | ||||||
|  |         IDeviceStatusChecker checker = null; | ||||||
|  |         if (config.getOnlineCheck() <= 0) { | ||||||
|  |             checker = new AlwaysOnDeviceChecker(); | ||||||
|  |         } else { | ||||||
|  |             if (config.getStoreType() == DeviceStoreTypeEnum.ALI_OSS.getType()) { | ||||||
|  |                 checker = new AliOssDeviceChecker(config.getStoreConfigJson()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (checker == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         checker.setDevice(device); | ||||||
|  |         checker.setDeviceConfig(config); | ||||||
|  |         return checker; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								src/main/java/com/ycwl/basic/device/IDeviceCommon.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/main/java/com/ycwl/basic/device/IDeviceCommon.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | package com.ycwl.basic.device; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceEntity; | ||||||
|  |  | ||||||
|  | public interface IDeviceCommon { | ||||||
|  |     void setDevice(DeviceEntity device); | ||||||
|  |     void setDeviceConfig(DeviceConfigEntity config); | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package com.ycwl.basic.device.checker; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.IDeviceCommon; | ||||||
|  |  | ||||||
|  | public interface IDeviceStatusChecker extends IDeviceCommon { | ||||||
|  |     boolean checkDeviceStatus(); | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package com.ycwl.basic.device.checker.helper; | ||||||
|  |  | ||||||
|  | import com.alibaba.fastjson.JSON; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceEntity; | ||||||
|  | import lombok.Setter; | ||||||
|  |  | ||||||
|  | public abstract class CommonDeviceChecker<C> { | ||||||
|  |     protected C config; | ||||||
|  |     @Setter | ||||||
|  |     protected DeviceEntity device; | ||||||
|  |     @Setter | ||||||
|  |     protected DeviceConfigEntity deviceConfig; | ||||||
|  |  | ||||||
|  |     public CommonDeviceChecker(String configJson) { | ||||||
|  |         config = JSON.parseObject(configJson, getConfigClass()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("unchecked") | ||||||
|  |     private Class<C> getConfigClass() { | ||||||
|  |         return (Class<C>) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,88 @@ | |||||||
|  | package com.ycwl.basic.device.checker.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.date.DateUtil; | ||||||
|  | import com.aliyun.oss.OSS; | ||||||
|  | import com.aliyun.oss.OSSClientBuilder; | ||||||
|  | import com.aliyun.oss.OSSException; | ||||||
|  | import com.aliyun.oss.model.ListObjectsV2Request; | ||||||
|  | import com.aliyun.oss.model.ListObjectsV2Result; | ||||||
|  | import com.aliyun.oss.model.OSSObjectSummary; | ||||||
|  | import com.ycwl.basic.device.checker.IDeviceStatusChecker; | ||||||
|  | import com.ycwl.basic.device.checker.helper.CommonDeviceChecker; | ||||||
|  | import com.ycwl.basic.device.entity.alioss.DeviceAliOssConfig; | ||||||
|  | import com.ycwl.basic.device.entity.common.FileObject; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
|  | @Slf4j | ||||||
|  | public class AliOssDeviceChecker extends CommonDeviceChecker<DeviceAliOssConfig> implements IDeviceStatusChecker { | ||||||
|  |     public AliOssDeviceChecker(String configJson) { | ||||||
|  |         super(configJson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private OSS getClient() { | ||||||
|  |         return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private List<FileObject> getOssFileListByPrefix(String prefix) { | ||||||
|  |         OSS ossClient = getClient(); | ||||||
|  |         ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName()); | ||||||
|  |         listObjectsV2Request.setPrefix(config.getPrefix() + prefix); | ||||||
|  |         boolean isTruncated = true; | ||||||
|  |         String continuationToken = null; | ||||||
|  |         List<OSSObjectSummary> objectList = new ArrayList<>(); | ||||||
|  |         try { | ||||||
|  |             while (isTruncated) { | ||||||
|  |                 if (continuationToken != null) { | ||||||
|  |                     listObjectsV2Request.setContinuationToken(continuationToken); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // 列举文件。 | ||||||
|  |                 ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request); | ||||||
|  |  | ||||||
|  |                 objectList.addAll(result.getObjectSummaries()); | ||||||
|  |  | ||||||
|  |                 isTruncated = result.isTruncated(); | ||||||
|  |                 continuationToken = result.getNextContinuationToken(); | ||||||
|  |             } | ||||||
|  |             return objectList.stream().filter(item -> item.getKey().endsWith(".ts")).map(item -> { | ||||||
|  |                 FileObject object = new FileObject(); | ||||||
|  |                 object.setPath(item.getKey()); | ||||||
|  |                 object.setNeedDownload(true); | ||||||
|  |                 String[] splitDir = item.getKey().split("/"); | ||||||
|  |                 String splitDate = splitDir[splitDir.length - 2]; | ||||||
|  |                 String splitName = splitDir[splitDir.length - 1]; | ||||||
|  |                 String[] splitExt = splitName.split("\\.", 2); | ||||||
|  |                 String[] splitDt = splitExt[0].split("_", 2); | ||||||
|  |                 String createTime = splitDt[0]; | ||||||
|  |                 String endTime = splitDt[1]; | ||||||
|  |                 object.setName(splitName); | ||||||
|  |                 object.setEndTime(DateUtil.parse(splitDate+endTime, "yyyyMMddHHmmss")); | ||||||
|  |                 object.setCreateTime(DateUtil.parse(splitDate+createTime, "yyyyMMddHHmmss")); | ||||||
|  |                 return object; | ||||||
|  |             }).collect(Collectors.toList()); | ||||||
|  |         } catch (OSSException e) { | ||||||
|  |             log.error("获取OSS文件列表失败", e); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |     @Override | ||||||
|  |     public boolean checkDeviceStatus() { | ||||||
|  |         Date now = new Date(); | ||||||
|  |         if (deviceConfig.getOnlineMaxInterval() == null) { | ||||||
|  |             // 没有合适配置 | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         Date startTime = DateUtil.offsetMinute(now, -deviceConfig.getOnlineMaxInterval()); | ||||||
|  |         List<FileObject> fileList = getOssFileListByPrefix(DateUtil.format(startTime, "yyyyMMdd/HHmm")); | ||||||
|  |         if (fileList != null) { | ||||||
|  |             return !fileList.isEmpty(); | ||||||
|  |         } else { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package com.ycwl.basic.device.checker.impl; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.checker.IDeviceStatusChecker; | ||||||
|  | import com.ycwl.basic.device.checker.helper.CommonDeviceChecker; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceEntity; | ||||||
|  | import lombok.Setter; | ||||||
|  |  | ||||||
|  | @SuppressWarnings("LombokSetterMayBeUsed") | ||||||
|  | public class AlwaysOnDeviceChecker implements IDeviceStatusChecker { | ||||||
|  |     @Setter | ||||||
|  |     private DeviceEntity device; | ||||||
|  |     @Setter | ||||||
|  |     private DeviceConfigEntity deviceConfig; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean checkDeviceStatus() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,14 @@ | |||||||
|  | package com.ycwl.basic.device.entity.alioss; | ||||||
|  |  | ||||||
|  | import lombok.Data; | ||||||
|  | import org.apache.commons.lang3.StringUtils; | ||||||
|  |  | ||||||
|  | @Data | ||||||
|  | public class DeviceAliOssConfig { | ||||||
|  |     private String accessKeyId; | ||||||
|  |     private String accessKeySecret; | ||||||
|  |     private String bucketName; | ||||||
|  |     private String endpoint; | ||||||
|  |     private String region; | ||||||
|  |     private String prefix; | ||||||
|  | } | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | package com.ycwl.basic.device.entity.common; | ||||||
|  |  | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | import java.util.Date; | ||||||
|  |  | ||||||
|  | @Data | ||||||
|  | public class FileObject { | ||||||
|  |     private String path; | ||||||
|  |     private String name; | ||||||
|  |     private String url; | ||||||
|  |     private boolean needDownload = false; | ||||||
|  |     private Date createTime; | ||||||
|  |     private Date endTime; | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package com.ycwl.basic.device.entity.local; | ||||||
|  |  | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | @Data | ||||||
|  | public class DeviceLocalConfig { | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package com.ycwl.basic.device.enums; | ||||||
|  |  | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | @Getter | ||||||
|  | @AllArgsConstructor | ||||||
|  | public enum DeviceStoreTypeEnum { | ||||||
|  |     ALI_OSS(1, "阿里云OSS"), | ||||||
|  |     LOCAL(2, "本地文件"); | ||||||
|  |  | ||||||
|  |     private final int type; | ||||||
|  |     private final String remark; | ||||||
|  |  | ||||||
|  |     public static DeviceStoreTypeEnum getByType(int type) { | ||||||
|  |         for (DeviceStoreTypeEnum e : values()) { | ||||||
|  |             if (e.type == type) { | ||||||
|  |                 return e; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package com.ycwl.basic.device.operator; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.IDeviceCommon; | ||||||
|  | import com.ycwl.basic.device.entity.common.FileObject; | ||||||
|  |  | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public interface IDeviceStorageOperator extends IDeviceCommon { | ||||||
|  |     /** | ||||||
|  |      * 获取指定时间范围内的文件列表 | ||||||
|  |      * | ||||||
|  |      * @param startDate 开始时间 | ||||||
|  |      * @param endDate   结束时间 | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     List<FileObject> getFileListByDtRange(Date startDate, Date endDate); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 删除指定日期之前的文件,不包含指定的日期当天 | ||||||
|  |      * | ||||||
|  |      * @param date 指定日期,不包含指定日期当天 | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     boolean removeFilesBeforeDate(Date date); | ||||||
|  | } | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | package com.ycwl.basic.device.operator.helper; | ||||||
|  |  | ||||||
|  | import com.alibaba.fastjson.JSON; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceEntity; | ||||||
|  | import lombok.Setter; | ||||||
|  |  | ||||||
|  | public abstract class CommonPieceGetter<C> { | ||||||
|  |     protected C config; | ||||||
|  |     @Setter | ||||||
|  |     private DeviceEntity device; | ||||||
|  |     @Setter | ||||||
|  |     private DeviceConfigEntity deviceConfig; | ||||||
|  |  | ||||||
|  |     public CommonPieceGetter(String configJson) { | ||||||
|  |         config = JSON.parseObject(configJson, getConfigClass()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("unchecked") | ||||||
|  |     private Class<C> getConfigClass() { | ||||||
|  |         return (Class<C>) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,151 @@ | |||||||
|  | package com.ycwl.basic.device.operator.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.date.DateUtil; | ||||||
|  | import com.aliyun.oss.HttpMethod; | ||||||
|  | import com.aliyun.oss.OSS; | ||||||
|  | import com.aliyun.oss.OSSClientBuilder; | ||||||
|  | import com.aliyun.oss.OSSException; | ||||||
|  | import com.aliyun.oss.model.DeleteObjectsRequest; | ||||||
|  | import com.aliyun.oss.model.ListObjectsV2Request; | ||||||
|  | import com.aliyun.oss.model.ListObjectsV2Result; | ||||||
|  | import com.aliyun.oss.model.OSSObjectSummary; | ||||||
|  | import com.ycwl.basic.device.entity.alioss.DeviceAliOssConfig; | ||||||
|  | import com.ycwl.basic.device.entity.common.FileObject; | ||||||
|  | import com.ycwl.basic.device.operator.IDeviceStorageOperator; | ||||||
|  | import com.ycwl.basic.device.operator.helper.CommonPieceGetter; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
|  | import java.net.URL; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Calendar; | ||||||
|  | import java.util.Comparator; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
|  | @Slf4j | ||||||
|  | public class AliOssStorageOperator extends CommonPieceGetter<DeviceAliOssConfig> implements IDeviceStorageOperator { | ||||||
|  |     public AliOssStorageOperator(String configJson) { | ||||||
|  |         super(configJson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private OSS getClient() { | ||||||
|  |         return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private List<OSSObjectSummary> getOssObjectListByPrefix(String prefix) { | ||||||
|  |         OSS ossClient = getClient(); | ||||||
|  |         ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName()); | ||||||
|  |         listObjectsV2Request.setPrefix(config.getPrefix() + prefix); | ||||||
|  |         boolean isTruncated = true; | ||||||
|  |         String continuationToken = null; | ||||||
|  |         List<OSSObjectSummary> objectList = new ArrayList<>(); | ||||||
|  |         try { | ||||||
|  |             while (isTruncated) { | ||||||
|  |                 if (continuationToken != null) { | ||||||
|  |                     listObjectsV2Request.setContinuationToken(continuationToken); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // 列举文件。 | ||||||
|  |                 ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request); | ||||||
|  |  | ||||||
|  |                 objectList.addAll(result.getObjectSummaries()); | ||||||
|  |  | ||||||
|  |                 isTruncated = result.isTruncated(); | ||||||
|  |                 continuationToken = result.getNextContinuationToken(); | ||||||
|  |             } | ||||||
|  |             return objectList; | ||||||
|  |         } catch (OSSException e) { | ||||||
|  |             log.error("获取OSS文件列表失败", e); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private List<FileObject> getOssFileListByPrefix(String prefix) { | ||||||
|  |         OSS ossClient = getClient(); | ||||||
|  |         List<OSSObjectSummary> objectList = getOssObjectListByPrefix(prefix); | ||||||
|  |         if (objectList == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         return objectList.stream().filter(item -> item.getKey().endsWith(".ts")).map(item -> { | ||||||
|  |             FileObject object = new FileObject(); | ||||||
|  |             object.setPath(item.getKey()); | ||||||
|  |             URL url = ossClient.generatePresignedUrl(item.getBucketName(), item.getKey(), DateUtil.offsetHour(new Date(), 8), HttpMethod.GET); | ||||||
|  |             object.setUrl(url.toString()); | ||||||
|  |             object.setNeedDownload(true); | ||||||
|  |             String[] splitDir = item.getKey().split("/"); | ||||||
|  |             String splitDate = splitDir[splitDir.length - 2]; | ||||||
|  |             String splitName = splitDir[splitDir.length - 1]; | ||||||
|  |             String[] splitExt = splitName.split("\\.", 2); | ||||||
|  |             String[] splitDt = splitExt[0].split("_", 2); | ||||||
|  |             String createTime = splitDt[0]; | ||||||
|  |             String endTime = splitDt[1]; | ||||||
|  |             object.setName(splitName); | ||||||
|  |             object.setEndTime(DateUtil.parse(splitDate+endTime, "yyyyMMddHHmmss")); | ||||||
|  |             object.setCreateTime(DateUtil.parse(splitDate+createTime, "yyyyMMddHHmmss")); | ||||||
|  |             return object; | ||||||
|  |         }).collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private boolean removeFilesByPrefix(String prefix) { | ||||||
|  |         OSS ossClient = getClient(); | ||||||
|  |         List<OSSObjectSummary> objectList = getOssObjectListByPrefix(prefix); | ||||||
|  |         if (objectList == null) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         DeleteObjectsRequest request = new DeleteObjectsRequest(config.getBucketName()); | ||||||
|  |         request.setKeys(objectList.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList())); | ||||||
|  |         try { | ||||||
|  |             ossClient.deleteObjects(request); | ||||||
|  |             return true; | ||||||
|  |         } catch (OSSException e) { | ||||||
|  |             return false; | ||||||
|  |         } finally { | ||||||
|  |             ossClient.shutdown(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<FileObject> getFileListByDtRange(Date startDate, Date endDate) { | ||||||
|  |         if (startDate == null || endDate == null) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |         List<FileObject> fileList = new ArrayList<>(); | ||||||
|  |         if (startDate.after(endDate)) { | ||||||
|  |             return fileList; | ||||||
|  |         } | ||||||
|  |         Calendar calendar = Calendar.getInstance(); | ||||||
|  |         calendar.setTime(startDate); | ||||||
|  |         calendar.set(Calendar.SECOND, 0); | ||||||
|  |         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd/HHmm"); | ||||||
|  |         while (calendar.getTime().before(endDate)) { | ||||||
|  |             String prefix = dateFormat.format(calendar.getTime()); | ||||||
|  |             List<FileObject> fileListByPrefix = getOssFileListByPrefix(prefix); | ||||||
|  |             if (fileListByPrefix == null) { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             fileList.addAll(fileListByPrefix); | ||||||
|  |             calendar.add(Calendar.MINUTE, 1); | ||||||
|  |         } | ||||||
|  |         calendar.clear(); | ||||||
|  |         return fileList.stream() | ||||||
|  |                 .sorted(Comparator.comparing(FileObject::getCreateTime)) | ||||||
|  |                 .filter(item -> item.getCreateTime().after(startDate)) | ||||||
|  |                 .filter(item -> item.getCreateTime().before(endDate)) | ||||||
|  |                 .collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean removeFilesBeforeDate(Date date) { | ||||||
|  |         Calendar calendar = Calendar.getInstance(); | ||||||
|  |         calendar.setTime(date); | ||||||
|  |         calendar.set(Calendar.SECOND, 0); | ||||||
|  |         calendar.set(Calendar.MINUTE, 0); | ||||||
|  |         calendar.set(Calendar.HOUR_OF_DAY, 0); | ||||||
|  |         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd/"); | ||||||
|  |         calendar.add(Calendar.DAY_OF_MONTH, -1); | ||||||
|  |         String prefix = dateFormat.format(calendar.getTime()); | ||||||
|  |         return removeFilesByPrefix(prefix); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | package com.ycwl.basic.device.operator.impl; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.entity.common.FileObject; | ||||||
|  | import com.ycwl.basic.device.entity.local.DeviceLocalConfig; | ||||||
|  | import com.ycwl.basic.device.operator.IDeviceStorageOperator; | ||||||
|  | import com.ycwl.basic.device.operator.helper.CommonPieceGetter; | ||||||
|  |  | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public class LocalStorageOperator extends CommonPieceGetter<DeviceLocalConfig> implements IDeviceStorageOperator { | ||||||
|  |     public LocalStorageOperator(String configJson) { | ||||||
|  |         super(configJson); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<FileObject> getFileListByDtRange(Date startDate, Date endDate) { | ||||||
|  |         return Collections.emptyList(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean removeFilesBeforeDate(Date date) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,6 +1,7 @@ | |||||||
| package com.ycwl.basic.mapper.pc; | package com.ycwl.basic.mapper.pc; | ||||||
|  |  | ||||||
| import com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO; | import com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO; | ||||||
|  | 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.device.req.DeviceAddOrUpdateReq; | import com.ycwl.basic.model.pc.device.req.DeviceAddOrUpdateReq; | ||||||
| import com.ycwl.basic.model.pc.device.req.DeviceReqQuery; | import com.ycwl.basic.model.pc.device.req.DeviceReqQuery; | ||||||
| @@ -24,7 +25,10 @@ public interface DeviceMapper { | |||||||
|     int update(DeviceAddOrUpdateReq deviceReqQuery); |     int update(DeviceAddOrUpdateReq deviceReqQuery); | ||||||
|     int updateStatus(Long id); |     int updateStatus(Long id); | ||||||
|  |  | ||||||
|  |     DeviceEntity getByDeviceId(Long deviceId); | ||||||
|     List<DeviceRespVO> listByScenicId(Long scenicId); |     List<DeviceRespVO> listByScenicId(Long scenicId); | ||||||
|  |  | ||||||
|     ScenicDeviceCountVO deviceCountByScenicId(@Param("scenicId") Long scenicId,@Param("userId") Long userId); |     ScenicDeviceCountVO deviceCountByScenicId(@Param("scenicId") Long scenicId,@Param("userId") Long userId); | ||||||
|  |  | ||||||
|  |     DeviceConfigEntity getConfigByDeviceId(Long deviceId); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import java.util.List; | |||||||
| @Mapper | @Mapper | ||||||
| public interface FaceMapper { | public interface FaceMapper { | ||||||
|     List<FaceRespVO> list(FaceReqQuery faceReqQuery); |     List<FaceRespVO> list(FaceReqQuery faceReqQuery); | ||||||
|  |     List<FaceRespVO> listByScenicIdAndNotFinished(Long scenicId); | ||||||
|     FaceRespVO getById(Long id); |     FaceRespVO getById(Long id); | ||||||
|     int add(FaceEntity face); |     int add(FaceEntity face); | ||||||
|     int deleteById(Long id); |     int deleteById(Long id); | ||||||
| @@ -23,4 +24,6 @@ public interface FaceMapper { | |||||||
|     int update(FaceEntity face); |     int update(FaceEntity face); | ||||||
|  |  | ||||||
|     FaceRespVO getByMemberId(Long userId); |     FaceRespVO getByMemberId(Long userId); | ||||||
|  |  | ||||||
|  |     int finishedJourney(Long faceId); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,4 +21,6 @@ public interface FaceSampleMapper { | |||||||
|     int deleteById(Long id); |     int deleteById(Long id); | ||||||
|     int deleteByIds(@Param("list") List<Long> ids); |     int deleteByIds(@Param("list") List<Long> ids); | ||||||
|     int update(FaceSampleEntity faceSample); |     int update(FaceSampleEntity faceSample); | ||||||
|  |  | ||||||
|  |     List<FaceSampleRespVO> listByIds(List<Long> list); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ public interface ScenicMapper { | |||||||
|  |  | ||||||
|     int updateStatus(Long id); |     int updateStatus(Long id); | ||||||
|  |  | ||||||
|  |     ScenicConfigEntity getConfig(Long scenicId); | ||||||
|     /** |     /** | ||||||
|      * 添加景区配置 |      * 添加景区配置 | ||||||
|      * |      * | ||||||
| @@ -51,7 +52,7 @@ public interface ScenicMapper { | |||||||
|      * |      * | ||||||
|      * @param scenicId |      * @param scenicId | ||||||
|      */ |      */ | ||||||
|     void deleteConfigByscenicId(Long scenicId); |     void deleteConfigByScenicId(Long scenicId); | ||||||
|  |  | ||||||
|     List<ScenicAppVO> appList(ScenicReqQuery scenicReqQuery); |     List<ScenicAppVO> appList(ScenicReqQuery scenicReqQuery); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ package com.ycwl.basic.mapper.pc; | |||||||
| import com.ycwl.basic.model.pc.task.entity.TaskEntity; | import com.ycwl.basic.model.pc.task.entity.TaskEntity; | ||||||
| import com.ycwl.basic.model.pc.task.req.TaskReqQuery; | import com.ycwl.basic.model.pc.task.req.TaskReqQuery; | ||||||
| import com.ycwl.basic.model.pc.task.resp.TaskRespVO; | import com.ycwl.basic.model.pc.task.resp.TaskRespVO; | ||||||
|  | import com.ycwl.basic.model.pc.template.entity.TemplateConfigEntity; | ||||||
| import com.ycwl.basic.model.pc.template.entity.TemplateEntity; | import com.ycwl.basic.model.pc.template.entity.TemplateEntity; | ||||||
| import com.ycwl.basic.model.pc.template.req.TemplateReqQuery; | import com.ycwl.basic.model.pc.template.req.TemplateReqQuery; | ||||||
| import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | ||||||
| @@ -26,4 +27,9 @@ public interface TemplateMapper { | |||||||
|     int deleteByPid(Long pid); |     int deleteByPid(Long pid); | ||||||
|     int deleteByScenicId(Long scenicId); |     int deleteByScenicId(Long scenicId); | ||||||
|     List<TemplateRespVO> getByPid(Long id); |     List<TemplateRespVO> getByPid(Long id); | ||||||
|  |     TemplateConfigEntity getConfig(Long templateId); | ||||||
|  |     int addConfig(TemplateConfigEntity templateConfig); | ||||||
|  |     int updateConfigById(TemplateConfigEntity templateConfigEntity); | ||||||
|  |     int deleteConfigByTemplateId(Long templateId); | ||||||
|  |     int deleteConfigById(Long id); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | |||||||
| import com.ycwl.basic.model.pc.video.entity.VideoEntity; | import com.ycwl.basic.model.pc.video.entity.VideoEntity; | ||||||
| import com.ycwl.basic.model.pc.video.req.VideoReqQuery; | import com.ycwl.basic.model.pc.video.req.VideoReqQuery; | ||||||
| import com.ycwl.basic.model.pc.video.resp.VideoRespVO; | import com.ycwl.basic.model.pc.video.resp.VideoRespVO; | ||||||
|  | import lombok.NonNull; | ||||||
| import org.apache.ibatis.annotations.Mapper; | import org.apache.ibatis.annotations.Mapper; | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -22,4 +23,6 @@ public interface VideoMapper { | |||||||
|     int add(VideoEntity task); |     int add(VideoEntity task); | ||||||
|     int deleteById(Long id); |     int deleteById(Long id); | ||||||
|     int update(VideoEntity task); |     int update(VideoEntity task); | ||||||
|  |  | ||||||
|  |     VideoEntity findByTaskId(@NonNull Long taskId); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | package com.ycwl.basic.model.pc.device.entity; | ||||||
|  |  | ||||||
|  | import com.baomidou.mybatisplus.annotation.TableName; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonFormat; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | import java.math.BigDecimal; | ||||||
|  | import java.util.Date; | ||||||
|  |  | ||||||
|  | @Data | ||||||
|  | @TableName("device_config") | ||||||
|  | public class DeviceConfigEntity { | ||||||
|  |     private Long id; | ||||||
|  |     /** | ||||||
|  |      * 设备id | ||||||
|  |      */ | ||||||
|  |     private Long deviceId; | ||||||
|  |     /** | ||||||
|  |      * 启用时间 | ||||||
|  |      */ | ||||||
|  |     private Date startTime; | ||||||
|  |     /** | ||||||
|  |      * 结束时间 | ||||||
|  |      */ | ||||||
|  |     private Date endTime; | ||||||
|  |     /** | ||||||
|  |      * 创建时间 | ||||||
|  |      */ | ||||||
|  |     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") | ||||||
|  |     private Date createTime; | ||||||
|  |     /** | ||||||
|  |      * 存储类型 | ||||||
|  |      */ | ||||||
|  |     private Integer storeType; | ||||||
|  |     /** | ||||||
|  |      * 存储配置 | ||||||
|  |      */ | ||||||
|  |     private String storeConfigJson; | ||||||
|  |     /** | ||||||
|  |      * 存储过期天数 | ||||||
|  |      */ | ||||||
|  |     private Integer storeExpireDay; | ||||||
|  |     /** | ||||||
|  |      * 检测设备是否在线 | ||||||
|  |      */ | ||||||
|  |     private Integer onlineCheck; | ||||||
|  |     /** | ||||||
|  |      * 检测设备是否在线最大间隔 | ||||||
|  |      */ | ||||||
|  |     private Integer onlineMaxInterval; | ||||||
|  |     /** | ||||||
|  |      * 切割时,取人脸前多少秒的视频 | ||||||
|  |      */ | ||||||
|  |     private BigDecimal cutPre; | ||||||
|  |     /** | ||||||
|  |      * 切割时,取人脸后多少秒的视频 | ||||||
|  |      */ | ||||||
|  |     private BigDecimal cutPost; | ||||||
|  | } | ||||||
| @@ -16,6 +16,7 @@ import java.util.Date; | |||||||
| public class FaceEntity { | public class FaceEntity { | ||||||
|     @TableId |     @TableId | ||||||
|     private Long id; |     private Long id; | ||||||
|  |     private Long scenicId; | ||||||
|     /** |     /** | ||||||
|      * 人脸得分 |      * 人脸得分 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ import java.util.Date; | |||||||
| @Data | @Data | ||||||
| @ApiModel("人脸查询参数") | @ApiModel("人脸查询参数") | ||||||
| public class FaceReqQuery extends BaseQueryParameterReq { | public class FaceReqQuery extends BaseQueryParameterReq { | ||||||
|  |     @ApiModelProperty("景区id") | ||||||
|  |     private Long scenicId; | ||||||
|     @ApiModelProperty("会员id") |     @ApiModelProperty("会员id") | ||||||
|     private Long memberId; |     private Long memberId; | ||||||
|     @ApiModelProperty("用户上传的人脸照片") |     @ApiModelProperty("用户上传的人脸照片") | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import java.util.Date; | |||||||
| @ApiModel(value = "订单查询对象") | @ApiModel(value = "订单查询对象") | ||||||
| public class OrderReqQuery extends BaseQueryParameterReq { | public class OrderReqQuery extends BaseQueryParameterReq { | ||||||
|     private Long id; |     private Long id; | ||||||
|  |     private Long scenicId; | ||||||
|     private Long memberId; |     private Long memberId; | ||||||
|     @ApiModelProperty("用户昵称") |     @ApiModelProperty("用户昵称") | ||||||
|     private String memberNickname; |     private String memberNickname; | ||||||
|   | |||||||
| @@ -102,4 +102,6 @@ public class OrderRespVO { | |||||||
|     private Date refundAt; |     private Date refundAt; | ||||||
|     @ApiModelProperty("订单明细") |     @ApiModelProperty("订单明细") | ||||||
|     private List<OrderItemVO> orderItemList; |     private List<OrderItemVO> orderItemList; | ||||||
|  |     private Long scenicId; | ||||||
|  |     private String scenicName; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -38,4 +38,21 @@ public class ScenicConfigEntity { | |||||||
|      */ |      */ | ||||||
|     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") | ||||||
|     private Date createTime; |     private Date createTime; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 预约流程,1-预约,2-在线,3-全部 | ||||||
|  |      */ | ||||||
|  |     private Integer bookRoutine; | ||||||
|  |     /** | ||||||
|  |      * 样本保存时间 | ||||||
|  |      */ | ||||||
|  |     private Integer sampleStoreDay; | ||||||
|  |     /** | ||||||
|  |      * 视频保存时间 | ||||||
|  |      */ | ||||||
|  |     private Integer videoStoreDay; | ||||||
|  |     /** | ||||||
|  |      * 最大行程时长 | ||||||
|  |      */ | ||||||
|  |     private Integer maxJourneyHour; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| package com.ycwl.basic.model.pc.scenic.req; | package com.ycwl.basic.model.pc.scenic.req; | ||||||
|  |  | ||||||
| import com.fasterxml.jackson.annotation.JsonFormat; | import com.fasterxml.jackson.annotation.JsonFormat; | ||||||
| import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; |  | ||||||
| import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||||
| import io.swagger.annotations.ApiModelProperty; | import io.swagger.annotations.ApiModelProperty; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| @@ -78,8 +77,6 @@ public class ScenicAddOrUpdateReq { | |||||||
|     private Date createTime; |     private Date createTime; | ||||||
|     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") | ||||||
|     private Date updateTime; |     private Date updateTime; | ||||||
|     @ApiModelProperty("景区配置") |  | ||||||
|     private ScenicConfigEntity scenicConfig; |  | ||||||
|     @ApiModelProperty("景区源素材价格,元") |     @ApiModelProperty("景区源素材价格,元") | ||||||
|     private BigDecimal price; |     private BigDecimal price; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -79,13 +79,11 @@ public class ScenicRespVO { | |||||||
|      * 状态 1启用0关闭 |      * 状态 1启用0关闭 | ||||||
|      */ |      */ | ||||||
|     @ApiModelProperty("状态 1启用0关闭") |     @ApiModelProperty("状态 1启用0关闭") | ||||||
|     private String status; |     private Integer status; | ||||||
|     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") | ||||||
|     private Date createTime; |     private Date createTime; | ||||||
|     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") | ||||||
|     private Date updateTime; |     private Date updateTime; | ||||||
|     @ApiModelProperty("景区配置") |  | ||||||
|     private ScenicConfigEntity scenicConfig; |  | ||||||
|     @ApiModelProperty("景区源素材价格,元") |     @ApiModelProperty("景区源素材价格,元") | ||||||
|     private BigDecimal price; |     private BigDecimal price; | ||||||
|     @ApiModelProperty("镜头数") |     @ApiModelProperty("镜头数") | ||||||
|   | |||||||
| @@ -30,6 +30,10 @@ public class SourceEntity { | |||||||
|      * 所属用户 |      * 所属用户 | ||||||
|      */ |      */ | ||||||
|     private Long memberId; |     private Long memberId; | ||||||
|  |     /** | ||||||
|  |      * 人脸样本id | ||||||
|  |      */ | ||||||
|  |     private Long faceSampleId; | ||||||
|     /** |     /** | ||||||
|      * 原素材类型:1视频,2图像 |      * 原素材类型:1视频,2图像 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package com.ycwl.basic.model.pc.template.entity; | ||||||
|  |  | ||||||
|  | import com.baomidou.mybatisplus.annotation.TableName; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | import java.util.Date; | ||||||
|  |  | ||||||
|  | @Data | ||||||
|  | @TableName("template_config") | ||||||
|  | public class TemplateConfigEntity { | ||||||
|  |     private Long id; | ||||||
|  |     private Long templateId; | ||||||
|  |     private Integer isDefault; | ||||||
|  |     private Date createDate; | ||||||
|  |     private Integer minimalPlaceholderFill; | ||||||
|  | } | ||||||
| @@ -7,6 +7,7 @@ import com.ycwl.basic.service.pc.MenuService; | |||||||
| import com.ycwl.basic.utils.ApiResponse; | import com.ycwl.basic.utils.ApiResponse; | ||||||
| import com.ycwl.basic.utils.SnowFlakeUtil; | import com.ycwl.basic.utils.SnowFlakeUtil; | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -15,7 +16,7 @@ import java.util.List; | |||||||
|  * @Author:longbinbin |  * @Author:longbinbin | ||||||
|  * @Date:2024/12/3 10:16 |  * @Date:2024/12/3 10:16 | ||||||
|  */ |  */ | ||||||
|  | @Service | ||||||
| public class MenuServiceImpl implements MenuService { | public class MenuServiceImpl implements MenuService { | ||||||
|  |  | ||||||
|     @Autowired |     @Autowired | ||||||
|   | |||||||
| @@ -96,7 +96,7 @@ public class ScenicServiceImpl implements ScenicService { | |||||||
|     public ApiResponse<Boolean> deleteById(Long id) { |     public ApiResponse<Boolean> deleteById(Long id) { | ||||||
|         int i = scenicMapper.deleteById(id); |         int i = scenicMapper.deleteById(id); | ||||||
|         if (i > 0) { |         if (i > 0) { | ||||||
|             scenicMapper.deleteConfigByscenicId(id); |             scenicMapper.deleteConfigByScenicId(id); | ||||||
|             scenicAccountMapper.deleteByScenicId(id); |             scenicAccountMapper.deleteByScenicId(id); | ||||||
|             return ApiResponse.success(true); |             return ApiResponse.success(true); | ||||||
|         }else { |         }else { | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ import com.ycwl.basic.model.pc.face.resp.FaceRespVO; | |||||||
| import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; | import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; | ||||||
| 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.task.resp.AddFaceRespVo; | import com.ycwl.basic.model.task.resp.AddFaceRespVo; | ||||||
| import com.ycwl.basic.model.task.resp.SearchFaceRespVo; | import com.ycwl.basic.model.task.resp.SearchFaceRespVo; | ||||||
| import com.ycwl.basic.service.task.TaskFaceService; | import com.ycwl.basic.service.task.TaskFaceService; | ||||||
| @@ -84,13 +85,12 @@ public class TaskFaceServiceImpl implements TaskFaceService { | |||||||
|                     .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData) |                     .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData) | ||||||
|                     .map(Long::parseLong) |                     .map(Long::parseLong) | ||||||
|                     .collect(Collectors.toList()); |                     .collect(Collectors.toList()); | ||||||
|             faceEntity.setMatchSampleIds(StringUtils.joinWith(",", faceSampleIds)); |             faceEntity.setMatchSampleIds(StringUtils.join(faceSampleIds, ",")); | ||||||
|             faceMapper.update(faceEntity); |             faceMapper.update(faceEntity); | ||||||
|             respVo.setSampleListIds(faceSampleIds); |             respVo.setSampleListIds(faceSampleIds); | ||||||
|             respVo.setScore(matchList.get(0).getQualitieScore()); |             respVo.setScore(matchList.get(0).getQualitieScore()); | ||||||
|             return respVo; |             return respVo; | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             e.printStackTrace(); |  | ||||||
|             log.error("人脸搜索失败:{}", e.getMessage()); |             log.error("人脸搜索失败:{}", e.getMessage()); | ||||||
|             throw new BaseException(e.getMessage()); |             throw new BaseException(e.getMessage()); | ||||||
|         } |         } | ||||||
| @@ -136,7 +136,15 @@ public class TaskFaceServiceImpl implements TaskFaceService { | |||||||
|         FaceSampleReqQuery query = new FaceSampleReqQuery(); |         FaceSampleReqQuery query = new FaceSampleReqQuery(); | ||||||
|         query.setDeviceId(scenicId); |         query.setDeviceId(scenicId); | ||||||
|         faceSampleMapper.list(query); |         faceSampleMapper.list(query); | ||||||
|         Date thatDay = DateUtil.offsetDay(new Date(), -3); |         ScenicConfigEntity scenicConfig = scenicMapper.getConfig(scenicId); | ||||||
|  |         if (scenicConfig == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         Integer sampleStoreDay = scenicConfig.getSampleStoreDay(); | ||||||
|  |         if (sampleStoreDay == null) { | ||||||
|  |             sampleStoreDay = 3; | ||||||
|  |         } | ||||||
|  |         Date thatDay = DateUtil.offsetDay(new Date(), -sampleStoreDay); | ||||||
|         Date dayStart = DateUtil.beginOfDay(thatDay); |         Date dayStart = DateUtil.beginOfDay(thatDay); | ||||||
|         Date dayEnd = DateUtil.endOfDay(thatDay); |         Date dayEnd = DateUtil.endOfDay(thatDay); | ||||||
|         query.setStartTime(dayStart); |         query.setStartTime(dayStart); | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import com.ycwl.basic.mapper.pc.RenderWorkerMapper; | |||||||
| import com.ycwl.basic.mapper.pc.SourceMapper; | import com.ycwl.basic.mapper.pc.SourceMapper; | ||||||
| import com.ycwl.basic.mapper.pc.TaskMapper; | import com.ycwl.basic.mapper.pc.TaskMapper; | ||||||
| import com.ycwl.basic.mapper.pc.TemplateMapper; | import com.ycwl.basic.mapper.pc.TemplateMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.VideoMapper; | ||||||
| import com.ycwl.basic.model.pc.face.resp.FaceRespVO; | import com.ycwl.basic.model.pc.face.resp.FaceRespVO; | ||||||
| import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; | import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; | ||||||
| import com.ycwl.basic.model.pc.renderWorker.entity.RenderWorkerEntity; | import com.ycwl.basic.model.pc.renderWorker.entity.RenderWorkerEntity; | ||||||
| @@ -16,6 +17,7 @@ import com.ycwl.basic.model.pc.task.entity.TaskEntity; | |||||||
| import com.ycwl.basic.model.pc.task.resp.TaskRespVO; | import com.ycwl.basic.model.pc.task.resp.TaskRespVO; | ||||||
| import com.ycwl.basic.model.pc.template.req.TemplateReqQuery; | import com.ycwl.basic.model.pc.template.req.TemplateReqQuery; | ||||||
| import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | ||||||
|  | import com.ycwl.basic.model.pc.video.entity.VideoEntity; | ||||||
| import com.ycwl.basic.model.task.req.ClientStatusReqVo; | import com.ycwl.basic.model.task.req.ClientStatusReqVo; | ||||||
| import com.ycwl.basic.model.task.req.TaskReqVo; | import com.ycwl.basic.model.task.req.TaskReqVo; | ||||||
| import com.ycwl.basic.model.task.req.WorkerAuthReqVo; | import com.ycwl.basic.model.task.req.WorkerAuthReqVo; | ||||||
| @@ -57,6 +59,8 @@ public class TaskTaskServiceImpl implements TaskService { | |||||||
|     private SourceMapper sourceMapper; |     private SourceMapper sourceMapper; | ||||||
|     @Autowired |     @Autowired | ||||||
|     private OssUtil ossUtil; |     private OssUtil ossUtil; | ||||||
|  |     @Autowired | ||||||
|  |     private VideoMapper videoMapper; | ||||||
|  |  | ||||||
|     private RenderWorkerEntity getWorker(@NonNull WorkerAuthReqVo req) { |     private RenderWorkerEntity getWorker(@NonNull WorkerAuthReqVo req) { | ||||||
|         String accessKey = req.getAccessKey(); |         String accessKey = req.getAccessKey(); | ||||||
| @@ -112,9 +116,7 @@ public class TaskTaskServiceImpl implements TaskService { | |||||||
|         } |         } | ||||||
|         List<TaskRespVO> taskList = taskMapper.selectNotRunning(); |         List<TaskRespVO> taskList = taskMapper.selectNotRunning(); | ||||||
|         resp.setTasks(taskList); |         resp.setTasks(taskList); | ||||||
|         taskList.forEach(task -> { |         taskList.forEach(task -> taskMapper.assignToWorker(task.getId(), worker.getId())); | ||||||
|             taskMapper.assignToWorker(task.getId(), worker.getId()); |  | ||||||
|         }); |  | ||||||
|         // return Task |         // return Task | ||||||
|         return resp; |         return resp; | ||||||
|     } |     } | ||||||
| @@ -131,9 +133,7 @@ public class TaskTaskServiceImpl implements TaskService { | |||||||
|         } |         } | ||||||
|         Map<String, List<SourceRespVO>> sourcesMap = Arrays.stream(faceRespVO.getMatchSampleIds().split(",")) |         Map<String, List<SourceRespVO>> sourcesMap = Arrays.stream(faceRespVO.getMatchSampleIds().split(",")) | ||||||
|                 .map(Long::valueOf) |                 .map(Long::valueOf) | ||||||
|                 .map(sampleId -> { |                 .map(sampleId -> faceSampleMapper.getById(sampleId)) | ||||||
|                     return faceSampleMapper.getById(sampleId); |  | ||||||
|                 }) |  | ||||||
|                 .filter(Objects::nonNull) |                 .filter(Objects::nonNull) | ||||||
|                 .map(FaceSampleRespVO::getSourceId) |                 .map(FaceSampleRespVO::getSourceId) | ||||||
|                 .map(sourceId -> sourceMapper.getById(sourceId)) |                 .map(sourceId -> sourceMapper.getById(sourceId)) | ||||||
| @@ -178,6 +178,22 @@ public class TaskTaskServiceImpl implements TaskService { | |||||||
|         taskUpdate.setStatus(1); |         taskUpdate.setStatus(1); | ||||||
|         taskUpdate.setWorkerId(worker.getId()); |         taskUpdate.setWorkerId(worker.getId()); | ||||||
|         taskMapper.update(taskUpdate); |         taskMapper.update(taskUpdate); | ||||||
|  |         VideoEntity video = videoMapper.findByTaskId(taskId); | ||||||
|  |         if (video != null) { | ||||||
|  |             video.setVideoUrl(task.getVideoUrl()); | ||||||
|  |             videoMapper.update(video); | ||||||
|  |         } else { | ||||||
|  |             video = new VideoEntity(); | ||||||
|  |             video.setId(SnowFlakeUtil.getLongId()); | ||||||
|  |             video.setScenicId(task.getScenicId()); | ||||||
|  |             video.setMemberId(task.getMemberId()); | ||||||
|  |             video.setTemplateId(task.getTemplateId()); | ||||||
|  |             video.setTaskId(taskId); | ||||||
|  |             video.setWorkerId(worker.getId()); | ||||||
|  |             video.setVideoUrl(task.getVideoUrl()); | ||||||
|  |             video.setCreateTime(new Date()); | ||||||
|  |             videoMapper.add(video); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
							
								
								
									
										142
									
								
								src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | |||||||
|  | package com.ycwl.basic.task; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.mapper.pc.DeviceMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.FaceMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.FaceSampleMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.ScenicMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.TemplateMapper; | ||||||
|  | import com.ycwl.basic.model.pc.face.resp.FaceRespVO; | ||||||
|  | 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.template.entity.TemplateConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.template.req.TemplateReqQuery; | ||||||
|  | import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; | ||||||
|  | import com.ycwl.basic.model.task.resp.SearchFaceRespVo; | ||||||
|  | import com.ycwl.basic.service.task.TaskFaceService; | ||||||
|  | import com.ycwl.basic.service.task.TaskService; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.scheduling.annotation.EnableScheduling; | ||||||
|  | import org.springframework.scheduling.annotation.Scheduled; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Component | ||||||
|  | @EnableScheduling | ||||||
|  | @Slf4j | ||||||
|  | public class DynamicTaskGenerator { | ||||||
|  |     @Autowired | ||||||
|  |     private ScenicMapper scenicMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private TemplateMapper templateMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private FaceMapper faceMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private TaskFaceService faceService; | ||||||
|  |     @Autowired | ||||||
|  |     private FaceSampleMapper faceSampleMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private TaskService taskService; | ||||||
|  |     @Autowired | ||||||
|  |     private DeviceMapper deviceMapper; | ||||||
|  |  | ||||||
|  |     @Scheduled(cron = "0 0 * * * ?") | ||||||
|  |     public void dynamicTask() { | ||||||
|  |         List<ScenicRespVO> scenicList = scenicMapper.list(new ScenicReqQuery()); | ||||||
|  |         for (ScenicRespVO scenic : scenicList) { | ||||||
|  |             log.info("定时任务执行,当前景区:{}", scenic.getName()); | ||||||
|  |             ScenicConfigEntity scenicConfig = scenicMapper.getConfig(scenic.getId()); | ||||||
|  |             if (scenicConfig == null || scenicConfig.getBookRoutine() == 2) { | ||||||
|  |                 log.info("当前景区{},未启用提前预约流程", scenic.getName()); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             log.info("当前景区{},启用了提前预约流程", scenic.getName()); | ||||||
|  |             TemplateReqQuery templateQuery = new TemplateReqQuery(); | ||||||
|  |             templateQuery.setScenicId(scenic.getId()); | ||||||
|  |             List<TemplateRespVO> templateList = templateMapper.list(templateQuery); | ||||||
|  |             for (TemplateRespVO template : templateList) { | ||||||
|  |                 log.info("当前景区{},启用了提前预约流程,模板:{}", scenic.getName(), template.getName()); | ||||||
|  |                 if (template.getStatus() == 0) { | ||||||
|  |                     log.info("当前模板{}未启用,跳过", template.getName()); | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 TemplateConfigEntity templateConfig = templateMapper.getConfig(template.getId()); | ||||||
|  |                 if (templateConfig == null) { | ||||||
|  |                     log.info("当前模板{}未配置,跳过", template.getName()); | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 if (templateConfig.getIsDefault() == 0) { | ||||||
|  |                     if (scenicConfig.getBookRoutine() == 1) { | ||||||
|  |                         log.info("当前模板{}未启用默认,且景区启用预约流程,跳过", template.getName()); | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 Integer minimalPlaceholderFill = templateConfig.getMinimalPlaceholderFill(); | ||||||
|  |                 List<String> placeholderList = new ArrayList<>(); | ||||||
|  |                 if (minimalPlaceholderFill == null) { | ||||||
|  |                     minimalPlaceholderFill = 0; | ||||||
|  |                 } | ||||||
|  |                 List<TemplateRespVO> subTemplateList = templateMapper.getByPid(template.getId()); | ||||||
|  |                 for (TemplateRespVO subTemplate : subTemplateList) { | ||||||
|  |                     if (subTemplate.getIsPlaceholder() == 1) { | ||||||
|  |                         placeholderList.add(subTemplate.getSourceUrl()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 if (minimalPlaceholderFill == 0) { | ||||||
|  |                     for (TemplateRespVO subTemplate : subTemplateList) { | ||||||
|  |                         if (subTemplate.getIsPlaceholder() == 1) { | ||||||
|  |                             minimalPlaceholderFill += 1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 log.info("当前模板{}启用默认,最小占位素材:{}", template.getName(), minimalPlaceholderFill); | ||||||
|  |                 // 查找人脸样本 | ||||||
|  |                 List<FaceRespVO> list = faceMapper.listByScenicIdAndNotFinished(scenic.getId()); | ||||||
|  |                 for (FaceRespVO face : list) { | ||||||
|  |                     log.info("当前模板{}启用默认,人脸样本:{}", template.getName(), face.getFaceUrl()); | ||||||
|  |                     if (((new Date()).getTime() - face.getCreateAt().getTime()) > scenicConfig.getMaxJourneyHour() * 3600 * 1000) { | ||||||
|  |                         log.info("当前人脸样本{}已超过最大游玩{}小时,自动检测人脸", face.getFaceUrl(), scenicConfig.getMaxJourneyHour()); | ||||||
|  |                         List<String> oldMatchedSampleListIds = new ArrayList<>(); | ||||||
|  |                         if (face.getMatchSampleIds() != null) { | ||||||
|  |                             oldMatchedSampleListIds = Arrays.asList(face.getMatchSampleIds().split(",")); | ||||||
|  |                         } | ||||||
|  |                         SearchFaceRespVo searchFace = faceService.searchFace(scenic.getId(), face.getId()); | ||||||
|  |                         if (oldMatchedSampleListIds.size() == searchFace.getSampleListIds().size()) { | ||||||
|  |                             boolean isEqual = true; | ||||||
|  |                             for (Long sampleId : searchFace.getSampleListIds()) { | ||||||
|  |                                 if (!oldMatchedSampleListIds.contains(sampleId.toString())) { | ||||||
|  |                                     isEqual = false; | ||||||
|  |                                     break; | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                             if (isEqual) { | ||||||
|  |                                 log.info("当前人脸样本{}已超过最大游玩{}小时,但人脸检测结果与上次相同,跳过", face.getFaceUrl(), scenicConfig.getMaxJourneyHour()); | ||||||
|  |                                 continue; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         List<FaceSampleRespVO> faceSampleList = faceSampleMapper.listByIds(searchFace.getSampleListIds()); | ||||||
|  |                         int matchedPlaceholder = 0; | ||||||
|  |                         for (FaceSampleRespVO faceSample : faceSampleList) { | ||||||
|  |                             if (placeholderList.contains(faceSample.getDeviceId().toString())) { | ||||||
|  |                                 matchedPlaceholder += 1; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         if (matchedPlaceholder >= minimalPlaceholderFill) { | ||||||
|  |                             log.info("当前人脸样本{}已超过最小占位素材{},自动创建任务", face.getFaceUrl(), minimalPlaceholderFill); | ||||||
|  |                             taskService.createRenderTask(scenic.getId(), template.getId(), face.getId()); | ||||||
|  |                             faceMapper.finishedJourney(face.getId()); | ||||||
|  |                         } else { | ||||||
|  |                             log.info("当前人脸样本{}未超过最小占位素材{},未达到自动生成条件", face.getFaceUrl(), minimalPlaceholderFill); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								src/main/java/com/ycwl/basic/task/FaceCleaner.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/main/java/com/ycwl/basic/task/FaceCleaner.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | package com.ycwl.basic.task; | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.mapper.pc.FaceSampleMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.ScenicMapper; | ||||||
|  | import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery; | ||||||
|  | import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO; | ||||||
|  | import com.ycwl.basic.service.task.TaskFaceService; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.scheduling.annotation.EnableScheduling; | ||||||
|  | import org.springframework.scheduling.annotation.Scheduled; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Component | ||||||
|  | @EnableScheduling | ||||||
|  | @Slf4j | ||||||
|  | public class FaceCleaner { | ||||||
|  |     @Autowired | ||||||
|  |     private ScenicMapper scenicMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private TaskFaceService faceService; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Scheduled(cron = "0 0 4 * * ?") | ||||||
|  |     public void clean(){ | ||||||
|  |         ScenicReqQuery scenicQuery = new ScenicReqQuery(); | ||||||
|  |         List<ScenicRespVO> scenicList = scenicMapper.list(scenicQuery); | ||||||
|  |         scenicList.forEach(scenic -> { | ||||||
|  |             log.info("当前景区{},开始删除人脸样本", scenic.getName()); | ||||||
|  |             faceService.batchDeleteFace(scenic.getId()); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,176 +0,0 @@ | |||||||
| //package com.ycwl.basic.task; |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //import cn.hutool.core.util.StrUtil; |  | ||||||
| //import com.alibaba.fastjson.JSONArray; |  | ||||||
| //import com.alibaba.fastjson.JSONObject; |  | ||||||
| //import com.tu.common.redis.RedisUtils; |  | ||||||
| //import com.tu.common.utils.ChinaMobileUtil; |  | ||||||
| //import com.tu.common.utils.DateUtils; |  | ||||||
| //import com.tu.dao.TuSpaceManageDao; |  | ||||||
| //import com.tu.dto.GetLiveSteamUrlDTO; |  | ||||||
| //import lombok.extern.slf4j.Slf4j; |  | ||||||
| //import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| //import org.springframework.beans.factory.annotation.Value; |  | ||||||
| //import org.springframework.core.annotation.Order; |  | ||||||
| //import org.springframework.scheduling.annotation.EnableScheduling; |  | ||||||
| //import org.springframework.scheduling.annotation.Scheduled; |  | ||||||
| //import org.springframework.stereotype.Component; |  | ||||||
| // |  | ||||||
| //import javax.annotation.PostConstruct; |  | ||||||
| //import java.util.*; |  | ||||||
| // |  | ||||||
| //import static com.tu.common.utils.ChinaMobileUtil.getTokenBySend; |  | ||||||
| //import static com.tu.common.utils.ChinaMobileUtil.sendPost; |  | ||||||
| // |  | ||||||
| //@Slf4j |  | ||||||
| //@Component |  | ||||||
| //@EnableScheduling |  | ||||||
| //public class GetSpaceChinaMobileLiveSteamJob { |  | ||||||
| // |  | ||||||
| //    @Autowired |  | ||||||
| //    TuSpaceManageDao tuSpaceManageDao; |  | ||||||
| //    @Autowired |  | ||||||
| //    RedisUtils redisUtils; |  | ||||||
| //    @Autowired |  | ||||||
| //    ChinaMobileUtil chinaMobileUtil; |  | ||||||
| //    @Value("${spring.profiles.active}") |  | ||||||
| //    private String springProfile; |  | ||||||
| // |  | ||||||
| //    //public static String token = null; |  | ||||||
| //    private static Queue failMsgSubQueue = new LinkedList(); // 保存订阅失败的数据 |  | ||||||
| // |  | ||||||
| //    /** |  | ||||||
| //     * 订阅消息 |  | ||||||
| //     */ |  | ||||||
| //    @PostConstruct |  | ||||||
| //    public void msgSubscription() { |  | ||||||
| //        new Thread(() -> { |  | ||||||
| //            if (springProfile.equals("prod")) { |  | ||||||
| //                List<GetLiveSteamUrlDTO> liveSteamUrl = tuSpaceManageDao.getLiveSteamUrl(null, 2); |  | ||||||
| //                List<String> deviceIdList = new ArrayList<>(); |  | ||||||
| //                for (GetLiveSteamUrlDTO item : liveSteamUrl) { |  | ||||||
| //                    String deviceSn = item.getDeviceSn(); |  | ||||||
| //                    if (deviceSn != null && !deviceSn.equals("")) { |  | ||||||
| //                        deviceIdList.add(deviceSn); |  | ||||||
| // |  | ||||||
| //                        if (deviceIdList.size() == 29) { |  | ||||||
| //                            // 30条数据为一组,分开订阅 |  | ||||||
| //                            String msg = doMsgSubscription(deviceIdList); |  | ||||||
| //                            if (StrUtil.isBlank(msg)) { |  | ||||||
| //                                // 消息订阅失败,过一会儿再试试 |  | ||||||
| //                                List<String> failDeviceIdList = new ArrayList<>(); |  | ||||||
| //                                Collections.copy(failDeviceIdList, deviceIdList); |  | ||||||
| //                                failMsgSubQueue.offer(failDeviceIdList); |  | ||||||
| //                            } |  | ||||||
| //                            deviceIdList = new ArrayList<>(); |  | ||||||
| //                        } |  | ||||||
| // |  | ||||||
| //                    } |  | ||||||
| //                } |  | ||||||
| //                doMsgSubscription(deviceIdList); |  | ||||||
| //            } |  | ||||||
| //        }).start(); |  | ||||||
| // |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //    /** |  | ||||||
| //     * 每小时扫描订阅失败的消息 |  | ||||||
| //     */ |  | ||||||
| //    @PostConstruct |  | ||||||
| //    @Scheduled(cron = "0 0 * * * *") |  | ||||||
| //    public void scanQueue() { |  | ||||||
| //        if (failMsgSubQueue.size() > 0) { |  | ||||||
| //            Object poll = failMsgSubQueue.poll(); |  | ||||||
| //            if (poll != null) { |  | ||||||
| //                List<String> pollList = (List<String>) poll; |  | ||||||
| //                String msg = doMsgSubscription(pollList); |  | ||||||
| //                if (StrUtil.isBlank(msg)) { |  | ||||||
| //                    // 消息订阅失败,过一会儿再试试 |  | ||||||
| //                    List<String> failDeviceIdList = new ArrayList<>(); |  | ||||||
| //                    Collections.copy(failDeviceIdList, pollList); |  | ||||||
| //                    failMsgSubQueue.offer(failDeviceIdList); |  | ||||||
| //                } |  | ||||||
| //            } |  | ||||||
| //        } |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //    @PostConstruct |  | ||||||
| //    @Scheduled(fixedRate = 1000 * 60 * 60 * 2) |  | ||||||
| //    @Order(1) |  | ||||||
| //    public void getToken() { |  | ||||||
| //        if (springProfile.equals("prod")) { |  | ||||||
| //            String tokenBySend = getTokenBySend(); |  | ||||||
| //            redisUtils.set("CHINA_MOBILE_TOKEN_KEY_NEW", tokenBySend, RedisUtils.HOUR_TOW_EXPIRE); |  | ||||||
| //        } |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| //    @Scheduled(cron = "0 */19 * * * *") |  | ||||||
| //    @PostConstruct |  | ||||||
| //    @Order(2) |  | ||||||
| //    public void setLiveSteam() { |  | ||||||
| //        new Thread(() -> { |  | ||||||
| //            if (springProfile.equals("prod")) { |  | ||||||
| //                List<GetLiveSteamUrlDTO> liveSteamUrl = tuSpaceManageDao.getLiveSteamUrl(null, 2); |  | ||||||
| //                for (GetLiveSteamUrlDTO item : liveSteamUrl) { |  | ||||||
| //                    String url = getLiveSteam(item.getDeviceSn()); |  | ||||||
| //                    if (url != null && !url.equals("")) { |  | ||||||
| //                        tuSpaceManageDao.updateLiveSteamUrl(item.getId(), url); |  | ||||||
| //                    } |  | ||||||
| //                } |  | ||||||
| //            } |  | ||||||
| //        }).start(); |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| //    public String getLiveSteam(String deviceId) { |  | ||||||
| //        log.info("【移动】开始获取视频流" + deviceId); |  | ||||||
| //        String url_hls = "https://open.andmu.cn/v3/open/api/device/hls"; |  | ||||||
| //        JSONObject bodyParam = new JSONObject(); |  | ||||||
| //        bodyParam.put("deviceId", deviceId); |  | ||||||
| //        bodyParam.put("endTime", DateUtils.addDateDays(new Date(), 2).getTime()); |  | ||||||
| //        log.info("【移动】bodyParam->{}", bodyParam); |  | ||||||
| //        String res = sendPost(url_hls, bodyParam, chinaMobileUtil.getTempToken()); |  | ||||||
| //        log.info("【移动】开始获取视频流结果:-》{}" + res); |  | ||||||
| //        JSONObject jsonObject = JSONObject.parseObject(res); |  | ||||||
| //        String m3u8Url = null; |  | ||||||
| //        if (jsonObject.get("resultCode").toString().equals("000000")) { |  | ||||||
| //            String data = jsonObject.get("data").toString(); |  | ||||||
| //            JSONObject jsonData = JSONObject.parseObject(data); |  | ||||||
| //            m3u8Url = jsonData.get("m3u8Url").toString(); |  | ||||||
| //        } |  | ||||||
| //        // token已过期 |  | ||||||
| //        if (jsonObject.get("resultCode").toString().equals("11504")) { |  | ||||||
| //            // 删除redis的token,会重新获取 |  | ||||||
| //            redisUtils.delete("CHINA_MOBILE_TOKEN_KEY_NEW"); |  | ||||||
| //            getLiveSteam(deviceId); |  | ||||||
| //        } |  | ||||||
| //        return m3u8Url; |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //    public static void main(String[] args) { |  | ||||||
| // |  | ||||||
| //        //List<String> deviceIdList =new ArrayList<>(30); |  | ||||||
| //        //deviceIdList.add("2"); |  | ||||||
| //        //deviceIdList.add("1"); |  | ||||||
| //        // |  | ||||||
| //        //List<String> failDeviceIdList = new ArrayList<>(deviceIdList); |  | ||||||
| //        //failMsgSubQueue.offer(failDeviceIdList); |  | ||||||
| //        //deviceIdList = new ArrayList<>(); |  | ||||||
| //        //List<String> pollList = ( List<String>) failMsgSubQueue.poll(); |  | ||||||
| //        //for (String s : pollList) { |  | ||||||
| //        //    System.out.println(s); |  | ||||||
| //        //} |  | ||||||
| //        //System.out.println(failMsgSubQueue.poll()); |  | ||||||
| //        //System.out.println(failMsgSubQueue.size()); |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //        //String s = doMsgSubscription(Arrays.asList("040312e7fc9f", "743fc2dae410")); |  | ||||||
| //        //System.out.println(s); |  | ||||||
| //    } |  | ||||||
| // |  | ||||||
| // |  | ||||||
| // |  | ||||||
| //} |  | ||||||
							
								
								
									
										49
									
								
								src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | package com.ycwl.basic.task; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import com.ycwl.basic.device.DeviceFactory; | ||||||
|  | import com.ycwl.basic.device.operator.IDeviceStorageOperator; | ||||||
|  | import com.ycwl.basic.mapper.pc.DeviceMapper; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; | ||||||
|  | import com.ycwl.basic.model.pc.device.req.DeviceReqQuery; | ||||||
|  | import com.ycwl.basic.model.pc.device.resp.DeviceRespVO; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.scheduling.annotation.EnableScheduling; | ||||||
|  | import org.springframework.scheduling.annotation.Scheduled; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | @Component | ||||||
|  | @EnableScheduling | ||||||
|  | @Slf4j | ||||||
|  | public class VideoPieceCleaner { | ||||||
|  |     @Autowired | ||||||
|  |     private DeviceMapper deviceMapper; | ||||||
|  |  | ||||||
|  |     @Scheduled(cron = "0 0 0 * * ?") | ||||||
|  |     public void clean() { | ||||||
|  |         log.info("开始删除视频文件"); | ||||||
|  |         List<DeviceRespVO> deviceList = deviceMapper.list(new DeviceReqQuery()); | ||||||
|  |         for (DeviceRespVO device : deviceList) { | ||||||
|  |             DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(device.getId()); | ||||||
|  |             if (config == null) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (config.getStoreExpireDay() == null) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (config.getStoreExpireDay() <= 0) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             IDeviceStorageOperator storageOperator = DeviceFactory.getDeviceStorageOperator(null, config); | ||||||
|  |             if (storageOperator == null) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             storageOperator.removeFilesBeforeDate(new Date(System.currentTimeMillis() - config.getStoreExpireDay() * 24 * 60 * 60 * 1000)); | ||||||
|  |             log.info("删除视频文件完成"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										370
									
								
								src/main/java/com/ycwl/basic/task/VideoPieceGetter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								src/main/java/com/ycwl/basic/task/VideoPieceGetter.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,370 @@ | |||||||
|  | package com.ycwl.basic.task; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.date.DateUtil; | ||||||
|  | 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.mapper.pc.DeviceMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.FaceSampleMapper; | ||||||
|  | import com.ycwl.basic.mapper.pc.SourceMapper; | ||||||
|  | import com.ycwl.basic.model.pc.device.entity.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.SourceEntity; | ||||||
|  | import com.ycwl.basic.utils.OssUtil; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.scheduling.annotation.EnableScheduling; | ||||||
|  | import org.springframework.scheduling.annotation.Scheduled; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
|  | import java.io.BufferedReader; | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.FileInputStream; | ||||||
|  | import java.io.FileNotFoundException; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.InputStreamReader; | ||||||
|  | import java.math.BigDecimal; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.concurrent.LinkedBlockingQueue; | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | import java.util.stream.IntStream; | ||||||
|  |  | ||||||
|  | @Component | ||||||
|  | @EnableScheduling | ||||||
|  | @Slf4j | ||||||
|  | public class VideoPieceGetter { | ||||||
|  |     @Autowired | ||||||
|  |     private FaceSampleMapper faceSampleMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private DeviceMapper deviceMapper; | ||||||
|  |     @Autowired | ||||||
|  |     private OssUtil ossUtil; | ||||||
|  |     @Autowired | ||||||
|  |     private SourceMapper sourceMapper; | ||||||
|  |  | ||||||
|  |     @Data | ||||||
|  |     public static class Task { | ||||||
|  |         public Long deviceId; | ||||||
|  |         public Long faceSampleId; | ||||||
|  |         public Date createTime; | ||||||
|  |     } | ||||||
|  |     @Data | ||||||
|  |     public static class FfmpegTask { | ||||||
|  |         List<FileObject> fileList; | ||||||
|  |         BigDecimal duration; | ||||||
|  |         BigDecimal offsetStart; | ||||||
|  |         String outputFile; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static LinkedBlockingQueue<Task> queue = new LinkedBlockingQueue<>(); | ||||||
|  |  | ||||||
|  |     public static void addTask(Task task) { | ||||||
|  |         queue.add(task); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Scheduled(fixedDelay = 5000L) | ||||||
|  |     public void doTask() { | ||||||
|  |         Task task = queue.poll(); | ||||||
|  |         if (task == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         log.info("poll task: {}", task); | ||||||
|  |         FaceSampleRespVO faceSample = faceSampleMapper.getById(task.getFaceSampleId()); | ||||||
|  |         DeviceEntity device = deviceMapper.getByDeviceId(task.getDeviceId()); | ||||||
|  |         DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(task.getDeviceId()); | ||||||
|  |         BigDecimal cutPre = BigDecimal.valueOf(5L); | ||||||
|  |         BigDecimal cutPost = BigDecimal.valueOf(4L); | ||||||
|  |         if (config == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // 有配置 | ||||||
|  |         if (config.getCutPre() != null) { | ||||||
|  |             cutPre = config.getCutPre(); | ||||||
|  |         } | ||||||
|  |         if (config.getCutPost() != null) { | ||||||
|  |             cutPost = config.getCutPost(); | ||||||
|  |         } | ||||||
|  |         IDeviceStorageOperator pieceGetter = DeviceFactory.getDeviceStorageOperator(device, config); | ||||||
|  |         if (pieceGetter == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         BigDecimal duration = cutPre.add(cutPost); | ||||||
|  |         List<FileObject> listByDtRange = pieceGetter.getFileListByDtRange( | ||||||
|  |                 new Date(task.getCreateTime().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue()), | ||||||
|  |                 new Date(task.getCreateTime().getTime() + cutPost.multiply(BigDecimal.valueOf(1000)).longValue()) | ||||||
|  |         ); | ||||||
|  |         if (listByDtRange.isEmpty()) { | ||||||
|  |             queue.add(task); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         long offset = task.getCreateTime().getTime() - listByDtRange.get(0).getCreateTime().getTime(); | ||||||
|  |         FfmpegTask ffmpegTask = new FfmpegTask(); | ||||||
|  |         ffmpegTask.setFileList(listByDtRange); | ||||||
|  |         ffmpegTask.setDuration(duration); | ||||||
|  |         ffmpegTask.setOffsetStart(BigDecimal.valueOf(offset, 3)); | ||||||
|  |         File outFile = new File(faceSample.getDeviceId().toString() + "_" + faceSample.getId() + ".mp4"); | ||||||
|  |         ffmpegTask.setOutputFile(outFile.getAbsolutePath()); | ||||||
|  |         boolean result = startFfmpegTask(ffmpegTask); | ||||||
|  |         if (!result) { | ||||||
|  |             log.warn("视频裁切失败"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         log.info("视频裁切成功"); | ||||||
|  |         try { | ||||||
|  |             InputStream inputStream = new FileInputStream(outFile); | ||||||
|  |             String url = ossUtil.uploadFile(inputStream, "user-video-source", outFile.getName()); | ||||||
|  |             SourceEntity sourceEntity = new SourceEntity(); | ||||||
|  |             sourceEntity.setVideoUrl(url); | ||||||
|  |             sourceEntity.setFaceSampleId(faceSample.getId()); | ||||||
|  |             sourceEntity.setScenicId(faceSample.getScenicId()); | ||||||
|  |             sourceEntity.setDeviceId(faceSample.getDeviceId()); | ||||||
|  |             sourceEntity.setType(1); | ||||||
|  |             sourceMapper.add(sourceEntity); | ||||||
|  |         } catch (FileNotFoundException e) { | ||||||
|  |             throw new RuntimeException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean startFfmpegTask(FfmpegTask task) { | ||||||
|  |         boolean result; | ||||||
|  |         if (task.getFileList().size() == 1) { | ||||||
|  |             // 单个文件切割,用简单方法 | ||||||
|  |             result = runFfmpegForSingleFile(task); | ||||||
|  |         } else { | ||||||
|  |             // 多个文件切割,用速度快的 | ||||||
|  |             result = runFfmpegForMultipleFile1(task); | ||||||
|  |         } | ||||||
|  |         // 先尝试方法1 | ||||||
|  |         if (result) { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         log.warn("FFMPEG简易方法失败,尝试复杂方法转码"); | ||||||
|  |         // 不行再尝试方法二 | ||||||
|  |         return runFfmpegForMultipleFile2(task); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private boolean runFfmpegForMultipleFile1(FfmpegTask task) { | ||||||
|  |         // 多文件,方法一:先转换成ts,然后合并切割 | ||||||
|  |         // 步骤一:先转换成ts,并行转换 | ||||||
|  |         boolean notOk = task.getFileList().stream().map(file -> { | ||||||
|  |             try { | ||||||
|  |                 if (file.isNeedDownload() || (!file.getName().endsWith(".ts"))) { | ||||||
|  |                     String tmpFile = file.getName() + ".ts"; | ||||||
|  |                     boolean result = convertMp4ToTs(file, tmpFile); | ||||||
|  |                     // 因为是并行转换,没法保证顺序,就直接存里面 | ||||||
|  |                     if (result) { | ||||||
|  |                         file.setUrl(tmpFile); | ||||||
|  |                     } else { | ||||||
|  |                         // 失败了,务必删除临时文件 | ||||||
|  |                         (new File(tmpFile)).delete(); | ||||||
|  |                     } | ||||||
|  |                     return result; | ||||||
|  |                 } else { | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             } catch (IOException e) { | ||||||
|  |                 log.warn("转码出错"); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         }).anyMatch(b -> !b); | ||||||
|  |         // 转码进程中出现问题 | ||||||
|  |         if (notOk) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         // 步骤二:使用concat协议拼接裁切 | ||||||
|  |         boolean result; | ||||||
|  |         try { | ||||||
|  |             result = quickVideoCut( | ||||||
|  |                     "concat:" + task.getFileList().stream().map(FileObject::getUrl).collect(Collectors.joining("|")), | ||||||
|  |                     task.getOffsetStart(), task.getDuration(), task.getOutputFile() | ||||||
|  |             ); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         // 步骤三:删除临时文件 | ||||||
|  |         task.getFileList().stream().map(FileObject::getUrl).forEach(tmpFile -> { | ||||||
|  |             File f = new File(tmpFile); | ||||||
|  |             if (f.exists() && f.isFile()) { | ||||||
|  |                 f.delete(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private boolean runFfmpegForMultipleFile2(FfmpegTask task) { | ||||||
|  |         // 多文件,方法二:使用计算资源编码 | ||||||
|  |         try { | ||||||
|  |             return slowVideoCut(task.getFileList(), task.getOffsetStart(), task.getDuration(), task.getOutputFile()); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private boolean runFfmpegForSingleFile(FfmpegTask task) { | ||||||
|  |         try { | ||||||
|  |             return quickVideoCut(task.getFileList().get(0).getUrl(), task.getOffsetStart(), task.getDuration(), task.getOutputFile()); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 把MP4转换成可以拼接的TS文件 | ||||||
|  |      * | ||||||
|  |      * @param file        MP4文件,或ffmpeg支持的输入 | ||||||
|  |      * @param outFileName 输出文件路径 | ||||||
|  |      * @return 是否成功 | ||||||
|  |      * @throws IOException 奇奇怪怪的报错 | ||||||
|  |      */ | ||||||
|  |     private boolean convertMp4ToTs(FileObject file, String outFileName) throws IOException { | ||||||
|  |         List<String> ffmpegCmd = new ArrayList<>(); | ||||||
|  |         ffmpegCmd.add("ffmpeg"); | ||||||
|  |         ffmpegCmd.add("-hide_banner"); | ||||||
|  |         ffmpegCmd.add("-y"); | ||||||
|  |         ffmpegCmd.add("-i"); | ||||||
|  |         ffmpegCmd.add(file.getUrl()); | ||||||
|  |         ffmpegCmd.add("-c"); | ||||||
|  |         ffmpegCmd.add("copy"); | ||||||
|  |         ffmpegCmd.add("-bsf:v"); | ||||||
|  |         ffmpegCmd.add("h264_mp4toannexb"); | ||||||
|  |         ffmpegCmd.add("-f"); | ||||||
|  |         ffmpegCmd.add("mpegts"); | ||||||
|  |         ffmpegCmd.add(outFileName); | ||||||
|  |         return handleFfmpegProcess(ffmpegCmd); | ||||||
|  |     } | ||||||
|  |     private boolean convertHevcToTs(FileObject file, String outFileName) throws IOException { | ||||||
|  |         List<String> ffmpegCmd = new ArrayList<>(); | ||||||
|  |         ffmpegCmd.add("ffmpeg"); | ||||||
|  |         ffmpegCmd.add("-hide_banner"); | ||||||
|  |         ffmpegCmd.add("-y"); | ||||||
|  |         ffmpegCmd.add("-i"); | ||||||
|  |         ffmpegCmd.add(file.getUrl()); | ||||||
|  |         ffmpegCmd.add("-c"); | ||||||
|  |         ffmpegCmd.add("copy"); | ||||||
|  |         ffmpegCmd.add("-bsf:v"); | ||||||
|  |         ffmpegCmd.add("hevc_mp4toannexb"); | ||||||
|  |         ffmpegCmd.add("-f"); | ||||||
|  |         ffmpegCmd.add("mpegts"); | ||||||
|  |         ffmpegCmd.add(outFileName); | ||||||
|  |         return handleFfmpegProcess(ffmpegCmd); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 快速切割,不产生转码,速度快,但可能会出现:第一帧数据不是I帧导致前面的数据无法使用 | ||||||
|  |      * | ||||||
|  |      * @param inputFile  输入文件,ffmpeg支持的协议均可 | ||||||
|  |      * @param offset     离输入文件开始的偏移 | ||||||
|  |      * @param length     输出文件时长 | ||||||
|  |      * @param outputFile 输出文件名称 | ||||||
|  |      * @return 是否成功 | ||||||
|  |      * @throws IOException 奇奇怪怪的报错 | ||||||
|  |      */ | ||||||
|  |     private boolean quickVideoCut(String inputFile, BigDecimal offset, BigDecimal length, String outputFile) throws IOException { | ||||||
|  |         List<String> ffmpegCmd = new ArrayList<>(); | ||||||
|  |         ffmpegCmd.add("ffmpeg"); | ||||||
|  |         ffmpegCmd.add("-hide_banner"); | ||||||
|  |         ffmpegCmd.add("-y"); | ||||||
|  |         ffmpegCmd.add("-i"); | ||||||
|  |         ffmpegCmd.add(inputFile); | ||||||
|  |         ffmpegCmd.add("-c:v"); | ||||||
|  |         ffmpegCmd.add("copy"); | ||||||
|  |         ffmpegCmd.add("-an"); | ||||||
|  |         ffmpegCmd.add("-ss"); | ||||||
|  |         ffmpegCmd.add(offset.toPlainString()); | ||||||
|  |         ffmpegCmd.add("-t"); | ||||||
|  |         ffmpegCmd.add(length.toPlainString()); | ||||||
|  |         ffmpegCmd.add("-f"); | ||||||
|  |         ffmpegCmd.add("mp4"); | ||||||
|  |         ffmpegCmd.add(outputFile); | ||||||
|  |         return handleFfmpegProcess(ffmpegCmd); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 转码切割,兜底逻辑,速度慢,但优势:成功后转码视频绝对可用 | ||||||
|  |      * | ||||||
|  |      * @param inputFiles 输入文件List,ffmpeg支持的协议均可 | ||||||
|  |      * @param offset     离输入文件开始的偏移 | ||||||
|  |      * @param length     输出文件时长 | ||||||
|  |      * @param outputFile 输出文件名称 | ||||||
|  |      * @return 是否成功 | ||||||
|  |      * @throws IOException 奇奇怪怪的报错 | ||||||
|  |      */ | ||||||
|  |     private boolean slowVideoCut(List<FileObject> inputFiles, BigDecimal offset, BigDecimal length, String outputFile) throws IOException { | ||||||
|  |         List<String> ffmpegCmd = new ArrayList<>(); | ||||||
|  |         ffmpegCmd.add("ffmpeg"); | ||||||
|  |         ffmpegCmd.add("-hide_banner"); | ||||||
|  |         ffmpegCmd.add("-y"); | ||||||
|  |         for (FileObject file : inputFiles) { | ||||||
|  |             ffmpegCmd.add("-i"); | ||||||
|  |             ffmpegCmd.add(file.getUrl()); | ||||||
|  |         } | ||||||
|  |         // 使用filter_complex做拼接 | ||||||
|  |         ffmpegCmd.add("-filter_complex"); | ||||||
|  |         ffmpegCmd.add( | ||||||
|  |                 IntStream.range(0, inputFiles.size()).mapToObj(i -> "[" + i + ":v]").collect(Collectors.joining("")) + | ||||||
|  |                         "concat=n=2:v=1[v]" | ||||||
|  |         ); | ||||||
|  |         ffmpegCmd.add("-map"); | ||||||
|  |         ffmpegCmd.add("[v]"); | ||||||
|  |         ffmpegCmd.add("-preset:v"); | ||||||
|  |         ffmpegCmd.add("fast"); | ||||||
|  |         ffmpegCmd.add("-an"); | ||||||
|  |         // 没有使用copy,因为使用了filter_complex | ||||||
|  |         ffmpegCmd.add("-ss"); | ||||||
|  |         ffmpegCmd.add(offset.toPlainString()); | ||||||
|  |         ffmpegCmd.add("-t"); | ||||||
|  |         ffmpegCmd.add(length.toPlainString()); | ||||||
|  |         ffmpegCmd.add("-f"); | ||||||
|  |         ffmpegCmd.add("mp4"); | ||||||
|  |         ffmpegCmd.add(outputFile); | ||||||
|  |  | ||||||
|  |         return handleFfmpegProcess(ffmpegCmd); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 运行ffmpeg,并确认ffmpeg是否正常退出 | ||||||
|  |      * | ||||||
|  |      * @param ffmpegCmd ffmpeg命令 | ||||||
|  |      * @return 是否正常退出 | ||||||
|  |      */ | ||||||
|  |     private static boolean handleFfmpegProcess(List<String> ffmpegCmd) throws IOException { | ||||||
|  |         Date _startDt = new Date(); | ||||||
|  |         log.info("FFMPEG执行命令:【{}】", String.join(" ", ffmpegCmd)); | ||||||
|  |         ProcessBuilder pb = new ProcessBuilder(ffmpegCmd); | ||||||
|  |         Process ffmpegProcess = pb.start(); | ||||||
|  |         // 如果需要额外分析输出之类 | ||||||
|  |         if (log.isTraceEnabled()) { | ||||||
|  |             InputStream stderr = ffmpegProcess.getErrorStream(); | ||||||
|  |             BufferedReader reader = new BufferedReader(new InputStreamReader(stderr)); | ||||||
|  |             String line; | ||||||
|  |             while ((line = reader.readLine()) != null) { | ||||||
|  |                 log.trace(line); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         try { | ||||||
|  |             // 最长1分钟 | ||||||
|  |             boolean exited = ffmpegProcess.waitFor(1, TimeUnit.MINUTES); | ||||||
|  |             if (exited) { | ||||||
|  |                 int code = ffmpegProcess.exitValue(); | ||||||
|  |                 Date _endDt = new Date(); | ||||||
|  |                 log.info("FFMPEG执行命令结束,Code:【{}】,耗费时间:【{}ms】,命令:【{}】", code, _endDt.getTime() - _startDt.getTime(), String.join(" ", ffmpegCmd)); | ||||||
|  |                 return 0 == code; | ||||||
|  |             } else { | ||||||
|  |                 log.error("FFMPEG执行命令没有在1分钟内退出,命令:【{}】", String.join(" ", ffmpegCmd)); | ||||||
|  |                 ffmpegProcess.destroy(); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |             // TODO: 被中断了 | ||||||
|  |             log.warn("FFMPEG执行命令:【{}】,被中断了", String.join(" ", ffmpegCmd)); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -72,4 +72,14 @@ | |||||||
|             group by device_id |             group by device_id | ||||||
|              )b on a.scenic_id = b.scenic_id |              )b on a.scenic_id = b.scenic_id | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="getConfigByDeviceId" resultType="com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity"> | ||||||
|  |         select * | ||||||
|  |         from device_config | ||||||
|  |         where device_id = #{deviceId} | ||||||
|  |     </select> | ||||||
|  |     <select id="getByDeviceId" resultType="com.ycwl.basic.model.pc.device.entity.DeviceEntity"> | ||||||
|  |         select * | ||||||
|  |         from device | ||||||
|  |         where id = #{deviceId} | ||||||
|  |     </select> | ||||||
| </mapper> | </mapper> | ||||||
| @@ -2,12 +2,15 @@ | |||||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||||
| <mapper namespace="com.ycwl.basic.mapper.pc.FaceMapper"> | <mapper namespace="com.ycwl.basic.mapper.pc.FaceMapper"> | ||||||
|     <insert id="add"> |     <insert id="add"> | ||||||
|         insert into face(id, score, member_id, face_url, match_sample_ids, first_match_rate, match_result) |         insert into face(id, scenic_id, score, member_id, face_url, match_sample_ids, first_match_rate, match_result) | ||||||
|         values (#{id}, #{score}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult}) |         values (#{id}, #{scenicId}, #{score}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult}) | ||||||
|     </insert> |     </insert> | ||||||
|     <update id="update"> |     <update id="update"> | ||||||
|         update face |         update face | ||||||
|         <set> |         <set> | ||||||
|  |             <if test="scenicId!= null "> | ||||||
|  |                 scenic_id = #{scenicId}, | ||||||
|  |             </if> | ||||||
|             <if test="memberId!= null "> |             <if test="memberId!= null "> | ||||||
|                 member_id = #{memberId}, |                 member_id = #{memberId}, | ||||||
|             </if> |             </if> | ||||||
| @@ -29,6 +32,9 @@ | |||||||
|         </set> |         </set> | ||||||
|         where id = #{id} |         where id = #{id} | ||||||
|     </update> |     </update> | ||||||
|  |     <update id="finishedJourney"> | ||||||
|  |         update face set finished_journey = 1 where id = #{id} | ||||||
|  |     </update> | ||||||
|     <delete id="deleteById"> |     <delete id="deleteById"> | ||||||
|         delete from face where id = #{id} |         delete from face where id = #{id} | ||||||
|     </delete> |     </delete> | ||||||
| @@ -42,7 +48,7 @@ | |||||||
|     </if> |     </if> | ||||||
|     </delete> |     </delete> | ||||||
|     <select id="list" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> |     <select id="list" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> | ||||||
|         select id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result |         select id, scenic_id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result | ||||||
|         from face |         from face | ||||||
|         <where> |         <where> | ||||||
|             <if test="memberId!= null and memberId!= ''"> |             <if test="memberId!= null and memberId!= ''"> | ||||||
| @@ -66,13 +72,18 @@ | |||||||
|         </where> |         </where> | ||||||
|     </select> |     </select> | ||||||
|     <select id="getById" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> |     <select id="getById" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> | ||||||
|         select id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result |         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 id = #{id} |         where id = #{id} | ||||||
|     </select> |     </select> | ||||||
|     <select id="getByMemberId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> |     <select id="getByMemberId" resultType="com.ycwl.basic.model.pc.face.resp.FaceRespVO"> | ||||||
|         select id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result |         select 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 = #{memberId} |         where member_id = #{memberId} | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="listByScenicIdAndNotFinished" 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 scenic_id = #{scenicId} and finished_journey != 1 | ||||||
|  |     </select> | ||||||
| </mapper> | </mapper> | ||||||
| @@ -85,4 +85,13 @@ | |||||||
|         from face_sample |         from face_sample | ||||||
|         where id = #{id} |         where id = #{id} | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="listByIds" resultType="com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO"> | ||||||
|  |         select id, scenic_id, device_id, face_url, match_sample_ids, first_match_rate, source_id, match_result,`status` | ||||||
|  |         from face_sample | ||||||
|  |         where id in ( | ||||||
|  |         <foreach collection="list" item="id" separator=","> | ||||||
|  |             #{id} | ||||||
|  |         </foreach> | ||||||
|  |         ) | ||||||
|  |     </select> | ||||||
| </mapper> | </mapper> | ||||||
| @@ -3,6 +3,8 @@ | |||||||
| <mapper namespace="com.ycwl.basic.mapper.pc.OrderMapper"> | <mapper namespace="com.ycwl.basic.mapper.pc.OrderMapper"> | ||||||
|     <resultMap id="PCBaseResultMap" type="com.ycwl.basic.model.pc.order.resp.OrderRespVO"> |     <resultMap id="PCBaseResultMap" type="com.ycwl.basic.model.pc.order.resp.OrderRespVO"> | ||||||
|         <id column="id" property="id"/> |         <id column="id" property="id"/> | ||||||
|  |         <result column="scenic_id" property="scenicId"/> | ||||||
|  |         <result column="scenic_name" property="scenicName"/> | ||||||
|         <result column="member_id" property="memberId"/> |         <result column="member_id" property="memberId"/> | ||||||
|         <result column="nickname" property="memberNickname"/> |         <result column="nickname" property="memberNickname"/> | ||||||
|         <result column="real_name" property="memberRealName"/> |         <result column="real_name" property="memberRealName"/> | ||||||
| @@ -120,10 +122,11 @@ | |||||||
|         delete from `order` where id = #{id} |         delete from `order` where id = #{id} | ||||||
|     </delete> |     </delete> | ||||||
|     <select id="list" resultMap="PCBaseResultMap"> |     <select id="list" resultMap="PCBaseResultMap"> | ||||||
|         select distinct o.id, o.member_id,m.nickname ,m.real_name , o.openid, o.price, pay_price, remark, o.broker_id, o.promo_code, |         select distinct o.id, o.scenic_id, s.name as scenic_name, o.member_id,m.nickname ,m.real_name , o.openid, o.price, pay_price, remark, o.broker_id, o.promo_code, | ||||||
|                refund_reason, refund_status, o.`status`, refund_at, pay_at, cancel_at, o.goods_type |                refund_reason, refund_status, o.`status`, refund_at, pay_at, cancel_at,oi.id oiId, o.goods_type, oi.goods_id | ||||||
|         from `order`  AS o |         from `order`  AS o | ||||||
|         left join member m on o.member_id = m.id |         left join member m on o.member_id = m.id | ||||||
|  |         left join scenic s on o.scenic_id = s.id | ||||||
|         left join order_item oi on o.id = oi.order_id |         left join order_item oi on o.id = oi.order_id | ||||||
|         left join source sr on o.goods_type='2' and oi.goods_id = sr.id |         left join source sr on o.goods_type='2' and oi.goods_id = sr.id | ||||||
|         left join video vd on o.goods_type='1' and oi.goods_id = vd.id |         left join video vd on o.goods_type='1' and oi.goods_id = vd.id | ||||||
| @@ -131,6 +134,9 @@ | |||||||
|             <if test="id!= null "> |             <if test="id!= null "> | ||||||
|                 and o.id = #{id} |                 and o.id = #{id} | ||||||
|             </if> |             </if> | ||||||
|  |             <if test="scenicId != null"> | ||||||
|  |                 and o.scenic_id = #{scenicId} | ||||||
|  |             </if> | ||||||
|             <if test="memberNickname!= null and memberNickname!=''"> |             <if test="memberNickname!= null and memberNickname!=''"> | ||||||
|                 and m.nickname like concat('%',#{memberNickname},'%') |                 and m.nickname like concat('%',#{memberNickname},'%') | ||||||
|             </if> |             </if> | ||||||
| @@ -189,11 +195,12 @@ | |||||||
|         order by o.create_at desc |         order by o.create_at desc | ||||||
|     </select> |     </select> | ||||||
|     <select id="getById" resultMap="PCBaseResultMap"> |     <select id="getById" resultMap="PCBaseResultMap"> | ||||||
|         select o.id, o.member_id, o.openid, o.price, o.pay_price, o.remark, o.broker_id, o.promo_code, o.refund_reason, |         select o.id, o.scenic_id, s.name as scenic_name, o.member_id, o.openid, o.price, o.pay_price, o.remark, o.broker_id, o.promo_code, o.refund_reason, | ||||||
|                o.refund_status, o.status, o.create_at, o.update_at, o.pay_at, o.cancel_at, o.refund_at, |                o.refund_status, o.status, o.create_at, o.update_at, o.pay_at, o.cancel_at, o.refund_at, | ||||||
|                m.nickname , m.real_name |                m.nickname , m.real_name | ||||||
|             from `order` o |             from `order` o | ||||||
|         left join member m on m.id = o.member_id |         left join member m on m.id = o.member_id | ||||||
|  |         left join scenic s on o.scenic_id = s.id | ||||||
|         left join order_item oi on o.id = oi.order_id |         left join order_item oi on o.id = oi.order_id | ||||||
|         left join template t on o.goods_type='3' and oi.goods_id = t.id |         left join template t on o.goods_type='3' and oi.goods_id = t.id | ||||||
|         left join source sr on o.goods_type='2' and oi.goods_id = sr.id |         left join source sr on o.goods_type='2' and oi.goods_id = sr.id | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||||||
| <mapper namespace="com.ycwl.basic.mapper.pc.ScenicMapper"> | <mapper namespace="com.ycwl.basic.mapper.pc.ScenicMapper"> | ||||||
|     <insert id="add"> |     <insert id="add"> | ||||||
|         insert into scenic(id, `name`, introduction,cover_url, longitude, latitude, radius, province, city, area, address) |         insert into scenic(id, `name`, introduction, phone, cover_url, longitude, latitude, radius, province, city, area, address) | ||||||
|         values (#{id}, #{name}, #{introduction}, #{coverUrl},#{longitude}, #{latitude}, #{radius}, #{province}, #{city}, #{area}, #{address}) |         values (#{id}, #{name}, #{introduction}, #{phone}, #{coverUrl},#{longitude}, #{latitude}, #{radius}, #{province}, #{city}, #{area}, #{address}) | ||||||
|     </insert> |     </insert> | ||||||
|     <insert id="addConfig"> |     <insert id="addConfig"> | ||||||
|         insert into scenic_config(id, scenic_id, start_time, end_time, is_default) |         insert into scenic_config(id, scenic_id, start_time, end_time, is_default) | ||||||
| @@ -79,16 +79,14 @@ | |||||||
|     <delete id="deleteById"> |     <delete id="deleteById"> | ||||||
|         delete from scenic where id = #{id} |         delete from scenic where id = #{id} | ||||||
|     </delete> |     </delete> | ||||||
|     <delete id="deleteConfigByscenicId"> |     <delete id="deleteConfigByScenicId"> | ||||||
|         delete from scenic_config where scenic_id = #{scenicId} |         delete from scenic_config where scenic_id = #{scenicId} | ||||||
|     </delete> |     </delete> | ||||||
|     <select id="list" resultMap="scenicAndConfig"> |     <select id="list" resultMap="scenic"> | ||||||
|         select s.id, `name`, `phone`, introduction,cover_url, longitude, latitude, radius, province, city, area, address, `status`, s.create_time, update_time, |         select s.id, `name`, `phone`, introduction,cover_url, longitude, latitude, radius, province, city, area, address, `status`, s.create_time, update_time, | ||||||
|         c.start_time, c.end_time, |  | ||||||
|         (select scenic_account.account from scenic_account where scenic_account.scenic_id = s.id and scenic_account.is_super = 1 limit 1) as account, |         (select scenic_account.account from scenic_account where scenic_account.scenic_id = s.id and scenic_account.is_super = 1 limit 1) as account, | ||||||
|         c.is_default, c.create_time createTime2,s.price |         s.price | ||||||
|             from scenic s |             from scenic s | ||||||
|             left join scenic_config c on s.id = c.id |  | ||||||
|         <where> |         <where> | ||||||
|             <if test="name!=null and name!=''"> |             <if test="name!=null and name!=''"> | ||||||
|                 and locate(#{name},`name`) > 0 |                 and locate(#{name},`name`) > 0 | ||||||
| @@ -113,11 +111,10 @@ | |||||||
|             </if> |             </if> | ||||||
|         </where> |         </where> | ||||||
|     </select> |     </select> | ||||||
|     <select id="getById" resultMap="scenicAndConfig"> |     <select id="getById" resultMap="scenic"> | ||||||
|         select s.id, `name`, `phone`, introduction,cover_url, longitude, latitude, radius, province, city, area, address, `status`, s.create_time, update_time, |         select s.id, `name`, `phone`, introduction,cover_url, longitude, latitude, radius, province, city, area, address, `status`, s.create_time, update_time, | ||||||
|             c.start_time, c.end_time, c.is_default, c.create_time createTime2,s.price |             s.price | ||||||
|         from scenic s |         from scenic s | ||||||
|                  left join scenic_config c on s.id = c.id |  | ||||||
|         where s.id = #{id} |         where s.id = #{id} | ||||||
|     </select> |     </select> | ||||||
|     <select id="appList" resultType="com.ycwl.basic.model.mobile.scenic.ScenicAppVO"> |     <select id="appList" resultType="com.ycwl.basic.model.mobile.scenic.ScenicAppVO"> | ||||||
| @@ -175,8 +172,13 @@ | |||||||
|         where `status` = 1 |         where `status` = 1 | ||||||
|         ORDER BY distance ASC |         ORDER BY distance ASC | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="getConfig" resultType="com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity"> | ||||||
|  |         select * | ||||||
|  |         from scenic_config | ||||||
|  |         where scenic_id = #{scenicId} | ||||||
|  |     </select> | ||||||
|  |  | ||||||
|     <resultMap id="scenicAndConfig" type="com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO"> |     <resultMap id="scenic" type="com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO"> | ||||||
|         <id property="id" column="id"/> |         <id property="id" column="id"/> | ||||||
|         <result property="name" column="name"/> |         <result property="name" column="name"/> | ||||||
|         <result property="phone" column="phone"/> |         <result property="phone" column="phone"/> | ||||||
| @@ -194,13 +196,5 @@ | |||||||
|         <result property="price" column="price"/> |         <result property="price" column="price"/> | ||||||
|         <result property="createTime" column="create_time"/> |         <result property="createTime" column="create_time"/> | ||||||
|         <result property="updateTime" column="update_time"/> |         <result property="updateTime" column="update_time"/> | ||||||
|         <association property="scenicConfig" javaType="com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity"> |  | ||||||
|             <id property="id" column="c.id"/> |  | ||||||
|             <result property="scenicId" column="s.id"/> |  | ||||||
|             <result property="startTime" column="c.start_time"/> |  | ||||||
|             <result property="endTime" column="c.end_time"/> |  | ||||||
|             <result property="isDefault" column="c.is_default"/> |  | ||||||
|             <result property="createTime" column="createTime2"/> |  | ||||||
|         </association> |  | ||||||
|     </resultMap> |     </resultMap> | ||||||
| </mapper> | </mapper> | ||||||
| @@ -10,6 +10,7 @@ | |||||||
|         <set> |         <set> | ||||||
|             <if test="workerId!= null">worker_id = #{workerId}, </if> |             <if test="workerId!= null">worker_id = #{workerId}, </if> | ||||||
|             <if test="memberId!= null">member_id = #{memberId}, </if> |             <if test="memberId!= null">member_id = #{memberId}, </if> | ||||||
|  |             <if test="faceId!= null">face_id = #{faceId}, </if> | ||||||
|             <if test="templateId!= null">template_id = #{templateId}, </if> |             <if test="templateId!= null">template_id = #{templateId}, </if> | ||||||
|             <if test="scenicId!= null">scenic_id = #{scenicId}, </if> |             <if test="scenicId!= null">scenic_id = #{scenicId}, </if> | ||||||
|             <if test="taskParams!= null">task_params = #{taskParams}, </if> |             <if test="taskParams!= null">task_params = #{taskParams}, </if> | ||||||
| @@ -26,7 +27,7 @@ | |||||||
|     </update> |     </update> | ||||||
|     <update id="assignToWorker"> |     <update id="assignToWorker"> | ||||||
|         update task |         update task | ||||||
|         set worker_id = #{workerId} |         set worker_id = #{workerId}, status = 2 | ||||||
|         where id = #{taskId} |         where id = #{taskId} | ||||||
|     </update> |     </update> | ||||||
|     <update id="deassign"> |     <update id="deassign"> | ||||||
|   | |||||||
| @@ -5,6 +5,10 @@ | |||||||
|         insert into template(id, scenic_id, `name`, pid, is_placeholder, source_url, luts, overlays, audios, cover_url, frame_rate, speed, price) |         insert into template(id, scenic_id, `name`, pid, is_placeholder, source_url, luts, overlays, audios, cover_url, frame_rate, speed, price) | ||||||
|         values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}) |         values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}) | ||||||
|     </insert> |     </insert> | ||||||
|  |     <insert id="addConfig"> | ||||||
|  |         insert into template_config(template_id, is_default, minimal_placeholder_fill) | ||||||
|  |         values (#{templateId}, #{isDefault}, #{minimalPlaceholderFill}) | ||||||
|  |     </insert> | ||||||
|     <update id="update"> |     <update id="update"> | ||||||
|         update template |         update template | ||||||
|         <set> |         <set> | ||||||
| @@ -35,6 +39,14 @@ | |||||||
|                     END) |                     END) | ||||||
|         where id = #{id} |         where id = #{id} | ||||||
|     </update> |     </update> | ||||||
|  |     <update id="updateConfigById"> | ||||||
|  |         update template_config | ||||||
|  |         <set> | ||||||
|  |             <if test="isDefault!= null">is_default = #{isDefault}, </if> | ||||||
|  |             <if test="minimalPlaceholderFill!= null">minimal_placeholder_fill = #{minimalPlaceholderFill}, </if> | ||||||
|  |         </set> | ||||||
|  |         where id = #{id} | ||||||
|  |     </update> | ||||||
|     <delete id="deleteById"> |     <delete id="deleteById"> | ||||||
|         delete from template where id = #{id} |         delete from template where id = #{id} | ||||||
|     </delete> |     </delete> | ||||||
| @@ -44,6 +56,12 @@ | |||||||
|     <delete id="deleteByScenicId"> |     <delete id="deleteByScenicId"> | ||||||
|         delete from template where scenic_id = #{id} |         delete from template where scenic_id = #{id} | ||||||
|     </delete> |     </delete> | ||||||
|  |     <delete id="deleteConfigByTemplateId"> | ||||||
|  |         delete from template_config where template_id = #{id} | ||||||
|  |     </delete> | ||||||
|  |     <delete id="deleteConfigById"> | ||||||
|  |         delete from template_config where id = #{id} | ||||||
|  |     </delete> | ||||||
|     <select id="list" resultType="com.ycwl.basic.model.pc.template.resp.TemplateRespVO"> |     <select id="list" resultType="com.ycwl.basic.model.pc.template.resp.TemplateRespVO"> | ||||||
|         select t.id, t.scenic_id, s.name as scenic_name, t.`name`, t.cover_url, t.status, t.create_time, t.update_time |         select t.id, t.scenic_id, s.name as scenic_name, t.`name`, t.cover_url, t.status, t.create_time, t.update_time | ||||||
|         from template t left join scenic s on s.id = t.scenic_id |         from template t left join scenic s on s.id = t.scenic_id | ||||||
| @@ -55,6 +73,7 @@ | |||||||
|                 and scenic_id = #{scenicId} |                 and scenic_id = #{scenicId} | ||||||
|             </if> |             </if> | ||||||
|             <if test="name!= null">and locate(#{name},t.`name`) > 0 </if> |             <if test="name!= null">and locate(#{name},t.`name`) > 0 </if> | ||||||
|  |             <if test="scenicId!= null">and t.scenic_id = #{scenicId} </if> | ||||||
|             <if test="isPlaceholder!= null">and is_placeholder = #{isPlaceholder} </if> |             <if test="isPlaceholder!= null">and is_placeholder = #{isPlaceholder} </if> | ||||||
|             <if test="status!= null">and t.`status` = #{status} </if> |             <if test="status!= null">and t.`status` = #{status} </if> | ||||||
|             <if test="startTime!= null">and t.create_time >= #{startTime} </if> |             <if test="startTime!= null">and t.create_time >= #{startTime} </if> | ||||||
| @@ -71,4 +90,7 @@ | |||||||
|         from template t left join scenic s on s.id = t.scenic_id |         from template t left join scenic s on s.id = t.scenic_id | ||||||
|         where pid = #{id} |         where pid = #{id} | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="getConfig" resultType="com.ycwl.basic.model.pc.template.entity.TemplateConfigEntity"> | ||||||
|  |         select * from template_config where template_id = #{templateId} | ||||||
|  |     </select> | ||||||
| </mapper> | </mapper> | ||||||
| @@ -49,4 +49,7 @@ | |||||||
|         left join template t on v.template_id = t.id |         left join template t on v.template_id = t.id | ||||||
|         where v.id = #{id} |         where v.id = #{id} | ||||||
|     </select> |     </select> | ||||||
|  |     <select id="findByTaskId" resultType="com.ycwl.basic.model.pc.video.entity.VideoEntity"> | ||||||
|  |         select * from video where task_id = #{taskId} limit 1 | ||||||
|  |     </select> | ||||||
| </mapper> | </mapper> | ||||||
		Reference in New Issue
	
	Block a user