功能:在保险、规则、交易、积分和短信模块中实现初始功能和基础组件。

This commit is contained in:
abcv7
2026-03-03 04:04:22 +08:00
parent e050eb3317
commit e156d625bf
1999 changed files with 146080 additions and 63 deletions
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>sfbx-framework</artifactId>
<groupId>com.itheima.sfbx</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<!--基础模块-web支持-->
<artifactId>framework-web</artifactId>
<name>framework-web</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-redis</artifactId>
</dependency>
<dependency>
<groupId>com.itheima.sfbx</groupId>
<artifactId>framework-knife4j-web</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,12 @@
package com.itheima.sfbx.framework.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveResponse {
}
@@ -0,0 +1,52 @@
package com.itheima.sfbx.framework.aspect;
import com.alibaba.fastjson.JSONObject;
import com.itheima.sfbx.framework.anno.SensitiveResponse;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* @ClassName SensitiveAspect.java
* @Description TODO
*/
@Aspect
@Component
public class SensitiveAspect {
@Around(value = "@annotation(sensitiveResponse)")
public Object select(ProceedingJoinPoint joinPoint, SensitiveResponse sensitiveResponse) throws Throwable {
// 执行目标方法
Object result = joinPoint.proceed();
// 获取目标方法
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
// 获取目标方法的泛型返回类型
Type genericReturnType = method.getGenericReturnType();
if (!EmptyUtil.isNullOrEmpty(result)){
// 进行脱敏处理
String jsonResponse = JSONObject.toJSONString(result);
String maskedResponse = maskSensitiveData(jsonResponse);
// 将脱敏后的数据转换为实际返回类型
return JSONObject.parseObject(maskedResponse,genericReturnType);
}
return result;
}
private String maskSensitiveData(String jsonData) {
//使用正则表单式替换,我也不会写~~直接GPT搞定!
return jsonData
.replaceAll("\"identityCard\"\\s*:\\s*\"(\\d{1})(\\d{15})(\\d{2})\"", "\"identityCard\":\"$1**************$3\"")
.replaceAll("\"name\"\\s*:\\s*\"(.).+?\"", "\"name\":\"$1*\"")
.replaceAll("\"bankCardNo\"\\s*:\\s*\"(.).+?\"", "\"bankCardNo\":\"$1*\"")
.replaceAll("\"bankName\"\\s*:\\s*\"(.).+?\"", "\"bankName\":\"$1*\"")
.replaceAll("\"bankReservedPhoneNum\"\\s*:\\s*\"(.).+?\"", "\"bankReservedPhoneNum\":\"$1*\"");
}
}
@@ -0,0 +1,33 @@
package com.itheima.sfbx.framework.config;
import com.itheima.sfbx.framework.intercept.CompanyCheckIntercept;
import com.itheima.sfbx.framework.intercept.WebAuthIntercept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @ClassName WebMvcConfig.java
* @Description webMvc高级配置
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
WebAuthIntercept webAuthIntercept;
@Autowired
CompanyCheckIntercept companyCheckIntercept;
/**
* @Description 拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//多租户拦截
registry.addInterceptor(webAuthIntercept).addPathPatterns("/**");
//数字签名拦截
registry.addInterceptor(companyCheckIntercept).addPathPatterns("/coefficent/**");
}
}
@@ -0,0 +1,26 @@
package com.itheima.sfbx.framework.intercept;
import com.itheima.sfbx.framework.commons.constant.security.SecurityConstant;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName CompanyCheckIntercept.java
* @Description 企业请求appSecret的安全校验
*/
@Component
public class CompanyCheckIntercept implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//从头部中拿到当前appSecret
String appSecret = request.getHeader(SecurityConstant.APP_SECRET);
//校验
return true;
}
}
@@ -0,0 +1,56 @@
package com.itheima.sfbx.framework.intercept;
import com.itheima.sfbx.framework.commons.constant.security.OauthCacheConstant;
import com.itheima.sfbx.framework.commons.constant.security.SecurityConstant;
import com.itheima.sfbx.framework.commons.dto.security.UserVO;
import com.itheima.sfbx.framework.commons.utils.EmptyUtil;
import com.itheima.sfbx.framework.commons.utils.SubjectContent;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName WebAuthIntercept.java
* @Description 认证信息放到SubjectContent上下文中
*/
@Component
public class WebAuthIntercept implements HandlerInterceptor {
@Autowired
RedissonClient redissonClient;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
//从头部中拿到当前userToken
String userToken = request.getHeader(SecurityConstant.USER_TOKEN);
if (!EmptyUtil.isNullOrEmpty(userToken)){
RBucket<UserVO> userVORBucket = redissonClient.getBucket(OauthCacheConstant.USER_TOKEN + userToken);
UserVO userVO = userVORBucket.get();
//放入当前线程中:用户当前的web直接获得userVO使用
SubjectContent.setUserVO(userVO);
//下游传递userToken
SubjectContent.setUserToken(userToken);
//下游传递companyNo
SubjectContent.setCompanyNo(userVO.getCompanyNo());
//下游传递companyNo
SubjectContent.setDataSecurityVO(userVO.getDataSecurityVO());
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
//移除当前线程中的参数
SubjectContent.removeUserVO();
SubjectContent.removeUserToken();
SubjectContent.removeCompanyNo();
SubjectContent.removeDataSecurityVO();
}
}
@@ -0,0 +1,58 @@
package com.itheima.sfbx.framework.web;
import com.itheima.sfbx.framework.commons.basic.ResponseResult;
import com.itheima.sfbx.framework.commons.enums.basic.BaseEnum;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.framework.commons.utils.ExceptionsUtil;
import com.itheima.sfbx.framework.commons.utils.ResponseResultBuild;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @ClassName BaseController.java
* @Description 基础的controller
* ControllerAdvice:对controller层的增强,其他的controller则不需要继承,也会被拦截处理
*/
@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionController {
/**
* 对于项目中业务异常进行处理
* 由开发人员在处理业务代码时主动抛出的异常信息
* */
@ExceptionHandler(ProjectException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult<Object> prodException(ProjectException e) {
log.error("【业务操作异常】{}",e.getMessage());
return ResponseResultBuild.build(e.getBaseEnum(), e.getMessage());
}
/**
* 对于项目中Validation数据校验异常处理
* 校验Controller层接收数据的合法性
* */
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult<String> vaildDataException(MethodArgumentNotValidException manvExceptionex) {
log.warn("【数据校验异常】:{} ", manvExceptionex.getMessage());
return ResponseResultBuild.build(BaseEnum.VALID_EXCEPTION, manvExceptionex.getMessage());
}
/**
* 项目中框架级别或没有指定的异常处理
* */
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseResult<String> topException(Exception ex) {
log.error("【系统运行异常】:{}", ExceptionsUtil.getStackTraceAsString(ex));
return ResponseResultBuild.build(BaseEnum.SYSYTEM_FAIL, ex.getMessage());
}
}