Browse Source

12.3 冲刺计划累计充值

huangqizheng/feature-20251203174217-冲刺计划
huangqizhen 1 month ago
parent
commit
5554d943d1
  1. 1
      src/main/java/com/example/demo/DemoApplication.java
  2. 370
      src/main/java/com/example/demo/config/GlobalExceptionHandler.java
  3. 39
      src/main/java/com/example/demo/controller/Temporary/RedController.java
  4. 32
      src/main/java/com/example/demo/domain/vo/Red.java
  5. 19
      src/main/java/com/example/demo/mapper/Temporary/RedMapper.java
  6. 2
      src/main/java/com/example/demo/security/SecurityConfig.java
  7. 17
      src/main/java/com/example/demo/service/Temporary/RedService.java
  8. 35
      src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java
  9. 9
      src/main/resources/mapper/RedMapper.xml

1
src/main/java/com/example/demo/DemoApplication.java

@ -16,6 +16,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@MapperScan(basePackages = "com.example.demo.mapper.live", sqlSessionTemplateRef = "mysql5SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.sqlserver", sqlSessionTemplateRef = "sqlserver1SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.cash", sqlSessionTemplateRef = "mysql1SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.Temporary", sqlSessionTemplateRef = "mysql1SqlSessionTemplate")
public class DemoApplication {
public static void main(String[] args) {

370
src/main/java/com/example/demo/config/GlobalExceptionHandler.java

@ -0,0 +1,370 @@
package com.example.demo.config;
import cn.hutool.core.io.resource.NoResourceException;
import com.example.demo.Util.BusinessException;
import com.example.demo.Util.ExecutionContextUtil;
import com.example.demo.Util.FeiShuAlertUtil;
import com.example.demo.domain.vo.coin.ExecutionContext;
import com.example.demo.domain.vo.coin.Result;
import com.example.demo.exception.SystemException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.micrometer.common.util.StringUtils;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.stream.Collectors;
/**
* 全局异常处理器 - 优化封装版
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// ==================== 业务异常处理 ====================
/**
* 处理业务异常
*/
@ExceptionHandler({BusinessException.class})
@ResponseBody
public ResponseEntity<Result> handleBusinessException(BusinessException e) {
logger.warn("业务异常: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.OK).body(Result.error(e));
}
/**
* 处理系统异常
*/
@ExceptionHandler(SystemException.class)
@ResponseBody
public ResponseEntity<Result> handleSystemException(SystemException e) {
logger.error("系统异常: ", e);
// 发送飞书报警
sendFeishuAlert(e, "系统异常: " + e.getMessage(), getCauseMessage(e));
// 返回通用的错误信息
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException("正在为您努力加载中...")));
}
// ==================== 资源未找到异常处理 ====================
/**
* 处理资源未找到异常
*/
@ExceptionHandler(NoResourceFoundException.class)
@ResponseBody
public ResponseEntity<Result> handleNoResourceFoundException(NoResourceFoundException e) {
logger.warn("资源未找到: {} - {}", e.getHttpMethod(), e.getResourcePath());
String errorMessage = String.format("接口[%s %s]不存在,请检查接口地址",
e.getHttpMethod(), e.getResourcePath());
Result result = Result.error(new BusinessException(404, errorMessage));
return ResponseEntity.status(HttpStatus.OK).body(result);
}
// ==================== 参数校验异常处理 ====================
/**
* 处理参数校验异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<Result> handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
String errorMessage = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
logger.warn("参数校验异常: {}", errorMessage);
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException(errorMessage)));
}
/**
* 处理约束违反异常
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResponseEntity<Result> handleConstraintViolation(ConstraintViolationException e) {
String errorMessage = e.getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
logger.warn("约束违反异常: {}", errorMessage);
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException(errorMessage)));
}
/**
* 处理请求方法不支持异常
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseBody
public ResponseEntity<Result> handleHttpRequestMethodNotSupported(
HttpRequestMethodNotSupportedException e) {
String errorMessage = "请求方法不支持,请使用: " + e.getSupportedHttpMethods();
logger.warn("请求方法不支持: {}", e.getMethod());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException(errorMessage)));
}
/**
* 处理参数类型不匹配异常
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseBody
public ResponseEntity<Result> handleMethodArgumentTypeMismatch(
MethodArgumentTypeMismatchException e) {
String errorMessage = handleTypeMismatch(e);
logger.warn("参数类型不匹配: {} - {}", e.getName(), e.getValue());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException(errorMessage)));
}
// /**
// * 处理表单绑定异常
// */
// @ExceptionHandler(BindException.class)
// @ResponseBody
// public ResponseEntity<Result> handleBindException(BindException e) {
// String errorMessage = handleBindException(e);
// logger.warn("表单绑定异常: {}", errorMessage);
// return ResponseEntity.status(HttpStatus.OK)
// .body(Result.error(new BusinessException(errorMessage)));
// }
/**
* 处理缺失请求参数异常
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public ResponseEntity<Result> handleMissingServletRequestParameter(
MissingServletRequestParameterException e) {
String errorMessage = handleMissingParameter(e);
logger.warn("缺失请求参数: {}", e.getParameterName());
return ResponseEntity.status(HttpStatus.OK)
.body(Result.error(new BusinessException(errorMessage)));
}
/**
* 处理请求体不可读异常
*/
// @ExceptionHandler(HttpMessageNotReadableException.class)
// @ResponseBody
// public ResponseEntity<Result> handleHttpMessageNotReadable(
// HttpMessageNotReadableException e) {
//
// String errorMessage = handleHttpMessageNotReadable(e);
// logger.warn("请求体不可读: {}", e.getMessage());
// return ResponseEntity.status(HttpStatus.BAD_REQUEST)
// .body(Result.error(new BusinessException(errorMessage)));
// }
// ==================== 通用异常处理 ====================
/**
* 处理未预期的异常
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<Result> handleUnexpectedException(Exception e) {
// 如果是参数校验相关异常已经被上面的方法处理这里作为兜底
if (isValidationException(e)) {
String errorMessage = getValidationErrorMessage(e);
logger.warn("参数校验异常(兜底): {}", errorMessage);
Result result = Result.error(new BusinessException(errorMessage));
return ResponseEntity.status(HttpStatus.OK).body(result);
}
logger.error("未预期异常: {}", e.getMessage(), e);
// 发送飞书报警
sendFeishuAlert(e, "未预期异常: " + e.getClass().getName(), e.getMessage());
// 返回通用错误信息
Result result = Result.error(new BusinessException("正在为您努力加载中..."));
return ResponseEntity.status(HttpStatus.OK).body(result);
}
// ==================== 异常处理工具方法 ====================
/**
* 发送飞书报警
*/
private void sendFeishuAlert(Exception e, String title, String detail) {
ExecutionContext context = ExecutionContextUtil.getExecutionContext();
if (context != null) {
String message = title;
if (StringUtils.isNotBlank(detail)) {
message += "\n错误详情: " + detail;
}
FeiShuAlertUtil.sendAlertMessage(
context,
e.getStackTrace()[0].getFileName(),
e.getStackTrace()[0].getLineNumber(),
message,
context.getRequestParams()
);
}
}
/**
* 获取异常原因信息
*/
private String getCauseMessage(Exception e) {
if (e.getCause() != null) {
return e.getCause().getMessage();
}
return "";
}
/**
* 判断是否是字段校验异常
*/
private boolean isValidationException(Exception e) {
return e instanceof MethodArgumentNotValidException ||
e instanceof ConstraintViolationException ||
e instanceof HttpMessageNotReadableException ||
e instanceof HttpRequestMethodNotSupportedException ||
e instanceof MethodArgumentTypeMismatchException ||
e instanceof BindException ||
e instanceof MissingServletRequestParameterException ||
e instanceof NoHandlerFoundException ||
e instanceof NoResourceException;
}
/**
* 获取校验异常的错误信息兜底方法
*/
private String getValidationErrorMessage(Exception e) {
if (e instanceof MethodArgumentNotValidException) {
return ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
} else if (e instanceof ConstraintViolationException) {
return ((ConstraintViolationException) e).getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
} else if (e instanceof MethodArgumentTypeMismatchException) {
return handleTypeMismatch((MethodArgumentTypeMismatchException) e);
} else if (e instanceof BindException) {
return handleBindException((BindException) e);
} else if (e instanceof MissingServletRequestParameterException) {
return handleMissingParameter((MissingServletRequestParameterException) e);
} else if (e instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable((HttpMessageNotReadableException) e);
} else if (e instanceof HttpRequestMethodNotSupportedException) {
return "请求方法不支持,请使用: " + ((HttpRequestMethodNotSupportedException) e).getSupportedHttpMethods();
}
return "参数校验失败";
}
/**
* 处理类型不匹配异常
*/
private String handleTypeMismatch(MethodArgumentTypeMismatchException ex) {
String parameterName = ex.getName();
Class<?> requiredType = ex.getRequiredType();
String errorMsg = String.format("参数'%s'的值'%s'格式错误",
parameterName, ex.getValue());
if (requiredType != null) {
if (Number.class.isAssignableFrom(requiredType)) {
errorMsg += ",应为数字类型";
} else if (requiredType == Boolean.class || requiredType == boolean.class) {
errorMsg += ",应为布尔值(true/false)";
} else if (requiredType == Date.class || requiredType == LocalDate.class) {
errorMsg += ",日期格式应为: yyyy-MM-dd";
} else if (requiredType == LocalDateTime.class) {
errorMsg += ",日期时间格式应为: yyyy-MM-dd HH:mm:ss";
} else if (requiredType.isEnum()) {
errorMsg += ",可选值为: " + Arrays.toString(requiredType.getEnumConstants());
}
}
return errorMsg;
}
/**
* 处理表单对象绑定错误
*/
private String handleBindException(BindException ex) {
return ex.getBindingResult().getFieldErrors().stream()
.map(error -> {
String field = error.getField();
String message = error.getDefaultMessage();
Object rejectedValue = error.getRejectedValue();
return rejectedValue == null
? String.format("字段'%s': %s", field, message)
: String.format("字段'%s'的值'%s'无效: %s", field, rejectedValue, message);
})
.collect(Collectors.joining("; "));
}
/**
* 处理必填参数缺失异常
*/
private String handleMissingParameter(MissingServletRequestParameterException ex) {
return String.format("缺少必填参数: '%s' (类型: %s)",
ex.getParameterName(), ex.getParameterType());
}
/**
* 处理请求体解析异常
*/
private String handleHttpMessageNotReadable(HttpMessageNotReadableException ex) {
Throwable rootCause = ex.getRootCause();
if (rootCause instanceof JsonParseException) {
return "JSON格式错误: " + rootCause.getMessage();
} else if (rootCause instanceof InvalidFormatException) {
InvalidFormatException ife = (InvalidFormatException) rootCause;
return String.format("字段'%s'的值'%s'格式不正确,期望类型: %s",
ife.getPath().get(ife.getPath().size() - 1).getFieldName(),
ife.getValue(),
ife.getTargetType().getSimpleName());
} else if (rootCause != null) {
return "请求体格式错误: " + rootCause.getMessage();
}
return "请求体格式错误或无法解析";
}
/**
* 获取异常根源信息
*/
private String getRootCauseMessage(Throwable e) {
Throwable rootCause = ExceptionUtils.getRootCause(e);
return rootCause != null ? rootCause.getMessage() : e.getMessage();
}
}

