v3.26.0 【优化】分页请求2次;【优化】菜单展开单个代码优化;【优化】操作记录返回结果;【优化】json viewer升级;【优化】S3协议优化;【优化】代码生成字典优化;

This commit is contained in:
zhuoda
2025-08-10 13:02:01 +08:00
parent 8135e0ec10
commit d2c55e35ff
109 changed files with 309 additions and 266 deletions

View File

@@ -67,7 +67,7 @@ public class AdminInterceptor implements HandlerInterceptor {
Method method = ((HandlerMethod) handler).getMethod();
NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class);
if (noNeedLogin != null) {
checkActiveTimeout(requestEmployee);
updateActiveTimeout(requestEmployee);
SmartRequestUtil.setRequestUser(requestEmployee);
return true;
}
@@ -77,8 +77,8 @@ public class AdminInterceptor implements HandlerInterceptor {
return false;
}
// 检测token 活跃频率
checkActiveTimeout(requestEmployee);
// 更新活跃
updateActiveTimeout(requestEmployee);
// --------------- 第三步: 校验 权限 ---------------
@@ -123,15 +123,12 @@ public class AdminInterceptor implements HandlerInterceptor {
/**
* 检测token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结
* 更新活跃时间
*/
private void checkActiveTimeout(RequestEmployee requestEmployee) {
// 用户不在线,也不用检测
private void updateActiveTimeout(RequestEmployee requestEmployee) {
if (requestEmployee == null) {
return;
}
StpUtil.checkActiveTimeout();
StpUtil.updateLastActiveToNow();
}

View File

@@ -81,7 +81,7 @@ public class FileConfig implements WebMvcConfigurer {
StaticCredentialsProvider.create(
AwsBasicCredentials.create(accessKey, secretKey)))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(false)
.pathStyleAccessEnabled(true)
.chunkedEncodingEnabled(false)
.build())
.build();

View File

@@ -101,7 +101,18 @@ public class FileStorageCloudServiceImpl implements IFileStorageService {
userMetadata.put(USER_METADATA_FILE_FORMAT, fileType);
userMetadata.put(USER_METADATA_FILE_SIZE, String.valueOf(file.getSize()));
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(cloudConfig.getBucketName()).key(fileKey).metadata(userMetadata).contentLength(file.getSize()).contentType(this.getContentType(fileType)).contentEncoding(StandardCharsets.UTF_8.name()).contentDisposition("attachment;filename=" + urlEncoderFilename).build();
// 根据文件路径获取并设置访问权限
ObjectCannedACL acl = this.getACL(path);
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(cloudConfig.getBucketName())
.key(fileKey)
.metadata(userMetadata)
.contentLength(file.getSize())
.contentType(this.getContentType(fileType))
.contentEncoding(StandardCharsets.UTF_8.name())
.contentDisposition("attachment;filename=" + urlEncoderFilename)
.acl(acl)
.build();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
@@ -112,10 +123,6 @@ public class FileStorageCloudServiceImpl implements IFileStorageService {
} finally {
IOUtils.closeQuietly(inputStream);
}
// 根据文件路径获取并设置访问权限
ObjectCannedACL acl = this.getACL(path);
PutObjectAclRequest aclRequest = PutObjectAclRequest.builder().bucket(cloudConfig.getBucketName()).key(fileKey).acl(this.getACL(path)).build();
s3Client.putObjectAcl(aclRequest);
// 返回上传结果
FileUploadVO uploadVO = new FileUploadVO();
uploadVO.setFileName(originalFileName);

View File

@@ -11,6 +11,7 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartIpUtil;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.operatelog.OperateLogDao;
@@ -46,7 +47,7 @@ import java.util.concurrent.ThreadPoolExecutor;
* @Date 2021-12-08 20:48:52
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Aspect
@@ -71,14 +72,14 @@ public abstract class OperateLogAspect {
public void logPointCut() {
}
@AfterReturning(pointcut = "logPointCut()")
public void doAfterReturning(JoinPoint joinPoint) {
handleLog(joinPoint, null);
@AfterReturning(pointcut = "logPointCut()", returning = "responseDTO")
public void doAfterReturning(JoinPoint joinPoint, Object responseDTO) {
handleLog(joinPoint, null, responseDTO);
}
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e);
handleLog(joinPoint, e, null);
}
/**
@@ -109,16 +110,15 @@ public abstract class OperateLogAspect {
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
}
protected void handleLog(final JoinPoint joinPoint, final Exception e) {
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object responseDTO) {
try {
OperateLog operateLog = this.getAnnotationLog(joinPoint);
if (operateLog == null) {
return;
}
this.submitLog(joinPoint, e);
this.submitLog(joinPoint, e, responseDTO);
} catch (Exception exp) {
log.error("保存操作日志异常:{}", exp.getMessage());
exp.printStackTrace();
}
}
@@ -173,11 +173,8 @@ public abstract class OperateLogAspect {
/**
* 提交存储操作日志
*
* @param joinPoint
* @param e
* @throws Exception
*/
private void submitLog(final JoinPoint joinPoint, final Throwable e) throws Exception {
private void submitLog(final JoinPoint joinPoint, final Throwable e, Object responseDTO) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//设置用户信息
RequestUser user = SmartRequestUtil.getRequestUser();
@@ -191,7 +188,7 @@ public abstract class OperateLogAspect {
String methodName = joinPoint.getSignature().getName();
String operateMethod = className + "." + methodName;
String failReason = null;
Boolean successFlag = true;
boolean successFlag = true;
if (e != null) {
successFlag = false;
failReason = getExceptionString(e);
@@ -210,15 +207,32 @@ public abstract class OperateLogAspect {
.userAgent(user.getUserAgent())
.failReason(failReason)
.successFlag(successFlag).build();
Operation apiOperation = this.getApiOperation(joinPoint);
if (apiOperation != null) {
operateLogEntity.setContent(apiOperation.summary());
}
Tag api = this.getApi(joinPoint);
if (api != null) {
String name = api.name();
operateLogEntity.setModule(StrUtil.join(",", name));
}
// 处理返回值 ResponseDTO
if(responseDTO instanceof ResponseDTO) {
ResponseDTO response = (ResponseDTO) responseDTO;
ResponseDTO logResponseDTO = new ResponseDTO(
response.getCode(),
response.getLevel(),
response.getOk(),
response.getMsg(),
null
);
logResponseDTO.setDataType(response.getDataType());
operateLogEntity.setResponse(JSON.toJSONString(logResponseDTO));
}
taskExecutor.execute(() -> {
this.saveLog(operateLogEntity);
});

View File

@@ -71,6 +71,11 @@ public class OperateLogEntity {
*/
private String param;
/**
* 返回值
*/
private String response;
/**
* 客户ip
*/

View File

@@ -47,6 +47,9 @@ public class OperateLogVO {
@Schema(description = "请求参数")
private String param;
@Schema(description = "返回值")
private String response;
@Schema(description = "客户ip")
private String ip;

View File

@@ -48,7 +48,7 @@
#end
#if($field.frontComponent == "DictSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<DictSelect width="100%" v-model:value="form.${field.fieldName}" dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
<DictSelect width="100%" v-model:value="form.${field.fieldName}" :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "Date")
@@ -106,7 +106,7 @@
#end
#if($field.frontComponent == "DictSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<DictSelect width="100%" v-model:value="form.${field.fieldName}" dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
<DictSelect width="100%" v-model:value="form.${field.fieldName}" :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "Date")

View File

@@ -22,7 +22,7 @@
#end
#if($field.queryTypeEnum == "Dict")
<a-form-item label="${field.label}" class="smart-query-form-item">
<DictSelect dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
<DictSelect :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
</a-form-item>
#end
#if($field.queryTypeEnum == "Enum")

View File

@@ -48,7 +48,7 @@
#end
#if($field.frontComponent == "DictSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<DictSelect width="100%" v-model:value="form.${field.fieldName}" dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
<DictSelect width="100%" v-model:value="form.${field.fieldName}" :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "Date")
@@ -106,7 +106,7 @@
#end
#if($field.frontComponent == "DictSelect")
<a-form-item label="$codeGeneratorTool.removeEnumDesc($!{field.label})" name="${field.fieldName}">
<DictSelect width="100%" v-model:value="form.${field.fieldName}" dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
<DictSelect width="100%" v-model:value="form.${field.fieldName}" :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="$!{field.label}"/>
</a-form-item>
#end
#if($field.frontComponent == "Date")

View File

@@ -22,7 +22,7 @@
#end
#if($field.queryTypeEnum == "Dict")
<a-form-item label="${field.label}" class="smart-query-form-item">
<DictSelect dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
<DictSelect :dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
</a-form-item>
#end
#if($field.queryTypeEnum == "Enum")

View File

@@ -26,7 +26,7 @@
AND (INSTR(module,#{query.keywords}) OR INSTR(content,#{query.keywords}))
</if>
<if test="query.requestKeywords != null and query.requestKeywords != ''">
AND (INSTR(url,#{query.requestKeywords}) OR INSTR(method,#{query.requestKeywords}) OR INSTR(param,#{query.requestKeywords}))
AND (INSTR(url,#{query.requestKeywords}) OR INSTR(method,#{query.requestKeywords}) OR INSTR(param,#{query.requestKeywords}) OR INSTR(response,#{query.requestKeywords}))
</if>
<if test="query.successFlag != null">
AND success_flag = #{query.successFlag}