提交代码

This commit is contained in:
jiang 2024-12-03 09:07:47 +08:00
parent ec6e30b3d7
commit 9024d5dbd2
8 changed files with 174 additions and 81 deletions

View File

@ -1,9 +1,12 @@
package com.bonus.ai.controller; package com.bonus.ai.controller;
import com.bonus.ai.utils.MinioUtil;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.bonus.ai.domain.DataSetBasicFileEntity; import com.bonus.ai.domain.DataSetBasicFileEntity;
import com.bonus.ai.service.dataset.AnnotationTaskService; import com.bonus.ai.service.dataset.AnnotationTaskService;
import com.bonus.common.security.annotation.RequiresPermissions; import com.bonus.common.security.annotation.RequiresPermissions;
import io.swagger.models.auth.In;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -11,9 +14,13 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@RestController @RestController
@ -23,37 +30,64 @@ public class AnnotationExportController {
@Resource @Resource
private AnnotationTaskService annotationTaskService; private AnnotationTaskService annotationTaskService;
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
@Resource
private MinioUtil minioUtil;
@RequiresPermissions("dataCenter:task:annotation:export") @RequiresPermissions("dataCenter:task:annotation:export")
@PostMapping("/export/{taskId}") @PostMapping("/export/{versionId}")
public void exportAuditedAnnotations(HttpServletResponse response, HttpServletRequest request, @PathVariable Long taskId) { public void exportAuditedAnnotations(HttpServletResponse response, HttpServletRequest request, @PathVariable Long versionId) {
try { // Step 1: 获取标注结果
// Step 1: 获取标注结果 List<DataSetBasicFileEntity> annotations = annotationTaskService.geAllAuditAnnotationByTaskId(versionId);
List<DataSetBasicFileEntity> annotations = annotationTaskService.geAllAuditAnnotationByTaskId(taskId);
// Step 2: 按文件生成 JSON // Step 2: 设置响应头
List<File> jsonFiles = new ArrayList<>(); response.setContentType("application/zip");
for (DataSetBasicFileEntity annotation : annotations) { response.setHeader("Content-Disposition", "attachment; filename=annotations.zip");
String fileName = annotation.getFileName() + ".json";
File jsonFile = createJsonFile(fileName, annotation);
jsonFiles.add(jsonFile);
}
// Step 3: 压缩为 ZIP // Step 3: 直接将数据写入 ZIP 输出流
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
// Step 4: 遍历标注结果处理每个文件
for (DataSetBasicFileEntity annotation : annotations) {
String fileName = annotation.getFileName();
// Step 4: 设置响应头提供文件下载 // 下载图片并写入 ZIP
} writeImageToZip(zipOut, fileName, annotation.getFileUrl());
catch (Exception e) {
e.printStackTrace();
}
// 去掉文件扩展名
int dotIndex = fileName.lastIndexOf(".");
if (dotIndex != -1) {
fileName = fileName.substring(0, dotIndex);
}
// 写入 JSON 数据
writeJsonToZip(zipOut, fileName + ".json", annotation.getAnnotationResult());
}
} catch (Exception e) {
// 优化异常处理记录详细错误信息
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
try {
response.getWriter().write("导出失败:" + e.getMessage());
} catch (IOException ex) {
ex.printStackTrace();
}
}
} }
private void writeJsonToZip(ZipOutputStream zipOut, String fileName, String jsonContent) throws IOException {
public File createJsonFile(String fileName, Object data) throws IOException { ZipEntry zipEntry = new ZipEntry(fileName);
File jsonFile = new File(fileName); zipOut.putNextEntry(zipEntry);
objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFile, data); zipOut.write(jsonContent.getBytes(StandardCharsets.UTF_8));
return jsonFile; zipOut.closeEntry();
} }
private void writeImageToZip(ZipOutputStream zipOut, String fileName, String fileUrl) throws IOException {
try (InputStream inputStream = minioUtil.downloadFile(fileUrl)) {
ZipEntry zipEntryImg = new ZipEntry(fileName);
zipOut.putNextEntry(zipEntryImg);
IOUtils.copy(inputStream, zipOut);
zipOut.closeEntry();
}
}
} }

View File

