feat(puzzle): 添加批量替换模板元素功能

- 在 PuzzleTemplateController 中新增 replaceElements 接口
- 在 PuzzleElementMapper 中新增 getByTemplateIdAndKey 查询方法
- 在 PuzzleTemplateServiceImpl 中实现 replaceElements 业务逻辑
- 在 IPuzzleTemplateService 接口中定义 replaceElements 方法
- 在 PuzzleElementMapper.xml 中添加对应 SQL 查询语句
This commit is contained in:
2025-11-18 12:47:24 +08:00
parent a49e581915
commit 42e806df76
5 changed files with 101 additions and 0 deletions

View File

@@ -118,6 +118,17 @@ public class PuzzleTemplateController {
return ApiResponse.success(null);
}
/**
* 批量替换模板元素(删除旧元素,添加新元素)
*/
@PutMapping("/templates/{templateId}/elements")
public ApiResponse<Void> replaceElements(@PathVariable Long templateId,
@RequestBody List<ElementCreateRequest> elements) {
log.info("批量替换元素请求: templateId={}, count={}", templateId, elements.size());
templateService.replaceElements(templateId, elements);
return ApiResponse.success(null);
}
/**
* 更新元素
*/

View File

@@ -23,6 +23,12 @@ public interface PuzzleElementMapper {
*/
List<PuzzleElementEntity> getByTemplateId(@Param("templateId") Long templateId);
/**
* 根据模板ID和元素Key查询元素
*/
PuzzleElementEntity getByTemplateIdAndKey(@Param("templateId") Long templateId,
@Param("elementKey") String elementKey);
/**
* 插入元素
*/

View File

@@ -69,6 +69,14 @@ public interface IPuzzleTemplateService {
*/
void batchAddElements(Long templateId, List<ElementCreateRequest> elements);
/**
* 批量替换元素(删除旧元素,添加新元素)
*
* @param templateId 模板ID
* @param elements 新的元素列表
*/
void replaceElements(Long templateId, List<ElementCreateRequest> elements);
/**
* 更新元素
*/

View File

@@ -20,6 +20,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -227,6 +229,72 @@ public class PuzzleTemplateServiceImpl implements IPuzzleTemplateService {
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void replaceElements(Long templateId, List<ElementCreateRequest> elements) {
log.info("批量替换元素: templateId={}, count={}", templateId, elements.size());
// 1. 校验模板
PuzzleTemplateEntity template = templateMapper.getById(templateId);
if (template == null) {
throw new IllegalArgumentException("模板不存在: " + templateId);
}
// 2. 获取现有元素(建立 elementKey -> Entity 的映射)
List<PuzzleElementEntity> existingElements = elementMapper.getByTemplateId(templateId);
Map<String, PuzzleElementEntity> existingMap = existingElements.stream()
.collect(Collectors.toMap(
PuzzleElementEntity::getElementKey,
entity -> entity,
(e1, e2) -> e1 // 如果有重复key,保留第一个
));
// 3. 构建新元素的 key 集合
Set<String> newElementKeys = elements.stream()
.map(ElementCreateRequest::getElementKey)
.collect(Collectors.toSet());
// 4. 找出需要删除的元素(旧元素中不在新元素列表中的)
List<Long> toDeleteIds = existingElements.stream()
.filter(entity -> !newElementKeys.contains(entity.getElementKey()))
.map(PuzzleElementEntity::getId)
.collect(Collectors.toList());
// 5. 删除不需要的元素
int deletedCount = 0;
for (Long id : toDeleteIds) {
elementMapper.deleteById(id);
deletedCount++;
}
log.info("删除不需要的元素: templateId={}, count={}", templateId, deletedCount);
// 6. 处理新元素列表:更新或插入
int updatedCount = 0;
int insertedCount = 0;
for (ElementCreateRequest request : elements) {
request.setTemplateId(templateId);
ElementConfigHelper.validateRequest(request);
PuzzleElementEntity existingEntity = existingMap.get(request.getElementKey());
if (existingEntity != null) {
// 更新现有元素
PuzzleElementEntity entity = ElementConfigHelper.toEntity(request);
entity.setId(existingEntity.getId());
elementMapper.update(entity);
updatedCount++;
} else {
// 插入新元素
PuzzleElementEntity entity = ElementConfigHelper.toEntity(request);
entity.setDeleted(0);
elementMapper.insert(entity);
insertedCount++;
}
}
log.info("批量替换元素完成: templateId={}, deleted={}, updated={}, inserted={}",
templateId, deletedCount, updatedCount, insertedCount);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateElement(Long id, ElementCreateRequest request) {

View File

@@ -49,6 +49,14 @@
ORDER BY z_index ASC, id ASC
</select>
<!-- 根据模板ID和元素Key查询元素 -->
<select id="getByTemplateIdAndKey" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List"/>
FROM puzzle_element
WHERE template_id = #{templateId} AND element_key = #{elementKey} AND deleted = 0
LIMIT 1
</select>
<!-- 插入(重构版) -->
<insert id="insert" parameterType="com.ycwl.basic.puzzle.entity.PuzzleElementEntity"
useGeneratedKeys="true" keyProperty="id">