From 343df65c698d579335d9c7c47160b79ae0c14f8a Mon Sep 17 00:00:00 2001 From: wh Date: Tue, 28 Apr 2026 12:15:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B5=84=E6=BA=90=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SysConfigController.java | 51 +++-- .../dto/request/SaveSysConfigRequest.java | 8 +- .../dto/request/SysConfigPageQuery.java | 7 +- .../dto/request/UpdateSysConfigRequest.java | 14 ++ .../labelsys/backend/entity/SysConfig.java | 1 + .../service/AnnotationResultService.java | 65 +++--- .../backend/service/SysConfigService.java | 198 +++++++++--------- src/main/resources/sql/data.sql | 20 +- src/main/resources/sql/schema.sql | 2 + 9 files changed, 189 insertions(+), 177 deletions(-) create mode 100644 src/main/java/com/labelsys/backend/dto/request/UpdateSysConfigRequest.java diff --git a/src/main/java/com/labelsys/backend/controller/SysConfigController.java b/src/main/java/com/labelsys/backend/controller/SysConfigController.java index 56fceee..50b71f2 100644 --- a/src/main/java/com/labelsys/backend/controller/SysConfigController.java +++ b/src/main/java/com/labelsys/backend/controller/SysConfigController.java @@ -1,19 +1,5 @@ package com.labelsys.backend.controller; -import com.labelsys.backend.annotation.RequirePosition; -import com.labelsys.backend.common.Result; -import com.labelsys.backend.context.UserContext; -import com.labelsys.backend.dto.common.PageResult; -import com.labelsys.backend.dto.request.SaveSysConfigRequest; -import com.labelsys.backend.dto.request.SysConfigPageQuery; -import com.labelsys.backend.dto.response.SysConfigResponse; -import com.labelsys.backend.enums.UserPosition; -import com.labelsys.backend.service.SysConfigService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; import org.springdoc.core.annotations.ParameterObject; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -23,6 +9,21 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.labelsys.backend.common.Result; +import com.labelsys.backend.context.UserContext; +import com.labelsys.backend.dto.common.PageResult; +import com.labelsys.backend.dto.request.SaveSysConfigRequest; +import com.labelsys.backend.dto.request.SysConfigPageQuery; +import com.labelsys.backend.dto.request.UpdateSysConfigRequest; +import com.labelsys.backend.dto.response.SysConfigResponse; +import com.labelsys.backend.service.SysConfigService; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + @Tag(name = "系统配置管理") @RestController @RequestMapping("/api/sys-configs") @@ -32,21 +33,21 @@ public class SysConfigController { private final SysConfigService sysConfigService; @Operation(summary = "创建系统配置") - @RequirePosition(UserPosition.ADMIN) + // @RequirePosition(UserPosition.ADMIN) @PostMapping public Result create(@Valid @RequestBody SaveSysConfigRequest request) { - return Result.success(sysConfigService.toResponse(sysConfigService.saveConfig(UserContext.requireUser(), request))); + return Result + .success(sysConfigService.toResponse(sysConfigService.saveConfig(UserContext.requireUser(), request))); } @Operation(summary = "更新系统配置") - @RequirePosition(UserPosition.ADMIN) + // @RequirePosition(UserPosition.ADMIN) @PutMapping("/{id}") public Result update( - @Parameter(description = "配置ID", example = "191000000000000501") - @PathVariable Long id, - @Valid @RequestBody SaveSysConfigRequest request - ) { - return Result.success(sysConfigService.toResponse(sysConfigService.updateConfig(UserContext.requireUser(), id, request))); + @Parameter(description = "配置ID", example = "191000000000000501") @PathVariable Long id, + @Valid @RequestBody UpdateSysConfigRequest request) { + return Result.success( + sysConfigService.toResponse(sysConfigService.updateConfig(UserContext.requireUser(), id, request))); } @Operation(summary = "分页查询系统配置") @@ -57,10 +58,8 @@ public class SysConfigController { @Operation(summary = "查询系统配置详情") @GetMapping("/{id}") - public Result detail( - @Parameter(description = "配置ID", example = "191000000000000501") - @PathVariable Long id - ) { + public Result + detail(@Parameter(description = "配置ID", example = "191000000000000501") @PathVariable Long id) { return Result.success(sysConfigService.getConfig(UserContext.requireUser(), id)); } } diff --git a/src/main/java/com/labelsys/backend/dto/request/SaveSysConfigRequest.java b/src/main/java/com/labelsys/backend/dto/request/SaveSysConfigRequest.java index e03e773..90fb7d2 100644 --- a/src/main/java/com/labelsys/backend/dto/request/SaveSysConfigRequest.java +++ b/src/main/java/com/labelsys/backend/dto/request/SaveSysConfigRequest.java @@ -7,7 +7,7 @@ import jakarta.validation.constraints.NotBlank; public record SaveSysConfigRequest( @Schema(description = "配置类型", example = "MODEL") @NotBlank(message = "配置类型不能为空") String configType, @Schema(description = "配置名称", example = "qwen-plus-extract") @NotBlank(message = "配置名称不能为空") String configName, - @Schema(description = "配置值", example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") @NotBlank(message = "配置值不能为空") String configValue, - @Schema(description = "配置状态", example = "ENABLED") @NotBlank(message = "配置状态不能为空") String status -) { -} + @Schema(description = "配置值", + example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") @NotBlank( + message = "配置值不能为空") String configValue, + @Schema(description = "配置状态", example = "ENABLED") String status) {} diff --git a/src/main/java/com/labelsys/backend/dto/request/SysConfigPageQuery.java b/src/main/java/com/labelsys/backend/dto/request/SysConfigPageQuery.java index e2af1be..9c47f7b 100644 --- a/src/main/java/com/labelsys/backend/dto/request/SysConfigPageQuery.java +++ b/src/main/java/com/labelsys/backend/dto/request/SysConfigPageQuery.java @@ -3,11 +3,8 @@ package com.labelsys.backend.dto.request; import io.swagger.v3.oas.annotations.media.Schema; @Schema(description = "系统配置分页查询请求") -public record SysConfigPageQuery( - @Schema(description = "配置类型", example = "MODEL") String configType, +public record SysConfigPageQuery(@Schema(description = "配置类型", example = "MODEL") String configType, @Schema(description = "配置名称", example = "qwen-plus-extract") String configName, @Schema(description = "配置状态", example = "ENABLED") String status, @Schema(description = "页码", example = "1") Integer pageNo, - @Schema(description = "每页数量", example = "10") Integer pageSize -) { -} + @Schema(description = "每页数量", example = "10") Integer pageSize) {} diff --git a/src/main/java/com/labelsys/backend/dto/request/UpdateSysConfigRequest.java b/src/main/java/com/labelsys/backend/dto/request/UpdateSysConfigRequest.java new file mode 100644 index 0000000..7b68f89 --- /dev/null +++ b/src/main/java/com/labelsys/backend/dto/request/UpdateSysConfigRequest.java @@ -0,0 +1,14 @@ +package com.labelsys.backend.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; + +@Schema(description = "更新系统配置请求") +public record UpdateSysConfigRequest( + + @Schema(description = "配置类型", example = "MODEL") String configType, + @Schema(description = "配置名称", example = "qwen-plus-extract") String configName, + @Schema(description = "配置值", + example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") @NotBlank( + message = "配置值不能为空") String configValue, + @Schema(description = "配置状态", example = "ENABLED") String status) {} diff --git a/src/main/java/com/labelsys/backend/entity/SysConfig.java b/src/main/java/com/labelsys/backend/entity/SysConfig.java index 26b5559..a8e1f02 100644 --- a/src/main/java/com/labelsys/backend/entity/SysConfig.java +++ b/src/main/java/com/labelsys/backend/entity/SysConfig.java @@ -23,6 +23,7 @@ public class SysConfig { private String configValue; private String status; private Long creatorId; + private String creatorRole; private LocalDateTime createdAt; private LocalDateTime updatedAt; } diff --git a/src/main/java/com/labelsys/backend/service/AnnotationResultService.java b/src/main/java/com/labelsys/backend/service/AnnotationResultService.java index a5f66e8..ec72bfb 100644 --- a/src/main/java/com/labelsys/backend/service/AnnotationResultService.java +++ b/src/main/java/com/labelsys/backend/service/AnnotationResultService.java @@ -1,5 +1,9 @@ package com.labelsys.backend.service; +import java.util.List; + +import org.springframework.stereotype.Service; + import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.labelsys.backend.common.ResultCode; @@ -14,11 +18,9 @@ import com.labelsys.backend.entity.SourceResource; import com.labelsys.backend.enums.RuntimeResultStatus; import com.labelsys.backend.mapper.AnnotationResultMapper; import com.labelsys.backend.mapper.SourceResourceMapper; -import com.labelsys.backend.service.DataPermissionService; -import java.util.List; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; @Slf4j @Service @@ -32,37 +34,38 @@ public class AnnotationResultService { public PageResult pageResults(LoginUser currentUser, AnnotationResultPageQuery query) { List allowedRoles = dataPermissionService.getAllowedRoles(currentUser); boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser); - - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() - .eq(AnnotationResult::getCompanyId, currentUser.companyId()) - .eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId()) - .eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId()) - .eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview, query.requiresManualReview()); - + + LambdaQueryWrapper wrapper = + new LambdaQueryWrapper().eq(AnnotationResult::getCompanyId, currentUser.companyId()) + .eq(query.taskId() != null, AnnotationResult::getTaskId, query.taskId()) + .eq(query.resourceId() != null, AnnotationResult::getResourceId, query.resourceId()) + .eq(query.requiresManualReview() != null, AnnotationResult::getRequiresManualReview, + query.requiresManualReview()); + if (shouldFilterByUserId) { wrapper.eq(AnnotationResult::getCreatorId, currentUser.userId()); } else if (!allowedRoles.isEmpty()) { wrapper.in(AnnotationResult::getCreatorRole, allowedRoles); } - + wrapper.orderByDesc(AnnotationResult::getCreatedAt); Page page = new Page<>(query.pageNo(), query.pageSize()); Page resultPage = annotationResultMapper.selectPage(page, wrapper); - List records = resultPage.getRecords().stream() - .map(this::toResponse) + List records = resultPage.getRecords().stream().map(this::toResponse) .filter(response -> query.runtimeStatus() == null || query.runtimeStatus().equals(response.runtimeStatus())) .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()); } public AnnotationResultResponse getResult(LoginUser currentUser, Long resultId) { AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId()); if (result == null) { - log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", - resultId, currentUser.companyId(), currentUser.userId()); + log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", resultId, + currentUser.companyId(), currentUser.userId()); throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在"); } return toResponse(result); @@ -71,34 +74,20 @@ public class AnnotationResultService { public AnnotationResultCompareResponse compareResult(LoginUser currentUser, Long resultId) { AnnotationResult result = annotationResultMapper.findActiveByIdAndCompanyId(resultId, currentUser.companyId()); if (result == null) { - log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", - resultId, currentUser.companyId(), currentUser.userId()); + log.warn("Result not found or cross-tenant access attempt: resultId={}, companyId={}, userId={}", resultId, + currentUser.companyId(), currentUser.userId()); throw new BusinessException(ResultCode.NOT_FOUND, "结果不存在"); } SourceResource resource = sourceResourceMapper.selectById(result.getResourceId()); - return new AnnotationResultCompareResponse( - result.getId(), - result.getTaskId(), - result.getResourceId(), - result.getQaContentJson(), - result.getDiffSummary(), - result.getQaContentStorageMode(), - result.getQaContentFilePath(), - resource == null ? null : resource.getFilePath()); + return new AnnotationResultCompareResponse(result.getId(), result.getTaskId(), result.getResourceId(), + result.getQaContentJson(), result.getDiffSummary(), result.getQaContentStorageMode(), + result.getQaContentFilePath(), resource == null ? null : resource.getFilePath()); } private AnnotationResultResponse toResponse(AnnotationResult result) { - return new AnnotationResultResponse( - result.getId(), - result.getTaskId(), - result.getResourceId(), - deriveStatus(result), - result.getRequiresManualReview(), - result.getIsDeleted(), - result.getQaContentStorageMode(), - result.getReviewComment(), - result.getReviewedAt(), - result.getCreatedAt()); + return new AnnotationResultResponse(result.getId(), result.getTaskId(), result.getResourceId(), + deriveStatus(result), result.getRequiresManualReview(), result.getIsDeleted(), + result.getQaContentStorageMode(), result.getReviewComment(), result.getReviewedAt(), result.getCreatedAt()); } private String deriveStatus(AnnotationResult result) { diff --git a/src/main/java/com/labelsys/backend/service/SysConfigService.java b/src/main/java/com/labelsys/backend/service/SysConfigService.java index 0979969..73438f9 100644 --- a/src/main/java/com/labelsys/backend/service/SysConfigService.java +++ b/src/main/java/com/labelsys/backend/service/SysConfigService.java @@ -1,6 +1,14 @@ package com.labelsys.backend.service; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.labelsys.backend.common.ResultCode; @@ -12,21 +20,18 @@ import com.labelsys.backend.dto.request.PromptConfigOptionRequest; import com.labelsys.backend.dto.request.SaveSysConfigRequest; import com.labelsys.backend.dto.request.SysConfigPageQuery; import com.labelsys.backend.dto.request.TaskModelConfigRequest; +import com.labelsys.backend.dto.request.UpdateSysConfigRequest; 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.ConfigType; +import com.labelsys.backend.enums.UserRole; import com.labelsys.backend.mapper.SysConfigMapper; import com.labelsys.backend.util.IdGenerator; -import java.util.Comparator; -import java.util.List; -import java.util.Map; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; @Slf4j @Service @@ -35,63 +40,87 @@ public class SysConfigService { private final SysConfigMapper sysConfigMapper; private final ObjectMapper objectMapper; + private final DataPermissionService dataPermissionService; @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()) - .build(); + 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(); sysConfigMapper.insert(config); - log.info("saved sys config, companyId={}, userId={}, configName={}, configType={}", - currentUser.companyId(), currentUser.userId(), request.configName(), request.configType()); + log.info("saved sys config, companyId={}, userId={}, userRole={}, configName={}, configType={}", + currentUser.companyId(), currentUser.userId(), currentUser.role().name(), request.configName(), + request.configType()); return config; } @Transactional - public SysConfig updateConfig(LoginUser currentUser, Long configId, SaveSysConfigRequest request) { + public SysConfig updateConfig(LoginUser currentUser, Long configId, UpdateSysConfigRequest request) { validateConfigType(request.configType()); SysConfig existing = getConfigEntity(currentUser, configId); - SysConfig duplicate = sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(), request.configName()); - if (duplicate != null && !duplicate.getId().equals(configId)) { - throw new BusinessException(ResultCode.CONFLICT, "配置名称已存在"); + // SysConfig duplicate = + // sysConfigMapper.findByCompanyIdAndConfigName(currentUser.companyId(), request.configName()); + // if (duplicate != null && !duplicate.getId().equals(configId)) { + // throw new BusinessException(ResultCode.CONFLICT, "配置名称已存在"); + // } + if (StringUtils.hasText(request.configName())) { + existing.setConfigName(request.configName()); + } + if (StringUtils.hasText(request.configType())) { + existing.setConfigType(request.configType()); + } + if (StringUtils.hasText(request.configValue())) { + existing.setConfigValue(request.configValue()); + } + if (StringUtils.hasText(request.status())) { + existing.setStatus(request.status()); } - existing.setConfigType(request.configType()); - existing.setConfigName(request.configName()); - existing.setConfigValue(request.configValue()); - existing.setStatus(request.status()); sysConfigMapper.updateById(existing); - log.info("updated sys config, companyId={}, userId={}, configId={}", - currentUser.companyId(), currentUser.userId(), configId); + log.info("updated sys config, companyId={}, userId={}, configId={}", currentUser.companyId(), + currentUser.userId(), configId); return existing; } public SysConfigResponse getConfig(LoginUser currentUser, Long configId) { - return toResponse(getConfigEntity(currentUser, configId)); + SysConfig config = getConfigEntity(currentUser, configId); + if (!dataPermissionService.canAccessCreator(currentUser, config.getCreatorId(), + UserRole.valueOf(config.getCreatorRole()))) { + throw new BusinessException(ResultCode.FORBIDDEN, "无权访问配置"); + } + return toResponse(config); } public PageResult pageConfigs(LoginUser currentUser, SysConfigPageQuery query) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapper() - .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()) - .orderByDesc(SysConfig::getCreatedAt); - List records = sysConfigMapper.selectList(wrapper).stream() - .sorted(Comparator.comparing(SysConfig::getCreatedAt, Comparator.nullsLast(Comparator.naturalOrder())).reversed()) - .map(this::toResponse) - .toList(); - return paginate(records, query.pageNo(), query.pageSize()); + List allowedRoles = dataPermissionService.getAllowedRoles(currentUser); + boolean shouldFilterByUserId = dataPermissionService.shouldFilterByUserId(currentUser); + + LambdaQueryWrapper wrapper = + new LambdaQueryWrapper().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()); + + if (shouldFilterByUserId) { + wrapper.eq(SysConfig::getCreatorId, currentUser.userId()); + } else if (!allowedRoles.isEmpty()) { + wrapper.in(SysConfig::getCreatorRole, allowedRoles); + } + + wrapper.orderByDesc(SysConfig::getCreatedAt); + + Page page = new Page<>(query.pageNo(), query.pageSize()); + Page resultPage = sysConfigMapper.selectPage(page, wrapper); + + List records = resultPage.getRecords().stream().map(this::toResponse).toList(); + + return new PageResult<>(records, resultPage.getTotal(), (int)resultPage.getCurrent(), + (int)resultPage.getSize()); } @Transactional @@ -113,8 +142,8 @@ public class SysConfigService { throw new BusinessException(ResultCode.BAD_REQUEST, "提示词配置不能为空"); } if (StringUtils.hasText(request.selectedConfigName())) { - SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType( - currentUser.companyId(), request.selectedConfigName(), ConfigType.PROMPT.name()); + SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType(currentUser.companyId(), + request.selectedConfigName(), ConfigType.PROMPT.name()); if (config == null) { throw new BusinessException(ResultCode.NOT_FOUND, "提示词配置不存在"); } @@ -127,12 +156,8 @@ public class SysConfigService { } public TaskModelConfigResponse toResponse(ResolvedModelConfig config) { - return new TaskModelConfigResponse( - config.configId(), - config.configName(), - config.modelName(), - config.modelUrl(), - maskSecret(config.apiKey())); + return new TaskModelConfigResponse(config.configId(), config.configName(), config.modelName(), + config.modelUrl(), maskSecret(config.apiKey())); } public TaskPromptConfigResponse toResponse(ResolvedPromptConfig config) { @@ -140,14 +165,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(), + return new SysConfigResponse(config.getId(), config.getConfigType(), config.getConfigName(), + config.getConfigValue(), config.getStatus(), config.getCreatorId(), config.getCreatedAt(), config.getUpdatedAt()); } @@ -155,45 +174,39 @@ public class SysConfigService { if (!StringUtils.hasText(configName)) { throw new BusinessException(ResultCode.BAD_REQUEST, "模型配置名称不能为空"); } - SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType( - currentUser.companyId(), configName, ConfigType.MODEL.name()); + SysConfig config = sysConfigMapper.findByCompanyIdAndConfigNameAndType(currentUser.companyId(), configName, + 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()); + return new ResolvedModelConfig(config.getId(), config.getConfigName(), configValue.modelName(), + 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())) { + if (request == null || !StringUtils.hasText(request.modelName()) || !StringUtils.hasText(request.modelUrl()) + || !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(); + 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(); sysConfigMapper.insert(config); - log.info("auto created model config, companyId={}, userId={}, configName={}", - currentUser.companyId(), currentUser.userId(), request.modelName()); - return new ResolvedModelConfig(config.getId(), config.getConfigName(), - request.modelName(), request.modelUrl(), request.apiKey()); + log.info("auto created model config, companyId={}, userId={}, configName={}", currentUser.companyId(), + currentUser.userId(), request.modelName()); + return new ResolvedModelConfig(config.getId(), config.getConfigName(), request.modelName(), + 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()); + return new ResolvedModelConfig(existing.getId(), existing.getConfigName(), configValue.modelName(), + configValue.modelUrl(), configValue.apiKey()); } private SysConfig getConfigEntity(LoginUser currentUser, Long configId) { @@ -220,10 +233,8 @@ public class SysConfigService { private String writeModelConfig(ManualModelConfigRequest request) { try { - return objectMapper.writeValueAsString(Map.of( - "modelName", request.modelName(), - "modelUrl", request.modelUrl(), - "apiKey", request.apiKey())); + return objectMapper.writeValueAsString( + Map.of("modelName", request.modelName(), "modelUrl", request.modelUrl(), "apiKey", request.apiKey())); } catch (JsonProcessingException ex) { throw new BusinessException(ResultCode.BAD_REQUEST, "模型配置值生成失败"); } @@ -239,20 +250,19 @@ public class SysConfigService { return "****" + secret.substring(secret.length() - 4); } - private PageResult paginate(List 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 toIndex = Math.min(fromIndex + actualPageSize, records.size()); - return new PageResult<>(records.subList(fromIndex, toIndex), (long) records.size(), actualPageNo, actualPageSize); - } + // private PageResult paginate(List 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 toIndex = Math.min(fromIndex + actualPageSize, records.size()); + // 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) { - } + public record ResolvedModelConfig(Long configId, String configName, String modelName, String modelUrl, + String apiKey) {} - public record ResolvedPromptConfig(Long configId, String configName, String promptText) { - } + public record ResolvedPromptConfig(Long configId, String configName, String promptText) {} } diff --git a/src/main/resources/sql/data.sql b/src/main/resources/sql/data.sql index c67b8ae..48ff6e2 100644 --- a/src/main/resources/sql/data.sql +++ b/src/main/resources/sql/data.sql @@ -33,26 +33,26 @@ INSERT INTO sys_menu (id, company_id, menu_code, menu_name, path, visible_positi ON CONFLICT DO NOTHING; INSERT INTO sys_config ( - id, company_id, config_type, config_name, config_value, status, creator_id + id, company_id, config_type, config_name, config_value, status, creator_id, creator_role ) VALUES (401, 2, 'MODEL', 'qwen-max', - '{"modelUrl":"https://api.example.com/extract","apiKey":"extract-api-key-demo"}', 'ENABLED', 2), + '{"modelUrl":"https://api.example.com/extract","apiKey":"extract-api-key-demo"}', 'ENABLED', 2, 'ENGINEER'), (402, 2, 'MODEL', 'glm-4.5', - '{"modelUrl":"https://api.example.com/verify","apiKey":"verify-api-key-demo"}', 'ENABLED', 2), + '{"modelUrl":"https://api.example.com/verify","apiKey":"verify-api-key-demo"}', 'ENABLED', 2, 'ENGINEER'), (403, 2, 'PROMPT', 'extractPrompt', - '请根据输入内容提取结构化问答对。', 'ENABLED', 2), + '请根据输入内容提取结构化问答对。', 'ENABLED', 2,'ENGINEER'), (404, 2, 'PROMPT', 'verifyPrompt', - '请核验抽取结果是否准确,并给出修正答案。', 'ENABLED', 2), + '请核验抽取结果是否准确,并给出修正答案。', 'ENABLED', 2,'ENGINEER'), (406, 2, 'MODEL', 'qwen-vl-max', - '{"modelUrl":"https://api.example.com/extract-vl","apiKey":"extract-vl-api-key-demo"}', 'ENABLED', 2), + '{"modelUrl":"https://api.example.com/extract-vl","apiKey":"extract-vl-api-key-demo"}', 'ENABLED', 2,'ENGINEER'), (407, 2, 'MODEL', 'glm-4.5v', - '{"modelUrl":"https://api.example.com/verify-vl","apiKey":"verify-vl-api-key-demo"}', 'ENABLED', 2), + '{"modelUrl":"https://api.example.com/verify-vl","apiKey":"verify-vl-api-key-demo"}', 'ENABLED', 2,'ENGINEER'), (408, 2, 'PROMPT', 'imageExtractPrompt', - '请根据输入图片内容提取结构化问答对。', 'ENABLED', 2), + '请根据输入图片内容提取结构化问答对。', 'ENABLED', 2,'ENGINEER'), (409, 2, 'PROMPT', 'imageVerifyPrompt', - '请核验图片问答结果是否准确。', 'ENABLED', 2), + '请核验图片问答结果是否准确。', 'ENABLED', 2,'ENGINEER'), (405, 2, 'SYSTEM', 'storageProvider', - '{"provider":"rustfs","defaultBucket":"source-data"}', 'ENABLED', 2) + '{"provider":"rustfs","defaultBucket":"source-data"}', 'ENABLED', 2,'ENGINEER') ON CONFLICT DO NOTHING; INSERT INTO source_resource ( diff --git a/src/main/resources/sql/schema.sql b/src/main/resources/sql/schema.sql index e9e97e1..8d7d6a2 100644 --- a/src/main/resources/sql/schema.sql +++ b/src/main/resources/sql/schema.sql @@ -98,6 +98,7 @@ CREATE TABLE IF NOT EXISTS sys_config ( config_value TEXT NOT NULL, status VARCHAR(32) NOT NULL DEFAULT 'ENABLED', creator_id BIGINT NOT NULL, + creator_role VARCHAR(50) NOT NULL DEFAULT 'EMPLOYEE', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uq_sys_config_company_name UNIQUE (company_id, config_name), @@ -113,6 +114,7 @@ COMMENT ON COLUMN sys_config.config_name IS '配置名称。MODEL 类型时存 COMMENT ON COLUMN sys_config.config_value IS '配置值。MODEL 类型建议保存 JSON,至少包含 modelName、modelUrl、apiKey;PROMPT 类型保存提示词文本;SYSTEM 类型预留后续扩展。'; COMMENT ON COLUMN sys_config.status IS '配置状态,默认 ENABLED。'; COMMENT ON COLUMN sys_config.creator_id IS '创建人用户ID。'; +COMMENT ON COLUMN sys_config.creator_role IS '创建人角色.默认 EMPLOYEE。'; COMMENT ON COLUMN sys_config.created_at IS '创建时间。'; COMMENT ON COLUMN sys_config.updated_at IS '更新时间。';