2026-04-14 13:47:38 +08:00
|
|
|
|
package com.label.controller;
|
2026-04-09 15:43:45 +08:00
|
|
|
|
|
2026-04-14 16:33:34 +08:00
|
|
|
|
import com.label.annotation.RequireRole;
|
|
|
|
|
|
import com.label.common.auth.TokenPrincipal;
|
2026-04-09 15:43:45 +08:00
|
|
|
|
import com.label.common.result.PageResult;
|
|
|
|
|
|
import com.label.common.result.Result;
|
2026-04-15 15:28:11 +08:00
|
|
|
|
import com.label.dto.ExportBatchCreateRequest;
|
|
|
|
|
|
import com.label.dto.FinetuneJobResponse;
|
2026-04-14 13:39:24 +08:00
|
|
|
|
import com.label.entity.TrainingDataset;
|
|
|
|
|
|
import com.label.entity.ExportBatch;
|
2026-04-14 13:45:15 +08:00
|
|
|
|
import com.label.service.ExportService;
|
|
|
|
|
|
import com.label.service.FinetuneService;
|
2026-04-12 00:15:59 +08:00
|
|
|
|
import io.swagger.v3.oas.annotations.Operation;
|
2026-04-15 15:28:11 +08:00
|
|
|
|
import io.swagger.v3.oas.annotations.Parameter;
|
2026-04-12 00:15:59 +08:00
|
|
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
2026-04-09 15:43:45 +08:00
|
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-14 13:31:50 +08:00
|
|
|
|
* 训练数据导出与微调接口(5 个端点,全部 ADMIN 权限)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Tag(name = "导出管理", description = "训练样本查询、导出批次和微调任务")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RestController
|
2026-04-15 10:46:57 +08:00
|
|
|
|
@RequestMapping("/label")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
|
public class ExportController {
|
|
|
|
|
|
|
|
|
|
|
|
private final ExportService exportService;
|
|
|
|
|
|
private final FinetuneService finetuneService;
|
|
|
|
|
|
|
2026-04-14 13:31:50 +08:00
|
|
|
|
/** GET /api/training/samples — 分页查询已审批可导出样本 */
|
|
|
|
|
|
@Operation(summary = "分页查询可导出训练样本")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@GetMapping("/api/training/samples")
|
2026-04-14 16:33:34 +08:00
|
|
|
|
@RequireRole("ADMIN")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
public Result<PageResult<TrainingDataset>> listSamples(
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "页码,从 1 开始", example = "1")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(defaultValue = "1") int page,
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "每页条数", example = "20")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(defaultValue = "20") int pageSize,
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "样本类型过滤,可选值:EXTRACTION、QA_GENERATION", example = "EXTRACTION")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(required = false) String sampleType,
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "是否已导出过滤", example = "false")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(required = false) Boolean exported,
|
|
|
|
|
|
HttpServletRequest request) {
|
|
|
|
|
|
return Result.success(exportService.listSamples(page, pageSize, sampleType, exported, principal(request)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 13:31:50 +08:00
|
|
|
|
/** POST /api/export/batch — 创建导出批次 */
|
|
|
|
|
|
@Operation(summary = "创建导出批次")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@PostMapping("/api/export/batch")
|
2026-04-14 16:33:34 +08:00
|
|
|
|
@RequireRole("ADMIN")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@ResponseStatus(HttpStatus.CREATED)
|
2026-04-15 15:28:11 +08:00
|
|
|
|
public Result<ExportBatch> createBatch(
|
|
|
|
|
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
|
|
|
|
|
description = "创建训练数据导出批次请求体",
|
|
|
|
|
|
required = true)
|
|
|
|
|
|
@RequestBody ExportBatchCreateRequest body,
|
2026-04-09 15:43:45 +08:00
|
|
|
|
HttpServletRequest request) {
|
2026-04-15 15:28:11 +08:00
|
|
|
|
return Result.success(exportService.createBatch(body.getSampleIds(), principal(request)));
|
2026-04-09 15:43:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 13:31:50 +08:00
|
|
|
|
/** POST /api/export/{batchId}/finetune — 提交微调任务 */
|
|
|
|
|
|
@Operation(summary = "提交微调任务")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@PostMapping("/api/export/{batchId}/finetune")
|
2026-04-14 16:33:34 +08:00
|
|
|
|
@RequireRole("ADMIN")
|
2026-04-15 15:28:11 +08:00
|
|
|
|
public Result<FinetuneJobResponse> triggerFinetune(
|
|
|
|
|
|
@Parameter(description = "导出批次 ID", example = "501")
|
|
|
|
|
|
@PathVariable Long batchId,
|
|
|
|
|
|
HttpServletRequest request) {
|
|
|
|
|
|
return Result.success(toFinetuneJobResponse(finetuneService.trigger(batchId, principal(request))));
|
2026-04-09 15:43:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 13:31:50 +08:00
|
|
|
|
/** GET /api/export/{batchId}/status — 查询微调状态 */
|
|
|
|
|
|
@Operation(summary = "查询微调状态")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@GetMapping("/api/export/{batchId}/status")
|
2026-04-14 16:33:34 +08:00
|
|
|
|
@RequireRole("ADMIN")
|
2026-04-15 15:28:11 +08:00
|
|
|
|
public Result<FinetuneJobResponse> getFinetuneStatus(
|
|
|
|
|
|
@Parameter(description = "导出批次 ID", example = "501")
|
|
|
|
|
|
@PathVariable Long batchId,
|
|
|
|
|
|
HttpServletRequest request) {
|
|
|
|
|
|
return Result.success(toFinetuneJobResponse(finetuneService.getStatus(batchId, principal(request))));
|
2026-04-09 15:43:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-14 13:31:50 +08:00
|
|
|
|
/** GET /api/export/list — 分页查询导出批次列表 */
|
|
|
|
|
|
@Operation(summary = "分页查询导出批次")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@GetMapping("/api/export/list")
|
2026-04-14 16:33:34 +08:00
|
|
|
|
@RequireRole("ADMIN")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
public Result<PageResult<ExportBatch>> listBatches(
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "页码,从 1 开始", example = "1")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(defaultValue = "1") int page,
|
2026-04-15 15:28:11 +08:00
|
|
|
|
@Parameter(description = "每页条数", example = "20")
|
2026-04-09 15:43:45 +08:00
|
|
|
|
@RequestParam(defaultValue = "20") int pageSize,
|
|
|
|
|
|
HttpServletRequest request) {
|
|
|
|
|
|
return Result.success(exportService.listBatches(page, pageSize, principal(request)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-15 15:28:11 +08:00
|
|
|
|
private FinetuneJobResponse toFinetuneJobResponse(Map<String, Object> values) {
|
|
|
|
|
|
FinetuneJobResponse response = new FinetuneJobResponse();
|
|
|
|
|
|
response.setBatchId(asLong(values.get("batchId")));
|
|
|
|
|
|
response.setGlmJobId(asString(values.get("glmJobId")));
|
|
|
|
|
|
response.setFinetuneStatus(asString(values.get("finetuneStatus")));
|
|
|
|
|
|
response.setProgress(asInteger(values.get("progress")));
|
|
|
|
|
|
response.setErrorMessage(asString(values.get("errorMessage")));
|
|
|
|
|
|
return response;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Long asLong(Object value) {
|
|
|
|
|
|
return value == null ? null : Long.parseLong(value.toString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Integer asInteger(Object value) {
|
|
|
|
|
|
return value == null ? null : Integer.parseInt(value.toString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String asString(Object value) {
|
|
|
|
|
|
return value == null ? null : value.toString();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-09 15:43:45 +08:00
|
|
|
|
private TokenPrincipal principal(HttpServletRequest request) {
|
|
|
|
|
|
return (TokenPrincipal) request.getAttribute("__token_principal__");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|