Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
postcard-service
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhouxudong
postcard-service
Commits
70128765
Commit
70128765
authored
Dec 14, 2023
by
zhouxudong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
提交代码
parents
Pipeline
#101
failed with stages
Changes
33
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
2166 additions
and
0 deletions
+2166
-0
pom.xml
pom.xml
+98
-0
PostcardApplication.java
src/main/java/com/postcard/service/PostcardApplication.java
+19
-0
ResponseAnnotation.java
...ostcard/service/config/annotation/ResponseAnnotation.java
+17
-0
BaseContextHandler.java
.../com/postcard/service/config/auth/BaseContextHandler.java
+37
-0
CurrentUserInterceptor.java
.../postcard/service/config/auth/CurrentUserInterceptor.java
+39
-0
WebConfig.java
...main/java/com/postcard/service/config/auth/WebConfig.java
+84
-0
AuthException.java
.../com/postcard/service/config/exception/AuthException.java
+14
-0
BaseException.java
.../com/postcard/service/config/exception/BaseException.java
+26
-0
GlobalExceptionHandler.java
...card/service/config/exception/GlobalExceptionHandler.java
+61
-0
GlobalResponseBodyAdvice.java
...rd/service/config/exception/GlobalResponseBodyAdvice.java
+58
-0
ServiceException.java
...m/postcard/service/config/exception/ServiceException.java
+14
-0
MyBatisPlusConfig.java
...om/postcard/service/config/mybatis/MyBatisPlusConfig.java
+32
-0
MyMetaObjectHandler.java
.../postcard/service/config/mybatis/MyMetaObjectHandler.java
+67
-0
CustomerConvertConfig.java
.../postcard/service/config/other/CustomerConvertConfig.java
+86
-0
OrikaConfig.java
...n/java/com/postcard/service/config/other/OrikaConfig.java
+47
-0
RedisConfig.java
...n/java/com/postcard/service/config/redis/RedisConfig.java
+46
-0
SwaggerConfig.java
...va/com/postcard/service/config/swagger/SwaggerConfig.java
+54
-0
WebClientConfig.java
.../com/postcard/service/config/webflux/WebClientConfig.java
+16
-0
Constants.java
src/main/java/com/postcard/service/constant/Constants.java
+10
-0
MsgConstants.java
...main/java/com/postcard/service/constant/MsgConstants.java
+10
-0
RedisConstants.java
...in/java/com/postcard/service/constant/RedisConstants.java
+10
-0
TokenConstants.java
...in/java/com/postcard/service/constant/TokenConstants.java
+24
-0
AjaxResult.java
src/main/java/com/postcard/service/domain/AjaxResult.java
+236
-0
BaseEntity.java
src/main/java/com/postcard/service/domain/BaseEntity.java
+60
-0
JwtInfo.java
src/main/java/com/postcard/service/domain/JwtInfo.java
+28
-0
IpUtils.java
src/main/java/com/postcard/service/util/IpUtils.java
+187
-0
JwtTokenUtil.java
...main/java/com/postcard/service/util/jwt/JwtTokenUtil.java
+125
-0
RedisUtil.java
src/main/java/com/postcard/service/util/redis/RedisUtil.java
+353
-0
application-dev.yml
src/main/resources/application-dev.yml
+47
-0
application-prod.yml
src/main/resources/application-prod.yml
+43
-0
application-test.yml
src/main/resources/application-test.yml
+44
-0
application.yml
src/main/resources/application.yml
+40
-0
logback-spring.xml
src/main/resources/logback-spring.xml
+134
-0
No files found.
pom.xml
0 → 100644
View file @
70128765
<?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>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-parent
</artifactId>
<version>
2.7.15
</version>
</parent>
<groupId>
com.postcard
</groupId>
<artifactId>
postcard-service
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<description>
舒城明信片服务
</description>
<packaging>
jar
</packaging>
<properties>
<maven.compiler.source>
8
</maven.compiler.source>
<maven.compiler.target>
8
</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-redis
</artifactId>
</dependency>
<!--mysql连接驱动-->
<dependency>
<groupId>
com.mysql
</groupId>
<artifactId>
mysql-connector-j
</artifactId>
<scope>
runtime
</scope>
</dependency>
<!-- mybatis增强器依赖 -->
<dependency>
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-boot-starter
</artifactId>
<version>
3.5.2
</version>
</dependency>
<!-- hutool工具包 -->
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-all
</artifactId>
<version>
5.8.20
</version>
</dependency>
<dependency>
<groupId>
org.projectlombok
</groupId>
<artifactId>
lombok
</artifactId>
<version>
1.18.28
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-core
</artifactId>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-webflux
</artifactId>
</dependency>
<!-- jwt-->
<dependency>
<groupId>
com.nimbusds
</groupId>
<artifactId>
nimbus-jose-jwt
</artifactId>
<version>
9.23
</version>
</dependency>
<!--启用Spring Boot的配置处理器。-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-configuration-processor
</artifactId>
<optional>
true
</optional>
</dependency>
<!--swagger 增强-->
<dependency>
<groupId>
com.github.xiaoymin
</groupId>
<artifactId>
knife4j-spring-boot-starter
</artifactId>
<version>
3.0.3
</version>
</dependency>
<dependency>
<groupId>
org.bouncycastle
</groupId>
<artifactId>
bcprov-jdk15to18
</artifactId>
<version>
1.68
</version>
</dependency>
<!-- ## 类型转换-->
<dependency>
<groupId>
ma.glasnost.orika
</groupId>
<artifactId>
orika-core
</artifactId>
<version>
1.5.4
</version>
</dependency>
</dependencies>
</project>
src/main/java/com/postcard/service/PostcardApplication.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
/**
* @Author:zhouxudong
* @version: 1.0
* @Date: 2023/11/17 15:41
* @Description:
*/
@SpringBootApplication
/*@EnableOpenApi
@EnableSwagger2*/
public
class
PostcardApplication
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
PostcardApplication
.
class
,
args
);
}
}
src/main/java/com/postcard/service/config/annotation/ResponseAnnotation.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @Author:zhouxudong
* @version: 1.0
* @Date: 2023/11/17 16:45
* @Description: 自定义注解,添加注解后不包装返回对象
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
public
@interface
ResponseAnnotation
{
}
src/main/java/com/postcard/service/config/auth/BaseContextHandler.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
auth
;
import
com.postcard.service.domain.JwtInfo
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 17:16
* @description: 当前登录人信息
*/
public
class
BaseContextHandler
{
private
static
final
ThreadLocal
<
JwtInfo
>
currentUserInfoThreadLocal
=
new
ThreadLocal
<>();
public
static
void
setCurrentUserInfo
(
JwtInfo
currentUserInfo
)
throws
Exception
{
if
(
currentUserInfo
!=
null
)
{
try
{
currentUserInfoThreadLocal
.
set
(
currentUserInfo
);
}
catch
(
Exception
e
)
{
throw
new
Exception
(
"失效"
);
}
}
}
public
static
JwtInfo
getCurrentUserInfo
()
{
JwtInfo
currentUserInfo
=
currentUserInfoThreadLocal
.
get
();
if
(
currentUserInfo
==
null
)
{
currentUserInfo
=
new
JwtInfo
();
currentUserInfoThreadLocal
.
set
(
currentUserInfo
);
}
return
currentUserInfo
;
}
public
static
void
removeCurrentUserInfo
()
{
currentUserInfoThreadLocal
.
remove
();
}
}
src/main/java/com/postcard/service/config/auth/CurrentUserInterceptor.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
auth
;
import
com.postcard.service.config.exception.AuthException
;
import
com.postcard.service.constant.Constants
;
import
com.postcard.service.domain.JwtInfo
;
import
com.postcard.service.util.jwt.JwtTokenUtil
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.servlet.AsyncHandlerInterceptor
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
/** 服务拦截器,根据配置的请求路径,进行请求的拦截,执行preHandle方法 */
@Configuration
public
class
CurrentUserInterceptor
implements
AsyncHandlerInterceptor
{
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
// 从header中获取权限请求头
String
authToken
=
request
.
getHeader
(
Constants
.
TOKEN_HEADER
);
if
(
StringUtils
.
isBlank
(
authToken
))
{
throw
new
AuthException
(
"未授权,请重新登录"
);
}
String
token
=
authToken
.
substring
(
"Bearer"
.
length
()
+
1
).
trim
();
JwtInfo
jwtUser
=
JwtTokenUtil
.
getJwtUser
(
token
);
// 根据token信息,生成当前登录用户信息的设置,存放容器threadlocal
BaseContextHandler
.
setCurrentUserInfo
(
jwtUser
);
return
true
;
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
e
)
{
BaseContextHandler
.
removeCurrentUserInfo
();
}
}
src/main/java/com/postcard/service/config/auth/WebConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
auth
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.web.servlet.config.annotation.EnableWebMvc
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
import
java.nio.charset.StandardCharsets
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
/** Web层配置类 */
@Configuration
@EnableWebMvc
public
class
WebConfig
implements
WebMvcConfigurer
{
@Autowired
private
CurrentUserInterceptor
currentUserInterceptor
;
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
// 添加需要拦截的路径,以及处理拦截的拦截器
registry
// 拦截器
.
addInterceptor
(
currentUserInterceptor
)
// 拦截路径
.
addPathPatterns
(
getIncludePathPatterns
())
// 白名单
.
excludePathPatterns
(
getExcludePathPatterns
());
}
@Override
public
void
addResourceHandlers
(
ResourceHandlerRegistry
registry
)
{
registry
.
addResourceHandler
(
"/**"
).
addResourceLocations
(
"classpath:/static/"
);
registry
.
addResourceHandler
(
"swagger-ui.html"
)
.
addResourceLocations
(
"classpath:/META-INF/resources/"
);
registry
.
addResourceHandler
(
"doc.html"
).
addResourceLocations
(
"classpath:/META-INF/resources/"
);
}
// Spring Boot使用UTF-8编码来对字符串进行处理
@Override
public
void
configureMessageConverters
(
List
<
HttpMessageConverter
<?>>
converters
)
{
converters
.
add
(
new
StringHttpMessageConverter
(
StandardCharsets
.
UTF_8
));
}
/** 需要拦截的信息 */
private
ArrayList
<
String
>
getIncludePathPatterns
()
{
ArrayList
<
String
>
list
=
new
ArrayList
<>();
String
[]
urls
=
{
"/**"
};
Collections
.
addAll
(
list
,
urls
);
return
list
;
}
private
String
[]
swagger
()
{
return
new
String
[]
{
"/swagger-resources/**"
,
"/swagger-ui.html"
,
"/webjars/**"
,
"/v3/**"
,
"/v2/**"
,
"/error"
,
"/swagger**/**"
,
"/swagger-ui/index.html"
,
"/swagger-ui/index.html/**"
,
"/doc.html"
,
"doc.html/**"
,
"/doc.html#/**"
,
"/**/login"
,
"/favicon.ico"
,
"/favicon.ico/**"
,
"/swagger-ui.html/**"
};
}
/** 不需要任何用户信息 白名单 */
private
ArrayList
<
String
>
getExcludePathPatterns
()
{
ArrayList
<
String
>
list
=
new
ArrayList
<>();
Collections
.
addAll
(
list
,
swagger
());
return
list
;
}
}
src/main/java/com/postcard/service/config/exception/AuthException.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
exception
;
/**
* @description: 授权异常
* @date: 2023/11/17 16:31
* @param:
* @return:
**/
public
class
AuthException
extends
BaseException
{
public
AuthException
(
String
message
)
{
super
(
message
);
}
}
src/main/java/com/postcard/service/config/exception/BaseException.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
exception
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
lombok.NoArgsConstructor
;
import
lombok.Setter
;
/**
* @description:
* @date: 2023/11/17 16:30
* @param:
* @return:
**/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public
class
BaseException
extends
RuntimeException
{
private
Integer
code
;
private
String
message
;
public
BaseException
(
String
message
){
super
(
message
);
this
.
message
=
message
;
}
}
src/main/java/com/postcard/service/config/exception/GlobalExceptionHandler.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
exception
;
import
com.postcard.service.domain.AjaxResult
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.ObjectError
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
javax.validation.ValidationException
;
import
java.util.stream.Collectors
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 16:32
* @description: 统一异常处理
*/
@RestControllerAdvice
@Slf4j
public
class
GlobalExceptionHandler
{
@ExceptionHandler
(
value
=
BaseException
.
class
)
public
AjaxResult
handlerException
(
BaseException
e
){
log
.
error
(
"发生异常BaseException:"
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
@ExceptionHandler
(
value
=
ValidationException
.
class
)
public
AjaxResult
handlerException
(
ValidationException
e
){
log
.
error
(
"发生参数校验异常Exception:"
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
@ExceptionHandler
(
value
=
MethodArgumentNotValidException
.
class
)
public
AjaxResult
handlerException
(
MethodArgumentNotValidException
e
){
log
.
error
(
"发生参数校验异常:"
,
e
);
String
error
=
e
.
getBindingResult
().
getAllErrors
().
stream
().
map
(
ObjectError:
:
getDefaultMessage
).
distinct
().
collect
(
Collectors
.
joining
(
";"
));
return
AjaxResult
.
error
(
error
);
// return AjaxResult.error(e.getMessage());
}
@ExceptionHandler
(
value
=
AuthException
.
class
)
public
AjaxResult
authException
(
AuthException
e
){
log
.
error
(
"发生权限异常:"
,
e
);
return
AjaxResult
.
auth
(
e
.
getMessage
());
}
@ExceptionHandler
(
value
=
ServiceException
.
class
)
public
AjaxResult
serviceException
(
ServiceException
e
){
log
.
error
(
"发生自定义异常Exception:"
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
@ExceptionHandler
(
value
=
Exception
.
class
)
public
AjaxResult
handlerException
(
Exception
e
){
log
.
error
(
"发生异常Exception:"
,
e
);
return
AjaxResult
.
error
(
e
.
getMessage
());
}
}
src/main/java/com/postcard/service/config/exception/GlobalResponseBodyAdvice.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
exception
;
import
cn.hutool.json.JSONUtil
;
import
com.postcard.service.config.annotation.ResponseAnnotation
;
import
com.postcard.service.domain.AjaxResult
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.server.ServerHttpRequest
;
import
org.springframework.http.server.ServerHttpResponse
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice
;
import
java.lang.reflect.AnnotatedElement
;
import
java.lang.reflect.Method
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/12/1 16:56
* @description:
*/
@RestControllerAdvice
(
basePackages
=
"com.lyy.user.moudle"
)
@Slf4j
public
class
GlobalResponseBodyAdvice
implements
ResponseBodyAdvice
{
@Override
public
boolean
supports
(
MethodParameter
methodParameter
,
Class
converterType
)
{
boolean
isIntercept
=
true
;
Method
method
=
methodParameter
.
getMethod
();
AnnotatedElement
annotatedElement
=
methodParameter
.
getAnnotatedElement
();
ResponseAnnotation
annotation
=
AnnotationUtils
.
findAnnotation
(
annotatedElement
,
ResponseAnnotation
.
class
);
if
(!
ObjectUtils
.
isEmpty
(
annotation
))
{
isIntercept
=
false
;
}
// methodParameter.getMethodAnnotations();
// if(AntPathMatcher)
return
isIntercept
;
}
@Override
public
Object
beforeBodyWrite
(
Object
body
,
MethodParameter
returnType
,
MediaType
selectedContentType
,
Class
selectedConverterType
,
ServerHttpRequest
request
,
ServerHttpResponse
response
)
{
AjaxResult
value
=
AjaxResult
.
success
(
body
);
boolean
isStringResult
=
returnType
.
getParameterType
().
equals
(
String
.
class
);
if
(
isStringResult
)
{
return
JSONUtil
.
toJsonStr
(
value
);
}
return
value
;
}
}
src/main/java/com/postcard/service/config/exception/ServiceException.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
exception
;
/**
* @description: 业务异常
* @date: 2023/11/17 16:31
* @param:
* @return:
**/
public
class
ServiceException
extends
BaseException
{
public
ServiceException
(
String
message
)
{
super
(
message
);
}
}
src/main/java/com/postcard/service/config/mybatis/MyBatisPlusConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
mybatis
;
import
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.transaction.annotation.EnableTransactionManagement
;
@Configuration
@EnableTransactionManagement
@Slf4j
public
class
MyBatisPlusConfig
{
/**
* @description:
* @date: 2023/11/17 16:22
* @param: []
* @return: com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor
**/
@Bean
public
MybatisPlusInterceptor
optimisticLockerInterceptor
()
{
//1 创建MybatisPlusInterceptor拦截器对象
MybatisPlusInterceptor
mpInterceptor
=
new
MybatisPlusInterceptor
();
//2 乐观锁
mpInterceptor
.
addInnerInterceptor
(
new
OptimisticLockerInnerInterceptor
());
//3.分页
mpInterceptor
.
addInnerInterceptor
(
new
PaginationInnerInterceptor
());
return
mpInterceptor
;
}
}
src/main/java/com/postcard/service/config/mybatis/MyMetaObjectHandler.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
mybatis
;
import
com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
;
import
com.postcard.service.config.auth.BaseContextHandler
;
import
com.postcard.service.domain.JwtInfo
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.ibatis.reflection.MetaObject
;
import
org.springframework.stereotype.Component
;
import
java.time.LocalDateTime
;
import
java.util.Arrays
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 16:46
* @description:
*/
@Slf4j
@Component
public
class
MyMetaObjectHandler
implements
MetaObjectHandler
{
private
final
String
[]
createNeedToFill
=
{
"createBy"
,
"createTime"
,
"updateBy"
,
"updateTime"
,
"version"
};
private
final
String
[]
updateNeedToFill
=
{
"updateBy"
,
"updateTime"
};
private
final
Class
[]
ignoreAutoFillEntity
=
{};
@Override
public
void
insertFill
(
MetaObject
metaObject
)
{
if
(!
ignoreAutoFill
(
metaObject
))
{
autofill
(
metaObject
,
createNeedToFill
);
}
}
@Override
public
void
updateFill
(
MetaObject
metaObject
)
{
if
(!
ignoreAutoFill
(
metaObject
))
{
autofill
(
metaObject
,
updateNeedToFill
);
}
}
private
void
autofill
(
MetaObject
metaObject
,
String
[]
arrayNeedToFill
)
{
JwtInfo
userInfo
=
BaseContextHandler
.
getCurrentUserInfo
();
Arrays
.
stream
(
arrayNeedToFill
)
.
forEach
(
property
->
{
if
(
metaObject
.
hasSetter
(
property
))
{
if
(
property
.
endsWith
(
"By"
))
{
this
.
setFieldValByName
(
property
,
userInfo
.
getUserName
(),
metaObject
);
}
if
(
property
.
endsWith
(
"Time"
))
{
this
.
setFieldValByName
(
property
,
LocalDateTime
.
now
(),
metaObject
);
}
if
(
property
.
equals
(
"version"
))
{
this
.
setFieldValByName
(
property
,
1
,
metaObject
);
}
}
});
}
private
Boolean
ignoreAutoFill
(
MetaObject
metaObject
)
{
return
Arrays
.
stream
(
ignoreAutoFillEntity
)
.
anyMatch
(
entity
->
metaObject
.
getOriginalObject
().
getClass
()
==
entity
);
}
}
src/main/java/com/postcard/service/config/other/CustomerConvertConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
other
;
import
lombok.extern.slf4j.Slf4j
;
import
ma.glasnost.orika.CustomConverter
;
import
ma.glasnost.orika.MappingContext
;
import
ma.glasnost.orika.metadata.Type
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.Order
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalTime
;
import
java.time.format.DateTimeFormatter
;
@Configuration
@Slf4j
@Order
(
30
)
public
class
CustomerConvertConfig
{
private
static
final
DateTimeFormatter
df_datetime
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
private
static
final
DateTimeFormatter
df_date
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd"
);
private
static
final
DateTimeFormatter
df_time
=
DateTimeFormatter
.
ofPattern
(
"HH:mm:ss"
);
/**
* String -> LocalDateTime 转换器
*
* @return
*/
@Bean
(
"localDateTimeConvert"
)
public
CustomConverter
localDateTimeConvert
()
{
return
new
CustomConverter
<
String
,
LocalDateTime
>()
{
@Override
public
boolean
canConvert
(
Type
sourceType
,
Type
destinationType
)
{
return
((
String
.
class
).
isAssignableFrom
(
sourceType
.
getClass
()))
&&
((
LocalDateTime
.
class
).
isAssignableFrom
(
destinationType
.
getClass
()));
}
@Override
public
LocalDateTime
convert
(
String
o
,
Type
<?
extends
LocalDateTime
>
type
,
MappingContext
mappingContext
)
{
return
LocalDateTime
.
parse
(
o
,
df_datetime
);
}
};
}
/** String -> LocalDate 转换器 */
@Bean
(
"localDateConvert"
)
public
CustomConverter
localDateConvert
()
{
return
new
CustomConverter
<
String
,
LocalDate
>()
{
@Override
public
boolean
canConvert
(
Type
sourceType
,
Type
destinationType
)
{
return
((
String
.
class
).
isAssignableFrom
(
sourceType
.
getClass
()))
&&
((
LocalDate
.
class
).
isAssignableFrom
(
destinationType
.
getClass
()));
}
@Override
public
LocalDate
convert
(
String
o
,
Type
<?
extends
LocalDate
>
type
,
MappingContext
mappingContext
)
{
return
LocalDate
.
parse
(
o
,
df_date
);
}
};
}
/**
* String -> LocalTime 转换器
*
* @return
*/
@Bean
(
"localTimeConvert"
)
public
CustomConverter
localTimeConvert
()
{
return
new
CustomConverter
<
String
,
LocalTime
>()
{
@Override
public
boolean
canConvert
(
Type
sourceType
,
Type
destinationType
)
{
return
((
String
.
class
).
isAssignableFrom
(
sourceType
.
getClass
()))
&&
((
LocalTime
.
class
).
isAssignableFrom
(
destinationType
.
getClass
()));
}
@Override
public
LocalTime
convert
(
String
o
,
Type
<?
extends
LocalTime
>
type
,
MappingContext
mappingContext
)
{
return
LocalTime
.
parse
(
o
,
df_time
);
}
};
}
}
src/main/java/com/postcard/service/config/other/OrikaConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
other
;
import
lombok.extern.slf4j.Slf4j
;
import
ma.glasnost.orika.CustomConverter
;
import
ma.glasnost.orika.MapperFactory
;
import
ma.glasnost.orika.converter.ConverterFactory
;
import
ma.glasnost.orika.impl.DefaultMapperFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.annotation.Order
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 16:53
* @description: 类型转换
*/
@Configuration
@Slf4j
@Order
(
31
)
public
class
OrikaConfig
{
@Autowired
@Qualifier
(
"localDateTimeConvert"
)
private
CustomConverter
localDateTimeConvert
;
@Autowired
@Qualifier
(
"localDateConvert"
)
private
CustomConverter
localDateConvert
;
@Autowired
@Qualifier
(
"localTimeConvert"
)
private
CustomConverter
localTimeConvert
;
@Bean
public
MapperFactory
mapperFactory
()
{
MapperFactory
mapperFactory
=
new
DefaultMapperFactory
.
Builder
().
build
();
// 注册自定义转换器
ConverterFactory
converterFactory
=
mapperFactory
.
getConverterFactory
();
converterFactory
.
registerConverter
(
localDateTimeConvert
);
converterFactory
.
registerConverter
(
localDateConvert
);
converterFactory
.
registerConverter
(
localTimeConvert
);
return
mapperFactory
;
}
}
src/main/java/com/postcard/service/config/redis/RedisConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
redis
;
import
com.fasterxml.jackson.annotation.JsonAutoDetect
;
import
com.fasterxml.jackson.annotation.JsonTypeInfo
;
import
com.fasterxml.jackson.annotation.PropertyAccessor
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
;
import
org.springframework.data.redis.serializer.StringRedisSerializer
;
/**
* redis配置
*
* @author garden
*/
@Configuration
public
class
RedisConfig
{
@Bean
@SuppressWarnings
(
value
=
{
"unchecked"
,
"rawtypes"
})
public
RedisTemplate
<
Object
,
Object
>
redisTemplate
(
RedisConnectionFactory
connectionFactory
)
{
RedisTemplate
<
Object
,
Object
>
template
=
new
RedisTemplate
<>();
template
.
setConnectionFactory
(
connectionFactory
);
StringRedisSerializer
stringRedisSerializer
=
new
StringRedisSerializer
();
template
.
setKeySerializer
(
stringRedisSerializer
);
// key的序列化类型
Jackson2JsonRedisSerializer
jackson2JsonRedisSerializer
=
new
Jackson2JsonRedisSerializer
(
Object
.
class
);
ObjectMapper
objectMapper
=
new
ObjectMapper
();
objectMapper
.
setVisibility
(
PropertyAccessor
.
ALL
,
JsonAutoDetect
.
Visibility
.
ANY
);
objectMapper
.
activateDefaultTyping
(
LaissezFaireSubTypeValidator
.
instance
,
ObjectMapper
.
DefaultTyping
.
NON_FINAL
,
JsonTypeInfo
.
As
.
PROPERTY
);
jackson2JsonRedisSerializer
.
setObjectMapper
(
objectMapper
);
jackson2JsonRedisSerializer
.
setObjectMapper
(
objectMapper
);
template
.
setValueSerializer
(
jackson2JsonRedisSerializer
);
// value的序列化类型
template
.
setHashKeySerializer
(
stringRedisSerializer
);
template
.
setHashValueSerializer
(
jackson2JsonRedisSerializer
);
template
.
afterPropertiesSet
();
return
template
;
}
}
src/main/java/com/postcard/service/config/swagger/SwaggerConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
swagger
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
springfox.documentation.builders.ApiInfoBuilder
;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.builders.RequestHandlerSelectors
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.service.Contact
;
import
springfox.documentation.spi.DocumentationType
;
import
springfox.documentation.spring.web.plugins.Docket
;
/**
* @Author:zhouxudong
*
* @version: 1.0 @Date: 2023/11/22 18:31 @Description:
*/
@Slf4j
@Configuration
public
class
SwaggerConfig
{
@Bean
// 相当于Spring 配置中的<bean>
public
Docket
createRestApi
()
{
return
new
Docket
(
DocumentationType
.
OAS_30
)
// 是否启用Swagger
// 分组设置
.
groupName
(
"区域大纲基本接口"
)
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.
apiInfo
(
apiInfo
())
// 设置哪些接口暴露给Swagger展示
.
select
()
// 扫描所有有注解的api,用这种方式更灵活
.
apis
(
RequestHandlerSelectors
.
withMethodAnnotation
(
ApiOperation
.
class
))
.
paths
(
PathSelectors
.
any
())
.
build
();
}
private
ApiInfo
apiInfo
()
{
// 用ApiInfoBuilder进行定制
return
new
ApiInfoBuilder
()
// 设置标题
.
title
(
"标题:明信片模块_接口文档"
)
// 描述
.
description
(
"描述:明信片模块_接口文档"
)
// 作者信息
.
contact
(
new
Contact
(
"postcard"
,
null
,
null
))
// 版本
.
version
(
"版本号:v1.0"
)
.
build
();
}
}
src/main/java/com/postcard/service/config/webflux/WebClientConfig.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
config
.
webflux
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.reactive.function.client.WebClient
;
@Configuration
@Slf4j
public
class
WebClientConfig
{
@Bean
public
WebClient
webClient
()
{
return
WebClient
.
builder
().
build
();
}
}
src/main/java/com/postcard/service/constant/Constants.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
constant
;
/**
* @Author:zhouxudong
*
* @version: 1.0 @Date: 2023/12/14 17:01 @Description:
*/
public
class
Constants
{
public
static
final
String
TOKEN_HEADER
=
"Authorization"
;
}
src/main/java/com/postcard/service/constant/MsgConstants.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
constant
;
/**
* @Author:zhouxudong
* @version: 1.0
* @Date: 2023/12/14 17:02
* @Description:
*/
public
class
MsgConstants
{
}
src/main/java/com/postcard/service/constant/RedisConstants.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
constant
;
/**
* @Author:zhouxudong
* @version: 1.0
* @Date: 2023/12/14 17:02
* @Description:
*/
public
class
RedisConstants
{
}
src/main/java/com/postcard/service/constant/TokenConstants.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
constant
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 17:14
* @description:
*/
public
class
TokenConstants
{
public
static
final
byte
[]
SECRET
=
"03jh6Uf6#4z9^c6!gGA|BYc!@q3Sl4IDR"
.
getBytes
();
public
static
final
String
DETAILS
=
"details"
;
public
static
final
String
AUTHORITIES
=
"authorities"
;
public
static
final
String
EXPIRE_TIME
=
"expire_time"
;
public
static
final
String
CREATE_TIME
=
"create_time"
;
public
static
final
String
RESULT
=
"message"
;
public
static
final
String
SUCCESS
=
"success"
;
public
static
final
class
TOKEN_RESULT
{
public
static
final
String
TOKEN_PARSE_SUCCESS
=
"token解析成功"
;
}
public
static
final
String
DATA
=
"data"
;
}
src/main/java/com/postcard/service/domain/AjaxResult.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
domain
;
import
lombok.Data
;
import
org.apache.commons.lang3.ObjectUtils
;
import
java.util.HashMap
;
import
java.util.Objects
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/24 17:21
* @description: 请求用户服务返回数据格式
*/
@Data
public
class
AjaxResult
extends
HashMap
<
String
,
Object
>
{
private
static
final
long
serialVersionUID
=
1L
;
/** 状态码 */
public
static
final
String
CODE_TAG
=
"code"
;
/** 返回内容 */
public
static
final
String
MSG_TAG
=
"msg"
;
/** 数据对象 */
public
static
final
String
DATA_TAG
=
"data"
;
/** 状态类型 */
public
enum
ErrorCodeEum
{
/** 成功 */
SUCCESS
(
200
,
"成功"
),
/** 警告 */
WARN
(
300
,
"警告"
),
AUTHENTICATION
(
401
,
"认证"
),
/** 错误 */
ERROR
(
500
,
"错误"
);
private
final
int
code
;
private
final
String
message
;
ErrorCodeEum
(
int
code
,
String
message
)
{
this
.
code
=
code
;
this
.
message
=
message
;
}
public
int
code
()
{
return
this
.
code
;
}
public
String
message
()
{
return
this
.
message
;
}
}
/** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 */
public
AjaxResult
()
{}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param errorCodeEum 状态类型
* @param msg 返回内容
*/
public
AjaxResult
(
ErrorCodeEum
errorCodeEum
,
String
msg
)
{
super
.
put
(
CODE_TAG
,
errorCodeEum
.
code
());
super
.
put
(
MSG_TAG
,
msg
);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态类型
* @param msg 返回内容
* @param data 数据对象
*/
public
AjaxResult
(
int
code
,
String
msg
,
Object
data
)
{
super
.
put
(
CODE_TAG
,
code
);
super
.
put
(
MSG_TAG
,
msg
);
if
(
ObjectUtils
.
isNotEmpty
(
data
))
{
super
.
put
(
DATA_TAG
,
data
);
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public
static
AjaxResult
success
()
{
return
AjaxResult
.
success
(
"操作成功"
);
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public
static
AjaxResult
success
(
Object
data
)
{
return
AjaxResult
.
success
(
"操作成功"
,
data
);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public
static
AjaxResult
success
(
String
msg
)
{
return
AjaxResult
.
success
(
msg
,
null
);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public
static
AjaxResult
success
(
String
msg
,
Object
data
)
{
return
new
AjaxResult
(
ErrorCodeEum
.
SUCCESS
.
code
(),
msg
,
data
);
}
/**
* 返回消息
*
* @param msg 返回内容
* @return 警告消息
*/
public
static
AjaxResult
warn
(
String
msg
)
{
return
AjaxResult
.
warn
(
msg
,
null
);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public
static
AjaxResult
warn
(
String
msg
,
Object
data
)
{
return
new
AjaxResult
(
ErrorCodeEum
.
WARN
.
code
(),
msg
,
data
);
}
/**
* 返回授权消息
*
* @param msg 返回内容
* @return 返回授权消息
*/
public
static
AjaxResult
auth
(
String
msg
)
{
return
AjaxResult
.
auth
(
msg
,
null
);
}
/**
* 返回授权消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 返回授权消息
*/
public
static
AjaxResult
auth
(
String
msg
,
Object
data
)
{
return
new
AjaxResult
(
ErrorCodeEum
.
AUTHENTICATION
.
code
(),
msg
,
data
);
}
/**
* 返回错误消息
*
* @return
*/
public
static
AjaxResult
error
()
{
return
AjaxResult
.
error
(
"操作失败"
);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public
static
AjaxResult
error
(
String
msg
)
{
return
AjaxResult
.
error
(
msg
,
null
);
}
public
static
AjaxResult
error
(
int
code
,
String
msg
)
{
return
new
AjaxResult
(
ErrorCodeEum
.
ERROR
.
code
(),
msg
,
null
);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public
static
AjaxResult
error
(
String
msg
,
Object
data
)
{
return
new
AjaxResult
(
ErrorCodeEum
.
ERROR
.
code
(),
msg
,
data
);
}
/**
* 是否为成功消息
*
* @return 结果
*/
public
boolean
isSuccess
()
{
return
Objects
.
equals
(
ErrorCodeEum
.
SUCCESS
.
code
(),
this
.
get
(
CODE_TAG
));
}
/**
* 是否为警告消息
*
* @return 结果
*/
public
boolean
isWarn
()
{
return
Objects
.
equals
(
ErrorCodeEum
.
WARN
.
code
(),
this
.
get
(
CODE_TAG
));
}
/**
* 是否为错误消息
*
* @return 结果
*/
public
boolean
isError
()
{
return
Objects
.
equals
(
ErrorCodeEum
.
ERROR
.
code
(),
this
.
get
(
CODE_TAG
));
}
/**
* 方便链式调用
*
* @param key 键
* @param value 值
* @return 数据对象
*/
@Override
public
AjaxResult
put
(
String
key
,
Object
value
)
{
super
.
put
(
key
,
value
);
return
this
;
}
}
src/main/java/com/postcard/service/domain/BaseEntity.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
domain
;
import
com.baomidou.mybatisplus.annotation.FieldFill
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.Version
;
import
com.baomidou.mybatisplus.extension.activerecord.Model
;
import
lombok.*
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
/**
* @Author:zhouxudong
* @version: 1.0
* @Date: 2023/11/23 16:57
* @Description:
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public
abstract
class
BaseEntity
extends
Model
implements
Serializable
{
@TableId
protected
Long
id
;
@TableField
(
value
=
"create_by"
,
fill
=
FieldFill
.
INSERT
)
protected
String
createBy
;
@TableField
(
value
=
"create_time"
,
fill
=
FieldFill
.
INSERT
)
protected
LocalDateTime
createTime
;
@TableField
(
value
=
"update_by"
,
fill
=
FieldFill
.
INSERT_UPDATE
)
protected
String
updateBy
;
@TableField
(
value
=
"update_time"
,
fill
=
FieldFill
.
INSERT_UPDATE
)
protected
LocalDateTime
updateTime
;
@Version
@TableField
(
value
=
"version"
,
fill
=
FieldFill
.
INSERT
)
protected
Integer
version
;
public
Serializable
pkVal
()
{
return
this
.
id
;
}
}
src/main/java/com/postcard/service/domain/JwtInfo.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
domain
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 17:13
* @description: jwt 信息
*/
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors
(
chain
=
true
)
public
class
JwtInfo
{
/** 人员id */
private
Integer
userId
;
/** 人员名称 */
private
String
userName
;
private
String
loginName
;
/** 手机号 */
private
String
phone
;
}
src/main/java/com/postcard/service/util/IpUtils.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
util
;
import
org.apache.commons.lang3.ObjectUtils
;
import
javax.servlet.http.HttpServletRequest
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
/**
* 获取IP方法
*
* @author ruoyi
*/
public
class
IpUtils
{
public
static
String
getIpAddr
(
HttpServletRequest
request
)
{
if
(
request
==
null
)
{
return
null
;
}
String
ip
=
null
;
// X-Forwarded-For:Squid 服务代理
String
ipAddresses
=
request
.
getHeader
(
"X-Forwarded-For"
);
if
(
ipAddresses
==
null
||
ipAddresses
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddresses
))
{
// Proxy-Client-IP:apache 服务代理
ipAddresses
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
ipAddresses
==
null
||
ipAddresses
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddresses
))
{
// WL-Proxy-Client-IP:weblogic 服务代理
ipAddresses
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
ipAddresses
==
null
||
ipAddresses
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddresses
))
{
// HTTP_CLIENT_IP:有些代理服务器
ipAddresses
=
request
.
getHeader
(
"HTTP_CLIENT_IP"
);
}
if
(
ipAddresses
==
null
||
ipAddresses
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddresses
))
{
// X-Real-IP:nginx服务代理
ipAddresses
=
request
.
getHeader
(
"X-Real-IP"
);
}
// 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
if
(
ipAddresses
!=
null
&&
ipAddresses
.
length
()
!=
0
)
{
ip
=
ipAddresses
.
split
(
","
)[
0
];
}
// 还是不能获取到,最后再通过request.getRemoteAddr();获取
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ipAddresses
))
{
ip
=
request
.
getRemoteAddr
();
}
return
ip
.
equals
(
"0:0:0:0:0:0:0:1"
)
?
"127.0.0.1"
:
ip
;
}
public
static
boolean
internalIp
(
String
ip
)
{
byte
[]
addr
=
textToNumericFormatV4
(
ip
);
return
internalIp
(
addr
)
||
"127.0.0.1"
.
equals
(
ip
);
}
private
static
boolean
internalIp
(
byte
[]
addr
)
{
if
(
ObjectUtils
.
isEmpty
(
addr
)
||
addr
.
length
<
2
)
{
return
true
;
}
final
byte
b0
=
addr
[
0
];
final
byte
b1
=
addr
[
1
];
// 10.x.x.x/8
final
byte
SECTION_1
=
0x0A
;
// 172.16.x.x/12
final
byte
SECTION_2
=
(
byte
)
0xAC
;
final
byte
SECTION_3
=
(
byte
)
0x10
;
final
byte
SECTION_4
=
(
byte
)
0x1F
;
// 192.168.x.x/16
final
byte
SECTION_5
=
(
byte
)
0xC0
;
final
byte
SECTION_6
=
(
byte
)
0xA8
;
switch
(
b0
)
{
case
SECTION_1:
return
true
;
case
SECTION_2:
if
(
b1
>=
SECTION_3
&&
b1
<=
SECTION_4
)
{
return
true
;
}
case
SECTION_5:
switch
(
b1
)
{
case
SECTION_6:
return
true
;
}
default
:
return
false
;
}
}
/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public
static
byte
[]
textToNumericFormatV4
(
String
text
)
{
if
(
text
.
length
()
==
0
)
{
return
null
;
}
byte
[]
bytes
=
new
byte
[
4
];
String
[]
elements
=
text
.
split
(
"\\."
,
-
1
);
try
{
long
l
;
int
i
;
switch
(
elements
.
length
)
{
case
1
:
l
=
Long
.
parseLong
(
elements
[
0
]);
if
((
l
<
0L
)
||
(
l
>
4294967295L
))
{
return
null
;
}
bytes
[
0
]
=
(
byte
)
(
int
)
(
l
>>
24
&
0xFF
);
bytes
[
1
]
=
(
byte
)
(
int
)
((
l
&
0xFFFFFF
)
>>
16
&
0xFF
);
bytes
[
2
]
=
(
byte
)
(
int
)
((
l
&
0xFFFF
)
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
2
:
l
=
Integer
.
parseInt
(
elements
[
0
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
0
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
l
=
Integer
.
parseInt
(
elements
[
1
]);
if
((
l
<
0L
)
||
(
l
>
16777215L
))
{
return
null
;
}
bytes
[
1
]
=
(
byte
)
(
int
)
(
l
>>
16
&
0xFF
);
bytes
[
2
]
=
(
byte
)
(
int
)
((
l
&
0xFFFF
)
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
3
:
for
(
i
=
0
;
i
<
2
;
++
i
)
{
l
=
Integer
.
parseInt
(
elements
[
i
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
i
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
}
l
=
Integer
.
parseInt
(
elements
[
2
]);
if
((
l
<
0L
)
||
(
l
>
65535L
))
{
return
null
;
}
bytes
[
2
]
=
(
byte
)
(
int
)
(
l
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
4
:
for
(
i
=
0
;
i
<
4
;
++
i
)
{
l
=
Integer
.
parseInt
(
elements
[
i
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
i
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
}
break
;
default
:
return
null
;
}
}
catch
(
NumberFormatException
e
)
{
return
null
;
}
return
bytes
;
}
public
static
String
getHostIp
()
{
try
{
return
InetAddress
.
getLocalHost
().
getHostAddress
();
}
catch
(
UnknownHostException
e
)
{
}
return
"127.0.0.1"
;
}
public
static
String
getHostName
()
{
try
{
return
InetAddress
.
getLocalHost
().
getHostName
();
}
catch
(
UnknownHostException
e
)
{
}
return
"未知"
;
}
}
src/main/java/com/postcard/service/util/jwt/JwtTokenUtil.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
util
.
jwt
;
import
cn.hutool.core.bean.BeanUtil
;
import
com.nimbusds.jose.*
;
import
com.nimbusds.jose.crypto.MACVerifier
;
import
com.postcard.service.config.exception.AuthException
;
import
com.postcard.service.constant.TokenConstants
;
import
com.postcard.service.domain.JwtInfo
;
import
lombok.extern.slf4j.Slf4j
;
import
java.text.ParseException
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author: zhouxudong
* @version: 1.0
* @createTime: 2023/11/17 17:11
* @description:
*/
@Slf4j
public
class
JwtTokenUtil
{
/**
* 采用HS256算法生成token
*
* @param
* @return
* @throws JOSEException
*/
/* public static String createToken(SysUserInfo sysUserInfo, List authorities) {
JwtInfo jwtUser =
new JwtInfo()
.setUserId(sysUserInfo.getUserId())
.setUserName(sysUserInfo.getUserName())
.setPhone(sysUserInfo.getPhonenumber())
.setLoginName(sysUserInfo.getLoginName());
JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);
JSONObject jsonObject = new JSONObject();
jsonObject.appendField(TokenConstants.DETAILS, jwtUser);
jsonObject.appendField(TokenConstants.AUTHORITIES, authorities);
jsonObject.appendField(TokenConstants.CREATE_TIME, System.currentTimeMillis());
Payload payload = new Payload(jsonObject);
JWSObject jwsObject = new JWSObject(jwsHeader, payload);
JWSSigner jwsSigner;
try {
jwsSigner = new MACSigner(TokenConstants.SECRET);
try {
jwsObject.sign(jwsSigner);
} catch (JOSEException e) {
log.error("生成token异常", e);
}
} catch (KeyLengthException e) {
log.error("生成token,密钥长度异常", e);
}
return jwsObject.serialize();
}*/
/**
* 解析token
*
* @param token
* @return
* @throws ParseException
* @throws JOSEException
*/
public
static
Map
<
String
,
Object
>
parseToken
(
String
token
)
{
/*if (!ObjectUtils.isEmpty(token) && StringUtils.startsWithIgnoreCase(token, "Bearer ")) {
token = token.substring(7);
}*/
JWSObject
jwsObject
;
JWSVerifier
jwsVerifier
;
try
{
jwsObject
=
JWSObject
.
parse
(
token
);
jwsVerifier
=
new
MACVerifier
(
TokenConstants
.
SECRET
);
}
catch
(
ParseException
|
JOSEException
e
)
{
log
.
error
(
"解析token报错:"
,
e
);
throw
new
AuthException
(
"认证失败,请重新登录"
);
}
return
verify
(
jwsObject
,
jwsVerifier
);
}
/**
* 验证token
*
* @param jwsObject
* @param jwsVerifier
* @return
* @throws JOSEException
*/
private
static
Map
<
String
,
Object
>
verify
(
JWSObject
jwsObject
,
JWSVerifier
jwsVerifier
)
{
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
Payload
payload
=
jwsObject
.
getPayload
();
boolean
flag
=
Boolean
.
TRUE
;
try
{
if
(
jwsObject
.
verify
(
jwsVerifier
))
{
resultMap
.
put
(
TokenConstants
.
RESULT
,
TokenConstants
.
TOKEN_RESULT
.
TOKEN_PARSE_SUCCESS
);
Map
<
String
,
Object
>
jsonObject
=
payload
.
toJSONObject
();
resultMap
.
put
(
TokenConstants
.
DATA
,
jsonObject
);
}
else
{
throw
new
AuthException
(
"认证失败"
);
// resultMap.put(TokenConstants.RESULT, TokenConstants.TOKEN_RESULT.TOKEN_PARSE_FAILED);
}
}
catch
(
JOSEException
e
)
{
log
.
error
(
"解析token报错"
,
e
);
throw
new
AuthException
(
"认证失败"
);
}
resultMap
.
put
(
TokenConstants
.
SUCCESS
,
flag
);
return
resultMap
;
}
/**
* 返回jwtUser
*
* @param token
* @return
*/
public
static
JwtInfo
getJwtUser
(
String
token
)
{
Map
<
String
,
Object
>
objectMap
=
parseToken
(
token
);
Map
<
String
,
Object
>
data
=
(
Map
<
String
,
Object
>)
objectMap
.
get
(
TokenConstants
.
DATA
);
JwtInfo
jwtUser
=
BeanUtil
.
toBean
(
data
.
get
(
TokenConstants
.
DETAILS
),
JwtInfo
.
class
);
return
jwtUser
;
}
}
src/main/java/com/postcard/service/util/redis/RedisUtil.java
0 → 100644
View file @
70128765
package
com
.
postcard
.
service
.
util
.
redis
;
import
cn.hutool.core.date.DateTime
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.extra.spring.SpringUtil
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
/**
* @Author:zhouxudong
*
* @version: 1.0 @Date: 2023/11/20 9:27 @Description: redis 工具类
*/
public
class
RedisUtil
{
private
RedisUtil
()
{}
@SuppressWarnings
(
"unchecked"
)
private
static
RedisTemplate
<
String
,
Object
>
redisTemplate
=
SpringUtil
.
getBean
(
"redisTemplate"
,
RedisTemplate
.
class
);
/**
* 设置有效时间 单位默认秒
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功;false=设置失败
*/
public
static
boolean
expire
(
final
String
key
,
final
long
timeout
)
{
return
expire
(
key
,
timeout
,
TimeUnit
.
SECONDS
);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功;false=设置失败
*/
public
static
boolean
expire
(
final
String
key
,
final
long
timeout
,
final
TimeUnit
unit
)
{
Boolean
ret
=
redisTemplate
.
expire
(
key
,
timeout
,
unit
);
return
ret
!=
null
&&
ret
;
}
/**
* 删除单个key
*
* @param key 键
* @return true=删除成功;false=删除失败
*/
public
static
boolean
del
(
final
String
key
)
{
Boolean
ret
=
redisTemplate
.
delete
(
key
);
return
ret
!=
null
&&
ret
;
}
/**
* 删除多个key
*
* @param keys 键集合
* @return 成功删除的个数
*/
public
static
long
del
(
final
Collection
<
String
>
keys
)
{
Long
ret
=
redisTemplate
.
delete
(
keys
);
return
ret
==
null
?
0
:
ret
;
}
/**
* 存入普通对象
*
* @param key Redis键
* @param value 值
*/
public
static
void
set
(
final
String
key
,
final
Object
value
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
);
}
// 存储普通对象操作
/**
* 存入普通对象
*
* @param key 键
* @param value 值
* @param timeout 有效期,单位秒
*/
public
static
void
set
(
final
String
key
,
final
Object
value
,
final
long
timeout
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
,
timeout
,
TimeUnit
.
SECONDS
);
}
public
static
void
set
(
final
String
key
,
final
Object
value
,
final
long
timeout
,
TimeUnit
timeUnit
)
{
redisTemplate
.
opsForValue
().
set
(
key
,
value
,
timeout
,
timeUnit
);
}
/**
* 获取普通对象
*
* @param key 键
* @return 对象
*/
public
static
Object
get
(
final
String
key
)
{
return
redisTemplate
.
opsForValue
().
get
(
key
);
}
/**
* @description: 获取key的剩余过期时间 如果key不存在 或者没有设置过期时间 返回 -1 单位 为秒
* @date: 2023/11/23 9:53
* @param: [key]
* @return: java.lang.Long
**/
public
static
Long
getExpire
(
final
String
key
){
return
redisTemplate
.
getExpire
(
key
);
}
// 存储Hash操作
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param filed Hash filed键
* @param value 值
*/
public
static
void
hPut
(
final
String
key
,
final
String
filed
,
final
Object
value
)
{
redisTemplate
.
opsForHash
().
put
(
key
,
filed
,
value
);
}
/**
* 往Hash中存入多个数据
*
* @param key Redis键
* @param filedMap Hash键值对
*/
public
static
void
hPutAll
(
final
String
key
,
final
Map
<
String
,
Object
>
filedMap
)
{
redisTemplate
.
opsForHash
().
putAll
(
key
,
filedMap
);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param filed Hash filed键
* @return Hash中的对象
*/
public
static
Object
hGet
(
final
String
key
,
final
String
filed
)
{
return
redisTemplate
.
opsForHash
().
get
(
key
,
filed
);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param fileds Hash filed键集合
* @return Hash对象集合
*/
public
static
List
<
Object
>
hMultiGet
(
final
String
key
,
final
Collection
<
Object
>
fileds
)
{
return
redisTemplate
.
opsForHash
().
multiGet
(
key
,
fileds
);
}
// 存储Set相关操作
/**
* 往Set中存入数据
*
* @param key Redis键
* @param values 值
* @return 存入的个数
*/
public
static
long
sSet
(
final
String
key
,
final
Object
...
values
)
{
Long
count
=
redisTemplate
.
opsForSet
().
add
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
/**
* 删除Set中的数据
*
* @param key Redis键
* @param values 值
* @return 移除的个数
*/
public
static
long
sDel
(
final
String
key
,
final
Object
...
values
)
{
Long
count
=
redisTemplate
.
opsForSet
().
remove
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
// 存储List相关操作
/**
* 往List左侧中存入数据
*
* @param key Redis键
* @param value 数据
* @return 存入的个数
*/
public
static
long
lPush
(
final
String
key
,
final
Object
value
)
{
Long
count
=
redisTemplate
.
opsForList
().
leftPush
(
key
,
value
);
return
count
==
null
?
0
:
count
;
}
/**
* 往List右侧中存入数据
*
* @param key Redis键
* @param value 数据
* @return 存入的个数
*/
public
static
long
rPush
(
final
String
key
,
final
Object
value
)
{
Long
count
=
redisTemplate
.
opsForList
().
rightPush
(
key
,
value
);
return
count
==
null
?
0
:
count
;
}
/**
* 往List中左侧存入多个数据
*
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public
static
long
lPushAll
(
final
String
key
,
final
Collection
<
Object
>
values
)
{
Long
count
=
redisTemplate
.
opsForList
().
leftPushAll
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
/**
* 往List中左侧存入多个数据
*
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public
static
long
lPushAll
(
final
String
key
,
final
Object
...
values
)
{
Long
count
=
redisTemplate
.
opsForList
().
leftPushAll
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
/**
* 往List中右侧存入多个数据
*
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public
static
long
rPushAll
(
final
String
key
,
final
Collection
<
Object
>
values
)
{
Long
count
=
redisTemplate
.
opsForList
().
rightPushAll
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
/**
* 往List中右侧存入多个数据
*
* @param key Redis键
* @param values 多个数据
* @return 存入的个数
*/
public
static
long
rPushAll
(
final
String
key
,
final
Object
...
values
)
{
Long
count
=
redisTemplate
.
opsForList
().
rightPushAll
(
key
,
values
);
return
count
==
null
?
0
:
count
;
}
/**
* 从List中获取begin到end之间的元素
*
* @param key Redis键
* @param start 开始位置
* @param end 结束位置(start=0,end=-1表示获取全部元素)
* @return List对象
*/
public
static
List
<
Object
>
listGetRange
(
final
String
key
,
final
int
start
,
final
int
end
)
{
return
redisTemplate
.
opsForList
().
range
(
key
,
start
,
end
);
}
/**
* 从List左侧弹出数据
*
* @param key Redis键
* @return 对象
*/
public
static
Object
listGetL
(
final
String
key
)
{
return
redisTemplate
.
opsForList
().
leftPop
(
key
);
}
/**
* 从List右侧弹出数据
*
* @param key Redis键
* @return 对象
*/
public
static
Object
listGetR
(
final
String
key
)
{
return
redisTemplate
.
opsForList
().
rightPop
(
key
);
}
/**
* @description: 移除有序集合中给定的分数区间的所有成员
* @date: 2023/11/27 15:19
* @param: [key, start, end]
* @return: Long 移除的成员数
**/
public
static
Long
delZset
(
String
key
,
double
start
,
double
end
){
return
redisTemplate
.
opsForZSet
().
removeRangeByScore
(
key
,
start
,
end
);
}
/**
* @description: 计算在有序集合中指定区间分数的成员数
* @date: 2023/11/27 15:21
* @param: [key, start, end]
* @return: java.lang.Long
**/
public
static
Long
countZset
(
String
key
,
double
start
,
double
end
){
return
redisTemplate
.
opsForZSet
().
count
(
key
,
start
,
end
);
}
/**
* @description: 向有序集合添加一个或多个成员,或者更新已存在成员的分数
* @date: 2023/11/27 15:26
* @param: [key, fileds, end]
* @return: boolean
**/
public
static
boolean
addZset
(
String
key
,
Object
fileds
,
double
end
){
return
Boolean
.
TRUE
.
equals
(
redisTemplate
.
opsForZSet
().
add
(
key
,
fileds
,
end
));
}
//-------------流量控制-----------------
/**
* @description: 访问控制
* @date: 2023/12/14 14:30
* @param: [key, intervalTime 时间间隔(秒), max 最大访问次数]
* @return: void
**/
public
static
boolean
rateLimit
(
String
key
,
int
intervalTime
,
int
max
)
{
DateTime
now
=
DateUtil
.
date
();
DateTime
startTime
=
DateUtil
.
offsetSecond
(
now
,
intervalTime
*
-
1
);
delZset
(
key
,
0
,
startTime
.
getTime
());
Long
count
=
countZset
(
key
,
startTime
.
getTime
(),
now
.
getTime
());
if
(
count
==
null
||
count
<=
max
)
{
return
addZset
(
key
,
now
.
getTime
(),
now
.
getTime
());
}
else
{
return
false
;
}
}
}
src/main/resources/application-dev.yml
0 → 100644
View file @
70128765
spring
:
config
:
activate
:
on-profile
:
dev
#spring 默认数据库连接池
datasource
:
type
:
com.zaxxer.hikari.HikariDataSource
driverClassName
:
com.mysql.cj.jdbc.Driver
url
:
jdbc:mysql://rm-2ze10ohzb1898j5qdfo.mysql.rds.aliyuncs.com:3306/liyeyun?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
username
:
liyeyun
password
:
CF**ldcn
hikari
:
maximum-pool-size
:
10
minimum-idle
:
5
connection-timeout
:
10000
redis
:
host
:
r-2zekq6swp5wr808a3lpd.redis.rds.aliyuncs.com
port
:
6379
password
:
techbook4redis#&20190909
timeout
:
20000
database
:
2
lettuce
:
pool
:
# 连接池中最大连接数,负数表示没有限制
max-active
:
12
# 连接池中的最大空闲连接
max-idle
:
8
# 连接池中的最小空闲连接
min-idle
:
0
# 最大阻塞等待时间,负数表示没有限制
max-wait
:
5000
mybatis-plus
:
configuration
:
log-impl
:
org.apache.ibatis.logging.stdout.StdOutImpl
# 打印日志
knife4j
:
# 开启增强配置
enable
:
true
logging
:
level
:
com.postcard.service
:
debug
root
:
info
src/main/resources/application-prod.yml
0 → 100644
View file @
70128765
spring
:
config
:
activate
:
on-profile
:
pro
#spring 默认数据库连接池
datasource
:
type
:
com.zaxxer.hikari.HikariDataSource
url
:
jdbc:mysql://1.92.66.73:3306/liyeyun?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username
:
liyeyun
password
:
CF**ldcn
driver-class-name
:
com.mysql.cj.jdbc.Driver
hikari
:
maximum-pool-size
:
10
minimum-idle
:
5
connection-timeout
:
10000
redis
:
host
:
r-2zekq6swp5wr808a3lpd.redis.rds.aliyuncs.com
port
:
6379
password
:
techbook4redis#&20190909
timeout
:
3000
database
:
4
lettuce
:
pool
:
max-active
:
12
max-idle
:
8
min-idle
:
0
max-wait
:
5000
mybatis-plus
:
configuration
:
log-impl
:
org.apache.ibatis.logging.slf4j.Slf4jImpl
# 打印日志
knife4j
:
# 开启增强配置
enable
:
false
logging
:
level
:
com.postcard.service
:
debug
root
:
info
src/main/resources/application-test.yml
0 → 100644
View file @
70128765
spring
:
config
:
activate
:
on-profile
:
test
#spring 默认数据库连接池
datasource
:
type
:
com.zaxxer.hikari.HikariDataSource
url
:
jdbc:mysql://rm-2ze10ohzb1898j5qdfo.mysql.rds.aliyuncs.com:3306/liyeyun?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username
:
liyeyun
password
:
CF**ldcn
driver-class-name
:
com.mysql.cj.jdbc.Driver
hikari
:
maximum-pool-size
:
10
minimum-idle
:
5
connection-timeout
:
10000
redis
:
host
:
r-2zekq6swp5wr808a3lpd.redis.rds.aliyuncs.com
port
:
6379
password
:
techbook4redis#&20190909
timeout
:
3000
database
:
3
lettuce
:
pool
:
max-active
:
12
max-idle
:
8
min-idle
:
0
max-wait
:
5000
mybatis-plus
:
configuration
:
log-impl
:
org.apache.ibatis.logging.slf4j.Slf4jImpl
# 打印日志
knife4j
:
# 开启增强配置
enable
:
true
business
:
url
:
thread
:
http://test.user.liyeyun.com/lyy/api/threadInfo/v1.0/save
logging
:
level
:
com.postcard.service
:
debug
root
:
info
src/main/resources/application.yml
0 → 100644
View file @
70128765
spring
:
profiles
:
active
:
dev
application
:
name
:
postcard-service
main
:
#允许定义相同的bean对象 去覆盖原有的
allow-bean-definition-overriding
:
true
jackson
:
date-format
:
yyyy-MM-dd HH:mm:ss
time-zone
:
GMT+8
server
:
port
:
8090
servlet
:
# 应用的访问路径
context-path
:
/postcard
tomcat
:
uri-encoding
:
UTF-8
mybatis-plus
:
configuration
:
map-underscore-to-camel-case
:
true
cache-enabled
:
true
call-setters-on-nulls
:
true
return-instance-for-empty-row
:
true
jdbc-type-for-null
:
varchar
mapper-locations
:
classpath:/mapper/**/*.xml
global-config
:
db-config
:
#注解自增
id-type
:
ASSIGN_ID
#数据库大写下划线转换
capital-mode
:
true
#表名是否使用驼峰转下划线命名
table-underline
:
true
#逻辑已删除值
logic-delete-value
:
0
logic-not-delete-value
:
1
src/main/resources/logback-spring.xml
0 → 100644
View file @
70128765
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property
name=
"projectName"
value=
"postcard-service"
/>
<springProperty
scope=
"context"
name=
"moduleName"
source=
"spring.application.name"
defaultValue=
"postcard-service"
/>
<springProperty
scope=
"context"
name=
"logNum"
source=
"log.num"
defaultValue=
"01"
/>
<springProfile
name=
"test"
>
<property
name=
"logPathPrefix"
value=
"/app/logs"
/>
</springProfile>
<springProfile
name=
"pro"
>
<property
name=
"logPathPrefix"
value=
"/app/logs"
/>
</springProfile>
<property
name=
"logger.path"
value=
"${logPathPrefix}/${projectName}"
/>
<property
name=
"maxHistory"
value=
"30"
/>
<property
name=
"maxFileSize"
value=
"50MB"
/>
<property
name=
"CONSOLE_LOG_PATTERN"
value=
"${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"
/>
<conversionRule
conversionWord=
"clr"
converterClass=
"org.springframework.boot.logging.logback.ColorConverter"
/>
<conversionRule
conversionWord=
"wex"
converterClass=
"org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"
/>
<conversionRule
conversionWord=
"wEx"
converterClass=
"org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"
/>
<appender
name=
"CONSOLE"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<encoder>
<pattern>
${CONSOLE_LOG_PATTERN}
</pattern>
<charset>
utf8
</charset>
</encoder>
</appender>
<appender
name=
"DEBUG_FILE"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${logger.path}/debug/${moduleName}-${logNum}-debug.log
</file>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${logger.path}/debug/${moduleName}-${logNum}-debug-%d{yyyy-MM-dd}.%i.zip
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
${maxFileSize}
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>
${maxHistory}
</maxHistory>
</rollingPolicy>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
debug
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</appender>
<appender
name=
"INFO_FILE"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${logger.path}/info/${moduleName}-${logNum}-info.log
</file>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${logger.path}/info/${moduleName}-${logNum}-info-%d{yyyy-MM-dd}.%i.zip
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
${maxFileSize}
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>
${maxHistory}
</maxHistory>
</rollingPolicy>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
info
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</appender>
<appender
name=
"WARN_FILE"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${logger.path}/warn/${moduleName}-${logNum}-warn.log
</file>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${logger.path}/warn/${moduleName}-${logNum}-warn-%d{yyyy-MM-dd}.%i.zip
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
${maxFileSize}
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>
${maxHistory}
</maxHistory>
</rollingPolicy>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
warn
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</appender>
<appender
name=
"ERROR_FILE"
class=
"ch.qos.logback.core.rolling.RollingFileAppender"
>
<file>
${logger.path}/error/${moduleName}-${logNum}-error.log
</file>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<rollingPolicy
class=
"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
>
<fileNamePattern>
${logger.path}/error/${moduleName}-${logNum}-error-%d{yyyy-MM-dd}.%i.zip
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class=
"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"
>
<maxFileSize>
${maxFileSize}
</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>
${maxHistory}
</maxHistory>
</rollingPolicy>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<level>
ERROR
</level>
<onMatch>
ACCEPT
</onMatch>
<onMismatch>
DENY
</onMismatch>
</filter>
</appender>
<!--dev环境 info界别 输出到控制台-->
<springProfile
name=
"dev"
>
<root
level=
"info"
>
<appender-ref
ref=
"CONSOLE"
/>
</root>
</springProfile>
<!--test环境 info界别 输出到三个日志文件中-->
<springProfile
name=
"test"
>
<root
level=
"info"
>
<appender-ref
ref=
"INFO_FILE"
/>
<appender-ref
ref=
"DEBUG_FILE"
/>
<appender-ref
ref=
"ERROR_FILE"
/>
</root>
</springProfile>
<springProfile
name=
"pro"
>
<root
level=
"info"
>
<appender-ref
ref=
"INFO_FILE"
/>
<appender-ref
ref=
"DEBUG_FILE"
/>
<appender-ref
ref=
"ERROR_FILE"
/>
</root>
</springProfile>
</configuration>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment