➕ Feat: init project
This commit is contained in:
parent
238b411ed3
commit
89ff44cfcf
3
.gitignore
vendored
3
.gitignore
vendored
@ -42,4 +42,5 @@ buildNumber.properties
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
.idea
|
||||
target
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Commerce-System-Backend
|
||||
|
||||
🚧 Fix,➕ Feat,🔨 Refactor,📝 Docs,✨ Style,🍱 Perf,🔧 Test,⚡️ Chore,🐛 Bug
|
||||
Commerce System
|
110
pom.xml
Normal file
110
pom.xml
Normal file
@ -0,0 +1,110 @@
|
||||
<?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>
|
||||
|
||||
<groupId>top.xinsin</groupId>
|
||||
<artifactId>Commerce-System-Backend</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.5</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.3.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.26</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.26</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.32</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.16</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
<!-- 模板引擎依赖-->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
13
src/main/java/top/xinsin/Main.java
Normal file
13
src/main/java/top/xinsin/Main.java
Normal file
@ -0,0 +1,13 @@
|
||||
package top.xinsin;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("top.xinsin.mapper")
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Main.class,args);
|
||||
}
|
||||
}
|
23
src/main/java/top/xinsin/config/GlobalWebMvcConfig.java
Normal file
23
src/main/java/top/xinsin/config/GlobalWebMvcConfig.java
Normal file
@ -0,0 +1,23 @@
|
||||
package top.xinsin.config;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:55
|
||||
* @version 1.0
|
||||
*/
|
||||
@SpringBootConfiguration
|
||||
public class GlobalWebMvcConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowCredentials(true)
|
||||
.allowedOriginPatterns("*")
|
||||
.allowedMethods("GET", "POST", "DELETE", "PUT", "HEAD")
|
||||
.allowedHeaders("*")
|
||||
.exposedHeaders("*");
|
||||
}
|
||||
}
|
24
src/main/java/top/xinsin/config/InterceptorConfig.java
Normal file
24
src/main/java/top/xinsin/config/InterceptorConfig.java
Normal file
@ -0,0 +1,24 @@
|
||||
package top.xinsin.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import top.xinsin.interceptor.AuthenticationInterceptor;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:54
|
||||
* @version 1.0
|
||||
*/
|
||||
@Configuration
|
||||
public class InterceptorConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new AuthenticationInterceptor()).
|
||||
//拦截
|
||||
addPathPatterns("/**").
|
||||
//放行登录接口
|
||||
excludePathPatterns("/user/login").
|
||||
excludePathPatterns("/user/register");
|
||||
}
|
||||
}
|
25
src/main/java/top/xinsin/config/MybatisPlusConfig.java
Normal file
25
src/main/java/top/xinsin/config/MybatisPlusConfig.java
Normal file
@ -0,0 +1,25 @@
|
||||
package top.xinsin.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class MybatisPlusConfig{
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||
paginationInnerInterceptor.setOptimizeJoin(true);
|
||||
paginationInnerInterceptor.setDbType(DbType.MYSQL);
|
||||
paginationInnerInterceptor.setOverflow(true);
|
||||
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
||||
OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
|
||||
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
|
||||
return interceptor;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package top.xinsin.interceptor;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
|
||||
import com.auth0.jwt.exceptions.SignatureVerificationException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import top.xinsin.util.HttpCodes;
|
||||
import top.xinsin.util.JWTUtils;
|
||||
import top.xinsin.util.R;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:49
|
||||
* @version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class AuthenticationInterceptor implements HandlerInterceptor {
|
||||
public static final String OPTIONS = "OPTIONS";
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if (OPTIONS.equals(request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
// 从http请求头中取出token
|
||||
final String token = request.getHeader("Access-Token");
|
||||
//解决跨域问题
|
||||
response.setHeader("Access-Control-Allow-Origin","*");
|
||||
//解决跨域问题
|
||||
response.setHeader("Access-Control-Allow-Headers","*");
|
||||
R responseData;
|
||||
try {
|
||||
JWTUtils.verify(token);
|
||||
return true;
|
||||
} catch (SignatureVerificationException e) {
|
||||
log.info("用户验证了无效签名");
|
||||
responseData = R.failed(HttpCodes.ACCESS_DENIED,"无效签名");
|
||||
}catch (TokenExpiredException e){
|
||||
log.info("用户验证的签名已过期");
|
||||
responseData = R.failed(HttpCodes.INVALID_TOKEN,"签名已过期");
|
||||
}catch (AlgorithmMismatchException e){
|
||||
log.info("用户验证的token算法不一致");
|
||||
responseData = R.failed(HttpCodes.INVALID_TOKEN,"token算法不一致");
|
||||
}catch (Exception e){
|
||||
log.info("token无效或者是空的");
|
||||
responseData = R.failed(HttpCodes.INVALID_TOKEN,"token无效");
|
||||
}
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.getWriter().write(JSONObject.toJSONString(responseData));
|
||||
return false;
|
||||
}
|
||||
}
|
56
src/main/java/top/xinsin/util/HttpCodes.java
Normal file
56
src/main/java/top/xinsin/util/HttpCodes.java
Normal file
@ -0,0 +1,56 @@
|
||||
package top.xinsin.util;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:47
|
||||
* @version 1.0
|
||||
*/
|
||||
public enum HttpCodes {
|
||||
/**
|
||||
* 200
|
||||
* 成功执行
|
||||
*/
|
||||
HTTP_CODES200(200,"接口一不小心执行成功啦!"),
|
||||
/**
|
||||
* 500
|
||||
* 服务器错误
|
||||
*/
|
||||
|
||||
HTTP_CODES500(500,"哎呀,错误了请节哀!"),
|
||||
/**
|
||||
* 401
|
||||
* 数据错误
|
||||
*/
|
||||
HTTP_CODES401(401,"你这请求是坏的,你不会写吗?"),
|
||||
/**
|
||||
* 501
|
||||
* 账号密码错误
|
||||
*/
|
||||
HTTP_CODES501(501,"帐号或密码错误!"),
|
||||
/**
|
||||
* 250
|
||||
* token验证错误
|
||||
*/
|
||||
INVALID_TOKEN(250,"令牌验证错误"),
|
||||
/**
|
||||
* 251
|
||||
* 无权限访问
|
||||
*/
|
||||
ACCESS_DENIED( 251,"你没有权限访问");
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
|
||||
HttpCodes(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
72
src/main/java/top/xinsin/util/JWTUtils.java
Normal file
72
src/main/java/top/xinsin/util/JWTUtils.java
Normal file
@ -0,0 +1,72 @@
|
||||
package top.xinsin.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTCreator;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:47
|
||||
* @version 1.0
|
||||
*/
|
||||
public class JWTUtils {
|
||||
private static final String KEY = "a3Q%b5R@j7kP*9d-v'Y|h-%i(h9J0sU1/o";
|
||||
|
||||
/**
|
||||
* 创建token
|
||||
* @param map 字段
|
||||
* @return token
|
||||
*/
|
||||
public static String getToken(Map<String,String> map){
|
||||
Calendar instance = Calendar.getInstance();
|
||||
//默认两个小时过期
|
||||
instance.add(Calendar.HOUR,2);
|
||||
//创建jwt builder
|
||||
JWTCreator.Builder builder = JWT.create();
|
||||
//payload
|
||||
map.forEach(builder::withClaim);
|
||||
//指定令牌过期时间
|
||||
return builder.withExpiresAt(instance.getTime())
|
||||
.sign(Algorithm.HMAC512(KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token是否合法
|
||||
* @param token token
|
||||
*/
|
||||
public static void verify(String token){
|
||||
JWT.require(Algorithm.HMAC512(KEY)).build().verify(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中提取信息
|
||||
*
|
||||
* @param token token
|
||||
* @return token中包含的信息
|
||||
*/
|
||||
public static DecodedJWT getTokenInfo(String token) {
|
||||
return JWT.require(Algorithm.HMAC512(KEY)).build().verify(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断token与用户名是否对应
|
||||
*
|
||||
* @param token token
|
||||
* @param username 用户名
|
||||
* @return 是否对应
|
||||
*/
|
||||
public static boolean isUser(String token, String username) {
|
||||
String tokenUsername = getTokenInfo(token).getClaim("username").asString();
|
||||
return tokenUsername.equals(username);
|
||||
}
|
||||
public static Integer getId(String token){
|
||||
return Integer.valueOf(getTokenInfo(token).getClaim("id").asString());
|
||||
}
|
||||
public static Integer getAuth(String token) {
|
||||
return getTokenInfo(token).getClaim("auth").asInt();
|
||||
}
|
||||
}
|
34
src/main/java/top/xinsin/util/R.java
Normal file
34
src/main/java/top/xinsin/util/R.java
Normal file
@ -0,0 +1,34 @@
|
||||
package top.xinsin.util;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author xinsin
|
||||
* Created On 2023/4/3 15:45
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
public class R<T> {
|
||||
private int status;
|
||||
private String message;
|
||||
private T data;
|
||||
private long timestamp;
|
||||
|
||||
public R() {
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
public static<T> R<T> success(T data){
|
||||
R<T> rData = new R<>();
|
||||
rData.setStatus(HttpCodes.HTTP_CODES200.getCode());
|
||||
rData.setMessage(HttpCodes.HTTP_CODES200.getMessage());
|
||||
rData.setData(data);
|
||||
return rData;
|
||||
}
|
||||
public static<T> R<T> failed(HttpCodes httpCodes, T data){
|
||||
R<T> rData = new R<>();
|
||||
rData.setStatus(httpCodes.getCode());
|
||||
rData.setMessage(httpCodes.getMessage());
|
||||
rData.setData(data);
|
||||
return rData;
|
||||
}
|
||||
}
|
36
src/main/resources/application.yml
Normal file
36
src/main/resources/application.yml
Normal file
@ -0,0 +1,36 @@
|
||||
server:
|
||||
port: 8001
|
||||
spring:
|
||||
datasource:
|
||||
username: commerce_system
|
||||
password: Jix656dzD6St4YCn
|
||||
url: jdbc:mysql://wzpmc.cn:3306/commerce_system?serverTimezone=UTC-8
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
# druid配置
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
initialSize: 5
|
||||
minIdle: 5
|
||||
maxActive: 20
|
||||
maxWait: 60000
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
poolPreparedStatements: true
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
|
||||
filters: stat,wall,log4j
|
||||
maxPoolPreparedStatementPerConnectionSize: 20
|
||||
useGlobalDataSourceStat: true
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
|
||||
mvc:
|
||||
static-path-pattern: /static/**
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
logic-delete-field: del # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
|
||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
Loading…
x
Reference in New Issue
Block a user