From 8c81a994c860d555808ee3ee749156be9ca67789 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Wed, 11 Dec 2024 15:38:18 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BA=BA=E8=84=B8?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E8=A7=86=E9=A2=91=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=88=A0=E9=99=A4=E6=BA=90=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=B8=B2=E6=9F=93=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=88=A0=E9=99=A4=E4=BA=BA=E8=84=B8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ycwl/basic/device/DeviceFactory.java | 45 +++ .../com/ycwl/basic/device/IDeviceCommon.java | 9 + .../device/checker/IDeviceStatusChecker.java | 7 + .../checker/helper/CommonDeviceChecker.java | 23 ++ .../checker/impl/AliOssDeviceChecker.java | 88 +++++ .../checker/impl/AlwaysOnDeviceChecker.java | 20 + .../entity/alioss/DeviceAliOssConfig.java | 14 + .../device/entity/common/FileObject.java | 15 + .../entity/local/DeviceLocalConfig.java | 7 + .../device/enums/DeviceStoreTypeEnum.java | 23 ++ .../operator/IDeviceStorageOperator.java | 26 ++ .../operator/helper/CommonPieceGetter.java | 24 ++ .../operator/impl/AliOssStorageOperator.java | 151 +++++++ .../operator/impl/LocalStorageOperator.java | 26 ++ .../ycwl/basic/mapper/pc/DeviceMapper.java | 4 + .../com/ycwl/basic/mapper/pc/FaceMapper.java | 3 + .../basic/mapper/pc/FaceSampleMapper.java | 2 + .../ycwl/basic/mapper/pc/ScenicMapper.java | 3 +- .../ycwl/basic/mapper/pc/TemplateMapper.java | 6 + .../com/ycwl/basic/mapper/pc/VideoMapper.java | 3 + .../pc/device/entity/DeviceConfigEntity.java | 59 +++ .../model/pc/face/entity/FaceEntity.java | 1 + .../basic/model/pc/face/req/FaceReqQuery.java | 2 + .../model/pc/order/req/OrderReqQuery.java | 1 + .../model/pc/order/resp/OrderRespVO.java | 2 + .../pc/scenic/entity/ScenicConfigEntity.java | 17 + .../pc/scenic/req/ScenicAddOrUpdateReq.java | 3 - .../model/pc/scenic/resp/ScenicRespVO.java | 4 +- .../model/pc/source/entity/SourceEntity.java | 4 + .../template/entity/TemplateConfigEntity.java | 16 + .../service/impl/pc/MenuServiceImpl.java | 3 +- .../service/impl/pc/ScenicServiceImpl.java | 2 +- .../impl/task/TaskFaceServiceImpl.java | 14 +- .../impl/task/TaskTaskServiceImpl.java | 28 +- .../ycwl/basic/task/DynamicTaskGenerator.java | 142 +++++++ .../java/com/ycwl/basic/task/FaceCleaner.java | 35 ++ .../task/GetSpaceChinaMobileLiveSteamJob.java | 176 --------- .../ycwl/basic/task/VideoPieceCleaner.java | 49 +++ .../com/ycwl/basic/task/VideoPieceGetter.java | 370 ++++++++++++++++++ src/main/resources/mapper/pc/DeviceMapper.xml | 10 + src/main/resources/mapper/pc/FaceMapper.xml | 21 +- .../resources/mapper/pc/FaceSampleMapper.xml | 9 + src/main/resources/mapper/pc/OrderMapper.xml | 13 +- src/main/resources/mapper/pc/ScenicMapper.xml | 32 +- src/main/resources/mapper/pc/TaskMapper.xml | 3 +- .../resources/mapper/pc/TemplateMapper.xml | 22 ++ src/main/resources/mapper/pc/VideoMapper.xml | 3 + 47 files changed, 1318 insertions(+), 222 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/device/DeviceFactory.java create mode 100644 src/main/java/com/ycwl/basic/device/IDeviceCommon.java create mode 100644 src/main/java/com/ycwl/basic/device/checker/IDeviceStatusChecker.java create mode 100644 src/main/java/com/ycwl/basic/device/checker/helper/CommonDeviceChecker.java create mode 100644 src/main/java/com/ycwl/basic/device/checker/impl/AliOssDeviceChecker.java create mode 100644 src/main/java/com/ycwl/basic/device/checker/impl/AlwaysOnDeviceChecker.java create mode 100644 src/main/java/com/ycwl/basic/device/entity/alioss/DeviceAliOssConfig.java create mode 100644 src/main/java/com/ycwl/basic/device/entity/common/FileObject.java create mode 100644 src/main/java/com/ycwl/basic/device/entity/local/DeviceLocalConfig.java create mode 100644 src/main/java/com/ycwl/basic/device/enums/DeviceStoreTypeEnum.java create mode 100644 src/main/java/com/ycwl/basic/device/operator/IDeviceStorageOperator.java create mode 100644 src/main/java/com/ycwl/basic/device/operator/helper/CommonPieceGetter.java create mode 100644 src/main/java/com/ycwl/basic/device/operator/impl/AliOssStorageOperator.java create mode 100644 src/main/java/com/ycwl/basic/device/operator/impl/LocalStorageOperator.java create mode 100644 src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceConfigEntity.java create mode 100644 src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateConfigEntity.java create mode 100644 src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java create mode 100644 src/main/java/com/ycwl/basic/task/FaceCleaner.java delete mode 100644 src/main/java/com/ycwl/basic/task/GetSpaceChinaMobileLiveSteamJob.java create mode 100644 src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java create mode 100644 src/main/java/com/ycwl/basic/task/VideoPieceGetter.java diff --git a/src/main/java/com/ycwl/basic/device/DeviceFactory.java b/src/main/java/com/ycwl/basic/device/DeviceFactory.java new file mode 100644 index 0000000..812cec5 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/DeviceFactory.java @@ -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; + } +} diff --git a/src/main/java/com/ycwl/basic/device/IDeviceCommon.java b/src/main/java/com/ycwl/basic/device/IDeviceCommon.java new file mode 100644 index 0000000..58d1bd3 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/IDeviceCommon.java @@ -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); +} diff --git a/src/main/java/com/ycwl/basic/device/checker/IDeviceStatusChecker.java b/src/main/java/com/ycwl/basic/device/checker/IDeviceStatusChecker.java new file mode 100644 index 0000000..1235bac --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/checker/IDeviceStatusChecker.java @@ -0,0 +1,7 @@ +package com.ycwl.basic.device.checker; + +import com.ycwl.basic.device.IDeviceCommon; + +public interface IDeviceStatusChecker extends IDeviceCommon { + boolean checkDeviceStatus(); +} diff --git a/src/main/java/com/ycwl/basic/device/checker/helper/CommonDeviceChecker.java b/src/main/java/com/ycwl/basic/device/checker/helper/CommonDeviceChecker.java new file mode 100644 index 0000000..b1a5658 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/checker/helper/CommonDeviceChecker.java @@ -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 { + protected C config; + @Setter + protected DeviceEntity device; + @Setter + protected DeviceConfigEntity deviceConfig; + + public CommonDeviceChecker(String configJson) { + config = JSON.parseObject(configJson, getConfigClass()); + } + + @SuppressWarnings("unchecked") + private Class getConfigClass() { + return (Class) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + } +} diff --git a/src/main/java/com/ycwl/basic/device/checker/impl/AliOssDeviceChecker.java b/src/main/java/com/ycwl/basic/device/checker/impl/AliOssDeviceChecker.java new file mode 100644 index 0000000..a80c349 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/checker/impl/AliOssDeviceChecker.java @@ -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 implements IDeviceStatusChecker { + public AliOssDeviceChecker(String configJson) { + super(configJson); + } + + private OSS getClient() { + return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret()); + } + + private List getOssFileListByPrefix(String prefix) { + OSS ossClient = getClient(); + ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName()); + listObjectsV2Request.setPrefix(config.getPrefix() + prefix); + boolean isTruncated = true; + String continuationToken = null; + List 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 fileList = getOssFileListByPrefix(DateUtil.format(startTime, "yyyyMMdd/HHmm")); + if (fileList != null) { + return !fileList.isEmpty(); + } else { + return false; + } + } +} diff --git a/src/main/java/com/ycwl/basic/device/checker/impl/AlwaysOnDeviceChecker.java b/src/main/java/com/ycwl/basic/device/checker/impl/AlwaysOnDeviceChecker.java new file mode 100644 index 0000000..05ed4b2 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/checker/impl/AlwaysOnDeviceChecker.java @@ -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; + } +} diff --git a/src/main/java/com/ycwl/basic/device/entity/alioss/DeviceAliOssConfig.java b/src/main/java/com/ycwl/basic/device/entity/alioss/DeviceAliOssConfig.java new file mode 100644 index 0000000..0ae272a --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/entity/alioss/DeviceAliOssConfig.java @@ -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; +} diff --git a/src/main/java/com/ycwl/basic/device/entity/common/FileObject.java b/src/main/java/com/ycwl/basic/device/entity/common/FileObject.java new file mode 100644 index 0000000..27d51bd --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/entity/common/FileObject.java @@ -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; +} diff --git a/src/main/java/com/ycwl/basic/device/entity/local/DeviceLocalConfig.java b/src/main/java/com/ycwl/basic/device/entity/local/DeviceLocalConfig.java new file mode 100644 index 0000000..6293e1b --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/entity/local/DeviceLocalConfig.java @@ -0,0 +1,7 @@ +package com.ycwl.basic.device.entity.local; + +import lombok.Data; + +@Data +public class DeviceLocalConfig { +} diff --git a/src/main/java/com/ycwl/basic/device/enums/DeviceStoreTypeEnum.java b/src/main/java/com/ycwl/basic/device/enums/DeviceStoreTypeEnum.java new file mode 100644 index 0000000..5d24254 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/enums/DeviceStoreTypeEnum.java @@ -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; + } +} diff --git a/src/main/java/com/ycwl/basic/device/operator/IDeviceStorageOperator.java b/src/main/java/com/ycwl/basic/device/operator/IDeviceStorageOperator.java new file mode 100644 index 0000000..e8b28cd --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/operator/IDeviceStorageOperator.java @@ -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 getFileListByDtRange(Date startDate, Date endDate); + + /** + * 删除指定日期之前的文件,不包含指定的日期当天 + * + * @param date 指定日期,不包含指定日期当天 + * @return + */ + boolean removeFilesBeforeDate(Date date); +} diff --git a/src/main/java/com/ycwl/basic/device/operator/helper/CommonPieceGetter.java b/src/main/java/com/ycwl/basic/device/operator/helper/CommonPieceGetter.java new file mode 100644 index 0000000..9c73030 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/operator/helper/CommonPieceGetter.java @@ -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 { + protected C config; + @Setter + private DeviceEntity device; + @Setter + private DeviceConfigEntity deviceConfig; + + public CommonPieceGetter(String configJson) { + config = JSON.parseObject(configJson, getConfigClass()); + } + + @SuppressWarnings("unchecked") + private Class getConfigClass() { + return (Class) ((java.lang.reflect.ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + } + +} diff --git a/src/main/java/com/ycwl/basic/device/operator/impl/AliOssStorageOperator.java b/src/main/java/com/ycwl/basic/device/operator/impl/AliOssStorageOperator.java new file mode 100644 index 0000000..5f0e5f5 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/operator/impl/AliOssStorageOperator.java @@ -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 implements IDeviceStorageOperator { + public AliOssStorageOperator(String configJson) { + super(configJson); + } + + private OSS getClient() { + return new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret()); + } + + private List getOssObjectListByPrefix(String prefix) { + OSS ossClient = getClient(); + ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(config.getBucketName()); + listObjectsV2Request.setPrefix(config.getPrefix() + prefix); + boolean isTruncated = true; + String continuationToken = null; + List 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 getOssFileListByPrefix(String prefix) { + OSS ossClient = getClient(); + List 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 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 getFileListByDtRange(Date startDate, Date endDate) { + if (startDate == null || endDate == null) { + return null; + } + List 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 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); + } +} diff --git a/src/main/java/com/ycwl/basic/device/operator/impl/LocalStorageOperator.java b/src/main/java/com/ycwl/basic/device/operator/impl/LocalStorageOperator.java new file mode 100644 index 0000000..d321f85 --- /dev/null +++ b/src/main/java/com/ycwl/basic/device/operator/impl/LocalStorageOperator.java @@ -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 implements IDeviceStorageOperator { + public LocalStorageOperator(String configJson) { + super(configJson); + } + + @Override + public List getFileListByDtRange(Date startDate, Date endDate) { + return Collections.emptyList(); + } + + @Override + public boolean removeFilesBeforeDate(Date date) { + return false; + } +} diff --git a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java index 86f81df..bb983cb 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java @@ -1,6 +1,7 @@ package com.ycwl.basic.mapper.pc; 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.req.DeviceAddOrUpdateReq; import com.ycwl.basic.model.pc.device.req.DeviceReqQuery; @@ -24,7 +25,10 @@ public interface DeviceMapper { int update(DeviceAddOrUpdateReq deviceReqQuery); int updateStatus(Long id); + DeviceEntity getByDeviceId(Long deviceId); List listByScenicId(Long scenicId); ScenicDeviceCountVO deviceCountByScenicId(@Param("scenicId") Long scenicId,@Param("userId") Long userId); + + DeviceConfigEntity getConfigByDeviceId(Long deviceId); } diff --git a/src/main/java/com/ycwl/basic/mapper/pc/FaceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/FaceMapper.java index d9e95cc..7ebc1ac 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/FaceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/FaceMapper.java @@ -16,6 +16,7 @@ import java.util.List; @Mapper public interface FaceMapper { List list(FaceReqQuery faceReqQuery); + List listByScenicIdAndNotFinished(Long scenicId); FaceRespVO getById(Long id); int add(FaceEntity face); int deleteById(Long id); @@ -23,4 +24,6 @@ public interface FaceMapper { int update(FaceEntity face); FaceRespVO getByMemberId(Long userId); + + int finishedJourney(Long faceId); } diff --git a/src/main/java/com/ycwl/basic/mapper/pc/FaceSampleMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/FaceSampleMapper.java index a282bf0..cf41d0d 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/FaceSampleMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/FaceSampleMapper.java @@ -21,4 +21,6 @@ public interface FaceSampleMapper { int deleteById(Long id); int deleteByIds(@Param("list") List ids); int update(FaceSampleEntity faceSample); + + List listByIds(List list); } diff --git a/src/main/java/com/ycwl/basic/mapper/pc/ScenicMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/ScenicMapper.java index f80389f..f417196 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/ScenicMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/ScenicMapper.java @@ -30,6 +30,7 @@ public interface ScenicMapper { int updateStatus(Long id); + ScenicConfigEntity getConfig(Long scenicId); /** * 添加景区配置 * @@ -51,7 +52,7 @@ public interface ScenicMapper { * * @param scenicId */ - void deleteConfigByscenicId(Long scenicId); + void deleteConfigByScenicId(Long scenicId); List appList(ScenicReqQuery scenicReqQuery); diff --git a/src/main/java/com/ycwl/basic/mapper/pc/TemplateMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/TemplateMapper.java index 1305535..2f76cdb 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/TemplateMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/TemplateMapper.java @@ -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.req.TaskReqQuery; 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.req.TemplateReqQuery; import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; @@ -26,4 +27,9 @@ public interface TemplateMapper { int deleteByPid(Long pid); int deleteByScenicId(Long scenicId); List getByPid(Long id); + TemplateConfigEntity getConfig(Long templateId); + int addConfig(TemplateConfigEntity templateConfig); + int updateConfigById(TemplateConfigEntity templateConfigEntity); + int deleteConfigByTemplateId(Long templateId); + int deleteConfigById(Long id); } diff --git a/src/main/java/com/ycwl/basic/mapper/pc/VideoMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/VideoMapper.java index e6ab007..124afa1 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/VideoMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/VideoMapper.java @@ -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.req.VideoReqQuery; import com.ycwl.basic.model.pc.video.resp.VideoRespVO; +import lombok.NonNull; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -22,4 +23,6 @@ public interface VideoMapper { int add(VideoEntity task); int deleteById(Long id); int update(VideoEntity task); + + VideoEntity findByTaskId(@NonNull Long taskId); } diff --git a/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceConfigEntity.java b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceConfigEntity.java new file mode 100644 index 0000000..e37d35e --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceConfigEntity.java @@ -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; +} diff --git a/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java b/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java index 9db8b04..8c74f5a 100644 --- a/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/face/entity/FaceEntity.java @@ -16,6 +16,7 @@ import java.util.Date; public class FaceEntity { @TableId private Long id; + private Long scenicId; /** * 人脸得分 */ diff --git a/src/main/java/com/ycwl/basic/model/pc/face/req/FaceReqQuery.java b/src/main/java/com/ycwl/basic/model/pc/face/req/FaceReqQuery.java index e6014e4..cba2db3 100644 --- a/src/main/java/com/ycwl/basic/model/pc/face/req/FaceReqQuery.java +++ b/src/main/java/com/ycwl/basic/model/pc/face/req/FaceReqQuery.java @@ -16,6 +16,8 @@ import java.util.Date; @Data @ApiModel("人脸查询参数") public class FaceReqQuery extends BaseQueryParameterReq { + @ApiModelProperty("景区id") + private Long scenicId; @ApiModelProperty("会员id") private Long memberId; @ApiModelProperty("用户上传的人脸照片") diff --git a/src/main/java/com/ycwl/basic/model/pc/order/req/OrderReqQuery.java b/src/main/java/com/ycwl/basic/model/pc/order/req/OrderReqQuery.java index 55940f4..41c2b53 100644 --- a/src/main/java/com/ycwl/basic/model/pc/order/req/OrderReqQuery.java +++ b/src/main/java/com/ycwl/basic/model/pc/order/req/OrderReqQuery.java @@ -18,6 +18,7 @@ import java.util.Date; @ApiModel(value = "订单查询对象") public class OrderReqQuery extends BaseQueryParameterReq { private Long id; + private Long scenicId; private Long memberId; @ApiModelProperty("用户昵称") private String memberNickname; diff --git a/src/main/java/com/ycwl/basic/model/pc/order/resp/OrderRespVO.java b/src/main/java/com/ycwl/basic/model/pc/order/resp/OrderRespVO.java index b61d74d..bf6b9b9 100644 --- a/src/main/java/com/ycwl/basic/model/pc/order/resp/OrderRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/order/resp/OrderRespVO.java @@ -102,4 +102,6 @@ public class OrderRespVO { private Date refundAt; @ApiModelProperty("订单明细") private List orderItemList; + private Long scenicId; + private String scenicName; } diff --git a/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java b/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java index da1e9c6..2e04211 100644 --- a/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/scenic/entity/ScenicConfigEntity.java @@ -38,4 +38,21 @@ public class ScenicConfigEntity { */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; + + /** + * 预约流程,1-预约,2-在线,3-全部 + */ + private Integer bookRoutine; + /** + * 样本保存时间 + */ + private Integer sampleStoreDay; + /** + * 视频保存时间 + */ + private Integer videoStoreDay; + /** + * 最大行程时长 + */ + private Integer maxJourneyHour; } diff --git a/src/main/java/com/ycwl/basic/model/pc/scenic/req/ScenicAddOrUpdateReq.java b/src/main/java/com/ycwl/basic/model/pc/scenic/req/ScenicAddOrUpdateReq.java index 1cfe0c9..2ff5333 100644 --- a/src/main/java/com/ycwl/basic/model/pc/scenic/req/ScenicAddOrUpdateReq.java +++ b/src/main/java/com/ycwl/basic/model/pc/scenic/req/ScenicAddOrUpdateReq.java @@ -1,7 +1,6 @@ package com.ycwl.basic.model.pc.scenic.req; import com.fasterxml.jackson.annotation.JsonFormat; -import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -78,8 +77,6 @@ public class ScenicAddOrUpdateReq { private Date createTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date updateTime; - @ApiModelProperty("景区配置") - private ScenicConfigEntity scenicConfig; @ApiModelProperty("景区源素材价格,元") private BigDecimal price; diff --git a/src/main/java/com/ycwl/basic/model/pc/scenic/resp/ScenicRespVO.java b/src/main/java/com/ycwl/basic/model/pc/scenic/resp/ScenicRespVO.java index 6c5eb34..47f1008 100644 --- a/src/main/java/com/ycwl/basic/model/pc/scenic/resp/ScenicRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/scenic/resp/ScenicRespVO.java @@ -79,13 +79,11 @@ public class ScenicRespVO { * 状态 1启用0关闭 */ @ApiModelProperty("状态 1启用0关闭") - private String status; + private Integer status; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date updateTime; - @ApiModelProperty("景区配置") - private ScenicConfigEntity scenicConfig; @ApiModelProperty("景区源素材价格,元") private BigDecimal price; @ApiModelProperty("镜头数") diff --git a/src/main/java/com/ycwl/basic/model/pc/source/entity/SourceEntity.java b/src/main/java/com/ycwl/basic/model/pc/source/entity/SourceEntity.java index 97bf763..e3c9371 100644 --- a/src/main/java/com/ycwl/basic/model/pc/source/entity/SourceEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/source/entity/SourceEntity.java @@ -30,6 +30,10 @@ public class SourceEntity { * 所属用户 */ private Long memberId; + /** + * 人脸样本id + */ + private Long faceSampleId; /** * 原素材类型:1视频,2图像 */ diff --git a/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateConfigEntity.java b/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateConfigEntity.java new file mode 100644 index 0000000..02d81ff --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/pc/template/entity/TemplateConfigEntity.java @@ -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; +} diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/MenuServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/MenuServiceImpl.java index 2a32b77..f383a33 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/MenuServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/MenuServiceImpl.java @@ -7,6 +7,7 @@ import com.ycwl.basic.service.pc.MenuService; import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.SnowFlakeUtil; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @@ -15,7 +16,7 @@ import java.util.List; * @Author:longbinbin * @Date:2024/12/3 10:16 */ - +@Service public class MenuServiceImpl implements MenuService { @Autowired diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java index e67db49..4a2bfce 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java @@ -96,7 +96,7 @@ public class ScenicServiceImpl implements ScenicService { public ApiResponse deleteById(Long id) { int i = scenicMapper.deleteById(id); if (i > 0) { - scenicMapper.deleteConfigByscenicId(id); + scenicMapper.deleteConfigByScenicId(id); scenicAccountMapper.deleteByScenicId(id); return ApiResponse.success(true); }else { diff --git a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java index a0e0476..b38418b 100644 --- a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java @@ -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.req.FaceSampleReqQuery; import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; +import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import com.ycwl.basic.model.task.resp.AddFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.service.task.TaskFaceService; @@ -84,13 +85,12 @@ public class TaskFaceServiceImpl implements TaskFaceService { .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData) .map(Long::parseLong) .collect(Collectors.toList()); - faceEntity.setMatchSampleIds(StringUtils.joinWith(",", faceSampleIds)); + faceEntity.setMatchSampleIds(StringUtils.join(faceSampleIds, ",")); faceMapper.update(faceEntity); respVo.setSampleListIds(faceSampleIds); respVo.setScore(matchList.get(0).getQualitieScore()); return respVo; } catch (Exception e) { - e.printStackTrace(); log.error("人脸搜索失败:{}", e.getMessage()); throw new BaseException(e.getMessage()); } @@ -136,7 +136,15 @@ public class TaskFaceServiceImpl implements TaskFaceService { FaceSampleReqQuery query = new FaceSampleReqQuery(); query.setDeviceId(scenicId); 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 dayEnd = DateUtil.endOfDay(thatDay); query.setStartTime(dayStart); diff --git a/src/main/java/com/ycwl/basic/service/impl/task/TaskTaskServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/task/TaskTaskServiceImpl.java index f72d384..c9fdbe3 100644 --- a/src/main/java/com/ycwl/basic/service/impl/task/TaskTaskServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/task/TaskTaskServiceImpl.java @@ -8,6 +8,7 @@ import com.ycwl.basic.mapper.pc.RenderWorkerMapper; import com.ycwl.basic.mapper.pc.SourceMapper; import com.ycwl.basic.mapper.pc.TaskMapper; 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.faceSample.resp.FaceSampleRespVO; 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.template.req.TemplateReqQuery; 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.TaskReqVo; import com.ycwl.basic.model.task.req.WorkerAuthReqVo; @@ -57,6 +59,8 @@ public class TaskTaskServiceImpl implements TaskService { private SourceMapper sourceMapper; @Autowired private OssUtil ossUtil; + @Autowired + private VideoMapper videoMapper; private RenderWorkerEntity getWorker(@NonNull WorkerAuthReqVo req) { String accessKey = req.getAccessKey(); @@ -112,9 +116,7 @@ public class TaskTaskServiceImpl implements TaskService { } List taskList = taskMapper.selectNotRunning(); resp.setTasks(taskList); - taskList.forEach(task -> { - taskMapper.assignToWorker(task.getId(), worker.getId()); - }); + taskList.forEach(task -> taskMapper.assignToWorker(task.getId(), worker.getId())); // return Task return resp; } @@ -131,9 +133,7 @@ public class TaskTaskServiceImpl implements TaskService { } Map> sourcesMap = Arrays.stream(faceRespVO.getMatchSampleIds().split(",")) .map(Long::valueOf) - .map(sampleId -> { - return faceSampleMapper.getById(sampleId); - }) + .map(sampleId -> faceSampleMapper.getById(sampleId)) .filter(Objects::nonNull) .map(FaceSampleRespVO::getSourceId) .map(sourceId -> sourceMapper.getById(sourceId)) @@ -178,6 +178,22 @@ public class TaskTaskServiceImpl implements TaskService { taskUpdate.setStatus(1); taskUpdate.setWorkerId(worker.getId()); 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 diff --git a/src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java b/src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java new file mode 100644 index 0000000..41932b5 --- /dev/null +++ b/src/main/java/com/ycwl/basic/task/DynamicTaskGenerator.java @@ -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 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 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 placeholderList = new ArrayList<>(); + if (minimalPlaceholderFill == null) { + minimalPlaceholderFill = 0; + } + List 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 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 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 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); + } + } + } + } + } + } +} diff --git a/src/main/java/com/ycwl/basic/task/FaceCleaner.java b/src/main/java/com/ycwl/basic/task/FaceCleaner.java new file mode 100644 index 0000000..14c4b22 --- /dev/null +++ b/src/main/java/com/ycwl/basic/task/FaceCleaner.java @@ -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 scenicList = scenicMapper.list(scenicQuery); + scenicList.forEach(scenic -> { + log.info("当前景区{},开始删除人脸样本", scenic.getName()); + faceService.batchDeleteFace(scenic.getId()); + }); + } +} diff --git a/src/main/java/com/ycwl/basic/task/GetSpaceChinaMobileLiveSteamJob.java b/src/main/java/com/ycwl/basic/task/GetSpaceChinaMobileLiveSteamJob.java deleted file mode 100644 index 4740bff..0000000 --- a/src/main/java/com/ycwl/basic/task/GetSpaceChinaMobileLiveSteamJob.java +++ /dev/null @@ -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 liveSteamUrl = tuSpaceManageDao.getLiveSteamUrl(null, 2); -// List 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 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 pollList = (List) poll; -// String msg = doMsgSubscription(pollList); -// if (StrUtil.isBlank(msg)) { -// // 消息订阅失败,过一会儿再试试 -// List 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 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 deviceIdList =new ArrayList<>(30); -// //deviceIdList.add("2"); -// //deviceIdList.add("1"); -// // -// //List failDeviceIdList = new ArrayList<>(deviceIdList); -// //failMsgSubQueue.offer(failDeviceIdList); -// //deviceIdList = new ArrayList<>(); -// //List pollList = ( List) 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); -// } -// -// -// -//} diff --git a/src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java b/src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java new file mode 100644 index 0000000..aa44056 --- /dev/null +++ b/src/main/java/com/ycwl/basic/task/VideoPieceCleaner.java @@ -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 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("删除视频文件完成"); + } + } +} diff --git a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java new file mode 100644 index 0000000..43fe52d --- /dev/null +++ b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java @@ -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 fileList; + BigDecimal duration; + BigDecimal offsetStart; + String outputFile; + } + + public static LinkedBlockingQueue 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 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 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 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 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 inputFiles, BigDecimal offset, BigDecimal length, String outputFile) throws IOException { + List 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 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; + } + } + +} diff --git a/src/main/resources/mapper/pc/DeviceMapper.xml b/src/main/resources/mapper/pc/DeviceMapper.xml index d805506..1f3a26b 100644 --- a/src/main/resources/mapper/pc/DeviceMapper.xml +++ b/src/main/resources/mapper/pc/DeviceMapper.xml @@ -72,4 +72,14 @@ group by device_id )b on a.scenic_id = b.scenic_id + + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/FaceMapper.xml b/src/main/resources/mapper/pc/FaceMapper.xml index c74d2f1..b46b00d 100644 --- a/src/main/resources/mapper/pc/FaceMapper.xml +++ b/src/main/resources/mapper/pc/FaceMapper.xml @@ -2,12 +2,15 @@ - insert into face(id, score, member_id, face_url, match_sample_ids, first_match_rate, match_result) - values (#{id}, #{score}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult}) + insert into face(id, scenic_id, score, member_id, face_url, match_sample_ids, first_match_rate, match_result) + values (#{id}, #{scenicId}, #{score}, #{memberId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult}) update face + + scenic_id = #{scenicId}, + member_id = #{memberId}, @@ -29,6 +32,9 @@ where id = #{id} + + update face set finished_journey = 1 where id = #{id} + delete from face where id = #{id} @@ -42,7 +48,7 @@ + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/FaceSampleMapper.xml b/src/main/resources/mapper/pc/FaceSampleMapper.xml index 649539c..0cba491 100644 --- a/src/main/resources/mapper/pc/FaceSampleMapper.xml +++ b/src/main/resources/mapper/pc/FaceSampleMapper.xml @@ -85,4 +85,13 @@ from face_sample where id = #{id} + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/OrderMapper.xml b/src/main/resources/mapper/pc/OrderMapper.xml index 7429bbf..4c0695c 100644 --- a/src/main/resources/mapper/pc/OrderMapper.xml +++ b/src/main/resources/mapper/pc/OrderMapper.xml @@ -3,6 +3,8 @@ + + @@ -120,10 +122,11 @@ delete from `order` where id = #{id} + - 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 - left join scenic_config c on s.id = c.id where s.id = #{id} + - + @@ -194,13 +196,5 @@ - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/mapper/pc/TaskMapper.xml b/src/main/resources/mapper/pc/TaskMapper.xml index 7f67abb..23d21dd 100644 --- a/src/main/resources/mapper/pc/TaskMapper.xml +++ b/src/main/resources/mapper/pc/TaskMapper.xml @@ -10,6 +10,7 @@ worker_id = #{workerId}, member_id = #{memberId}, + face_id = #{faceId}, template_id = #{templateId}, scenic_id = #{scenicId}, task_params = #{taskParams}, @@ -26,7 +27,7 @@ update task - set worker_id = #{workerId} + set worker_id = #{workerId}, status = 2 where id = #{taskId} diff --git a/src/main/resources/mapper/pc/TemplateMapper.xml b/src/main/resources/mapper/pc/TemplateMapper.xml index 8cd6bb9..4d039ac 100644 --- a/src/main/resources/mapper/pc/TemplateMapper.xml +++ b/src/main/resources/mapper/pc/TemplateMapper.xml @@ -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) values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}) + + insert into template_config(template_id, is_default, minimal_placeholder_fill) + values (#{templateId}, #{isDefault}, #{minimalPlaceholderFill}) + update template @@ -35,6 +39,14 @@ END) where id = #{id} + + update template_config + + is_default = #{isDefault}, + minimal_placeholder_fill = #{minimalPlaceholderFill}, + + where id = #{id} + delete from template where id = #{id} @@ -44,6 +56,12 @@ delete from template where scenic_id = #{id} + + delete from template_config where template_id = #{id} + + + delete from template_config where id = #{id} + + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/VideoMapper.xml b/src/main/resources/mapper/pc/VideoMapper.xml index 518e7ef..c25afa1 100644 --- a/src/main/resources/mapper/pc/VideoMapper.xml +++ b/src/main/resources/mapper/pc/VideoMapper.xml @@ -49,4 +49,7 @@ left join template t on v.template_id = t.id where v.id = #{id} + \ No newline at end of file From 68dbd6c38bc42d469c3e187ee97a98fe6348a8b6 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 12 Dec 2024 09:58:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E3=80=81=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E3=80=81=E6=99=AF=E5=8C=BA=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/controller/pc/DeviceController.java | 12 ++++++++++++ .../basic/controller/pc/ScenicController.java | 10 ++++++++++ .../controller/pc/TemplateController.java | 14 ++++++++++++++ .../ycwl/basic/mapper/pc/DeviceMapper.java | 2 ++ .../service/impl/pc/DeviceServiceImpl.java | 19 +++++++++++++++++++ .../service/impl/pc/ScenicServiceImpl.java | 19 +++++++++++++++++++ .../service/impl/pc/TemplateServiceImpl.java | 19 +++++++++++++++++++ .../ycwl/basic/service/pc/DeviceService.java | 4 ++++ .../ycwl/basic/service/pc/ScenicService.java | 3 +++ .../basic/service/pc/TemplateService.java | 5 +++++ src/main/resources/mapper/pc/DeviceMapper.xml | 15 +++++++++++++++ src/main/resources/mapper/pc/ScenicMapper.xml | 8 ++++++-- .../resources/mapper/pc/TemplateMapper.xml | 8 +++----- 13 files changed, 131 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/ycwl/basic/controller/pc/DeviceController.java b/src/main/java/com/ycwl/basic/controller/pc/DeviceController.java index 3d26644..fc84dd7 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/DeviceController.java +++ b/src/main/java/com/ycwl/basic/controller/pc/DeviceController.java @@ -1,6 +1,7 @@ package com.ycwl.basic.controller.pc; import com.github.pagehelper.PageInfo; +import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; 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.resp.DeviceRespVO; @@ -52,4 +53,15 @@ public class DeviceController { public ApiResponse updateStatus(@PathVariable("id") Long id) { return deviceService.updateStatus(id); } + + @GetMapping("/config/{id}") + public ApiResponse getConfig(@PathVariable("id") Long id) { + return ApiResponse.success(deviceService.getConfig(id)); + } + + @PostMapping("/saveConfig/{configId}") + public ApiResponse saveConfig(@PathVariable("configId") Long configId, @RequestBody DeviceConfigEntity deviceConfigEntity) { + deviceService.saveConfig(configId, deviceConfigEntity); + return ApiResponse.success(null); + } } diff --git a/src/main/java/com/ycwl/basic/controller/pc/ScenicController.java b/src/main/java/com/ycwl/basic/controller/pc/ScenicController.java index 2f5d892..669cf98 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/ScenicController.java +++ b/src/main/java/com/ycwl/basic/controller/pc/ScenicController.java @@ -72,4 +72,14 @@ public class ScenicController { return scenicService.updateConfigById(scenicConfig); } + @ApiOperation("查询景区配置") + @GetMapping("/config/{id}") + public ApiResponse getConfig(@PathVariable("id") Long id) { + return ApiResponse.success(scenicService.getConfig(id)); + } + @PostMapping("/saveConfig/{id}") + public ApiResponse saveConfig(@PathVariable("id") Long id, @RequestBody ScenicConfigEntity config) { + scenicService.saveConfig(id, config); + return ApiResponse.success(null); + } } diff --git a/src/main/java/com/ycwl/basic/controller/pc/TemplateController.java b/src/main/java/com/ycwl/basic/controller/pc/TemplateController.java index 3d2e358..bd830e2 100644 --- a/src/main/java/com/ycwl/basic/controller/pc/TemplateController.java +++ b/src/main/java/com/ycwl/basic/controller/pc/TemplateController.java @@ -1,6 +1,8 @@ package com.ycwl.basic.controller.pc; import com.github.pagehelper.PageInfo; +import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; +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.req.TemplateReqQuery; import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; @@ -60,4 +62,16 @@ public class TemplateController { public ApiResponse updateStatus(@RequestBody Long id) { return templateService.updateStatus(id); } + + + @GetMapping("/config/{id}") + public ApiResponse getConfig(@PathVariable("id") Long id) { + return ApiResponse.success(templateService.getConfig(id)); + } + + @PostMapping("/saveConfig/{configId}") + public ApiResponse saveConfig(@PathVariable("configId") Long configId, @RequestBody TemplateConfigEntity deviceConfigEntity) { + templateService.saveConfig(configId, deviceConfigEntity); + return ApiResponse.success(null); + } } diff --git a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java index bb983cb..b21bfcd 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java @@ -31,4 +31,6 @@ public interface DeviceMapper { ScenicDeviceCountVO deviceCountByScenicId(@Param("scenicId") Long scenicId,@Param("userId") Long userId); DeviceConfigEntity getConfigByDeviceId(Long deviceId); + int addConfig(DeviceConfigEntity deviceConfigEntity); + int updateConfig(DeviceConfigEntity deviceConfigEntity); } diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java index f521b87..87160e9 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/DeviceServiceImpl.java @@ -3,6 +3,7 @@ package com.ycwl.basic.service.impl.pc; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.ycwl.basic.mapper.pc.DeviceMapper; +import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; 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.resp.DeviceRespVO; @@ -65,4 +66,22 @@ public class DeviceServiceImpl implements DeviceService { public ApiResponse updateStatus(Long id) { return ApiResponse.success(deviceMapper.updateStatus(id)); } + + @Override + public DeviceConfigEntity getConfig(Long id) { + DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(id); + if (config == null) { + config = new DeviceConfigEntity(); + config.setId(SnowFlakeUtil.getLongId()); + config.setDeviceId(id); + deviceMapper.addConfig(config); + } + return config; + } + + @Override + public void saveConfig(Long configId, DeviceConfigEntity config) { + config.setId(configId); + deviceMapper.updateConfig(config); + } } diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java index 4a2bfce..e0f18ef 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/ScenicServiceImpl.java @@ -167,6 +167,25 @@ public class ScenicServiceImpl implements ScenicService { } } + @Override + public ScenicConfigEntity getConfig(Long id) { + ScenicConfigEntity config = scenicMapper.getConfig(id); + if (config == null) { + config = new ScenicConfigEntity(); + config.setId(SnowFlakeUtil.getLongId()); + config.setScenicId(id); + config.setIsDefault(1); + scenicMapper.addConfig(config); + } + return config; + } + + @Override + public void saveConfig(Long configId, ScenicConfigEntity config) { + config.setId(configId); + scenicMapper.updateConfigById(config); + } + private IAcsClient getClient() { DefaultProfile profile = DefaultProfile.getProfile( faceDetectConfig.getRegion(),faceDetectConfig.getAccessKeyId(), faceDetectConfig.getAccessKeySecret()); diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/TemplateServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/TemplateServiceImpl.java index e63e430..c4be60e 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/TemplateServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/TemplateServiceImpl.java @@ -3,6 +3,7 @@ package com.ycwl.basic.service.impl.pc; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.ycwl.basic.mapper.pc.TemplateMapper; +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.req.TemplateReqQuery; import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; @@ -104,4 +105,22 @@ public class TemplateServiceImpl implements TemplateService { return ApiResponse.fail("更新模版状态失败"); } } + + @Override + public TemplateConfigEntity getConfig(Long templateId) { + TemplateConfigEntity config = templateMapper.getConfig(templateId); + if (config == null) { + config = new TemplateConfigEntity(); + config.setId(SnowFlakeUtil.getLongId()); + config.setTemplateId(templateId); + templateMapper.addConfig(config); + } + return config; + } + + @Override + public void saveConfig(Long configId, TemplateConfigEntity config) { + config.setId(configId); + templateMapper.updateConfigById(config); + } } diff --git a/src/main/java/com/ycwl/basic/service/pc/DeviceService.java b/src/main/java/com/ycwl/basic/service/pc/DeviceService.java index b3e5b5e..8ff3d27 100644 --- a/src/main/java/com/ycwl/basic/service/pc/DeviceService.java +++ b/src/main/java/com/ycwl/basic/service/pc/DeviceService.java @@ -1,6 +1,7 @@ package com.ycwl.basic.service.pc; import com.github.pagehelper.PageInfo; +import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity; 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.resp.DeviceRespVO; @@ -20,4 +21,7 @@ public interface DeviceService { ApiResponse addOrUpdate(DeviceAddOrUpdateReq deviceReqQuery); ApiResponse deleteById(Long id); ApiResponse updateStatus(Long id); + + DeviceConfigEntity getConfig(Long id); + void saveConfig(Long configId, DeviceConfigEntity config); } diff --git a/src/main/java/com/ycwl/basic/service/pc/ScenicService.java b/src/main/java/com/ycwl/basic/service/pc/ScenicService.java index 008ed17..83acdee 100644 --- a/src/main/java/com/ycwl/basic/service/pc/ScenicService.java +++ b/src/main/java/com/ycwl/basic/service/pc/ScenicService.java @@ -28,4 +28,7 @@ public interface ScenicService { * @return */ ApiResponse updateConfigById(ScenicConfigEntity scenicConfig); + + ScenicConfigEntity getConfig(Long id); + void saveConfig(Long configId, ScenicConfigEntity config); } diff --git a/src/main/java/com/ycwl/basic/service/pc/TemplateService.java b/src/main/java/com/ycwl/basic/service/pc/TemplateService.java index 630b2c3..f1374a4 100644 --- a/src/main/java/com/ycwl/basic/service/pc/TemplateService.java +++ b/src/main/java/com/ycwl/basic/service/pc/TemplateService.java @@ -1,6 +1,7 @@ package com.ycwl.basic.service.pc; import com.github.pagehelper.PageInfo; +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.req.TemplateReqQuery; import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; @@ -21,4 +22,8 @@ public interface TemplateService { ApiResponse deleteById(Long id); ApiResponse update(TemplateEntity template); ApiResponse updateStatus(Long id); + + TemplateConfigEntity getConfig(Long templateId); + + void saveConfig(Long configId, TemplateConfigEntity config); } diff --git a/src/main/resources/mapper/pc/DeviceMapper.xml b/src/main/resources/mapper/pc/DeviceMapper.xml index 1f3a26b..15e7374 100644 --- a/src/main/resources/mapper/pc/DeviceMapper.xml +++ b/src/main/resources/mapper/pc/DeviceMapper.xml @@ -4,6 +4,10 @@ insert into device(id, scenic_id, name, no, latitude, longitude) values (#{id}, #{scenicId}, #{name}, #{no}, #{latitude}, #{longitude}) + + insert into device_config(id, device_id, create_time) + values (#{id}, #{deviceId}, now()) + update device set scenic_id = #{scenicId}, name = #{name}, no = #{no}, longitude = #{longitude}, latitude = #{latitude}, update_at = now() where id = #{id} @@ -19,6 +23,17 @@ END) where id = #{id} + + update device_config + set store_type = #{storeType}, + store_config_json = #{storeConfigJson}, + store_expire_day = #{storeExpireDay}, + online_check = #{onlineCheck}, + online_max_interval = #{onlineMaxInterval}, + cut_pre = #{cutPre}, + cut_post = #{cutPost} + where id = #{id} + delete from device where id = #{id} diff --git a/src/main/resources/mapper/pc/ScenicMapper.xml b/src/main/resources/mapper/pc/ScenicMapper.xml index 153c08c..56fefcc 100644 --- a/src/main/resources/mapper/pc/ScenicMapper.xml +++ b/src/main/resources/mapper/pc/ScenicMapper.xml @@ -6,8 +6,8 @@ values (#{id}, #{name}, #{introduction}, #{phone}, #{coverUrl},#{longitude}, #{latitude}, #{radius}, #{province}, #{city}, #{area}, #{address}) - insert into scenic_config(id, scenic_id, start_time, end_time, is_default) - values (#{id}, #{scenicId}, #{startTime}, #{endTime}, #{isDefault}) + insert into scenic_config(id, scenic_id, create_time) + values (#{id}, #{scenicId}, now()) update @@ -73,6 +73,10 @@ is_default=#{isDefault}, + book_routine=#{bookRoutine}, + sample_store_day=#{sampleStoreDay}, + video_store_day=#{videoStoreDay}, + max_journey_hour=#{maxJourneyHour}, where id = #{id} diff --git a/src/main/resources/mapper/pc/TemplateMapper.xml b/src/main/resources/mapper/pc/TemplateMapper.xml index 4d039ac..020744b 100644 --- a/src/main/resources/mapper/pc/TemplateMapper.xml +++ b/src/main/resources/mapper/pc/TemplateMapper.xml @@ -6,8 +6,8 @@ values (#{id}, #{scenicId}, #{name}, #{pid}, #{isPlaceholder}, #{sourceUrl}, #{luts}, #{overlays}, #{audios}, #{coverUrl}, #{frameRate}, #{speed}, #{price}) - insert into template_config(template_id, is_default, minimal_placeholder_fill) - values (#{templateId}, #{isDefault}, #{minimalPlaceholderFill}) + insert into template_config(id, template_id, create_time) + values (#{id}, #{templateId}, now()) update template @@ -66,9 +66,7 @@ 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 - - pid = #{pid} - + pid = 0 and scenic_id = #{scenicId} From 118af81ac6438d4093bed824634639f217c967b4 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 12 Dec 2024 14:38:15 +0800 Subject: [PATCH 3/3] =?UTF-8?q?GA/T=201400=E5=8D=8F=E8=AE=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/task/TaskTaskController.java | 2 + .../basic/controller/viid/ViidController.java | 269 ++++++++++++++++++ .../ycwl/basic/mapper/pc/DeviceMapper.java | 6 + .../model/pc/device/entity/DeviceEntity.java | 11 + .../model/pc/device/resp/DeviceRespVO.java | 5 + .../model/viid/entity/DeviceIdObject.java | 14 + .../model/viid/entity/FaceListObject.java | 12 + .../basic/model/viid/entity/FaceObject.java | 169 +++++++++++ .../viid/entity/ResponseStatusObject.java | 21 ++ .../model/viid/entity/SubImageInfoObject.java | 28 ++ .../basic/model/viid/entity/SubImageList.java | 13 + .../model/viid/entity/SystemTimeObject.java | 18 ++ .../basic/model/viid/req/FaceUploadReq.java | 11 + .../basic/model/viid/req/KeepaliveReq.java | 11 + .../basic/model/viid/req/RegisterReq.java | 11 + .../basic/model/viid/req/UnRegisterReq.java | 12 + .../basic/model/viid/resp/SystemTimeResp.java | 13 + .../basic/model/viid/resp/VIIDBaseResp.java | 15 + .../impl/task/TaskFaceServiceImpl.java | 7 +- .../com/ycwl/basic/utils/AliFaceUtil.java | 21 ++ .../java/com/ycwl/basic/utils/ImageUtils.java | 79 +++++ .../java/com/ycwl/basic/utils/IpUtils.java | 175 ++++++++++++ src/main/resources/mapper/pc/DeviceMapper.xml | 23 +- .../resources/mapper/pc/FaceSampleMapper.xml | 10 +- src/main/resources/mapper/pc/SourceMapper.xml | 8 +- 25 files changed, 953 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/controller/viid/ViidController.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java create mode 100644 src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java create mode 100644 src/main/java/com/ycwl/basic/utils/AliFaceUtil.java create mode 100644 src/main/java/com/ycwl/basic/utils/ImageUtils.java create mode 100644 src/main/java/com/ycwl/basic/utils/IpUtils.java diff --git a/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java b/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java index 3585405..335c5b9 100644 --- a/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java +++ b/src/main/java/com/ycwl/basic/controller/task/TaskTaskController.java @@ -7,6 +7,7 @@ import com.ycwl.basic.model.task.req.WorkerAuthReqVo; import com.ycwl.basic.model.task.resp.TaskSyncRespVo; import com.ycwl.basic.service.task.TaskService; import com.ycwl.basic.utils.ApiResponse; +import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; @IgnoreToken @RestController +@Api(tags = "渲染端对接接口") @RequestMapping("/task/v1/") public class TaskTaskController { diff --git a/src/main/java/com/ycwl/basic/controller/viid/ViidController.java b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java new file mode 100644 index 0000000..80550bd --- /dev/null +++ b/src/main/java/com/ycwl/basic/controller/viid/ViidController.java @@ -0,0 +1,269 @@ +package com.ycwl.basic.controller.viid; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.ycwl.basic.annotation.IgnoreToken; +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.DeviceEntity; +import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; +import com.ycwl.basic.model.pc.source.entity.SourceEntity; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import com.ycwl.basic.model.viid.entity.FaceListObject; +import com.ycwl.basic.model.viid.entity.FaceObject; +import com.ycwl.basic.model.viid.entity.ResponseStatusObject; +import com.ycwl.basic.model.viid.entity.SubImageInfoObject; +import com.ycwl.basic.model.viid.entity.SubImageList; +import com.ycwl.basic.model.viid.entity.SystemTimeObject; +import com.ycwl.basic.model.viid.req.FaceUploadReq; +import com.ycwl.basic.model.viid.req.KeepaliveReq; +import com.ycwl.basic.model.viid.req.RegisterReq; +import com.ycwl.basic.model.viid.req.UnRegisterReq; +import com.ycwl.basic.model.viid.resp.SystemTimeResp; +import com.ycwl.basic.model.viid.resp.VIIDBaseResp; +import com.ycwl.basic.service.task.TaskFaceService; +import com.ycwl.basic.utils.AliFaceUtil; +import com.ycwl.basic.utils.ImageUtils; +import com.ycwl.basic.utils.IpUtils; +import com.ycwl.basic.utils.OssUtil; +import com.ycwl.basic.utils.SnowFlakeUtil; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +@IgnoreToken +@RestController +@Api(tags = "摄像头对接接口") +@RequestMapping("/VIID") +@Slf4j +public class ViidController { + @Autowired + private DeviceMapper deviceMapper; + private static final String serverId = "00000000000000000001"; + @Autowired + private SourceMapper sourceMapper; + + // region 注册注销基础接口 + /** + * 注册接口 + * + * @param req 注册的信息 + * @param request 请求 + * @return 返回 + */ + @RequestMapping(value = "/System/Register", method = RequestMethod.POST) + public VIIDBaseResp register(@RequestBody RegisterReq req, HttpServletRequest request) { + DeviceIdObject deviceIdObject = req.getRegisterObject(); + log.info("注册的设备信息:{}", deviceIdObject); + // 保存设备注册时间 + DeviceEntity device = deviceMapper.getByDeviceNo(deviceIdObject.getDeviceId()); + if (device == null) { + device = new DeviceEntity(); + device.setName("未配置设备"); + device.setNo(deviceIdObject.getDeviceId()); + device.setOnline(1); + } + device.setKeepaliveAt(new Date()); + device.setIpAddr(IpUtils.getIpAddr(request)); + if (device.getId() != null) { + deviceMapper.updateEntity(device); + } else { + device.setId(SnowFlakeUtil.getLongId()); + deviceMapper.addEntity(device); + } + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(serverId, "/VIID/System/Register", "0", "注册成功", sdfTime.format(new Date())) + ); + } + + /** + * 保活接口 + * + * @param req 保活的设备信息 + * @param request 请求 + * @return 返回 + */ + @RequestMapping(value = "/System/Keepalive", method = RequestMethod.POST) + public VIIDBaseResp keepalive(@RequestBody KeepaliveReq req, HttpServletRequest request) { + DeviceIdObject keepaliveObject = req.getKeepaliveObject(); + log.info("对方发送的心跳的信息:{}", keepaliveObject); + + String deviceId = keepaliveObject.getDeviceId(); + DeviceEntity device = deviceMapper.getByDeviceNo(deviceId); + + // 判断设备状态 + if (device == null) { + // 不存在设备就注册 + device = new DeviceEntity(); + device.setName("未配置设备"); + device.setNo(deviceId); + device.setOnline(1); + device.setKeepaliveAt(new Date()); + device.setIpAddr(IpUtils.getIpAddr(request)); + device.setId(SnowFlakeUtil.getLongId()); + deviceMapper.addEntity(device); + } else { + device.setOnline(1); + device.setKeepaliveAt(new Date()); + deviceMapper.updateEntity(device); + } + log.info("已经解析过的心跳信息:{}", keepaliveObject); + + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(deviceId, "/VIID/System/UnRegister", "0", "注销成功", sdfTime.format(new Date())) + ); + } + + /** + * 注销设备 + * + * @param req 参数 + * @return 返回 + */ + @RequestMapping(value = "/System/UnRegister", method = RequestMethod.POST) + public VIIDBaseResp unRegister(@RequestBody UnRegisterReq req) { + // 获取设备id + DeviceIdObject unRegisterObject = req.getUnRegisterObject(); + String deviceId = unRegisterObject.getDeviceId(); + log.info("获取的注销的请求参数:{}", unRegisterObject); + + // 首先查询该设备是否存在 + DeviceEntity device = deviceMapper.getByDeviceNo(deviceId); + // 判断 + if (device != null) { + device.setOnline(0); + device.setKeepaliveAt(new Date()); + int update = deviceMapper.updateEntity(device); + } + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(deviceId, "/VIID/System/UnRegister", "0", "注销成功", sdfTime.format(new Date())) + ); + } + + /** + * 校时接口 + * + * @return 返回 + */ + @RequestMapping(value = "/System/Time", method = RequestMethod.GET) + public SystemTimeResp time() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + return new SystemTimeResp( + new SystemTimeObject(serverId, "2", sdf.format(new Date()), TimeZone.getTimeZone("Asia/Shanghai").toString()) + ); + } + + // endregion + + @Autowired + private FaceSampleMapper faceSampleMapper; + + @Autowired + private TaskFaceService taskFaceService; + @Autowired + private OssUtil ossUtil; + + + /** + * 批量新增人脸 + */ + @RequestMapping(value = "/Faces", method = RequestMethod.POST) + public VIIDBaseResp faces(@RequestBody FaceUploadReq req) { + log.info("收到的人脸上报信息:{}",req); + FaceListObject faceListObject = req.getFaceListObject(); + List faceObject = faceListObject.getFaceObject(); + String faceId = null; + // 遍历人脸列表 + for (FaceObject face : faceObject) { + // 设置FaceId + faceId = face.getFaceID(); + Long newFaceSampleId = SnowFlakeUtil.getLongId(); + // 获取图片信息 + SubImageList subImageList = face.getSubImageList(); + // 判断人脸对象中的列表是否为空 + String deviceID = face.getDeviceID(); + DeviceEntity device = deviceMapper.getByDeviceNo(deviceID); + if (device == null) { + continue; + } + Long scenicId = device.getScenicId(); + if (scenicId == null) { + continue; + } + if (ObjectUtil.isNotEmpty(subImageList) && CollUtil.isNotEmpty(subImageList.getSubImageInfoObject())) { + // 遍历每个图片对象 + for (SubImageInfoObject subImage : subImageList.getSubImageInfoObject()) { + // base64转换成MultipartFIle + MultipartFile file = ImageUtils.base64ToMultipartFile(subImage.getData()); + String ext = subImage.getFileFormat(); + if (ext.equalsIgnoreCase("jpeg")) { + ext = "jpg"; + } + // Type=11 人脸 + if (subImage.getType().equals("11")) { + // 上传oss + FaceSampleEntity faceSample = new FaceSampleEntity(); + faceSample.setId(newFaceSampleId); + faceSample.setScenicId(scenicId); + faceSample.setDeviceId(device.getId()); + faceSample.setStatus(0); + faceSample.setCreateAt(new Date()); + String url; + try { + url = ossUtil.uploadFile(file.getInputStream(), AliFaceUtil.generateEntityId(faceSample) + "." + ext); + } catch (IOException e) { + log.error("文件上传失败!", e); + continue; + } + faceSample.setFaceUrl(url); + faceSampleMapper.add(faceSample); + log.info("人脸信息入库成功!"); + taskFaceService.addFaceSample(faceSample.getId()); + } + // Type=14 场景图 + else if (subImage.getType().equals("14")) { + SourceEntity source = new SourceEntity(); + source.setId(SnowFlakeUtil.getLongId()); + source.setDeviceId(device.getId()); + source.setScenicId(device.getScenicId()); + source.setFaceSampleId(newFaceSampleId); + source.setType(2); + // 上传oss + String url; + try { + url = ossUtil.uploadFile(file.getInputStream(), "user-photo/", newFaceSampleId + "." + ext); + } catch (IOException e) { + log.error("文件上传失败!", e); + continue; + } + source.setUrl(url); + sourceMapper.add(source); + } + } + } + log.info("设备ID:{}", deviceID); + } + + SimpleDateFormat sdfTime = new SimpleDateFormat("yyyyMMddHHmmss"); + return new VIIDBaseResp( + new ResponseStatusObject(faceId, "/VIID/Faces", "0", "OK", sdfTime.format(new Date())) + ); + } + +} diff --git a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java index b21bfcd..f73994d 100644 --- a/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/pc/DeviceMapper.java @@ -33,4 +33,10 @@ public interface DeviceMapper { DeviceConfigEntity getConfigByDeviceId(Long deviceId); int addConfig(DeviceConfigEntity deviceConfigEntity); int updateConfig(DeviceConfigEntity deviceConfigEntity); + + DeviceEntity getByDeviceNo(String deviceNo); + + int updateEntity(DeviceEntity device); + + int addEntity(DeviceEntity device); } diff --git a/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java index 873a1b6..054f256 100644 --- a/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java +++ b/src/main/java/com/ycwl/basic/model/pc/device/entity/DeviceEntity.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; /** @@ -27,6 +28,14 @@ public class DeviceEntity { * 设备编号 */ private String no; + /** + * 经度 + */ + private BigDecimal longitude; + /*** + * 纬度 + */ + private BigDecimal latitude; /** * 是否启用,0不启用,1启用 */ @@ -35,6 +44,8 @@ public class DeviceEntity { * 是否在线,0不在线,1在线 */ private Integer online; + private String ipAddr; + private Date keepaliveAt; private Date createAt; private Date updateAt; } diff --git a/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java b/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java index bca82c8..b39c363 100644 --- a/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java +++ b/src/main/java/com/ycwl/basic/model/pc/device/resp/DeviceRespVO.java @@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; /** @@ -22,6 +23,10 @@ public class DeviceRespVO { private String name; @ApiModelProperty("设备编号") private String no; + @ApiModelProperty("经度") + private BigDecimal longitude; + @ApiModelProperty("纬度") + private BigDecimal latitude; @ApiModelProperty("是否启用,0不启用,1启用") private Integer status; @ApiModelProperty("是否在线,0不在线,1在线") diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java new file mode 100644 index 0000000..bf0bde1 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/DeviceIdObject.java @@ -0,0 +1,14 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class DeviceIdObject implements Serializable { + + @JsonProperty("DeviceID") + private String deviceId; + +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java new file mode 100644 index 0000000..cab924a --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/FaceListObject.java @@ -0,0 +1,12 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class FaceListObject { + @JsonProperty("FaceObject") + private List faceObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java new file mode 100644 index 0000000..88b35ed --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/FaceObject.java @@ -0,0 +1,169 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class FaceObject { + @JsonProperty("FaceID") + private String FaceID; + @JsonProperty("InfoKind") + private Integer InfoKind; + @JsonProperty("SourceID") + private String SourceID; + @JsonProperty("DeviceID") + private String DeviceID; + @JsonProperty("LeftTopX") + private Integer LeftTopX; + @JsonProperty("LeftTopY") + private Integer LeftTopY; + @JsonProperty("RightBtmX") + private Integer RightBtmX; + @JsonProperty("RightBtmY") + private Integer RightBtmY; + @JsonProperty("IDNumber") + private String IDNumber; + @JsonProperty("Name") + private String Name; + @JsonProperty("UsedName") + private String UsedName; + @JsonProperty("Alias") + private String Alias; + @JsonProperty("AgeUpLimit") + private Integer AgeUpLimit; + @JsonProperty("AgeLowerLimit") + private Integer AgeLowerLimit; + @JsonProperty("EthicCode") + private String EthicCode; + @JsonProperty("NationalityCode") + private String NationalityCode; + @JsonProperty("NativeCityCode") + private String NativeCityCode; + @JsonProperty("ResidenceAdminDivision") + private String ResidenceAdminDivision; + @JsonProperty("ChineseAccentCode") + private String ChineseAccentCode; + @JsonProperty("JobCategory") + private String JobCategory; + @JsonProperty("AccompanyNumber") + private Integer AccompanyNumber; + @JsonProperty("SkinColor") + private String SkinColor; + @JsonProperty("FaceStyle") + private String FaceStyle; + @JsonProperty("FacialFeature") + private String FacialFeature; + @JsonProperty("PhysicalFeature") + private String PhysicalFeature; + @JsonProperty("IsDriver") + private Integer IsDriver; + @JsonProperty("IsForeigner") + private Integer IsForeigner; + @JsonProperty("ImmigrantTypeCode") + private String ImmigrantTypeCode; + @JsonProperty("IsSuspectedTerrorist") + private Integer IsSuspectedTerrorist; + @JsonProperty("SuspectedTerroristNumber") + private String SuspectedTerroristNumber; + @JsonProperty("IsCriminalInvolved") + private Integer IsCriminalInvolved; + @JsonProperty("CriminalInvolvedSpecilisationCode") + private String CriminalInvolvedSpecilisationCode; + @JsonProperty("BodySpeciallMark") + private String BodySpeciallMark; + @JsonProperty("CrimeMethod") + private String CrimeMethod; + @JsonProperty("CrimeCharacterCode") + private String CrimeCharacterCode; + @JsonProperty("EscapedCriminalNumber") + private String EscapedCriminalNumber; + @JsonProperty("IsDetainees") + private Integer IsDetainees; + @JsonProperty("DetentionHouseCode") + private String DetentionHouseCode; + @JsonProperty("DetaineesSpecialIdentity") + private String DetaineesSpecialIdentity; + @JsonProperty("MemberTypeCode") + private String MemberTypeCode; + @JsonProperty("IsVictim") + private String IsVictim; + @JsonProperty("VictimType") + private String VictimType; + @JsonProperty("CorpseConditionCode") + private String CorpseConditionCode; + @JsonProperty("IsSuspiciousPerson") + private String IsSuspiciousPerson; + @JsonProperty("Attitude") + private String Attitude; + @JsonProperty("Similaritydegree") + private String Similaritydegree; + @JsonProperty("EyebrowStyle") + private String EyebrowStyle; + @JsonProperty("NoseStyle") + private String NoseStyle; + @JsonProperty("MustacheStyle") + private String MustacheStyle; + @JsonProperty("LipStyle") + private String LipStyle; + @JsonProperty("WrinklePouch") + private String WrinklePouch; + @JsonProperty("AcneStain") + private String AcneStain; + @JsonProperty("FreckleBirthmark") + private String FreckleBirthmark; + @JsonProperty("ScarDimple") + private String ScarDimple; + @JsonProperty("TabID") + private String TabID; + @JsonProperty("OtherFeature") + private String OtherFeature; + @JsonProperty("Maritalstatus") + private String Maritalstatus; + @JsonProperty("FamilyAddress") + private String FamilyAddress; + @JsonProperty("CollectorOrg") + private String CollectorOrg; + @JsonProperty("CollectorID") + private String CollectorID; + @JsonProperty("DeviceSNNo") + private String DeviceSNNo; + @JsonProperty("APSId") + private String APSId; + @JsonProperty("LocationMarkTime") + private String LocationMarkTime; + @JsonProperty("FaceAppearTime") + private String FaceAppearTime; + @JsonProperty("FaceDisAppearTime") + private String FaceDisAppearTime; + @JsonProperty("ShotTime") + private String ShotTime; + @JsonProperty("IDType") + private String IDType; + @JsonProperty("GenderCode") + private String GenderCode; + @JsonProperty("HairStyle") + private String HairStyle; + @JsonProperty("HairColor") + private String HairColor; + @JsonProperty("RespiratorColor") + private String RespiratorColor; + @JsonProperty("CapStyle") + private String CapStyle; + @JsonProperty("CapColor") + private String CapColor; + @JsonProperty("GlassStyle") + private String GlassStyle; + @JsonProperty("GlassColor") + private String GlassColor; + @JsonProperty("PassportType") + private String PassportType; + @JsonProperty("DetaineesIdentity") + private String DetaineesIdentity; + @JsonProperty("InjuredDegree") + private String InjuredDegree; + @JsonProperty("EntryTime") + private String EntryTime; + @JsonProperty("SubImageList") + private SubImageList subImageList; + +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java new file mode 100644 index 0000000..695ad50 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/ResponseStatusObject.java @@ -0,0 +1,21 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class ResponseStatusObject { + + @JsonProperty("Id") + private String id; + @JsonProperty("RequestURL") + private String requestUrl; + @JsonProperty("StatusCode") + private String statusCode; + @JsonProperty("StatusString") + private String statusString; + @JsonProperty("LocalTime") + private String localTime; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java new file mode 100644 index 0000000..71284d7 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageInfoObject.java @@ -0,0 +1,28 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class SubImageInfoObject { + @JsonProperty("ImageID") + private String ImageID; + @JsonProperty("EventSort") + private Integer EventSort; + @JsonProperty("DeviceID") + private String DeviceID; + @JsonProperty("StoragePath") + private String StoragePath; + @JsonProperty("Type") + private String Type; + @JsonProperty("FileFormat") + private String FileFormat; + @JsonProperty("Width") + private String Width; + @JsonProperty("Height") + private String Height; + @JsonProperty("ShotTime") + private String ShotTime; + @JsonProperty("Data") + private String Data; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java new file mode 100644 index 0000000..2723a04 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SubImageList.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class SubImageList { + + @JsonProperty("SubImageInfoObject") + private List subImageInfoObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java b/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java new file mode 100644 index 0000000..5630729 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/entity/SystemTimeObject.java @@ -0,0 +1,18 @@ +package com.ycwl.basic.model.viid.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SystemTimeObject { + @JsonProperty("VIIDServerID") + private String viidServerId; + @JsonProperty("TimeMode") + private String timeMode; + @JsonProperty("LocalTime") + private String localTime; + @JsonProperty("TimeZone") + private String timezone; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java b/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java new file mode 100644 index 0000000..d801527 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/FaceUploadReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.FaceListObject; +import lombok.Data; + +@Data +public class FaceUploadReq { + @JsonProperty("FaceListObject") + private FaceListObject faceListObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java b/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java new file mode 100644 index 0000000..efb3204 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/KeepaliveReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class KeepaliveReq { + @JsonProperty("KeepaliveObject") + private DeviceIdObject keepaliveObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java b/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java new file mode 100644 index 0000000..98e6ca1 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/RegisterReq.java @@ -0,0 +1,11 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class RegisterReq { + @JsonProperty("RegisterObject") + private DeviceIdObject registerObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java b/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java new file mode 100644 index 0000000..89051e5 --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/req/UnRegisterReq.java @@ -0,0 +1,12 @@ +package com.ycwl.basic.model.viid.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.DeviceIdObject; +import lombok.Data; + +@Data +public class UnRegisterReq { + + @JsonProperty("UnRegisterObject") + private DeviceIdObject unRegisterObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java b/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java new file mode 100644 index 0000000..f07801e --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/resp/SystemTimeResp.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.model.viid.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.SystemTimeObject; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SystemTimeResp { + @JsonProperty("SystemTimeObject") + private SystemTimeObject systemTimeObject; +} diff --git a/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java b/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java new file mode 100644 index 0000000..6fe80ae --- /dev/null +++ b/src/main/java/com/ycwl/basic/model/viid/resp/VIIDBaseResp.java @@ -0,0 +1,15 @@ +package com.ycwl.basic.model.viid.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ycwl.basic.model.viid.entity.ResponseStatusObject; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class VIIDBaseResp { + + @JsonProperty("ResponseStatusObject") + private ResponseStatusObject responseStatusObject; + +} diff --git a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java index b38418b..371bc5f 100644 --- a/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/task/TaskFaceServiceImpl.java @@ -25,6 +25,7 @@ import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity; import com.ycwl.basic.model.task.resp.AddFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.service.task.TaskFaceService; +import com.ycwl.basic.utils.AliFaceUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -102,8 +103,7 @@ public class TaskFaceServiceImpl implements TaskFaceService { FaceSampleRespVO faceSampleRespVO = faceSampleMapper.getById(faceSampleId); AddFaceEntityRequest request = new AddFaceEntityRequest(); request.setDbName(faceSampleRespVO.getScenicId().toString()); - SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); - String entityId = faceSampleRespVO.getDeviceId().toString() + "_" + sdf.format(faceSampleRespVO.getCreateAt()); + String entityId = AliFaceUtil.generateEntityId(faceSampleRespVO); request.setEntityId(entityId); IAcsClient client = getClient(); try { @@ -150,9 +150,8 @@ public class TaskFaceServiceImpl implements TaskFaceService { query.setStartTime(dayStart); query.setEndTime(dayEnd); IAcsClient client = getClient(); - SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); faceSampleMapper.list(query).forEach(faceSampleEntity -> { - String entityId = faceSampleEntity.getDeviceId().toString() + "_" + sdf.format(faceSampleEntity.getCreateAt()); + String entityId = AliFaceUtil.generateEntityId(faceSampleEntity); DeleteFaceEntityRequest request = new DeleteFaceEntityRequest(); request.setDbName(scenicId.toString()); request.setEntityId(entityId); diff --git a/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java b/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java new file mode 100644 index 0000000..658307f --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/AliFaceUtil.java @@ -0,0 +1,21 @@ +package com.ycwl.basic.utils; + +import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity; +import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO; + +import java.text.SimpleDateFormat; + +public class AliFaceUtil { + private static final String DATE_FORMAT="yyyyMMddHHmmssSSS"; + + public static String generateEntityId(FaceSampleEntity entity) { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); + String entityId = entity.getDeviceId().toString() + "_" + sdf.format(entity.getCreateAt()); + return entityId; + } + public static String generateEntityId(FaceSampleRespVO entity) { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); + String entityId = entity.getDeviceId().toString() + "_" + sdf.format(entity.getCreateAt()); + return entityId; + } +} diff --git a/src/main/java/com/ycwl/basic/utils/ImageUtils.java b/src/main/java/com/ycwl/basic/utils/ImageUtils.java new file mode 100644 index 0000000..1bca534 --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/ImageUtils.java @@ -0,0 +1,79 @@ +package com.ycwl.basic.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; + +public class ImageUtils { + public static MultipartFile base64ToMultipartFile(String base64) { + String[] baseStrs = base64.split(","); + byte[] b; + b = Base64.getDecoder().decode(baseStrs[0]); + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) { + b[i] += 256; + } + } + return new Base64DecodedMultipartFile(b, baseStrs[0]); + } + public static class Base64DecodedMultipartFile implements MultipartFile { + + private final byte[] imgContent; + private final String header; + + public Base64DecodedMultipartFile(byte[] imgContent, String header) { + this.imgContent = imgContent; + this.header = header.split(";")[0]; + } + + @Override + public String getName() { + // TODO - implementation depends on your requirements + return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1]; + } + + @Override + public String getOriginalFilename() { + // TODO - implementation depends on your requirements + return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1]; + } + + @Override + public String getContentType() { + // TODO - implementation depends on your requirements + return header.split(":")[0]; + } + + @Override + public boolean isEmpty() { + return imgContent == null || imgContent.length == 0; + } + + @Override + public long getSize() { + return imgContent.length; + } + + @Override + public byte[] getBytes() { + return imgContent; + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(imgContent); + } + + @Override + public void transferTo(File dest) throws IOException, IllegalStateException { + new FileOutputStream(dest).write(imgContent); + } + + } + +} diff --git a/src/main/java/com/ycwl/basic/utils/IpUtils.java b/src/main/java/com/ycwl/basic/utils/IpUtils.java new file mode 100644 index 0000000..b4dc6a7 --- /dev/null +++ b/src/main/java/com/ycwl/basic/utils/IpUtils.java @@ -0,0 +1,175 @@ +package com.ycwl.basic.utils; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 获取IP方法 + * + * @author tsingeye + */ +public class IpUtils { + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + if (request == null) { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) { + if (text.length() == 0) { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\." , -1); + try { + long l; + int i; + switch (elements.length) { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } catch (NumberFormatException e) { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + } + return "127.0.0.1"; + } + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) { + if (false == isUnknown(subIp)) { + ip = subIp; + break; + } + } + } + return ip; + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } +} \ No newline at end of file diff --git a/src/main/resources/mapper/pc/DeviceMapper.xml b/src/main/resources/mapper/pc/DeviceMapper.xml index 15e7374..5685564 100644 --- a/src/main/resources/mapper/pc/DeviceMapper.xml +++ b/src/main/resources/mapper/pc/DeviceMapper.xml @@ -8,6 +8,10 @@ insert into device_config(id, device_id, create_time) values (#{id}, #{deviceId}, now()) + + insert into device(id, name, no, status, online, ip_addr, keepalive_at, create_at, update_at) + values (#{id}, #{name}, #{no}, 0, #{online}, #{ipAddr}, #{keepaliveAt}, now(), now()) + update device set scenic_id = #{scenicId}, name = #{name}, no = #{no}, longitude = #{longitude}, latitude = #{latitude}, update_at = now() where id = #{id} @@ -34,11 +38,21 @@ cut_post = #{cutPost} where id = #{id} + + update device + set name = #{name}, + no = #{no}, + online = #{online}, + ip_addr = #{ipAddr}, + keepalive_at = #{keepaliveAt}, + update_at = now() + where id = #{id} + delete from device where id = #{id} + \ No newline at end of file diff --git a/src/main/resources/mapper/pc/FaceSampleMapper.xml b/src/main/resources/mapper/pc/FaceSampleMapper.xml index 0cba491..a70ba85 100644 --- a/src/main/resources/mapper/pc/FaceSampleMapper.xml +++ b/src/main/resources/mapper/pc/FaceSampleMapper.xml @@ -2,8 +2,8 @@ - insert into face_sample(id, scenic_id, device_id, source_id, face_url, match_sample_ids, first_match_rate, match_result,`status`) - values (#{id}, #{scenicId}, #{deviceId}, #{sourceId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult},#{status}) + insert into face_sample(id, scenic_id, device_id, source_id, face_url, match_sample_ids, first_match_rate, match_result,`status`, create_at) + values (#{id}, #{scenicId}, #{deviceId}, #{sourceId}, #{faceUrl}, #{matchSampleIds}, #{firstMatchRate}, #{matchResult},#{status},#{createAt}) update face_sample @@ -32,6 +32,10 @@ `status` = #{status}, + + `score` = #{score}, + + update_at = now(), where id = #{id} @@ -81,7 +85,7 @@ diff --git a/src/main/resources/mapper/pc/SourceMapper.xml b/src/main/resources/mapper/pc/SourceMapper.xml index 7f3e714..b454508 100644 --- a/src/main/resources/mapper/pc/SourceMapper.xml +++ b/src/main/resources/mapper/pc/SourceMapper.xml @@ -2,7 +2,8 @@ - insert into source(id, scenic_id, device_id, member_id, url) values (#{id}, #{scenicId}, #{deviceId}, #{memberId}, #{url}) + insert into source(id, scenic_id, device_id, member_id, url, video_url, `type`, face_sample_id) + values (#{id}, #{scenicId}, #{deviceId}, #{memberId}, #{url}, #{videoUrl}, #{type}, #{faceSampleId}) update source @@ -11,7 +12,10 @@ device_id = #{deviceId}, member_id = #{memberId}, url = #{url}, + video_url = #{videoUrl}, is_buy = #{isBuy}, + `type` = #{type}, + face_sample_id = #{faceSampleId}, where id = #{id} @@ -20,7 +24,7 @@