feat(common): 添加 BusinessException/GlobalExceptionHandler/CompanyContext/状态枚举 (T007/T008/T012-T015)

This commit is contained in:
wh
2026-04-09 13:21:06 +08:00
parent ae55e87e2c
commit 52d5dd9c24
7 changed files with 135 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
package com.label.common.context;
public class CompanyContext {
private static final ThreadLocal<Long> COMPANY_ID = new ThreadLocal<>();
public static void set(Long companyId) {
COMPANY_ID.set(companyId);
}
public static Long get() {
return COMPANY_ID.get();
}
public static void clear() {
COMPANY_ID.remove(); // Use remove() not set(null) to prevent memory leaks
}
private CompanyContext() { // Prevent instantiation
throw new UnsupportedOperationException("Utility class");
}
}

View File

@@ -0,0 +1,22 @@
package com.label.common.exception;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
public class BusinessException extends RuntimeException {
private final String code;
private final HttpStatus httpStatus;
public BusinessException(String code, String message) {
super(message);
this.code = code;
this.httpStatus = HttpStatus.BAD_REQUEST;
}
public BusinessException(String code, String message, HttpStatus httpStatus) {
super(message);
this.code = code;
this.httpStatus = httpStatus;
}
}

View File

@@ -0,0 +1,28 @@
package com.label.common.exception;
import com.label.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<Result<?>> handleBusinessException(BusinessException e) {
log.warn("业务异常: code={}, message={}", e.getCode(), e.getMessage());
return ResponseEntity
.status(e.getHttpStatus())
.body(Result.failure(e.getCode(), e.getMessage()));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Result<?>> handleException(Exception e) {
log.error("系统异常", e);
return ResponseEntity
.internalServerError()
.body(Result.failure("INTERNAL_ERROR", "系统内部错误"));
}
}

View File

@@ -0,0 +1,13 @@
package com.label.common.statemachine;
import java.util.Map;
import java.util.Set;
public enum DatasetStatus {
PENDING_REVIEW, APPROVED, REJECTED;
public static final Map<DatasetStatus, Set<DatasetStatus>> TRANSITIONS = Map.of(
PENDING_REVIEW, Set.of(APPROVED, REJECTED)
// APPROVED/REJECTED: terminal states
);
}

View File

@@ -0,0 +1,15 @@
package com.label.common.statemachine;
import java.util.Map;
import java.util.Set;
public enum SourceStatus {
PENDING, PREPROCESSING, EXTRACTING, QA_REVIEW, APPROVED;
public static final Map<SourceStatus, Set<SourceStatus>> TRANSITIONS = Map.of(
PENDING, Set.of(EXTRACTING, PREPROCESSING),
PREPROCESSING, Set.of(PENDING),
EXTRACTING, Set.of(QA_REVIEW),
QA_REVIEW, Set.of(APPROVED)
);
}

View File

@@ -0,0 +1,16 @@
package com.label.common.statemachine;
import java.util.Map;
import java.util.Set;
public enum TaskStatus {
UNCLAIMED, IN_PROGRESS, SUBMITTED, APPROVED, REJECTED;
public static final Map<TaskStatus, Set<TaskStatus>> TRANSITIONS = Map.of(
UNCLAIMED, Set.of(IN_PROGRESS),
IN_PROGRESS, Set.of(SUBMITTED, UNCLAIMED, IN_PROGRESS), // IN_PROGRESS->IN_PROGRESS for ADMIN reassign
SUBMITTED, Set.of(APPROVED, REJECTED),
REJECTED, Set.of(IN_PROGRESS)
// APPROVED: terminal state, no outgoing transitions
);
}

View File

@@ -0,0 +1,20 @@
package com.label.common.statemachine;
import java.util.Map;
import java.util.Set;
public enum VideoJobStatus {
PENDING, RUNNING, SUCCESS, FAILED, RETRYING;
/**
* Automatic state machine transitions.
* Note: FAILED → PENDING is a manual ADMIN operation, handled separately in VideoProcessService.reset().
*/
public static final Map<VideoJobStatus, Set<VideoJobStatus>> TRANSITIONS = Map.of(
PENDING, Set.of(RUNNING),
RUNNING, Set.of(SUCCESS, FAILED, RETRYING),
RETRYING, Set.of(RUNNING, FAILED)
// SUCCESS: terminal state
// FAILED → PENDING: manual ADMIN reset, NOT in this automatic transitions map
);
}