├── .gitignore
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── pkh
│ │ ├── OpenApiApplication.java
│ │ ├── ServletInitializer.java
│ │ ├── annotation
│ │ ├── DS.java
│ │ ├── PkhLog.java
│ │ ├── Replace.java
│ │ ├── aspect
│ │ │ ├── DataSourceAspect.java
│ │ │ ├── PkhLogAspect.java
│ │ │ └── ReplaceAspect.java
│ │ └── parser
│ │ │ └── ReplaceParser.java
│ │ ├── bean
│ │ ├── param
│ │ │ ├── AdminListParam.java
│ │ │ ├── BaseListParam.java
│ │ │ ├── CustomerListParam.java
│ │ │ ├── OrderCreateParam.java
│ │ │ ├── PikaDayEditParam.java
│ │ │ ├── RoleListParam.java
│ │ │ ├── UserListParam.java
│ │ │ └── UserParam.java
│ │ ├── response
│ │ │ └── PikaResponse.java
│ │ └── vo
│ │ │ └── UserVo.java
│ │ ├── commons
│ │ ├── datasource
│ │ │ ├── DynamicDataSource.java
│ │ │ └── DynamicDataSourceContextHolder.java
│ │ ├── jwt
│ │ │ ├── JWTCredentialMatcher.java
│ │ │ └── JWTToken.java
│ │ └── util
│ │ │ └── RSAUtil.java
│ │ ├── configuraton
│ │ ├── BiliLikeListener.java
│ │ ├── OrderListener.java
│ │ ├── PikaConfiguration.java
│ │ ├── RedisConfig.java
│ │ ├── RedissonConfig.java
│ │ ├── WebMvcConfig.java
│ │ ├── datasource
│ │ │ └── DataSourceConfiguration.java
│ │ └── shiro
│ │ │ ├── ShiroConfig.java
│ │ │ └── UserRealm.java
│ │ ├── controller
│ │ ├── AdminController.java
│ │ ├── ArticleController.java
│ │ ├── CustomerController.java
│ │ ├── LoginController.java
│ │ ├── OrderController.java
│ │ ├── PikaDayController.java
│ │ ├── RoleController.java
│ │ ├── UserController.java
│ │ └── VipController.java
│ │ ├── dao
│ │ ├── mapper
│ │ │ ├── AdminUserMapper.java
│ │ │ ├── MyBatisBaseDao.java
│ │ │ ├── RoleMapper.java
│ │ │ ├── UserMapper.java
│ │ │ └── UserRoleMapper.java
│ │ ├── po
│ │ │ ├── Customer.java
│ │ │ ├── Rights.java
│ │ │ ├── Role.java
│ │ │ ├── User.java
│ │ │ ├── UserRole.java
│ │ │ ├── Vip.java
│ │ │ └── admindb
│ │ │ │ └── AdminUser.java
│ │ └── prop
│ │ │ └── PikaDayBean.java
│ │ ├── enums
│ │ ├── RoleEnum.java
│ │ └── SexEnum.java
│ │ ├── filter
│ │ ├── JWTFilter.java
│ │ └── LogFilter.java
│ │ ├── handler
│ │ └── GlobalExceptionHandler.java
│ │ ├── interceptor
│ │ └── LogInterceptor.java
│ │ ├── learn
│ │ ├── pibatis
│ │ │ ├── MapperImpl.java
│ │ │ ├── MapperProxyFactory.java
│ │ │ ├── MyApplication.java
│ │ │ ├── Select.java
│ │ │ └── UserMapper.java
│ │ └── proxy
│ │ │ ├── Coder.java
│ │ │ └── Programmer.java
│ │ ├── service
│ │ ├── AdminService.java
│ │ ├── ArticleService.java
│ │ ├── CustomerService.java
│ │ ├── LoginService.java
│ │ ├── RoleService.java
│ │ ├── StockService.java
│ │ ├── UserService.java
│ │ ├── VipService.java
│ │ └── impl
│ │ │ ├── AdminServiceImpl.java
│ │ │ ├── ArticleServiceImpl.java
│ │ │ ├── LoginServiceImpl.java
│ │ │ ├── RoleServiceImpl.java
│ │ │ ├── StockServiceImpl.java
│ │ │ ├── UserServiceImpl.java
│ │ │ └── VipServiceImpl.java
│ │ └── util
│ │ ├── HttpUtil.java
│ │ ├── JWTUtil.java
│ │ ├── RSAUtil.java
│ │ └── RedisUtil.java
└── resources
│ ├── application.properties
│ ├── logback.xml
│ ├── mapper
│ ├── RoleMapper.xml
│ ├── UserMapper.xml
│ ├── UserRoleMapper.xml
│ └── admindb
│ │ └── AdminUserMapper.xml
│ └── mybatis-configuration.xml
└── test
└── java
└── com
└── pkh
├── OpenApiApplicationTests.java
├── annotation
└── parser
│ └── ReplaceTest.java
├── configuraton
└── PikaDayConfigurationTest.java
├── dao
└── mapper
│ ├── RoleMapperTest.java
│ └── UserMapperTest.java
├── service
└── impl
│ └── UserServiceImplTest.java
└── util
└── HttpUtilTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 | src/main/java/com/pkh/learn/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 |
17 | ### IntelliJ IDEA ###
18 | .idea
19 | *.iws
20 | *.iml
21 | *.ipr
22 |
23 | ### NetBeans ###
24 | /nbproject/private/
25 | /nbbuild/
26 | /dist/
27 | /nbdist/
28 | /.nb-gradle/
29 | build/
30 | !**/src/main/**/build/
31 | !**/src/test/**/build/
32 |
33 | ### VS Code ###
34 | .vscode/
35 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.7.7
9 |
10 |
11 | com.pkh
12 | open-api
13 | 0.0.1-SNAPSHOT
14 | war
15 | open-api
16 | open-api
17 |
18 | 8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-web
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-tomcat
30 | provided
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-test
35 | test
36 |
37 |
38 |
39 |
40 | com.alibaba
41 | fastjson
42 | 1.2.83
43 |
44 |
45 |
46 |
47 | ch.qos.logback
48 | logback-access
49 | 1.1.7
50 |
51 |
52 | ch.qos.logback
53 | logback-classic
54 | 1.1.7
55 |
56 |
57 | ch.qos.logback
58 | logback-core
59 | 1.1.7
60 |
61 |
62 | com.squareup.okhttp3
63 | okhttp
64 | 3.10.0
65 |
66 |
67 |
68 | org.projectlombok
69 | lombok
70 | 1.16.18
71 |
72 |
73 |
74 | mysql
75 | mysql-connector-java
76 | 8.0.13
77 |
78 |
79 |
80 | org.mybatis.spring.boot
81 | mybatis-spring-boot-starter
82 | 1.3.1
83 |
84 |
85 |
86 | log4j
87 | log4j
88 | 1.2.17
89 |
90 |
91 |
92 | org.aspectj
93 | aspectjrt
94 |
95 |
96 |
97 | org.aspectj
98 | aspectjweaver
99 |
100 |
101 |
102 | org.apache.httpcomponents.client5
103 | httpclient5
104 | 5.1.4
105 |
106 |
107 |
108 |
109 | org.springframework.boot
110 | spring-boot-starter-data-redis
111 |
112 |
113 |
114 |
115 | org.redisson
116 | redisson-spring-boot-starter
117 | 3.23.5
118 |
119 |
120 |
121 |
122 | org.apache.shiro
123 | shiro-spring
124 | 1.10.1
125 |
126 |
127 |
128 |
129 | com.auth0
130 | java-jwt
131 | 3.10.3
132 |
133 |
134 |
135 |
136 |
137 |
138 | org.springframework.boot
139 | spring-boot-maven-plugin
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/OpenApiApplication.java:
--------------------------------------------------------------------------------
1 | package com.pkh;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.ComponentScan;
7 | import org.springframework.context.annotation.EnableAspectJAutoProxy;
8 |
9 | @SpringBootApplication
10 | @ComponentScan("com.pkh.*")
11 | @MapperScan("com.pkh.dao.mapper")
12 | @EnableAspectJAutoProxy(proxyTargetClass = true)
13 | public class OpenApiApplication {
14 |
15 | public static void main(String[] args) {
16 | SpringApplication.run(OpenApiApplication.class, args);
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/ServletInitializer.java:
--------------------------------------------------------------------------------
1 | package com.pkh;
2 |
3 | import org.springframework.boot.builder.SpringApplicationBuilder;
4 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
5 |
6 | public class ServletInitializer extends SpringBootServletInitializer {
7 |
8 | @Override
9 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
10 | return application.sources(OpenApiApplication.class);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/DS.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Target({ElementType.METHOD,ElementType.TYPE})
9 | @Retention(RetentionPolicy.RUNTIME)
10 | public @interface DS {
11 | String value() default "";
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/PkhLog.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.METHOD)
10 | public @interface PkhLog {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/Replace.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target({ElementType.FIELD})
10 | public @interface Replace {
11 |
12 | String source() default "";
13 |
14 | String target() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/aspect/DataSourceAspect.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation.aspect;
2 |
3 | import com.pkh.annotation.DS;
4 | import com.pkh.commons.datasource.DynamicDataSourceContextHolder;
5 | import org.aspectj.lang.JoinPoint;
6 | import org.aspectj.lang.annotation.After;
7 | import org.aspectj.lang.annotation.Aspect;
8 | import org.aspectj.lang.annotation.Before;
9 | import org.aspectj.lang.annotation.Pointcut;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.core.annotation.Order;
13 | import org.springframework.stereotype.Component;
14 |
15 | @Aspect
16 | @Order(-10)
17 | @Component
18 | public class DataSourceAspect {
19 | /**
20 | * 日志打印工具
21 | */
22 | private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
23 |
24 | @Pointcut("@annotation(com.pkh.annotation.DS)")
25 | public void dataSourceAspect(){}
26 |
27 | @Before("dataSourceAspect() && @annotation(ds)")
28 | public void changeDataSource(JoinPoint joinPoint, DS ds) {
29 | String dsId = ds.value();
30 | if (!DynamicDataSourceContextHolder.containsDataSource(dsId)) {
31 | DynamicDataSourceContextHolder.setDataSourceType("pkhdb");
32 | logger.warn("datasource not exist, dsId:{}", dsId);
33 | } else {
34 | logger.info("change dataSource to:" + ds.value() + ". method:" + joinPoint.getSignature());
35 | DynamicDataSourceContextHolder.setDataSourceType(ds.value());
36 | }
37 | }
38 |
39 | @After("@annotation(ds)")
40 | public void restoreDataSource(JoinPoint point, DS ds) {
41 | DynamicDataSourceContextHolder.clearDataSourceType();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/aspect/PkhLogAspect.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation.aspect;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.aspectj.lang.JoinPoint;
6 | import org.aspectj.lang.annotation.After;
7 | import org.aspectj.lang.annotation.Aspect;
8 | import org.aspectj.lang.annotation.Before;
9 | import org.aspectj.lang.annotation.Pointcut;
10 | import org.aspectj.lang.reflect.MethodSignature;
11 | import org.springframework.stereotype.Component;
12 | import org.springframework.web.context.request.RequestContextHolder;
13 | import org.springframework.web.context.request.ServletRequestAttributes;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.text.SimpleDateFormat;
17 | import java.util.Date;
18 |
19 | @Component
20 | @Aspect
21 | @Slf4j
22 | public class PkhLogAspect {
23 |
24 | @Pointcut("@annotation(com.pkh.annotation.PkhLog)")
25 | public void pkhLogAspect(){}
26 |
27 | @Before("pkhLogAspect()")
28 | public void beforePkhLog(JoinPoint joinPoint) {
29 | ServletRequestAttributes requestAttributes =
30 | (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
31 | HttpServletRequest request = requestAttributes.getRequest();
32 |
33 | String methodName = joinPoint.getSignature().getName();
34 | log.info("========================================= Method " + methodName + "() begin=========================================");
35 | // 执行时间
36 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
37 | Date d= new Date();
38 | String time = sdf.format(d);
39 | log.info("Time : " + time);
40 | // 打印请求 URL
41 | log.info("URL : " + request.getRequestURL());
42 | // 打印 请求方法
43 | log.info("HTTP Method : " + request.getMethod());
44 | // 打印controller 的全路径以及执行方法
45 | log.info("Class Method : " + joinPoint.getSignature().getDeclaringTypeName() + "." + methodName);
46 | // 打印请求的 IP
47 | log.info("IP : " + request.getRemoteHost());
48 | // 打印请求入参
49 | log.info("Request Args : " + JSON.toJSONString(joinPoint.getArgs()));
50 | log.info("Executing Controller...");
51 | }
52 |
53 | @After("pkhLogAspect()")
54 | public void afterPkhLog(JoinPoint joinPoint) {
55 | String methodName = joinPoint.getSignature().getName();
56 | log.info("========================================= Method " + methodName + "() End =========================================");
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/aspect/ReplaceAspect.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation.aspect;
2 |
3 | import com.pkh.annotation.Replace;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.aspectj.lang.JoinPoint;
6 | import org.aspectj.lang.annotation.Around;
7 | import org.aspectj.lang.annotation.Aspect;
8 | import org.aspectj.lang.annotation.Pointcut;
9 | import org.springframework.core.annotation.Order;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.lang.reflect.Field;
13 |
14 | @Aspect
15 | @Order(1)
16 | @Component
17 | @Slf4j
18 | public class ReplaceAspect {
19 | /**
20 | * 定义切点,@Replace为切点
21 | */
22 | @Pointcut("@within(com.pkh.annotation.Replace)")
23 | public void replaceAspect() {}
24 |
25 | /**
26 | * 切入点之前执行
27 | */
28 | @Around("replaceAspect()")
29 | public void parseReplace(JoinPoint joinPoint) {
30 | // System.out.println("parseReplace before");
31 | log.info("-----------around--------------");
32 | Object o = joinPoint.getTarget();
33 | Class> clazz = o.getClass();
34 | try {
35 | Field[] fields = clazz.getDeclaredFields();
36 | for (Field field : fields) {
37 | if (field.isAnnotationPresent(Replace.class)) {
38 | field.setAccessible(true);
39 | // 获取当前field设置的注解
40 | Replace trimSpace = field.getAnnotation(Replace.class);
41 | String source = trimSpace.source();
42 | String target = trimSpace.target();
43 |
44 | // 获取当前field的值进行处理 " kangkang@pika.com "
45 | String s = String.valueOf(field.get(o));
46 | String replace = s.replace(target, source);
47 | field.set(o,replace);
48 | }
49 | }
50 | } catch (Exception e) {
51 | e.printStackTrace();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/annotation/parser/ReplaceParser.java:
--------------------------------------------------------------------------------
1 | package com.pkh.annotation.parser;
2 |
3 | import com.pkh.annotation.Replace;
4 |
5 | import java.lang.reflect.Field;
6 |
7 | public class ReplaceParser {
8 |
9 | /**
10 | * 解析Replace注解
11 | *
12 | * @param o 解析对象
13 | */
14 | public static Object parse(Object o) {
15 | Class> mClass = null;
16 | Object o1 = o;
17 | try {
18 | mClass = o.getClass();
19 | Field[] fields = mClass.getDeclaredFields();
20 | for (Field field : fields) {
21 | if (field.isAnnotationPresent(Replace.class)) {
22 | field.setAccessible(true);
23 | // 获取当前field设置的注解
24 | Replace trimSpace = field.getAnnotation(Replace.class);
25 | String source = trimSpace.source();
26 | String target = trimSpace.target();
27 |
28 | // 获取当前field的值进行处理 " kangkang@pika.com "
29 | String s = String.valueOf(field.get(o1));
30 | String replace = s.replace(target, source);
31 | field.set(o1,replace);
32 | }
33 | }
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | }
37 | return o1;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/AdminListParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | public class AdminListParam extends BaseListParam {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/BaseListParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.List;
6 |
7 | @Data
8 | public class BaseListParam {
9 | // 页码
10 | private Integer pageIndex;
11 |
12 | // 页面大小
13 | private Integer pageSize;
14 |
15 | // 排序字段
16 | private String sortBy;
17 |
18 | // 顺序: 正序 倒序
19 | private String sortOrder;
20 |
21 | // 分页计算offset
22 | private Integer offset;
23 |
24 | // 语言类型
25 | private List langTypes;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/CustomerListParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | public class CustomerListParam extends BaseListParam{
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/OrderCreateParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | public class OrderCreateParam {
4 | private String productId;
5 |
6 | private Integer count;
7 |
8 | public String getProductId() {
9 | return productId;
10 | }
11 |
12 | public void setProductId(String productId) {
13 | this.productId = productId;
14 | }
15 |
16 | public Integer getCount() {
17 | return count;
18 | }
19 |
20 | public void setCount(Integer count) {
21 | this.count = count;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/PikaDayEditParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | public class PikaDayEditParam {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/RoleListParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.List;
6 |
7 | @Data
8 | public class RoleListParam extends BaseListParam {
9 | /**
10 | * 角色NO
11 | */
12 | private String roleNo;
13 |
14 | /**
15 | * 角色名称
16 | */
17 | private String name;
18 |
19 | /**
20 | * 状态 0:初始 1:激活 2:失效
21 | */
22 | private String status;
23 |
24 | /**
25 | * 类型
26 | */
27 | private String type;
28 |
29 | private List createTime;
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/UserListParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | import com.pkh.annotation.Replace;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @Data
9 | public class UserListParam extends BaseListParam{
10 |
11 | @Replace(source = "_", target = " ")
12 | private String userId;
13 |
14 | private String sex;
15 |
16 | private List createTime;
17 |
18 | public UserListParam() {
19 | }
20 |
21 | public UserListParam(String userId) {
22 | this.userId = userId;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/param/UserParam.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.param;
2 |
3 | import com.pkh.annotation.Replace;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | @Data
9 | public class UserParam extends BaseListParam{
10 |
11 | private String userId;
12 |
13 | private String password;
14 |
15 | public UserParam(String userId, String password) {
16 | this.userId = userId;
17 | this.password = password;
18 | }
19 |
20 | public String getUserId() {
21 | return userId;
22 | }
23 |
24 | public void setUserId(String userId) {
25 | this.userId = userId;
26 | }
27 |
28 | public String getPassword() {
29 | return password;
30 | }
31 |
32 | public void setPassword(String password) {
33 | this.password = password;
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/response/PikaResponse.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.response;
2 |
3 | import java.io.Serializable;
4 |
5 | public class PikaResponse implements Serializable {
6 | private static final long serialVersionUID = 1L;
7 | private T data;
8 | private String message;
9 | private String code;
10 |
11 | public PikaResponse() {
12 | this.code = "0";
13 | }
14 |
15 | public PikaResponse(T data) {
16 | if (data == null) {
17 | this.code = "0";
18 | } else {
19 | this.code = "0";
20 | this.data = data;
21 | }
22 | this.message = "success";
23 | }
24 |
25 | public PikaResponse(String code, String message) {
26 | this.code = code;
27 | this.message = message;
28 | }
29 |
30 | public T getData() {
31 | return data;
32 | }
33 |
34 | public void setData(T data) {
35 | this.data = data;
36 | }
37 |
38 | public String getMessage() {
39 | return message;
40 | }
41 |
42 | public void setMessage(String message) {
43 | this.message = message;
44 | }
45 |
46 | public String getCode() {
47 | return code;
48 | }
49 |
50 | public void setCode(String code) {
51 | this.code = code;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/bean/vo/UserVo.java:
--------------------------------------------------------------------------------
1 | package com.pkh.bean.vo;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | @Data
8 | public class UserVo {
9 | private Long id;
10 |
11 | private String userId;
12 |
13 | private String userName;
14 |
15 | private String sex;
16 |
17 | private String type;
18 |
19 | private String phone;
20 |
21 | private String mobie;
22 |
23 | private String email;
24 |
25 | private String weChat;
26 |
27 | private String telegram;
28 |
29 | private String address;
30 |
31 | private String zipCode;
32 |
33 | private String createTime;
34 |
35 | private String updateTime;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/commons/datasource/DynamicDataSource.java:
--------------------------------------------------------------------------------
1 | package com.pkh.commons.datasource;
2 |
3 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
4 |
5 | public class DynamicDataSource extends AbstractRoutingDataSource {
6 | /**
7 | * 取得一个字符串
8 | */
9 | @Override
10 | protected Object determineCurrentLookupKey() {
11 | return DynamicDataSourceContextHolder.getDataSourceType();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/commons/datasource/DynamicDataSourceContextHolder.java:
--------------------------------------------------------------------------------
1 | package com.pkh.commons.datasource;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class DynamicDataSourceContextHolder {
7 | /**
8 | * 使用ThreadLocal维护变量
9 | */
10 | private static final ThreadLocal contextHolder = new ThreadLocal<>();
11 |
12 | /**
13 | * 管理所有的数据源id
14 | */
15 | public static List dataSourceIds = new ArrayList<>();
16 |
17 | /**
18 | * 设置当前数据源类型
19 | */
20 | public static void setDataSourceType(String dataSourceType) {
21 | contextHolder.set(dataSourceType);
22 | }
23 |
24 | public static String getDataSourceType() {
25 | return contextHolder.get();
26 | }
27 |
28 | public static void clearDataSourceType() {
29 | contextHolder.remove();
30 | }
31 |
32 | /**
33 | * 判断指定DataSource当前是否存在
34 | *
35 | * @param dataSourceId 数据源Id
36 | * @return
37 | */
38 | public static boolean containsDataSource(String dataSourceId) {
39 | return dataSourceIds.contains(dataSourceId);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/commons/jwt/JWTCredentialMatcher.java:
--------------------------------------------------------------------------------
1 | package com.pkh.commons.jwt;
2 |
3 | import com.auth0.jwt.exceptions.TokenExpiredException;
4 | import com.pkh.dao.po.User;
5 | import org.apache.shiro.authc.AuthenticationInfo;
6 | import org.apache.shiro.authc.AuthenticationToken;
7 | import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
8 |
9 | import java.security.MessageDigest;
10 | import java.security.NoSuchAlgorithmException;
11 |
12 | public class JWTCredentialMatcher extends HashedCredentialsMatcher {
13 |
14 | private static final String HEXITS = "0123456789abcdef";
15 | @Override
16 | public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo info) {
17 | String token = String.valueOf(authenticationToken.getCredentials());
18 | User user =(User) info.getPrincipals().getPrimaryPrincipal();
19 | try {
20 | // return JWTUtil.verify(token, user.getUserName(), user.getPassword());
21 | return true;
22 | } catch (TokenExpiredException e) {
23 |
24 | throw new RuntimeException("token过期");
25 | }
26 | }
27 | /**
28 | * 检查用户输入的密码,加密后是否和数据库存储的密码一致
29 | * 1. 截取随机密码
30 | * 2. 根据随机密码生成sha1摘要
31 | * 3. 根据sha1摘要和模式串生成乱码密钥
32 | * 4. 对比新生成的乱码密钥和数据库中存储的乱码密钥是否一致
33 | *
34 | * sha1$raYr1$da39a3ee5e6b4b0d3255bfef95601890afd80709
35 | *
36 | * @param password 密码
37 | * @param encryptPassword 存储的加密后的密码
38 | * @return
39 | * @throws Exception
40 | */
41 | public static boolean checkPassword(String password, String encryptPassword) throws Exception {
42 | String[] pwdList = encryptPassword.split("\\$");
43 | if (pwdList.length == 3) {
44 | if (pwdList[0].equals("sha1")) {
45 | MessageDigest sha1 = createSha1(pwdList[1] + password);
46 | String pwdHash = getPwdHash(sha1, HEXITS);
47 | if (pwdList[2].equals(pwdHash)) {
48 | return true;
49 | }
50 | }
51 | }
52 | return false;
53 | }
54 |
55 |
56 | /**
57 | * 对明文密码进行加密
58 | * 1. 密码+随机数组成随机字符串
59 | * 2. 对随机字符串生成sha1摘要
60 | * 3. 根据sha1摘要和模式串生成乱码密钥
61 | *
62 | * 加密后密码样例:sha1$raYr1$da39a3ee5e6b4b0d3255bfef95601890afd80709
63 | *
64 | * @param password 明文密码
65 | * @return
66 | * @throws Exception
67 | */
68 | // public static String encryptPassword(String password) throws Exception {
69 | // String random = SysTool.getRandomString(5);
70 | // String value = random + password;
71 | // MessageDigest sha1 = createSha1(value);
72 | // String pwdHash = getPwdHash(sha1, HEXITS);
73 | // return "sha1$" + random + "$" + pwdHash;
74 | // }
75 |
76 | /**
77 | * 根据明文密码生成sha1摘要
78 | *
79 | * @param value 明文密码
80 | * @return
81 | * @throws NoSuchAlgorithmException
82 | */
83 | private static MessageDigest createSha1(String value) throws NoSuchAlgorithmException {
84 | MessageDigest sha1 = MessageDigest.getInstance("sha1");
85 | sha1.reset();
86 | sha1.update(value.getBytes());
87 | return sha1;
88 | }
89 |
90 | /**
91 | * 根据sha1摘要 和 模式串生成密码
92 | *
93 | * @param sha1
94 | * @param hexits
95 | * @return
96 | */
97 | private static String getPwdHash(MessageDigest sha1, String hexits) {
98 | byte[] pwd = sha1.digest();
99 | StringBuilder sb = new StringBuilder();
100 | for (byte b : pwd) {
101 | sb.append(hexits.charAt((b >>> 4) & 0xf));
102 | sb.append(hexits.charAt(b & 0xf));
103 | }
104 | return sb.toString();
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/commons/jwt/JWTToken.java:
--------------------------------------------------------------------------------
1 | package com.pkh.commons.jwt;
2 |
3 | import org.apache.shiro.authc.AuthenticationToken;
4 |
5 | public class JWTToken implements AuthenticationToken {
6 | private String token;
7 |
8 | public JWTToken(String token) {
9 | this.token = token;
10 | }
11 |
12 | public String getToken() {
13 | return token;
14 | }
15 |
16 | @Override
17 | public Object getPrincipal() {
18 | return token;
19 | }
20 |
21 | @Override
22 | public Object getCredentials() {
23 | return token;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/commons/util/RSAUtil.java:
--------------------------------------------------------------------------------
1 | package com.pkh.commons.util;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import org.apache.tomcat.util.codec.binary.Base64;
5 |
6 | import javax.crypto.Cipher;
7 | import java.security.KeyFactory;
8 | import java.security.interfaces.RSAPrivateKey;
9 | import java.security.interfaces.RSAPublicKey;
10 | import java.security.spec.PKCS8EncodedKeySpec;
11 | import java.security.spec.X509EncodedKeySpec;
12 |
13 | public class RSAUtil {
14 | private static JSONObject keyMap=new JSONObject();
15 |
16 | static {
17 | keyMap.put("ANTPOOL_PUBLIC_KEY","MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+89V7vpOj1rG6bTAKYM56qmFLwNCBVDJ3MltVVtxVUUByqc5b6u909MmmrLBqS//PWC6zc3wZzU1+ayh8xbUAEZuA3EjlPHIaFIVIz04RaW10+1xnby/RQE23tDqsv9a2jv/axjE/27b62nzvCWeItu1kNQ3MGdcuqKjke+LKhQ7nWPRCOd/ffVqSuRvG0YfUEkOz/6UpsPr6vrI331hWRB4DlYy8qFUmDsyvvExe4NjZWblXCqkEXRRAhi2SQRCl3teGuIHtDUxCskRIDiaMD+Qt2Yp+Vvbz6hUiqIWSIH1BoHJer/JOq2/O6X3cmuppU4AdVNgy8Bq236iXvrMQIDAQAB");
18 | }
19 |
20 | private static String getPublicKey(String keyName) {
21 | return keyMap.getString(keyName);
22 | }
23 |
24 | /**
25 | * RSA公钥加密
26 | *
27 | * @param str 加密字符串
28 | * @param publicKeyName 公钥名称
29 | * @return 密文
30 | * @throws Exception 加密过程中的异常信息
31 | */
32 | public static String encrypt(String str, String publicKeyName) throws Exception {
33 | String publicKey= getPublicKey(publicKeyName);
34 | //base64编码的公钥
35 | byte[] decoded = Base64.decodeBase64(publicKey);
36 | RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
37 |
38 | //RSA加密
39 | Cipher cipher = Cipher.getInstance("RSA");
40 | cipher.init(Cipher.ENCRYPT_MODE, pubKey);
41 | byte[] codeByte=cipher.doFinal(str.getBytes("UTF-8"));
42 | String outStr = Base64.encodeBase64String(codeByte);
43 | return outStr;
44 | }
45 |
46 | /**
47 | * RSA私钥解密
48 | *
49 | * @param str 加密字符串
50 | * @param privateKeyName 私钥名称
51 | * @return 铭文
52 | * @throws Exception 解密过程中的异常信息
53 | */
54 | public static String decrypt(String str, String privateKeyName) throws Exception {
55 | //64位解码加密后的字符串
56 | byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
57 | //base64编码的私钥
58 | byte[] decoded = Base64.decodeBase64(privateKeyName);
59 | RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
60 | //RSA解密
61 | Cipher cipher = Cipher.getInstance("RSA");
62 | cipher.init(Cipher.DECRYPT_MODE, priKey);
63 | String outStr = new String(cipher.doFinal(inputByte));
64 | return outStr;
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/BiliLikeListener.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import org.springframework.data.redis.connection.Message;
4 | import org.springframework.data.redis.connection.MessageListener;
5 |
6 | public class BiliLikeListener implements MessageListener {
7 | @Override
8 | public void onMessage(Message message, byte[] pattern) {
9 | String msg = message.toString();
10 | String channel = new String(message.getChannel());
11 | System.out.println("channel: " + channel + " msg: " + msg);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/OrderListener.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import org.springframework.data.redis.connection.Message;
4 | import org.springframework.data.redis.connection.MessageListener;
5 |
6 | public class OrderListener implements MessageListener {
7 | @Override
8 | public void onMessage(Message message, byte[] pattern) {
9 | String msg = message.toString();
10 | String channel = new String(message.getChannel());
11 | System.out.println("msg: " + msg + "channel: " + channel);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/PikaConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import com.pkh.dao.prop.PikaDayBean;
4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | @EnableAutoConfiguration
11 | public class PikaConfiguration {
12 |
13 | @Bean
14 | @ConfigurationProperties("pikaday")
15 | public PikaDayBean getPikaDayBean() {
16 |
17 | PikaDayBean pikaDayBean = new PikaDayBean();
18 | return pikaDayBean;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Qualifier;
5 | import org.springframework.cache.annotation.CachingConfigurerSupport;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.data.redis.connection.MessageListener;
9 | import org.springframework.data.redis.connection.RedisConnectionFactory;
10 | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
11 | import org.springframework.data.redis.core.RedisTemplate;
12 | import org.springframework.data.redis.listener.ChannelTopic;
13 | import org.springframework.data.redis.listener.RedisMessageListenerContainer;
14 | import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
15 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
16 | import org.springframework.data.redis.serializer.StringRedisSerializer;
17 |
18 | @Configuration
19 | @Slf4j
20 | public class RedisConfig extends CachingConfigurerSupport {
21 |
22 | /**
23 | * @param redisConnectionFactory redis连接工厂
24 | * @return
25 | */
26 | @Bean
27 | public RedisTemplate redisTemplate( RedisConnectionFactory redisConnectionFactory) {
28 | RedisTemplate redisTemplate = new RedisTemplate<>();
29 | // 设置Redis连接工厂
30 | redisTemplate.setConnectionFactory(redisConnectionFactory);
31 |
32 | // 设置key的序列化策略
33 | redisTemplate.setKeySerializer(new StringRedisSerializer());
34 |
35 | // 设置value的序列化策略
36 | redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
37 |
38 | return redisTemplate;
39 | }
40 |
41 | /**
42 | * 配置连接工厂
43 | *
44 | * @return
45 | */
46 | @Bean
47 | public LettuceConnectionFactory lettuceConnectionFactory() {
48 | // 这里您可以自定义配置,或者简单地返回一个新的实例让 Spring Boot 自动填充配置
49 | return new LettuceConnectionFactory();
50 | }
51 |
52 | @Bean
53 | public MessageListenerAdapter biliLikeListenerAdapter() {
54 | return new MessageListenerAdapter(new BiliLikeListener());
55 | }
56 |
57 | @Bean
58 | public MessageListenerAdapter orderListenerAdapter() {
59 | return new MessageListenerAdapter(new OrderListener());
60 | }
61 |
62 | @Bean
63 | public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory,
64 | @Qualifier("biliLikeListenerAdapter") MessageListenerAdapter biliLikeListenerAdapter,
65 | @Qualifier("orderListenerAdapter") MessageListenerAdapter orderListenerAdapter) {
66 | RedisMessageListenerContainer container = new RedisMessageListenerContainer();
67 | container.setConnectionFactory(redisConnectionFactory);
68 | container.addMessageListener(biliLikeListenerAdapter, new ChannelTopic("__bili_like__"));
69 | container.addMessageListener(orderListenerAdapter, new ChannelTopic("__order__"));
70 | return container;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/RedissonConfig.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import org.redisson.Redisson;
4 | import org.redisson.api.RedissonClient;
5 | import org.redisson.config.Config;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | public class RedissonConfig {
11 |
12 | @Bean
13 | public RedissonClient redissonClient() {
14 | Config config = new Config();
15 | // config.useClusterServers()
16 | // .addNodeAddress("redis://127.0.0.1:7001")
17 | // .addNodeAddress("redis://127.0.0.1:7002")
18 | // .addNodeAddress("redis://127.0.0.1:7003");
19 | config.useSingleServer()
20 | .setAddress("redis://127.0.0.1:6379")
21 | .setDatabase(1);
22 | return Redisson.create(config);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton;
2 |
3 | import com.pkh.interceptor.LogInterceptor;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 |
9 | @Configuration
10 | public class WebMvcConfig implements WebMvcConfigurer {
11 | @Override
12 | public void addInterceptors(InterceptorRegistry registry) {
13 | LogInterceptor logInterceptor = new LogInterceptor();
14 | // registry.addInterceptor(logInterceptor)
15 | // .addPathPatterns("/**");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/pkh/configuraton/datasource/DataSourceConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.pkh.configuraton.datasource;
2 |
3 | import com.pkh.commons.datasource.DynamicDataSource;
4 | import com.pkh.commons.datasource.DynamicDataSourceContextHolder;
5 | import com.zaxxer.hikari.HikariConfig;
6 | import com.zaxxer.hikari.HikariDataSource;
7 | import org.springframework.boot.context.properties.ConfigurationProperties;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 |
11 | import javax.sql.DataSource;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 |
15 | @Configuration
16 | public class DataSourceConfiguration {
17 | @Bean
18 | @ConfigurationProperties(prefix = "pkhdb.datasource")
19 | public HikariConfig pkhdbConfig() {
20 | return new HikariConfig();
21 | }
22 |
23 | @Bean
24 | @ConfigurationProperties(prefix = "admin.datasource")
25 | public HikariConfig admindbConfig() {
26 | return new HikariConfig();
27 | }
28 |
29 | @Bean("dataSource")
30 | public DataSource dataSource() {
31 | // 将多数据源存储在Map中
32 | Map