租移动
This commit is contained in:
@@ -9,6 +9,11 @@ import com.yunhai.bschclassmanage.utils.OtherUtil;
|
||||
import com.yunhai.bschclassmanage.utils.SensitiveDataUtil;
|
||||
import com.yunhai.bschclassmanage.utils.SyncLogRetryContext;
|
||||
import com.yunhai.bschclassmanage.utils.UserContext;
|
||||
import com.yunhai.platform.apistd.ApiResponse;
|
||||
import com.yunhai.platform.utils.exception.DException;
|
||||
import com.yunhai.platform.utils.exception.ErrorCode;
|
||||
import com.yunhai.platform.utils.exception.IErrorCode;
|
||||
import com.yunhai.platform.utils.http.ApiResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
@@ -70,11 +75,11 @@ public class SysOperationLogAspect {
|
||||
Object result = null;
|
||||
try {
|
||||
result = point.proceed();
|
||||
entity.setStatusCode(200);
|
||||
entity.setStatusCode(resolveSuccessCode(result));
|
||||
fillResponse(entity, result, DEFAULT_MAX_RESPONSE_SIZE);
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
entity.setStatusCode(500);
|
||||
entity.setStatusCode(resolveErrorCode(e));
|
||||
entity.setErrorMsg(buildErrorMsg(e));
|
||||
throw e;
|
||||
} finally {
|
||||
@@ -144,6 +149,35 @@ public class SysOperationLogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功路径:提取全局返回对象的业务状态码。
|
||||
* - Controller 直接返回 ApiResponse / ApiResult 时取其 code;
|
||||
* - 其余(普通对象 / void / null)由平台 ApiResponseAdvice 统一包装为 success,code = SUCCESS(0)。
|
||||
*/
|
||||
private int resolveSuccessCode(Object result) {
|
||||
if (result instanceof ApiResponse) {
|
||||
return ((ApiResponse<?>) result).getCode();
|
||||
}
|
||||
if (result instanceof ApiResult) {
|
||||
return ((ApiResult<?>) result).getCode();
|
||||
}
|
||||
return ErrorCode.SUCCESS.getCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常路径:从业务异常提取错误码,兜底 INTERNAL_SERVER_ERROR。
|
||||
* DException.getCode() 返回 IErrorCode(可能为 null),需二次取 int code。
|
||||
*/
|
||||
private int resolveErrorCode(Throwable e) {
|
||||
if (e instanceof DException) {
|
||||
IErrorCode ec = ((DException) e).getCode();
|
||||
if (ec != null) {
|
||||
return ec.getCode();
|
||||
}
|
||||
}
|
||||
return ErrorCode.INTERNAL_SERVER_ERROR.getCode();
|
||||
}
|
||||
|
||||
private HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes a = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return a != null ? a.getRequest() : null;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.yunhai.bschclassmanage.controller.api;
|
||||
|
||||
import com.yunhai.bschclassmanage.config.Config;
|
||||
import com.yunhai.bschclassmanage.enums.NodeType;
|
||||
import com.yunhai.bschclassmanage.model.dto.SendMoveUserGroupDTO;
|
||||
import com.yunhai.bschclassmanage.model.dto.SendUserGroupDTO;
|
||||
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
|
||||
import com.yunhai.bschclassmanage.service.ISendUserBaseService;
|
||||
import com.yunhai.bschclassmanage.utils.UserContext;
|
||||
import com.yunhai.platform.openapi.client.YschBaseOpenApi;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping(Config.API_PATH+"/usergroup/")
|
||||
@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true")
|
||||
public class SchUserGroupController {
|
||||
|
||||
@Autowired
|
||||
private ISendUserBaseService sendUserBaseService;
|
||||
|
||||
|
||||
@GetMapping("getNodeType")
|
||||
public List<SelectIntVO> getNodeType() {
|
||||
return NodeType.select();
|
||||
}
|
||||
|
||||
@GetMapping("addGroup")
|
||||
public void addGroup(@Valid @RequestBody SendUserGroupDTO groupdto) {
|
||||
sendUserBaseService.addGroup(groupdto.getName(),groupdto.getParentId(),groupdto.getSort(),NodeType.getById(groupdto.getType()),UserContext.getSchId());
|
||||
}
|
||||
|
||||
@GetMapping("editGroup")
|
||||
public void editGroup(@Valid @RequestBody SendUserGroupDTO groupdto) {
|
||||
sendUserBaseService.editGroup(groupdto.getId(),groupdto.getName(),groupdto.getParentId(),groupdto.getSort(),NodeType.getById(groupdto.getType()),UserContext.getSchId());
|
||||
}
|
||||
|
||||
@GetMapping("deleteGroup")
|
||||
public void deleteGroup(@RequestParam Integer id) {
|
||||
sendUserBaseService.deleteGroup(id,UserContext.getSchId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class SysOperationLog implements Serializable {
|
||||
private byte[] responseData; // GZIP 压缩后的响应 JSON
|
||||
|
||||
@Column(name = "status_code", nullable = false)
|
||||
private Integer statusCode; // 200 成功 / 500 异常
|
||||
private Integer statusCode; // 业务状态码:0 成功 / 非 0 失败(全局返回对象 code)
|
||||
|
||||
@Column(name = "cost_time", nullable = false)
|
||||
private Long costTime; // ms
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.yunhai.bschclassmanage.enums;
|
||||
|
||||
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@@ -80,4 +82,10 @@ public enum NodeType {
|
||||
|
||||
return null;
|
||||
}
|
||||
public static List<SelectIntVO> select() {
|
||||
List<SelectIntVO> list= CourseType.list().stream()
|
||||
.map(type -> new SelectIntVO(type.getId(), type.getName()))
|
||||
.collect(Collectors.toList());
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.yunhai.bschclassmanage.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 添加组员请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class SendMoveUserGroupDTO {
|
||||
@NotNull(message = "用户称不能为空")
|
||||
private Integer userId;
|
||||
@NotNull(message = "请选择移动组")
|
||||
private Integer groupId;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.yunhai.bschclassmanage.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 添加组员请求DTO
|
||||
*/
|
||||
@Data
|
||||
public class SendUserGroupDTO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
@NotNull(message = "组名称不能为空")
|
||||
private String name;
|
||||
|
||||
@NotNull(message = "请选择父节点")
|
||||
private Integer parentId;
|
||||
|
||||
@NotNull(message = "教师ID列表不能为空")
|
||||
private List<Integer> teaIds;
|
||||
|
||||
@NotNull(message = "请选择组类型")
|
||||
private Integer type;
|
||||
|
||||
private Integer sort;
|
||||
}
|
||||
+3
-3
@@ -110,7 +110,7 @@ public class SysOperationLogServiceImpl implements ISysOperationLogService {
|
||||
/**
|
||||
* 重试:按记录的 classMethod + requestParams 反射重放原始 Controller 操作。
|
||||
* 说明:
|
||||
* - 仅允许 statusCode != 200(失败)的记录重试;
|
||||
* - 仅允许 statusCode != 0(失败)的记录重试;
|
||||
* - 仅支持入参为 JSON 数组形式(POST body / @RequestBody)。GET query 串无法可靠重建,直接拒绝;
|
||||
* - 经 Spring 代理调用,会再次走 SysOperationLogAspect 切面、生成一条新的审计日志;
|
||||
* - 重放前还原原操作人上下文(UserContext),使新审计日志记录正确的操作人;
|
||||
@@ -121,8 +121,8 @@ public class SysOperationLogServiceImpl implements ISysOperationLogService {
|
||||
public Object retry(Long id) {
|
||||
SysOperationLog e = getById(id);
|
||||
if (e == null) throw new DException("审计日志不存在(id=" + id + ")");
|
||||
if (e.getStatusCode() != null && e.getStatusCode() == 200) {
|
||||
throw new DException("该操作已成功(statusCode=200),无需重试");
|
||||
if (e.getStatusCode() != null && e.getStatusCode() == 0) {
|
||||
throw new DException("该操作已成功(statusCode=0),无需重试");
|
||||
}
|
||||
// 多校隔离:不允许重试其他学校的操作日志
|
||||
if (e.getSchId() != null && UserContext.getSchId() != null
|
||||
|
||||
Reference in New Issue
Block a user