@ -22,7 +22,9 @@ public class ReleaseVersionController extends BaseController {
@Resource @Resource
private ReleaseVersionService releaseVersionService; private ReleaseVersionService releaseVersionService;
/**发布版本可以针对数据集发布也可以对标注任务发布 /**
* 发布版本可以针对数据集发布也可以对标注任务发布
*
* @param version 发布数据集的版本信息 * @param version 发布数据集的版本信息
* @return 返回影响的行数或错误信 * @return 返回影响的行数或错误信
*/ */
@ -32,7 +34,9 @@ public class ReleaseVersionController extends BaseController {
return releaseVersionService.release(version); return releaseVersionService.release(version);
} }
/**导出发布版本的数据集 /**
* 导出发布版本的数据集
*
* @param versionId 发布数据集的版本id * @param versionId 发布数据集的版本id
* @return 返回影响的行数或错误信 * @return 返回影响的行数或错误信
*/ */
@ -44,6 +48,7 @@ public class ReleaseVersionController extends BaseController {
/** /**
* 删除版本发布 * 删除版本发布
*
* @param versionIds id 集合 * @param versionIds id 集合
* @return * @return
*/ */
@ -54,9 +59,9 @@ public class ReleaseVersionController extends BaseController {
} }
/** /**
* 查看发布的版本列表 * 查看发布的版本列表
*
* @return 返回满足条件的版本列表 * @return 返回满足条件的版本列表
*/ */
@RequiresPermissions("dataCenter:version:list") @RequiresPermissions("dataCenter:version:list")
@ -66,8 +71,20 @@ public class ReleaseVersionController extends BaseController {
startPage(); startPage();
List<ReleaseVersionEntity> allReleaseVersions = releaseVersionService.getAllReleaseVersions(version); List<ReleaseVersionEntity> allReleaseVersions = releaseVersionService.getAllReleaseVersions(version);
return getDataTable(allReleaseVersions); return getDataTable(allReleaseVersions);
}catch (Exception e) { } catch (Exception e) {
return getDataTable(new ArrayList<>()); return getDataTable(new ArrayList<>());
} }
} }
/**
* 查看发布的版本列表
*
* @return 返回满足条件的版本列表
*/
@GetMapping("/listSelect")
public AjaxResult listSelect(ReleaseVersionEntity version) {
List<ReleaseVersionEntity> allReleaseVersions = releaseVersionService.getAllReleaseVersions(version);
return AjaxResult.success(allReleaseVersions);
}
} }

View File

@ -1,7 +1,9 @@
package com.bonus.ai.mapper; package com.bonus.ai.mapper;
import com.bonus.ai.domain.DataSetBasicFileEntity;
import com.bonus.ai.domain.dataset.ReleaseVersionEntity; import com.bonus.ai.domain.dataset.ReleaseVersionEntity;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -31,4 +33,10 @@ public interface ReleaseVersionMapper {
* @return 条数 * @return 条数
*/ */
int delete(Long[] versionIds); int delete(Long[] versionIds);
void releaseMap( @Param("taskBasicFile") List<DataSetBasicFileEntity> taskBasicFile,@Param("versionId") Long versionId);
List<DataSetBasicFileEntity> getReleaseMapList(Long versionId);
void deleteMap(Long versionId);
} }

View File

