Compare commits
53 Commits
6ee34de3fe
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
954f9b14cf | ||
|
|
3619d34739 | ||
|
|
c51f645227 | ||
|
|
92335758bd | ||
|
|
b9000e18d8 | ||
|
|
a226d1f1ad | ||
|
|
965f3cf179 | ||
|
|
bb0a043a88 | ||
|
|
4a84af3023 | ||
|
|
eb68b8b13b | ||
|
|
989003243a | ||
|
|
1f9c056378 | ||
|
|
fd8e9a4a2f | ||
|
|
642a2fa99a | ||
|
|
77dae2ea49 | ||
|
|
e88f6b43ad | ||
|
|
080417f42e | ||
|
|
642200776d | ||
|
|
2410e1ab6f | ||
|
|
84ac2fe5c7 | ||
|
|
9425ff3a1e | ||
|
|
e637e8a6a4 | ||
|
|
e1c1628e29 | ||
|
|
f01c991390 | ||
|
|
4065d993e2 | ||
|
|
c3fdf96ceb | ||
|
|
d679340f3c | ||
|
|
7fbe76559c | ||
|
|
2bf06dce54 | ||
|
|
83a412d3fd | ||
|
|
cc2508d014 | ||
|
|
2ccd8f39fe | ||
|
|
9d8d06427c | ||
|
|
3d5b693d22 | ||
|
|
99ffa9d490 | ||
|
|
fbbd73c916 | ||
|
|
74674990d8 | ||
|
|
942c68989c | ||
|
|
ca81514d43 | ||
|
|
7e35cf146e | ||
|
|
343df65c69 | ||
|
|
a01a06d4c1 | ||
|
|
1314e290d5 | ||
|
|
d404c7d187 | ||
|
|
79812b2c77 | ||
|
|
5662c1fda9 | ||
|
|
849e78658d | ||
|
|
ebe8b6c7ed | ||
|
|
b3c9fdfedd | ||
|
|
298e8eb35c | ||
|
|
2beebbe469 | ||
|
|
f087687bfa | ||
|
|
9483bea005 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,6 +20,7 @@ CLAUDE.md
|
|||||||
*.iws
|
*.iws
|
||||||
.agents/
|
.agents/
|
||||||
.history/
|
.history/
|
||||||
|
.trae/
|
||||||
logs/
|
logs/
|
||||||
|
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|||||||
20
pom.xml
20
pom.xml
@@ -15,6 +15,8 @@
|
|||||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||||
<springdoc-openapi.version>2.3.0</springdoc-openapi.version>
|
<springdoc-openapi.version>2.3.0</springdoc-openapi.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -82,6 +84,19 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk18on</artifactId>
|
||||||
|
<version>1.78.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
<artifactId>s3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
<artifactId>sts</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
@@ -101,8 +116,8 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.11.0</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${java.version}</source>
|
<source>21</source>
|
||||||
<target>${java.version}</target>
|
<target>21</target>
|
||||||
<annotationProcessorPaths>
|
<annotationProcessorPaths>
|
||||||
<path>
|
<path>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
@@ -110,6 +125,7 @@
|
|||||||
<version>1.18.30</version>
|
<version>1.18.30</version>
|
||||||
</path>
|
</path>
|
||||||
</annotationProcessorPaths>
|
</annotationProcessorPaths>
|
||||||
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package com.labelsys.backend;
|
|||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@MapperScan("com.labelsys.backend.mapper")
|
@MapperScan("com.labelsys.backend.mapper")
|
||||||
|
@EnableScheduling
|
||||||
public class LabelsysBackendApplication {
|
public class LabelsysBackendApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import lombok.NoArgsConstructor;
|
|||||||
@Schema(description = "统一返回结果")
|
@Schema(description = "统一返回结果")
|
||||||
public class Result<T> {
|
public class Result<T> {
|
||||||
|
|
||||||
@Schema(description = "业务状态码")
|
@Schema(description = "业务状态码", example = "0")
|
||||||
private Integer code;
|
private Integer code;
|
||||||
|
|
||||||
@Schema(description = "返回消息")
|
@Schema(description = "返回消息", example = "success")
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
@Schema(description = "返回数据")
|
@Schema(description = "返回数据", example = "{}")
|
||||||
private T data;
|
private T data;
|
||||||
|
|
||||||
public static <T> Result<T> success() {
|
public static <T> Result<T> success() {
|
||||||
|
|||||||
@@ -3,44 +3,78 @@ package com.labelsys.backend.common.exception;
|
|||||||
import com.labelsys.backend.common.Result;
|
import com.labelsys.backend.common.Result;
|
||||||
import com.labelsys.backend.common.ResultCode;
|
import com.labelsys.backend.common.ResultCode;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.util.stream.Collectors;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.validation.BindException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理器
|
||||||
|
* <p>
|
||||||
|
* 处理策略:
|
||||||
|
* 1. 业务异常(BusinessException):记录 INFO 级别日志,返回详细错误信息给前端
|
||||||
|
* 2. 参数校验异常:记录 WARN 级别日志,返回字段错误信息
|
||||||
|
* 3. 系统异常(Exception):记录 ERROR 级别日志,隐藏详细信息,返回通用错误提示
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理业务异常
|
||||||
|
* 业务异常是预期内的错误,需要详细返回给前端
|
||||||
|
*/
|
||||||
@ExceptionHandler(BusinessException.class)
|
@ExceptionHandler(BusinessException.class)
|
||||||
public Result<Void> handleBusiness(BusinessException exception, HttpServletResponse response) {
|
public Result<Void> handleBusiness(BusinessException exception, HttpServletResponse response) {
|
||||||
|
// 记录 INFO 级别日志(业务异常属于预期内错误)
|
||||||
|
log.info("Business exception occurred: code={}, message={}",
|
||||||
|
exception.getResultCode().getCode(), exception.getMessage());
|
||||||
|
|
||||||
response.setStatus(toHttpStatus(exception.getResultCode()).value());
|
response.setStatus(toHttpStatus(exception.getResultCode()).value());
|
||||||
return new Result<>(exception.getResultCode().getCode(), exception.getMessage(), null);
|
return new Result<>(exception.getResultCode().getCode(), exception.getMessage(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理参数校验异常
|
||||||
|
*/
|
||||||
@ExceptionHandler({ MethodArgumentNotValidException.class, BindException.class })
|
@ExceptionHandler({ MethodArgumentNotValidException.class, BindException.class })
|
||||||
public Result<Void> handleValidation(Exception exception, HttpServletResponse response) {
|
public Result<Void> handleValidation(Exception exception, HttpServletResponse response) {
|
||||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
|
||||||
String message;
|
String message;
|
||||||
if (exception instanceof MethodArgumentNotValidException methodArgumentNotValidException) {
|
if (exception instanceof MethodArgumentNotValidException methodException) {
|
||||||
message = methodArgumentNotValidException.getBindingResult().getFieldErrors().stream()
|
message = methodException.getBindingResult().getFieldErrors().stream()
|
||||||
.map(error -> error.getField() + error.getDefaultMessage())
|
.map(error -> error.getField() + ": " + error.getDefaultMessage())
|
||||||
.collect(Collectors.joining("; "));
|
.collect(Collectors.joining("; "));
|
||||||
} else if (exception instanceof BindException bindException) {
|
} else if (exception instanceof BindException bindException) {
|
||||||
message = bindException.getBindingResult().getFieldErrors().stream()
|
message = bindException.getBindingResult().getFieldErrors().stream()
|
||||||
.map(error -> error.getField() + error.getDefaultMessage())
|
.map(error -> error.getField() + ": " + error.getDefaultMessage())
|
||||||
.collect(Collectors.joining("; "));
|
.collect(Collectors.joining("; "));
|
||||||
} else {
|
} else {
|
||||||
message = ResultCode.BAD_REQUEST.getMessage();
|
message = ResultCode.BAD_REQUEST.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录 WARN 级别日志
|
||||||
|
log.warn("Validation failed: {}", message);
|
||||||
|
|
||||||
|
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||||
return new Result<>(ResultCode.BAD_REQUEST.getCode(), message, null);
|
return new Result<>(ResultCode.BAD_REQUEST.getCode(), message, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理系统异常
|
||||||
|
* 系统异常是预期外的错误,需要隐藏详细信息
|
||||||
|
*/
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public Result<Void> handleUnexpected(Exception exception, HttpServletResponse response) {
|
public Result<Void> handleUnexpected(Exception exception, HttpServletResponse response) {
|
||||||
|
// 记录 ERROR 级别日志(包含完整堆栈)
|
||||||
|
log.error("Unexpected exception occurred", exception);
|
||||||
|
|
||||||
|
// 返回通用错误信息,不暴露内部细节
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
return new Result<>(ResultCode.ERROR.getCode(), exception.getMessage(), null);
|
return new Result<>(ResultCode.ERROR.getCode(), "系统内部错误,请稍后重试", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpStatus toHttpStatus(ResultCode resultCode) {
|
private HttpStatus toHttpStatus(ResultCode resultCode) {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.labelsys.backend.config;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MyBatis Plus 配置类
|
||||||
|
*
|
||||||
|
* <p>配置 MyBatis Plus 的增强功能,包括分页插件等。
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class MybatisPlusConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置 MyBatis Plus 拦截器
|
||||||
|
*
|
||||||
|
* <p>注册分页拦截器,支持 PostgreSQL 数据库的分页查询。
|
||||||
|
* 设置分页溢出处理为 false(超出页数返回空页),最大分页限制为 200 条。
|
||||||
|
*
|
||||||
|
* @return MyBatis Plus 拦截器
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
|
|
||||||
|
// 创建分页拦截器,指定数据库类型为 PostgreSQL
|
||||||
|
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.POSTGRE_SQL);
|
||||||
|
|
||||||
|
// 设置分页溢出处理:false 表示超出页数时返回空页,不进行页码修正
|
||||||
|
paginationInnerInterceptor.setOverflow(false);
|
||||||
|
|
||||||
|
// 设置最大分页限制:200 条,防止一次性查询过多数据
|
||||||
|
paginationInnerInterceptor.setMaxLimit(200L);
|
||||||
|
|
||||||
|
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
||||||
|
|
||||||
|
return interceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.labelsys.backend.config;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||||
|
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||||
|
import software.amazon.awssdk.regions.Region;
|
||||||
|
import software.amazon.awssdk.services.s3.S3Client;
|
||||||
|
import software.amazon.awssdk.services.s3.S3Configuration;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储配置类
|
||||||
|
*
|
||||||
|
* <p>配置 AWS S3 客户端,用于与对象存储服务(如 MinIO、AWS S3)进行交互。
|
||||||
|
* 通过配置属性读取 endpoint、region、accessKey、secretKey 等参数。
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EnableConfigurationProperties(ObjectStorageProperties.class)
|
||||||
|
public class ObjectStorageConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储配置属性
|
||||||
|
*/
|
||||||
|
private final ObjectStorageProperties properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并配置 S3 客户端
|
||||||
|
*
|
||||||
|
* 配置内容包括:
|
||||||
|
* - endpoint: 对象存储服务地址
|
||||||
|
* - region: 区域标识
|
||||||
|
* - credentials: 访问密钥(accessKey 和 secretKey)
|
||||||
|
* - pathStyleAccess: 是否启用路径风格访问
|
||||||
|
*
|
||||||
|
* @return 配置完成的 S3 客户端
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public S3Client s3Client() {
|
||||||
|
return S3Client.builder()
|
||||||
|
// 设置自定义 endpoint(支持非 AWS S3 服务如 MinIO)
|
||||||
|
.endpointOverride(URI.create(properties.getEndpoint()))
|
||||||
|
// 设置区域
|
||||||
|
.region(Region.of(properties.getRegion()))
|
||||||
|
// 设置凭证提供者
|
||||||
|
.credentialsProvider(StaticCredentialsProvider.create(
|
||||||
|
AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey())))
|
||||||
|
// 配置路径风格访问(对于 MinIO 等自建存储服务通常需要启用)
|
||||||
|
.serviceConfiguration(S3Configuration.builder()
|
||||||
|
.pathStyleAccessEnabled(properties.isPathStyleAccess())
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.labelsys.backend.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储配置属性类
|
||||||
|
*
|
||||||
|
* 用于读取 `labelsys.object-storage` 前缀的配置项,
|
||||||
|
* 包括连接信息和存储桶配置。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "labelsys.object-storage")
|
||||||
|
public class ObjectStorageProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储服务地址
|
||||||
|
*/
|
||||||
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域标识
|
||||||
|
*/
|
||||||
|
private String region;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问密钥 ID
|
||||||
|
*/
|
||||||
|
private String accessKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问密钥
|
||||||
|
*/
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用路径风格访问(默认 true,适用于 MinIO 等自建存储)
|
||||||
|
*/
|
||||||
|
private boolean pathStyleAccess = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 源文件存储桶名称
|
||||||
|
*/
|
||||||
|
private String sourceBucket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产物存储桶名称
|
||||||
|
*/
|
||||||
|
private String artifactBucket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出文件存储桶名称
|
||||||
|
*/
|
||||||
|
private String exportBucket;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,9 +5,19 @@ import io.swagger.v3.oas.models.info.Info;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAPI (Swagger) 配置类
|
||||||
|
*
|
||||||
|
* 配置 API 文档的基本信息,包括标题、版本和描述。
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class OpenApiConfig {
|
public class OpenApiConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建 OpenAPI 文档配置
|
||||||
|
*
|
||||||
|
* @return OpenAPI 配置实例
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public OpenAPI labelsysOpenApi() {
|
public OpenAPI labelsysOpenApi() {
|
||||||
return new OpenAPI().info(new Info()
|
return new OpenAPI().info(new Info()
|
||||||
@@ -15,4 +25,5 @@ public class OpenApiConfig {
|
|||||||
.version("0.0.1")
|
.version("0.0.1")
|
||||||
.description("公司、员工、认证、岗位权限和数据权限接口"));
|
.description("公司、员工、认证、岗位权限和数据权限接口"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,22 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全配置类
|
||||||
|
*
|
||||||
|
* 配置安全相关的 Bean,如密码编码器等。
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityBeanConfig {
|
public class SecurityBeanConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建密码编码器
|
||||||
|
*
|
||||||
|
* <p>使用 BCrypt 算法对密码进行加密,BCrypt 是一种安全的密码哈希算法,
|
||||||
|
* 具有自动加盐和可配置的计算复杂度特性。
|
||||||
|
*
|
||||||
|
* @return BCryptPasswordEncoder 实例
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public PasswordEncoder passwordEncoder() {
|
public PasswordEncoder passwordEncoder() {
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
|
|||||||
@@ -6,14 +6,30 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web MVC 配置类
|
||||||
|
* <p>
|
||||||
|
* 实现 WebMvcConfigurer 接口,配置 Spring MVC 拦截器等功能。
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class WebMvcConfig implements WebMvcConfigurer {
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证拦截器
|
||||||
|
*/
|
||||||
private final AuthInterceptor authInterceptor;
|
private final AuthInterceptor authInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册拦截器
|
||||||
|
* <p>
|
||||||
|
* 将认证拦截器注册到拦截器链中,拦截所有 `/api/**` 路径的请求。
|
||||||
|
*
|
||||||
|
* @param registry 拦截器注册器
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
registry.addInterceptor(authInterceptor).addPathPatterns("/api/**");
|
registry.addInterceptor(authInterceptor).addPathPatterns("/api/**");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,37 +7,28 @@ import com.labelsys.backend.enums.UserRole;
|
|||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@Schema(description = "当前登录用户上下文")
|
@Schema(description = "当前登录用户上下文")
|
||||||
public record LoginUser(
|
public record LoginUser(@Schema(description = "用户ID") Long userId, @Schema(description = "公司ID") Long companyId,
|
||||||
@Schema(description = "用户ID") Long userId,
|
@Schema(description = "公司编码") String companyCode, @Schema(description = "公司名称") String companyName,
|
||||||
@Schema(description = "公司ID") Long companyId,
|
|
||||||
@Schema(description = "公司编码") String companyCode,
|
|
||||||
@Schema(description = "公司名称") String companyName,
|
|
||||||
@Schema(description = "手机号") String phone,
|
@Schema(description = "手机号") String phone,
|
||||||
@Schema(description = "用户名,可为空", example = "alpha-reviewer") String username,
|
@Schema(description = "用户名,可为空", example = "alpha-reviewer") String username,
|
||||||
@Schema(description = "真实姓名") String realName,
|
@Schema(description = "真实姓名") String realName,
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") UserPosition position,
|
@Schema(
|
||||||
|
description = "岗位,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员、SUPER_ADMIN系统管理员") UserPosition position,
|
||||||
@Schema(description = "是否必须修改密码") boolean mustChangePassword,
|
@Schema(description = "是否必须修改密码") boolean mustChangePassword,
|
||||||
@Schema(description = "会话版本") Integer sessionVersion
|
@Schema(description = "会话版本") Integer sessionVersion) {
|
||||||
) {
|
|
||||||
|
|
||||||
public static LoginUser from(SysUser user, SysCompany company) {
|
public static LoginUser from(SysUser user, SysCompany company) {
|
||||||
return new LoginUser(
|
return new LoginUser(user.getId(), company.getId(), company.getCompanyCode(), company.getCompanyName(),
|
||||||
user.getId(),
|
user.getPhone(), user.getUsername(), user.getRealName(), user.getRole(), user.getPosition(),
|
||||||
company.getId(),
|
Boolean.TRUE.equals(user.getMustChangePassword()), user.getSessionVersion());
|
||||||
company.getCompanyCode(),
|
|
||||||
company.getCompanyName(),
|
|
||||||
user.getPhone(),
|
|
||||||
user.getUsername(),
|
|
||||||
user.getRealName(),
|
|
||||||
user.getRole(),
|
|
||||||
user.getPosition(),
|
|
||||||
Boolean.TRUE.equals(user.getMustChangePassword()),
|
|
||||||
user.getSessionVersion()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlatformAdmin() {
|
// public boolean isPlatformAdmin() {
|
||||||
return "PLATFORM".equals(companyCode) && position == UserPosition.ADMIN;
|
// return "PLATFORM".equals(companyCode) && position == UserPosition.ADMIN;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public boolean isSuperAdmin() {
|
||||||
|
return position == UserPosition.SUPER_ADMIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,61 @@
|
|||||||
package com.labelsys.backend.context;
|
package com.labelsys.backend.context;
|
||||||
|
|
||||||
import com.labelsys.backend.common.exception.UnauthorizedException;
|
import com.labelsys.backend.common.exception.UnauthorizedException;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户上下文管理类
|
||||||
|
*
|
||||||
|
* 使用 ThreadLocal 存储当前线程的登录用户信息,
|
||||||
|
* 实现请求级别的用户上下文传递。
|
||||||
|
*/
|
||||||
public final class UserContext {
|
public final class UserContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户上下文持有者,存储当前线程的登录用户
|
||||||
|
*/
|
||||||
private static final ThreadLocal<LoginUser> HOLDER = new ThreadLocal<>();
|
private static final ThreadLocal<LoginUser> HOLDER = new ThreadLocal<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私有构造函数,防止实例化
|
||||||
|
*/
|
||||||
private UserContext() {
|
private UserContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置当前登录用户
|
||||||
|
*
|
||||||
|
* @param loginUser 登录用户信息
|
||||||
|
*/
|
||||||
public static void set(LoginUser loginUser) {
|
public static void set(LoginUser loginUser) {
|
||||||
HOLDER.set(loginUser);
|
HOLDER.set(loginUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户
|
||||||
|
*
|
||||||
|
* @return 当前登录用户的 Optional 对象,未登录时返回 empty
|
||||||
|
*/
|
||||||
public static Optional<LoginUser> get() {
|
public static Optional<LoginUser> get() {
|
||||||
return Optional.ofNullable(HOLDER.get());
|
return Optional.ofNullable(HOLDER.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户,未登录时抛出异常
|
||||||
|
*
|
||||||
|
* @return 当前登录用户
|
||||||
|
* @throws UnauthorizedException 未登录或登录已过期时抛出
|
||||||
|
*/
|
||||||
public static LoginUser requireUser() {
|
public static LoginUser requireUser() {
|
||||||
return get().orElseThrow(() -> new UnauthorizedException("未登录或登录已过期"));
|
return get().orElseThrow(() -> new UnauthorizedException("未登录或登录已过期"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理用户上下文
|
||||||
|
*
|
||||||
|
* 在请求结束时调用,防止 ThreadLocal 内存泄漏
|
||||||
|
*/
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
HOLDER.remove();
|
HOLDER.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
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.request.SaveAgentConfigRequest;
|
||||||
|
import com.labelsys.backend.dto.response.AgentConfigListResponse;
|
||||||
|
import com.labelsys.backend.entity.AnnotationAgentConfig;
|
||||||
|
import com.labelsys.backend.enums.UserPosition;
|
||||||
|
import com.labelsys.backend.service.AnnotationAgentConfigService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "Agent配置管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/agent-configs")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AnnotationAgentConfigController {
|
||||||
|
|
||||||
|
private final AnnotationAgentConfigService annotationAgentConfigService;
|
||||||
|
|
||||||
|
@Operation(summary = "保存Agent配置")
|
||||||
|
@PostMapping
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<AgentConfigListResponse> save(@Valid @RequestBody SaveAgentConfigRequest request) {
|
||||||
|
return Result.success(
|
||||||
|
annotationAgentConfigService.saveAgentConfigs(UserContext.requireUser(), request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取公司Agent对应配置列表:模型配置和提示词配置")
|
||||||
|
@GetMapping
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<AgentConfigListResponse> list() {
|
||||||
|
var user = UserContext.requireUser();
|
||||||
|
return Result.success(
|
||||||
|
annotationAgentConfigService.getAgentConfigsForCompany(user.companyId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.labelsys.backend.controller;
|
||||||
|
|
||||||
|
import com.labelsys.backend.context.UserContext;
|
||||||
|
import com.labelsys.backend.dto.common.PageResult;
|
||||||
|
import com.labelsys.backend.dto.request.AnnotationResultHistoryPageQuery;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationResultHistoryDetailResponse;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationResultHistoryResponse;
|
||||||
|
import com.labelsys.backend.service.AnnotationResultArchiveService;
|
||||||
|
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.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/annotation-result-history")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "标注结果归档管理", description = "标注结果归档历史查询接口")
|
||||||
|
public class AnnotationResultArchiveController {
|
||||||
|
|
||||||
|
private final AnnotationResultArchiveService annotationResultArchiveService;
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询归档历史")
|
||||||
|
@GetMapping
|
||||||
|
public ResponseEntity<PageResult<AnnotationResultHistoryResponse>> pageHistory(
|
||||||
|
@Valid AnnotationResultHistoryPageQuery query) {
|
||||||
|
return ResponseEntity.ok(annotationResultArchiveService.pageHistory(UserContext.requireUser(), query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询归档历史详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<AnnotationResultHistoryDetailResponse> getHistory(
|
||||||
|
@Parameter(description = "历史记录ID", example = "901")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return ResponseEntity.ok(annotationResultArchiveService.getHistory(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Operation(summary = "加载归档文件内容")
|
||||||
|
// @GetMapping("/{id}/content")
|
||||||
|
// public ResponseEntity<FileContentResponse> loadFileContent(
|
||||||
|
// @Parameter(description = "历史记录ID", example = "901")
|
||||||
|
// @PathVariable Long id) {
|
||||||
|
// return ResponseEntity.ok(annotationResultArchiveService.loadFileContent(UserContext.requireUser(), id));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.labelsys.backend.controller;
|
||||||
|
|
||||||
|
import com.labelsys.backend.annotation.RequirePosition;
|
||||||
|
import com.labelsys.backend.context.UserContext;
|
||||||
|
import com.labelsys.backend.dto.common.PageResult;
|
||||||
|
import com.labelsys.backend.dto.request.AnnotationResultPageQuery;
|
||||||
|
import com.labelsys.backend.dto.request.MergeReviewResultRequest;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationResultCompareResponse;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationResultDetailResponse;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationResultResponse;
|
||||||
|
import com.labelsys.backend.enums.UserPosition;
|
||||||
|
import com.labelsys.backend.service.AnnotationResultService;
|
||||||
|
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.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/annotation-results")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Tag(name = "标注结果管理", description = "标注结果相关接口")
|
||||||
|
public class AnnotationResultController {
|
||||||
|
|
||||||
|
private final AnnotationResultService annotationResultService;
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询标注结果")
|
||||||
|
@GetMapping
|
||||||
|
public ResponseEntity<PageResult<AnnotationResultResponse>> pageResults(
|
||||||
|
@Valid AnnotationResultPageQuery query) {
|
||||||
|
return ResponseEntity.ok(annotationResultService.pageResults(UserContext.requireUser(), query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询标注结果详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<AnnotationResultDetailResponse> getResult(
|
||||||
|
@Parameter(description = "结果ID", example = "191000000000000401")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return ResponseEntity.ok(annotationResultService.getResult(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询结果比对信息,REVIEWER岗位以上可操作")
|
||||||
|
@GetMapping("/{id}/compare")
|
||||||
|
@RequirePosition(UserPosition.REVIEWER)
|
||||||
|
public ResponseEntity<AnnotationResultCompareResponse> compareResult(
|
||||||
|
@Parameter(description = "结果ID", example = "191000000000000401")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return ResponseEntity.ok(annotationResultService.compareResult(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "提交合并审核结果,REVIEWER岗位以上可操作")
|
||||||
|
@PostMapping("/{id}/merge")
|
||||||
|
@RequirePosition(UserPosition.REVIEWER)
|
||||||
|
public ResponseEntity<Void> mergeReviewResult(
|
||||||
|
@Parameter(description = "结果ID", example = "191000000000000401")
|
||||||
|
@PathVariable Long id,
|
||||||
|
@Valid @RequestBody MergeReviewResultRequest request) {
|
||||||
|
annotationResultService.mergeReviewResult(UserContext.requireUser(), id, request);
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.labelsys.backend.controller;
|
||||||
|
|
||||||
|
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.AnnotationTaskPageQuery;
|
||||||
|
import com.labelsys.backend.dto.request.CreateAnnotationTaskRequest;
|
||||||
|
import com.labelsys.backend.dto.request.UpdateAnnotationTaskRequest;
|
||||||
|
import com.labelsys.backend.dto.response.AnnotationTaskResponse;
|
||||||
|
import com.labelsys.backend.service.AnnotationTaskService;
|
||||||
|
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.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
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.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "标注任务管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/annotation-tasks")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AnnotationTaskController {
|
||||||
|
|
||||||
|
private final AnnotationTaskService annotationTaskService;
|
||||||
|
|
||||||
|
@Operation(summary = "创建标注任务")
|
||||||
|
@PostMapping
|
||||||
|
public Result<AnnotationTaskResponse> create(@Valid @RequestBody CreateAnnotationTaskRequest request) {
|
||||||
|
return Result.success(annotationTaskService.createTask(UserContext.requireUser(), request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "更新标注任务")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<AnnotationTaskResponse> update(
|
||||||
|
@Parameter(description = "任务ID", example = "191000000000000301") @PathVariable Long id,
|
||||||
|
@Valid @RequestBody UpdateAnnotationTaskRequest request) {
|
||||||
|
return Result.success(annotationTaskService.updateTask(UserContext.requireUser(), id, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询标注任务")
|
||||||
|
@GetMapping
|
||||||
|
public Result<PageResult<AnnotationTaskResponse>> page(@ParameterObject AnnotationTaskPageQuery query) {
|
||||||
|
return Result.success(annotationTaskService.pageTasks(UserContext.requireUser(), query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询标注任务详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<AnnotationTaskResponse> detail(
|
||||||
|
@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) {
|
||||||
|
annotationTaskService.deleteTask(UserContext.requireUser(), id);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import com.labelsys.backend.dto.response.CurrentUserResponse;
|
|||||||
import com.labelsys.backend.dto.response.LoginResponse;
|
import com.labelsys.backend.dto.response.LoginResponse;
|
||||||
import com.labelsys.backend.service.AuthService;
|
import com.labelsys.backend.service.AuthService;
|
||||||
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.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -33,7 +34,10 @@ public class AuthController {
|
|||||||
|
|
||||||
@Operation(summary = "根据手机号查询可登录公司")
|
@Operation(summary = "根据手机号查询可登录公司")
|
||||||
@GetMapping("/companies")
|
@GetMapping("/companies")
|
||||||
public Result<List<CompanyOptionResponse>> listCompanies(@RequestParam String phone) {
|
public Result<List<CompanyOptionResponse>> listCompanies(
|
||||||
|
@Parameter(description = "手机号", example = "13800138000")
|
||||||
|
@RequestParam String phone
|
||||||
|
) {
|
||||||
return Result.success(authService.listAvailableCompanies(phone));
|
return Result.success(authService.listAvailableCompanies(phone));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +56,10 @@ public class AuthController {
|
|||||||
|
|
||||||
@Operation(summary = "退出登录")
|
@Operation(summary = "退出登录")
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
public Result<Void> logout(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorization) {
|
public Result<Void> logout(
|
||||||
|
@Parameter(description = "Bearer 访问令牌", example = "Bearer eyJhbGciOiJIUzI1NiJ9.demo.token")
|
||||||
|
@RequestHeader(HttpHeaders.AUTHORIZATION) String authorization
|
||||||
|
) {
|
||||||
authService.logout(extractToken(authorization));
|
authService.logout(extractToken(authorization));
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.labelsys.backend.dto.response.UserResponse;
|
|||||||
import com.labelsys.backend.enums.UserPosition;
|
import com.labelsys.backend.enums.UserPosition;
|
||||||
import com.labelsys.backend.service.UserService;
|
import com.labelsys.backend.service.UserService;
|
||||||
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.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -45,14 +46,22 @@ public class CompanyUserController {
|
|||||||
|
|
||||||
@Operation(summary = "修改员工角色和岗位")
|
@Operation(summary = "修改员工角色和岗位")
|
||||||
@PutMapping("/{userId}/assignment")
|
@PutMapping("/{userId}/assignment")
|
||||||
public Result<Void> updateAssignment(@PathVariable Long userId, @Valid @RequestBody UpdateUserAssignmentRequest request) {
|
public Result<Void> updateAssignment(
|
||||||
|
@Parameter(description = "用户ID", example = "191000000000000021")
|
||||||
|
@PathVariable Long userId,
|
||||||
|
@Valid @RequestBody UpdateUserAssignmentRequest request
|
||||||
|
) {
|
||||||
userService.updateAssignment(UserContext.requireUser(), userId, request);
|
userService.updateAssignment(UserContext.requireUser(), userId, request);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改员工状态")
|
@Operation(summary = "修改员工状态")
|
||||||
@PutMapping("/{userId}/status")
|
@PutMapping("/{userId}/status")
|
||||||
public Result<Void> updateStatus(@PathVariable Long userId, @Valid @RequestBody UpdateUserStatusRequest request) {
|
public Result<Void> updateStatus(
|
||||||
|
@Parameter(description = "用户ID", example = "191000000000000021")
|
||||||
|
@PathVariable Long userId,
|
||||||
|
@Valid @RequestBody UpdateUserStatusRequest request
|
||||||
|
) {
|
||||||
userService.updateStatus(UserContext.requireUser(), userId, request);
|
userService.updateStatus(UserContext.requireUser(), userId, request);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import com.labelsys.backend.annotation.RequirePosition;
|
|||||||
import com.labelsys.backend.common.Result;
|
import com.labelsys.backend.common.Result;
|
||||||
import com.labelsys.backend.context.UserContext;
|
import com.labelsys.backend.context.UserContext;
|
||||||
import com.labelsys.backend.dto.request.CreateCompanyAdminRequest;
|
import com.labelsys.backend.dto.request.CreateCompanyAdminRequest;
|
||||||
|
import com.labelsys.backend.dto.request.CreateSystemEngineerAdminRequest;
|
||||||
import com.labelsys.backend.dto.request.UpdateUserStatusRequest;
|
import com.labelsys.backend.dto.request.UpdateUserStatusRequest;
|
||||||
import com.labelsys.backend.dto.response.UserResponse;
|
import com.labelsys.backend.dto.response.UserResponse;
|
||||||
import com.labelsys.backend.enums.UserPosition;
|
import com.labelsys.backend.enums.UserPosition;
|
||||||
import com.labelsys.backend.service.UserService;
|
import com.labelsys.backend.service.UserService;
|
||||||
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.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,7 +27,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Tag(name = "平台公司管理员管理")
|
@Tag(name = "平台公司管理员管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/platform/company-admins")
|
@RequestMapping("/api/platform/company-admins")
|
||||||
@RequirePosition(UserPosition.ADMIN)
|
@RequirePosition(UserPosition.SUPER_ADMIN)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PlatformCompanyAdminController {
|
public class PlatformCompanyAdminController {
|
||||||
|
|
||||||
@@ -33,20 +35,37 @@ public class PlatformCompanyAdminController {
|
|||||||
|
|
||||||
@Operation(summary = "查询指定公司管理员列表")
|
@Operation(summary = "查询指定公司管理员列表")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Result<List<UserResponse>> listCompanyAdmins(@RequestParam Long companyId) {
|
public Result<List<UserResponse>> listCompanyAdmins(
|
||||||
|
@Parameter(description = "公司ID", example = "191000000000000001")
|
||||||
|
@RequestParam Long companyId
|
||||||
|
) {
|
||||||
return Result.success(userService.listCompanyAdmins(UserContext.requireUser(), companyId).stream().map(UserResponse::from).toList());
|
return Result.success(userService.listCompanyAdmins(UserContext.requireUser(), companyId).stream().map(UserResponse::from).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询所有公司用户列表")
|
||||||
|
@GetMapping("/all")
|
||||||
|
public Result<List<UserResponse>> listAllUsers() {
|
||||||
|
return Result.success(userService.listAllUsers(UserContext.requireUser()).stream().map(UserResponse::from).toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "创建公司管理员")
|
@Operation(summary = "创建公司管理员")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public Result<UserResponse> createCompanyAdmin(@Valid @RequestBody CreateCompanyAdminRequest request) {
|
public Result<UserResponse> createCompanyAdmin(@Valid @RequestBody CreateCompanyAdminRequest request) {
|
||||||
return Result.success(UserResponse.from(userService.createCompanyAdmin(UserContext.requireUser(), request)));
|
return Result.success(UserResponse.from(userService.createCompanyAdmin(UserContext.requireUser(), request)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "创建系统管理员")
|
||||||
|
@PostMapping("/system-engineer")
|
||||||
|
public Result<UserResponse> createSystemEngineerAdmin(@Valid @RequestBody CreateSystemEngineerAdminRequest request) {
|
||||||
|
return Result.success(UserResponse.from(userService.createSystemEngineerAdmin(UserContext.requireUser(), request)));
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "修改公司管理员状态")
|
@Operation(summary = "修改公司管理员状态")
|
||||||
@PutMapping("/{companyId}/{userId}/status")
|
@PutMapping("/{companyId}/{userId}/status")
|
||||||
public Result<Void> updateCompanyAdminStatus(
|
public Result<Void> updateCompanyAdminStatus(
|
||||||
|
@Parameter(description = "公司ID", example = "191000000000000001")
|
||||||
@PathVariable Long companyId,
|
@PathVariable Long companyId,
|
||||||
|
@Parameter(description = "用户ID", example = "191000000000000021")
|
||||||
@PathVariable Long userId,
|
@PathVariable Long userId,
|
||||||
@Valid @RequestBody UpdateUserStatusRequest request
|
@Valid @RequestBody UpdateUserStatusRequest request
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.labelsys.backend.dto.response.CompanyResponse;
|
|||||||
import com.labelsys.backend.enums.UserPosition;
|
import com.labelsys.backend.enums.UserPosition;
|
||||||
import com.labelsys.backend.service.CompanyService;
|
import com.labelsys.backend.service.CompanyService;
|
||||||
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.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -24,7 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Tag(name = "平台公司管理")
|
@Tag(name = "平台公司管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/platform/companies")
|
@RequestMapping("/api/platform/companies")
|
||||||
@RequirePosition(UserPosition.ADMIN)
|
@RequirePosition(UserPosition.SUPER_ADMIN)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PlatformCompanyController {
|
public class PlatformCompanyController {
|
||||||
|
|
||||||
@@ -44,7 +45,11 @@ public class PlatformCompanyController {
|
|||||||
|
|
||||||
@Operation(summary = "修改公司状态")
|
@Operation(summary = "修改公司状态")
|
||||||
@PutMapping("/{companyId}/status")
|
@PutMapping("/{companyId}/status")
|
||||||
public Result<Void> updateCompanyStatus(@PathVariable Long companyId, @Valid @RequestBody UpdateCompanyStatusRequest request) {
|
public Result<Void> updateCompanyStatus(
|
||||||
|
@Parameter(description = "公司ID", example = "191000000000000001")
|
||||||
|
@PathVariable Long companyId,
|
||||||
|
@Valid @RequestBody UpdateCompanyStatusRequest request
|
||||||
|
) {
|
||||||
companyService.updateStatus(UserContext.requireUser(), companyId, request);
|
companyService.updateStatus(UserContext.requireUser(), companyId, request);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package com.labelsys.backend.controller;
|
||||||
|
|
||||||
|
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.SaveImageBboxRequest;
|
||||||
|
import com.labelsys.backend.dto.request.SourceResourcePageQuery;
|
||||||
|
import com.labelsys.backend.dto.request.SourceUploadRequest;
|
||||||
|
import com.labelsys.backend.dto.response.ImageBboxResponse;
|
||||||
|
import com.labelsys.backend.dto.response.SourceResourceResponse;
|
||||||
|
import com.labelsys.backend.dto.response.SourceUploadResponse;
|
||||||
|
import com.labelsys.backend.entity.SourceResource;
|
||||||
|
import com.labelsys.backend.service.SourceResourceService;
|
||||||
|
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.http.HttpHeaders;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "资源管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/source-resources")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SourceResourceController {
|
||||||
|
|
||||||
|
private final SourceResourceService sourceResourceService;
|
||||||
|
|
||||||
|
@Operation(summary = "上传资源")
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public Result<SourceUploadResponse> upload(@ParameterObject @ModelAttribute SourceUploadRequest request) {
|
||||||
|
return Result.success(sourceResourceService.upload(UserContext.requireUser(), request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询资源")
|
||||||
|
@GetMapping
|
||||||
|
public Result<PageResult<SourceResourceResponse>> page(
|
||||||
|
@ParameterObject @ModelAttribute SourceResourcePageQuery query) {
|
||||||
|
return Result.success(sourceResourceService.pageResources(UserContext.requireUser(), query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询资源详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<SourceResourceResponse> detail(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id
|
||||||
|
) {
|
||||||
|
return Result.success(sourceResourceService.getResource(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除资源")
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public Result<Void> delete(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id
|
||||||
|
) {
|
||||||
|
sourceResourceService.deleteResource(UserContext.requireUser(), id);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "下载资源")
|
||||||
|
@GetMapping("/{id}/download")
|
||||||
|
public ResponseEntity<byte[]> downloadResource(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id
|
||||||
|
) {
|
||||||
|
var currentUser = UserContext.requireUser();
|
||||||
|
byte[] resourceData = sourceResourceService.downloadResource(currentUser, id);
|
||||||
|
|
||||||
|
// 获取资源信息以确定Content-Type
|
||||||
|
SourceResource resource = sourceResourceService.getResourceEntity(id);
|
||||||
|
String contentType = sourceResourceService.getContentType(resource);
|
||||||
|
|
||||||
|
return ResponseEntity.ok()
|
||||||
|
.header(HttpHeaders.CONTENT_TYPE, contentType)
|
||||||
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getResourceName() + "\"")
|
||||||
|
.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(resource.getFileSize()))
|
||||||
|
.body(resourceData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加新接口
|
||||||
|
@Operation(summary = "查询图片资源BBOX标注")
|
||||||
|
@GetMapping("/{id}/bbox")
|
||||||
|
public Result<ImageBboxResponse> getImageBbox(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id
|
||||||
|
) {
|
||||||
|
return Result.success(sourceResourceService.getImageBbox(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "保存图片资源BBOX标注")
|
||||||
|
@PostMapping("/{id}/bbox")
|
||||||
|
public Result<ImageBboxResponse> saveImageBbox(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id,
|
||||||
|
@Valid @RequestBody SaveImageBboxRequest request
|
||||||
|
) {
|
||||||
|
return Result.success(sourceResourceService.saveImageBbox(UserContext.requireUser(), id, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除图片资源BBOX标注")
|
||||||
|
@DeleteMapping("/{id}/bbox")
|
||||||
|
public Result<Void> deleteImageBbox(
|
||||||
|
@Parameter(description = "资源ID", example = "191000000000000101")
|
||||||
|
@PathVariable Long id
|
||||||
|
) {
|
||||||
|
sourceResourceService.deleteImageBbox(UserContext.requireUser(), id);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
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.request.UpdateSysConfigRequest;
|
||||||
|
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;
|
||||||
|
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.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "系统配置管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/sys-configs")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SysConfigController {
|
||||||
|
|
||||||
|
private final SysConfigService sysConfigService;
|
||||||
|
|
||||||
|
@Operation(summary = "创建系统配置")
|
||||||
|
@PostMapping
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<SysConfigResponse> create(@Valid @RequestBody SaveSysConfigRequest request) {
|
||||||
|
return Result
|
||||||
|
.success(sysConfigService.toResponse(sysConfigService.saveConfig(UserContext.requireUser(), request)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "更新系统配置")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<SysConfigResponse> update(
|
||||||
|
@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 = "分页查询系统配置")
|
||||||
|
@GetMapping
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<PageResult<SysConfigResponse>> page(@ParameterObject SysConfigPageQuery query) {
|
||||||
|
return Result.success(sysConfigService.pageConfigs(UserContext.requireUser(), query));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询配置详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
@RequirePosition(UserPosition.ADMIN) // 仅限ADMIN及以上岗位访问
|
||||||
|
public Result<SysConfigResponse> detail(
|
||||||
|
@Parameter(description = "配置ID", example = "191000000000000501") @PathVariable Long id) {
|
||||||
|
return Result.success(sysConfigService.getConfigDetail(UserContext.requireUser(), id));
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/com/labelsys/backend/dto/LlmConfigModel.java
Normal file
20
src/main/java/com/labelsys/backend/dto/LlmConfigModel.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.labelsys.backend.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "大模型配置模型")
|
||||||
|
@Data
|
||||||
|
public class LlmConfigModel {
|
||||||
|
@Schema(description = "多模态类型枚举")
|
||||||
|
private String llmType;
|
||||||
|
|
||||||
|
@Schema(description = "模型名称")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@Schema(description = "模型调用地址")
|
||||||
|
private String modelUrl;
|
||||||
|
|
||||||
|
@Schema(description = "API密钥,加密存储")
|
||||||
|
private String apiKey;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.labelsys.backend.dto.common;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "分页结果")
|
||||||
|
public record PageResult<T>(
|
||||||
|
@Schema(description = "当前页记录", example = "[]") List<T> records,
|
||||||
|
@Schema(description = "总记录数", example = "2") Long total,
|
||||||
|
@Schema(description = "页码", example = "1") Integer pageNo,
|
||||||
|
@Schema(description = "每页数量", example = "10") Integer pageSize
|
||||||
|
) {
|
||||||
|
public static <T> PageResult<T> from(IPage<T> page) {
|
||||||
|
return new PageResult<>(page.getRecords(), page.getTotal(), (int) page.getCurrent(), (int) page.getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// AnnotationResultHistoryPageQuery.java
|
||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "归档历史分页查询")
|
||||||
|
public record AnnotationResultHistoryPageQuery(
|
||||||
|
@Schema(description = "任务ID", example = "701") Long taskId,
|
||||||
|
@Schema(description = "资源ID", example = "601") Long resourceId,
|
||||||
|
@Schema(description = "页码", example = "1") Integer pageNo,
|
||||||
|
@Schema(description = "每页数量", example = "10") Integer pageSize
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果分页查询请求")
|
||||||
|
public record AnnotationResultPageQuery(
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "是否需要人工审核", example = "true") Boolean requiresManualReview,
|
||||||
|
@Schema(description = "运行态状态", example = "MANUAL_REVIEW_PENDING") String runtimeStatus,
|
||||||
|
@Schema(description = "页码", example = "1") Integer pageNo,
|
||||||
|
@Schema(description = "每页数量", example = "10") Integer pageSize
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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") TaskType taskType,
|
||||||
|
@Schema(description = "任务状态", example = "PENDING") String taskStatus,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||||
|
@Schema(description = "页码", example = "1") Integer pageNo,
|
||||||
|
@Schema(description = "每页数量", example = "10") Integer pageSize
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "BBOX坐标对象")
|
||||||
|
public record BboxCoordinate(
|
||||||
|
@Schema(description = "BBOX标识", example = "bbox_001") String id,
|
||||||
|
@NotNull @Schema(description = "左上角X坐标", example = "100") Integer x,
|
||||||
|
@NotNull @Schema(description = "左上角Y坐标", example = "50") Integer y,
|
||||||
|
@NotNull @Schema(description = "宽度", example = "200") Integer width,
|
||||||
|
@NotNull @Schema(description = "高度", example = "150") Integer height,
|
||||||
|
@Schema(description = "标注标签", example = "车辆") String label
|
||||||
|
//@Schema(description = "置信度", example = "0.95") Double confidence
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -5,8 +5,8 @@ import jakarta.validation.constraints.NotBlank;
|
|||||||
|
|
||||||
@Schema(description = "修改密码请求")
|
@Schema(description = "修改密码请求")
|
||||||
public record ChangePasswordRequest(
|
public record ChangePasswordRequest(
|
||||||
@Schema(description = "旧密码") @NotBlank(message = "不能为空") String oldPassword,
|
@Schema(description = "旧密码", example = "P@ssw0rd!") @NotBlank(message = "不能为空") String oldPassword,
|
||||||
@Schema(description = "新密码") @NotBlank(message = "不能为空") String newPassword,
|
@Schema(description = "新密码", example = "N3wP@ssw0rd!") @NotBlank(message = "不能为空") String newPassword,
|
||||||
@Schema(description = "确认新密码") @NotBlank(message = "不能为空") String confirmPassword
|
@Schema(description = "确认新密码", example = "N3wP@ssw0rd!") @NotBlank(message = "不能为空") String confirmPassword
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.TaskType;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "创建标注任务请求")
|
||||||
|
public record CreateAnnotationTaskRequest(
|
||||||
|
@Schema(description = "任务名称", example = "运输文档问答抽取任务") @NotBlank(message = "任务名称不能为空") String taskName,
|
||||||
|
@Schema(description = "任务类型", defaultValue = "EXTRACT_QA", example = "EXTRACT_QA") @NotNull(message = "任务类型不能为空") TaskType taskType,
|
||||||
|
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") @NotEmpty(message = "资源列表不能为空") List<Long> resourceIds) {
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
@Schema(description = "创建公司管理员请求")
|
@Schema(description = "创建公司管理员请求")
|
||||||
public record CreateCompanyAdminRequest(
|
public record CreateCompanyAdminRequest(
|
||||||
@Schema(description = "公司ID") @NotNull(message = "不能为空") Long companyId,
|
@Schema(description = "公司ID", example = "191000000000000001") @NotNull(message = "不能为空") Long companyId,
|
||||||
@Schema(description = "手机号") @NotBlank(message = "不能为空") String phone,
|
@Schema(description = "手机号", example = "13800138001") @NotBlank(message = "不能为空") String phone,
|
||||||
@Schema(description = "用户名,前端展示用,可为空", example = "platform-ops") String username,
|
@Schema(description = "用户名,前端展示用,可为空", example = "platform-ops") String username,
|
||||||
@Schema(description = "真实姓名") @NotBlank(message = "不能为空") String realName
|
@Schema(description = "真实姓名", example = "平台运维") @NotBlank(message = "不能为空") String realName
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotBlank;
|
|||||||
|
|
||||||
@Schema(description = "创建公司请求")
|
@Schema(description = "创建公司请求")
|
||||||
public record CreateCompanyRequest(
|
public record CreateCompanyRequest(
|
||||||
@Schema(description = "公司编码") @NotBlank(message = "不能为空") String companyCode,
|
@Schema(description = "公司编码", example = "ALPHA") @NotBlank(message = "不能为空") String companyCode,
|
||||||
@Schema(description = "公司名称") @NotBlank(message = "不能为空") String companyName
|
@Schema(description = "公司名称", example = "阿尔法标注有限公司") @NotBlank(message = "不能为空") String companyName
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
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) {
|
||||||
|
}
|
||||||
@@ -8,10 +8,10 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
@Schema(description = "创建员工请求")
|
@Schema(description = "创建员工请求")
|
||||||
public record CreateUserRequest(
|
public record CreateUserRequest(
|
||||||
@Schema(description = "手机号") @NotBlank(message = "不能为空") String phone,
|
@Schema(description = "手机号", example = "13800138002") @NotBlank(message = "不能为空") String phone,
|
||||||
@Schema(description = "用户名,前端展示用,可为空", example = "alpha-admin") String username,
|
@Schema(description = "用户名,前端展示用,可为空", example = "alpha-admin") String username,
|
||||||
@Schema(description = "真实姓名") @NotBlank(message = "不能为空") String realName,
|
@Schema(description = "真实姓名", example = "张审核") @NotBlank(message = "不能为空") String realName,
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") @NotNull(message = "不能为空") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师", example = "EMPLOYEE") @NotNull(message = "不能为空") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") @NotNull(message = "不能为空") UserPosition position
|
@Schema(description = "岗位,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员", example = "ANNOTATOR") @NotNull(message = "不能为空") UserPosition position
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import jakarta.validation.constraints.NotBlank;
|
|||||||
|
|
||||||
@Schema(description = "登录请求")
|
@Schema(description = "登录请求")
|
||||||
public record LoginRequest(
|
public record LoginRequest(
|
||||||
@Schema(description = "手机号") @NotBlank(message = "不能为空") String phone,
|
@Schema(description = "手机号", example = "平台管理员:13900000000") @NotBlank(message = "不能为空") String phone,
|
||||||
@Schema(description = "公司编码") @NotBlank(message = "不能为空") String companyCode,
|
@Schema(description = "公司编码", example = "平台编号:PLATFORM") @NotBlank(message = "不能为空") String companyCode,
|
||||||
@Schema(description = "登录密码") @NotBlank(message = "不能为空") String password
|
@Schema(description = "登录密码", example = "平台密码:admin@123") @NotBlank(message = "不能为空") String password
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "合并审核结果请求")
|
||||||
|
public record MergeReviewResultRequest(
|
||||||
|
@Schema(description = "合并后的答案映射,key为qa记录ID,value为合并后的答案")
|
||||||
|
Map<String, String> mergedAnswers,
|
||||||
|
|
||||||
|
@Schema(description = "每条QA记录的审核评论映射,key为qa记录ID,value为审核评论")
|
||||||
|
Map<String, String> reviewComments
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "保存Agent配置请求: 请求体中agentConfigs为map结构,key为AgentType枚举值,值为用户选择的模型配置ID和提示词配置ID")
|
||||||
|
@Data
|
||||||
|
public class SaveAgentConfigRequest {
|
||||||
|
|
||||||
|
@Schema(description = "Agent配置映射,key为AgentType枚举类型code,value为配置信息。支持的Agent类型:RedTeamAgent(红黑对抗)、AnalyzerAgent(分析)、IndustryClassifierAgent(行业识别)、HallucinationDetectorAgent(幻觉检测)、ReviewerAgent(审查)、regenerator(再次生成)")
|
||||||
|
@NotNull(message = "Agent配置不能为空")
|
||||||
|
private Map<String, AgentConfigItem> agentConfigs;
|
||||||
|
|
||||||
|
@Schema(description = "Agent配置项")
|
||||||
|
@Data
|
||||||
|
public static class AgentConfigItem {
|
||||||
|
|
||||||
|
@Schema(description = "模型配置ID", example = "191000000000000501")
|
||||||
|
@NotNull(message = "模型配置ID不能为空")
|
||||||
|
private Long modelConfigId;
|
||||||
|
|
||||||
|
@Schema(description = "提示词配置ID", example = "191000000000000502")
|
||||||
|
private Long promptConfigId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "保存图片BBOX请求")
|
||||||
|
public record SaveImageBboxRequest(
|
||||||
|
@NotEmpty @Schema(description = "BBOX坐标列表")
|
||||||
|
@Valid List<BboxCoordinate> bboxes,
|
||||||
|
@Schema(description = "备注") String remark
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -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 SaveSysConfigRequest(
|
||||||
|
@Schema(description = "配置类型: MODEL-大模型配置、PROMPT-提示词配置、SYSTEM-其他配置项", example = "MODEL") @NotBlank(message = "配置类型不能为空") String configType,
|
||||||
|
@Schema(description = "配置名称", example = "qwen-plus-extract") @NotBlank(message = "配置名称不能为空") String configName,
|
||||||
|
@Schema(description = "配置值, 当configType为model时候,configValue为大模型配置的json字符串,configType为其他值时,configValue为普通字符串",
|
||||||
|
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) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "资源分页查询请求")
|
||||||
|
public record SourceResourcePageQuery(
|
||||||
|
@Schema(description = "关键字", example = "运输") String keyword,
|
||||||
|
@Schema(description = "资源类型", example = "TEXT") String resourceType,
|
||||||
|
@Schema(description = "页码(可选,与pageSize同时提供时启用分页)", example = "1") Integer pageNo,
|
||||||
|
@Schema(description = "每页数量(可选,与pageNo同时提供时启用分页)", example = "10") Integer pageSize
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* 判断是否需要分页
|
||||||
|
* @return true表示需要分页,false表示查询全部
|
||||||
|
*/
|
||||||
|
public boolean needPagination() {
|
||||||
|
return pageNo != null && pageSize != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "资源上传请求")
|
||||||
|
public class SourceUploadRequest {
|
||||||
|
|
||||||
|
@Schema(description = "资源名称", example = "2026年4月运输巡检记录")
|
||||||
|
private String resourceName;
|
||||||
|
|
||||||
|
@Schema(description = "资源类型:TEXT、IMAGE、VIDEO", example = "TEXT")
|
||||||
|
private String resourceType;
|
||||||
|
|
||||||
|
@Schema(description = "备注", example = "第一批导入样本")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "上传文件", example = "inspection-record.txt")
|
||||||
|
private MultipartFile file;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
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,
|
||||||
|
@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) {}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.labelsys.backend.dto.request;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.TaskType;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "更新标注任务请求")
|
||||||
|
public record UpdateAnnotationTaskRequest(
|
||||||
|
@Schema(description = "任务类型", example = "EXTRACT_QA") TaskType taskType,
|
||||||
|
@Schema(description = "资源ID列表", example = "[191000000000000101,191000000000000102]") List<Long> resourceIds) {
|
||||||
|
}
|
||||||
@@ -6,6 +6,6 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
@Schema(description = "修改公司状态请求")
|
@Schema(description = "修改公司状态请求")
|
||||||
public record UpdateCompanyStatusRequest(
|
public record UpdateCompanyStatusRequest(
|
||||||
@Schema(description = "公司状态,枚举值:ENABLED启用、DISABLED禁用") @NotNull(message = "不能为空") CompanyStatus status
|
@Schema(description = "公司状态,枚举值:ENABLED启用、DISABLED禁用", example = "ENABLED") @NotNull(message = "不能为空") CompanyStatus status
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = "配置类型: MODEL-大模型配置、PROMPT-提示词配置、SYSTEM-其他配置项\", example = \"MODEL\"", example = "MODEL") String configType,
|
||||||
|
@Schema(description = "配置名称", example = "qwen-plus-extract") String configName,
|
||||||
|
@Schema(description = "配置值, 当configType为model时候,configValue为大模型配置的json字符串,configType为其他值时,configValue为普通字符串",
|
||||||
|
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) {}
|
||||||
@@ -7,7 +7,7 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
@Schema(description = "修改员工角色岗位请求")
|
@Schema(description = "修改员工角色岗位请求")
|
||||||
public record UpdateUserAssignmentRequest(
|
public record UpdateUserAssignmentRequest(
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") @NotNull(message = "不能为空") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师", example = "EMPLOYEE") @NotNull(message = "不能为空") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") @NotNull(message = "不能为空") UserPosition position
|
@Schema(description = "岗位,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员", example = "REVIEWER") @NotNull(message = "不能为空") UserPosition position
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
|
|
||||||
@Schema(description = "修改员工状态请求")
|
@Schema(description = "修改员工状态请求")
|
||||||
public record UpdateUserStatusRequest(
|
public record UpdateUserStatusRequest(
|
||||||
@Schema(description = "用户状态,枚举值:ENABLED启用、DISABLED禁用") @NotNull(message = "不能为空") UserStatus status
|
@Schema(description = "用户状态,枚举值:ENABLED启用、DISABLED禁用", example = "DISABLED") @NotNull(message = "不能为空") UserStatus status
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "Agent配置信息响应")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class AgentConfigInfoResponse {
|
||||||
|
|
||||||
|
@Schema(description = "配置ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "Agent类型。支持的Agent类型:RedTeamAgent(红黑对抗)、AnalyzerAgent(分析)、IndustryClassifierAgent(行业识别)、HallucinationDetectorAgent(幻觉检测)、ReviewerAgent(审查)、regenerator(再次生成)")
|
||||||
|
private String agentType;
|
||||||
|
|
||||||
|
@Schema(description = "模型配置信息")
|
||||||
|
private ModelConfigInfo modelConfig;
|
||||||
|
|
||||||
|
@Schema(description = "Prompt配置信息")
|
||||||
|
private PromptConfigInfo promptConfig;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "模型配置信息")
|
||||||
|
public static class ModelConfigInfo {
|
||||||
|
@Schema(description = "模型配置ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "模型名称")
|
||||||
|
private String modelName;
|
||||||
|
|
||||||
|
@Schema(description = "模型URL")
|
||||||
|
private String modelUrl;
|
||||||
|
|
||||||
|
@Schema(description = "API密钥")
|
||||||
|
private String apiKey;
|
||||||
|
|
||||||
|
@Schema(description = "LLM类型")
|
||||||
|
private String llmType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "Prompt配置信息")
|
||||||
|
public static class PromptConfigInfo {
|
||||||
|
@Schema(description = "Prompt配置ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "Prompt文本")
|
||||||
|
private String promptText;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "Agent配置列表响应:返回结果agentConfigs为公司Agent配置Map,key为AgentType枚举值(固定六个Agent类型key), 值为Agent配置对象")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class AgentConfigListResponse {
|
||||||
|
|
||||||
|
@Schema(description = "Agent配置映射,key为AgentType枚举类型code,value为Agent配置信息。AgentType类型code:RedTeamAgent(红黑对抗)、AnalyzerAgent(分析)、IndustryClassifierAgent(行业识别)、HallucinationDetectorAgent(幻觉检测)、ReviewerAgent(审查)、regenerator(再次生成)")
|
||||||
|
private Map<String, AgentConfigInfoResponse> agentConfigs;
|
||||||
|
|
||||||
|
@Schema(description = "公司所有Prompt配置列表")
|
||||||
|
private List<AgentConfigInfoResponse.PromptConfigInfo> promptConfigs;
|
||||||
|
|
||||||
|
@Schema(description = "公司所有Model配置列表")
|
||||||
|
private List<AgentConfigInfoResponse.ModelConfigInfo> modelConfigs;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果比对响应")
|
||||||
|
public record AnnotationResultCompareResponse(
|
||||||
|
@Schema(description = "结果ID", example = "191000000000000401") Long id,
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
|
||||||
|
@Schema(description = "问答对列表") List<QaRecord> qaRecords,
|
||||||
|
@Schema(description = "差异列表") List<DiffRecord> diffRecords
|
||||||
|
) {
|
||||||
|
|
||||||
|
@Schema(description = "问答记录")
|
||||||
|
public record QaRecord(
|
||||||
|
@Schema(description = "记录ID", example = "qa_001") String id,
|
||||||
|
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||||
|
@Schema(description = "问题", example = "运输时效是多久?") String question,
|
||||||
|
@Schema(description = "答案", example = "3天") String answer,
|
||||||
|
@Schema(description = "是否需要审核", example = "true") Boolean requiresReview,
|
||||||
|
@Schema(description = "源片段信息") SourceSegments sourceSegments,
|
||||||
|
@Schema(description = "问题分类") String questionCategory,
|
||||||
|
@Schema(description = "评分") Scores scores,
|
||||||
|
@Schema(description = "审核评论") String reviewComment
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "源片段信息")
|
||||||
|
public record SourceSegments(
|
||||||
|
@Schema(description = "片段内容") String segment,
|
||||||
|
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||||
|
@Schema(description = "块标题") String chunkTitle,
|
||||||
|
@Schema(description = "块内容") String chunkContent
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "差异记录")
|
||||||
|
public record DiffRecord(
|
||||||
|
@Schema(description = "关联的问答记录ID", example = "qa_001") String qaId,
|
||||||
|
@Schema(description = "问题", example = "运输时效是多久?") String question,
|
||||||
|
@Schema(description = "提取模型答案", example = "3天") String extractAnswer,
|
||||||
|
@Schema(description = "校验模型答案", example = "72小时") String verifyAnswer,
|
||||||
|
@Schema(description = "差异原因", example = "时间单位不一致") String diffReason,
|
||||||
|
@Schema(description = "合并后的最终答案", example = "72小时(3天)") String mergedAnswer,
|
||||||
|
@Schema(description = "问题分类") String questionCategory,
|
||||||
|
@Schema(description = "评分") Scores scores
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "评分结构")
|
||||||
|
public record Scores(
|
||||||
|
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||||
|
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||||
|
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||||
|
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||||
|
@Schema(description = "信任度", example = "0.64") Double trust
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.AnnotationResultStatus;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果详情响应(包含文件内容)")
|
||||||
|
public record AnnotationResultDetailResponse(
|
||||||
|
@Schema(description = "结果ID", example = "191000000000000401") Long id,
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "任务名称", example = "产品说明书标注") String taskName,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "资源名称", example = "产品A说明书.pdf") String resourceName,
|
||||||
|
@Schema(description = "标注结果状态", example = "MANUAL_REVIEW_PENDING") AnnotationResultStatus runtimeStatus,
|
||||||
|
@Schema(description = "是否需要人工审核", example = "true") Boolean requiresManualReview,
|
||||||
|
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||||
|
|
||||||
|
// 文件路径
|
||||||
|
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/801.json") String qaContentFilePath,
|
||||||
|
@Schema(description = "差异摘要文件路径", example = "annotation-results/2/diff/801.json") String diffSummaryFilePath,
|
||||||
|
|
||||||
|
// 文件内容
|
||||||
|
@Schema(description = "问答内容") QaContentDto qaContent,
|
||||||
|
@Schema(description = "差异摘要(需要审核时有值)") DiffContentDto diffSummary,
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T10:40:00") LocalDateTime createdAt
|
||||||
|
) {
|
||||||
|
@Schema(description = "问答内容结构")
|
||||||
|
public record QaContentDto(
|
||||||
|
@Schema(description = "问答记录列表") List<QaRecordDto> records
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "问答记录")
|
||||||
|
public record QaRecordDto(
|
||||||
|
@Schema(description = "记录ID", example = "q1") String id,
|
||||||
|
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||||
|
@Schema(description = "问题", example = "产品重量是多少?") String question,
|
||||||
|
@Schema(description = "答案", example = "5kg") String answer,
|
||||||
|
@Schema(description = "是否需要审核", example = "false") Boolean requiresReview,
|
||||||
|
@Schema(description = "源片段信息") SourceSegmentsDto sourceSegments,
|
||||||
|
@Schema(description = "问题分类") String questionCategory,
|
||||||
|
@Schema(description = "评分") ScoresDto scores,
|
||||||
|
@Schema(description = "审核评论") String reviewComment
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "源片段信息")
|
||||||
|
public record SourceSegmentsDto(
|
||||||
|
@Schema(description = "片段内容") String segment,
|
||||||
|
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||||
|
@Schema(description = "块标题") String chunkTitle,
|
||||||
|
@Schema(description = "块内容") String chunkContent
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "差异摘要结构")
|
||||||
|
public record DiffContentDto(
|
||||||
|
@Schema(description = "差异记录列表") List<DiffRecordDto> records
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "差异记录")
|
||||||
|
public record DiffRecordDto(
|
||||||
|
@Schema(description = "关联问答ID", example = "q2") String qaId,
|
||||||
|
@Schema(description = "问题", example = "保修期多久?") String question,
|
||||||
|
@Schema(description = "抽取答案", example = "2年") String extractAnswer,
|
||||||
|
@Schema(description = "验证答案", example = "3年") String verifyAnswer,
|
||||||
|
@Schema(description = "差异原因", example = "抽取与验证结果不一致") String diffReason,
|
||||||
|
@Schema(description = "合并后答案") String mergedAnswer,
|
||||||
|
@Schema(description = "问题分类") String questionCategory,
|
||||||
|
@Schema(description = "评分") ScoresDto scores
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "评分结构")
|
||||||
|
public record ScoresDto(
|
||||||
|
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||||
|
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||||
|
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||||
|
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||||
|
@Schema(description = "信任度", example = "0.64") Double trust
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "归档历史详情响应")
|
||||||
|
public record AnnotationResultHistoryDetailResponse(
|
||||||
|
@Schema(description = "历史记录ID", example = "901") Long id,
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "任务名称", example = "产品说明书标注") String taskName,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "资源名称", example = "产品A说明书.pdf") String resourceName,
|
||||||
|
|
||||||
|
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/802.json") String qaContentFilePath,
|
||||||
|
@Schema(description = "问答内容") QaContentDto qaContent,
|
||||||
|
@Schema(description = "归档原因", example = "审核通过后归档") String archiveReason,
|
||||||
|
@Schema(description = "归档操作人ID", example = "5") Long archivedBy,
|
||||||
|
@Schema(description = "归档时间", example = "2026-05-06T10:30:00") LocalDateTime archivedAt,
|
||||||
|
@Schema(description = "创建时间", example = "2026-05-06T10:30:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "审核人ID,自动归档时为null", example = "5") Long reviewerId,
|
||||||
|
@Schema(description = "审核人姓名,自动归档时为auto", example = "张三") String reviewerName
|
||||||
|
) {
|
||||||
|
@Schema(description = "问答内容结构")
|
||||||
|
public record QaContentDto(
|
||||||
|
@Schema(description = "问答记录列表") List<QaRecordDto> records
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "问答记录")
|
||||||
|
public record QaRecordDto(
|
||||||
|
@Schema(description = "记录ID", example = "q1") String id,
|
||||||
|
@Schema(description = "批次ID", example = "50") Long batchId,
|
||||||
|
@Schema(description = "问题", example = "产品重量是多少?") String question,
|
||||||
|
@Schema(description = "答案", example = "5kg") String answer,
|
||||||
|
@Schema(description = "是否需要审核", example = "false") Boolean requiresReview,
|
||||||
|
@Schema(description = "源片段信息") SourceSegmentsDto sourceSegments,
|
||||||
|
@Schema(description = "问题分类") String questionCategory,
|
||||||
|
@Schema(description = "评分") ScoresDto scores,
|
||||||
|
@Schema(description = "审核评论") String reviewComment
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "源片段信息")
|
||||||
|
public record SourceSegmentsDto(
|
||||||
|
@Schema(description = "片段内容") String segment,
|
||||||
|
@Schema(description = "块索引", example = "0") Integer chunkIndex,
|
||||||
|
@Schema(description = "块标题") String chunkTitle,
|
||||||
|
@Schema(description = "块内容") String chunkContent
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Schema(description = "评分结构")
|
||||||
|
public record ScoresDto(
|
||||||
|
@Schema(description = "相似度", example = "0.7") Double similarity,
|
||||||
|
@Schema(description = "置信度1", example = "0.9") Double confidence1,
|
||||||
|
@Schema(description = "置信度2", example = "0.85") Double confidence2,
|
||||||
|
@Schema(description = "幻觉检测", example = "0.9") Double hallucination,
|
||||||
|
@Schema(description = "信任度", example = "0.64") Double trust
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// AnnotationResultHistoryResponse.java
|
||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "归档历史响应")
|
||||||
|
public record AnnotationResultHistoryResponse(
|
||||||
|
@Schema(description = "历史记录ID, 不显示", example = "901") Long id,
|
||||||
|
//@Schema(description = "来源结果ID", example = "802") Long sourceResultId,
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "任务名称", example = "产品说明书标注") String taskName, // 新增
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "资源名称", example = "产品A说明书.pdf") String resourceName, // 新增
|
||||||
|
|
||||||
|
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/802.json") String qaContentFilePath,
|
||||||
|
@Schema(description = "归档原因", example = "审核通过后归档") String archiveReason,
|
||||||
|
@Schema(description = "归档操作人ID", example = "5") Long archivedBy,
|
||||||
|
@Schema(description = "归档时间", example = "2026-05-06T10:30:00") LocalDateTime archivedAt,
|
||||||
|
@Schema(description = "创建时间", example = "2026-05-06T10:30:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "审核人ID,自动归档时为null", example = "5") Long reviewerId,
|
||||||
|
@Schema(description = "审核人姓名,自动归档时为auto", example = "张三") String reviewerName
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.AnnotationResultStatus;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果响应")
|
||||||
|
public record AnnotationResultResponse(
|
||||||
|
@Schema(description = "结果ID", example = "191000000000000401") Long id,
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long taskId,
|
||||||
|
@Schema(description = "任务名称", example = "产品说明书标注") String taskName, // 新增
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long resourceId,
|
||||||
|
@Schema(description = "资源名称", example = "产品A说明书.pdf") String resourceName, // 新增
|
||||||
|
@Schema(description = "标注结果状态", example = "MANUAL_REVIEW_PENDING") AnnotationResultStatus runtimeStatus,
|
||||||
|
@Schema(description = "是否需要人工审核", example = "true") Boolean requiresManualReview,
|
||||||
|
@Schema(description = "是否已删除", example = "false") Boolean isDeleted,
|
||||||
|
@Schema(description = "问答内容文件路径", example = "annotation-results/2/qa/801.json") String qaContentFilePath,
|
||||||
|
@Schema(description = "差异摘要文件路径", example = "annotation-results/2/diff/801.json") String diffSummaryFilePath,
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T10:40:00") LocalDateTime createdAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import com.labelsys.backend.enums.TaskType;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "标注任务响应")
|
||||||
|
public record AnnotationTaskResponse(
|
||||||
|
@Schema(description = "任务ID", example = "191000000000000301") Long id,
|
||||||
|
@Schema(description = "任务名称", example = "运输文档问答抽取任务") String taskName,
|
||||||
|
@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 = "2026-04-27T10:20:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "更新时间", example = "2026-04-27T10:30:00") LocalDateTime updatedAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "可登录公司选项")
|
@Schema(description = "可登录公司选项")
|
||||||
public record CompanyOptionResponse(
|
public record CompanyOptionResponse(
|
||||||
@Schema(description = "公司ID") Long companyId,
|
@Schema(description = "公司ID", example = "191000000000000001") Long companyId,
|
||||||
@Schema(description = "公司编码") String companyCode,
|
@Schema(description = "公司编码", example = "ALPHA") String companyCode,
|
||||||
@Schema(description = "公司名称") String companyName
|
@Schema(description = "公司名称", example = "阿尔法标注有限公司") String companyName
|
||||||
) {
|
) {
|
||||||
public static CompanyOptionResponse from(SysCompany company) {
|
public static CompanyOptionResponse from(SysCompany company) {
|
||||||
return new CompanyOptionResponse(company.getId(), company.getCompanyCode(), company.getCompanyName());
|
return new CompanyOptionResponse(company.getId(), company.getCompanyCode(), company.getCompanyName());
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "公司响应")
|
@Schema(description = "公司响应")
|
||||||
public record CompanyResponse(
|
public record CompanyResponse(
|
||||||
@Schema(description = "公司ID") Long companyId,
|
@Schema(description = "公司ID", example = "191000000000000001") Long companyId,
|
||||||
@Schema(description = "公司编码") String companyCode,
|
@Schema(description = "公司编码", example = "ALPHA") String companyCode,
|
||||||
@Schema(description = "公司名称") String companyName,
|
@Schema(description = "公司名称", example = "阿尔法标注有限公司") String companyName,
|
||||||
@Schema(description = "公司状态,枚举值:ENABLED启用、DISABLED禁用") CompanyStatus status
|
@Schema(description = "公司状态,枚举值:ENABLED启用、DISABLED禁用", example = "ENABLED") CompanyStatus status
|
||||||
) {
|
) {
|
||||||
public static CompanyResponse from(SysCompany company) {
|
public static CompanyResponse from(SysCompany company) {
|
||||||
return new CompanyResponse(company.getId(), company.getCompanyCode(), company.getCompanyName(), company.getStatus());
|
return new CompanyResponse(company.getId(), company.getCompanyCode(), company.getCompanyName(), company.getStatus());
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "当前登录用户响应")
|
@Schema(description = "当前登录用户响应")
|
||||||
public record CurrentUserResponse(
|
public record CurrentUserResponse(
|
||||||
@Schema(description = "用户ID") Long userId,
|
@Schema(description = "用户ID", example = "191000000000000021") Long userId,
|
||||||
@Schema(description = "公司ID") Long companyId,
|
@Schema(description = "公司ID", example = "191000000000000001") Long companyId,
|
||||||
@Schema(description = "公司编码") String companyCode,
|
@Schema(description = "公司编码", example = "ALPHA") String companyCode,
|
||||||
@Schema(description = "公司名称") String companyName,
|
@Schema(description = "公司名称", example = "阿尔法标注有限公司") String companyName,
|
||||||
@Schema(description = "手机号") String phone,
|
@Schema(description = "手机号", example = "13800138002") String phone,
|
||||||
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
||||||
@Schema(description = "真实姓名") String realName,
|
@Schema(description = "真实姓名", example = "张审核") String realName,
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师", example = "EMPLOYEE") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") UserPosition position,
|
@Schema(description = "岗位,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员", example = "REVIEWER") UserPosition position,
|
||||||
@Schema(description = "是否必须修改密码") boolean mustChangePassword
|
@Schema(description = "是否必须修改密码", example = "false") boolean mustChangePassword
|
||||||
) {
|
) {
|
||||||
public static CurrentUserResponse from(LoginUser loginUser) {
|
public static CurrentUserResponse from(LoginUser loginUser) {
|
||||||
return new CurrentUserResponse(
|
return new CurrentUserResponse(
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.labelsys.backend.dto.response;
|
|
||||||
|
|
||||||
import com.labelsys.backend.entity.BizDataRecord;
|
|
||||||
import com.labelsys.backend.enums.UserRole;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
@Schema(description = "数据记录响应")
|
|
||||||
public record DataRecordResponse(
|
|
||||||
@Schema(description = "记录ID") Long id,
|
|
||||||
@Schema(description = "公司ID") Long companyId,
|
|
||||||
@Schema(description = "创建人ID") Long creatorId,
|
|
||||||
@Schema(description = "创建人角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole creatorRole,
|
|
||||||
@Schema(description = "记录名称") String recordName
|
|
||||||
) {
|
|
||||||
public static DataRecordResponse from(BizDataRecord record) {
|
|
||||||
return new DataRecordResponse(
|
|
||||||
record.getId(),
|
|
||||||
record.getCompanyId(),
|
|
||||||
record.getCreatorId(),
|
|
||||||
record.getCreatorRole(),
|
|
||||||
record.getRecordName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "文件内容响应")
|
||||||
|
public record FileContentResponse(
|
||||||
|
@Schema(description = "文件路径", example = "annotation-results/2/qa/801.json") String filePath,
|
||||||
|
@Schema(description = "文件内容") String content,
|
||||||
|
@Schema(description = "文件大小(字节)", example = "1024") Integer size
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "图片BBOX响应")
|
||||||
|
public record ImageBboxResponse(
|
||||||
|
@Schema(description = "bbox标识ID", example = "191000000000000101") Long id,
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000102") Long resourceId,
|
||||||
|
@Schema(description = "资源文件路径", example = "/data/images/car.jpg") String filepath,
|
||||||
|
@Schema(description = "BBOX坐标列表") List<BboxCoordinateResponse> bboxes,
|
||||||
|
@Schema(description = "备注", example = "车辆检测标注") String remark,
|
||||||
|
@Schema(description = "创建人名称", example = "张审核") String creatorName,
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T10:00:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "更新时间", example = "2026-04-27T10:05:00") LocalDateTime updatedAt
|
||||||
|
) {
|
||||||
|
|
||||||
|
@Schema(description = "BBOX坐标响应对象")
|
||||||
|
public record BboxCoordinateResponse(
|
||||||
|
@Schema(description = "BBOX标识", example = "bbox_001") String id,
|
||||||
|
@Schema(description = "左上角X坐标", example = "100") Integer x,
|
||||||
|
@Schema(description = "左上角Y坐标", example = "50") Integer y,
|
||||||
|
@Schema(description = "宽度", example = "200") Integer width,
|
||||||
|
@Schema(description = "高度", example = "150") Integer height,
|
||||||
|
@Schema(description = "标注标签", example = "车辆") String label
|
||||||
|
// @Schema(description = "置信度", example = "0.95") Double confidence
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,14 +8,14 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "登录响应")
|
@Schema(description = "登录响应")
|
||||||
public record LoginResponse(
|
public record LoginResponse(
|
||||||
@Schema(description = "访问令牌") String token,
|
@Schema(description = "访问令牌", example = "eyJhbGciOiJIUzI1NiJ9.demo.token") String token,
|
||||||
@Schema(description = "当前公司信息") CompanyOptionResponse company,
|
@Schema(description = "当前公司信息", example = "{\"companyId\":191000000000000001,\"companyCode\":\"ALPHA\",\"companyName\":\"阿尔法标注有限公司\"}") CompanyOptionResponse company,
|
||||||
@Schema(description = "手机号") String phone,
|
@Schema(description = "手机号", example = "13800138002") String phone,
|
||||||
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
||||||
@Schema(description = "真实姓名") String realName,
|
@Schema(description = "真实姓名", example = "张审核") String realName,
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师", example = "EMPLOYEE") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") UserPosition position,
|
@Schema(description = "岗位枚举,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN公司管理员、SUPER_ADMIN超级管理员", example = "REVIEWER") UserPosition position,
|
||||||
@Schema(description = "是否必须修改密码") boolean mustChangePassword
|
@Schema(description = "是否必须修改密码", example = "false") boolean mustChangePassword
|
||||||
) {
|
) {
|
||||||
public static LoginResponse from(String token, LoginUser loginUser, SysCompany company) {
|
public static LoginResponse from(String token, LoginUser loginUser, SysCompany company) {
|
||||||
return new LoginResponse(
|
return new LoginResponse(
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "菜单响应")
|
@Schema(description = "菜单响应")
|
||||||
public record MenuResponse(
|
public record MenuResponse(
|
||||||
@Schema(description = "菜单编码") String menuCode,
|
@Schema(description = "菜单编码", example = "annotation.task.list") String menuCode,
|
||||||
@Schema(description = "菜单名称") String menuName,
|
@Schema(description = "菜单名称", example = "标注任务") String menuName,
|
||||||
@Schema(description = "菜单路径") String path,
|
@Schema(description = "菜单路径", example = "/annotation/tasks") String path,
|
||||||
@Schema(description = "排序") Integer sortOrder
|
@Schema(description = "排序", example = "10") Integer sortOrder
|
||||||
) {
|
) {
|
||||||
public static MenuResponse from(SysMenu menu) {
|
public static MenuResponse from(SysMenu menu) {
|
||||||
return new MenuResponse(menu.getMenuCode(), menu.getMenuName(), menu.getPath(), menu.getSortOrder());
|
return new MenuResponse(menu.getMenuCode(), menu.getMenuName(), menu.getPath(), menu.getSortOrder());
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "合并审核结果响应")
|
||||||
|
public record MergeReviewResultResponse(
|
||||||
|
@Schema(description = "运行态结果ID", example = "191000000000000401") Long resultId,
|
||||||
|
@Schema(description = "历史结果ID", example = "191000000000000451") Long historyId,
|
||||||
|
@Schema(description = "归档原因", example = "MANUAL_REVIEW_MERGED") String archiveReason,
|
||||||
|
@Schema(description = "归档时间", example = "2026-04-27T11:05:00") LocalDateTime archivedAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "资源响应")
|
||||||
|
public record SourceResourceResponse(
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long id,
|
||||||
|
@Schema(description = "资源名称", example = "2026年4月运输巡检记录") String resourceName,
|
||||||
|
@Schema(description = "资源类型", example = "TEXT") String resourceType,
|
||||||
|
@Schema(description = "桶名称", example = "annotation-source") String bucketName,
|
||||||
|
@Schema(description = "文件路径", example = "company/191000000000000001/text/191000000000000101.txt") String filePath,
|
||||||
|
@Schema(description = "文件大小", example = "20480") Long fileSize,
|
||||||
|
@Schema(description = "存储提供方", example = "rustfs") String storageProvider,
|
||||||
|
@Schema(description = "是否有BBOX标注,不显示", example = "false") Boolean hasBbox,
|
||||||
|
@Schema(description = "备注", example = "第一批导入样本") String remark,
|
||||||
|
@Schema(description = "创建人名称", example = "张审核") String creatorName,
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T10:00:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "更新时间", example = "2026-04-27T10:05:00") LocalDateTime updatedAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "资源上传响应")
|
||||||
|
public record SourceUploadResponse(
|
||||||
|
@Schema(description = "资源ID", example = "191000000000000101") Long id,
|
||||||
|
@Schema(description = "资源名称", example = "2026年4月运输巡检记录") String resourceName,
|
||||||
|
@Schema(description = "资源类型", example = "TEXT") String resourceType,
|
||||||
|
@Schema(description = "桶名称", example = "annotation-source") String bucketName,
|
||||||
|
@Schema(description = "文件路径", example = "company/191000000000000001/text/191000000000000101.txt") String filePath,
|
||||||
|
@Schema(description = "文件大小", example = "20480") Long fileSize,
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T10:00:00") LocalDateTime createdAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.labelsys.backend.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "系统配置响应")
|
||||||
|
public record SysConfigResponse(
|
||||||
|
@Schema(description = "配置ID", example = "191000000000000501") Long id,
|
||||||
|
@Schema(description = "配置类型: MODEL-大模型配置、PROMPT-提示词配置、SYSTEM-其他配置项", example = "MODEL") String configType,
|
||||||
|
@Schema(description = "配置名称", example = "qwen-plus-extract") String configName,
|
||||||
|
@Schema(description = "配置值, 当configType为model时候,configValue为大模型配置的json字符串,configType为其他值时,configValue为普通字符串",
|
||||||
|
example = "{\"modelName\":\"qwen-plus\",\"modelUrl\":\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\"apiKey\":\"sk-demo1234\"}") String configValue,
|
||||||
|
@Schema(description = "配置状态", example = "ENABLED") String status,
|
||||||
|
@Schema(description = "创建人ID", example = "191000000000000021") Long creatorId,
|
||||||
|
@Schema(description = "创建时间", example = "2026-04-27T09:50:00") LocalDateTime createdAt,
|
||||||
|
@Schema(description = "更新时间", example = "2026-04-27T10:15:00") LocalDateTime updatedAt
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -8,15 +8,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
|
|
||||||
@Schema(description = "用户响应")
|
@Schema(description = "用户响应")
|
||||||
public record UserResponse(
|
public record UserResponse(
|
||||||
@Schema(description = "用户ID") Long userId,
|
@Schema(description = "用户ID", example = "191000000000000021") Long userId,
|
||||||
@Schema(description = "公司ID") Long companyId,
|
@Schema(description = "公司ID", example = "191000000000000001") Long companyId,
|
||||||
@Schema(description = "手机号") String phone,
|
@Schema(description = "手机号", example = "13800138002") String phone,
|
||||||
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
@Schema(description = "用户名,可为空", example = "alpha-admin") String username,
|
||||||
@Schema(description = "真实姓名") String realName,
|
@Schema(description = "真实姓名", example = "张审核") String realName,
|
||||||
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师") UserRole role,
|
@Schema(description = "角色,枚举值:EMPLOYEE员工、MANAGER部门经理、ENGINEER总工程师", example = "EMPLOYEE") UserRole role,
|
||||||
@Schema(description = "岗位,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员") UserPosition position,
|
@Schema(description = "岗位,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员", example = "REVIEWER") UserPosition position,
|
||||||
@Schema(description = "用户状态,枚举值:ENABLED启用、DISABLED禁用") UserStatus status,
|
@Schema(description = "用户状态,枚举值:ENABLED启用、DISABLED禁用", example = "ENABLED") UserStatus status,
|
||||||
@Schema(description = "是否必须修改密码") boolean mustChangePassword
|
@Schema(description = "是否必须修改密码", example = "false") boolean mustChangePassword
|
||||||
) {
|
) {
|
||||||
public static UserResponse from(SysUser user) {
|
public static UserResponse from(SysUser user) {
|
||||||
return new UserResponse(
|
return new UserResponse(
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.labelsys.backend.util.SM4Util;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("annotation_agent_configs")
|
||||||
|
public class AnnotationAgentConfig {
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@TableField("company_id")
|
||||||
|
private Long companyId; // 所属公司ID,来源于annotation_task.company_id
|
||||||
|
|
||||||
|
@TableField("agent_type")
|
||||||
|
private String agentType; // Agent角色: extract(抽取/Analyzer+Regenerator) / verify(校验/Reviewer) / industry(行业识别) / hallucination(幻觉检测)
|
||||||
|
|
||||||
|
@TableField("model_config_id")
|
||||||
|
private Long modelConfigId; // 模型配置来源ID,外键引用sys_config.id,任务启动时从sys_config(config_type=MODEL, status=ENABLED)获取
|
||||||
|
|
||||||
|
@TableField("model_name")
|
||||||
|
private String modelName; // 模型名称快照,如: qwen-max / glm-4 / claude-3-opus
|
||||||
|
|
||||||
|
@TableField("model_url")
|
||||||
|
private String modelUrl; // 模型调用地址快照
|
||||||
|
|
||||||
|
@TableField("model_api_key")
|
||||||
|
private String modelApiKey; // 模型调用密钥快照(需要加密存储)
|
||||||
|
|
||||||
|
@TableField("prompt_config_id")
|
||||||
|
private Long promptConfigId; // Prompt配置来源ID,外键引用sys_config.id,任务启动时从sys_config(config_type=PROMPT, status=ENABLED)获取
|
||||||
|
|
||||||
|
@TableField("prompt_text")
|
||||||
|
private String promptText; // Prompt文本快照,任务执行期间实际使用的提示词
|
||||||
|
|
||||||
|
@TableField(value = "config_snapshot", typeHandler = JacksonTypeHandler.class)
|
||||||
|
private JsonNode configSnapshot; // 完整配置快照JSON,包含temperature、max_tokens等运行时参数
|
||||||
|
|
||||||
|
@TableField("created_at")
|
||||||
|
private LocalDateTime createdAt; // 快照创建时间
|
||||||
|
|
||||||
|
@TableField("llm_type")
|
||||||
|
private String llmType; // LLM类型,如:text, audio, video, image等,默认为'text'
|
||||||
|
|
||||||
|
// Getter和Setter方法
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCompanyId() {
|
||||||
|
return companyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompanyId(Long companyId) {
|
||||||
|
this.companyId = companyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAgentType() {
|
||||||
|
return agentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAgentType(String agentType) {
|
||||||
|
this.agentType = agentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getModelConfigId() {
|
||||||
|
return modelConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelConfigId(Long modelConfigId) {
|
||||||
|
this.modelConfigId = modelConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelName() {
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelName(String modelName) {
|
||||||
|
this.modelName = modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelUrl() {
|
||||||
|
return modelUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelUrl(String modelUrl) {
|
||||||
|
this.modelUrl = modelUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelApiKey() {
|
||||||
|
if (this.modelApiKey != null) {
|
||||||
|
return SM4Util.decryptSafe(this.modelApiKey); // 解密返回
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelApiKey(String modelApiKey) {
|
||||||
|
if (modelApiKey != null) {
|
||||||
|
this.modelApiKey = SM4Util.encrypt(modelApiKey); // 加密存储
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPromptConfigId() {
|
||||||
|
return promptConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPromptConfigId(Long promptConfigId) {
|
||||||
|
this.promptConfigId = promptConfigId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPromptText() {
|
||||||
|
return promptText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPromptText(String promptText) {
|
||||||
|
this.promptText = promptText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonNode getConfigSnapshot() {
|
||||||
|
return configSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfigSnapshot(JsonNode configSnapshot) {
|
||||||
|
this.configSnapshot = configSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLlmType() {
|
||||||
|
return llmType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLlmType(String llmType) {
|
||||||
|
this.llmType = llmType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("annotation_result")
|
||||||
|
public class AnnotationResult {
|
||||||
|
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@TableField("company_id")
|
||||||
|
private Long companyId;
|
||||||
|
|
||||||
|
@TableField("creator_id")
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
@TableField("creator_role")
|
||||||
|
private String creatorRole;
|
||||||
|
|
||||||
|
@TableField("task_id")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
|
@TableField("resource_id")
|
||||||
|
private Long resourceId;
|
||||||
|
|
||||||
|
// 添加字段
|
||||||
|
@TableField("task_name")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@TableField("resource_name")
|
||||||
|
private String resourceName;
|
||||||
|
|
||||||
|
@TableField("qa_content_file_path")
|
||||||
|
private String qaContentFilePath;
|
||||||
|
|
||||||
|
@TableField("diff_summary_file_path")
|
||||||
|
private String diffSummaryFilePath;
|
||||||
|
|
||||||
|
@TableField("requires_manual_review")
|
||||||
|
private Boolean requiresManualReview;
|
||||||
|
|
||||||
|
@TableLogic(value = "false", delval = "true")
|
||||||
|
@TableField("is_deleted")
|
||||||
|
private Boolean isDeleted;
|
||||||
|
|
||||||
|
@TableField("reviewer_id")
|
||||||
|
private Long reviewerId;
|
||||||
|
|
||||||
|
@TableField("created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@TableField("updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("annotation_result_history")
|
||||||
|
public class AnnotationResultHistory {
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
private Long companyId;
|
||||||
|
private Long creatorId;
|
||||||
|
private String creatorRole;
|
||||||
|
private Long sourceResultId;
|
||||||
|
private Long taskId;
|
||||||
|
private Long resourceId;
|
||||||
|
private String taskName;
|
||||||
|
private String resourceName;
|
||||||
|
//private String qaContentJson;
|
||||||
|
// private String qaContentStorageMode;
|
||||||
|
private String qaContentFilePath;
|
||||||
|
private String archiveReason;
|
||||||
|
private Long archivedBy;
|
||||||
|
private LocalDateTime archivedAt;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
// 新增审核人相关字段
|
||||||
|
private Long reviewerId;
|
||||||
|
private String reviewerName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.labelsys.backend.enums.TaskType;
|
||||||
|
import com.labelsys.backend.enums.UserRole;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("annotation_task")
|
||||||
|
public class AnnotationTask {
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
private Long companyId;
|
||||||
|
private Long creatorId;
|
||||||
|
private UserRole creatorRole;
|
||||||
|
private String taskName;
|
||||||
|
private TaskType taskType;
|
||||||
|
private String taskStatus;
|
||||||
|
@TableLogic(value = "false", delval = "true")
|
||||||
|
private Boolean isDeleted;
|
||||||
|
private LocalDateTime startedAt;
|
||||||
|
private LocalDateTime finishedAt;
|
||||||
|
private String errorMessage;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("annotation_task_resource")
|
||||||
|
public class AnnotationTaskResource {
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
private Long companyId;
|
||||||
|
private Long taskId;
|
||||||
|
private Long resourceId;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
package com.labelsys.backend.entity;
|
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.UserRole;
|
import com.labelsys.backend.enums.UserRole;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -14,9 +11,7 @@ import lombok.NoArgsConstructor;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@TableName("biz_data_record")
|
|
||||||
public class BizDataRecord {
|
public class BizDataRecord {
|
||||||
@TableId(type = IdType.INPUT)
|
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long companyId;
|
private Long companyId;
|
||||||
private Long creatorId;
|
private Long creatorId;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.labelsys.backend.enums.UserRole;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片BBOX标注表实体类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("image_bbox_annotation")
|
||||||
|
public class ImageBboxAnnotation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属公司ID
|
||||||
|
*/
|
||||||
|
private Long companyId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关联的图片资源ID
|
||||||
|
*/
|
||||||
|
private Long resourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bbox坐标信息JSON数组
|
||||||
|
*/
|
||||||
|
private String bboxJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注说明
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人用户ID
|
||||||
|
*/
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人数据权限角色,默认 EMPLOYEE
|
||||||
|
*/
|
||||||
|
private UserRole creatorRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 软删除标记
|
||||||
|
*/
|
||||||
|
@TableLogic(value = "false", delval = "true")
|
||||||
|
private Boolean deleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 软删除时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime deletedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.labelsys.backend.enums.UserRole;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("source_resource")
|
||||||
|
public class SourceResource {
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
private Long companyId;
|
||||||
|
private Long creatorId;
|
||||||
|
private UserRole creatorRole;
|
||||||
|
private String resourceName;
|
||||||
|
private String resourceType;
|
||||||
|
private String bucketName;
|
||||||
|
private String filePath;
|
||||||
|
private Long fileSize;
|
||||||
|
private String storageProvider;
|
||||||
|
private Boolean hasBbox;
|
||||||
|
private String remark;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
@TableLogic(value = "false", delval = "true")
|
||||||
|
private Boolean deleted;
|
||||||
|
private LocalDateTime deletedAt;
|
||||||
|
}
|
||||||
29
src/main/java/com/labelsys/backend/entity/SysConfig.java
Normal file
29
src/main/java/com/labelsys/backend/entity/SysConfig.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.labelsys.backend.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("sys_config")
|
||||||
|
public class SysConfig {
|
||||||
|
@TableId(type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
private Long companyId;
|
||||||
|
private String configType;
|
||||||
|
private String configName;
|
||||||
|
private String configValue;
|
||||||
|
private String status;
|
||||||
|
private Long creatorId;
|
||||||
|
private String creatorRole;
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@ public class SysMenu {
|
|||||||
@TableId(type = IdType.INPUT)
|
@TableId(type = IdType.INPUT)
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long companyId;
|
private Long companyId;
|
||||||
private String permissionCode;
|
|
||||||
private String menuCode;
|
private String menuCode;
|
||||||
private String menuName;
|
private String menuName;
|
||||||
private String path;
|
private String path;
|
||||||
|
private String visiblePositions;
|
||||||
private Integer sortOrder;
|
private Integer sortOrder;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
|
|||||||
43
src/main/java/com/labelsys/backend/enums/AgentType.java
Normal file
43
src/main/java/com/labelsys/backend/enums/AgentType.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "Agent类型枚举")
|
||||||
|
public enum AgentType {
|
||||||
|
@Schema(description = "红黑对抗")
|
||||||
|
RED_TEAM("RedTeamAgent"),
|
||||||
|
|
||||||
|
@Schema(description = "分析")
|
||||||
|
ANALYZER("AnalyzerAgent"),
|
||||||
|
|
||||||
|
@Schema(description = "行业识别")
|
||||||
|
INDUSTRY_CLASSIFIER("IndustryClassifierAgent"),
|
||||||
|
|
||||||
|
@Schema(description = "幻觉检测")
|
||||||
|
HALLUCINATION_DETECTOR("HallucinationDetectorAgent"),
|
||||||
|
|
||||||
|
@Schema(description = "审查")
|
||||||
|
REVIEWER("ReviewerAgent"),
|
||||||
|
|
||||||
|
@Schema(description = "再次生成")
|
||||||
|
REGENERATOR("regenerator");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
AgentType(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
for (AgentType type : AgentType.values()) {
|
||||||
|
if (type.name().equalsIgnoreCase(value) || type.getCode().equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "标注结果状态枚举值:MANUAL_REVIEW_PENDING待人工审核、MANUAL_REVIEW_PENDING待自动归档、ARCHIVED已归档")
|
||||||
|
public enum AnnotationResultStatus {
|
||||||
|
MANUAL_REVIEW_PENDING,
|
||||||
|
AUTO_ARCHIVE_PENDING,
|
||||||
|
ARCHIVED
|
||||||
|
}
|
||||||
9
src/main/java/com/labelsys/backend/enums/ConfigMode.java
Normal file
9
src/main/java/com/labelsys/backend/enums/ConfigMode.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "模型配置模式,枚举值:SELECT:选择已有模型配置、MANUAL:手动录入新模型")
|
||||||
|
public enum ConfigMode {
|
||||||
|
SELECT,
|
||||||
|
MANUAL
|
||||||
|
}
|
||||||
15
src/main/java/com/labelsys/backend/enums/ConfigType.java
Normal file
15
src/main/java/com/labelsys/backend/enums/ConfigType.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "系统配置类型,枚举值:model:大模型配置、prompt:提示词配置, system:其他配置项")
|
||||||
|
public enum ConfigType {
|
||||||
|
MODEL,
|
||||||
|
PROMPT,
|
||||||
|
SYSTEM;
|
||||||
|
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
return Arrays.stream(values()).anyMatch(type -> type.name().equals(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/java/com/labelsys/backend/enums/IndustryType.java
Normal file
13
src/main/java/com/labelsys/backend/enums/IndustryType.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "行业类型,枚举值:TRANSPORT:交通、ELECTRICITY:电力、FINANCE:金融、MEDICAL:医疗、EDUCATION:教育、GENERAL:通用")
|
||||||
|
public enum IndustryType {
|
||||||
|
GENERAL,
|
||||||
|
TRANSPORT,
|
||||||
|
ELECTRICITY,
|
||||||
|
FINANCE,
|
||||||
|
MEDICAL,
|
||||||
|
EDUCATION
|
||||||
|
}
|
||||||
37
src/main/java/com/labelsys/backend/enums/MultiModalType.java
Normal file
37
src/main/java/com/labelsys/backend/enums/MultiModalType.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "多模态类型枚举")
|
||||||
|
public enum MultiModalType {
|
||||||
|
@Schema(description = "文本")
|
||||||
|
TEXT("text"),
|
||||||
|
|
||||||
|
@Schema(description = "音频")
|
||||||
|
AUDIO("audio"),
|
||||||
|
|
||||||
|
@Schema(description = "视频")
|
||||||
|
VIDEO("video"),
|
||||||
|
|
||||||
|
@Schema(description = "图片")
|
||||||
|
IMAGE("image");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
MultiModalType(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
for (MultiModalType type : MultiModalType.values()) {
|
||||||
|
if (type.name().equalsIgnoreCase(value) || type.getCode().equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "问答对存储形式,枚举值:INLINE:记录中保存、EXTERNAL:外部存储器rustfs")
|
||||||
|
public enum QaContentStorageMode {
|
||||||
|
INLINE,
|
||||||
|
EXTERNAL;
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
return Arrays.stream(values()).anyMatch(mode -> mode.name().equals(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/java/com/labelsys/backend/enums/ResourceType.java
Normal file
16
src/main/java/com/labelsys/backend/enums/ResourceType.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "资源类型,枚举值:TEXT:文本、IMAGE:图片、VIDEO:视频")
|
||||||
|
public enum ResourceType {
|
||||||
|
TEXT,
|
||||||
|
IMAGE,
|
||||||
|
VIDEO;
|
||||||
|
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
return Arrays.stream(values()).anyMatch(type -> type.name().equals(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/main/java/com/labelsys/backend/enums/TaskStatus.java
Normal file
17
src/main/java/com/labelsys/backend/enums/TaskStatus.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "任务状态枚举值:PENDING:待执行、RUNNING:处理中、COMPLETED:已完成、FAILED:失败")
|
||||||
|
public enum TaskStatus {
|
||||||
|
PENDING,
|
||||||
|
RUNNING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED;
|
||||||
|
|
||||||
|
public static boolean isValid(String value) {
|
||||||
|
return Arrays.stream(values()).anyMatch(status -> status.name().equals(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/com/labelsys/backend/enums/TaskType.java
Normal file
9
src/main/java/com/labelsys/backend/enums/TaskType.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package com.labelsys.backend.enums;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Schema(description = "标注任务类型枚举值:EXTRACT_QA:抽取任务、FINE_TUNE:微调任务")
|
||||||
|
public enum TaskType {
|
||||||
|
EXTRACT_QA,
|
||||||
|
FINE_TUNE
|
||||||
|
}
|
||||||
@@ -6,13 +6,9 @@ import lombok.RequiredArgsConstructor;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Schema(description = "岗位枚举,枚举值:UPLOADER上传者、ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN超级管理员")
|
@Schema(description = "岗位枚举,枚举值:ANNOTATOR标注员、DATA_TRAINER数据训练师、REVIEWER审核员、ADMIN公司管理员、SUPER_ADMIN超级管理员")
|
||||||
public enum UserPosition {
|
public enum UserPosition {
|
||||||
UPLOADER(1),
|
ANNOTATOR(1), DATA_TRAINER(2), REVIEWER(3), ADMIN(4), SUPER_ADMIN(5);
|
||||||
ANNOTATOR(2),
|
|
||||||
DATA_TRAINER(3),
|
|
||||||
REVIEWER(4),
|
|
||||||
ADMIN(5);
|
|
||||||
|
|
||||||
private final int level;
|
private final int level;
|
||||||
|
|
||||||
|
|||||||
@@ -8,98 +8,180 @@ import com.labelsys.backend.context.UserContext;
|
|||||||
import com.labelsys.backend.entity.SysCompany;
|
import com.labelsys.backend.entity.SysCompany;
|
||||||
import com.labelsys.backend.entity.SysUser;
|
import com.labelsys.backend.entity.SysUser;
|
||||||
import com.labelsys.backend.enums.CompanyStatus;
|
import com.labelsys.backend.enums.CompanyStatus;
|
||||||
import com.labelsys.backend.enums.UserPosition;
|
|
||||||
import com.labelsys.backend.enums.UserStatus;
|
import com.labelsys.backend.enums.UserStatus;
|
||||||
import com.labelsys.backend.mapper.SysCompanyMapper;
|
import com.labelsys.backend.mapper.SysCompanyMapper;
|
||||||
import com.labelsys.backend.mapper.SysUserMapper;
|
import com.labelsys.backend.mapper.SysUserMapper;
|
||||||
import com.labelsys.backend.service.session.TokenSessionRepository;
|
import com.labelsys.backend.service.session.TokenSessionRepository;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 认证拦截器
|
||||||
|
*
|
||||||
|
* <p>实现 HandlerInterceptor 接口,用于在请求处理前进行身份认证和权限校验。
|
||||||
|
* 负责验证用户登录状态、会话有效性、密码修改强制要求以及岗位权限检查。
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AuthInterceptor implements HandlerInterceptor {
|
public class AuthInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公开路径集合(无需登录即可访问)
|
||||||
|
* 包括认证相关接口和 Swagger 文档接口
|
||||||
|
*/
|
||||||
private static final Set<String> OPEN_PATHS = Set.of(
|
private static final Set<String> OPEN_PATHS = Set.of(
|
||||||
"/label/api/auth/companies",
|
"/api/auth/companies", "/label/api/auth/companies",
|
||||||
"/label/api/auth/login",
|
"/api/auth/login", "/label/api/auth/login",
|
||||||
"/label/swagger-ui.html",
|
"/swagger-ui.html", "/label/swagger-ui.html",
|
||||||
"/label/v3/api-docs",
|
"/v3/api-docs", "/label/v3/api-docs",
|
||||||
"/label/v3/api-docs/swagger-config"
|
"/v3/api-docs/swagger-config", "/label/v3/api-docs/swagger-config");
|
||||||
);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强制修改密码时允许访问的路径集合
|
||||||
|
* 包括修改密码、登出和获取当前用户信息接口
|
||||||
|
*/
|
||||||
private static final Set<String> ALLOWED_WHEN_MUST_CHANGE_PASSWORD = Set.of(
|
private static final Set<String> ALLOWED_WHEN_MUST_CHANGE_PASSWORD = Set.of(
|
||||||
"/label/api/auth/change-password",
|
"/api/auth/change-password", "/label/api/auth/change-password",
|
||||||
"/label/api/auth/logout",
|
"/api/auth/logout", "/label/api/auth/logout",
|
||||||
"/label/api/auth/me"
|
"/api/auth/me", "/label/api/auth/me");
|
||||||
);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token会话存储仓库
|
||||||
|
*/
|
||||||
private final TokenSessionRepository tokenSessionRepository;
|
private final TokenSessionRepository tokenSessionRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户数据访问层
|
||||||
|
*/
|
||||||
private final SysUserMapper sysUserMapper;
|
private final SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司数据访问层
|
||||||
|
*/
|
||||||
private final SysCompanyMapper sysCompanyMapper;
|
private final SysCompanyMapper sysCompanyMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话有效期
|
||||||
|
*/
|
||||||
private final Duration sessionTtl;
|
private final Duration sessionTtl;
|
||||||
|
|
||||||
public AuthInterceptor(
|
/**
|
||||||
TokenSessionRepository tokenSessionRepository,
|
* 构造函数
|
||||||
SysUserMapper sysUserMapper,
|
*
|
||||||
|
* @param tokenSessionRepository Token会话存储仓库
|
||||||
|
* @param sysUserMapper 用户数据访问层
|
||||||
|
* @param sysCompanyMapper 公司数据访问层
|
||||||
|
* @param sessionTtl 会话有效期(默认2小时)
|
||||||
|
*/
|
||||||
|
public AuthInterceptor(TokenSessionRepository tokenSessionRepository, SysUserMapper sysUserMapper,
|
||||||
SysCompanyMapper sysCompanyMapper,
|
SysCompanyMapper sysCompanyMapper,
|
||||||
@Value("${labelsys.session.ttl:PT2H}") Duration sessionTtl
|
@Value("${labelsys.session.ttl:PT2H}") Duration sessionTtl) {
|
||||||
) {
|
|
||||||
this.tokenSessionRepository = tokenSessionRepository;
|
this.tokenSessionRepository = tokenSessionRepository;
|
||||||
this.sysUserMapper = sysUserMapper;
|
this.sysUserMapper = sysUserMapper;
|
||||||
this.sysCompanyMapper = sysCompanyMapper;
|
this.sysCompanyMapper = sysCompanyMapper;
|
||||||
this.sessionTtl = sessionTtl;
|
this.sessionTtl = sessionTtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求处理前的认证拦截
|
||||||
|
*
|
||||||
|
* <p>执行以下校验逻辑:
|
||||||
|
* 1. OPTIONS 请求直接放行
|
||||||
|
* 2. 公开路径和 Swagger 路径直接放行
|
||||||
|
* 3. 非 HandlerMethod 请求直接放行
|
||||||
|
* 4. 验证 Token 并获取登录用户
|
||||||
|
* 5. 验证用户和公司状态
|
||||||
|
* 6. 验证会话版本(密码修改后会话失效)
|
||||||
|
* 7. 检查强制修改密码状态
|
||||||
|
* 8. 设置用户上下文并刷新会话
|
||||||
|
* 9. 检查岗位权限
|
||||||
|
*
|
||||||
|
* @param request HTTP请求
|
||||||
|
* @param response HTTP响应
|
||||||
|
* @param handler 处理器
|
||||||
|
* @return 是否放行
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
// OPTIONS 请求直接放行(CORS预检请求)
|
||||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String path = request.getRequestURI();
|
String path = request.getRequestURI();
|
||||||
|
// Swagger 相关路径和公开路径直接放行
|
||||||
if (path.startsWith("/swagger-ui") || path.startsWith("/v3/api-docs") || OPEN_PATHS.contains(path)) {
|
if (path.startsWith("/swagger-ui") || path.startsWith("/v3/api-docs") || OPEN_PATHS.contains(path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 非 HandlerMethod 请求直接放行
|
||||||
if (!(handler instanceof HandlerMethod handlerMethod)) {
|
if (!(handler instanceof HandlerMethod handlerMethod)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String token = extractToken(request.getHeader("Authorization"));
|
|
||||||
LoginUser loginUser = tokenSessionRepository.find(token)
|
|
||||||
.orElseThrow(() -> new UnauthorizedException("未登录或登录已过期"));
|
|
||||||
|
|
||||||
|
// 提取 Token 并验证会话
|
||||||
|
String token = extractToken(request.getHeader("Authorization"));
|
||||||
|
LoginUser loginUser =
|
||||||
|
tokenSessionRepository.find(token).orElseThrow(() -> new UnauthorizedException("未登录或登录已过期"));
|
||||||
|
|
||||||
|
// 验证用户和公司状态
|
||||||
SysUser user = sysUserMapper.findByIdAndCompanyId(loginUser.userId(), loginUser.companyId());
|
SysUser user = sysUserMapper.findByIdAndCompanyId(loginUser.userId(), loginUser.companyId());
|
||||||
SysCompany company = sysCompanyMapper.findById(loginUser.companyId());
|
SysCompany company = sysCompanyMapper.selectById(loginUser.companyId());
|
||||||
if (user == null || company == null || user.getStatus() != UserStatus.ENABLED || company.getStatus() != CompanyStatus.ENABLED) {
|
if (user == null || company == null || user.getStatus() != UserStatus.ENABLED
|
||||||
|
|| company.getStatus() != CompanyStatus.ENABLED) {
|
||||||
throw new UnauthorizedException("未登录或登录已过期");
|
throw new UnauthorizedException("未登录或登录已过期");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证会话版本(密码修改后会话失效)
|
||||||
if (!user.getSessionVersion().equals(loginUser.sessionVersion())) {
|
if (!user.getSessionVersion().equals(loginUser.sessionVersion())) {
|
||||||
throw new UnauthorizedException("登录状态已失效,请重新登录");
|
throw new UnauthorizedException("登录状态已失效,请重新登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查强制修改密码状态
|
||||||
if (Boolean.TRUE.equals(user.getMustChangePassword()) && !ALLOWED_WHEN_MUST_CHANGE_PASSWORD.contains(path)) {
|
if (Boolean.TRUE.equals(user.getMustChangePassword()) && !ALLOWED_WHEN_MUST_CHANGE_PASSWORD.contains(path)) {
|
||||||
throw new ForbiddenException("首次登录后请先修改密码");
|
throw new ForbiddenException("首次登录后请先修改密码");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置用户上下文并刷新会话
|
||||||
LoginUser refreshedUser = LoginUser.from(user, company);
|
LoginUser refreshedUser = LoginUser.from(user, company);
|
||||||
UserContext.set(refreshedUser);
|
UserContext.set(refreshedUser);
|
||||||
tokenSessionRepository.refresh(token, sessionTtl);
|
tokenSessionRepository.refresh(token, sessionTtl);
|
||||||
|
|
||||||
|
// 检查岗位权限
|
||||||
RequirePosition requirePosition = resolveRequirePosition(handlerMethod);
|
RequirePosition requirePosition = resolveRequirePosition(handlerMethod);
|
||||||
if (requirePosition != null && !refreshedUser.position().canAccess(requirePosition.value())) {
|
if (requirePosition != null && !refreshedUser.position().canAccess(requirePosition.value())) {
|
||||||
throw new ForbiddenException("当前岗位无权限访问");
|
throw new ForbiddenException("当前岗位无权限访问");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求处理完成后清理用户上下文
|
||||||
|
*
|
||||||
|
* @param request HTTP请求
|
||||||
|
* @param response HTTP响应
|
||||||
|
* @param handler 处理器
|
||||||
|
* @param ex 异常(如果有)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||||
|
Exception ex) {
|
||||||
UserContext.clear();
|
UserContext.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 Authorization 头中提取 Token
|
||||||
|
*
|
||||||
|
* @param authorization Authorization 头值
|
||||||
|
* @return Token
|
||||||
|
*/
|
||||||
private String extractToken(String authorization) {
|
private String extractToken(String authorization) {
|
||||||
if (authorization == null || !authorization.startsWith("Bearer ")) {
|
if (authorization == null || !authorization.startsWith("Bearer ")) {
|
||||||
throw new UnauthorizedException("未登录或登录已过期");
|
throw new UnauthorizedException("未登录或登录已过期");
|
||||||
@@ -107,6 +189,14 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
return authorization.substring(7).trim();
|
return authorization.substring(7).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析方法或类上的 @RequirePosition 注解
|
||||||
|
*
|
||||||
|
* <p>优先从方法上获取注解,若方法上没有则从类上获取。
|
||||||
|
*
|
||||||
|
* @param handlerMethod 处理器方法
|
||||||
|
* @return RequirePosition 注解(可能为null)
|
||||||
|
*/
|
||||||
private RequirePosition resolveRequirePosition(HandlerMethod handlerMethod) {
|
private RequirePosition resolveRequirePosition(HandlerMethod handlerMethod) {
|
||||||
RequirePosition methodAnnotation = handlerMethod.getMethodAnnotation(RequirePosition.class);
|
RequirePosition methodAnnotation = handlerMethod.getMethodAnnotation(RequirePosition.class);
|
||||||
if (methodAnnotation != null) {
|
if (methodAnnotation != null) {
|
||||||
@@ -114,4 +204,5 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
}
|
}
|
||||||
return handlerMethod.getBeanType().getAnnotation(RequirePosition.class);
|
return handlerMethod.getBeanType().getAnnotation(RequirePosition.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.AnnotationAgentConfig;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AnnotationAgentConfigMapper extends BaseMapper<AnnotationAgentConfig> {
|
||||||
|
// 基于BaseMapper,已提供基本的CRUD操作
|
||||||
|
// 如需特殊查询,可在此添加自定义方法
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.AnnotationResultHistory;
|
||||||
|
|
||||||
|
public interface AnnotationResultHistoryMapper extends BaseMapper<AnnotationResultHistory> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.AnnotationResult;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注结果数据访问层
|
||||||
|
*
|
||||||
|
* 继承 BaseMapper<AnnotationResult>,提供标注结果表的基础 CRUD 操作,
|
||||||
|
* 并扩展自定义的查询和更新方法。
|
||||||
|
*/
|
||||||
|
public interface AnnotationResultMapper extends BaseMapper<AnnotationResult> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID和公司ID查询活跃的标注结果
|
||||||
|
*
|
||||||
|
* @param id 结果ID
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @return 标注结果信息,不存在或已归档返回 null
|
||||||
|
*/
|
||||||
|
AnnotationResult findActiveByIdAndCompanyId(@Param("id") Long id, @Param("companyId") Long companyId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记标注结果为已归档
|
||||||
|
*
|
||||||
|
* @param id 结果ID
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @param reviewerId 审核人ID
|
||||||
|
* @return 更新影响的行数
|
||||||
|
*/
|
||||||
|
int markArchived(@Param("id") Long id,
|
||||||
|
@Param("companyId") Long companyId,
|
||||||
|
@Param("reviewerId") Long reviewerId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记标注结果为已审核并归档
|
||||||
|
*
|
||||||
|
* @param id 结果ID
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @param reviewerId 审核人ID
|
||||||
|
* @return 更新影响的行数
|
||||||
|
*/
|
||||||
|
int markReviewedAndArchived(@Param("id") Long id,
|
||||||
|
@Param("companyId") Long companyId,
|
||||||
|
@Param("reviewerId") Long reviewerId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.AnnotationTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注任务数据访问层
|
||||||
|
*
|
||||||
|
* 继承 BaseMapper<AnnotationTask>,提供标注任务表的基础 CRUD 操作,
|
||||||
|
* 并扩展自定义的查询方法。
|
||||||
|
*/
|
||||||
|
public interface AnnotationTaskMapper extends BaseMapper<AnnotationTask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID和公司ID查询标注任务
|
||||||
|
*
|
||||||
|
* @param id 任务ID
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @return 标注任务信息,不存在返回 null
|
||||||
|
*/
|
||||||
|
AnnotationTask findByIdAndCompanyId(@Param("id") Long id, @Param("companyId") Long companyId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.AnnotationTaskResource;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标注任务资源关联数据访问层
|
||||||
|
*
|
||||||
|
* 继承 BaseMapper<AnnotationTaskResource>,提供标注任务资源关联表的基础 CRUD 操作,
|
||||||
|
* 并扩展自定义的查询和删除方法。
|
||||||
|
*/
|
||||||
|
public interface AnnotationTaskResourceMapper extends BaseMapper<AnnotationTaskResource> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据任务ID查询关联的资源ID列表
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 资源ID列表
|
||||||
|
*/
|
||||||
|
List<Long> listResourceIdsByTaskId(@Param("taskId") Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据任务ID删除关联的资源记录
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @return 删除影响的行数
|
||||||
|
*/
|
||||||
|
int deleteByTaskId(@Param("taskId") Long taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计资源被任务关联的数量
|
||||||
|
*
|
||||||
|
* @param resourceId 资源ID
|
||||||
|
* @return 关联数量
|
||||||
|
*/
|
||||||
|
int countByResourceId(@Param("resourceId") Long resourceId);
|
||||||
|
}
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.labelsys.backend.mapper;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import com.labelsys.backend.entity.BizDataRecord;
|
|
||||||
import java.util.List;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
|
|
||||||
public interface BizDataRecordMapper extends BaseMapper<BizDataRecord> {
|
|
||||||
|
|
||||||
List<BizDataRecord> listVisibleByEmployee(@Param("companyId") Long companyId, @Param("creatorId") Long creatorId);
|
|
||||||
|
|
||||||
List<BizDataRecord> listVisibleByManager(@Param("companyId") Long companyId);
|
|
||||||
|
|
||||||
List<BizDataRecord> listVisibleByEngineer(@Param("companyId") Long companyId);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.ImageBboxAnnotation;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图像边界框标注数据访问层
|
||||||
|
*
|
||||||
|
* 继承 BaseMapper<ImageBboxAnnotation>,提供图像边界框标注表的基础 CRUD 操作,
|
||||||
|
* 并扩展自定义的查询和删除方法。
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ImageBboxAnnotationMapper extends BaseMapper<ImageBboxAnnotation> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据资源ID查询图像边界框标注
|
||||||
|
*
|
||||||
|
* @param resourceId 资源ID
|
||||||
|
* @return 图像边界框标注,不存在返回 null
|
||||||
|
*/
|
||||||
|
ImageBboxAnnotation selectByResourceId(@Param("resourceId") Long resourceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据资源ID删除图像边界框标注
|
||||||
|
*
|
||||||
|
* @param resourceId 资源ID
|
||||||
|
* @return 删除影响的行数
|
||||||
|
*/
|
||||||
|
int deleteByResourceId(@Param("resourceId") Long resourceId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.labelsys.backend.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.labelsys.backend.entity.SourceResource;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 源资源数据访问层
|
||||||
|
*
|
||||||
|
* 继承 BaseMapper<SourceResource>,提供源资源表的基础 CRUD 操作,
|
||||||
|
* 并扩展自定义的查询方法。
|
||||||
|
*/
|
||||||
|
public interface SourceResourceMapper extends BaseMapper<SourceResource> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据公司ID和资源ID列表查询资源
|
||||||
|
*
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @param resourceIds 资源ID列表
|
||||||
|
* @return 资源列表
|
||||||
|
*/
|
||||||
|
List<SourceResource> selectByCompanyIdAndIds(@Param("companyId") Long companyId, @Param("resourceIds") List<Long> resourceIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据公司ID和资源名称查询资源
|
||||||
|
*
|
||||||
|
* @param companyId 公司ID
|
||||||
|
* @param resourceName 资源名称
|
||||||
|
* @return 资源信息,不存在返回 null
|
||||||
|
*/
|
||||||
|
SourceResource selectByCompanyIdAndResourceName(@Param("companyId") Long companyId, @Param("resourceName") String resourceName);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user