feat(puzzle): 增强拼图填充引擎功能

- 新增 requireRuleMatch 参数控制是否必须匹配规则
- 重构 DeviceCountConditionStrategy 支持两种匹配模式
- 移除已废弃的 DeviceCountRangeConditionStrategy
- 引入 FillResult 类封装填充结果信息
- 优化条件上下文和数据源上下文的 extra 字段类型
- 更新相关测试用例和文档说明
This commit is contained in:
2025-11-20 15:11:13 +08:00
parent aaa8d8310a
commit 2fd852c5c6
13 changed files with 470 additions and 261 deletions

View File

@@ -8,6 +8,7 @@ import com.ycwl.basic.puzzle.dto.PuzzleGenerateResponse;
import com.ycwl.basic.puzzle.entity.PuzzleElementEntity;
import com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity;
import com.ycwl.basic.puzzle.entity.PuzzleTemplateEntity;
import com.ycwl.basic.puzzle.fill.FillResult;
import com.ycwl.basic.puzzle.fill.PuzzleElementFillEngine;
import com.ycwl.basic.puzzle.mapper.PuzzleElementMapper;
import com.ycwl.basic.puzzle.mapper.PuzzleGenerationRecordMapper;
@@ -229,16 +230,25 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
}
// 1. 自动填充(基于faceId和规则)
boolean ruleMatched = false;
if (request.getFaceId() != null) {
try {
Map<String, String> autoFilled = fillEngine.execute(
FillResult fillResult = fillEngine.execute(
template.getId(),
request.getFaceId(),
scenicId
);
if (autoFilled != null && !autoFilled.isEmpty()) {
dynamicData.putAll(autoFilled);
log.info("自动填充成功, 填充了{}个元素", autoFilled.size());
ruleMatched = fillResult.isRuleMatched();
if (fillResult.isRuleMatched()) {
log.info("自动填充成功: 匹配规则[{}], 填充了{}个元素",
fillResult.getMatchedRuleName(),
fillResult.getFilledCount());
dynamicData.putAll(fillResult.getDynamicData());
} else {
log.info("自动填充未匹配任何规则, templateId={}, faceId={}",
template.getId(), request.getFaceId());
}
} catch (Exception e) {
log.error("自动填充异常, templateId={}, faceId={}", template.getId(), request.getFaceId(), e);
@@ -246,7 +256,16 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
}
}
// 2. 手动数据覆盖(优先级更高)
// 2. 检查是否必须匹配规则
Boolean requireRuleMatch = request.getRequireRuleMatch();
if (Boolean.TRUE.equals(requireRuleMatch) && !ruleMatched) {
throw new IllegalArgumentException(
String.format("未匹配到任何填充规则,无法生成图片 (templateCode=%s, faceId=%s, requireRuleMatch=true)",
request.getTemplateCode(), request.getFaceId())
);
}
// 3. 手动数据覆盖(优先级更高)
if (request.getDynamicData() != null && !request.getDynamicData().isEmpty()) {
dynamicData.putAll(request.getDynamicData());
log.debug("合并手动传入的dynamicData, count={}", request.getDynamicData().size());