You've already forked FrameTour-BE
All checks were successful
ZhenTu-BE/pipeline/head This commit looks good
在findFirstAvailableTemplate方法中新增scanSource参数,用于控制模板生成时的来源检查逻辑。调用方TaskTaskServiceImpl在强制创建vlog时传入false以跳过来源检查。
189 lines
8.1 KiB
Java
189 lines
8.1 KiB
Java
package com.ycwl.basic.biz;
|
|
|
|
import com.ycwl.basic.mapper.SourceMapper;
|
|
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
|
|
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.resp.FaceSampleRespVO;
|
|
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
|
|
import com.ycwl.basic.model.pc.template.entity.TemplateConfigEntity;
|
|
import com.ycwl.basic.repository.FaceRepository;
|
|
import com.ycwl.basic.repository.SourceRepository;
|
|
import com.ycwl.basic.repository.TemplateRepository;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Slf4j
|
|
@Component
|
|
public class TemplateBiz {
|
|
@Autowired
|
|
private TemplateRepository templateRepository;
|
|
@Autowired
|
|
private FaceRepository faceRepository;
|
|
@Autowired
|
|
private SourceMapper sourceMapper;
|
|
|
|
public boolean determineTemplateCanGenerate(Long templateId, Long faceId) {
|
|
return determineTemplateCanGenerate(templateId, faceId, true);
|
|
}
|
|
|
|
public boolean determineTemplateCanGenerate(Long templateId, Long faceId, boolean scanSource) {
|
|
List<String> placeholderList = templateRepository.getTemplatePlaceholder(templateId);
|
|
TemplateConfigEntity templateConfig = templateRepository.getTemplateConfig(templateId);
|
|
int minimalPlaceholderFill = 1;
|
|
if (null != templateConfig) {
|
|
if (null != templateConfig.getMinimalPlaceholderFill()) {
|
|
minimalPlaceholderFill = templateConfig.getMinimalPlaceholderFill();
|
|
}
|
|
}
|
|
if (minimalPlaceholderFill <= 0) {
|
|
return true;
|
|
}
|
|
FaceEntity face = faceRepository.getFace(faceId);
|
|
long count;
|
|
if (scanSource) {
|
|
List<SourceEntity> sourceEntities = sourceMapper.listVideoByScenicFaceRelation(face.getScenicId(), faceId);
|
|
if (sourceEntities == null || sourceEntities.isEmpty()) {
|
|
return false;
|
|
}
|
|
count = sourceEntities.stream()
|
|
.map(SourceEntity::getDeviceId)
|
|
.filter(Objects::nonNull) // 添加对 null 的检查
|
|
.distinct()
|
|
.filter(deviceId -> placeholderList.contains(deviceId.toString()))
|
|
.count();
|
|
} else {
|
|
List<FaceSampleEntity> faceSampleList = faceRepository.getFaceSampleList(faceId);
|
|
if (faceSampleList == null || faceSampleList.isEmpty()) {
|
|
return false;
|
|
}
|
|
count = faceSampleList.stream()
|
|
.map(FaceSampleEntity::getDeviceId)
|
|
.filter(Objects::nonNull) // 添加对 null 的检查
|
|
.distinct()
|
|
.filter(deviceId -> placeholderList.contains(deviceId.toString()))
|
|
.count();
|
|
}
|
|
return count >= minimalPlaceholderFill;
|
|
}
|
|
|
|
public boolean determineTemplateCanAutoGenerate(Long templateId, Long faceId) {
|
|
return determineTemplateCanAutoGenerate(templateId, faceId, true);
|
|
}
|
|
|
|
public boolean determineTemplateCanAutoGenerate(Long templateId, Long faceId, boolean scanSource) {
|
|
List<String> placeholderList = templateRepository.getTemplatePlaceholder(templateId);
|
|
TemplateConfigEntity templateConfig = templateRepository.getTemplateConfig(templateId);
|
|
Integer minimalPlaceholderFill = null;
|
|
if (null != templateConfig) {
|
|
if (null != templateConfig.getAutomaticPlaceholderFill()) {
|
|
minimalPlaceholderFill = templateConfig.getAutomaticPlaceholderFill();
|
|
}
|
|
}
|
|
if (minimalPlaceholderFill == null) {
|
|
// 未开启
|
|
log.info("模板:{},未配置最小自动生成功能,默认生成!", templateId);
|
|
minimalPlaceholderFill = 1;
|
|
}
|
|
if (minimalPlaceholderFill <= 0) {
|
|
return true;
|
|
}
|
|
FaceEntity face = faceRepository.getFace(faceId);
|
|
List<FaceSampleEntity> faceSampleList = faceRepository.getFaceSampleList(faceId);
|
|
if (faceSampleList.isEmpty()) {
|
|
return false;
|
|
}
|
|
long count;
|
|
if (scanSource) {
|
|
List<SourceEntity> sourceEntities = sourceMapper.listVideoByScenicFaceRelation(face.getScenicId(), faceId);
|
|
count = sourceEntities.stream()
|
|
.map(SourceEntity::getDeviceId)
|
|
.filter(Objects::nonNull) // 添加对 null 的检查
|
|
.distinct()
|
|
.filter(deviceId -> placeholderList.contains(deviceId.toString()))
|
|
.count();
|
|
} else {
|
|
count = faceSampleList.stream()
|
|
.map(FaceSampleEntity::getDeviceId)
|
|
.distinct()
|
|
.filter(deviceId -> placeholderList.contains(deviceId.toString()))
|
|
.count();
|
|
}
|
|
return count >= minimalPlaceholderFill;
|
|
}
|
|
|
|
public Map<String, List<SourceEntity>> filterTaskParams(Long templateId, Map<String, List<SourceEntity>> allTaskParams) {
|
|
if (allTaskParams == null || allTaskParams.isEmpty()) {
|
|
return Map.of();
|
|
}
|
|
|
|
List<String> templatePlaceholders = templateRepository.getTemplatePlaceholder(templateId);
|
|
if (templatePlaceholders == null || templatePlaceholders.isEmpty()) {
|
|
log.info("filterTaskParams: templateId:{} has no placeholders", templateId);
|
|
return Map.of();
|
|
}
|
|
|
|
// 统计每个 placeholder 在模板中出现的次数
|
|
Map<String, Long> placeholderCounts = templatePlaceholders.stream()
|
|
.collect(Collectors.groupingBy(
|
|
placeholder -> placeholder,
|
|
Collectors.counting()
|
|
));
|
|
|
|
Map<String, List<SourceEntity>> filteredParams = new HashMap<>();
|
|
|
|
for (Map.Entry<String, Long> entry : placeholderCounts.entrySet()) {
|
|
String placeholder = entry.getKey();
|
|
Long requiredCount = entry.getValue();
|
|
|
|
if (placeholder.startsWith("P")) {
|
|
// 图片源:占位符格式为 "P{deviceId}"
|
|
String imageKey = placeholder;
|
|
if (allTaskParams.containsKey(imageKey)) {
|
|
List<SourceEntity> allSources = allTaskParams.get(imageKey);
|
|
int actualCount = Math.min(requiredCount.intValue(), allSources.size());
|
|
List<SourceEntity> selectedSources = allSources.subList(0, actualCount);
|
|
filteredParams.put(imageKey, new ArrayList<>(selectedSources));
|
|
}
|
|
} else {
|
|
// 视频源:占位符直接对应设备ID
|
|
String videoKey = placeholder;
|
|
if (allTaskParams.containsKey(videoKey)) {
|
|
List<SourceEntity> allSources = allTaskParams.get(videoKey);
|
|
int actualCount = Math.min(requiredCount.intValue(), allSources.size());
|
|
List<SourceEntity> selectedSources = allSources.subList(0, actualCount);
|
|
filteredParams.put(videoKey, new ArrayList<>(selectedSources));
|
|
}
|
|
}
|
|
}
|
|
|
|
log.debug("filterTaskParams: templateId:{}, original keys:{}, filtered keys:{}, placeholder counts:{}",
|
|
templateId, allTaskParams.keySet().size(), filteredParams.keySet().size(), placeholderCounts);
|
|
|
|
return filteredParams;
|
|
}
|
|
|
|
public Long findFirstAvailableTemplate(List<Long> templateIds, Long faceId, boolean scanSource) {
|
|
if (templateIds == null || templateIds.isEmpty() || faceId == null) {
|
|
return null;
|
|
}
|
|
|
|
for (Long templateId : templateIds) {
|
|
if (determineTemplateCanGenerate(templateId, faceId, scanSource)) {
|
|
return templateId;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
} |