1. 手动合并存在重复被合并的文件,并统一包名

This commit is contained in:
chenbowen
2025-09-22 03:09:15 +08:00
parent 9a311fc3f6
commit 2a2fe74e78
5615 changed files with 85783 additions and 85832 deletions

View File

@@ -0,0 +1,27 @@
package com.zt.plat.framework.operatelog.config;
import com.mzt.logapi.service.ILogRecordService;
import com.mzt.logapi.starter.annotation.EnableLogRecord;
import com.zt.plat.framework.operatelog.core.service.LogRecordServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
/**
* 操作日志配置类
*
* @author HUIHUI
*/
@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦
@AutoConfiguration
@Slf4j
public class ZtOperateLogConfiguration {
@Bean
@Primary
public ILogRecordService iLogRecordServiceImpl() {
return new LogRecordServiceImpl();
}
}

View File

@@ -0,0 +1,15 @@
package com.zt.plat.framework.operatelog.config;
import com.zt.plat.framework.common.biz.system.logger.OperateLogCommonApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* OperateLog 使用到 Feign 的配置项
*
* @author ZT
*/
@AutoConfiguration
@EnableFeignClients(clients = {OperateLogCommonApi.class}) // 主要是引入相关的 API 服务
public class ZtOperateLogRpcAutoConfiguration {
}

View File

@@ -0,0 +1,4 @@
/**
* 占位,无特殊作用
*/
package com.zt.plat.framework.operatelog.core;

View File

@@ -0,0 +1,91 @@
package com.zt.plat.framework.operatelog.core.service;
import com.mzt.logapi.beans.LogRecord;
import com.mzt.logapi.service.ILogRecordService;
import com.zt.plat.framework.common.biz.system.logger.OperateLogCommonApi;
import com.zt.plat.framework.common.biz.system.logger.dto.OperateLogCreateReqDTO;
import com.zt.plat.framework.common.util.monitor.TracerUtils;
import com.zt.plat.framework.common.util.servlet.ServletUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 操作日志 ILogRecordService 实现类
*
* 基于 {@link OperateLogCommonApi} 实现,记录操作日志
*
* @author HUIHUI
*/
@Slf4j
public class LogRecordServiceImpl implements ILogRecordService {
@Resource
private OperateLogCommonApi operateLogApi;
@Override
public void record(LogRecord logRecord) {
OperateLogCreateReqDTO reqDTO = new OperateLogCreateReqDTO();
try {
reqDTO.setTraceId(TracerUtils.getTraceId());
// 补充用户信息
fillUserFields(reqDTO);
// 补全模块信息
fillModuleFields(reqDTO, logRecord);
// 补全请求信息
fillRequestFields(reqDTO);
// 2. 异步记录日志
operateLogApi.createOperateLogAsync(reqDTO);
} catch (Throwable ex) {
// 由于 @Async 异步调用,这里打印下日志,更容易跟进
log.error("[record][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
}
}
private static void fillUserFields(OperateLogCreateReqDTO reqDTO) {
// 使用 SecurityFrameworkUtils。因为要考虑rpc、mq、job它其实不是 web
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if (loginUser == null) {
return;
}
reqDTO.setUserId(loginUser.getId());
reqDTO.setUserType(loginUser.getUserType());
}
public static void fillModuleFields(OperateLogCreateReqDTO reqDTO, LogRecord logRecord) {
reqDTO.setType(logRecord.getType()); // 大模块类型例如CRM 客户
reqDTO.setSubType(logRecord.getSubType());// 操作名称,例如:转移客户
reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 业务编号,例如:客户编号
reqDTO.setAction(logRecord.getAction());// 操作内容,例如:修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"}
}
private static void fillRequestFields(OperateLogCreateReqDTO reqDTO) {
// 获得 Request 对象
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
return;
}
// 补全请求信息
reqDTO.setRequestMethod(request.getMethod());
reqDTO.setRequestUrl(request.getRequestURI());
reqDTO.setUserIp(ServletUtils.getClientIP(request));
reqDTO.setUserAgent(ServletUtils.getUserAgent(request));
}
@Override
public List<LogRecord> queryLog(String bizNo, String type) {
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
}
@Override
public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) {
throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询");
}
}

View File

@@ -0,0 +1,7 @@
/**
* 基于 mzt-log 框架
* 实现操作日志功能
*
* @author HUIHUI
*/
package com.zt.plat.framework.operatelog;

View File

@@ -0,0 +1,35 @@
package com.zt.plat.framework.security.config;
import com.zt.plat.framework.web.config.WebProperties;
import jakarta.annotation.Resource;
import org.springframework.core.Ordered;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
/**
* 自定义的 URL 的安全配置
* 目的:每个 Maven Module 可以自定义规则!
*
* @author ZT
*/
public abstract class AuthorizeRequestsCustomizer
implements Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry>, Ordered {
@Resource
private WebProperties webProperties;
protected String buildAdminApi(String url) {
return webProperties.getAdminApi().getPrefix() + url;
}
protected String buildAppApi(String url) {
return webProperties.getAppApi().getPrefix() + url;
}
@Override
public int getOrder() {
return 0;
}
}

