diff --git a/backend/pom.xml b/backend/pom.xml index d28fa4236..6e92d8479 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -33,6 +33,7 @@ 3.5.5 1.6.3 1.18.32 + 0.2.0 @@ -120,6 +121,12 @@ ${mapstruct.version} + + org.projectlombok + lombok + ${lombok.version} + + mysql mysql-connector-java @@ -152,6 +159,12 @@ lombok ${lombok.version} + + + org.mapstruct + mapstruct + ${mapstruct.version} + diff --git a/backend/services/data-management-service/pom.xml b/backend/services/data-management-service/pom.xml index 8625fe3b0..68afd432f 100644 --- a/backend/services/data-management-service/pom.xml +++ b/backend/services/data-management-service/pom.xml @@ -72,9 +72,41 @@ org.springframework.boot spring-boot-maven-plugin + true exec + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${maven.compiler.source} + ${maven.compiler.target} + + + + org.projectlombok + lombok + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + ${lombok-mapstruct-binding.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + -parameters + -Amapstruct.defaultComponentModel=spring + + + diff --git a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/application/service/TagApplicationService.java b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/application/service/TagApplicationService.java index bea506884..839305adf 100644 --- a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/application/service/TagApplicationService.java +++ b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/application/service/TagApplicationService.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import java.util.List; import java.util.UUID; @@ -39,6 +40,37 @@ public Tag createTag(String name, String color, String description) { return tagMapper.findById(tag.getId()); } + /** + * 更新标签 + * + * @param tag 待更新的标签实体,必须包含有效的 ID + * @return 更新结果 + */ + @Transactional + public Tag updateTag(Tag tag) { + Tag existingTag = tagMapper.findById(tag.getId()); + if (existingTag == null) { + throw new IllegalArgumentException("Tag not found: " + tag.getId()); + } + existingTag.setName(tag.getName()); + existingTag.setColor(tag.getColor()); + existingTag.setDescription(tag.getDescription()); + tagMapper.update(existingTag); + return tagMapper.findById(existingTag.getId()); + } + + @Transactional + public void deleteTag(List tagIds) { + List tags = tagMapper.findByIdIn(tagIds); + if (tags.stream().anyMatch(tag -> tag.getUsageCount() > 0)) { + throw new IllegalArgumentException("Cannot delete tags that are in use"); + } + if (CollectionUtils.isEmpty(tags)) { + return; + } + tagMapper.deleteTagsById(tags.stream().map(Tag::getId).toList()); + } + /** * 获取所有标签 */ diff --git a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/infrastructure/persistence/mapper/TagMapper.java b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/infrastructure/persistence/mapper/TagMapper.java index 993d2c533..6d2b8cf1d 100644 --- a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/infrastructure/persistence/mapper/TagMapper.java +++ b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/infrastructure/persistence/mapper/TagMapper.java @@ -11,6 +11,7 @@ public interface TagMapper { Tag findById(@Param("id") String id); Tag findByName(@Param("name") String name); List findByNameIn(@Param("list") List names); + List findByIdIn(@Param("ids") List ids); List findByKeyword(@Param("keyword") String keyword); List findAllByOrderByUsageCountDesc(); @@ -22,4 +23,5 @@ public interface TagMapper { int insertDatasetTag(@Param("datasetId") String datasetId, @Param("tagId") String tagId); int deleteDatasetTagsByDatasetId(@Param("datasetId") String datasetId); List findByDatasetId(@Param("datasetId") String datasetId); + void deleteTagsById(@Param("ids") List ids); } diff --git a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/converter/TagConverter.java b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/converter/TagConverter.java new file mode 100644 index 000000000..281a686af --- /dev/null +++ b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/converter/TagConverter.java @@ -0,0 +1,30 @@ +package com.dataengine.datamanagement.interfaces.converter; + +import com.dataengine.datamanagement.domain.model.dataset.Tag; +import com.dataengine.datamanagement.interfaces.dto.TagResponse; +import com.dataengine.datamanagement.interfaces.dto.UpdateTagRequest; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 标签转换器 + */ +@Mapper +public interface TagConverter { + /** 单例实例 */ + TagConverter INSTANCE = Mappers.getMapper(TagConverter.class); + + /** + * 将 UpdateTagRequest 转换为 Tag 实体 + * @param request 更新标签请求DTO + * @return 标签实体 + */ + Tag updateRequestToTag(UpdateTagRequest request); + + /** + * 将 Tag 实体转换为 TagResponse DTO + * @param tag 标签实体 + * @return 标签响应DTO + */ + TagResponse convertToResponse(Tag tag); +} diff --git a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/dto/UpdateTagRequest.java b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/dto/UpdateTagRequest.java new file mode 100644 index 000000000..12ff8d469 --- /dev/null +++ b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/dto/UpdateTagRequest.java @@ -0,0 +1,20 @@ +package com.dataengine.datamanagement.interfaces.dto; + +import lombok.Getter; +import lombok.Setter; + +/** + * 更新标签请求DTO + */ +@Getter +@Setter +public class UpdateTagRequest { + /** 标签 ID */ + private String id; + /** 标签名称 */ + private String name; + /** 标签颜色 */ + private String color; + /** 标签描述 */ + private String description; +} diff --git a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/rest/TagController.java b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/rest/TagController.java index 7b3290884..b0cc983a7 100644 --- a/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/rest/TagController.java +++ b/backend/services/data-management-service/src/main/java/com/dataengine/datamanagement/interfaces/rest/TagController.java @@ -3,13 +3,19 @@ import com.dataengine.common.interfaces.Response; import com.dataengine.datamanagement.application.service.TagApplicationService; import com.dataengine.datamanagement.domain.model.dataset.Tag; +import com.dataengine.datamanagement.interfaces.converter.TagConverter; import com.dataengine.datamanagement.interfaces.dto.CreateTagRequest; import com.dataengine.datamanagement.interfaces.dto.TagResponse; +import com.dataengine.datamanagement.interfaces.dto.UpdateTagRequest; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -30,10 +36,10 @@ public TagController(TagApplicationService tagApplicationService) { * 查询标签列表 */ @GetMapping - public ResponseEntity>> getTags(@RequestParam(required = false) String keyword) { + public ResponseEntity>> getTags(@RequestParam(name = "keyword", required = false) String keyword) { List tags = tagApplicationService.searchTags(keyword); List response = tags.stream() - .map(this::convertToResponse) + .map(TagConverter.INSTANCE::convertToResponse) .collect(Collectors.toList()); return ResponseEntity.ok(Response.ok(response)); } @@ -49,19 +55,31 @@ public ResponseEntity> createTag(@RequestBody CreateTagReq createTagRequest.getColor(), createTagRequest.getDescription() ); - return ResponseEntity.status(201).body(Response.ok(convertToResponse(tag))); + return ResponseEntity.ok(Response.ok(TagConverter.INSTANCE.convertToResponse(tag))); } catch (IllegalArgumentException e) { return ResponseEntity.badRequest().body(Response.error(e.getMessage(), null)); } } - private TagResponse convertToResponse(Tag tag) { - TagResponse response = new TagResponse(); - response.setId(tag.getId()); - response.setName(tag.getName()); - response.setColor(tag.getColor()); - response.setDescription(tag.getDescription()); - response.setUsageCount(tag.getUsageCount() != null ? tag.getUsageCount().intValue() : null); - return response; + /** + * 更新标签 + * + * @param updateTagRequest 更新参数 + * @return 更新结果 + */ + @PutMapping + public ResponseEntity> updateTag(@RequestBody @Valid UpdateTagRequest updateTagRequest) { + Tag tag = tagApplicationService.updateTag(TagConverter.INSTANCE.updateRequestToTag(updateTagRequest)); + return ResponseEntity.ok(Response.ok(TagConverter.INSTANCE.convertToResponse(tag))); + } + + @DeleteMapping + public ResponseEntity> deleteTag(@RequestParam(value = "ids") @Valid @Size(max = 10) List ids) { + try { + tagApplicationService.deleteTag(ids.stream().filter(StringUtils::isNoneBlank).distinct().toList()); + return ResponseEntity.ok(Response.ok(null)); + } catch (IllegalArgumentException e) { + return ResponseEntity.badRequest().body(Response.error(e.getMessage(), null)); + } } } diff --git a/backend/services/data-management-service/src/main/resources/mappers/TagMapper.xml b/backend/services/data-management-service/src/main/resources/mappers/TagMapper.xml index 0d82879f0..087d65246 100644 --- a/backend/services/data-management-service/src/main/resources/mappers/TagMapper.xml +++ b/backend/services/data-management-service/src/main/resources/mappers/TagMapper.xml @@ -92,4 +92,20 @@ ORDER BY t.usage_count DESC, t.name ASC + + DELETE FROM t_dm_tags WHERE + id IN + + #{id} + + + +