@ -8,6 +8,7 @@ import com.bonus.ai.domain.DataSetBasicFileEntity;
import com.bonus.ai.domain.dataset.*; import com.bonus.ai.domain.dataset.*;
import com.bonus.ai.mapper.AnnotationTaskMapper; import com.bonus.ai.mapper.AnnotationTaskMapper;
import com.bonus.ai.mapper.DatasetFileMapper; import com.bonus.ai.mapper.DatasetFileMapper;
import com.bonus.ai.mapper.ReleaseVersionMapper;
import com.bonus.ai.service.dataset.AnnotationTaskService; import com.bonus.ai.service.dataset.AnnotationTaskService;
import com.bonus.ai.utils.AverageUtil; import com.bonus.ai.utils.AverageUtil;
import com.bonus.common.core.utils.SpringUtils; import com.bonus.common.core.utils.SpringUtils;
@ -49,6 +50,9 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
@Resource @Resource
private DatasetFileMapper datasetFileMapper; private DatasetFileMapper datasetFileMapper;
@Resource
private ReleaseVersionMapper releaseVersionMapper;
@Resource @Resource
private MinioConfig minioConfig; private MinioConfig minioConfig;
@ -335,17 +339,8 @@ public class AnnotationTaskServiceImpl implements AnnotationTaskService {
} }
@Override @Override
public List<DataSetBasicFileEntity> geAllAuditAnnotationByTaskId(Long taskId){ public List<DataSetBasicFileEntity> geAllAuditAnnotationByTaskId(Long versionId){
try { return releaseVersionMapper.getReleaseMapList(versionId);
AnnotationTaskEntity task = new AnnotationTaskEntity();
task.setTaskId(taskId);
task.setFileAnnotationStatus("2");
return annotationTaskMapper.getTaskBasicFile(task);
}catch (Exception e)
{
e.printStackTrace();
return new ArrayList<>();
}
} }
@Override @Override
public String getLatestDatasetVersion(Long datasetId ){ public String getLatestDatasetVersion(Long datasetId ){

View File

@ -1,6 +1,9 @@
package com.bonus.ai.service.Impl.dataset; package com.bonus.ai.service.Impl.dataset;
import com.bonus.ai.domain.DataSetBasicFileEntity;
import com.bonus.ai.domain.dataset.AnnotationTaskEntity;
import com.bonus.ai.domain.dataset.ReleaseVersionEntity; import com.bonus.ai.domain.dataset.ReleaseVersionEntity;
import com.bonus.ai.mapper.AnnotationTaskMapper;
import com.bonus.ai.mapper.ReleaseVersionMapper; import com.bonus.ai.mapper.ReleaseVersionMapper;
import com.bonus.ai.service.dataset.ReleaseVersionService; import com.bonus.ai.service.dataset.ReleaseVersionService;
import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.core.web.domain.AjaxResult;
@ -15,9 +18,13 @@ import java.util.List;
* @author bonus * @author bonus
*/ */
@Service @Service
public class ReleaseVersionServiceImpl implements ReleaseVersionService { public class ReleaseVersionServiceImpl implements ReleaseVersionService {
@Resource @Resource
private ReleaseVersionMapper mapper; private ReleaseVersionMapper mapper;
@Resource
private AnnotationTaskMapper annotationTaskMapper;
/** /**
* 获取数据集版本列表 * 获取数据集版本列表
* *
@ -38,10 +45,21 @@ public class ReleaseVersionServiceImpl implements ReleaseVersionService {
@Override @Override
public AjaxResult release(ReleaseVersionEntity version) { public AjaxResult release(ReleaseVersionEntity version) {
try { try {
AnnotationTaskEntity task = new AnnotationTaskEntity();
task.setTaskId(version.getTaskId());
task.setFileAnnotationStatus("2");
List<DataSetBasicFileEntity> taskBasicFile = annotationTaskMapper.getTaskBasicFile(task);
if (taskBasicFile.isEmpty()) {
return AjaxResult.error("不存在已审核的标注信息,不能发布");
}
version.setCreateBy(SecurityUtils.getUserId().toString()); version.setCreateBy(SecurityUtils.getUserId().toString());
int num = mapper.release(version); int num = mapper.release(version);
return num>0?AjaxResult.success():AjaxResult.error(); if (num > 0) {
}catch (Exception e) { mapper.releaseMap(taskBasicFile, version.getVersionId());
}
return num > 0 ? AjaxResult.success() : AjaxResult.error();
} catch (Exception e) {
return AjaxResult.error(); return AjaxResult.error();
} }
} }
@ -56,8 +74,11 @@ public class ReleaseVersionServiceImpl implements ReleaseVersionService {
public AjaxResult delete(Long[] versionIds) { public AjaxResult delete(Long[] versionIds) {
try { try {
int delete = mapper.delete(versionIds); int delete = mapper.delete(versionIds);
return delete>0?AjaxResult.success():AjaxResult.error(); for (Long versionId : versionIds) {
}catch (Exception e) { mapper.deleteMap(versionId);
}
return delete > 0 ? AjaxResult.success() : AjaxResult.error();
} catch (Exception e) {
return AjaxResult.error(); return AjaxResult.error();
} }
} }

View File

@ -31,4 +31,7 @@ public interface ReleaseVersionService {
* @return 条数 * @return 条数
*/ */
AjaxResult delete(Long[] versionIds); AjaxResult delete(Long[] versionIds);
} }

View File

@ -352,20 +352,11 @@
<select id="getLatestDatasetVersion" <select id="getLatestDatasetVersion"
parameterType="Long" resultType="String"> parameterType="Long" resultType="String">
SELECT SELECT version_name
t.version_name FROM ai_dataset_version
FROM WHERE dataset_id = #{datasetId}
ai_dataset_version t ORDER BY create_time DESC
WHERE LIMIT 1
t.create_time = (
SELECT
MAX(create_time)
FROM
ai_dataset_version
WHERE
dataset_id = t.dataset_id
)
AND t.dataset_id = #{datasetId}
</select> </select>

View File

@ -1,10 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bonus.ai.mapper.ReleaseVersionMapper"> <mapper namespace="com.bonus.ai.mapper.ReleaseVersionMapper">
<insert id="release"> <insert id="release" useGeneratedKeys="true" keyProperty="versionId">
INSERT INTO ai_dataset_version (version_name, version_description, dataset_id, task_id, create_by) INSERT INTO ai_dataset_version (version_name, version_description, dataset_id, task_id, create_by)
VALUES (#{versionName}, #{versionDesc}, #{datasetId}, #{taskId}, #{createBy}); VALUES (#{versionName}, #{versionDesc}, #{datasetId}, #{taskId}, #{createBy});
</insert> </insert>
<insert id="releaseMap">
INSERT INTO ai_version_file_map (version_id, file_id, annotation_result)
VALUES
<foreach collection="taskBasicFile" item="item" index="index" separator=",">
(#{versionId}, #{item.fileId}, #{item.annotationResult})
</foreach>
</insert>
<update id="delete"> <update id="delete">
update ai_dataset_version set del_flag='1' where version_id in update ai_dataset_version set del_flag='1' where version_id in
@ -12,32 +19,49 @@
#{id} #{id}
</foreach> </foreach>
</update> </update>
<delete id="deleteMap">
delete from ai_version_file_map where version_id = #{versionId}
</delete>
<select id="getAllReleaseVersions" resultType="com.bonus.ai.domain.dataset.ReleaseVersionEntity"> <select id="getAllReleaseVersions" resultType="com.bonus.ai.domain.dataset.ReleaseVersionEntity">
select atv.version_id AS versionId, SELECT
atv.version_name AS versionName, adv.version_id AS versionId,
atv.version_description AS versionDesc, ad.dataset_name AS datasetName,
atv.dataset_id AS datasetId, adv.version_name AS versionName,
atv.task_id AS taskId,
atv.create_by AS createBy,
atv.create_time AS createTime,
aat.task_name as taskName,
ad.dataset_name as datasetName,
aat.annotation_type as annotationType,
su.user_name AS releaseUserName, su.user_name AS releaseUserName,
SUM(CASE WHEN ap.annotation_status = '2' or ap.annotation_status = '3' THEN 1 ELSE 0 END) AS auditedCount, adv.create_time AS createTime,
COUNT(*) AS totalCount aat.task_name AS taskName,
from ai_dataset_version atv aat.annotation_type AS annotationType,
left join ai_annotation_task aat on aat.task_id = atv.task_id COUNT(avfm.version_id) AS totalCount
left join ai_dataset ad on ad.dataset_id = atv.dataset_id FROM
left join ai_annotation_task_annotator_map ap on atv.task_id = ap.task_id ai_dataset_version adv
left join sys_user su ON su.user_id = atv.create_by LEFT JOIN ai_dataset ad ON adv.dataset_id = ad.dataset_id
where atv.del_flag = '0' and ap.annotation_status IN ('0', '1', '2','3') and atv.dataset_id =#{datasetId} LEFT JOIN sys_user su ON adv.create_by = su.user_id
LEFT JOIN ai_annotation_task aat ON adv.task_id = aat.task_id
LEFT JOIN ai_version_file_map avfm ON adv.version_id = avfm.version_id
WHERE adv.dataset_id =#{datasetId} AND adv.del_flag='0'
<if test="versionName != null and versionName != ''"> <if test="versionName != null and versionName != ''">
AND atv.version_name LIKE CONCAT('%', #{versionName}, '%') AND adv.version_name LIKE CONCAT('%', #{versionName}, '%')
</if> </if>
GROUP BY ap.task_id, atv.create_time GROUP BY
ORDER BY atv.create_time DESC adv.version_id,
ad.dataset_name,
adv.version_name,
su.user_name,
adv.create_time,
aat.task_name,
aat.annotation_type
ORDER BY
adv.create_time DESC
</select> </select>
<select id="getReleaseMapList" resultType="com.bonus.ai.domain.DataSetBasicFileEntity">
SELECT
adf.file_name AS fileName,
adf.file_url AS fileUrl,
avfm.annotation_result AS annotationResult
from ai_version_file_map avfm
LEFT JOIN ai_basic_file adf ON avfm.file_id = adf.file_id AND adf.del_flag = '0'
WHERE avfm.version_id =#{versionId}
</select>
</mapper> </mapper>