Compare commits
1 Commits
a8aa2a60fe
...
feature/zi
| Author | SHA1 | Date | |
|---|---|---|---|
| daf84cd6fe |
@@ -1,11 +1,16 @@
|
|||||||
package com.tashow.cloud.ai.controller.admin.aisample;
|
package com.tashow.cloud.ai.controller.admin.aisample;
|
||||||
|
|
||||||
import com.tashow.cloud.ai.controller.admin.aisample.vo.*;
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleFileRespVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSamplePageReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRelateModelVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRelateTagVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRespVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleSaveReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.FileUploadReqVO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
||||||
import com.tashow.cloud.ai.service.aisample.AiSampleService;
|
import com.tashow.cloud.ai.service.aisample.AiSampleService;
|
||||||
import com.tashow.cloud.common.pojo.CommonResult;
|
import com.tashow.cloud.common.pojo.CommonResult;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
import com.tashow.cloud.common.util.object.BeanUtils;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@@ -14,7 +19,14 @@ import jakarta.annotation.security.PermitAll;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -33,14 +45,12 @@ public class AiSampleController {
|
|||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建样本库-上传文件")
|
@Operation(summary = "创建样本库-上传文件")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:create')")
|
|
||||||
public CommonResult<List<AiSampleFileRespVO>> createAiSample(FileUploadReqVO uploadReqVO) {
|
public CommonResult<List<AiSampleFileRespVO>> createAiSample(FileUploadReqVO uploadReqVO) {
|
||||||
return success(aiSampleService.createAiSample(uploadReqVO));
|
return success(aiSampleService.createAiSample(uploadReqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/updates")
|
@PutMapping("/updates")
|
||||||
@Operation(summary = "更新样本库")
|
@Operation(summary = "批量更新样本")
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:update')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<Boolean> updateAiSample(@Valid @RequestBody List<AiSampleSaveReqVO> updateReqVO) {
|
public CommonResult<Boolean> updateAiSample(@Valid @RequestBody List<AiSampleSaveReqVO> updateReqVO) {
|
||||||
aiSampleService.updateAiSamples(updateReqVO);
|
aiSampleService.updateAiSamples(updateReqVO);
|
||||||
@@ -49,7 +59,6 @@ public class AiSampleController {
|
|||||||
|
|
||||||
@PutMapping("/relate")
|
@PutMapping("/relate")
|
||||||
@Operation(summary = "添加关联标签")
|
@Operation(summary = "添加关联标签")
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:update')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<Boolean> relate(@Valid @RequestBody AiSampleRelateTagVO relateTagVO) {
|
public CommonResult<Boolean> relate(@Valid @RequestBody AiSampleRelateTagVO relateTagVO) {
|
||||||
aiSampleService.relate(relateTagVO);
|
aiSampleService.relate(relateTagVO);
|
||||||
@@ -58,7 +67,6 @@ public class AiSampleController {
|
|||||||
|
|
||||||
@DeleteMapping("/deleteRelate")
|
@DeleteMapping("/deleteRelate")
|
||||||
@Operation(summary = "删除关联标签")
|
@Operation(summary = "删除关联标签")
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:delete')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<Boolean> deleteRelate(@Valid @RequestBody AiSampleRelateTagVO relateTagVO) {
|
public CommonResult<Boolean> deleteRelate(@Valid @RequestBody AiSampleRelateTagVO relateTagVO) {
|
||||||
aiSampleService.deleteRelate(relateTagVO);
|
aiSampleService.deleteRelate(relateTagVO);
|
||||||
@@ -66,9 +74,8 @@ public class AiSampleController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
@DeleteMapping("/delete")
|
||||||
@Operation(summary = "删除样本库")
|
@Operation(summary = "删除样本")
|
||||||
@Parameter(name = "id", description = "编号", required = true)
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:delete')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<Boolean> deleteAiSample(@RequestParam("id") String ids) {
|
public CommonResult<Boolean> deleteAiSample(@RequestParam("id") String ids) {
|
||||||
aiSampleService.deleteAiSample(ids);
|
aiSampleService.deleteAiSample(ids);
|
||||||
@@ -76,30 +83,36 @@ public class AiSampleController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@Operation(summary = "获得样本库")
|
@Operation(summary = "获得样本")
|
||||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:query')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<AiSampleRespVO> getAiSample(@RequestParam("id") Long id) {
|
public CommonResult<AiSampleRespVO> getAiSample(@RequestParam("id") Long id) {
|
||||||
AiSampleDO aiSample = aiSampleService.getAiSample(id);
|
return success(aiSampleService.buildSampleRespVO(aiSampleService.getAiSample(id)));
|
||||||
return success(BeanUtils.toBean(aiSample, AiSampleRespVO.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得样本库分页")
|
@Operation(summary = "获得样本分页")
|
||||||
// @PreAuthorize("@ss.hasPermission('ai:sample:query')")
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public CommonResult<PageResult<AiSampleRespVO>> getAiSamplePage(@Valid AiSamplePageReqVO pageReqVO) {
|
public CommonResult<PageResult<AiSampleRespVO>> getAiSamplePage(@Valid AiSamplePageReqVO pageReqVO) {
|
||||||
PageResult<AiSampleDO> pageResult = aiSampleService.getAiSamplePage(pageReqVO);
|
PageResult<AiSampleDO> pageResult = aiSampleService.getAiSamplePage(pageReqVO);
|
||||||
return success(BeanUtils.toBean(pageResult, AiSampleRespVO.class));
|
List<AiSampleRespVO> list = pageResult.getList().stream().map(aiSampleService::buildSampleRespVO).toList();
|
||||||
|
return success(new PageResult<>(list, pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/download")
|
@GetMapping("/download")
|
||||||
@Operation(summary = "批量下载样本")
|
@Operation(summary = "批量下载样本")
|
||||||
@Parameter(name = "ids", description = "样本ID列表(逗号分隔)", required = true, example = "1,2,3")
|
@Parameter(name = "ids", description = "样本ID列表,逗号分隔", required = true, example = "1,2,3")
|
||||||
@PermitAll
|
@PermitAll
|
||||||
public void downloadSamples(@RequestParam("ids") String ids, HttpServletResponse response) throws IOException {
|
public void downloadSamples(@RequestParam("ids") String ids, HttpServletResponse response) throws IOException {
|
||||||
aiSampleService.downloadSamples(ids, response);
|
aiSampleService.downloadSamples(ids, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/relateModel")
|
||||||
|
@Operation(summary = "样本关联模型")
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<Boolean> relateModel(@Valid @RequestBody AiSampleRelateModelVO relateModelVO) {
|
||||||
|
aiSampleService.relateSamples(relateModelVO.getSampleIds(), relateModelVO.getModelIds());
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.tashow.cloud.ai.controller.admin.aisample.vo;
|
|||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
import com.tashow.cloud.common.serializer.ImgJsonSerializer;
|
import com.tashow.cloud.common.serializer.ImgJsonSerializer;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -18,4 +17,5 @@ public class AiSampleFileRespVO {
|
|||||||
|
|
||||||
@Schema(description = "文件名称")
|
@Schema(description = "文件名称")
|
||||||
private String fileName;
|
private String fileName;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.aisample.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 样本关联模型 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AiSampleRelateModelVO {
|
||||||
|
|
||||||
|
@Schema(description = "样本ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private List<Long> sampleIds;
|
||||||
|
|
||||||
|
@Schema(description = "模型ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private List<Long> modelIds;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,22 +5,38 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
||||||
import com.tashow.cloud.common.serializer.ImgJsonSerializer;
|
import com.tashow.cloud.common.serializer.ImgJsonSerializer;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 样本库 Response VO")
|
@Schema(description = "管理后台 - 样本库 Response VO")
|
||||||
@Data
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class AiSampleRespVO {
|
public class AiSampleRespVO {
|
||||||
|
|
||||||
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "7701")
|
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "7701")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "标签列表")
|
@Schema(description = "标签列表(已废弃,使用enumTags和customTags代替)")
|
||||||
|
@Deprecated
|
||||||
private List<AiSampleTagDO> tags;
|
private List<AiSampleTagDO> tags;
|
||||||
|
|
||||||
|
@Schema(description = "枚举标签列表(包含分组信息)")
|
||||||
|
private List<TagInfo> enumTags;
|
||||||
|
|
||||||
|
// @Schema(description = "个性标签列表")
|
||||||
|
// private List<TagInfo> customTags;
|
||||||
|
|
||||||
|
@Schema(description = "关联模型列表")
|
||||||
|
private List<ModelInfo> relatedModels;
|
||||||
|
|
||||||
@Schema(description = "样本文件地址")
|
@Schema(description = "样本文件地址")
|
||||||
@JsonSerialize(using = ImgJsonSerializer.class)
|
@JsonSerialize(using = ImgJsonSerializer.class)
|
||||||
private String sampleFilePath;
|
private String sampleFilePath;
|
||||||
@@ -51,6 +67,42 @@ public class AiSampleRespVO {
|
|||||||
@Schema(description = "文件后缀")
|
@Schema(description = "文件后缀")
|
||||||
private String suffix;
|
private String suffix;
|
||||||
|
|
||||||
|
@Schema(description = "标签信息")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class TagInfo {
|
||||||
|
@Schema(description = "标签ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "标签名称")
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(description = "枚举值")
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
|
@Schema(description = "分组ID")
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
@Schema(description = "分组名称")
|
||||||
|
private String groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "模型信息")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class ModelInfo {
|
||||||
|
@Schema(description = "模型ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "模型名称")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@Schema(description = "版本号")
|
||||||
|
private String version;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import lombok.*;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import com.alibaba.excel.annotation.*;
|
import com.alibaba.excel.annotation.*;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 样本标签分组库 Response VO")
|
@Schema(description = "管理后台 - 样本标签")
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class AiSampleTagGroupRespVO {
|
public class AiSampleTagGroupRespVO {
|
||||||
@@ -19,6 +19,10 @@ public class AiSampleTagGroupRespVO {
|
|||||||
@ExcelProperty("分组名称")
|
@ExcelProperty("分组名称")
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
|
||||||
|
@Schema(description = "1-枚举型, 2-个性型", example = "1")
|
||||||
|
@ExcelProperty("分组类型")
|
||||||
|
private Integer groupType;
|
||||||
|
|
||||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@ExcelProperty("创建时间")
|
@ExcelProperty("创建时间")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.tashow.cloud.ai.controller.admin.aisample.vo;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 样本标签分组库新增/修改 Request VO")
|
@Schema(description = "管理后台 - 样本标签分组库")
|
||||||
@Data
|
@Data
|
||||||
public class AiSampleTagGroupSaveReqVO {
|
public class AiSampleTagGroupSaveReqVO {
|
||||||
|
|
||||||
@@ -13,4 +13,10 @@ public class AiSampleTagGroupSaveReqVO {
|
|||||||
@Schema(description = "分组名称", example = "张三")
|
@Schema(description = "分组名称", example = "张三")
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
|
||||||
|
@Schema(description = "分组类型:1-枚举型, 2-个性型", example = "1")
|
||||||
|
private Integer groupType;
|
||||||
|
|
||||||
|
@Schema(description = "枚举值(枚举分组专用)", example = "猫")
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -13,4 +13,8 @@ public class AiSampleTagListRespVO {
|
|||||||
private Long id;
|
private Long id;
|
||||||
@Schema(description = "标签名称")
|
@Schema(description = "标签名称")
|
||||||
private String tagName;
|
private String tagName;
|
||||||
|
@Schema(description = "标签类型:1-枚举标签, 2-个性标签")
|
||||||
|
private Integer tagType;
|
||||||
|
@Schema(description = "枚举值")
|
||||||
|
private String enumValue;
|
||||||
}
|
}
|
||||||
@@ -18,4 +18,13 @@ public class AiSampleTagSaveReqVO {
|
|||||||
@Schema(description = "标签名称", example = "张三")
|
@Schema(description = "标签名称", example = "张三")
|
||||||
private String tagName;
|
private String tagName;
|
||||||
|
|
||||||
|
@Schema(description = "标签类型:1-枚举标签, 2-个性标签", example = "1")
|
||||||
|
private Integer tagType;
|
||||||
|
|
||||||
|
@Schema(description = "枚举值", example = "猫")
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
|
@Schema(description = "关联分组ID(单个ID或逗号分隔的多个ID)", example = "1")
|
||||||
|
private String groupId;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
package com.tashow.cloud.ai.controller.admin.model;
|
package com.tashow.cloud.ai.controller.admin.model;
|
||||||
|
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRespVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelAccuracyAnalysisReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelAnalysisResultVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelDifferenceVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelIterateReqVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelReferenceSamplesReqVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelRespVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelRespVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
||||||
|
import com.tashow.cloud.ai.service.aisample.AiSampleService;
|
||||||
import com.tashow.cloud.ai.service.model.AiModelService;
|
import com.tashow.cloud.ai.service.model.AiModelService;
|
||||||
import com.tashow.cloud.common.pojo.CommonResult;
|
import com.tashow.cloud.common.pojo.CommonResult;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
@@ -15,7 +23,14 @@ import jakarta.annotation.Resource;
|
|||||||
import jakarta.annotation.security.PermitAll;
|
import jakarta.annotation.security.PermitAll;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -29,6 +44,8 @@ public class AiModelController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AiModelService modelService;
|
private AiModelService modelService;
|
||||||
|
@Resource
|
||||||
|
private AiSampleService aiSampleService;
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建模型")
|
@Operation(summary = "创建模型")
|
||||||
@@ -70,4 +87,42 @@ public class AiModelController {
|
|||||||
return success(BeanUtils.toBean(pageResult, AiModelRespVO.class));
|
return success(BeanUtils.toBean(pageResult, AiModelRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/reference-samples")
|
||||||
|
@Operation(summary = "模型引用样本")
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<Boolean> referenceSamples(@Valid @RequestBody AiModelReferenceSamplesReqVO reqVO) {
|
||||||
|
modelService.referenceSamples(reqVO.getModelId(), reqVO.getSampleIds());
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/samples")
|
||||||
|
@Operation(summary = "获取模型关联样本")
|
||||||
|
@Parameter(name = "modelId", description = "模型ID", required = true)
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<List<AiSampleRespVO>> getModelSamples(@RequestParam Long modelId) {
|
||||||
|
List<AiSampleDO> samples = modelService.getModelSamples(modelId);
|
||||||
|
return success(samples.stream().map(aiSampleService::buildSampleRespVO).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/accuracy-analysis")
|
||||||
|
@Operation(summary = "模型准确度分析")
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<AiModelAnalysisResultVO> analyzeModel(@Valid @RequestBody AiModelAccuracyAnalysisReqVO reqVO) {
|
||||||
|
return success(modelService.analyzeModel(reqVO.getSampleIds(), reqVO.getModelIds()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/difference")
|
||||||
|
@Operation(summary = "模型样本差异筛查")
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<AiModelDifferenceVO> checkDifference(@RequestParam List<Long> modelIds) {
|
||||||
|
return success(modelService.checkDifference(modelIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/iterate")
|
||||||
|
@Operation(summary = "模型迭代")
|
||||||
|
@PermitAll
|
||||||
|
public CommonResult<Long> iterateModel(@Valid @RequestBody AiModelIterateReqVO reqVO) {
|
||||||
|
return success(modelService.iterateModel(reqVO.getModelId(), reqVO.getNewVersion(), reqVO.getDescription()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 模型准确度分析 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AiModelAccuracyAnalysisReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "样本ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotEmpty(message = "样本ID列表不能为空")
|
||||||
|
private List<Long> sampleIds;
|
||||||
|
|
||||||
|
@Schema(description = "模型ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotEmpty(message = "模型ID列表不能为空")
|
||||||
|
private List<Long> modelIds;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 模型准确度分析")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AiModelAnalysisResultVO {
|
||||||
|
|
||||||
|
@Schema(description = "样本分析列表")
|
||||||
|
private List<SampleAnalysis> samples;
|
||||||
|
|
||||||
|
@Schema(description = "样本分析")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class SampleAnalysis {
|
||||||
|
@Schema(description = "样本ID")
|
||||||
|
private Long sampleId;
|
||||||
|
|
||||||
|
@Schema(description = "样本名称", example = "")
|
||||||
|
private String sampleName;
|
||||||
|
|
||||||
|
@Schema(description = "枚举标签", example = "猫")
|
||||||
|
private String enumTag;
|
||||||
|
|
||||||
|
@Schema(description = "模型分析结果列表")
|
||||||
|
private List<ModelAnalysisResult> modelResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "模型分析结果")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class ModelAnalysisResult {
|
||||||
|
@Schema(description = "模型ID")
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
@Schema(description = "模型名称", example = "A01 模型")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@Schema(description = "模型版本", example = "V1.0.0")
|
||||||
|
private String modelVersion;
|
||||||
|
|
||||||
|
@Schema(description = "物种识别结果", example = "猫")
|
||||||
|
private String speciesResult;
|
||||||
|
|
||||||
|
@Schema(description = "物种匹配度", example = "1.00")
|
||||||
|
private BigDecimal speciesMatchRate;
|
||||||
|
|
||||||
|
@Schema(description = "情绪识别结果", example = "兴奋")
|
||||||
|
private String emotionResult;
|
||||||
|
|
||||||
|
@Schema(description = "情绪匹配度", example = "0.95")
|
||||||
|
private BigDecimal emotionMatchRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 模型样本差异")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AiModelDifferenceVO {
|
||||||
|
|
||||||
|
@Schema(description = "重复引用样本列表")
|
||||||
|
private List<AiSampleDetailVO> duplicatedSamples;
|
||||||
|
|
||||||
|
@Schema(description = "未重复引用样本列表")
|
||||||
|
private List<AiSampleDetailVO> uniqueSamples;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 模型迭代 ")
|
||||||
|
@Data
|
||||||
|
public class AiModelIterateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "模型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "模型ID不能为空")
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
@Schema(description = "新版本号", requiredMode = Schema.RequiredMode.REQUIRED, example = "v2.0")
|
||||||
|
@NotBlank(message = "新版本号不能为空")
|
||||||
|
private String newVersion;
|
||||||
|
|
||||||
|
@Schema(description = "版本描述", example = "优化算法性能")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,19 +6,19 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - AI模型分页 Request VO")
|
@Schema(description = "管理后台 - AI模型分")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class AiModelPageReqVO extends PageParam {
|
public class AiModelPageReqVO extends PageParam {
|
||||||
|
|
||||||
@Schema(description = "模型名称(模糊查询)", example = "宠物声音翻译")
|
@Schema(description = "模型名称", example = "宠物声音翻译")
|
||||||
private String modelName;
|
private String modelName;
|
||||||
|
|
||||||
@Schema(description = "版本号(精确查询)", example = "v1.0.0")
|
@Schema(description = "版本号", example = "v1.0.0")
|
||||||
private String version;
|
private String version;
|
||||||
|
|
||||||
@Schema(description = "状态(0-禁用 1-启用 2-测试中 3-已废弃)", example = "1")
|
@Schema(description = "状态(0-禁用 1-启用)", example = "1")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 模型引用样")
|
||||||
|
@Data
|
||||||
|
public class AiModelReferenceSamplesReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "模型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "模型ID不能为空")
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
@Schema(description = "样本ID列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotEmpty(message = "样本ID列表不能为空")
|
||||||
|
private List<Long> sampleIds;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - AI模型 Response VO")
|
@Schema(description = "管理后台 - AI模型")
|
||||||
@Data
|
@Data
|
||||||
public class AiModelRespVO {
|
public class AiModelRespVO {
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - AI模型新增/修改 Request VO")
|
@Schema(description = "管理后台 - AI模型")
|
||||||
@Data
|
@Data
|
||||||
public class AiModelSaveReqVO {
|
public class AiModelSaveReqVO {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.tashow.cloud.ai.controller.admin.model.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 样本详情VO - 用于模型分析和差异筛查
|
||||||
|
*/
|
||||||
|
@Schema(description = "样本详情VO")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AiSampleDetailVO {
|
||||||
|
|
||||||
|
@Schema(description = "样本ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "样本名称")
|
||||||
|
private String sampleName;
|
||||||
|
|
||||||
|
@Schema(description = "样本文件地址")
|
||||||
|
private String sampleFilePath;
|
||||||
|
|
||||||
|
@Schema(description = "枚举标签列表")
|
||||||
|
private List<TagInfo> enumTags;
|
||||||
|
|
||||||
|
@Schema(description = "个性标签列表")
|
||||||
|
private List<TagInfo> customTags;
|
||||||
|
|
||||||
|
@Schema(description = "关联模型列表")
|
||||||
|
private List<ModelInfo> relatedModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签信息
|
||||||
|
*/
|
||||||
|
@Schema(description = "标签信息")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class TagInfo {
|
||||||
|
@Schema(description = "标签ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "标签名称")
|
||||||
|
private String tagName;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "枚举值")
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
|
@Schema(description = "分组名称")
|
||||||
|
private String groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型信息
|
||||||
|
*/
|
||||||
|
@Schema(description = "模型信息")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class ModelInfo {
|
||||||
|
@Schema(description = "模型ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "模型名称")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@Schema(description = "版本号")
|
||||||
|
private String version;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.tashow.cloud.ai.dal.dataobject.aisample;
|
package com.tashow.cloud.ai.dal.dataobject.aisample;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
|
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 样本标签库 DO
|
* 样本标签库 DO
|
||||||
@@ -30,5 +30,19 @@ public class AiSampleTagDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private String tagName;
|
private String tagName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举值
|
||||||
|
*/
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签类型:1-枚举标签, 2-个性标签
|
||||||
|
*/
|
||||||
|
private Integer tagType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联分组ID(单个ID或逗号分隔的多个ID)
|
||||||
|
*/
|
||||||
|
private String groupId;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -31,4 +31,14 @@ public class AiSampleTagGroupDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组类型:1-枚举型, 2-个性型
|
||||||
|
*/
|
||||||
|
private Integer groupType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 枚举值
|
||||||
|
*/
|
||||||
|
private String enumValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.tashow.cloud.ai.dal.dataobject.model;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型样本关联 DO
|
||||||
|
*
|
||||||
|
* @author tashow
|
||||||
|
*/
|
||||||
|
@TableName("tz_ai_model_sample_relate")
|
||||||
|
@KeySequence("tz_ai_model_sample_relate_seq")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AiModelSampleRelateDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型ID
|
||||||
|
*/
|
||||||
|
private Long modelId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 样本ID
|
||||||
|
*/
|
||||||
|
private Long sampleId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,13 +24,12 @@ public interface AiSampleTagMapper extends BaseMapperX<AiSampleTagDO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Select("<script>" +
|
@Select("<script>" +
|
||||||
"SELECT t.id, t.tag_name tagName " +
|
"SELECT t.id, t.tag_name tagName, t.tag_type tagType, t.enum_value enumValue, t.group_id groupId " +
|
||||||
"FROM tz_ai_sample_tag t " +
|
"FROM tz_ai_sample_tag t " +
|
||||||
"INNER JOIN tz_ai_sample_tag_group_relate r ON t.id = r.sample_tag_id " +
|
|
||||||
"<where>" +
|
"<where>" +
|
||||||
"AND t.deleted =0"+
|
" t.deleted = 0" +
|
||||||
" <if test=\"pageReqVO.groupId != null\">" +
|
" <if test=\"pageReqVO.groupId != null\">" +
|
||||||
" AND r.sample_tag_group_id = #{pageReqVO.groupId}" +
|
" AND (t.group_id IS NULL OR FIND_IN_SET(#{pageReqVO.groupId}, t.group_id))" +
|
||||||
" </if>" +
|
" </if>" +
|
||||||
" <if test=\"pageReqVO.tagName != null and pageReqVO.tagName != ''\">" +
|
" <if test=\"pageReqVO.tagName != null and pageReqVO.tagName != ''\">" +
|
||||||
" AND t.tag_name LIKE CONCAT('%',#{pageReqVO.tagName},'%')" +
|
" AND t.tag_name LIKE CONCAT('%',#{pageReqVO.tagName},'%')" +
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.tashow.cloud.ai.dal.mysql.model;
|
||||||
|
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelSampleRelateDO;
|
||||||
|
import com.tashow.cloud.mybatis.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型样本关联 Mapper
|
||||||
|
*
|
||||||
|
* @author tashow
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface AiModelSampleRelateMapper extends BaseMapperX<AiModelSampleRelateDO> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -79,4 +79,20 @@ public interface AiSampleService {
|
|||||||
*/
|
*/
|
||||||
void downloadSamples(String ids, HttpServletResponse response) throws IOException;
|
void downloadSamples(String ids, HttpServletResponse response) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 样本关联模型(覆写逻辑)
|
||||||
|
*
|
||||||
|
* @param sampleIds 样本ID列表
|
||||||
|
* @param modelIds 模型ID列表
|
||||||
|
*/
|
||||||
|
void relateSamples(List<Long> sampleIds, List<Long> modelIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建样本响应VO(包含枚举标签、个性标签、关联模型)
|
||||||
|
*
|
||||||
|
* @param sample 样本DO
|
||||||
|
* @return 样本响应VO
|
||||||
|
*/
|
||||||
|
AiSampleRespVO buildSampleRespVO(AiSampleDO sample);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,27 @@
|
|||||||
package com.tashow.cloud.ai.service.aisample;
|
package com.tashow.cloud.ai.service.aisample;
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.tashow.cloud.ai.controller.admin.aisample.vo.*;
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleFileRespVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSamplePageReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRelateTagVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleRespVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleSaveReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.FileUploadReqVO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagRelateDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagRelateDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelSampleRelateDO;
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleMapper;
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupMapper;
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagRelateMapper;
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagRelateMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.model.AiModelMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.model.AiModelSampleRelateMapper;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
import com.tashow.cloud.common.util.object.BeanUtils;
|
import com.tashow.cloud.common.util.object.BeanUtils;
|
||||||
import com.tashow.cloud.fileapi.api.file.FileApi;
|
import com.tashow.cloud.fileapi.api.file.FileApi;
|
||||||
@@ -22,6 +31,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@@ -29,15 +39,14 @@ import java.io.IOException;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
/**
|
|
||||||
* 样本库 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
public class AiSampleServiceImpl implements AiSampleService {
|
public class AiSampleServiceImpl implements AiSampleService {
|
||||||
@@ -49,42 +58,41 @@ public class AiSampleServiceImpl implements AiSampleService {
|
|||||||
@Resource
|
@Resource
|
||||||
private AiSampleTagRelateMapper aiSampleTagRelateMapper;
|
private AiSampleTagRelateMapper aiSampleTagRelateMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private AiSampleTagGroupMapper aiSampleTagGroupMapper;
|
||||||
|
@Resource
|
||||||
|
private AiModelSampleRelateMapper modelSampleRelateMapper;
|
||||||
|
@Resource
|
||||||
|
private AiModelMapper modelMapper;
|
||||||
|
@Resource
|
||||||
private FileApi fileApi;
|
private FileApi fileApi;
|
||||||
|
|
||||||
@Value("${file-server}")
|
@Value("${file-server}")
|
||||||
private String fileServer;
|
private String fileServer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public List<AiSampleFileRespVO> createAiSample(FileUploadReqVO uploadReqVO) {
|
public List<AiSampleFileRespVO> createAiSample(FileUploadReqVO uploadReqVO) {
|
||||||
//返回图片路径
|
List<AiSampleFileRespVO> result = new ArrayList<>();
|
||||||
List<AiSampleFileRespVO> urls = new ArrayList<>();
|
|
||||||
/* 调用文件上传服务*/
|
|
||||||
for (MultipartFile file : uploadReqVO.getFiles()) {
|
for (MultipartFile file : uploadReqVO.getFiles()) {
|
||||||
//返回上传结果
|
|
||||||
String filePath=fileApi.createFile(file.getOriginalFilename(), "", file.getBytes());
|
|
||||||
//保存样本信息
|
|
||||||
AiSampleDO aiSampleDO = new AiSampleDO();
|
|
||||||
aiSampleDO.setSampleFilePath(filePath);
|
|
||||||
String filename = file.getOriginalFilename();
|
String filename = file.getOriginalFilename();
|
||||||
String displayName = filename.substring(0, filename.lastIndexOf('.'));
|
String filePath = fileApi.createFile(filename, "", file.getBytes());
|
||||||
aiSampleDO.setSampleName(displayName);
|
|
||||||
aiSampleDO.setSuffix(filename.substring(filename.lastIndexOf('.') + 1));
|
AiSampleDO sample = new AiSampleDO();
|
||||||
aiSampleDO.setSampleMineType(file.getContentType());
|
sample.setSampleFilePath(filePath);
|
||||||
aiSampleDO.setSampleSize(file.getSize());
|
sample.setSampleName(filename.substring(0, filename.lastIndexOf('.')));
|
||||||
aiSampleMapper.insert(aiSampleDO);
|
sample.setSuffix(filename.substring(filename.lastIndexOf('.') + 1));
|
||||||
urls.add(new AiSampleFileRespVO().setFileUrl(filePath).setFileName(filename).setDisplayName(displayName));
|
sample.setSampleMineType(file.getContentType());
|
||||||
|
sample.setSampleSize(file.getSize());
|
||||||
|
aiSampleMapper.insert(sample);
|
||||||
|
|
||||||
|
result.add(new AiSampleFileRespVO().setFileUrl(filePath).setFileName(filename));
|
||||||
}
|
}
|
||||||
// 返回
|
return result;
|
||||||
return urls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAiSample(AiSampleSaveReqVO updateReqVO) {
|
public void updateAiSample(AiSampleSaveReqVO updateReqVO) {
|
||||||
// 校验存在
|
aiSampleMapper.updateById(BeanUtils.toBean(updateReqVO, AiSampleDO.class));
|
||||||
validateAiSampleExists(updateReqVO.getId());
|
|
||||||
// 更新
|
|
||||||
AiSampleDO updateObj = BeanUtils.toBean(updateReqVO, AiSampleDO.class);
|
|
||||||
aiSampleMapper.updateById(updateObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,110 +102,107 @@ public class AiSampleServiceImpl implements AiSampleService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void relate(AiSampleRelateTagVO relateTagVO) {
|
public void relate(AiSampleRelateTagVO relateTagVO) {
|
||||||
List<AiSampleTagRelateDO> tagRelateDOS = new ArrayList<>();
|
List<AiSampleTagRelateDO> relates = new ArrayList<>();
|
||||||
for (Long sampleId : relateTagVO.getSampleIds()) {
|
for (Long sampleId : relateTagVO.getSampleIds()) {
|
||||||
for (Long tagId : relateTagVO.getTagId()) {
|
for (Long tagId : relateTagVO.getTagId()) {
|
||||||
AiSampleTagRelateDO relateDO = aiSampleTagRelateMapper.selectOne(
|
validateTagGroupRule(sampleId, tagId);
|
||||||
new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
AiSampleTagRelateDO exist = aiSampleTagRelateMapper.selectOne(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
.eq(AiSampleTagRelateDO::getSampleId, sampleId)
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId)
|
||||||
.eq(AiSampleTagRelateDO::getSampleTagId, tagId) );
|
.eq(AiSampleTagRelateDO::getSampleTagId, tagId));
|
||||||
if (relateDO== null){
|
if (exist == null) {
|
||||||
relateDO = new AiSampleTagRelateDO();
|
relates.add(new AiSampleTagRelateDO().setSampleId(sampleId).setSampleTagId(tagId));
|
||||||
relateDO.setSampleId(sampleId);
|
|
||||||
relateDO.setSampleTagId(tagId);
|
|
||||||
tagRelateDOS.add(relateDO);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!tagRelateDOS.isEmpty()){
|
if (CollUtil.isNotEmpty(relates)) {
|
||||||
aiSampleTagRelateMapper.insertBatch(tagRelateDOS);
|
aiSampleTagRelateMapper.insertBatch(relates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteRelate(AiSampleRelateTagVO relateTagVO) {
|
public void deleteRelate(AiSampleRelateTagVO relateTagVO) {
|
||||||
List<Long> tagRelateIds = new ArrayList<>();
|
List<Long> ids = new ArrayList<>();
|
||||||
for (Long sampleId : relateTagVO.getSampleIds()) {
|
for (Long sampleId : relateTagVO.getSampleIds()) {
|
||||||
for (Long tagId : relateTagVO.getTagId()) {
|
for (Long tagId : relateTagVO.getTagId()) {
|
||||||
AiSampleTagRelateDO relateDO = aiSampleTagRelateMapper.selectOne(
|
AiSampleTagRelateDO exist = aiSampleTagRelateMapper.selectOne(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
|
||||||
.eq(AiSampleTagRelateDO::getSampleId, sampleId)
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId)
|
||||||
.eq(AiSampleTagRelateDO::getSampleTagId, tagId)
|
.eq(AiSampleTagRelateDO::getSampleTagId, tagId));
|
||||||
);
|
if (exist != null) {
|
||||||
if (relateDO != null) {
|
ids.add(exist.getId());
|
||||||
tagRelateIds.add(relateDO.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!tagRelateIds.isEmpty()) {
|
if (CollUtil.isNotEmpty(ids)) {
|
||||||
aiSampleTagRelateMapper.deleteBatchIds(tagRelateIds);
|
aiSampleTagRelateMapper.deleteBatchIds(ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAiSample(String ids) {
|
public void deleteAiSample(String ids) {
|
||||||
// 删除
|
|
||||||
aiSampleMapper.deleteByIds(Arrays.asList(ids.split(StrUtil.COMMA)));
|
aiSampleMapper.deleteByIds(Arrays.asList(ids.split(StrUtil.COMMA)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAiSampleExists(Long id) {
|
|
||||||
if (aiSampleMapper.selectById(id) == null) {
|
|
||||||
// throw exception(AI_SAMPLE_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiSampleDO getAiSample(Long id) {
|
public AiSampleDO getAiSample(Long id) {
|
||||||
AiSampleDO aiSampleDO = aiSampleMapper.selectById(id);
|
AiSampleDO sample = aiSampleMapper.selectById(id);
|
||||||
aiSampleDO.setSampleFilePath(aiSampleDO.getSampleFilePath());
|
if (sample == null) {
|
||||||
//先获取关联的标签id
|
return null;
|
||||||
List<AiSampleTagRelateDO> tagRelateDOS = aiSampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>().eq(AiSampleTagRelateDO::getSampleId, id));
|
}
|
||||||
List<Long> tagIds = tagRelateDOS.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
|
||||||
aiSampleDO.setTags(aiSampleTagMapper.selectList(new LambdaQueryWrapper<AiSampleTagDO>().in(AiSampleTagDO::getId, tagIds)));
|
List<Long> tagIds = aiSampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
return aiSampleDO;
|
.eq(AiSampleTagRelateDO::getSampleId, id))
|
||||||
|
.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
||||||
|
sample.setTags(CollUtil.isEmpty(tagIds)
|
||||||
|
? List.of()
|
||||||
|
: aiSampleTagMapper.selectList(new LambdaQueryWrapper<AiSampleTagDO>().in(AiSampleTagDO::getId, tagIds)));
|
||||||
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<AiSampleDO> getAiSamplePage(AiSamplePageReqVO pageReqVO) {
|
public PageResult<AiSampleDO> getAiSamplePage(AiSamplePageReqVO pageReqVO) {
|
||||||
// PageResult<AiSampleDO> aiSampleDOPageResult = aiSampleMapper.selectPage(pageReqVO);
|
IPage<AiSampleDO> page = aiSampleMapper.getAiSamplePage(MyBatisUtils.buildPage(pageReqVO), pageReqVO);
|
||||||
IPage<AiSampleDO> aiSampleDOPageResult = aiSampleMapper.getAiSamplePage(MyBatisUtils.buildPage(pageReqVO),pageReqVO);
|
List<AiSampleDO> samples = page.getRecords();
|
||||||
//根据样本id获取关联的标签id
|
List<Long> sampleIds = samples.stream().map(AiSampleDO::getId).toList();
|
||||||
List<Long> sampleIds = aiSampleDOPageResult.getRecords().stream().map(AiSampleDO::getId).toList();
|
if (CollUtil.isEmpty(sampleIds)) {
|
||||||
List<AiSampleTagRelateDO> tagRelateDOS = aiSampleTagRelateMapper.selectList(
|
return new PageResult<>(samples, page.getTotal());
|
||||||
new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
|
||||||
.in(!sampleIds.isEmpty(), AiSampleTagRelateDO::getSampleId, sampleIds));
|
|
||||||
List<Long> tagIds = tagRelateDOS.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
|
||||||
//获取标签信息
|
|
||||||
List<AiSampleTagDO> aiSampleTagDOS = aiSampleTagMapper.selectList(
|
|
||||||
new LambdaQueryWrapper<AiSampleTagDO>()
|
|
||||||
.in(!tagIds.isEmpty(), AiSampleTagDO::getId, tagIds));
|
|
||||||
|
|
||||||
//封装标签信息
|
|
||||||
for (AiSampleDO aiSampleDO : aiSampleDOPageResult.getRecords()) {
|
|
||||||
List<AiSampleTagRelateDO> list = tagRelateDOS.stream()
|
|
||||||
.filter(a -> ObjectUtil.equals(aiSampleDO.getId(), a.getSampleId()))
|
|
||||||
.toList();
|
|
||||||
Object[] tagsId = list.stream().map(AiSampleTagRelateDO::getSampleTagId).toArray();
|
|
||||||
List<AiSampleTagDO> list1 = aiSampleTagDOS.stream().filter(a -> ArrayUtil.containsAny(tagsId, a.getId())).toList();
|
|
||||||
aiSampleDO.setTags(list1);
|
|
||||||
}
|
}
|
||||||
return new PageResult<>(aiSampleDOPageResult.getRecords(), aiSampleDOPageResult.getTotal());
|
|
||||||
|
List<AiSampleTagRelateDO> relates = aiSampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
|
.in(AiSampleTagRelateDO::getSampleId, sampleIds));
|
||||||
|
List<Long> tagIds = relates.stream().map(AiSampleTagRelateDO::getSampleTagId).distinct().toList();
|
||||||
|
List<AiSampleTagDO> tags = CollUtil.isEmpty(tagIds)
|
||||||
|
? List.of()
|
||||||
|
: aiSampleTagMapper.selectList(new LambdaQueryWrapper<AiSampleTagDO>().in(AiSampleTagDO::getId, tagIds));
|
||||||
|
|
||||||
|
Map<Long, AiSampleTagDO> tagMap = new HashMap<>();
|
||||||
|
for (AiSampleTagDO tag : tags) {
|
||||||
|
tagMap.put(tag.getId(), tag);
|
||||||
|
}
|
||||||
|
Map<Long, List<AiSampleTagDO>> sampleTagMap = new HashMap<>();
|
||||||
|
for (AiSampleTagRelateDO relate : relates) {
|
||||||
|
AiSampleTagDO tag = tagMap.get(relate.getSampleTagId());
|
||||||
|
if (tag != null) {
|
||||||
|
sampleTagMap.computeIfAbsent(relate.getSampleId(), k -> new ArrayList<>()).add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (AiSampleDO sample : samples) {
|
||||||
|
sample.setTags(sampleTagMap.getOrDefault(sample.getId(), List.of()));
|
||||||
|
}
|
||||||
|
return new PageResult<>(samples, page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void downloadSamples(String ids, HttpServletResponse response) throws IOException {
|
public void downloadSamples(String ids, HttpServletResponse response) throws IOException {
|
||||||
List<AiSampleDO> samples = aiSampleMapper.selectBatchIds(Arrays.asList(ids.split(StrUtil.COMMA)));
|
List<AiSampleDO> samples = aiSampleMapper.selectBatchIds(Arrays.asList(ids.split(StrUtil.COMMA)));
|
||||||
|
|
||||||
if (samples.size() == 1) {
|
if (samples.size() == 1) {
|
||||||
// 单个文件直接下载
|
|
||||||
AiSampleDO sample = samples.get(0);
|
AiSampleDO sample = samples.get(0);
|
||||||
byte[] bytes = HttpUtil.downloadBytes(fileServer + sample.getSampleFilePath());
|
byte[] bytes = HttpUtil.downloadBytes(fileServer + sample.getSampleFilePath());
|
||||||
response.setContentType(sample.getSampleMineType());
|
response.setContentType(sample.getSampleMineType());
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(sample.getSampleName(), "UTF-8"));
|
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(sample.getSampleName(), "UTF-8"));
|
||||||
response.getOutputStream().write(bytes);
|
response.getOutputStream().write(bytes);
|
||||||
} else {
|
return;
|
||||||
// 多个文件打包成ZIP
|
}
|
||||||
|
|
||||||
response.setContentType("application/zip");
|
response.setContentType("application/zip");
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=samples.zip");
|
response.setHeader("Content-Disposition", "attachment; filename=samples.zip");
|
||||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
||||||
@@ -209,6 +214,120 @@ public class AiSampleServiceImpl implements AiSampleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void relateSamples(List<Long> sampleIds, List<Long> modelIds) {
|
||||||
|
if (CollUtil.isEmpty(sampleIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean noModels = CollUtil.isEmpty(modelIds);
|
||||||
|
for (Long sampleId : sampleIds) {
|
||||||
|
modelSampleRelateMapper.delete(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getSampleId, sampleId));
|
||||||
|
if (noModels) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Long modelId : modelIds) {
|
||||||
|
modelSampleRelateMapper.insert(new AiModelSampleRelateDO().setSampleId(sampleId).setModelId(modelId));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateTagGroupRule(Long sampleId, Long tagId) {
|
||||||
|
AiSampleTagDO currentTag = aiSampleTagMapper.selectById(tagId);
|
||||||
|
if (currentTag == null || !Integer.valueOf(1).equals(currentTag.getTagType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long groupId = getFirstGroupId(currentTag.getGroupId());
|
||||||
|
if (groupId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AiSampleTagGroupDO group = aiSampleTagGroupMapper.selectById(groupId);
|
||||||
|
if (group != null && Integer.valueOf(2).equals(group.getGroupType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiSampleTagRelateDO> existingRelates = aiSampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId));
|
||||||
|
for (AiSampleTagRelateDO relate : existingRelates) {
|
||||||
|
if (tagId.equals(relate.getSampleTagId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AiSampleTagDO existingTag = aiSampleTagMapper.selectById(relate.getSampleTagId());
|
||||||
|
if (existingTag != null && parseGroupIds(existingTag.getGroupId()).contains(groupId)) {
|
||||||
|
aiSampleTagRelateMapper.deleteById(relate.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AiSampleRespVO buildSampleRespVO(AiSampleDO sample) {
|
||||||
|
AiSampleRespVO respVO = BeanUtils.toBean(sample, AiSampleRespVO.class);
|
||||||
|
respVO.setEnumTags(buildEnumTags(sample.getId()));
|
||||||
|
respVO.setRelatedModels(buildRelatedModels(sample.getId()));
|
||||||
|
return respVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AiSampleRespVO.TagInfo> buildEnumTags(Long sampleId) {
|
||||||
|
List<Long> tagIds = aiSampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId))
|
||||||
|
.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
||||||
|
if (CollUtil.isEmpty(tagIds)) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiSampleTagDO> tags = aiSampleTagMapper.selectBatchIds(tagIds).stream()
|
||||||
|
.filter(tag -> Integer.valueOf(1).equals(tag.getTagType())).toList();
|
||||||
|
Map<Long, String> groupNames = new HashMap<>();
|
||||||
|
Set<Long> groupIds = new HashSet<>();
|
||||||
|
for (AiSampleTagDO tag : tags) {
|
||||||
|
Long groupId = getFirstGroupId(tag.getGroupId());
|
||||||
|
if (groupId != null) {
|
||||||
|
groupIds.add(groupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (AiSampleTagGroupDO group : aiSampleTagGroupMapper.selectBatchIds(groupIds)) {
|
||||||
|
groupNames.put(group.getId(), group.getGroupName());
|
||||||
|
}
|
||||||
|
return tags.stream().map(tag -> {
|
||||||
|
Long groupId = getFirstGroupId(tag.getGroupId());
|
||||||
|
return AiSampleRespVO.TagInfo.builder()
|
||||||
|
.id(tag.getId())
|
||||||
|
.tagName(tag.getTagName())
|
||||||
|
.enumValue(tag.getEnumValue())
|
||||||
|
.groupId(groupId)
|
||||||
|
.groupName(groupId == null ? null : groupNames.get(groupId))
|
||||||
|
.build();
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AiSampleRespVO.ModelInfo> buildRelatedModels(Long sampleId) {
|
||||||
|
List<Long> modelIds = modelSampleRelateMapper.selectList(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getSampleId, sampleId))
|
||||||
|
.stream().map(AiModelSampleRelateDO::getModelId).toList();
|
||||||
|
if (CollUtil.isEmpty(modelIds)) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
return modelMapper.selectBatchIds(modelIds).stream()
|
||||||
|
.map(model -> AiSampleRespVO.ModelInfo.builder()
|
||||||
|
.id(model.getId())
|
||||||
|
.modelName(model.getModelName())
|
||||||
|
.version(model.getVersion())
|
||||||
|
.build())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getFirstGroupId(String groupIds) {
|
||||||
|
return Long.parseLong(groupIds.split(StrUtil.COMMA)[0].trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> parseGroupIds(String groupIds) {
|
||||||
|
return Arrays.stream(groupIds.split(StrUtil.COMMA))
|
||||||
|
.map(String::trim)
|
||||||
|
.map(Long::parseLong)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,50 +13,42 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* 样本标签分组库 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
public class AiSampleTagGroupServiceImpl implements AiSampleTagGroupService {
|
public class AiSampleTagGroupServiceImpl implements AiSampleTagGroupService {
|
||||||
|
|
||||||
|
private static final Integer ENUM_TYPE = 1;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AiSampleTagGroupMapper aiSampleTagGroupMapper;
|
private AiSampleTagGroupMapper aiSampleTagGroupMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createAiSampleTagGroup(AiSampleTagGroupSaveReqVO createReqVO) {
|
public Long createAiSampleTagGroup(AiSampleTagGroupSaveReqVO createReqVO) {
|
||||||
// 插入
|
AiSampleTagGroupDO group = BeanUtils.toBean(createReqVO, AiSampleTagGroupDO.class);
|
||||||
AiSampleTagGroupDO aiSampleTagGroup = BeanUtils.toBean(createReqVO, AiSampleTagGroupDO.class);
|
aiSampleTagGroupMapper.insert(group);
|
||||||
aiSampleTagGroupMapper.insert(aiSampleTagGroup);
|
return group.getId();
|
||||||
// 返回
|
|
||||||
return aiSampleTagGroup.getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAiSampleTagGroup(AiSampleTagGroupSaveReqVO updateReqVO) {
|
public void updateAiSampleTagGroup(AiSampleTagGroupSaveReqVO updateReqVO) {
|
||||||
// 校验存在
|
AiSampleTagGroupDO existingGroup = aiSampleTagGroupMapper.selectById(updateReqVO.getId());
|
||||||
validateAiSampleTagGroupExists(updateReqVO.getId());
|
if (isEnumType(existingGroup.getGroupType())
|
||||||
// 更新
|
&& !existingGroup.getGroupType().equals(updateReqVO.getGroupType())) {
|
||||||
AiSampleTagGroupDO updateObj = BeanUtils.toBean(updateReqVO, AiSampleTagGroupDO.class);
|
throw new IllegalArgumentException("Enum group type cannot be changed");
|
||||||
aiSampleTagGroupMapper.updateById(updateObj);
|
}
|
||||||
|
AiSampleTagGroupDO group = BeanUtils.toBean(updateReqVO, AiSampleTagGroupDO.class);
|
||||||
|
aiSampleTagGroupMapper.updateById(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAiSampleTagGroup(Long id) {
|
public void deleteAiSampleTagGroup(Long id) {
|
||||||
// 校验存在
|
AiSampleTagGroupDO group = aiSampleTagGroupMapper.selectById(id);
|
||||||
validateAiSampleTagGroupExists(id);
|
if (isEnumType(group.getGroupType())) {
|
||||||
// 删除
|
throw new IllegalArgumentException("Enum group cannot be deleted");
|
||||||
|
}
|
||||||
aiSampleTagGroupMapper.deleteById(id);
|
aiSampleTagGroupMapper.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAiSampleTagGroupExists(Long id) {
|
|
||||||
if (aiSampleTagGroupMapper.selectById(id) == null) {
|
|
||||||
// throw exception(AI_SAMPLE_TAG_GROUP_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiSampleTagGroupDO getAiSampleTagGroup(Long id) {
|
public AiSampleTagGroupDO getAiSampleTagGroup(Long id) {
|
||||||
return aiSampleTagGroupMapper.selectById(id);
|
return aiSampleTagGroupMapper.selectById(id);
|
||||||
@@ -69,6 +61,11 @@ public class AiSampleTagGroupServiceImpl implements AiSampleTagGroupService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AiSampleTagGroupDO> getAiSampleTagGroupList() {
|
public List<AiSampleTagGroupDO> getAiSampleTagGroupList() {
|
||||||
return aiSampleTagGroupMapper.selectList(new LambdaQueryWrapper<AiSampleTagGroupDO>().orderByDesc(AiSampleTagGroupDO::getId));
|
return aiSampleTagGroupMapper.selectList(new LambdaQueryWrapper<AiSampleTagGroupDO>()
|
||||||
|
.orderByDesc(AiSampleTagGroupDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEnumType(Integer type) {
|
||||||
|
return ENUM_TYPE.equals(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.tashow.cloud.ai.service.aisample;
|
package com.tashow.cloud.ai.service.aisample;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagPageReqVO;
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagPageReqVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagSaveReqVO;
|
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagSaveReqVO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupDO;
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupRelateDO;
|
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupMapper;
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupMapper;
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupRelateMapper;
|
|
||||||
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
import com.tashow.cloud.common.util.object.BeanUtils;
|
import com.tashow.cloud.common.util.object.BeanUtils;
|
||||||
@@ -17,80 +16,58 @@ import jakarta.annotation.Resource;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 样本标签库 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
public class AiSampleTagServiceImpl implements AiSampleTagService {
|
public class AiSampleTagServiceImpl implements AiSampleTagService {
|
||||||
|
|
||||||
|
private static final Integer ENUM_TYPE = 1;
|
||||||
|
private static final Integer DEFAULT_TAG_TYPE = 2;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AiSampleTagMapper aiSampleTagMapper;
|
private AiSampleTagMapper aiSampleTagMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private AiSampleTagGroupMapper aiSampleTagGroupMapper;
|
private AiSampleTagGroupMapper aiSampleTagGroupMapper;
|
||||||
@Resource
|
|
||||||
private AiSampleTagGroupRelateMapper tagGroupRelateMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createAiSampleTag(AiSampleTagSaveReqVO createReqVO) {
|
public Long createAiSampleTag(AiSampleTagSaveReqVO createReqVO) {
|
||||||
// 插入
|
Integer tagType = createReqVO.getTagType() == null ? DEFAULT_TAG_TYPE : createReqVO.getTagType();
|
||||||
AiSampleTagDO aiSampleTag = BeanUtils.toBean(createReqVO, AiSampleTagDO.class);
|
createReqVO.setTagType(tagType);
|
||||||
aiSampleTagMapper.insert(aiSampleTag);
|
if (isEnumType(tagType)) {
|
||||||
//插入关联
|
validateEnumTagGroup(createReqVO.getGroupId());
|
||||||
List<AiSampleTagGroupRelateDO> tagGroupRelateDOS = new ArrayList<>();
|
|
||||||
for (Long groupId : createReqVO.getGroupIds()) {
|
|
||||||
AiSampleTagGroupRelateDO tagGroupRelateDO = new AiSampleTagGroupRelateDO();
|
|
||||||
tagGroupRelateDO.setSampleTagGroupId(groupId);
|
|
||||||
tagGroupRelateDO.setSampleTagId(aiSampleTag.getId());
|
|
||||||
tagGroupRelateDOS.add(tagGroupRelateDO);
|
|
||||||
}
|
}
|
||||||
tagGroupRelateMapper.insertBatch(tagGroupRelateDOS);
|
|
||||||
// 返回
|
AiSampleTagDO tag = BeanUtils.toBean(createReqVO, AiSampleTagDO.class);
|
||||||
return aiSampleTag.getId();
|
aiSampleTagMapper.insert(tag);
|
||||||
|
return tag.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAiSampleTag(AiSampleTagSaveReqVO updateReqVO) {
|
public void updateAiSampleTag(AiSampleTagSaveReqVO updateReqVO) {
|
||||||
// 校验存在
|
AiSampleTagDO existingTag = aiSampleTagMapper.selectById(updateReqVO.getId());
|
||||||
validateAiSampleTagExists(updateReqVO.getId());
|
if (isEnumType(existingTag.getTagType())) {
|
||||||
// 更新
|
if (!existingTag.getTagType().equals(updateReqVO.getTagType())) {
|
||||||
AiSampleTagDO updateObj = BeanUtils.toBean(updateReqVO, AiSampleTagDO.class);
|
throw new IllegalArgumentException("Enum tag type cannot be changed");
|
||||||
aiSampleTagMapper.updateById(updateObj);
|
|
||||||
List<Long> groupIds = updateReqVO.getGroupIds();
|
|
||||||
// 删除该标签的所有旧关联
|
|
||||||
tagGroupRelateMapper.delete(new LambdaQueryWrapper<AiSampleTagGroupRelateDO>()
|
|
||||||
.eq(AiSampleTagGroupRelateDO::getSampleTagId, updateReqVO.getId()));
|
|
||||||
//插入关联
|
|
||||||
List<AiSampleTagGroupRelateDO> tagGroupRelateDOS = new ArrayList<>();
|
|
||||||
for (Long groupId : groupIds) {
|
|
||||||
AiSampleTagGroupRelateDO tagGroupRelateDO = new AiSampleTagGroupRelateDO();
|
|
||||||
tagGroupRelateDO.setSampleTagId(updateReqVO.getId());
|
|
||||||
tagGroupRelateDO.setSampleTagGroupId(groupId);
|
|
||||||
tagGroupRelateDOS.add(tagGroupRelateDO);
|
|
||||||
}
|
}
|
||||||
tagGroupRelateMapper.insertBatch(tagGroupRelateDOS);
|
if (!existingTag.getGroupId().equals(updateReqVO.getGroupId())) {
|
||||||
|
throw new IllegalArgumentException("Enum tag group cannot be changed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AiSampleTagDO tag = BeanUtils.toBean(updateReqVO, AiSampleTagDO.class);
|
||||||
|
aiSampleTagMapper.updateById(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAiSampleTag(Long id) {
|
public void deleteAiSampleTag(Long id) {
|
||||||
// 校验存在
|
AiSampleTagDO tag = aiSampleTagMapper.selectById(id);
|
||||||
validateAiSampleTagExists(id);
|
if (isEnumType(tag.getTagType())) {
|
||||||
// 删除
|
throw new IllegalArgumentException("Enum tag cannot be deleted");
|
||||||
|
}
|
||||||
aiSampleTagMapper.deleteById(id);
|
aiSampleTagMapper.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAiSampleTagExists(Long id) {
|
|
||||||
if (aiSampleTagMapper.selectById(id) == null) {
|
|
||||||
// throw exception(AI_SAMPLE_TAG_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AiSampleTagDO getAiSampleTag(Long id) {
|
public AiSampleTagDO getAiSampleTag(Long id) {
|
||||||
return aiSampleTagMapper.selectById(id);
|
return aiSampleTagMapper.selectById(id);
|
||||||
@@ -98,8 +75,8 @@ public class AiSampleTagServiceImpl implements AiSampleTagService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<AiSampleTagDO> getAiSampleTagPage(AiSampleTagPageReqVO pageReqVO) {
|
public PageResult<AiSampleTagDO> getAiSampleTagPage(AiSampleTagPageReqVO pageReqVO) {
|
||||||
IPage<AiSampleTagDO> prodPageList = aiSampleTagMapper.getAiSampleTagPage(MyBatisUtils.buildPage(pageReqVO),pageReqVO);
|
IPage<AiSampleTagDO> page = aiSampleTagMapper.getAiSampleTagPage(MyBatisUtils.buildPage(pageReqVO), pageReqVO);
|
||||||
return new PageResult<>(prodPageList.getRecords(), prodPageList.getTotal());
|
return new PageResult<>(page.getRecords(), page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -109,14 +86,30 @@ public class AiSampleTagServiceImpl implements AiSampleTagService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AiSampleTagGroupDO> getGroupListByTagId(Long tagId) {
|
public List<AiSampleTagGroupDO> getGroupListByTagId(Long tagId) {
|
||||||
List<AiSampleTagGroupRelateDO> relateList = tagGroupRelateMapper.selectList(
|
AiSampleTagDO tag = aiSampleTagMapper.selectById(tagId);
|
||||||
new LambdaQueryWrapper<AiSampleTagGroupRelateDO>()
|
return aiSampleTagGroupMapper.selectBatchIds(parseGroupIds(tag.getGroupId()));
|
||||||
.eq(AiSampleTagGroupRelateDO::getSampleTagId, tagId));
|
}
|
||||||
List<Long> groupIds = relateList.stream()
|
|
||||||
.map(AiSampleTagGroupRelateDO::getSampleTagGroupId)
|
private void validateEnumTagGroup(String groupIdStr) {
|
||||||
.distinct()
|
Long groupId = getFirstGroupId(groupIdStr);
|
||||||
.collect(Collectors.toList());
|
AiSampleTagGroupDO group = aiSampleTagGroupMapper.selectById(groupId);
|
||||||
return aiSampleTagGroupMapper.selectList(
|
if (group == null || !isEnumType(group.getGroupType())) {
|
||||||
new LambdaQueryWrapper<AiSampleTagGroupDO>().in(AiSampleTagGroupDO::getId, groupIds));
|
throw new IllegalArgumentException("Enum tag can only bind enum group");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEnumType(Integer type) {
|
||||||
|
return ENUM_TYPE.equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getFirstGroupId(String groupIds) {
|
||||||
|
return parseGroupIds(groupIds).get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> parseGroupIds(String groupIds) {
|
||||||
|
return Arrays.stream(groupIds.split(StrUtil.COMMA))
|
||||||
|
.map(String::trim)
|
||||||
|
.map(Long::parseLong)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.tashow.cloud.ai.service.model;
|
package com.tashow.cloud.ai.service.model;
|
||||||
|
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelAnalysisResultVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelDifferenceVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -52,4 +55,46 @@ public interface AiModelService {
|
|||||||
*/
|
*/
|
||||||
PageResult<AiModelDO> getModelPage(AiModelPageReqVO pageReqVO);
|
PageResult<AiModelDO> getModelPage(AiModelPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型引用样本(覆写式)
|
||||||
|
*
|
||||||
|
* @param modelId 模型ID
|
||||||
|
* @param sampleIds 样本ID列表
|
||||||
|
*/
|
||||||
|
void referenceSamples(Long modelId, List<Long> sampleIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模型关联的样本
|
||||||
|
*
|
||||||
|
* @param modelId 模型ID
|
||||||
|
* @return 样本列表
|
||||||
|
*/
|
||||||
|
List<AiSampleDO> getModelSamples(Long modelId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型准确度分析(通过翻译接口分析样本匹配度)
|
||||||
|
*
|
||||||
|
* @param modelId 模型ID
|
||||||
|
* @return 分析结果
|
||||||
|
*/
|
||||||
|
AiModelAnalysisResultVO analyzeModel(List<Long> sampleIds, List<Long> modelIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型样本差异筛查(支持多模型)
|
||||||
|
*
|
||||||
|
* @param modelIds 模型ID列表
|
||||||
|
* @return 差异结果(重复引用样本和未重复引用样本)
|
||||||
|
*/
|
||||||
|
AiModelDifferenceVO checkDifference(List<Long> modelIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模型迭代(复制模型和样本关联)
|
||||||
|
*
|
||||||
|
* @param modelId 原模型ID
|
||||||
|
* @param newVersion 新版本号
|
||||||
|
* @param description 版本描述
|
||||||
|
* @return 新模型ID
|
||||||
|
*/
|
||||||
|
Long iterateModel(Long modelId, String newVersion, String description);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,71 @@
|
|||||||
package com.tashow.cloud.ai.service.model;
|
package com.tashow.cloud.ai.service.model;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelAnalysisResultVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelDifferenceVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelPageReqVO;
|
||||||
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiModelSaveReqVO;
|
||||||
|
import com.tashow.cloud.ai.controller.admin.model.vo.AiSampleDetailVO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagRelateDO;
|
||||||
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelDO;
|
||||||
|
import com.tashow.cloud.ai.dal.dataobject.model.AiModelSampleRelateDO;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagRelateMapper;
|
||||||
import com.tashow.cloud.ai.dal.mysql.model.AiModelMapper;
|
import com.tashow.cloud.ai.dal.mysql.model.AiModelMapper;
|
||||||
|
import com.tashow.cloud.ai.dal.mysql.model.AiModelSampleRelateMapper;
|
||||||
import com.tashow.cloud.common.pojo.PageResult;
|
import com.tashow.cloud.common.pojo.PageResult;
|
||||||
import com.tashow.cloud.common.util.object.BeanUtils;
|
import com.tashow.cloud.common.util.object.BeanUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
|
||||||
* AI模型管理 Service 实现类
|
|
||||||
*
|
|
||||||
* @author tashow
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
|
@Slf4j
|
||||||
public class AiModelServiceImpl implements AiModelService {
|
public class AiModelServiceImpl implements AiModelService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AiModelMapper modelMapper;
|
private AiModelMapper modelMapper;
|
||||||
|
@Resource
|
||||||
|
private AiModelSampleRelateMapper modelSampleRelateMapper;
|
||||||
|
@Resource
|
||||||
|
private AiSampleMapper sampleMapper;
|
||||||
|
@Resource
|
||||||
|
private AiSampleTagRelateMapper sampleTagRelateMapper;
|
||||||
|
@Resource
|
||||||
|
private AiSampleTagMapper sampleTagMapper;
|
||||||
|
@Resource
|
||||||
|
private AiSampleTagGroupMapper sampleTagGroupMapper;
|
||||||
|
|
||||||
|
@Value("${translate-server}")
|
||||||
|
private String translateServer;
|
||||||
|
@Value("${file-server}")
|
||||||
|
private String fileServer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createModel(AiModelSaveReqVO createReqVO) {
|
public Long createModel(AiModelSaveReqVO createReqVO) {
|
||||||
@@ -32,11 +74,9 @@ public class AiModelServiceImpl implements AiModelService {
|
|||||||
return model.getId();
|
return model.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateModel(AiModelSaveReqVO updateReqVO) {
|
public void updateModel(AiModelSaveReqVO updateReqVO) {
|
||||||
AiModelDO updateObj = BeanUtils.toBean(updateReqVO, AiModelDO.class);
|
modelMapper.updateById(BeanUtils.toBean(updateReqVO, AiModelDO.class));
|
||||||
modelMapper.updateById(updateObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -46,10 +86,7 @@ public class AiModelServiceImpl implements AiModelService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AiModelDO> getEnabledModels() {
|
public List<AiModelDO> getEnabledModels() {
|
||||||
return modelMapper.selectList(
|
return modelMapper.selectList(new LambdaQueryWrapper<AiModelDO>().eq(AiModelDO::getStatus, 1));
|
||||||
new LambdaQueryWrapper<AiModelDO>()
|
|
||||||
.eq(AiModelDO::getStatus, 1)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -57,4 +94,274 @@ public class AiModelServiceImpl implements AiModelService {
|
|||||||
return modelMapper.selectPage(pageReqVO);
|
return modelMapper.selectPage(pageReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void referenceSamples(Long modelId, List<Long> sampleIds) {
|
||||||
|
modelSampleRelateMapper.delete(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getModelId, modelId));
|
||||||
|
if (CollUtil.isEmpty(sampleIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<AiModelSampleRelateDO> relates = sampleIds.stream()
|
||||||
|
.map(sampleId -> AiModelSampleRelateDO.builder().modelId(modelId).sampleId(sampleId).build())
|
||||||
|
.toList();
|
||||||
|
modelSampleRelateMapper.insertBatch(relates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AiSampleDO> getModelSamples(Long modelId) {
|
||||||
|
List<Long> sampleIds = modelSampleRelateMapper.selectList(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getModelId, modelId))
|
||||||
|
.stream().map(AiModelSampleRelateDO::getSampleId).toList();
|
||||||
|
return sampleMapper.selectBatchIds(sampleIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AiModelAnalysisResultVO analyzeModel(List<Long> sampleIds, List<Long> modelIds) {
|
||||||
|
if (CollUtil.isEmpty(sampleIds) || CollUtil.isEmpty(modelIds)) {
|
||||||
|
return AiModelAnalysisResultVO.builder().samples(List.of()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiModelAnalysisResultVO.SampleAnalysis> samples = new ArrayList<>();
|
||||||
|
for (Long sampleId : sampleIds) {
|
||||||
|
AiSampleDO sample = sampleMapper.selectById(sampleId);
|
||||||
|
if (sample == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AiSampleTagDO> enumTags = getEnumTagsForSample(sampleId);
|
||||||
|
String enumTagStr = enumTags.stream().map(AiSampleTagDO::getTagName).collect(Collectors.joining(","));
|
||||||
|
|
||||||
|
List<AiModelAnalysisResultVO.ModelAnalysisResult> modelResults = modelIds.stream()
|
||||||
|
.map(modelRefId -> buildModelAnalysis(sample, enumTags, modelRefId))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
samples.add(AiModelAnalysisResultVO.SampleAnalysis.builder()
|
||||||
|
.sampleId(sample.getId())
|
||||||
|
.sampleName(sample.getSampleName())
|
||||||
|
.enumTag(enumTagStr)
|
||||||
|
.modelResults(modelResults)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
return AiModelAnalysisResultVO.builder().samples(samples).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AiModelDifferenceVO checkDifference(List<Long> modelIds) {
|
||||||
|
Map<Long, Integer> sampleRefCount = new HashMap<>();
|
||||||
|
for (Long modelId : modelIds) {
|
||||||
|
for (Long sampleId : getModelSampleIds(modelId)) {
|
||||||
|
sampleRefCount.merge(sampleId, 1, Integer::sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> duplicatedIds = new ArrayList<>();
|
||||||
|
List<Long> uniqueIds = new ArrayList<>();
|
||||||
|
sampleRefCount.forEach((sampleId, count) -> {
|
||||||
|
if (count >= 2) {
|
||||||
|
duplicatedIds.add(sampleId);
|
||||||
|
} else {
|
||||||
|
uniqueIds.add(sampleId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return AiModelDifferenceVO.builder()
|
||||||
|
.duplicatedSamples(buildSampleDetailVOList(duplicatedIds))
|
||||||
|
.uniqueSamples(buildSampleDetailVOList(uniqueIds))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long iterateModel(Long modelId, String newVersion, String description) {
|
||||||
|
AiModelDO original = modelMapper.selectById(modelId);
|
||||||
|
AiModelDO newModel = BeanUtils.toBean(original, AiModelDO.class);
|
||||||
|
newModel.setId(null);
|
||||||
|
newModel.setVersion(newVersion);
|
||||||
|
newModel.setDescription(description);
|
||||||
|
newModel.setStatus(2);
|
||||||
|
modelMapper.insert(newModel);
|
||||||
|
|
||||||
|
List<AiModelSampleRelateDO> newRelates = modelSampleRelateMapper.selectList(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getModelId, modelId))
|
||||||
|
.stream()
|
||||||
|
.map(relate -> AiModelSampleRelateDO.builder()
|
||||||
|
.modelId(newModel.getId())
|
||||||
|
.sampleId(relate.getSampleId())
|
||||||
|
.build())
|
||||||
|
.toList();
|
||||||
|
if (CollUtil.isNotEmpty(newRelates)) {
|
||||||
|
modelSampleRelateMapper.insertBatch(newRelates);
|
||||||
|
}
|
||||||
|
return newModel.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AiModelAnalysisResultVO.ModelAnalysisResult buildModelAnalysis(AiSampleDO sample, List<AiSampleTagDO> enumTags,
|
||||||
|
Long modelId) {
|
||||||
|
AiModelDO model = modelMapper.selectById(modelId);
|
||||||
|
if (model == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String speciesResult = null;
|
||||||
|
BigDecimal speciesMatchRate = null;
|
||||||
|
String emotionResult = null;
|
||||||
|
BigDecimal emotionMatchRate = null;
|
||||||
|
|
||||||
|
JSONObject translateResult = requestTranslate(sample, model);
|
||||||
|
if (translateResult != null) {
|
||||||
|
speciesResult = translateResult.getString("species_labels");
|
||||||
|
AiSampleTagGroupDO speciesGroup = getGroupByName("物种识别");
|
||||||
|
if (speciesGroup != null) {
|
||||||
|
speciesMatchRate = calculateMatchRate(speciesResult, enumTags, speciesGroup.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject intentResult = translateResult.getJSONObject("intent_result");
|
||||||
|
JSONObject probabilities = intentResult == null ? null : intentResult.getJSONObject("probabilities");
|
||||||
|
if (probabilities != null && !probabilities.isEmpty()) {
|
||||||
|
String emotionKey = probabilities.entrySet().stream()
|
||||||
|
.max(Comparator.comparingDouble(entry -> ((Number) entry.getValue()).doubleValue()))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.orElse(null);
|
||||||
|
if (StrUtil.isNotBlank(emotionKey) && emotionKey.contains("_")) {
|
||||||
|
emotionResult = emotionKey.split("_")[1];
|
||||||
|
AiSampleTagGroupDO emotionGroup = getGroupByName("情绪识别");
|
||||||
|
if (emotionGroup != null) {
|
||||||
|
emotionMatchRate = calculateMatchRate(emotionResult, enumTags, emotionGroup.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AiModelAnalysisResultVO.ModelAnalysisResult.builder()
|
||||||
|
.modelId(model.getId())
|
||||||
|
.modelName(model.getModelName())
|
||||||
|
.modelVersion(model.getVersion())
|
||||||
|
.speciesResult(speciesResult)
|
||||||
|
.speciesMatchRate(speciesMatchRate)
|
||||||
|
.emotionResult(emotionResult)
|
||||||
|
.emotionMatchRate(emotionMatchRate)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject requestTranslate(AiSampleDO sample, AiModelDO model) {
|
||||||
|
try {
|
||||||
|
String fileUrl = fileServer + sample.getSampleFilePath();
|
||||||
|
String response = HttpRequest.post(translateServer)
|
||||||
|
.form("audio_data", HttpUtil.downloadBytes(fileUrl), sample.getSampleName())
|
||||||
|
.form("model_name", model.getModelName())
|
||||||
|
.form("model_version", model.getVersion())
|
||||||
|
.timeout(20000)
|
||||||
|
.execute().body();
|
||||||
|
JSONObject result = JSON.parseObject(response);
|
||||||
|
if (result == null || result.isEmpty() || !result.containsKey("intent_result")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!Boolean.TRUE.equals(result.getBoolean("is_species_sound")) || result.getDoubleValue("confidence") < 0.7) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject intent = result.getJSONObject("intent_result");
|
||||||
|
return intent != null && intent.getDoubleValue("confidence") >= 0.7 ? result : null;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("调用翻译API失败,样本ID: {}", sample.getId(), ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> getSampleModelIds(Long sampleId) {
|
||||||
|
return modelSampleRelateMapper.selectList(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getSampleId, sampleId))
|
||||||
|
.stream().map(AiModelSampleRelateDO::getModelId).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> getModelSampleIds(Long modelId) {
|
||||||
|
return modelSampleRelateMapper.selectList(new LambdaQueryWrapper<AiModelSampleRelateDO>()
|
||||||
|
.eq(AiModelSampleRelateDO::getModelId, modelId))
|
||||||
|
.stream().map(AiModelSampleRelateDO::getSampleId).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AiSampleDetailVO> buildSampleDetailVOList(List<Long> sampleIds) {
|
||||||
|
return sampleIds.stream().map(this::buildSampleDetailVO).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AiSampleDetailVO buildSampleDetailVO(Long sampleId) {
|
||||||
|
AiSampleDO sample = sampleMapper.selectById(sampleId);
|
||||||
|
List<Long> tagIds = sampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId))
|
||||||
|
.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
||||||
|
|
||||||
|
List<AiSampleDetailVO.TagInfo> enumTags = new ArrayList<>();
|
||||||
|
List<AiSampleDetailVO.TagInfo> customTags = new ArrayList<>();
|
||||||
|
for (AiSampleTagDO tag : sampleTagMapper.selectBatchIds(tagIds)) {
|
||||||
|
AiSampleDetailVO.TagInfo tagInfo = AiSampleDetailVO.TagInfo.builder()
|
||||||
|
.id(tag.getId())
|
||||||
|
.tagName(tag.getTagName())
|
||||||
|
.enumValue(tag.getEnumValue())
|
||||||
|
.groupName(getTagGroupName(tag.getGroupId()))
|
||||||
|
.build();
|
||||||
|
if (Integer.valueOf(1).equals(tag.getTagType())) {
|
||||||
|
enumTags.add(tagInfo);
|
||||||
|
} else {
|
||||||
|
customTags.add(tagInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> modelIds = getSampleModelIds(sampleId);
|
||||||
|
List<AiSampleDetailVO.ModelInfo> relatedModels = modelMapper.selectBatchIds(modelIds).stream()
|
||||||
|
.map(model -> AiSampleDetailVO.ModelInfo.builder()
|
||||||
|
.id(model.getId())
|
||||||
|
.modelName(model.getModelName())
|
||||||
|
.version(model.getVersion())
|
||||||
|
.build())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return AiSampleDetailVO.builder()
|
||||||
|
.id(sample.getId())
|
||||||
|
.sampleName(sample.getSampleName())
|
||||||
|
.sampleFilePath(sample.getSampleFilePath())
|
||||||
|
.enumTags(enumTags)
|
||||||
|
.customTags(customTags)
|
||||||
|
.relatedModels(relatedModels)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTagGroupName(String groupIds) {
|
||||||
|
if (StrUtil.isBlank(groupIds)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
AiSampleTagGroupDO group = sampleTagGroupMapper.selectById(Long.parseLong(groupIds.split(StrUtil.COMMA)[0].trim()));
|
||||||
|
return group == null ? "" : group.getGroupName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AiSampleTagDO> getEnumTagsForSample(Long sampleId) {
|
||||||
|
List<Long> tagIds = sampleTagRelateMapper.selectList(new LambdaQueryWrapper<AiSampleTagRelateDO>()
|
||||||
|
.eq(AiSampleTagRelateDO::getSampleId, sampleId))
|
||||||
|
.stream().map(AiSampleTagRelateDO::getSampleTagId).toList();
|
||||||
|
return sampleTagMapper.selectBatchIds(tagIds).stream()
|
||||||
|
.filter(tag -> Integer.valueOf(1).equals(tag.getTagType()))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AiSampleTagGroupDO getGroupByName(String groupName) {
|
||||||
|
return sampleTagGroupMapper.selectOne(new LambdaQueryWrapper<AiSampleTagGroupDO>()
|
||||||
|
.eq(AiSampleTagGroupDO::getGroupName, groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateMatchRate(String recognitionValue, List<AiSampleTagDO> enumTags, Long groupId) {
|
||||||
|
if (StrUtil.isBlank(recognitionValue) || CollUtil.isEmpty(enumTags)) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
for (AiSampleTagDO tag : enumTags) {
|
||||||
|
if (tag.getGroupId().contains(groupId.toString())) {
|
||||||
|
if (recognitionValue.equalsIgnoreCase(tag.getTagName())
|
||||||
|
|| recognitionValue.contains(tag.getTagName())
|
||||||
|
|| tag.getTagName().contains(recognitionValue)) {
|
||||||
|
return BigDecimal.ONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user