初始化修改代码

This commit is contained in:
2025-07-19 20:22:06 +08:00
parent 06548a4716
commit 4a0cf71e5d
26 changed files with 890 additions and 175 deletions

15
Dockerfile.buildagent Normal file
View File

@ -0,0 +1,15 @@
# 使用 JDK 8 作为构建环境
FROM openjdk:8-jdk
# 使用阿里云的 apt 镜像源Debian 11 bullseye
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
# 更新包列表并安装 Maven 和 Git
RUN apt update && \
apt install -y maven git && \
mvn --version && \
git --version
# 设置工作目录
WORKDIR /home/jenkins/workspace

31
Jenkinsfile vendored
View File

@ -1,10 +1,10 @@
pipeline {
agent any
tools {
maven 'M3' // 必须在 Jenkins → Manage Jenkins → Global Tool Configuration 中配置过
}
// tools {
// maven 'M3' // 必须在 Jenkins → Manage Jenkins → Global Tool Configuration 中配置过
// }
environment {
APP_NAME = "sczx-app"
APP_NAME = "sczx_order"
DOCKER_IMAGE = "${APP_NAME}:latest"
CONTAINER_NAME = "${APP_NAME}-container"
}
@ -13,11 +13,16 @@ pipeline {
stage('Checkout') {
steps {
echo "📦 正在拉取代码..."
git branch: 'main', url: 'http://115.190.8.52:3000/sczx_group/sczx-app.git'
git branch: 'main', url: 'http://115.190.8.52:3000/sczx_group/sczx_order.git'
}
}
stage('Build with Maven') {
stage('Build with Maven in JDK 8') {
agent {
dockerfile {
filename "Dockerfile.buildagent"
}
}
steps {
echo "🛠️ 正在使用 Maven 构建..."
sh 'mvn clean package -s settings.xml'
@ -31,32 +36,34 @@ pipeline {
}
stage('Build Docker Image') {
agent any
steps {
echo "🐋 正在构建 Docker 镜像..."
sh """
docker build -t \${DOCKER_IMAGE} .
"""
sh 'docker build -t "$DOCKER_IMAGE" .'
}
}
stage('Stop Old Container') {
agent any
steps {
echo "🛑 正在停止旧的容器(如果存在)..."
sh '''
if [ "$(docker ps -f 'name=sczx-app-container' --format '{{.Status}}')" ]; then
docker stop sczx-app-container
docker rm sczx-app-container
if [ "$(docker ps -f 'name=sczx_order-container' --format '{{.Status}}')" ]; then
docker stop sczx_order-container
docker rm sczx_order-container
fi
'''
}
}
stage('Run New Container') {
agent any
steps {
echo "🟢 正在运行新的容器..."
sh """
docker run -d \
--name \${CONTAINER_NAME} \
--network sczx-net \
-p 8088:8088 \
-e JAVA_OPTS="-Xms256m -Xmx512m -Duser.timezone=Asia/Shanghai" \
--restart always \

View File

@ -1 +1 @@
闪充智行后端
闪充智行订单服务

99
pom.xml
View File

@ -4,12 +4,12 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.sczx</groupId>
<artifactId>sczx-app</artifactId>
<artifactId>sczx_order</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>sczx-app</name>
<description>sczx-app service</description>
<name>sczx_order</name>
<description>sczx_order service</description>
<properties>
<java.version>1.8</java.version>
@ -146,17 +146,46 @@
<version>8.0.33</version>
</dependency>
<!-- Springdoc OpenAPI UI -->
<!-- JWT -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version> <!-- 支持 Java 8 的最新版本 -->
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>4.15.5</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version> <!-- 可根据需要选择版本 -->
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- JAXB API (Java 8 兼容) -->
@ -171,11 +200,33 @@
<artifactId>reactor-core</artifactId>
<version>3.2.2.RELEASE</version> <!-- 支持 Java 8 -->
</dependency>
<!-- MapStruct 核心库 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- MapStruct 注解处理器(用于编译期生成实现类) -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
<scope>provided</scope>
</dependency>
<!-- FastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
<!-- Build Configuration -->
<build>
<finalName>sczx-app</finalName>
<finalName>sczx_order</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
@ -214,32 +265,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>unpack</id>
<phase>process-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>4.15.5</version>
<type>jar</type>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<includes>META-INF/resources/**</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>

View File

@ -1,16 +0,0 @@
package com.sczx.app.config;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
//@Configuration
public class SpringDocConfig {
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("sczx-service")
.packagesToScan("com.sczx.app.controller")
.build();
}
}

View File

@ -1,44 +0,0 @@
package com.sczx.app.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/4.15.5/");
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("/v3/api-docs/**")
.addResourceLocations("classpath:/META-INF/resources/swagger-ui/");
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
// 添加支持 application/json;charset=UTF-8 的 Jackson 转换器
converters.add(new MappingJackson2HttpMessageConverter() {
@Override
public List<MediaType> getSupportedMediaTypes() {
return Collections.singletonList(MediaType.APPLICATION_JSON_UTF8);
}
});
}
}

View File

@ -1,16 +0,0 @@
package com.sczx.app.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = "示例接口", description = "用于演示 Springdoc 的接口")
public class DemoController {
@GetMapping("/test")
@Operation(summary = "测试接口", description = "返回一个测试字符串")
public String test() {
return "OK";
}
}

View File

@ -1,7 +1,8 @@
package com.sczx.app;
package com.sczx.order;
import com.sczx.app.common.constant.SystemConstants;
import com.sczx.app.utils.ComputerInfo;
import com.sczx.order.common.constant.SystemConstants;
import com.sczx.order.utils.ComputerInfo;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -15,19 +16,19 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.io.IOException;
@Slf4j
@SpringBootApplication
@EnableDiscoveryClient // 启用服务注册与发现
@EnableRetry
@EnableFeignClients(basePackages = SystemConstants.FEIGN_CLIENT_BASE_PACKAGE )
@EnableTransactionManagement
@EnableHystrix
@MapperScan("com.sczx.app.mapper") // 扫描 Mapper 接口
@MapperScan("com.sczx.order.mapper") // 扫描 Mapper 接口
public class Application {
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
Environment environment = context.getBean(Environment.class);
System.out.println("启动成功后端服务API地址http://" + ComputerInfo.getIpAddr() + ":"
+ environment.getProperty("server.port") + "/doc.html");
log.info("启动成功后端服务API地址http://{}:{}/swagger-ui.html", ComputerInfo.getIpAddr(), environment.getProperty("server.port"));
}
}

View File

@ -0,0 +1,58 @@
package com.sczx.order.aspect;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @Author Huang Kai
* @Date 2023/1/18 17:01
* @Version 1.0
*/
@Aspect
@Component
@Slf4j
public class FacadeAspect {
/** 以 controller 包下定义的所有请求为切入点 */
@Pointcut("execution(public * com..facade.*.*(..))")
public void facadeLog() {}
/**
* 在切点之前织入
* @param joinPoint
*/
@Before("facadeLog()")
public void doBefore(JoinPoint joinPoint) {
// 打印请求相关参数
log.info("=========================remote Start =========================");
// 打印 Http method
//log.info("HTTP Method : {}", request.getMethod());
// 打印调用 controller 的全路径以及执行方法
log.info("Class Method:{}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
// 打印请求的 IP
//log.info("IP : {}", request.getRemoteAddr());
// 打印请求入参
log.info("facadeAspect_Request:{}", JSON.toJSONString(joinPoint.getArgs()));
}
@Around("facadeLog()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
// 打印出参
log.info("facadeAspect_Response:{}", JSON.toJSONString(result));
// 执行耗时
log.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
log.info("=========================remote End =========================");
return result;
}
}

View File

@ -0,0 +1,97 @@
package com.sczx.order.aspect;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @Author Huang Kai
* @Date 2023/1/18 17:01
* @Version 1.0
*/
@Aspect
@Component
@Slf4j
public class WebLogAspect {
/** 以 controller 包下定义的所有请求为切入点 */
@Pointcut("execution(public * com.sczx.*.controller.*.*(..))")
public void webLog() {}
/**
* 在切点之前织入
* @param joinPoint
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
String uid = UUID.randomUUID().toString();
MDC.put("requestId",uid.substring(24,36));
// 开始打印请求日志
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = null;
if (attributes != null) {
request = attributes.getRequest();
}
// 打印请求相关参数
log.info("========================= Start =========================");
// 打印请求入参
try{
Object[] args = joinPoint.getArgs();
List<Object> filteredArgs = new ArrayList<>();
for (Object arg : args) {
//如果是文件类,则只打印文件名称和大小
if (arg instanceof MultipartFile) {
MultipartFile file = (MultipartFile) arg;
JSONObject fileJson = new JSONObject();
fileJson.put("filename", file.getOriginalFilename());
fileJson.put("size", file.getSize());
filteredArgs.add(fileJson);
} else {
filteredArgs.add(arg);
}
}
if (request != null) {
log.info("URL:{} , {}", request.getRequestURL().toString(), JSON.toJSONString(filteredArgs));
}
} catch (Exception e){
log.error("打印WebLogAspect_Request失败args无法被序列化", e);
}
}
/**
* 处理完请求后执行
* @param joinPoint
* @param result
*/
@AfterReturning(pointcut = "webLog()", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result) {
// 打印出参
try {
log.info("WebLogAspect_Response:{}", JSON.toJSON(result));
}catch (Exception e){
log.error("打印WebLogAspect_Response失败result无法被序列化", e);
}
log.info("========================= End =========================");
MDC.clear();
}
@AfterThrowing(throwing="ex",pointcut="webLog()")
public void doRecoveryActions(Throwable ex){
MDC.clear();
}
}

View File

@ -0,0 +1,12 @@
package com.sczx.order.common;
/**
* @Author: 张黎
* @Date: 2025/07/09/20:20
* @Description:
*/
public interface IApiCode {
String getCode();
String getMsg();
}

View File

@ -0,0 +1,123 @@
package com.sczx.order.common;
import com.sczx.order.common.enums.ApiErrorCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: 张黎
* @Date: 2025/07/09/20:25
* @Description:
*/
@ApiModel(value = "公共返回结果")
@Builder
@Data
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1331134667810352183L;
@ApiModelProperty(value = "成功标识")
private boolean success;
@ApiModelProperty(value = "返回编码")
private String code;
@ApiModelProperty(value = "返回信息说明")
private String msg;
private String issue;
@ApiModelProperty(value = "返回数据")
private T data;
public Result(boolean success, String code, String msg, String issue, T data) {
this.success = success;
this.code = code;
this.msg = msg;
this.issue = issue;
this.data = data;
}
public static Result result(IApiCode apiCode) {
return result(apiCode, (Object)null);
}
public static Result result(IApiCode apiCode, Object data) {
return result(apiCode, apiCode.getMsg(), data);
}
public static Result result(IApiCode apiCode, String issue, Object data) {
return result((IApiCode)apiCode, (String)null, issue, data);
}
public static Result result(IApiCode apiCode, String msg, String issue, Object data) {
String message = apiCode.getMsg();
if (StringUtils.isNotBlank(msg)) {
message = msg;
}
return result(apiCode.getCode(), message, issue, data);
}
public static Result result(String code, String msg, String issue, Object data) {
return builder().code(code).success("0".equals(code)).msg(msg).issue(issue).data(data).build();
}
public static Result ok() {
return ok((Object)null);
}
public static Result ok(Object data) {
return result(ApiErrorCode.SUCCESS, data);
}
public static Result ok(String key, Object value) {
Map<String, Object> map = new HashMap(1);
map.put(key, value);
return ok(map);
}
public static Result fail(String msg) {
return result((IApiCode)ApiErrorCode.FAIL, msg, msg, (Object)null);
}
public static Result fail(IApiCode apiCode) {
return result(apiCode, (Object)null);
}
public static Result fail(IApiCode apiCode, String issue) {
return result(apiCode, issue, (Object)null);
}
public static Result fail(String code, String msg) {
return result((String)code, msg, msg, (Object)null);
}
public static Result fail(String code, String msg, String issue) {
return result((String)code, msg, issue, (Object)null);
}
public static Result fail(String code, String msg, String issue, Object data) {
return result(code, msg, issue, data);
}
public static Result fail(IApiCode apiCode, String issue, Object data) {
if (ApiErrorCode.SUCCESS == apiCode) {
throw new RuntimeException("失败结果状态码不能为" + ApiErrorCode.SUCCESS.getCode());
} else {
return result(apiCode, issue, data);
}
}
public static Result fail(String key, Object value) {
Map<String, Object> map = new HashMap();
map.put(key, value);
return result(ApiErrorCode.FAIL, map);
}
public Result() {
}
}

View File

@ -1,4 +1,4 @@
package com.sczx.app.common.constant;
package com.sczx.order.common.constant;
/**
@ -18,6 +18,6 @@ public interface SystemConstants {
/***
* feign客户端所在包路径
*/
String FEIGN_CLIENT_BASE_PACKAGE = "com.sczx.app.thirdpart.facade";
String FEIGN_CLIENT_BASE_PACKAGE = "com.sczx.order.thirdpart.facade";
}

View File

@ -0,0 +1,55 @@
package com.sczx.order.common.enums;
import com.sczx.order.common.IApiCode;
/**
* @Author: 张黎
* @Date: 2025/07/09/20:22
* @Description:
*/
public enum ApiErrorCode implements IApiCode {
SUCCESS("0", "操作成功"),
ARG_ERROR("401000", "参数错误"),
NOT_PERMISSION("401001", "没有权限"),
HTTP_MEDIA_TYPE_NOT_SUPPORTED_ERROR("401002", "media类型出错"),
HTTP_METHOD_NOT_ALLOW_ERROR("401003", "http请求method错误"),
BODY_NOT_MATCH("401004", "请求的数据格式不符!"),
NOT_FOUND("404000", "你请求的路径不存在"),
UNAUTHORIZED("404001", "非法访问"),
FAIL("500000", "操作失败"),
INNER_ERROR("500001", "服务器内部异常");
private final String code;
private final String msg;
private ApiErrorCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
public static ApiErrorCode getApiCode(String code) {
ApiErrorCode[] ecs = values();
ApiErrorCode[] var2 = ecs;
int var3 = ecs.length;
for(int var4 = 0; var4 < var3; ++var4) {
ApiErrorCode ec = var2[var4];
if (ec.getCode().equals(code)) {
return ec;
}
}
return SUCCESS;
}
@Override
public String getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
}

View File

@ -1,4 +1,4 @@
package com.sczx.app.config;
package com.sczx.order.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

View File

@ -0,0 +1,47 @@
package com.sczx.order.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Arrays;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.sczx.order.controller")) // 修改为你的 controller 包路径
.paths(PathSelectors.any())
.build()
.globalOperationParameters(Arrays.asList(
new ParameterBuilder()
.name("Authorization")
.description("Bearer Token")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(true)
.build()
));
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("订单服务接口文档")
.description("sczx_order订单服务接口文档")
.version("1.0")
.build();
}
}

View File

@ -0,0 +1,14 @@
package com.sczx.order.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/test")
public String test() {
return "OK";
}
}

View File

@ -0,0 +1,85 @@
package com.sczx.order.exception;
import com.sczx.order.common.IApiCode;
import com.sczx.order.common.enums.ApiErrorCode;
/**
*
* @author zhangli
*/
public class BizException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
protected String errorCode;
/**
* 错误信息
*/
protected String errorMsg;
public BizException() {
super();
}
public BizException(IApiCode apiCode) {
super(apiCode.getCode());
this.errorCode = apiCode.getCode();
this.errorMsg = apiCode.getMsg();
}
public BizException(IApiCode apiCode, Throwable cause) {
super(apiCode.getCode(), cause);
this.errorCode = apiCode.getCode();
this.errorMsg = apiCode.getMsg();
}
public BizException(String errorMsg) {
super(errorMsg);
this.errorCode = ApiErrorCode.FAIL.getCode();
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg) {
super(errorCode);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg, Throwable cause) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
@Override
public String getMessage() {
return errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}

View File

@ -0,0 +1,50 @@
package com.sczx.order.exception;
import com.sczx.order.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* @author zhangli
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理自定义的业务异常
*
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public Result bizExceptionHandler(HttpServletRequest req, BizException e) {
log.warn("发生业务异常!原因是:{}", e.getErrorMsg(), e);
return Result.fail(e.getErrorCode(), e.getErrorMsg());
}
@ExceptionHandler(value = InnerException.class)
@ResponseBody
public Result innerExceptionHandler(HttpServletRequest req, InnerException e) {
log.error("发生服务内部异常!原因是:{}", e.getErrorMsg(), e);
return Result.fail(e.getErrorCode(), e.getErrorMsg());
}
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result exceptionHandler(HttpServletRequest req, Exception e) {
log.error("意料外异常!原因是:{}", e.getMessage(), e);
return Result.fail("99999", "系统内部异常");
}
}

View File

@ -0,0 +1,86 @@
package com.sczx.order.exception;
import com.sczx.order.common.IApiCode;
import com.sczx.order.common.enums.ApiErrorCode;
/**
*
* @author zhangli
*/
public class InnerException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
protected String errorCode;
/**
* 错误信息
*/
protected String errorMsg;
public InnerException() {
super();
}
public InnerException(IApiCode apiCode) {
super(apiCode.getCode());
this.errorCode = apiCode.getCode();
this.errorMsg = apiCode.getMsg();
}
public InnerException(IApiCode apiCode, Throwable cause) {
super(apiCode.getCode(), cause);
this.errorCode = apiCode.getCode();
this.errorMsg = apiCode.getMsg();
}
public InnerException(String errorMsg) {
super(errorMsg);
this.errorCode = ApiErrorCode.INNER_ERROR.getCode();
this.errorMsg = errorMsg;
}
public InnerException(String errorCode, String errorMsg) {
super(errorCode);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public InnerException(String errorCode, String errorMsg, Throwable cause) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
@Override
public String getMessage() {
return errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}

View File

@ -1,4 +1,4 @@
package com.sczx.app.utils;
package com.sczx.order.utils;
import java.io.BufferedReader;
import java.io.IOException;

View File

@ -0,0 +1,63 @@
package com.sczx.order.utils;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
/**
* @Author: 张黎
* @Date: 2025/07/06/14:00
* @Description:
*/
@Slf4j
@Component
public class JwtUtil {
@Value("${auth.token-expiration}")
private long expiration;
private final SecretKey key;
public JwtUtil(@Value("${auth.secret-key}") String secretKey) {
this.key = Keys.hmacShaKeyFor(secretKey.getBytes());
// this.key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
log.info("JWT 密钥:{}", secretKey);
}
public String generateToken(String username, String role) {
return Jwts.builder()
.setSubject(username)
.claim("role", role)
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(key, SignatureAlgorithm.HS512)
.compact();
}
public String extractUsername(String token) {
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
return true;
} catch (JwtException ex) {
return false;
}
}
}

View File

@ -0,0 +1,33 @@
package com.sczx.order.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* @Author: 张黎
* @Date: 2025/07/06/14:21
* @Description:
*/
@Component
public class RedisUtil {
@Autowired
private StringRedisTemplate redisTemplate;
public void set(String key, String value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
public String get(String key) {
return redisTemplate.opsForValue().get(key);
}
public void delete(String key) {
redisTemplate.delete(key);
}
}

View File

@ -4,7 +4,7 @@ server:
spring:
application:
name: sczx-app # 微服务名称
name: sczx-order # 微服务名称
http:
encoding:
charset: UTF-8
@ -13,7 +13,6 @@ spring:
mvc:
async:
request-timeout: -1
cloud:
nacos:
discovery:
@ -22,7 +21,8 @@ spring:
metadata:
version: 1.0.0
env: dev
lifecycle:
timeout-per-shutdown-phase: 30s # 设置优雅停机时间
datasource:
url: jdbc:mysql://115.190.8.52:3306/sczx?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: sczx_user
@ -31,15 +31,16 @@ spring:
hikari:
maximum-pool-size: 10
auto-commit: true
jpa:
hibernate:
ddl-auto: update
show-sql: true
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
lifecycle:
timeout-per-shutdown-phase: 30s # 设置优雅停机时间
redis:
host: 115.190.8.52
port: 6379
lettuce:
pool:
max-active: 8
max-wait: 2000ms
max-idle: 4
min-idle: 1
max-life-time: 300000ms
management:
endpoints:
@ -67,15 +68,14 @@ hystrix:
thread:
timeoutInMilliseconds: 10000 # 默认熔断超时时间
springdoc:
swagger-ui:
url: /v3/api-docs
path: /doc.html
packages-to-scan: com.sczx.app.controller # 替换为你的 controller 包路径
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
type-aliases-package: com.sczx.app.entity # 实体类包路径
type-aliases-package: com.sczx.order.po # 实体类包路径
configuration:
mapUnderscoreToCamelCase: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印 SQL调试用
auth:
secret-key: his-is-a-very-long-and-secure-secret-key-for-jwt-signing-please-dont-use-short-keys
token-expiration: 86400000 # 24小时

View File

@ -1,21 +0,0 @@
package com.sczx.app.service;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://115.190.8.52:3306/sczx", "sczx_user", "Sczx123@")
.globalConfig(builder -> {
builder.author("zhangli")
.outputDir(System.getProperty("user.dir") + "/src/main/java");
})
.packageConfig(builder -> {
builder.parent("com.sczx.app")
.moduleName("user");
})
.strategyConfig(builder -> {
builder.addInclude("user"); // 表名
})
.execute();
}
}

View File

@ -0,0 +1,41 @@
package com.sczx.order.service;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class CodeGenerator {
private static final String parentPackage = "com.sczx.order";
private static final String jdbcUrl = "jdbc:mysql://115.190.8.52:3306/sczx?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&useSSL=false&serverTimezone=Asia/Shanghai";
private static final String username = "sczx_user";
private static final String password = "Sczx123@";
private static final String author = "zhangli";
public static void main(String[] args) {
DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig.Builder(jdbcUrl, username, password);
FastAutoGenerator.create(DATA_SOURCE_CONFIG)
// 全局配置
.globalConfig(builder -> builder.outputDir(System.getProperty("user.dir") + "/src/main/java")
.author(author).disableOpenDir().enableSwagger()
.dateType(DateType.TIME_PACK).commentDate("yyyy-MM-dd HH:mm:ss")
.fileOverride())
// 包配置
.packageConfig(builder -> builder.parent(parentPackage).entity("po").service("repository").serviceImpl("repository.impl").xml("")
.mapper("mapper").pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper")))
// 策略配置
.strategyConfig((scanner, builder) -> builder.addInclude(scanner.apply("请输入表名:"))
.addTablePrefix("zc_"/*,"zd_"*/)//可支持多个,按逗号分隔
.entityBuilder().formatFileName("%sPO").enableLombok()
.mapperBuilder().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper")
.controllerBuilder().formatFileName("%sController").enableRestStyle()
.serviceBuilder().formatServiceFileName("%sRepo").formatServiceImplFileName("%sRepoImpl"))
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
}