From d84c7689f431281a41d05f6e058bc13ecbcfd50f Mon Sep 17 00:00:00 2001
From: weiweiw <14335254+weiweiw22@user.noreply.gitee.com>
Date: Mon, 25 Nov 2024 15:08:17 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9C=A8=E7=BA=BF=E6=A0=87?=
=?UTF-8?q?=E6=B3=A8util=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../bonus/ai/client/OnlineAnnotateUtil.java | 24 +-
.../OnlineAnnotationFallbackFactory.java | 83 ------
.../ai/client/OnlineAnnotationService.java | 72 ------
.../client/OnlineAnnotationServiceOkHttp.java | 96 +++++++
.../bonus/ai/client/ParsedLabelConfig.java | 124 +++++++++
.../bonus/ai/client/ProjectInputParam.java | 34 +++
.../com/bonus/ai/client/ProjectParam.java | 239 ++++++++++++------
.../dataset/AnnotationTaskController.java | 7 +-
.../domain/dataset/AnnotationTaskEntity.java | 6 +-
.../bonus/ai/mapper/AnnotationTaskMapper.java | 3 +-
.../dataset/AnnotationTaskServiceImpl.java | 119 +++++++--
.../dataset/AnnotationTaskService.java | 2 +
.../resources/mapper/AnnotationTaskMapper.xml | 19 +-
13 files changed, 547 insertions(+), 281 deletions(-)
delete mode 100644 bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationFallbackFactory.java
delete mode 100644 bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationService.java
create mode 100644 bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationServiceOkHttp.java
create mode 100644 bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ParsedLabelConfig.java
create mode 100644 bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectInputParam.java
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotateUtil.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotateUtil.java
index 8df90d3..0e09d85 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotateUtil.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotateUtil.java
@@ -6,13 +6,17 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OnlineAnnotateUtil {
- final static String template = ".*?";
+ final static String template = ".*?";
/**
* 替换 View 中的 Label 标签内容
- * @param labels 要替换的 labels 列表
* @return 替换后的字符串
*/
- public static String rectangleImageLabels(List labels) {
+ public static String rectangleImageLabels(String labelsStr) {
+ if ( labelsStr.isEmpty()) {
+ return "";
+ }
+ // 使用 split 分割字符串并转换为 List
+ List labels = Arrays.asList(labelsStr.split(","));
if (labels == null || labels.isEmpty()){
return "";
}
@@ -48,11 +52,11 @@ public class OnlineAnnotateUtil {
*
*
*/
- public static void main(String[] args) {
-// List labels = Arrays.asList("label1", "label2", "label3");
- List labels = Stream.of("label1", "label2", "label3")
- .collect(Collectors.toList());
- String result = rectangleImageLabels(labels);
- System.out.println(result);
- }
+// public static void main(String[] args) {
+//// List labels = Arrays.asList("label1", "label2", "label3");
+// List labels = Stream.of("label1", "label2", "label3")
+// .collect(Collectors.toList());
+// String result = rectangleImageLabels(labels);
+// System.out.println(result);
+// }
}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationFallbackFactory.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationFallbackFactory.java
deleted file mode 100644
index cd734a6..0000000
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationFallbackFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.bonus.ai.client;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.cloud.openfeign.FallbackFactory;
-import org.springframework.stereotype.Component;
-
-
-@Component
-public class OnlineAnnotationFallbackFactory implements FallbackFactory {
- private static final Logger log = LoggerFactory.getLogger(OnlineAnnotationFallbackFactory.class);
-
- @Override
- public OnlineAnnotationService create(Throwable throwable) {
-
- log.error("系统服务调用失败:{}", throwable.getMessage());
- return new OnlineAnnotationService() {
- @Override
- public String createProject(ProjectParam projectParam, String authorization) {
- return null;
-
- }
-
- @Override
- public String getProjectById(String id, String authorization) {
- return "";
- }
-
- @Override
- public boolean deleteProjectById(String id, String authorization) {
- return false;
- }
-
- @Override
- public String updateProject(ProjectParam projectParam, String authorization) {
- return "";
- }
-
- @Override
- public String createTask(TaskParam task, String authorization) {
- return null;
- }
-
- @Override
- public String getTaskById(String id, String authorization) {
- return "";
- }
-
- @Override
- public boolean deleteTaskById(String id, String authorization) {
- return false;
- }
-
- @Override
- public String updateTask(TaskParam task, String authorization) {
- return "";
- }
-
- @Override
- public String createAnnotation(AnnotationParam annotationParam, String authorization) {
- return "";
- }
-
- @Override
- public String getAnnotationById(String id, String authorization) {
- return "";
- }
-
- @Override
- public boolean deleteAnnotationById(String id, String authorization) {
- return false;
- }
-
- @Override
- public String updateAnnotation(AnnotationParam annotationParam, String authorization) {
- return "";
- }
-
-
- };
- }
-}
-
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationService.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationService.java
deleted file mode 100644
index da3372b..0000000
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationService.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.bonus.ai.client;
-
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.*;
-
-
-@FeignClient(name = "onlineAnnotationService")
-public interface OnlineAnnotationService {
-
- /**
- * project <------> 人工智能数据中心的标注任务
- * project 增删改查
- */
- @PostMapping("/api/projects/")
- public String createProject(@RequestBody ProjectParam projectParam, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @GetMapping("/api/projects/{id}/")
- public String getProjectById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @DeleteMapping("/api/projects/{id}/")
- public boolean deleteProjectById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @PatchMapping("/api/projects/")
- public String updateProject(@RequestBody ProjectParam projectParam, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- /**
- * task <------> 人工智能数据中心的具体的标注文件
- * task 增删改查
- */
- @PostMapping("/api/tasks/")
- public String createTask(@RequestBody TaskParam task, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @GetMapping("/api/tasks/{id}/")
- public String getTaskById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
-
- @DeleteMapping("/api/tasks/{id}/")
- public boolean deleteTaskById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @PatchMapping("/api/tasks/")
- public String updateTask(@RequestBody TaskParam task, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
-
- /**
- * annotation <------> 人工智能数据中心的标注结果
- * annotation 增删改查
- */
- @PostMapping("/api/tasks/{id}/annotations/")
- public String createAnnotation(@RequestBody AnnotationParam annotationParam, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
-
- @GetMapping("/api/annotations/{id}")
- public String getAnnotationById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- @DeleteMapping("/api/annotations/{id}")
- public boolean deleteAnnotationById(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
-
- @PatchMapping("/api/tasks/{id}/annotations/")
- public String updateAnnotation(@RequestBody AnnotationParam annotationParam, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
- /**
- * 导出指定project的所有标注结果
- */
-// @GetMapping("/api/project/{id}/export")
-// public String exportAnnotationByProjectId(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-//
-// @GetMapping("/api/annotations/{id}")
-// public String exportAnnotationByTaskIds(@PathVariable("id") String id, @RequestHeader(AIConstants.AUTHORIZATION_HEADER) String authorization);
-
-
-}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationServiceOkHttp.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationServiceOkHttp.java
new file mode 100644
index 0000000..64de405
--- /dev/null
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/OnlineAnnotationServiceOkHttp.java
@@ -0,0 +1,96 @@
+package com.bonus.ai.client;
+
+import com.bonus.ai.config.OnlineAnnotateConfig;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.stereotype.Service;
+import java.io.IOException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Service
+public class OnlineAnnotationServiceOkHttp {
+
+ private static final OkHttpClient client = new OkHttpClient();
+ private static final ObjectMapper objectMapper = new ObjectMapper(); // 用于JSON序列化和反序列化
+ //private static final String BASE_URL = "http://127.0.0.1:8080/api/projects/"; // 替换为实际URL
+
+ @Resource
+ private OnlineAnnotateConfig onlineAnnotateConfig;
+
+
+ // Create project
+ public ProjectParam createProject(ProjectInputParam projectParam) throws IOException {
+ String url = onlineAnnotateConfig.getUrl()+ "/projects/";
+ String json = objectMapper.writeValueAsString(projectParam);
+
+ RequestBody body = RequestBody.create(json, MediaType.parse("application/json"));
+
+ log.error("Request JSON: " + json);
+ Request request = new Request.Builder()
+ .url(url)
+ .post(body)
+ .addHeader("Authorization", onlineAnnotateConfig.getApikey())
+ .build();
+
+ String response = executeRequest(request);
+ return ProjectParam.fromJson(response);
+ }
+
+ // Get project by ID
+ public ProjectParam getProjectById(String id) throws IOException {
+ String url = onlineAnnotateConfig.getUrl()+ "/projects/" + id + "/";
+ Request request = new Request.Builder()
+ .url(url)
+ .get()
+ .addHeader("Authorization", onlineAnnotateConfig.getApikey())
+ .build();
+
+ String response = executeRequest(request);
+ return ProjectParam.fromJson(response);
+ }
+
+ // Delete project by ID
+ public boolean deleteProjectById(String id) throws IOException {
+ String url = onlineAnnotateConfig.getUrl()+ "/projects/" + id + "/";
+ Request request = new Request.Builder()
+ .url(url)
+ .delete()
+ .addHeader("Authorization", onlineAnnotateConfig.getApikey())
+ .build();
+
+ String response = executeRequest(request);
+ return response != null && !response.isEmpty();
+ }
+
+ // Update project
+ public ProjectParam updateProject(ProjectInputParam projectParam) throws IOException {
+ String url = onlineAnnotateConfig.getUrl()+ "/projects/"+ projectParam.getId() + "/";
+ String json = objectMapper.writeValueAsString(projectParam);
+
+ RequestBody body = RequestBody.create(json, MediaType.parse("application/json"));
+ Request request = new Request.Builder()
+ .url(url)
+ .patch(body)
+ .addHeader("Authorization", onlineAnnotateConfig.getApikey())
+ .build();
+
+ String response = executeRequest(request);
+ return ProjectParam.fromJson(response);
+ }
+
+ // Execute the request
+ private String executeRequest(Request request) throws IOException {
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ throw new IOException("Unexpected code " + response);
+ }
+ return response.body() != null ? response.body().string() : null;
+ }
+ }
+}
+
+
+
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ParsedLabelConfig.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ParsedLabelConfig.java
new file mode 100644
index 0000000..6daec89
--- /dev/null
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ParsedLabelConfig.java
@@ -0,0 +1,124 @@
+package com.bonus.ai.client;
+
+//public class ParsedLabelConfig {
+//}
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class ParsedLabelConfig {
+
+ @JsonProperty("label")
+ private Label label;
+
+ @Data
+ public static class Label {
+ @JsonProperty("type")
+ private String type;
+
+ @JsonProperty("to_name")
+ private List toName;
+
+ @JsonProperty("inputs")
+ private List inputs;
+
+ @JsonProperty("labels")
+ private List labels;
+
+ @JsonProperty("labels_attrs")
+ private Map labelsAttrs;
+ }
+
+ @Data
+ public static class Input {
+ @JsonProperty("type")
+ private String type;
+
+ @JsonProperty("value")
+ private String value;
+
+ @JsonProperty("valueType")
+ private String valueType; // 注意:JSON 中为 `null`,在 Java 中用 `String` 表示
+ }
+
+ @Data
+ public static class LabelAttributes {
+ @JsonProperty("value")
+ private String value;
+
+ @JsonProperty("background")
+ private String background;
+ }
+
+ /**
+ * 将 JSON 字符串解析为实体类对象
+ */
+ public static ParsedLabelConfig fromJson(String json) throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ return mapper.readValue(json, ParsedLabelConfig.class);
+ }
+
+ /**
+ * 将实体类对象转换为 JSON 字符串
+ */
+ public String toJson() throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ return mapper.writeValueAsString(this);
+ }
+
+ public static void main(String[] args) throws JsonProcessingException {
+ String json = "{\n" +
+ " \"parsed_label_config\": {\n" +
+ " \"label\": {\n" +
+ " \"type\": \"RectangleLabels\",\n" +
+ " \"to_name\": [\"image\"],\n" +
+ " \"inputs\": [\n" +
+ " {\n" +
+ " \"type\": \"Image\",\n" +
+ " \"value\": \"image\",\n" +
+ " \"valueType\": null\n" +
+ " }\n" +
+ " ],\n" +
+ " \"labels\": [\"person\", \"cat\"],\n" +
+ " \"labels_attrs\": {\n" +
+ " \"person\": {\n" +
+ " \"value\": \"person\",\n" +
+ " \"background\": \"#FFA39E\"\n" +
+ " },\n" +
+ " \"cat\": {\n" +
+ " \"value\": \"cat\",\n" +
+ " \"background\": \"#D4380D\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+
+// ParsedLabelConfig record = ParsedLabelConfig.fromJson(json);
+//
+// System.out.println(record);
+ // 提取 "parsed_label_config" 部分
+ ObjectMapper mapper = new ObjectMapper();
+
+ String parsedLabelConfigJson = mapper.readTree(json).get("parsed_label_config").toString();
+
+ // JSON 转为实体类
+ ParsedLabelConfig parsedLabelConfig = ParsedLabelConfig.fromJson(parsedLabelConfigJson);
+ System.out.println("实体类内容:");
+ System.out.println(parsedLabelConfig);
+
+ // 实体类转为 JSON
+ String jsonOutput = parsedLabelConfig.toJson();
+ System.out.println("\n转换回 JSON:");
+ System.out.println(jsonOutput);
+ }
+
+}
+
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectInputParam.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectInputParam.java
new file mode 100644
index 0000000..bba1633
--- /dev/null
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectInputParam.java
@@ -0,0 +1,34 @@
+package com.bonus.ai.client;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class ProjectInputParam {
+
+ private Long id;
+ private String title;
+ private String description;
+ @JsonProperty("label_config")
+ private String labelConfig;
+ @JsonProperty("expert_instruction")
+ private String expertInstruction = "labels";
+ @JsonProperty("show_instruction")
+ private boolean showInstruction = true;
+ @JsonProperty("show_skip_button")
+ private boolean showSkipButton = true;
+ @JsonProperty("enable_empty_annotation")
+ private boolean enableEmptyAnnotation = true;
+ @JsonProperty("show_annotation_history")
+ private boolean showAnnotationHistory = true;
+ private int organization = 1;
+ private String color = "color";
+ @JsonProperty("maximum_annotations")
+ private int maximumAnnotations = 1;
+}
+
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectParam.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectParam.java
index 4a99286..7c987f8 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectParam.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/client/ProjectParam.java
@@ -1,6 +1,8 @@
package com.bonus.ai.client;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
@@ -11,25 +13,29 @@ import java.util.Map;
@Data
public class ProjectParam {
- private int id;
+ private Long id = 0L;
+ @JsonProperty("title")
private String title;
+ @JsonProperty("description")
private String description;
+
@JsonProperty("label_config")
+ @JsonRawValue(true)
private String labelConfig;
@JsonProperty("expert_instruction")
- private String expertInstruction;
+ private String expertInstruction = "labels";
@JsonProperty("show_instruction")
- private boolean showInstruction;
+ private boolean showInstruction = true;
@JsonProperty("show_skip_button")
- private boolean showSkipButton;
+ private boolean showSkipButton = true;
@JsonProperty("enable_empty_annotation")
- private boolean enableEmptyAnnotation;
+ private boolean enableEmptyAnnotation = true;
@JsonProperty("show_annotation_history")
- private boolean showAnnotationHistory;
- private int organization;
- private String color;
+ private boolean showAnnotationHistory = true;
+ private int organization = 1;
+ private String color = "color";
@JsonProperty("maximum_annotations")
- private int maximumAnnotations;
+ private int maximumAnnotations = 1;
@JsonProperty("is_published")
private boolean isPublished;
@JsonProperty("model_version")
@@ -95,13 +101,13 @@ public class ProjectParam {
// Getters and Setters for all fields
@Data
public static class CreatedBy {
- private int id;
+ private int id = 1;
@JsonProperty("first_name")
- private String firstName;
+ private String firstName = "";
@JsonProperty("last_name")
- private String lastName;
- private String email;
- private String avatar;
+ private String lastName = "";
+ private String email = "wang272160587@gmail.com";
+ private String avatar = null;
// Getters and Setters
}
@@ -117,91 +123,166 @@ public class ProjectParam {
@Data
public static class ParsedLabelConfig {
- private Map label;
- // Getters and Setters
- }
+ @JsonProperty("label")
+ private com.bonus.ai.client.ParsedLabelConfig.Label label;
- @Data
- public static class LabelConfig {
- private String type;
- @JsonProperty("to_name")
- private List toName;
- private List inputs;
- private List labels;
- @JsonProperty("labels_attrs")
- private Map labelsAttrs;
+ @Data
+ public static class Label {
+ @JsonProperty("type")
+ private String type;
- // Getters and Setters
- }
+ @JsonProperty("to_name")
+ private List toName;
- @Data
- public static class Input {
- private String type;
- private String value;
- private String valueType;
+ @JsonProperty("inputs")
+ private List inputs;
- // Getters and Setters
- }
+ @JsonProperty("labels")
+ private List labels;
- @Data
- public static class LabelAttributes {
- private String value;
- private String background;
+ @JsonProperty("labels_attrs")
+ private Map labelsAttrs;
+ }
+
+ @Data
+ public static class Input {
+ @JsonProperty("type")
+ private String type;
+
+ @JsonProperty("value")
+ private String value;
+
+ @JsonProperty("valueType")
+ private String valueType; // 注意:JSON 中为 `null`,在 Java 中用 `String` 表示
+ }
+
+ @Data
+ public static class LabelAttributes {
+ @JsonProperty("value")
+ private String value;
+
+ @JsonProperty("background")
+ private String background;
+ }
- // Getters and Setters
}
public static ProjectParam fromJson(String json) throws JsonProcessingException {
- ObjectMapper mapper = new ObjectMapper();
- return mapper.readValue(json, ProjectParam.class);
+ return new ObjectMapper().readValue(json, ProjectParam.class);
}
-
- public String toJson() throws JsonProcessingException {
+ public String toJson() throws Exception {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
public static void main(String[] args) throws JsonProcessingException {
- String json = "{\n" +
- " \"data\": {\n" +
- " \"image\": \"https://example.com/image.jpg\",\n" +
- " \"text\": \"Hello, AI!\"\n" +
- " },\n" +
- " \"id\": 1,\n" +
- " \"meta\": {\n" +
- " \"key\": \"value\"\n" +
- " },\n" +
- " \"created_at\": \"2024-06-18T23:45:46Z\",\n" +
- " \"updated_at\": \"2024-06-18T23:45:46Z\",\n" +
- " \"is_labeled\": false,\n" +
- " \"overlap\": 1,\n" +
- " \"inner_id\": 1,\n" +
- " \"total_annotations\": 0,\n" +
- " \"cancelled_annotations\": 0,\n" +
- " \"total_predictions\": 0,\n" +
- " \"comment_count\": 0,\n" +
- " \"unresolved_comment_count\": 0,\n" +
- " \"last_comment_updated_at\": \"2024-01-15T09:30:00Z\",\n" +
- " \"project\": 1,\n" +
- " \"updated_by\": [\n" +
- " {\n" +
- " \"user_id\": 1\n" +
- " }\n" +
- " ],\n" +
- " \"file_upload\": \"42d46c4c-my-pic.jpeg\",\n" +
- " \"comment_authors\": [\n" +
- " 1\n" +
- " ]\n" +
- "}";
-
+ String json = "{\"id\":16,\"title\":\"taskName\",\"description\":\"description\",\"label_config\":\"\\n \\n \\n \\n\",\"expert_instruction\":\"labels\",\"show_instruction\":true,\"show_skip_button\":true,\"enable_empty_annotation\":true,\"show_annotation_history\":true,\"organization\":1,\"color\":\"color\",\"maximum_annotations\":1,\"is_published\":false,\"model_version\":\"\",\"is_draft\":false,\"created_by\":{\"id\":1,\"first_name\":\"\",\"last_name\":\"\",\"email\":\"wang272160587@gmail.com\",\"avatar\":null},\"created_at\":\"2024-11-25T01:27:36.414342Z\",\"min_annotations_to_start_training\":0,\"start_training_on_annotation_update\":false,\"show_collab_predictions\":true,\"num_tasks_with_annotations\":null,\"task_number\":null,\"useful_annotation_number\":null,\"ground_truth_number\":null,\"skipped_annotations_number\":null,\"total_annotations_number\":null,\"total_predictions_number\":null,\"sampling\":\"Sequential sampling\",\"show_ground_truth_first\":false,\"show_overlap_first\":false,\"overlap_cohort_percentage\":100,\"task_data_login\":null,\"task_data_password\":null,\"control_weights\":{\"label\":{\"overall\":1.0,\"type\":\"RectangleLabels\",\"labels\":{\"person\":1.0,\"cat\":1.0}}},\"parsed_label_config\":{\"label\":{\"type\":\"RectangleLabels\",\"to_name\":[\"image\"],\"inputs\":[{\"type\":\"Image\",\"value\":\"image\",\"valueType\":null}],\"labels\":[\"person\",\"cat\"],\"labels_attrs\":{\"person\":{\"value\":\"person\",\"background\":\"#FFA39E\"},\"cat\":{\"value\":\"cat\",\"background\":\"#D4380D\"}}}},\"evaluate_predictions_automatically\":false,\"config_has_control_tags\":true,\"skip_queue\":\"REQUEUE_FOR_OTHERS\",\"reveal_preannotations_interactively\":false,\"pinned_at\":null,\"finished_task_number\":null,\"queue_total\":0,\"queue_done\":0}";
+// String json = "{\"id\":16,\"title\":\"taskName\",\"description\":\"description\",\"label_config\":\"\\n \\n \\n \\n \\n \\n\",\"expert_instruction\":\"labels\",\"show_instruction\":true,\"show_skip_button\":true,\"enable_empty_annotation\":true,\"show_annotation_history\":true,\"organization\":1,\"color\":\"color\",\"maximum_annotations\":1,\"is_published\":false}";
+// String json = "{\n" +
+// " \"id\": 11,\n" +
+// " \"title\": \"测试项目\",\n" +
+// " \"description\": \"My Second project\",\n" +
+// " \"label_config\": \"\\n \\n \\n \\n \\n \\n\",\n" +
+// " \"expert_instruction\": \"Label all cats\",\n" +
+// " \"show_instruction\": true,\n" +
+// " \"show_skip_button\": true,\n" +
+// " \"enable_empty_annotation\": true,\n" +
+// " \"show_annotation_history\": true,\n" +
+// " \"organization\": 1,\n" +
+// " \"color\": \"color\",\n" +
+// " \"maximum_annotations\": 1,\n" +
+// " \"is_published\": false,\n" +
+// " \"model_version\": \"\",\n" +
+// " \"is_draft\": false,\n" +
+// " \"created_by\": {\n" +
+// " \"id\": 1,\n" +
+// " \"first_name\": \"\",\n" +
+// " \"last_name\": \"\",\n" +
+// " \"email\": \"wang272160587@gmail.com\",\n" +
+// " \"avatar\": null\n" +
+// " },\n" +
+// " \"created_at\": \"2024-11-25T00:36:17.622117Z\",\n" +
+// " \"min_annotations_to_start_training\": 0,\n" +
+// " \"start_training_on_annotation_update\": false,\n" +
+// " \"show_collab_predictions\": true,\n" +
+// " \"num_tasks_with_annotations\": null,\n" +
+// " \"task_number\": null,\n" +
+// " \"useful_annotation_number\": null,\n" +
+// " \"ground_truth_number\": null,\n" +
+// " \"skipped_annotations_number\": null,\n" +
+// " \"total_annotations_number\": null,\n" +
+// " \"total_predictions_number\": null,\n" +
+// " \"sampling\": \"Sequential sampling\",\n" +
+// " \"show_ground_truth_first\": false,\n" +
+// " \"show_overlap_first\": false,\n" +
+// " \"overlap_cohort_percentage\": 100,\n" +
+// " \"task_data_login\": null,\n" +
+// " \"task_data_password\": null,\n" +
+// " \"control_weights\": {\n" +
+// " \"label\": {\n" +
+// " \"overall\": 1.0,\n" +
+// " \"type\": \"RectangleLabels\",\n" +
+// " \"labels\": {\n" +
+// " \"person\": 1.0,\n" +
+// " \"cat\": 1.0\n" +
+// " }\n" +
+// " }\n" +
+// " },\n" +
+// " \"parsed_label_config\": {\n" +
+// " \"label\": {\n" +
+// " \"type\": \"RectangleLabels\",\n" +
+// " \"to_name\": [\n" +
+// " \"image\"\n" +
+// " ],\n" +
+// " \"inputs\": [\n" +
+// " {\n" +
+// " \"type\": \"Image\",\n" +
+// " \"value\": \"image\",\n" +
+// " \"valueType\": null\n" +
+// " }\n" +
+// " ],\n" +
+// " \"labels\": [\n" +
+// " \"person\",\n" +
+// " \"cat\"\n" +
+// " ],\n" +
+// " \"labels_attrs\": {\n" +
+// " \"person\": {\n" +
+// " \"value\": \"person\",\n" +
+// " \"background\": \"#FFA39E\"\n" +
+// " },\n" +
+// " \"cat\": {\n" +
+// " \"value\": \"cat\",\n" +
+// " \"background\": \"#D4380D\"\n" +
+// " }\n" +
+// " }\n" +
+// " }\n" +
+// " },\n" +
+// " \"evaluate_predictions_automatically\": false,\n" +
+// " \"config_has_control_tags\": true,\n" +
+// " \"skip_queue\": \"REQUEUE_FOR_OTHERS\",\n" +
+// " \"reveal_preannotations_interactively\": true,\n" +
+// " \"pinned_at\": null,\n" +
+// " \"finished_task_number\": null,\n" +
+// " \"queue_total\": 0,\n" +
+// " \"queue_done\": 0\n" +
+// "}";
System.out.println(json);
- TaskParam record = TaskParam.fromJson(json);
- System.out.println("Create At: " + record.getData());
+ ProjectParam record = ProjectParam.fromJson(json);
System.out.println("Create At: " + record.getCreatedAt());
- System.out.println("Image URL: " + record.getData().getImage());
}
+
+// public static void main(String[] args) throws Exception {
+// String json = "{\"id\":16,\"title\":\"taskName\",\"description\":\"description\",\"label_config\":\"\\n \\n \\n \\n \\n \\n\",\"expert_instruction\":\"labels\",\"show_instruction\":true,\"show_skip_button\":true,\"enable_empty_annotation\":true,\"show_annotation_history\":true,\"organization\":1,\"color\":\"color\",\"maximum_annotations\":1,\"is_published\":false}";
+//
+// ObjectMapper objectMapper = new ObjectMapper();
+// ProjectParam projectParam = objectMapper.readValue(json, ProjectParam.class);
+//
+// System.out.println(projectParam);
+// }
+
+
}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/controller/dataset/AnnotationTaskController.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/controller/dataset/AnnotationTaskController.java
index f0c22dc..5ac7880 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/controller/dataset/AnnotationTaskController.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/controller/dataset/AnnotationTaskController.java
@@ -1,5 +1,6 @@
package com.bonus.ai.controller.dataset;
+import com.bonus.ai.client.AnnotationParam;
import com.bonus.ai.domain.dataset.AnnotationSubTaskEntity;
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
import com.bonus.ai.service.DataSetBasicFileService;
@@ -39,7 +40,8 @@ public class AnnotationTaskController extends BaseController {
@PostMapping("/edit")
public AjaxResult edit(@Validated @RequestBody AnnotationTaskEntity task) {
- return AjaxResult.success();
+ int status = annotationTaskService.updateTask(task);
+ return status == 1 ? AjaxResult.success() : AjaxResult.error("更新任务失败");
}
/**
@@ -72,7 +74,8 @@ public class AnnotationTaskController extends BaseController {
*/
@GetMapping(value = "/{taskId}")
public AjaxResult getInfo(@PathVariable Long taskId) {
- return AjaxResult.success(new AnnotationTaskEntity());
+ AnnotationTaskEntity taskEntity = annotationTaskService.getTaskInfo(taskId);
+ return AjaxResult.success(taskEntity);
}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/dataset/AnnotationTaskEntity.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/dataset/AnnotationTaskEntity.java
index be9cb6b..503a375 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/dataset/AnnotationTaskEntity.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/domain/dataset/AnnotationTaskEntity.java
@@ -1,5 +1,6 @@
package com.bonus.ai.domain.dataset;
+import com.bonus.ai.client.ProjectParam;
import com.bonus.ai.domain.enums.AnnotationFileStatus;
import com.bonus.ai.domain.enums.AnnotationTaskStatus;
import com.bonus.common.core.web.domain.BaseEntity;
@@ -32,10 +33,11 @@ public class AnnotationTaskEntity extends BaseEntity {
/**标签集合,标签之间用逗号分隔*/
private String labels;
- /**在线标注工具里关联的项目id*/
+ /**在线标注工具里关联的项目id 和label studio里 项目详情*/
Long projectId;
+ ProjectParam projectParam;
- AnnotationTaskStatus annotateTaskStatus;
+ private String annotateTaskStatus;
/**删除标志(0代表存在 1代表删除) */
private String delFlag;
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/mapper/AnnotationTaskMapper.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/mapper/AnnotationTaskMapper.java
index 181b014..4f5f2e0 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/mapper/AnnotationTaskMapper.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/mapper/AnnotationTaskMapper.java
@@ -54,5 +54,6 @@ public interface AnnotationTaskMapper
int deleteAnnotator(Long taskId);
- AnnotationTaskEntity selectAnnotationTaskListUUID(Long taskId);
+ //这个接口不需要,可以扩展selectAnnotationTaskList
+// AnnotationTaskEntity selectAnnotationTaskListUUID(Long taskId);
}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/Impl/dataset/AnnotationTaskServiceImpl.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/Impl/dataset/AnnotationTaskServiceImpl.java
index 55a42a6..ce33548 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/Impl/dataset/AnnotationTaskServiceImpl.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/Impl/dataset/AnnotationTaskServiceImpl.java
@@ -1,7 +1,9 @@
package com.bonus.ai.service.Impl.dataset;
import com.alibaba.fastjson.JSON;
-import com.bonus.ai.client.OnlineAnnotationService;
+import com.bonus.ai.client.OnlineAnnotateUtil;
+import com.bonus.ai.client.OnlineAnnotationServiceOkHttp;
+import com.bonus.ai.client.ProjectInputParam;
import com.bonus.ai.client.ProjectParam;
import com.bonus.ai.config.OnlineAnnotateConfig;
import com.bonus.ai.domain.dataset.*;
@@ -13,8 +15,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.io.IOException;
import java.util.List;
import java.util.UUID;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
@Slf4j
@Service
@@ -22,7 +28,8 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
@Resource
- OnlineAnnotationService onlineAnnotationService;
+ OnlineAnnotationServiceOkHttp onlineAnnotationService;
+// OnlineAnnotationService onlineAnnotationService;
@Resource
private OnlineAnnotateConfig onlineAnnotateConfig;
@@ -39,33 +46,49 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
@Autowired
private AnnotationTaskAnnotatorEntity annotationTaskAnnotatorEntity;
+
+ public void callWithOkHttp() throws Exception {
+ OkHttpClient client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url("http://127.0.0.1:8080/api/projects")
+ .addHeader("Authorization", "Token bb0859020874c95809212f7b9616d15bbdbb2422")
+ .build();
+
+ try (Response response = client.newCall(request).execute()) {
+ System.out.println(response.body().string());
+ }
+ }
/**
* 创建标注任务
*/
@Override
- public int createTask(AnnotationTaskEntity task) {
+ public int createTask(AnnotationTaskEntity task){
int status =0;
- // TODO 调用label studio 接口获取其project id
- ProjectParam lSProject = new ProjectParam();
+ //调用label studio 接口获取其project id
+ ProjectInputParam lSProject= new ProjectInputParam();
lSProject.setTitle(task.getTaskName());
lSProject.setDescription(task.getTaskDesc());
//需要将标签转换为json格式
- lSProject.setLabelConfig(task.getLabels());
- String project = onlineAnnotationService.createProject(lSProject, onlineAnnotateConfig.getApikey());
- List projectParams = JSON.parseArray(project, ProjectParam.class);
- if (projectParams.size() > 0) {
- Long projectId = Long.valueOf(projectParams.get(0).getId());
- task.setProjectId(projectId);
- for(ProjectParam projectParam: projectParams){
- //需要生成32位uuid
- String uuid = UUID.randomUUID().toString().replace("-", "");
- task.setTaskUuid(uuid);
- status= annotationTaskMapper.insertAnnotationTask(task);
+ String labelConfig = OnlineAnnotateUtil.rectangleImageLabels(task.getLabels());
+ lSProject.setLabelConfig(labelConfig);
+ String project = "";
+ try {
+ ProjectParam projectParams = onlineAnnotationService.createProject(lSProject);
+ if (projectParams != null) {
+ Long projectId = Long.valueOf(projectParams.getId());
+ task.setProjectId(projectId);
}
+ }catch (Exception e){
+ e.printStackTrace();
}
+
+ //需要生成32位uuid
+ String uuid = UUID.randomUUID().toString().replace("-", "");
+ task.setTaskUuid(uuid);
+ status= annotationTaskMapper.insertAnnotationTask(task);
//通过数据集id 从数据集和文件关联关系表获取文件信息
List datafile = datasetFileMapper.selectFilesByDatasetId(task.getDatasetId());
- //TODO 根据标注任务file list 和标注人信息自动分配
+ //根据标注任务file list 和标注人信息自动分配
List annotationTaskAnnotatorEntities = AverageUtil.distributeFiles(datafile, task);
// 获取project id以后调用AnnotationTaskMapper 和AnnotationTaskAnnotatorMapper 插入数据集
if(status == 1){
@@ -93,6 +116,30 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
*/
@Override
public int updateTask(AnnotationTaskEntity task){
+
+ //将信息也同步更新到label studio studio 对应的project
+ AnnotationTaskEntity newTask = new AnnotationTaskEntity();
+ newTask.setTaskId(task.getTaskId());
+ //处理与label studio 相关的更新
+ List resultTasks = annotationTaskMapper.selectAnnotationTaskList(newTask);
+ if (!resultTasks.isEmpty()) {
+ Long project = resultTasks.get(0).getProjectId();
+ //调用label studio 接口获取其project id
+ ProjectInputParam lSProject= new ProjectInputParam();
+ lSProject.setTitle(task.getTaskName());
+ lSProject.setDescription(task.getTaskDesc());
+ //需要将标签转换为json格式
+ String labelConfig = OnlineAnnotateUtil.rectangleImageLabels(task.getLabels());
+ lSProject.setLabelConfig(labelConfig);
+ lSProject.setId(project);
+ try {
+ ProjectParam projectParam = onlineAnnotationService.updateProject(lSProject);
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+
+ //删除对应的标注任务文件关联关系表信息
+ }
return 0;
}
@@ -105,16 +152,22 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
@Override
public int deleteTaskById(Long taskId) {
//删除任务需要删除两个个表 对应两个个表删除状态修改成1
+ AnnotationTaskEntity task = new AnnotationTaskEntity();
+ task.setTaskId(taskId);
int status = 0;
try{
- //删除主表任务信息
- status = annotationTaskMapper.deleteTaskById(taskId);
- //删除团队成员表信息
- status = annotationTaskMapper.deleteAnnotator(taskId);
- //查询对应的uuid
- AnnotationTaskEntity task = annotationTaskMapper.selectAnnotationTaskListUUID(taskId);
- //删除对应的标注任务文件关联关系表信息
- onlineAnnotationService.deleteProjectById(task.getTaskUuid(), onlineAnnotateConfig.getApikey());
+// //删除主表任务信息
+// status = annotationTaskMapper.deleteTaskById(taskId);
+// //删除团队成员表信息
+// status = annotationTaskMapper.deleteAnnotator(taskId);
+// //查询对应的label studio project id , 删除这个标注任务对应的label studio project
+ List resultTask = annotationTaskMapper.selectAnnotationTaskList(task);
+ if (!resultTask.isEmpty()){
+ Long project = resultTask.get(0).getProjectId();
+ //删除对应的标注任务文件关联关系表信息
+ onlineAnnotationService.deleteProjectById(String.valueOf(project));
+ }
+
}catch (Exception e){
e.printStackTrace();
}
@@ -129,6 +182,22 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
@Override
public AnnotationTaskEntity getTaskInfo(Long taskId) {
+
+ AnnotationTaskEntity task = new AnnotationTaskEntity();
+ task.setTaskId(taskId);
+ try {
+ //查询对应的label studio project id , 从label studio这个标注任务对应的label studio project
+ List resultTasks = annotationTaskMapper.selectAnnotationTaskList(task);
+ if (!resultTasks.isEmpty()) {
+ Long project = resultTasks.get(0).getProjectId();
+ //删除对应的标注任务文件关联关系表信息
+ ProjectParam projectParam = onlineAnnotationService.getProjectById(String.valueOf(project));
+ AnnotationTaskEntity resultTask = resultTasks.get(0);
+ resultTask.setProjectParam(projectParam);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ }
return null;
}
diff --git a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/dataset/AnnotationTaskService.java b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/dataset/AnnotationTaskService.java
index 3c76dc0..4c54f53 100644
--- a/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/dataset/AnnotationTaskService.java
+++ b/bonus-modules/bonus-ai/src/main/java/com/bonus/ai/service/dataset/AnnotationTaskService.java
@@ -4,6 +4,8 @@ import com.bonus.ai.domain.dataset.AnnotationSubTaskEntity;
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
import com.bonus.ai.domain.dataset.DataSetEntity;
+import java.io.IOException;
+
public interface AnnotationTaskService {
/**创建标注任务*/
int createTask(AnnotationTaskEntity task);
diff --git a/bonus-modules/bonus-ai/src/main/resources/mapper/AnnotationTaskMapper.xml b/bonus-modules/bonus-ai/src/main/resources/mapper/AnnotationTaskMapper.xml
index 33fc212..a963b53 100644
--- a/bonus-modules/bonus-ai/src/main/resources/mapper/AnnotationTaskMapper.xml
+++ b/bonus-modules/bonus-ai/src/main/resources/mapper/AnnotationTaskMapper.xml
@@ -14,7 +14,8 @@
-
+
+
@@ -23,6 +24,7 @@
+
select distinct t.task_id, t.task_uuid, t.task_name, t.description, t.annotation_scene, t.annotation_type,
FROM ai_annotation_task t
@@ -43,14 +45,17 @@
-
-