Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
4e0d660338
|
|
@ -1,21 +1,24 @@
|
|||
package com.bonus.ai.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class OnlineAnnotateUtil {
|
||||
final static String template = "<View><RectangleLabels name=\"label\" toName=\"image\">.*?</RectangleLabels></View>";
|
||||
/**
|
||||
* 替换 View 中的 Label 标签内容
|
||||
* @param template 原始字符串模板
|
||||
* @param labels 要替换的 labels 列表
|
||||
* @return 替换后的字符串
|
||||
*/
|
||||
public static String rectangleImageLabels(String template, List<String> labels) {
|
||||
public static String rectangleImageLabels(List<String> labels) {
|
||||
if (labels == null || labels.isEmpty()){
|
||||
return "";
|
||||
}
|
||||
// 构建新的 Label 标签内容
|
||||
StringBuilder labelBuilder = new StringBuilder();
|
||||
String[] colors = {"#FFA39E", "#D4380D", "#36CFC9", "#FF85C0", "#FFD666"}; // 颜色数组
|
||||
String[] colors = {"blue", "green", "orange", "purge"}; // 颜色数组
|
||||
int colorIndex = 0;
|
||||
|
||||
for (String label : labels) {
|
||||
|
|
@ -36,5 +39,20 @@ public class OnlineAnnotateUtil {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <View>
|
||||
* <Image name="image" value="$image" zoom="true" rotateControl="true" />
|
||||
* <RectangleLabels name="label" toName="image">
|
||||
* <Label value="Person" background="blue"/>
|
||||
* <Label value="Car" background="green"/>
|
||||
* </RectangleLabels>
|
||||
* </View>
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// List<String> labels = Arrays.asList("label1", "label2", "label3");
|
||||
List<String> labels = Stream.of("label1", "label2", "label3")
|
||||
.collect(Collectors.toList());
|
||||
String result = rectangleImageLabels(labels);
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package com.bonus.ai.controller;
|
|||
|
||||
import com.bonus.ai.domain.DataSetBasicFileEntity;
|
||||
import com.bonus.ai.service.DataSetBasicFileService;
|
||||
import com.bonus.common.core.constant.HttpStatus;
|
||||
import com.bonus.common.core.utils.Base64Utils;
|
||||
import com.bonus.common.core.utils.poi.ExcelUtil;
|
||||
import com.bonus.common.core.web.controller.BaseController;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ public class AnnotationTaskController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/create")
|
||||
public AjaxResult add(@Validated @RequestBody AnnotationTaskEntity task) {
|
||||
return AjaxResult.success();
|
||||
int status = annotationTaskService.createTask(task);
|
||||
return status == 1 ? AjaxResult.success() : AjaxResult.error("创建任务失败");
|
||||
}
|
||||
|
||||
/**修改任务
|
||||
|
|
@ -37,6 +38,7 @@ public class AnnotationTaskController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/edit")
|
||||
public AjaxResult edit(@Validated @RequestBody AnnotationTaskEntity task) {
|
||||
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
|
@ -47,6 +49,7 @@ public class AnnotationTaskController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/delete/{taskId}")
|
||||
public AjaxResult remove(@PathVariable Long taskId) {
|
||||
annotationTaskService.deleteTaskById(taskId);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package com.bonus.ai.domain.dataset;
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class AnnotationTaskAnnotatorMap {
|
||||
@Component
|
||||
public class AnnotationTaskAnnotatorEntity {
|
||||
|
||||
private Long annotatorId; // 标注人员
|
||||
private Long reviewerId; // 审核人员
|
||||
|
|
@ -22,4 +24,4 @@ public class AnnotationTaskAnnotatorMap {
|
|||
private String updateBy; // 更新者
|
||||
private Date updateTime; // 更新时间
|
||||
private Date createTime; // 创建时间
|
||||
}
|
||||
}
|
||||
|
|
@ -4,10 +4,13 @@ import com.bonus.ai.domain.enums.AnnotationFileStatus;
|
|||
import com.bonus.ai.domain.enums.AnnotationTaskStatus;
|
||||
import com.bonus.common.core.web.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
public class AnnotationTaskEntity extends BaseEntity {
|
||||
|
||||
/**任务名称*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.bonus.ai.mapper;
|
||||
|
||||
import com.bonus.ai.domain.dataset.AnnotationTaskAnnotatorEntity;
|
||||
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -38,7 +39,7 @@ public interface AnnotationTaskMapper
|
|||
* @param taskId 任务ID
|
||||
* @return 标注任务实体
|
||||
*/
|
||||
AnnotationTaskEntity selectAnnotationTaskById(Long taskId);
|
||||
// AnnotationTaskEntity selectAnnotationTaskById(Long taskId);
|
||||
|
||||
/**
|
||||
* 查询标注任务列表
|
||||
|
|
@ -46,4 +47,12 @@ public interface AnnotationTaskMapper
|
|||
* @return 标注任务列表
|
||||
*/
|
||||
List<AnnotationTaskEntity> selectAnnotationTaskList(AnnotationTaskEntity annotationTask);
|
||||
}
|
||||
|
||||
int insertAnnotTaskannotator(List<AnnotationTaskAnnotatorEntity> annotationTaskAnnotatorEntities);
|
||||
|
||||
int deleteTaskById(Long taskId);
|
||||
|
||||
int deleteAnnotator(Long taskId);
|
||||
|
||||
AnnotationTaskEntity selectAnnotationTaskListUUID(Long taskId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
package com.bonus.ai.service.Impl.dataset;
|
||||
|
||||
import com.bonus.ai.client.OnlineAnnotateUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.bonus.ai.client.OnlineAnnotationService;
|
||||
import com.bonus.ai.client.ProjectParam;
|
||||
import com.bonus.ai.client.TaskParam;
|
||||
import com.bonus.ai.config.MinioConfig;
|
||||
import com.bonus.ai.config.OnlineAnnotateConfig;
|
||||
import com.bonus.ai.domain.dataset.AnnotationSubTaskEntity;
|
||||
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
|
||||
import com.bonus.ai.domain.dataset.DataSetEntity;
|
||||
import com.bonus.ai.domain.dataset.*;
|
||||
import com.bonus.ai.mapper.AnnotationTaskMapper;
|
||||
import com.bonus.ai.mapper.DatasetFileMapper;
|
||||
import com.bonus.ai.service.dataset.AnnotationTaskService;
|
||||
import com.bonus.ai.utils.AverageUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
|
|
@ -26,21 +27,51 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
|
|||
@Resource
|
||||
private OnlineAnnotateConfig onlineAnnotateConfig;
|
||||
|
||||
@Resource
|
||||
private AnnotationTaskMapper annotationTaskMapper;
|
||||
|
||||
@Resource
|
||||
private DatasetFileMapper datasetFileMapper;
|
||||
|
||||
@Autowired
|
||||
private AnnotationTaskEntity annotationTaskEntity;
|
||||
|
||||
@Autowired
|
||||
private AnnotationTaskAnnotatorEntity annotationTaskAnnotatorEntity;
|
||||
|
||||
/**
|
||||
* 创建标注任务
|
||||
*/
|
||||
@Override
|
||||
public int createTask(AnnotationTaskEntity task) {
|
||||
int status =0;
|
||||
// TODO 调用label studio 接口获取其project id
|
||||
ProjectParam lSProject = new ProjectParam();
|
||||
lSProject.setTitle(task.getTaskName());
|
||||
lSProject.setDescription(task.getTaskDesc());
|
||||
//需要将标签转换为json格式
|
||||
lSProject.setLabelConfig(task.getLabels());
|
||||
onlineAnnotationService.createProject(lSProject, onlineAnnotateConfig.getApikey());
|
||||
String project = onlineAnnotationService.createProject(lSProject, onlineAnnotateConfig.getApikey());
|
||||
List<ProjectParam> 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);
|
||||
}
|
||||
}
|
||||
//通过数据集id 从数据集和文件关联关系表获取文件信息
|
||||
List<DatasetFile> datafile = datasetFileMapper.selectFilesByDatasetId(task.getDatasetId());
|
||||
//TODO 根据标注任务file list 和标注人信息自动分配
|
||||
List<AnnotationTaskAnnotatorEntity> annotationTaskAnnotatorEntities = AverageUtil.distributeFiles(datafile, task);
|
||||
// 获取project id以后调用AnnotationTaskMapper 和AnnotationTaskAnnotatorMapper 插入数据集
|
||||
return 0;
|
||||
if(status == 1){
|
||||
status = annotationTaskMapper.insertAnnotTaskannotator(annotationTaskAnnotatorEntities);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -73,7 +104,21 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
|
|||
*/
|
||||
@Override
|
||||
public int deleteTaskById(Long taskId) {
|
||||
return 0;
|
||||
//删除任务需要删除两个个表 对应两个个表删除状态修改成1
|
||||
int status = 0;
|
||||
try{
|
||||
//删除主表任务信息
|
||||
status = annotationTaskMapper.deleteTaskById(taskId);
|
||||
//删除团队成员表信息
|
||||
status = annotationTaskMapper.deleteAnnotator(taskId);
|
||||
//查询对应的uuid
|
||||
AnnotationTaskEntity task = annotationTaskMapper.selectAnnotationTaskListUUID(taskId);
|
||||
//删除对应的标注任务文件关联关系表信息
|
||||
onlineAnnotationService.deleteProjectById(task.getTaskUuid(), onlineAnnotateConfig.getApikey());
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.bonus.ai.utils;
|
||||
|
||||
import com.bonus.ai.domain.dataset.AnnotationTaskAnnotatorEntity;
|
||||
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
|
||||
import com.bonus.ai.domain.dataset.DatasetFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AverageUtil {
|
||||
|
||||
/**
|
||||
* 将文件集合分别平分到 annotators 和 reviewers 中
|
||||
* @param files 文件集合
|
||||
* @param taskEntity 标注任务实体
|
||||
* @return 分配结果,包含标注者和审核者的文件分配
|
||||
*/
|
||||
public static List<AnnotationTaskAnnotatorEntity> distributeFiles(List<DatasetFile> files, AnnotationTaskEntity taskEntity) {
|
||||
List<AnnotationTaskAnnotatorEntity> annotatorEntities = new ArrayList<>();
|
||||
|
||||
List<Long> annotators = taskEntity.getAnnotators(); // 获取标注者列表
|
||||
List<Long> reviewers = taskEntity.getReviewers(); // 获取审核者列表
|
||||
|
||||
// 平分文件给标注者
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
Long annotatorId = annotators.get(i % annotators.size()); // 轮流分配给标注者
|
||||
AnnotationTaskAnnotatorEntity entity = new AnnotationTaskAnnotatorEntity();
|
||||
entity.setAnnotatorId(annotatorId); // 设置标注者 ID
|
||||
entity.setFileId(files.get(i).getFileId()); // 假设 DatasetFile 有 getId() 方法
|
||||
annotatorEntities.add(entity);
|
||||
}
|
||||
|
||||
// 平分文件给审核者
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
Long reviewerId = reviewers.get(i % reviewers.size()); // 轮流分配给审核者
|
||||
AnnotationTaskAnnotatorEntity entity = new AnnotationTaskAnnotatorEntity();
|
||||
entity.setAnnotatorId(reviewerId); // 设置审核者 ID
|
||||
entity.setFileId(files.get(i).getFileId()); // 假设 DatasetFile 有 getId() 方法
|
||||
annotatorEntities.add(entity);
|
||||
}
|
||||
|
||||
return annotatorEntities;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,6 +28,16 @@
|
|||
FROM ai_annotation_task t
|
||||
left join ai_annotation_task_annotator_map a on t.task_id = a.task_id
|
||||
</sql>
|
||||
<update id="deleteTaskById">
|
||||
UPDATE ai_annotation_task
|
||||
SET del_flag = '1'
|
||||
WHERE task_id = #{taskId}
|
||||
</update>
|
||||
<update id="deleteAnnotator">
|
||||
UPDATE ai_annotation_task_annotator_map
|
||||
SET del_flag = '1'
|
||||
WHERE task_id = #{taskId}
|
||||
</update>
|
||||
|
||||
<!-- TODO 根据标注人id,查询所有标注文件列表-->
|
||||
|
||||
|
|
@ -57,6 +67,9 @@
|
|||
AND annotation_status = #{annotateTaskStatus}
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectAnnotationTaskListUUID" resultType="com.bonus.ai.domain.dataset.AnnotationTaskEntity">
|
||||
SELECT task_uuid FROM ai_annotation_task where del_flag = 0
|
||||
</select>
|
||||
|
||||
<!-- 插入标注任务 -->
|
||||
<insert id="insertAnnotationTask" parameterType="com.bonus.ai.domain.dataset.AnnotationTaskEntity">
|
||||
|
|
@ -96,6 +109,51 @@
|
|||
<if test="updateTime != null">#{updateTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<insert id="insertAnnotTaskannotator">
|
||||
INSERT INTO ai_annotation_task_annotator_map
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
task_id
|
||||
<if test="annotatorId != null">
|
||||
, annotator_id
|
||||
</if>
|
||||
<if test="reviewerId != null">
|
||||
, reviewer_id
|
||||
</if>
|
||||
<if test="description != null and description != ''">
|
||||
, description
|
||||
</if>
|
||||
<if test="annotationStatus != null">
|
||||
, annotation_status
|
||||
</if>
|
||||
<if test="annotationResult != null">
|
||||
, annotation_result
|
||||
</if>
|
||||
<if test="annotationResource != null">
|
||||
, annotation_resource
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
|
||||
#{taskId}
|
||||
<if test="annotatorId != null">
|
||||
, #{annotatorId}
|
||||
</if>
|
||||
<if test="reviewerId != null">
|
||||
, #{reviewerId}
|
||||
</if>
|
||||
<if test="description != null and description != ''">
|
||||
, #{description}
|
||||
</if>
|
||||
<if test="annotationStatus != null">
|
||||
, #{annotationStatus}
|
||||
</if>
|
||||
<if test="annotationResult != null">
|
||||
, #{annotationResult}
|
||||
</if>
|
||||
<if test="annotationResource != null">
|
||||
, #{annotationResource}
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
|
||||
<!-- 根据任务ID更新标注任务 -->
|
||||
|
|
|
|||
|
|
@ -27,13 +27,12 @@
|
|||
</delete>
|
||||
|
||||
<!-- 删除数据集文件映射关系 -->
|
||||
<delete id="deleteDatasetFiles" parameterType="String">
|
||||
delete from ai_dataset_file_map
|
||||
where dataset_id in
|
||||
<update id="deleteDatasetFiles">
|
||||
update FROM ai_dataset_file_map
|
||||
<foreach collection="array" item="datasetId" open="(" separator="," close=")">
|
||||
#{datasetId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</update>
|
||||
|
||||
<!-- <delete id="deleteDatasetFiles">-->
|
||||
<!-- DELETE FROM ai_dataset_file_map-->
|
||||
|
|
|
|||
Loading…
Reference in New Issue