39
src/main/java/com/example/demo/controller/Temporary/RedController.java

@ -0,0 +1,39 @@
package com.example.demo.controller.Temporary;
import com.example.demo.domain.vo.Red;
import com.example.demo.domain.vo.coin.Result;
import com.example.demo.service.Temporary.RedService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
/**
* @program: GOLD
* @ClassName RedController
* @description:
* @author: huangqizhen
* @create: 202512-03 16:47
* @Version 1.0
**/
@RestController
@RequestMapping("/Temporary")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class RedController {
@Autowired
private RedService redService;
@RequestMapping("/Red")
public Result selectSum(@RequestBody Red red) {
try {
redService.selectSum(red.getJwcode(),red.getType());
}
catch (Exception e) {
return Result.error(e.getMessage());
}
return Result.success(redService.selectSum(red.getJwcode(),red.getType()));
}
}

32
src/main/java/com/example/demo/domain/vo/Red.java

@ -0,0 +1,32 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.units.qual.N;
import java.math.BigDecimal;
import java.util.Date;
/**
* @program: GOLD
* @ClassName red
* @description:
* @author: huangqizhen
* @create: 202512-03 16:31
* @Version 1.0
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Red {
private Integer id;
private Integer jwcode;
private BigDecimal sum;
private Integer type;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date czTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime;
}

19
src/main/java/com/example/demo/mapper/Temporary/RedMapper.java

@ -0,0 +1,19 @@
package com.example.demo.mapper.Temporary;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
/**
* @program: GOLD
* @ClassName RedMapper
* @description:
* @author: huangqizhen
* @create: 202512-03 17:03
* @Version 1.0
**/
@Mapper
public interface RedMapper {
BigDecimal selectSum(@Param("jwcode") Integer jwcode, @Param("type") Integer type);
}