View File

@@ -0,0 +1,51 @@
package com.zt.plat.framework.security.config;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import java.util.Collections;
import java.util.List;
@ConfigurationProperties(prefix = "zt.security")
@Validated
@Data
public class SecurityProperties {
/**
* HTTP 请求时,访问令牌的请求 Header
*/
@NotEmpty(message = "Token Header 不能为空")
private String tokenHeader = "Authorization";
/**
* HTTP 请求时,访问令牌的请求参数
*
* 初始目的:解决 WebSocket 无法通过 header 传参,只能通过 token 参数拼接
*/
@NotEmpty(message = "Token Parameter 不能为空")
private String tokenParameter = "token";
/**
* mock 模式的开关
*/
@NotNull(message = "mock 模式的开关不能为空")
private Boolean mockEnable = false;
/**
* mock 模式的密钥
* 一定要配置密钥,保证安全性
*/
@NotEmpty(message = "mock 模式的密钥不能为空") // 这里设置了一个默认值,因为实际上只有 mockEnable 为 true 时才需要配置。
private String mockSecret = "test";
/**
* 免登录的 URL 列表
*/
private List<String> permitAllUrls = Collections.emptyList();
/**
* PasswordEncoder 加密复杂度,越高开销越大
*/
private Integer passwordEncoderLength = 4;
}

View File

@@ -0,0 +1,94 @@
package com.zt.plat.framework.security.config;
import com.zt.plat.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.security.core.context.TransmittableThreadLocalSecurityContextHolderStrategy;
import com.zt.plat.framework.security.core.filter.TokenAuthenticationFilter;
import com.zt.plat.framework.security.core.handler.AccessDeniedHandlerImpl;
import com.zt.plat.framework.security.core.handler.AuthenticationEntryPointImpl;
import com.zt.plat.framework.security.core.service.SecurityFrameworkService;
import com.zt.plat.framework.security.core.service.SecurityFrameworkServiceImpl;
import com.zt.plat.framework.web.core.handler.GlobalExceptionHandler;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
/**
* Spring Security 自动配置类,主要用于相关组件的配置
*
* 注意,不能和 {@link ZtWebSecurityConfigurerAdapter} 用一个,原因是会导致初始化报错。
* 参见 https://stackoverflow.com/questions/53847050/spring-boot-delegatebuilder-cannot-be-null-on-autowiring-authenticationmanager 文档。
*
* @author ZT
*/
@AutoConfiguration
@AutoConfigureOrder(-1) // 目的:先于 Spring Security 自动配置避免一键改包后org.* 基础包无法生效
@EnableConfigurationProperties(SecurityProperties.class)
public class ZtSecurityAutoConfiguration {
@Resource
private SecurityProperties securityProperties;
/**
* 认证失败处理类 Bean
*/
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return new AuthenticationEntryPointImpl();
}
/**
* 权限不够处理器 Bean
*/
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new AccessDeniedHandlerImpl();
}
/**
* Spring Security 加密器
* 考虑到安全性,这里采用 BCryptPasswordEncoder 加密器
*
* @see <a href="http://stackabuse.com/password-encoding-with-spring-security/">Password Encoding with Spring Security</a>
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(securityProperties.getPasswordEncoderLength());
}
/**
* Token 认证过滤器 Bean
*/
@Bean
public TokenAuthenticationFilter authenticationTokenFilter(GlobalExceptionHandler globalExceptionHandler,
OAuth2TokenCommonApi oauth2TokenApi) {
return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
}
@Bean("ss") // 使用 Spring Security 的缩写,方便使用
public SecurityFrameworkService securityFrameworkService(PermissionCommonApi permissionApi) {
return new SecurityFrameworkServiceImpl(permissionApi);
}
/**
* 声明调用 {@link SecurityContextHolder#setStrategyName(String)} 方法,
* 设置使用 {@link TransmittableThreadLocalSecurityContextHolderStrategy} 作为 Security 的上下文策略
*/
@Bean
public MethodInvokingFactoryBean securityContextHolderMethodInvokingFactoryBean() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
methodInvokingFactoryBean.setTargetMethod("setStrategyName");
methodInvokingFactoryBean.setArguments(TransmittableThreadLocalSecurityContextHolderStrategy.class.getName());
return methodInvokingFactoryBean;
}
}

View File

@@ -0,0 +1,25 @@
package com.zt.plat.framework.security.config;
import com.zt.plat.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.security.core.rpc.LoginUserRequestInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
/**
* Security 使用到 Feign 的配置项
*
* @author ZT
*/
@AutoConfiguration
@EnableFeignClients(clients = {OAuth2TokenCommonApi.class, // 主要是引入相关的 API 服务
PermissionCommonApi.class})
public class ZtSecurityRpcAutoConfiguration {
@Bean
public LoginUserRequestInterceptor loginUserRequestInterceptor() {
return new LoginUserRequestInterceptor();
}
}

Some files were not shown because too many files have changed in this diff Show More