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}
+
+
+
+