From 1923a5c438daf8efd585a069d7000d0fb082e0a8 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Thu, 2 Jan 2025 15:12:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/scenic/content/ContentPageVO.java | 1 + .../impl/mobile/AppScenicServiceImpl.java | 14 ++- .../service/impl/mobile/GoodsServiceImpl.java | 3 + .../service/impl/pc/FaceServiceImpl.java | 1 - .../service/impl/pc/TemplateServiceImpl.java | 19 ++-- .../impl/task/TaskTaskServiceImpl.java | 1 - .../com/ycwl/basic/task/VideoPieceGetter.java | 10 +- .../ycwl/basic/template/TemplateFactory.java | 4 + .../repository/TemplateRepository.java | 97 +++++++++++++++++++ src/main/resources/mapper/FaceMapper.xml | 4 +- 10 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/ycwl/basic/template/TemplateFactory.java create mode 100644 src/main/java/com/ycwl/basic/template/repository/TemplateRepository.java diff --git a/src/main/java/com/ycwl/basic/model/mobile/scenic/content/ContentPageVO.java b/src/main/java/com/ycwl/basic/model/mobile/scenic/content/ContentPageVO.java index f75a201..ce8b70b 100644 --- a/src/main/java/com/ycwl/basic/model/mobile/scenic/content/ContentPageVO.java +++ b/src/main/java/com/ycwl/basic/model/mobile/scenic/content/ContentPageVO.java @@ -23,6 +23,7 @@ public class ContentPageVO { private Integer contentType; @ApiModelProperty("源素材类型 1:视频 2:图片") private Integer sourceType; + private int lockType; @ApiModelProperty("内容id contentType为0或1时才有值") private Long contentId; @ApiModelProperty("模版id") diff --git a/src/main/java/com/ycwl/basic/service/impl/mobile/AppScenicServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/mobile/AppScenicServiceImpl.java index 4ca5bd1..d6444de 100644 --- a/src/main/java/com/ycwl/basic/service/impl/mobile/AppScenicServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/mobile/AppScenicServiceImpl.java @@ -22,9 +22,8 @@ import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO; import com.ycwl.basic.model.pc.source.req.SourceReqQuery; import com.ycwl.basic.model.pc.source.resp.SourceRespVO; import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity; -import com.ycwl.basic.model.pc.video.req.VideoReqQuery; -import com.ycwl.basic.model.pc.video.resp.VideoRespVO; import com.ycwl.basic.service.mobile.AppScenicService; +import com.ycwl.basic.template.repository.TemplateRepository; import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.JwtTokenUtil; import lombok.extern.slf4j.Slf4j; @@ -66,6 +65,8 @@ public class AppScenicServiceImpl implements AppScenicService { @Value("${face.score}") private BigDecimal faceScore; + @Autowired + private TemplateRepository templateRepository; @Override public ApiResponse> pageQuery(ScenicReqQuery scenicReqQuery) { @@ -179,12 +180,19 @@ public class AppScenicServiceImpl implements AppScenicService { List contentList = templateMapper.listFor(faceRespVO.getScenicId()); contentList.forEach(contentPageVO -> { List memberVideoEntityList = videoMapper.userFaceTemplateVideo(userId, faceId, contentPageVO.getTemplateId()); + contentPageVO.setContentType(1); if (!memberVideoEntityList.isEmpty()) { contentPageVO.setIsBuy(memberVideoEntityList.get(0).getIsBuy()); contentPageVO.setContentId(memberVideoEntityList.get(0).getVideoId()); - contentPageVO.setContentType(1); + contentPageVO.setLockType(-1); } else { contentPageVO.setContentType(0); + boolean canGenerate = templateRepository.determineTemplateCanGenerate(contentPageVO.getTemplateId(), faceId); + if (canGenerate) { + contentPageVO.setLockType(0); + } else { + contentPageVO.setLockType(1); + } } }); diff --git a/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java index 23cbbd0..af01f36 100644 --- a/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/mobile/GoodsServiceImpl.java @@ -16,6 +16,7 @@ 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 com.ycwl.basic.service.mobile.GoodsService; +import com.ycwl.basic.template.repository.TemplateRepository; import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.DateUtils; import org.apache.commons.lang3.StringUtils; @@ -48,6 +49,8 @@ public class GoodsServiceImpl implements GoodsService { private DeviceMapper deviceMapper; @Autowired private FaceMapper faceMapper; + @Autowired + private TemplateRepository templateRepository; public ApiResponse> goodsList(GoodsReqQuery query) { //查询原素材 diff --git a/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java index 012ccc9..518b855 100644 --- a/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/impl/pc/FaceServiceImpl.java @@ -208,7 +208,6 @@ public class FaceServiceImpl implements FaceService { task.faceId = faceEntity.getId(); task.faceSampleId = sampleRespVO.getId(); task.memberId = userId; - task.createTime = sampleRespVO.getCreateAt(); VideoPieceGetter.addTask(task); } taskTaskService.autoCreateTaskByFaceId(faceEntity.getId()); 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 50825da..65fb8d6 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 @@ -8,6 +8,7 @@ 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; import com.ycwl.basic.service.pc.TemplateService; +import com.ycwl.basic.template.repository.TemplateRepository; import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.utils.SnowFlakeUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +25,8 @@ public class TemplateServiceImpl implements TemplateService { @Autowired private TemplateMapper templateMapper; + @Autowired + private TemplateRepository templateRepository; @Override public ApiResponse> pageQuery(TemplateReqQuery templateReqQuery) { @@ -40,9 +43,7 @@ public class TemplateServiceImpl implements TemplateService { @Override public ApiResponse getById(Long id) { - TemplateRespVO data = templateMapper.getById(id); - data.setChildren(templateMapper.getByPid(id)); - return ApiResponse.success(data); + return ApiResponse.success(templateRepository.getTemplate(id)); } @Override @@ -70,6 +71,7 @@ public class TemplateServiceImpl implements TemplateService { int i = templateMapper.deleteById(id); if (i > 0) { templateMapper.deleteByPid(id); + templateRepository.clearTemplateCache(id); return ApiResponse.success(i); }else { return ApiResponse.fail("删除模版失败"); @@ -88,6 +90,7 @@ public class TemplateServiceImpl implements TemplateService { item.setStatus(1); templateMapper.add(item); }); + templateRepository.clearTemplateCache(template.getId()); } if (i > 0) { return ApiResponse.success(true); @@ -108,19 +111,13 @@ public class TemplateServiceImpl implements TemplateService { @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; + return templateRepository.getTemplateConfig(templateId); } @Override public void saveConfig(Long configId, TemplateConfigEntity config) { config.setId(configId); + templateRepository.clearTemplateCache(config.getTemplateId()); templateMapper.updateConfigById(config); } } 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 48b1f72..b00ad12 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 @@ -241,7 +241,6 @@ public class TaskTaskServiceImpl implements TaskService { VideoPieceGetter.Task task = new VideoPieceGetter.Task(); task.setFaceSampleId(sample.getId()); task.setMemberId(faceRespVO.getMemberId()); - task.setCreateTime(sample.getCreateAt()); return task; }).forEach(VideoPieceGetter::addTask); diff --git a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java index 931b7dd..39d0f50 100644 --- a/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java +++ b/src/main/java/com/ycwl/basic/task/VideoPieceGetter.java @@ -53,7 +53,6 @@ public class VideoPieceGetter { public static class Task { public String type = "normal"; public Long faceSampleId; - public Date createTime; public Callback callback; public Long memberId; public Long faceId; @@ -127,14 +126,14 @@ public class VideoPieceGetter { } 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()) + new Date(faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue()), + new Date(faceSample.getCreateAt().getTime() + cutPost.multiply(BigDecimal.valueOf(1000)).longValue()) ); if (listByDtRange.isEmpty()) { log.warn("没有可用的文件"); return; } - long offset = task.getCreateTime().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue() - listByDtRange.get(0).getCreateTime().getTime(); + long offset = faceSample.getCreateAt().getTime() - cutPre.multiply(BigDecimal.valueOf(1000)).longValue() - listByDtRange.get(0).getCreateTime().getTime(); FfmpegTask ffmpegTask = new FfmpegTask(); ffmpegTask.setFileList(listByDtRange); ffmpegTask.setDuration(duration); @@ -149,9 +148,12 @@ public class VideoPieceGetter { log.info("视频裁切成功"); IStorageAdapter adapter = StorageFactory.use("assets"); String url = adapter.uploadFile(outFile, "video-source", outFile.getName()); + // 上传成功后删除文件 + outFile.delete(); SourceEntity imgSource = sourceMapper.findBySampleId(faceSample.getId()); SourceEntity sourceEntity = new SourceEntity(); sourceEntity.setId(SnowFlakeUtil.getLongId()); + sourceEntity.setCreateTime(faceSample.getCreateAt()); MemberSourceEntity videoSource = new MemberSourceEntity(); videoSource.setMemberId(task.getMemberId()); videoSource.setType(1); diff --git a/src/main/java/com/ycwl/basic/template/TemplateFactory.java b/src/main/java/com/ycwl/basic/template/TemplateFactory.java new file mode 100644 index 0000000..3254c2c --- /dev/null +++ b/src/main/java/com/ycwl/basic/template/TemplateFactory.java @@ -0,0 +1,4 @@ +package com.ycwl.basic.template; + +public class TemplateFactory { +} diff --git a/src/main/java/com/ycwl/basic/template/repository/TemplateRepository.java b/src/main/java/com/ycwl/basic/template/repository/TemplateRepository.java new file mode 100644 index 0000000..2fc4311 --- /dev/null +++ b/src/main/java/com/ycwl/basic/template/repository/TemplateRepository.java @@ -0,0 +1,97 @@ +package com.ycwl.basic.template.repository; + +import com.alibaba.fastjson.JSONObject; +import com.ycwl.basic.mapper.FaceMapper; +import com.ycwl.basic.mapper.FaceSampleMapper; +import com.ycwl.basic.mapper.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.template.entity.TemplateConfigEntity; +import com.ycwl.basic.model.pc.template.resp.TemplateRespVO; +import com.ycwl.basic.utils.SnowFlakeUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service // 临时这么用 +public class TemplateRepository { + @Autowired + private FaceMapper faceMapper; + @Autowired + private FaceSampleMapper faceSampleMapper; + @Autowired + private TemplateMapper templateMapper; + @Autowired + private RedisTemplate redisTemplate; + public static final String TEMPLATE_CACHE_KEY = "template:%s"; + public static final String TEMPLATE_CONFIG_CACHE_KEY = "template:%s:config"; + + + public boolean determineTemplateCanGenerate(Long templateId, Long faceId) { + TemplateRespVO template = templateMapper.getById(templateId); + template.setChildren(templateMapper.getByPid(templateId)); + Map map = new HashMap<>(); + for (TemplateRespVO child : template.getChildren()) { + if (child.getIsPlaceholder() == 1) { + map.put(child.getSourceUrl(), false); + } + } + TemplateConfigEntity templateConfig = templateMapper.getConfig(templateId); + if (0 == templateConfig.getMinimalPlaceholderFill()) { + return true; + } + FaceRespVO face = faceMapper.getById(faceId); + if (face.getMatchSampleIds() == null) { + return false; + } + List faceSample = faceSampleMapper.listByIds(Arrays.stream(face.getMatchSampleIds().split(",")).map(Long::valueOf).collect(Collectors.toList())); + faceSample.stream().collect(Collectors.groupingBy(FaceSampleRespVO::getDeviceId)).forEach((deviceId, value) -> { + if (map.containsKey(deviceId.toString())) { + map.put(deviceId.toString(), true); + } + }); + return map.values().stream().filter(item -> item).count() >= templateConfig.getMinimalPlaceholderFill(); + } + + public TemplateRespVO getTemplate(Long templateId) { + if (redisTemplate.hasKey(String.format(TEMPLATE_CACHE_KEY, templateId))) { + return JSONObject.parseObject(redisTemplate.opsForValue().get(String.format(TEMPLATE_CACHE_KEY, templateId)), TemplateRespVO.class); + } + TemplateRespVO template = templateMapper.getById(templateId); + if (null == template.getPid() || template.getPid() == 0) { + template.setChildren(templateMapper.getByPid(templateId)); + redisTemplate.opsForValue().set(String.format(TEMPLATE_CACHE_KEY, templateId), JSONObject.toJSONString(template)); + return template; + } else { + clearTemplateCache(templateId); + return null; + } + } + + public TemplateConfigEntity getTemplateConfig(Long templateId) { + if (redisTemplate.hasKey(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId))) { + return JSONObject.parseObject(redisTemplate.opsForValue().get(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId)), TemplateConfigEntity.class); + } + TemplateConfigEntity templateConfig = templateMapper.getConfig(templateId); + if (templateConfig == null) { + templateConfig = new TemplateConfigEntity(); + templateConfig.setId(SnowFlakeUtil.getLongId()); + templateConfig.setTemplateId(templateId); + templateMapper.addConfig(templateConfig); + } + redisTemplate.opsForValue().set(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId), JSONObject.toJSONString(templateConfig)); + return templateConfig; + } + + public boolean clearTemplateCache(Long templateId) { + redisTemplate.delete(String.format(TEMPLATE_CACHE_KEY, templateId)); + redisTemplate.delete(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId)); + return true; + } +} diff --git a/src/main/resources/mapper/FaceMapper.xml b/src/main/resources/mapper/FaceMapper.xml index 92a9acd..e4909a1 100644 --- a/src/main/resources/mapper/FaceMapper.xml +++ b/src/main/resources/mapper/FaceMapper.xml @@ -74,7 +74,7 @@ select id, scenic_id, member_id, face_url,score, match_sample_ids, first_match_rate, match_result, create_at, update_at from face where member_id = #{userId} and scenic_id = #{scenicId} - order by id desc + order by update_at desc limit 1