refactor(puzzle): 移除填充规则中的景区ID依赖

- 删除 PuzzleFillRuleDTO、PuzzleFillRuleSaveRequest 和 PuzzleFillRuleEntity 中的 scenicId 字段
- 从 ConditionContext 和 DataSourceContext 中移除 scenicId 属性
- 更新 PuzzleElementFillEngine 的 execute 方法,不再接收和传递 scenicId 参数
- 修改 PuzzleGenerateServiceImpl 中调用填充引擎的逻辑,去除 scenicId 判断和传参
- 调整 PuzzleFillRuleMapper.xml 配置文件,移除 scenic_id 映射关系
- 更新所有相关单元测试用例,删除对 scenicId 的引用和验证
- 简化规则查询方法,由 listByTemplateAndScenic 改为 listByTemplateId
- 移除因缺少 scenicId 而产生的警告日志和特殊处理分支
This commit is contained in:
2025-11-19 23:23:08 +08:00
parent 6d18a770b8
commit 67aebd5770
12 changed files with 32 additions and 71 deletions

View File

@@ -46,11 +46,6 @@ public class PuzzleFillRuleDTO {
*/ */
private Integer enabled; private Integer enabled;
/**
* 景区ID
*/
private Long scenicId;
/** /**
* 规则描述 * 规则描述
*/ */

View File

@@ -46,11 +46,6 @@ public class PuzzleFillRuleSaveRequest {
*/ */
private Integer enabled; private Integer enabled;
/**
* 景区ID
*/
private Long scenicId;
/** /**
* 规则描述 * 规则描述
*/ */

View File

@@ -51,11 +51,6 @@ public class PuzzleFillRuleEntity {
*/ */
private Integer enabled; private Integer enabled;
/**
* 景区ID
*/
private Long scenicId;
/** /**
* 规则描述 * 规则描述
*/ */

View File

@@ -49,14 +49,13 @@ public class PuzzleElementFillEngine {
* *
* @param templateId 模板ID * @param templateId 模板ID
* @param faceId 人脸ID * @param faceId 人脸ID
* @param scenicId 景区ID
* @return 填充后的dynamicData * @return 填充后的dynamicData
*/ */
public Map<String, String> execute(Long templateId, Long faceId, Long scenicId) { public Map<String, String> execute(Long templateId, Long faceId) {
Map<String, String> dynamicData = new HashMap<>(); Map<String, String> dynamicData = new HashMap<>();
if (faceId == null || scenicId == null) { if (faceId == null) {
log.debug("自动填充被跳过, templateId={}, faceId={}, scenicId={}", templateId, faceId, scenicId); log.debug("自动填充被跳过, templateId={}, faceId={}", templateId, faceId);
return dynamicData; return dynamicData;
} }
@@ -78,7 +77,6 @@ public class PuzzleElementFillEngine {
// 3. 构建条件评估上下文 // 3. 构建条件评估上下文
ConditionContext conditionContext = ConditionContext.builder() ConditionContext conditionContext = ConditionContext.builder()
.faceId(faceId) .faceId(faceId)
.scenicId(scenicId)
.deviceCount(deviceCount) .deviceCount(deviceCount)
.deviceIds(deviceIds) .deviceIds(deviceIds)
.build(); .build();
@@ -105,7 +103,6 @@ public class PuzzleElementFillEngine {
// 5. 批量填充dynamicData // 5. 批量填充dynamicData
DataSourceContext dataSourceContext = DataSourceContext.builder() DataSourceContext dataSourceContext = DataSourceContext.builder()
.faceId(faceId) .faceId(faceId)
.scenicId(scenicId)
.build(); .build();
int successCount = 0; int successCount = 0;

View File

@@ -18,11 +18,6 @@ public class ConditionContext {
*/ */
private Long faceId; private Long faceId;
/**
* 景区ID
*/
private Long scenicId;
/** /**
* 机位数量(缓存值,避免重复查询) * 机位数量(缓存值,避免重复查询)
*/ */

View File

@@ -15,11 +15,6 @@ public class DataSourceContext {
*/ */
private Long faceId; private Long faceId;
/**
* 景区ID
*/
private Long scenicId;
/** /**
* 可扩展的其他上下文数据 * 可扩展的其他上下文数据
*/ */

View File

@@ -202,12 +202,11 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
Map<String, String> dynamicData = new HashMap<>(); Map<String, String> dynamicData = new HashMap<>();
// 1. 自动填充(基于faceId和规则) // 1. 自动填充(基于faceId和规则)
if (request.getFaceId() != null && scenicId != null) { if (request.getFaceId() != null) {
try { try {
Map<String, String> autoFilled = fillEngine.execute( Map<String, String> autoFilled = fillEngine.execute(
template.getId(), template.getId(),
request.getFaceId(), request.getFaceId()
scenicId
); );
if (autoFilled != null && !autoFilled.isEmpty()) { if (autoFilled != null && !autoFilled.isEmpty()) {
dynamicData.putAll(autoFilled); dynamicData.putAll(autoFilled);
@@ -217,9 +216,6 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
log.error("自动填充异常, templateId={}, faceId={}", template.getId(), request.getFaceId(), e); log.error("自动填充异常, templateId={}, faceId={}", template.getId(), request.getFaceId(), e);
// 自动填充失败不影响整体流程,继续执行 // 自动填充失败不影响整体流程,继续执行
} }
} else if (request.getFaceId() != null) {
log.warn("自动填充被跳过: 缺少scenicId或模板未绑定景区, templateId={}, faceId={}",
template.getId(), request.getFaceId());
} }
// 2. 手动数据覆盖(优先级更高) // 2. 手动数据覆盖(优先级更高)

View File

@@ -10,7 +10,6 @@
<result column="condition_value" property="conditionValue"/> <result column="condition_value" property="conditionValue"/>
<result column="priority" property="priority"/> <result column="priority" property="priority"/>
<result column="enabled" property="enabled"/> <result column="enabled" property="enabled"/>
<result column="scenic_id" property="scenicId"/>
<result column="description" property="description"/> <result column="description" property="description"/>
<result column="deleted" property="deleted"/> <result column="deleted" property="deleted"/>
<result column="create_time" property="createTime"/> <result column="create_time" property="createTime"/>

View File

@@ -66,15 +66,15 @@ class PuzzleElementFillEngineTest {
Long faceId = 123L; Long faceId = 123L;
Long scenicId = 1L; Long scenicId = 1L;
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(new ArrayList<>()); .thenReturn(new ArrayList<>());
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
verify(ruleMapper, times(1)).listByTemplateAndScenic(templateId, scenicId); verify(ruleMapper, times(1)).listByTemplateId(templateId);
verify(sourceMapper, never()).countDistinctDevicesByFaceId(anyLong()); verify(sourceMapper, never()).countDistinctDevicesByFaceId(anyLong());
} }
@@ -88,7 +88,7 @@ class PuzzleElementFillEngineTest {
// 模拟规则 // 模拟规则
PuzzleFillRuleEntity rule = createRule(1L, "4机位规则", 100); PuzzleFillRuleEntity rule = createRule(1L, "4机位规则", 100);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule)); .thenReturn(Arrays.asList(rule));
// 模拟机位数量和机位列表 // 模拟机位数量和机位列表
@@ -116,7 +116,7 @@ class PuzzleElementFillEngineTest {
.thenReturn("https://oss.example.com/img4.jpg"); .thenReturn("https://oss.example.com/img4.jpg");
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertEquals(4, result.size()); assertEquals(4, result.size());
@@ -131,14 +131,11 @@ class PuzzleElementFillEngineTest {
} }
@Test @Test
@DisplayName("缺少faceId或scenicId时直接返回空结果") @DisplayName("缺少faceId时直接返回空结果")
void shouldReturnEmptyWhenRequiredIdsMissing() { void shouldReturnEmptyWhenRequiredIdsMissing() {
Map<String, String> result = engine.execute(1L, null, 10L); Map<String, String> result = engine.execute(1L, null);
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
verifyNoInteractions(ruleMapper, itemMapper, sourceMapper, conditionEvaluator, dataSourceResolver); verifyNoInteractions(ruleMapper, itemMapper, sourceMapper, conditionEvaluator, dataSourceResolver);
Map<String, String> result2 = engine.execute(1L, 10L, null);
assertTrue(result2.isEmpty());
} }
@Test @Test
@@ -146,12 +143,11 @@ class PuzzleElementFillEngineTest {
void shouldContinueWhenRuleHasNoItems() { void shouldContinueWhenRuleHasNoItems() {
Long templateId = 1L; Long templateId = 1L;
Long faceId = 123L; Long faceId = 123L;
Long scenicId = 1L;
PuzzleFillRuleEntity highPriorityRule = createRule(1L, "高优先级无明细", 200); PuzzleFillRuleEntity highPriorityRule = createRule(1L, "高优先级无明细", 200);
PuzzleFillRuleEntity lowPriorityRule = createRule(2L, "低优先级有效", 100); PuzzleFillRuleEntity lowPriorityRule = createRule(2L, "低优先级有效", 100);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(highPriorityRule, lowPriorityRule)); .thenReturn(Arrays.asList(highPriorityRule, lowPriorityRule));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(1); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(1);
when(sourceMapper.getDeviceIdsByFaceId(faceId)).thenReturn(List.of(99L)); when(sourceMapper.getDeviceIdsByFaceId(faceId)).thenReturn(List.of(99L));
@@ -167,7 +163,8 @@ class PuzzleElementFillEngineTest {
when(dataSourceResolver.resolve(anyString(), anyString(), anyString(), anyString(), any())) when(dataSourceResolver.resolve(anyString(), anyString(), anyString(), anyString(), any()))
.thenReturn("https://oss.example.com/valid.png"); .thenReturn("https://oss.example.com/valid.png");
Map<String, String> result = engine.execute(templateId, faceId, scenicId); // When
Map<String, String> result = engine.execute(templateId, faceId);
assertEquals(1, result.size()); assertEquals(1, result.size());
assertEquals("https://oss.example.com/valid.png", result.get("avatar")); assertEquals("https://oss.example.com/valid.png", result.get("avatar"));
@@ -188,7 +185,7 @@ class PuzzleElementFillEngineTest {
PuzzleFillRuleEntity rule2 = createRule(2L, "中优先级规则", 50); PuzzleFillRuleEntity rule2 = createRule(2L, "中优先级规则", 50);
PuzzleFillRuleEntity rule3 = createRule(3L, "低优先级规则", 10); PuzzleFillRuleEntity rule3 = createRule(3L, "低优先级规则", 10);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule1, rule2, rule3)); .thenReturn(Arrays.asList(rule1, rule2, rule3));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4);
@@ -209,7 +206,7 @@ class PuzzleElementFillEngineTest {
.thenReturn("https://oss.example.com/img.jpg"); .thenReturn("https://oss.example.com/img.jpg");
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertEquals(1, result.size()); assertEquals(1, result.size());
@@ -236,7 +233,7 @@ class PuzzleElementFillEngineTest {
PuzzleFillRuleEntity rule1 = createRule(1L, "规则1", 100); PuzzleFillRuleEntity rule1 = createRule(1L, "规则1", 100);
PuzzleFillRuleEntity rule2 = createRule(2L, "规则2", 50); PuzzleFillRuleEntity rule2 = createRule(2L, "规则2", 50);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule1, rule2)); .thenReturn(Arrays.asList(rule1, rule2));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4);
@@ -247,7 +244,7 @@ class PuzzleElementFillEngineTest {
when(conditionEvaluator.evaluate(any(), any())).thenReturn(false); when(conditionEvaluator.evaluate(any(), any())).thenReturn(false);
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
@@ -264,7 +261,7 @@ class PuzzleElementFillEngineTest {
Long scenicId = 1L; Long scenicId = 1L;
PuzzleFillRuleEntity rule = createRule(1L, "测试规则", 100); PuzzleFillRuleEntity rule = createRule(1L, "测试规则", 100);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule)); .thenReturn(Arrays.asList(rule));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4);
@@ -283,7 +280,7 @@ class PuzzleElementFillEngineTest {
.thenReturn(null); .thenReturn(null);
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertEquals(1, result.size()); assertEquals(1, result.size());
@@ -300,7 +297,7 @@ class PuzzleElementFillEngineTest {
Long scenicId = 1L; Long scenicId = 1L;
PuzzleFillRuleEntity rule = createRule(1L, "测试规则", 100); PuzzleFillRuleEntity rule = createRule(1L, "测试规则", 100);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule)); .thenReturn(Arrays.asList(rule));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4);
@@ -318,7 +315,7 @@ class PuzzleElementFillEngineTest {
.thenReturn("https://oss.example.com/default.jpg"); .thenReturn("https://oss.example.com/default.jpg");
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertEquals(1, result.size()); assertEquals(1, result.size());
@@ -334,7 +331,7 @@ class PuzzleElementFillEngineTest {
Long scenicId = 1L; Long scenicId = 1L;
PuzzleFillRuleEntity rule = createRule(1L, "空明细规则", 100); PuzzleFillRuleEntity rule = createRule(1L, "空明细规则", 100);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule)); .thenReturn(Arrays.asList(rule));
when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4); when(sourceMapper.countDistinctDevicesByFaceId(faceId)).thenReturn(4);
@@ -345,7 +342,7 @@ class PuzzleElementFillEngineTest {
when(itemMapper.listByRuleId(1L)).thenReturn(new ArrayList<>()); when(itemMapper.listByRuleId(1L)).thenReturn(new ArrayList<>());
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
@@ -359,11 +356,11 @@ class PuzzleElementFillEngineTest {
Long faceId = 123L; Long faceId = 123L;
Long scenicId = 1L; Long scenicId = 1L;
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenThrow(new RuntimeException("Database error")); .thenThrow(new RuntimeException("Database error"));
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
@@ -386,7 +383,7 @@ class PuzzleElementFillEngineTest {
rule.setConditionValue("{\"deviceIds\": [200, 300], \"matchMode\": \"ALL\"}"); rule.setConditionValue("{\"deviceIds\": [200, 300], \"matchMode\": \"ALL\"}");
rule.setEnabled(1); rule.setEnabled(1);
when(ruleMapper.listByTemplateAndScenic(templateId, scenicId)) when(ruleMapper.listByTemplateId(templateId))
.thenReturn(Arrays.asList(rule)); .thenReturn(Arrays.asList(rule));
// 模拟机位数量和机位列表 // 模拟机位数量和机位列表
@@ -409,7 +406,7 @@ class PuzzleElementFillEngineTest {
.thenReturn("https://oss.example.com/device300.jpg"); .thenReturn("https://oss.example.com/device300.jpg");
// When // When
Map<String, String> result = engine.execute(templateId, faceId, scenicId); Map<String, String> result = engine.execute(templateId, faceId);
// Then // Then
assertEquals(2, result.size()); assertEquals(2, result.size());

View File

@@ -39,7 +39,6 @@ class AlwaysConditionStrategyTest {
ConditionContext context = ConditionContext.builder() ConditionContext context = ConditionContext.builder()
.deviceCount(4) .deviceCount(4)
.faceId(123L) .faceId(123L)
.scenicId(1L)
.build(); .build();
// When // When

View File

@@ -264,7 +264,6 @@ class PuzzleFillRuleServiceImplTest {
request.setConditionValue("{\"deviceCount\": 4}"); request.setConditionValue("{\"deviceCount\": 4}");
request.setPriority(100); request.setPriority(100);
request.setEnabled(1); request.setEnabled(1);
request.setScenicId(1L);
request.setDescription("测试描述"); request.setDescription("测试描述");
return request; return request;
} }
@@ -288,7 +287,6 @@ class PuzzleFillRuleServiceImplTest {
entity.setConditionValue("{\"deviceCount\": 4}"); entity.setConditionValue("{\"deviceCount\": 4}");
entity.setPriority(100); entity.setPriority(100);
entity.setEnabled(1); entity.setEnabled(1);
entity.setScenicId(1L);
return entity; return entity;
} }

View File

@@ -74,7 +74,7 @@ class PuzzleGenerateServiceImplTest {
when(templateMapper.getByCode("ticket")).thenReturn(template); when(templateMapper.getByCode("ticket")).thenReturn(template);
when(elementMapper.getByTemplateId(template.getId())).thenReturn(List.of(element)); when(elementMapper.getByTemplateId(template.getId())).thenReturn(List.of(element));
when(fillEngine.execute(eq(template.getId()), eq(88L), eq(9L))) when(fillEngine.execute(eq(template.getId()), eq(88L)))
.thenReturn(Map.of("faceImage", "https://images.test/a.png")); .thenReturn(Map.of("faceImage", "https://images.test/a.png"));
when(imageRenderer.render(eq(template), anyList(), anyMap())) when(imageRenderer.render(eq(template), anyList(), anyMap()))
.thenReturn(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB)); .thenReturn(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB));
@@ -105,7 +105,7 @@ class PuzzleGenerateServiceImplTest {
resetStorageFactory(); resetStorageFactory();
} }
verify(fillEngine).execute(template.getId(), 88L, 9L); verify(fillEngine).execute(template.getId(), 88L);
ArgumentCaptor<com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity> captor = ArgumentCaptor<com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity> captor =
ArgumentCaptor.forClass(com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity.class); ArgumentCaptor.forClass(com.ycwl.basic.puzzle.entity.PuzzleGenerationRecordEntity.class);
verify(recordMapper).insert(captor.capture()); verify(recordMapper).insert(captor.capture());
@@ -147,7 +147,7 @@ class PuzzleGenerateServiceImplTest {
resetStorageFactory(); resetStorageFactory();
} }
verify(fillEngine, never()).execute(anyLong(), anyLong(), anyLong()); verify(fillEngine, never()).execute(anyLong(), anyLong());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")