Merge commit 'ca81514d4373039356d1684f93ae24c9b2182c79'
This commit is contained in:
@@ -40,10 +40,8 @@ public class AnnotationTaskController {
|
||||
@Operation(summary = "更新标注任务")
|
||||
@PutMapping("/{id}")
|
||||
public Result<AnnotationTaskResponse> update(
|
||||
@Parameter(description = "任务ID", example = "191000000000000301")
|
||||
@PathVariable Long id,
|
||||
@Valid @RequestBody UpdateAnnotationTaskRequest request
|
||||
) {
|
||||
@Parameter(description = "任务ID", example = "191000000000000301") @PathVariable Long id,
|
||||
@Valid @RequestBody UpdateAnnotationTaskRequest request) {
|
||||
return Result.success(annotationTaskService.updateTask(UserContext.requireUser(), id, request));
|
||||
}
|
||||
|
||||
@@ -56,18 +54,14 @@ public class AnnotationTaskController {
|
||||
@Operation(summary = "查询标注任务详情")
|
||||
@GetMapping("/{id}")
|
||||
public Result<AnnotationTaskResponse> detail(
|
||||
@Parameter(description = "任务ID", example = "191000000000000301")
|
||||
@PathVariable Long id
|
||||
) {
|
||||
@Parameter(description = "任务ID", example = "191000000000000301") @PathVariable Long id) {
|
||||
return Result.success(annotationTaskService.getTask(UserContext.requireUser(), id));
|
||||
}
|
||||
|
||||
@Operation(summary = "删除标注任务")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Void> delete(
|
||||
@Parameter(description = "任务ID", example = "191000000000000301")
|
||||
@PathVariable Long id
|
||||
) {
|
||||
@Parameter(description = "任务ID", example = "191000000000000301") @PathVariable Long id) {
|
||||
annotationTaskService.deleteTask(UserContext.requireUser(), id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.labelsys.backend.dto.request;
|
||||
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "标注任务分页查询请求")
|
||||
public record AnnotationTaskPageQuery(
|
||||
@Schema(description = "关键字", example = "运输") String keyword,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") String taskType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") TaskType taskType,
|
||||
@Schema(description = "任务状态", example = "PENDING") String taskStatus,
|
||||
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
package com.labelsys.backend.dto.request;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "创建标注任务请求")
|
||||
public record CreateAnnotationTaskRequest(
|
||||
@Schema(description = "任务名称", example = "运输文档问答抽取任务") @NotBlank(message = "任务名称不能为空") String taskName,
|
||||
@Schema(description = "行业类型", example = "transport") String industryType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") String taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") @NotEmpty(message = "资源列表不能为空") List<Long> resourceIds,
|
||||
@Schema(description = "抽取模型配置", example = "{\"mode\":\"SELECT\",\"selectedConfigName\":\"qwen-plus-extract\"}") @Valid TaskModelConfigRequest extractModel,
|
||||
@Schema(description = "校验模型配置", example = "{\"mode\":\"MANUAL\",\"manualConfig\":{\"modelName\":\"qwen-max\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo5678\"}}") @Valid TaskModelConfigRequest verifyModel,
|
||||
@Schema(description = "抽取提示词配置", example = "{\"selectedConfigName\":\"qa-extract-v1\"}") @Valid PromptConfigOptionRequest extractPrompt,
|
||||
@Schema(description = "校验提示词配置", example = "{\"promptText\":\"请对抽取结果进行逐项校验,并输出差异说明。\"}") @Valid PromptConfigOptionRequest verifyPrompt
|
||||
) {
|
||||
@Schema(description = "任务名称", example = "运输文档问答抽取任务") @NotBlank(message = "任务名称不能为空") String taskName,
|
||||
@Schema(description = "行业类型", defaultValue = "TRANSPORT", example = "TRANSPORT") @NotNull(message = "行业类型不能为空") IndustryType industryType,
|
||||
@Schema(description = "任务类型", defaultValue = "EXTRACT_QA", example = "EXTRACT_QA") @NotNull(message = "任务类型不能为空") TaskType taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") @NotEmpty(message = "资源列表不能为空") List<Long> resourceIds,
|
||||
@Schema(description = "抽取模型配置", example = "{\"mode\":\"SELECT\",\"selectedConfigName\":\"qwen-plus-extract\"}") @Valid TaskModelConfigRequest extractModel,
|
||||
@Schema(description = "校验模型配置", example = "{\"mode\":\"MANUAL\",\"manualConfig\":{\"modelName\":\"qwen-max\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo5678\"}}") @Valid TaskModelConfigRequest verifyModel,
|
||||
@Schema(description = "抽取提示词配置", example = "{\"selectedConfigName\":\"qa-extract-v1\"}") @Valid PromptConfigOptionRequest extractPrompt,
|
||||
@Schema(description = "校验提示词配置", example = "{\"promptText\":\"请对抽取结果进行逐项校验,并输出差异说明。\"}") @Valid PromptConfigOptionRequest verifyPrompt) {
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
@Schema(description = "创建系统工程师管理员请求")
|
||||
public record CreateSystemEngineerAdminRequest(
|
||||
@Schema(description = "手机号", example = "13800138002") @NotBlank(message = "不能为空") String phone,
|
||||
@Schema(description = "用户名,前端展示用,可为空", example = "system-engineer") String username,
|
||||
@Schema(description = "真实姓名", example = "系统工程师") @NotBlank(message = "不能为空") String realName) {}
|
||||
@Schema(description = "手机号", example = "13800138002") @NotBlank(message = "不能为空") String phone,
|
||||
@Schema(description = "用户名,前端展示用,可为空", example = "system-engineer") String username,
|
||||
@Schema(description = "真实姓名", example = "系统工程师") @NotBlank(message = "不能为空") String realName) {
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.labelsys.backend.dto.request;
|
||||
|
||||
import com.labelsys.backend.enums.ConfigMode;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "任务模型配置请求")
|
||||
public record TaskModelConfigRequest(
|
||||
@Schema(description = "配置模式:SELECT 或 MANUAL", example = "SELECT") @NotBlank(message = "配置模式不能为空") String mode,
|
||||
@Schema(description = "已选择的配置名称", example = "qwen-plus-extract") String selectedConfigName,
|
||||
@Schema(description = "手动录入的模型配置", example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") @Valid ManualModelConfigRequest manualConfig
|
||||
) {
|
||||
@Schema(description = "配置模式:SELECT 或 MANUAL", example = "SELECT") @NotNull(message = "配置模式不能为空") ConfigMode mode,
|
||||
|
||||
@Schema(description = "已选择的配置名称", example = "qwen-plus-extract") String selectedConfigName,
|
||||
|
||||
@Schema(description = "手动录入的模型配置", example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") @Valid ManualModelConfigRequest manualConfig) {
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package com.labelsys.backend.dto.request;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "更新标注任务请求")
|
||||
public record UpdateAnnotationTaskRequest(
|
||||
@Schema(description = "行业类型", example = "transport") String industryType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") String taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") @NotEmpty(message = "资源列表不能为空") List<Long> resourceIds,
|
||||
@Schema(description = "抽取模型配置", example = "{\"mode\":\"SELECT\",\"selectedConfigName\":\"qwen-plus-extract\"}") @Valid TaskModelConfigRequest extractModel,
|
||||
@Schema(description = "校验模型配置", example = "{\"mode\":\"MANUAL\",\"manualConfig\":{\"modelName\":\"qwen-max\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo5678\"}}") @Valid TaskModelConfigRequest verifyModel,
|
||||
@Schema(description = "抽取提示词配置", example = "{\"selectedConfigName\":\"qa-extract-v1\"}") @Valid PromptConfigOptionRequest extractPrompt,
|
||||
@Schema(description = "校验提示词配置", example = "{\"promptText\":\"请对抽取结果进行逐项校验,并输出差异说明。\"}") @Valid PromptConfigOptionRequest verifyPrompt
|
||||
) {
|
||||
@Schema(description = "行业类型", example = "TRANSPORT") IndustryType industryType,
|
||||
@Schema(description = "任务类型", example = "EXTRACT_QA") TaskType taskType,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") List<Long> resourceIds,
|
||||
@Schema(description = "抽取模型配置", example = "{\"mode\":\"SELECT\",\"selectedConfigName\":\"qwen-plus-extract\"}") @Valid TaskModelConfigRequest extractModel,
|
||||
@Schema(description = "校验模型配置", example = "{\"mode\":\"MANUAL\",\"manualConfig\":{\"modelName\":\"qwen-max\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo5678\"}}") @Valid TaskModelConfigRequest verifyModel,
|
||||
@Schema(description = "抽取提示词配置", example = "{\"selectedConfigName\":\"qa-extract-v1\"}") @Valid PromptConfigOptionRequest extractPrompt,
|
||||
@Schema(description = "校验提示词配置", example = "{\"promptText\":\"请对抽取结果进行逐项校验,并输出差异说明。\"}") @Valid PromptConfigOptionRequest verifyPrompt) {
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
|
||||
@Schema(description = "标注任务响应")
|
||||
public record AnnotationTaskResponse(
|
||||
@Schema(description = "任务ID", example = "191000000000000301") Long id,
|
||||
@Schema(description = "任务名称", example = "运输文档问答抽取任务") String taskName,
|
||||
@Schema(description = "行业类型:默认值transport,暂不显示", example = "transport") String industryType,
|
||||
@Schema(description = "任务类型:暂不显示", example = "EXTRACT_QA") String taskType,
|
||||
@Schema(description = "行业类型:默认值transport,暂不显示", example = "transport") IndustryType industryType,
|
||||
@Schema(description = "任务类型:暂不显示", example = "EXTRACT_QA") TaskType taskType,
|
||||
@Schema(description = "任务状态", example = "PENDING") String taskStatus,
|
||||
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") List<Long> resourceIds,
|
||||
@Schema(description = "抽取模型配置", example = "{\"configId\":191000000000000511,\"configName\":\"qwen-plus-extract\",\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"maskedApiKey\":\"****1234\"}") TaskModelConfigResponse extractModel,
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.labelsys.backend.entity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import com.labelsys.backend.enums.UserRole;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -22,8 +24,8 @@ public class AnnotationTask {
|
||||
private Long creatorId;
|
||||
private UserRole creatorRole;
|
||||
private String taskName;
|
||||
private String industryType;
|
||||
private String taskType;
|
||||
private IndustryType industryType;
|
||||
private TaskType taskType;
|
||||
private Long extractModelConfigId;
|
||||
private String extractModelName;
|
||||
private String extractModelUrl;
|
||||
|
||||
12
src/main/java/com/labelsys/backend/enums/ConfigMode.java
Normal file
12
src/main/java/com/labelsys/backend/enums/ConfigMode.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.labelsys.backend.enums;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "模型配置模式,枚举值:SELECT:选择已有模型配置、MANUAL:手动配置新模型")
|
||||
public enum ConfigMode {
|
||||
@Schema(description = "从已有配置中选择")
|
||||
SELECT,
|
||||
|
||||
@Schema(description = "手动录入配置")
|
||||
MANUAL
|
||||
}
|
||||
21
src/main/java/com/labelsys/backend/enums/IndustryType.java
Normal file
21
src/main/java/com/labelsys/backend/enums/IndustryType.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.labelsys.backend.enums;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "行业类型")
|
||||
public enum IndustryType {
|
||||
@Schema(description = "交通运输")
|
||||
TRANSPORT,
|
||||
|
||||
@Schema(description = "电力")
|
||||
ELECTRICITY,
|
||||
|
||||
@Schema(description = "金融")
|
||||
FINANCE,
|
||||
|
||||
@Schema(description = "医疗")
|
||||
MEDICAL,
|
||||
|
||||
@Schema(description = "教育")
|
||||
EDUCATION
|
||||
}
|
||||
12
src/main/java/com/labelsys/backend/enums/TaskType.java
Normal file
12
src/main/java/com/labelsys/backend/enums/TaskType.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.labelsys.backend.enums;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "标注任务类型")
|
||||
public enum TaskType {
|
||||
@Schema(description = "抽取问答对")
|
||||
EXTRACT_QA,
|
||||
|
||||
@Schema(description = "大模型微调")
|
||||
FINE_TUNE
|
||||
}
|
||||
@@ -25,11 +25,15 @@ import com.labelsys.backend.dto.response.TaskPromptConfigResponse;
|
||||
import com.labelsys.backend.entity.AnnotationTask;
|
||||
import com.labelsys.backend.entity.AnnotationTaskResource;
|
||||
import com.labelsys.backend.entity.SourceResource;
|
||||
import com.labelsys.backend.entity.SysConfig;
|
||||
import com.labelsys.backend.enums.IndustryType;
|
||||
import com.labelsys.backend.enums.SourceStatus;
|
||||
import com.labelsys.backend.enums.TaskStatus;
|
||||
import com.labelsys.backend.enums.TaskType;
|
||||
import com.labelsys.backend.mapper.AnnotationTaskMapper;
|
||||
import com.labelsys.backend.mapper.AnnotationTaskResourceMapper;
|
||||
import com.labelsys.backend.mapper.SourceResourceMapper;
|
||||
import com.labelsys.backend.mapper.SysConfigMapper;
|
||||
import com.labelsys.backend.util.IdGenerator;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -43,44 +47,36 @@ public class AnnotationTaskService {
|
||||
private final AnnotationTaskMapper annotationTaskMapper;
|
||||
private final AnnotationTaskResourceMapper annotationTaskResourceMapper;
|
||||
private final SourceResourceMapper sourceResourceMapper;
|
||||
private final SysConfigMapper sysConfigMapper;
|
||||
private final SysConfigService sysConfigService;
|
||||
private final DataPermissionService dataPermissionService;
|
||||
|
||||
@Transactional
|
||||
public AnnotationTaskResponse createTask(LoginUser currentUser, CreateAnnotationTaskRequest request) {
|
||||
List<SourceResource> resources = loadAndValidateResources(currentUser, request.resourceIds());
|
||||
SysConfigService.ResolvedModelConfig extractModel = sysConfigService.resolveModelConfig(currentUser, request.extractModel());
|
||||
SysConfigService.ResolvedModelConfig verifyModel = sysConfigService.resolveModelConfig(currentUser, request.verifyModel());
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt = sysConfigService.resolvePromptConfig(currentUser, request.extractPrompt());
|
||||
SysConfigService.ResolvedPromptConfig verifyPrompt = sysConfigService.resolvePromptConfig(currentUser, request.verifyPrompt());
|
||||
SysConfigService.ResolvedModelConfig extractModel = sysConfigService.resolveModelConfig(currentUser,
|
||||
request.extractModel());
|
||||
SysConfigService.ResolvedModelConfig verifyModel = sysConfigService.resolveModelConfig(currentUser,
|
||||
request.verifyModel());
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt = sysConfigService.resolvePromptConfig(currentUser,
|
||||
request.extractPrompt());
|
||||
SysConfigService.ResolvedPromptConfig verifyPrompt = sysConfigService.resolvePromptConfig(currentUser,
|
||||
request.verifyPrompt());
|
||||
|
||||
AnnotationTask task = AnnotationTask.builder()
|
||||
.id(IdGenerator.nextId())
|
||||
.companyId(currentUser.companyId())
|
||||
.creatorId(currentUser.userId())
|
||||
.creatorRole(currentUser.role())
|
||||
.taskName(request.taskName())
|
||||
.industryType(defaultIndustryType(request.industryType()))
|
||||
.taskType(defaultTaskType(request.taskType()))
|
||||
.extractModelConfigId(extractModel.configId())
|
||||
.extractModelName(extractModel.modelName())
|
||||
.extractModelUrl(extractModel.modelUrl())
|
||||
.extractModelApiKey(extractModel.apiKey())
|
||||
.verifyModelConfigId(verifyModel.configId())
|
||||
.verifyModelName(verifyModel.modelName())
|
||||
.verifyModelUrl(verifyModel.modelUrl())
|
||||
.verifyModelApiKey(verifyModel.apiKey())
|
||||
.extractPromptConfigId(extractPrompt.configId())
|
||||
.extractPrompt(extractPrompt.promptText())
|
||||
.verifyPromptConfigId(verifyPrompt.configId())
|
||||
.verifyPrompt(verifyPrompt.promptText())
|
||||
.taskStatus(TaskStatus.PENDING.name())
|
||||
.isDeleted(false)
|
||||
.build();
|
||||
AnnotationTask task = AnnotationTask.builder().id(IdGenerator.nextId()).companyId(currentUser.companyId())
|
||||
.creatorId(currentUser.userId()).creatorRole(currentUser.role()).taskName(request.taskName())
|
||||
.industryType(defaultIndustryType(request.industryType())).taskType(defaultTaskType(request.taskType()))
|
||||
.extractModelConfigId(extractModel.configId()).extractModelName(extractModel.modelName())
|
||||
.extractModelUrl(extractModel.modelUrl()).extractModelApiKey(extractModel.apiKey())
|
||||
.verifyModelConfigId(verifyModel.configId()).verifyModelName(verifyModel.modelName())
|
||||
.verifyModelUrl(verifyModel.modelUrl()).verifyModelApiKey(verifyModel.apiKey())
|
||||
.extractPromptConfigId(extractPrompt.configId()).extractPrompt(extractPrompt.promptText())
|
||||
.verifyPromptConfigId(verifyPrompt.configId()).verifyPrompt(verifyPrompt.promptText())
|
||||
.taskStatus(TaskStatus.PENDING.name()).isDeleted(false).build();
|
||||
annotationTaskMapper.insert(task);
|
||||
saveTaskBindings(task.getId(), currentUser.companyId(), resources);
|
||||
log.info("created annotation task, companyId={}, userId={}, taskId={}, resourceCount={}",
|
||||
currentUser.companyId(), currentUser.userId(), task.getId(), resources.size());
|
||||
currentUser.companyId(), currentUser.userId(), task.getId(), resources.size());
|
||||
return buildTaskResponse(task, resourceIds(resources), extractModel, verifyModel, extractPrompt, verifyPrompt);
|
||||
}
|
||||
|
||||
@@ -92,42 +88,77 @@ public class AnnotationTaskService {
|
||||
}
|
||||
assertTaskPermission(currentUser, task);
|
||||
|
||||
List<Long> currentResourceIds = normalizeIds(annotationTaskResourceMapper.listResourceIdsByTaskId(taskId));
|
||||
List<Long> targetResourceIds = normalizeIds(request.resourceIds());
|
||||
boolean resourcesChanged = !currentResourceIds.equals(targetResourceIds);
|
||||
if (TaskStatus.RUNNING.name().equals(task.getTaskStatus()) && resourcesChanged) {
|
||||
throw new BusinessException(ResultCode.CONFLICT, "运行中的任务不允许修改资源");
|
||||
boolean resourcesChanged = false;
|
||||
List<SourceResource> resources = null;
|
||||
|
||||
if (request.resourceIds() != null && !request.resourceIds().isEmpty()) {
|
||||
List<Long> currentResourceIds = normalizeIds(annotationTaskResourceMapper.listResourceIdsByTaskId(taskId));
|
||||
List<Long> targetResourceIds = normalizeIds(request.resourceIds());
|
||||
resourcesChanged = !currentResourceIds.equals(targetResourceIds);
|
||||
if (TaskStatus.RUNNING.name().equals(task.getTaskStatus()) && resourcesChanged) {
|
||||
throw new BusinessException(ResultCode.CONFLICT, "运行中的任务不允许修改资源");
|
||||
}
|
||||
resources = loadAndValidateResources(currentUser, request.resourceIds());
|
||||
}
|
||||
|
||||
List<SourceResource> resources = loadAndValidateResources(currentUser, request.resourceIds());
|
||||
SysConfigService.ResolvedModelConfig extractModel = sysConfigService.resolveModelConfig(currentUser, request.extractModel());
|
||||
SysConfigService.ResolvedModelConfig verifyModel = sysConfigService.resolveModelConfig(currentUser, request.verifyModel());
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt = sysConfigService.resolvePromptConfig(currentUser, request.extractPrompt());
|
||||
SysConfigService.ResolvedPromptConfig verifyPrompt = sysConfigService.resolvePromptConfig(currentUser, request.verifyPrompt());
|
||||
SysConfigService.ResolvedModelConfig extractModel = null;
|
||||
SysConfigService.ResolvedModelConfig verifyModel = null;
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt = null;
|
||||
SysConfigService.ResolvedPromptConfig verifyPrompt = null;
|
||||
|
||||
if (request.extractModel() != null) {
|
||||
extractModel = sysConfigService.resolveModelConfig(currentUser, request.extractModel());
|
||||
task.setExtractModelConfigId(extractModel.configId());
|
||||
task.setExtractModelName(extractModel.modelName());
|
||||
task.setExtractModelUrl(extractModel.modelUrl());
|
||||
task.setExtractModelApiKey(extractModel.apiKey());
|
||||
}
|
||||
|
||||
if (request.verifyModel() != null) {
|
||||
verifyModel = sysConfigService.resolveModelConfig(currentUser, request.verifyModel());
|
||||
task.setVerifyModelConfigId(verifyModel.configId());
|
||||
task.setVerifyModelName(verifyModel.modelName());
|
||||
task.setVerifyModelUrl(verifyModel.modelUrl());
|
||||
task.setVerifyModelApiKey(verifyModel.apiKey());
|
||||
}
|
||||
|
||||
if (request.extractPrompt() != null) {
|
||||
extractPrompt = sysConfigService.resolvePromptConfig(currentUser, request.extractPrompt());
|
||||
task.setExtractPromptConfigId(extractPrompt.configId());
|
||||
task.setExtractPrompt(extractPrompt.promptText());
|
||||
}
|
||||
|
||||
if (request.verifyPrompt() != null) {
|
||||
verifyPrompt = sysConfigService.resolvePromptConfig(currentUser, request.verifyPrompt());
|
||||
task.setVerifyPromptConfigId(verifyPrompt.configId());
|
||||
task.setVerifyPrompt(verifyPrompt.promptText());
|
||||
}
|
||||
|
||||
if (request.industryType() != null) {
|
||||
task.setIndustryType(request.industryType());
|
||||
}
|
||||
|
||||
if (request.taskType() != null) {
|
||||
task.setTaskType(request.taskType());
|
||||
}
|
||||
|
||||
task.setIndustryType(defaultIndustryType(request.industryType()));
|
||||
task.setTaskType(defaultTaskType(request.taskType()));
|
||||
task.setExtractModelConfigId(extractModel.configId());
|
||||
task.setExtractModelName(extractModel.modelName());
|
||||
task.setExtractModelUrl(extractModel.modelUrl());
|
||||
task.setExtractModelApiKey(extractModel.apiKey());
|
||||
task.setVerifyModelConfigId(verifyModel.configId());
|
||||
task.setVerifyModelName(verifyModel.modelName());
|
||||
task.setVerifyModelUrl(verifyModel.modelUrl());
|
||||
task.setVerifyModelApiKey(verifyModel.apiKey());
|
||||
task.setExtractPromptConfigId(extractPrompt.configId());
|
||||
task.setExtractPrompt(extractPrompt.promptText());
|
||||
task.setVerifyPromptConfigId(verifyPrompt.configId());
|
||||
task.setVerifyPrompt(verifyPrompt.promptText());
|
||||
annotationTaskMapper.updateById(task);
|
||||
|
||||
if (resourcesChanged) {
|
||||
if (resourcesChanged && resources != null) {
|
||||
annotationTaskResourceMapper.deleteByTaskId(taskId);
|
||||
saveTaskBindings(taskId, currentUser.companyId(), resources);
|
||||
}
|
||||
|
||||
log.info("updated annotation task, companyId={}, userId={}, taskId={}, resourcesChanged={}",
|
||||
currentUser.companyId(), currentUser.userId(), taskId, resourcesChanged);
|
||||
return buildTaskResponse(task, resourceIds(resources), extractModel, verifyModel, extractPrompt, verifyPrompt);
|
||||
currentUser.companyId(), currentUser.userId(), taskId, resourcesChanged);
|
||||
|
||||
List<Long> finalResourceIds = resources != null ? resourceIds(resources)
|
||||
: normalizeIds(annotationTaskResourceMapper.listResourceIdsByTaskId(taskId));
|
||||
|
||||
if (extractModel == null || verifyModel == null || extractPrompt == null || verifyPrompt == null) {
|
||||
return buildTaskResponse(task, finalResourceIds);
|
||||
}
|
||||
return buildTaskResponse(task, finalResourceIds, extractModel, verifyModel, extractPrompt, verifyPrompt);
|
||||
}
|
||||
|
||||
public AnnotationTaskResponse getTask(LoginUser currentUser, Long taskId) {
|
||||
@@ -144,11 +175,11 @@ public class AnnotationTaskService {
|
||||
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
|
||||
|
||||
LambdaQueryWrapper<AnnotationTask> wrapper = new LambdaQueryWrapper<AnnotationTask>()
|
||||
.eq(AnnotationTask::getCompanyId, currentUser.companyId())
|
||||
.eq(StringUtils.hasText(query.taskType()), AnnotationTask::getTaskType, query.taskType())
|
||||
.eq(StringUtils.hasText(query.taskStatus()), AnnotationTask::getTaskStatus, query.taskStatus())
|
||||
.eq(query.isDeleted() != null, AnnotationTask::getIsDeleted, query.isDeleted())
|
||||
.like(StringUtils.hasText(query.keyword()), AnnotationTask::getTaskName, query.keyword());
|
||||
.eq(AnnotationTask::getCompanyId, currentUser.companyId())
|
||||
.eq(query.taskType() != null, AnnotationTask::getTaskType, query.taskType())
|
||||
.eq(StringUtils.hasText(query.taskStatus()), AnnotationTask::getTaskStatus, query.taskStatus())
|
||||
.eq(query.isDeleted() != null, AnnotationTask::getIsDeleted, query.isDeleted())
|
||||
.like(StringUtils.hasText(query.keyword()), AnnotationTask::getTaskName, query.keyword());
|
||||
|
||||
if (shouldFilterByUserId) {
|
||||
wrapper.eq(AnnotationTask::getCreatorId, currentUser.userId());
|
||||
@@ -162,13 +193,15 @@ public class AnnotationTaskService {
|
||||
Page<AnnotationTask> resultPage = annotationTaskMapper.selectPage(page, wrapper);
|
||||
|
||||
List<AnnotationTaskResponse> records = resultPage.getRecords().stream()
|
||||
.filter(task -> query.resourceId() == null ||
|
||||
annotationTaskResourceMapper.listResourceIdsByTaskId(task.getId()).contains(query.resourceId()))
|
||||
.map(task -> buildTaskResponse(task,
|
||||
normalizeIds(annotationTaskResourceMapper.listResourceIdsByTaskId(task.getId()))))
|
||||
.toList();
|
||||
.filter(task -> query.resourceId() == null
|
||||
|| annotationTaskResourceMapper.listResourceIdsByTaskId(task.getId())
|
||||
.contains(query.resourceId()))
|
||||
.map(task -> buildTaskResponse(task,
|
||||
normalizeIds(annotationTaskResourceMapper.listResourceIdsByTaskId(task.getId()))))
|
||||
.toList();
|
||||
|
||||
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(), (int) resultPage.getSize());
|
||||
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(),
|
||||
(int) resultPage.getSize());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -183,8 +216,8 @@ public class AnnotationTaskService {
|
||||
}
|
||||
task.setIsDeleted(true);
|
||||
annotationTaskMapper.updateById(task);
|
||||
log.info("deleted annotation task logically, companyId={}, userId={}, taskId={}",
|
||||
currentUser.companyId(), currentUser.userId(), taskId);
|
||||
log.info("deleted annotation task logically, companyId={}, userId={}, taskId={}", currentUser.companyId(),
|
||||
currentUser.userId(), taskId);
|
||||
}
|
||||
|
||||
private List<SourceResource> loadAndValidateResources(LoginUser currentUser, List<Long> resourceIds) {
|
||||
@@ -192,12 +225,14 @@ public class AnnotationTaskService {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "任务资源不能为空");
|
||||
}
|
||||
List<Long> normalizedIds = normalizeIds(resourceIds);
|
||||
List<SourceResource> resources = sourceResourceMapper.selectByCompanyIdAndIds(currentUser.companyId(), normalizedIds);
|
||||
List<SourceResource> resources = sourceResourceMapper.selectByCompanyIdAndIds(currentUser.companyId(),
|
||||
normalizedIds);
|
||||
if (resources.size() != normalizedIds.size()) {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "存在无效资源");
|
||||
}
|
||||
for (SourceResource resource : resources) {
|
||||
if (!dataPermissionService.canAccessCreator(currentUser, resource.getCreatorId(), resource.getCreatorRole())) {
|
||||
if (!dataPermissionService.canAccessCreator(currentUser, resource.getCreatorId(),
|
||||
resource.getCreatorRole())) {
|
||||
throw new BusinessException(ResultCode.FORBIDDEN, "无权访问资源");
|
||||
}
|
||||
if (!SourceStatus.READY.name().equals(resource.getSourceStatus())) {
|
||||
@@ -210,52 +245,39 @@ public class AnnotationTaskService {
|
||||
|
||||
private void saveTaskBindings(Long taskId, Long companyId, List<SourceResource> resources) {
|
||||
for (SourceResource resource : resources) {
|
||||
annotationTaskResourceMapper.insert(AnnotationTaskResource.builder()
|
||||
.id(IdGenerator.nextId())
|
||||
.companyId(companyId)
|
||||
.taskId(taskId)
|
||||
.resourceId(resource.getId())
|
||||
.build());
|
||||
annotationTaskResourceMapper.insert(AnnotationTaskResource.builder().id(IdGenerator.nextId())
|
||||
.companyId(companyId).taskId(taskId).resourceId(resource.getId()).build());
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationTaskResponse buildTaskResponse(AnnotationTask task,
|
||||
List<Long> resourceIds,
|
||||
SysConfigService.ResolvedModelConfig extractModel,
|
||||
SysConfigService.ResolvedModelConfig verifyModel,
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt,
|
||||
SysConfigService.ResolvedPromptConfig verifyPrompt) {
|
||||
return new AnnotationTaskResponse(
|
||||
task.getId(),
|
||||
task.getTaskName(),
|
||||
task.getIndustryType(),
|
||||
task.getTaskType(),
|
||||
task.getTaskStatus(),
|
||||
resourceIds,
|
||||
sysConfigService.toResponse(extractModel),
|
||||
sysConfigService.toResponse(verifyModel),
|
||||
sysConfigService.toResponse(extractPrompt),
|
||||
sysConfigService.toResponse(verifyPrompt),
|
||||
task.getCreatedAt(),
|
||||
task.getUpdatedAt());
|
||||
private AnnotationTaskResponse buildTaskResponse(AnnotationTask task, List<Long> resourceIds,
|
||||
SysConfigService.ResolvedModelConfig extractModel, SysConfigService.ResolvedModelConfig verifyModel,
|
||||
SysConfigService.ResolvedPromptConfig extractPrompt, SysConfigService.ResolvedPromptConfig verifyPrompt) {
|
||||
return new AnnotationTaskResponse(task.getId(), task.getTaskName(), task.getIndustryType(), task.getTaskType(),
|
||||
task.getTaskStatus(), resourceIds, sysConfigService.toResponse(extractModel),
|
||||
sysConfigService.toResponse(verifyModel), sysConfigService.toResponse(extractPrompt),
|
||||
sysConfigService.toResponse(verifyPrompt), task.getCreatedAt(), task.getUpdatedAt());
|
||||
}
|
||||
|
||||
private AnnotationTaskResponse buildTaskResponse(AnnotationTask task, List<Long> resourceIds) {
|
||||
return new AnnotationTaskResponse(
|
||||
task.getId(),
|
||||
task.getTaskName(),
|
||||
task.getIndustryType(),
|
||||
task.getTaskType(),
|
||||
task.getTaskStatus(),
|
||||
resourceIds,
|
||||
new TaskModelConfigResponse(task.getExtractModelConfigId(), null, task.getExtractModelName(),
|
||||
task.getExtractModelUrl(), maskSecret(task.getExtractModelApiKey())),
|
||||
new TaskModelConfigResponse(task.getVerifyModelConfigId(), null, task.getVerifyModelName(),
|
||||
task.getVerifyModelUrl(), maskSecret(task.getVerifyModelApiKey())),
|
||||
new TaskPromptConfigResponse(task.getExtractPromptConfigId(), null, task.getExtractPrompt()),
|
||||
new TaskPromptConfigResponse(task.getVerifyPromptConfigId(), null, task.getVerifyPrompt()),
|
||||
task.getCreatedAt(),
|
||||
task.getUpdatedAt());
|
||||
String extractModelConfigName = resolveConfigName(task.getExtractModelConfigId());
|
||||
String verifyModelConfigName = resolveConfigName(task.getVerifyModelConfigId());
|
||||
String extractPromptConfigName = resolveConfigName(task.getExtractPromptConfigId());
|
||||
String verifyPromptConfigName = resolveConfigName(task.getVerifyPromptConfigId());
|
||||
|
||||
return new AnnotationTaskResponse(task.getId(), task.getTaskName(), task.getIndustryType(), task.getTaskType(),
|
||||
task.getTaskStatus(), resourceIds,
|
||||
new TaskModelConfigResponse(task.getExtractModelConfigId(), extractModelConfigName,
|
||||
task.getExtractModelName(),
|
||||
task.getExtractModelUrl(), maskSecret(task.getExtractModelApiKey())),
|
||||
new TaskModelConfigResponse(task.getVerifyModelConfigId(), verifyModelConfigName,
|
||||
task.getVerifyModelName(),
|
||||
task.getVerifyModelUrl(), maskSecret(task.getVerifyModelApiKey())),
|
||||
new TaskPromptConfigResponse(task.getExtractPromptConfigId(), extractPromptConfigName,
|
||||
task.getExtractPrompt()),
|
||||
new TaskPromptConfigResponse(task.getVerifyPromptConfigId(), verifyPromptConfigName,
|
||||
task.getVerifyPrompt()),
|
||||
task.getCreatedAt(), task.getUpdatedAt());
|
||||
}
|
||||
|
||||
private List<Long> resourceIds(List<SourceResource> resources) {
|
||||
@@ -275,12 +297,12 @@ public class AnnotationTaskService {
|
||||
}
|
||||
}
|
||||
|
||||
private String defaultIndustryType(String industryType) {
|
||||
return StringUtils.hasText(industryType) ? industryType : "transport";
|
||||
private IndustryType defaultIndustryType(IndustryType industryType) {
|
||||
return industryType != null ? industryType : IndustryType.TRANSPORT;
|
||||
}
|
||||
|
||||
private String defaultTaskType(String taskType) {
|
||||
return StringUtils.hasText(taskType) ? taskType : "EXTRACT_QA";
|
||||
private TaskType defaultTaskType(TaskType taskType) {
|
||||
return taskType != null ? taskType : TaskType.EXTRACT_QA;
|
||||
}
|
||||
|
||||
private String maskSecret(String secret) {
|
||||
@@ -292,4 +314,12 @@ public class AnnotationTaskService {
|
||||
}
|
||||
return "****" + secret.substring(secret.length() - 4);
|
||||
}
|
||||
|
||||
private String resolveConfigName(Long configId) {
|
||||
if (configId == null) {
|
||||
return null;
|
||||
}
|
||||
SysConfig config = sysConfigMapper.selectById(configId);
|
||||
return config != null ? config.getConfigName() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.labelsys.backend.dto.response.SysConfigResponse;
|
||||
import com.labelsys.backend.dto.response.TaskModelConfigResponse;
|
||||
import com.labelsys.backend.dto.response.TaskPromptConfigResponse;
|
||||
import com.labelsys.backend.entity.SysConfig;
|
||||
import com.labelsys.backend.enums.ConfigMode;
|
||||
import com.labelsys.backend.enums.ConfigType;
|
||||
import com.labelsys.backend.enums.UserRole;
|
||||
import com.labelsys.backend.mapper.SysConfigMapper;
|
||||
@@ -45,18 +46,19 @@ public class SysConfigService {
|
||||
@Transactional
|
||||
public SysConfig saveConfig(LoginUser currentUser, SaveSysConfigRequest request) {
|
||||
validateConfigType(request.configType());
|
||||
SysConfig existing =
|
||||
sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(), request.configName());
|
||||
SysConfig existing = sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(),
|
||||
request.configName());
|
||||
if (existing != null) {
|
||||
throw new BusinessException(ResultCode.CONFLICT, "配置名称已存在");
|
||||
}
|
||||
SysConfig config = SysConfig.builder().id(IdGenerator.nextId()).companyId(currentUser.companyId())
|
||||
.configType(request.configType()).configName(request.configName()).configValue(request.configValue())
|
||||
.status(request.status()).creatorId(currentUser.userId()).creatorRole(currentUser.role().name()).build();
|
||||
.configType(request.configType()).configName(request.configName()).configValue(request.configValue())
|
||||
.status(request.status()).creatorId(currentUser.userId()).creatorRole(currentUser.role().name())
|
||||
.build();
|
||||
sysConfigMapper.insert(config);
|
||||
log.info("saved sys config, companyId={}, userId={}, userRole={}, configName={}, configType={}",
|
||||
currentUser.companyId(), currentUser.userId(), currentUser.role().name(), request.configName(),
|
||||
request.configType());
|
||||
currentUser.companyId(), currentUser.userId(), currentUser.role().name(), request.configName(),
|
||||
request.configType());
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -65,7 +67,8 @@ public class SysConfigService {
|
||||
validateConfigType(request.configType());
|
||||
SysConfig existing = getConfigEntity(currentUser, configId);
|
||||
// SysConfig duplicate =
|
||||
// sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(), request.configName());
|
||||
// sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(),
|
||||
// request.configName());
|
||||
// if (duplicate != null && !duplicate.getId().equals(configId)) {
|
||||
// throw new BusinessException(ResultCode.CONFLICT, "配置名称已存在");
|
||||
// }
|
||||
@@ -83,14 +86,14 @@ public class SysConfigService {
|
||||
}
|
||||
sysConfigMapper.updateById(existing);
|
||||
log.info("updated sys config, companyId={}, userId={}, configId={}", currentUser.companyId(),
|
||||
currentUser.userId(), configId);
|
||||
currentUser.userId(), configId);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public SysConfigResponse getConfig(LoginUser currentUser, Long configId) {
|
||||
SysConfig config = getConfigEntity(currentUser, configId);
|
||||
if (!dataPermissionService.canAccessCreator(currentUser, config.getCreatorId(),
|
||||
UserRole.valueOf(config.getCreatorRole()))) {
|
||||
UserRole.valueOf(config.getCreatorRole()))) {
|
||||
throw new BusinessException(ResultCode.FORBIDDEN, "无权访问配置");
|
||||
}
|
||||
return toResponse(config);
|
||||
@@ -100,8 +103,8 @@ public class SysConfigService {
|
||||
List<String> allowedRoles = dataPermissionService.getAllowedRoles(currentUser);
|
||||
boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser);
|
||||
|
||||
LambdaQueryWrapper<SysConfig> wrapper =
|
||||
new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getCompanyId, currentUser.companyId())
|
||||
LambdaQueryWrapper<SysConfig> wrapper = new LambdaQueryWrapper<SysConfig>()
|
||||
.eq(SysConfig::getCompanyId, currentUser.companyId())
|
||||
.eq(StringUtils.hasText(query.configType()), SysConfig::getConfigType, query.configType())
|
||||
.eq(StringUtils.hasText(query.status()), SysConfig::getStatus, query.status())
|
||||
.like(StringUtils.hasText(query.configName()), SysConfig::getConfigName, query.configName());
|
||||
@@ -119,19 +122,19 @@ public class SysConfigService {
|
||||
|
||||
List<SysConfigResponse> records = resultPage.getRecords().stream().map(this::toResponse).toList();
|
||||
|
||||
return new PageResult<>(records, resultPage.getTotal(), (int)resultPage.getCurrent(),
|
||||
(int)resultPage.getSize());
|
||||
return new PageResult<>(records, resultPage.getTotal(), (int) resultPage.getCurrent(),
|
||||
(int) resultPage.getSize());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ResolvedModelConfig resolveModelConfig(LoginUser currentUser, TaskModelConfigRequest request) {
|
||||
if (request == null || !StringUtils.hasText(request.mode())) {
|
||||
if (request == null || request.mode() == null) {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "模型配置不能为空");
|
||||
}
|
||||
if ("SELECT".equalsIgnoreCase(request.mode())) {
|
||||
if (request.mode() == ConfigMode.SELECT) {
|
||||
return resolveSelectedModel(currentUser, request.selectedConfigName());
|
||||
}
|
||||
if ("MANUAL".equalsIgnoreCase(request.mode())) {
|
||||
if (request.mode() == ConfigMode.MANUAL) {
|
||||
return resolveManualModel(currentUser, request.manualConfig());
|
||||
}
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "不支持的模型配置模式");
|
||||
@@ -143,7 +146,7 @@ public class SysConfigService {
|
||||
}
|
||||
if (StringUtils.hasText(request.selectedConfigName())) {
|
||||
SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType(currentUser.companyId(),
|
||||
request.selectedConfigName(), ConfigType.PROMPT.name());
|
||||
request.selectedConfigName(), ConfigType.PROMPT.name());
|
||||
if (config == null) {
|
||||
throw new BusinessException(ResultCode.NOT_FOUND, "提示词配置不存在");
|
||||
}
|
||||
@@ -157,7 +160,7 @@ public class SysConfigService {
|
||||
|
||||
public TaskModelConfigResponse toResponse(ResolvedModelConfig config) {
|
||||
return new TaskModelConfigResponse(config.configId(), config.configName(), config.modelName(),
|
||||
config.modelUrl(), maskSecret(config.apiKey()));
|
||||
config.modelUrl(), maskSecret(config.apiKey()));
|
||||
}
|
||||
|
||||
public TaskPromptConfigResponse toResponse(ResolvedPromptConfig config) {
|
||||
@@ -166,8 +169,8 @@ public class SysConfigService {
|
||||
|
||||
public SysConfigResponse toResponse(SysConfig config) {
|
||||
return new SysConfigResponse(config.getId(), config.getConfigType(), config.getConfigName(),
|
||||
config.getConfigValue(), config.getStatus(), config.getCreatorId(), config.getCreatedAt(),
|
||||
config.getUpdatedAt());
|
||||
config.getConfigValue(), config.getStatus(), config.getCreatorId(), config.getCreatedAt(),
|
||||
config.getUpdatedAt());
|
||||
}
|
||||
|
||||
private ResolvedModelConfig resolveSelectedModel(LoginUser currentUser, String configName) {
|
||||
@@ -175,38 +178,38 @@ public class SysConfigService {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "模型配置名称不能为空");
|
||||
}
|
||||
SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType(currentUser.companyId(), configName,
|
||||
ConfigType.MODEL.name());
|
||||
ConfigType.MODEL.name());
|
||||
if (config == null) {
|
||||
throw new BusinessException(ResultCode.NOT_FOUND, "模型配置不存在");
|
||||
}
|
||||
ModelConfigValue configValue = parseModelConfig(config.getConfigValue());
|
||||
return new ResolvedModelConfig(config.getId(), config.getConfigName(), configValue.modelName(),
|
||||
configValue.modelUrl(), configValue.apiKey());
|
||||
configValue.modelUrl(), configValue.apiKey());
|
||||
}
|
||||
|
||||
private ResolvedModelConfig resolveManualModel(LoginUser currentUser, ManualModelConfigRequest request) {
|
||||
if (request == null || !StringUtils.hasText(request.modelName()) || !StringUtils.hasText(request.modelUrl())
|
||||
|| !StringUtils.hasText(request.apiKey())) {
|
||||
|| !StringUtils.hasText(request.apiKey())) {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "手动模型配置不完整");
|
||||
}
|
||||
SysConfig existing = sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(), request.modelName());
|
||||
if (existing == null) {
|
||||
String configValue = writeModelConfig(request);
|
||||
SysConfig config = SysConfig.builder().id(IdGenerator.nextId()).companyId(currentUser.companyId())
|
||||
.configType(ConfigType.MODEL.name()).configName(request.modelName()).configValue(configValue)
|
||||
.status("ENABLED").creatorId(currentUser.userId()).build();
|
||||
.configType(ConfigType.MODEL.name()).configName(request.modelName()).configValue(configValue)
|
||||
.status("ENABLED").creatorId(currentUser.userId()).build();
|
||||
sysConfigMapper.insert(config);
|
||||
log.info("auto created model config, companyId={}, userId={}, configName={}", currentUser.companyId(),
|
||||
currentUser.userId(), request.modelName());
|
||||
currentUser.userId(), request.modelName());
|
||||
return new ResolvedModelConfig(config.getId(), config.getConfigName(), request.modelName(),
|
||||
request.modelUrl(), request.apiKey());
|
||||
request.modelUrl(), request.apiKey());
|
||||
}
|
||||
if (!ConfigType.MODEL.name().equals(existing.getConfigType())) {
|
||||
throw new BusinessException(ResultCode.CONFLICT, "同名配置已被其他类型占用");
|
||||
}
|
||||
ModelConfigValue configValue = parseModelConfig(existing.getConfigValue());
|
||||
return new ResolvedModelConfig(existing.getId(), existing.getConfigName(), configValue.modelName(),
|
||||
configValue.modelUrl(), configValue.apiKey());
|
||||
configValue.modelUrl(), configValue.apiKey());
|
||||
}
|
||||
|
||||
private SysConfig getConfigEntity(LoginUser currentUser, Long configId) {
|
||||
@@ -234,7 +237,8 @@ public class SysConfigService {
|
||||
private String writeModelConfig(ManualModelConfigRequest request) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(
|
||||
Map.of("modelName", request.modelName(), "modelUrl", request.modelUrl(), "apiKey", request.apiKey()));
|
||||
Map.of("modelName", request.modelName(), "modelUrl", request.modelUrl(), "apiKey",
|
||||
request.apiKey()));
|
||||
} catch (JsonProcessingException ex) {
|
||||
throw new BusinessException(ResultCode.BAD_REQUEST, "模型配置值生成失败");
|
||||
}
|
||||
@@ -250,19 +254,25 @@ public class SysConfigService {
|
||||
return "****" + secret.substring(secret.length() - 4);
|
||||
}
|
||||
|
||||
// private <T> PageResult<T> paginate(List<T> records, Integer pageNo, Integer pageSize) {
|
||||
// private <T> PageResult<T> paginate(List<T> records, Integer pageNo, Integer
|
||||
// pageSize) {
|
||||
// int actualPageNo = pageNo == null || pageNo < 1 ? 1 : pageNo;
|
||||
// int actualPageSize = pageSize == null || pageSize < 1 ? 10 : pageSize;
|
||||
// int fromIndex = Math.min((actualPageNo - 1) * actualPageSize, records.size());
|
||||
// int fromIndex = Math.min((actualPageNo - 1) * actualPageSize,
|
||||
// records.size());
|
||||
// int toIndex = Math.min(fromIndex + actualPageSize, records.size());
|
||||
// return new PageResult<>(records.subList(fromIndex, toIndex), (long)records.size(), actualPageNo,
|
||||
// return new PageResult<>(records.subList(fromIndex, toIndex),
|
||||
// (long)records.size(), actualPageNo,
|
||||
// actualPageSize);
|
||||
// }
|
||||
|
||||
private record ModelConfigValue(String modelName, String modelUrl, String apiKey) {}
|
||||
private record ModelConfigValue(String modelName, String modelUrl, String apiKey) {
|
||||
}
|
||||
|
||||
public record ResolvedModelConfig(Long configId, String configName, String modelName, String modelUrl,
|
||||
String apiKey) {}
|
||||
String apiKey) {
|
||||
}
|
||||
|
||||
public record ResolvedPromptConfig(Long configId, String configName, String promptText) {}
|
||||
public record ResolvedPromptConfig(Long configId, String configName, String promptText) {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user