jisti-meet服务开启

This commit is contained in:
2025-12-26 18:55:54 +08:00
parent c2b37503fc
commit 0658b82f39
43 changed files with 3979 additions and 1208 deletions

View File

@@ -33,6 +33,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -2,8 +2,11 @@ package org.xyzh.common.exception.handler;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
@@ -26,17 +29,16 @@ import java.util.stream.Collectors;
* @copyright yslg
* @since 2025-12-17
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 业务异常
*/
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleBusinessException(BusinessException e) {
log.warn("业务异常: {}", e.getMessage());
logger.warn("业务异常: {}", e.getMessage());
return ResultDomain.failure(e.getCode(), e.getMessage());
}
@@ -49,7 +51,7 @@ public class GlobalExceptionHandler {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining("; "));
log.warn("参数校验失败: {}", message);
logger.warn("参数校验失败: {}", message);
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
}
@@ -63,7 +65,7 @@ public class GlobalExceptionHandler {
String message = violations.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining("; "));
log.warn("参数校验失败: {}", message);
logger.warn("参数校验失败: {}", message);
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
}
@@ -76,7 +78,7 @@ public class GlobalExceptionHandler {
String message = e.getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining("; "));
log.warn("参数绑定失败: {}", message);
logger.warn("参数绑定失败: {}", message);
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
}
@@ -87,7 +89,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
String message = "缺少必要参数: " + e.getParameterName();
log.warn(message);
logger.warn(message);
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
}
@@ -98,7 +100,7 @@ public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleMissingServletRequestPartException(MissingServletRequestPartException e) {
String message = "缺少必要参数: " + e.getRequestPartName();
log.warn(message);
logger.warn(message);
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
}
@@ -108,17 +110,27 @@ public class GlobalExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
log.warn("文件上传大小超限: {}", e.getMessage());
logger.warn("文件上传大小超限: {}", e.getMessage());
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), "上传文件大小超过限制");
}
/**
* 权限不足异常
*/
@ExceptionHandler(AuthorizationDeniedException.class)
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleAuthorizationDeniedException(AuthorizationDeniedException e) {
logger.warn("权限不足: {}", e.getMessage());
return ResultDomain.failure(HttpStatus.FORBIDDEN.value(), "权限不足");
}
/**
* 其他未捕获异常
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.OK)
public ResultDomain<?> handleException(Exception e) {
log.error("系统异常: ", e);
logger.error("系统异常: ", e);
return ResultDomain.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常,请联系管理员");
}
}

View File

@@ -1,5 +1,6 @@
package org.xyzh.common.utils.validation;
import org.xyzh.common.utils.validation.method.FieldCompareValidateMethod;
import org.xyzh.common.utils.validation.method.InSetValidateMethod;
import org.xyzh.common.utils.validation.method.MinFieldsValidateMethod;
import org.xyzh.common.utils.validation.method.ObjectValidateMethod;
@@ -10,6 +11,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.regex.Pattern;
/**
@@ -380,4 +382,32 @@ public class ValidationUtils {
.validateMethod(new InSetValidateMethod(fieldLabel, allowedValues))
.build();
}
/**
* @description 创建字段比较校验参数(比较对象中的两个字段)
* @param field1Name 第一个字段名称
* @param field2Name 第二个字段名称
* @param fieldLabel 字段标签
* @param compareFunction 比较函数:(field1Value, field2Value) -> Boolean返回true表示通过
* @param errorMessage 自定义错误消息
* @return ValidationParam
*/
public static ValidationParam fieldCompare(String field1Name,
String field2Name,
String fieldLabel,
BiFunction<Object, Object, Boolean> compareFunction,
String errorMessage) {
return ValidationParam.builder()
.fieldName(field1Name)
.fieldLabel(fieldLabel)
.required(false)
.validateMethod(new FieldCompareValidateMethod(
field1Name,
field2Name,
fieldLabel,
compareFunction,
errorMessage
))
.build();
}
}

View File

@@ -0,0 +1,156 @@
package org.xyzh.common.utils.validation.method;
import java.lang.reflect.Field;
import java.util.function.BiFunction;
/**
* @description 字段比较校验方法,用于比较对象中的两个字段
* @filename FieldCompareValidateMethod.java
* @author Claude Code
* @copyright xyzh
* @since 2025-12-26
*/
public class FieldCompareValidateMethod implements ObjectValidateMethod {
/**
* 第一个字段名称
*/
private final String field1Name;
/**
* 第二个字段名称
*/
private final String field2Name;
/**
* 字段标签(用于错误消息)
*/
private final String fieldLabel;
/**
* 比较函数:(field1Value, field2Value) -> Boolean
* 返回 true 表示校验通过false 表示校验失败
*/
private final BiFunction<Object, Object, Boolean> compareFunction;
/**
* 自定义错误消息
*/
private final String customErrorMessage;
/**
* 构造函数
*
* @param field1Name 第一个字段名称
* @param field2Name 第二个字段名称
* @param fieldLabel 字段标签
* @param compareFunction 比较函数
* @param customErrorMessage 自定义错误消息
*/
public FieldCompareValidateMethod(String field1Name,
String field2Name,
String fieldLabel,
BiFunction<Object, Object, Boolean> compareFunction,
String customErrorMessage) {
this.field1Name = field1Name;
this.field2Name = field2Name;
this.fieldLabel = fieldLabel;
this.compareFunction = compareFunction;
this.customErrorMessage = customErrorMessage;
}
@Override
public Boolean validate(Object targetObject) {
if (targetObject == null) {
return true;
}
try {
// 获取第一个字段的值
Object field1Value = getFieldValue(targetObject, field1Name);
// 获取第二个字段的值
Object field2Value = getFieldValue(targetObject, field2Name);
// 如果任意字段为null跳过校验
if (field1Value == null || field2Value == null) {
return true;
}
// 执行比较函数
return compareFunction.apply(field1Value, field2Value);
} catch (Exception e) {
throw new RuntimeException("字段比较校验失败: " + e.getMessage(), e);
}
}
@Override
public String getErrorMessage() {
if (customErrorMessage != null && !customErrorMessage.trim().isEmpty()) {
return customErrorMessage;
}
return fieldLabel + "校验失败";
}
@Override
public String getName() {
return "字段比较校验";
}
/**
* 获取字段值(支持嵌套字段)
*
* @param obj 对象
* @param fieldName 字段名称(支持 "field" 或 "nested.field"
* @return 字段值
*/
private Object getFieldValue(Object obj, String fieldName) throws Exception {
if (fieldName == null || fieldName.trim().isEmpty()) {
return null;
}
// 支持嵌套字段访问(如 "user.name"
String[] fieldParts = fieldName.split("\\.");
Object currentObj = obj;
for (String part : fieldParts) {
if (currentObj == null) {
return null;
}
// 获取字段
Field field = findField(currentObj.getClass(), part);
if (field == null) {
throw new NoSuchFieldException("字段不存在: " + part);
}
// 设置可访问
field.setAccessible(true);
// 获取字段值
currentObj = field.get(currentObj);
}
return currentObj;
}
/**
* 查找字段(包括父类)
*
* @param clazz 类
* @param fieldName 字段名称
* @return 字段
*/
private Field findField(Class<?> clazz, String fieldName) {
Class<?> currentClass = clazz;
while (currentClass != null) {
try {
return currentClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
currentClass = currentClass.getSuperclass();
}
}
return null;
}
}