2
src/main/java/com/example/demo/security/SecurityConfig.java

@ -60,7 +60,7 @@ public class SecurityConfig {
request
.requestMatchers( HttpMethod.POST,
// 用户不登录就可以访问的路径
"/admin/login","/upload/**","/detailY/ERP","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**","/statistics/**","/Mysql/**").permitAll()
"/admin/login","/upload/**","/detailY/ERP","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**","/statistics/**","/Mysql/**","/Temporary/**").permitAll()
.requestMatchers(
"/error","alipay/**","/upload/**","/home/java/haiwaiyanfa/gold1/**","/home/java/haiwaiyanfa/**"
).permitAll()

17
src/main/java/com/example/demo/service/Temporary/RedService.java

@ -0,0 +1,17 @@
package com.example.demo.service.Temporary;
import com.example.demo.domain.vo.Red;
import java.math.BigDecimal;
/**
* @program: GOLD
* @ClassName RedService
* @description:
* @author: huangqizhen
* @create: 202512-03 16:38
* @Version 1.0
**/
public interface RedService {
BigDecimal selectSum(Integer jwcode, Integer type);
}

35
src/main/java/com/example/demo/serviceImpl/Temporary/RedServiceImpl.java

@ -0,0 +1,35 @@
package com.example.demo.serviceImpl.Temporary;
import com.example.demo.Util.BusinessException;
import com.example.demo.domain.vo.Red;
import com.example.demo.exception.SystemException;
import com.example.demo.mapper.Temporary.RedMapper;
import com.example.demo.service.Temporary.RedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
/**
* @program: GOLD
* @ClassName RedServiceImpl
* @description:
* @author: huangqizhen
* @create: 202512-03 16:37
* @Version 1.0
**/
@Service
public class RedServiceImpl implements RedService {
@Autowired
private RedMapper redMapper;
@Override
public BigDecimal selectSum(Integer jwcode,Integer type) {
if (jwcode == null){
throw new BusinessException("未接受到精网号");
}
if (type == null){
throw new BusinessException("未接受到类型");
}
return redMapper.selectSum(jwcode,type);
}
}

9
src/main/resources/mapper/RedMapper.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.Temporary.RedMapper">
<select id="selectSum" resultType="java.math.BigDecimal">
select sum from red where jwcode=#{jwcode} and type=#{type}
</select>
</mapper>
Loading…
Cancel
Save