diff --git a/pom.xml b/pom.xml
index a8a57cd..2570047 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.2.1
+ 2.4.6
com.example
@@ -14,12 +14,35 @@
GuoYan
GuoYan
- 17
+ 11
org.springframework.boot
- spring-boot-starter-web
+
+
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+ 2.2.6.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter
@@ -27,12 +50,23 @@
spring-boot-starter-test
test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ compile
+
com.baomidou
mybatis-plus-boot-starter
3.4.0
+
+ com.alibaba
+ fastjson
+ 1.2.76
+
org.projectlombok
@@ -43,8 +77,39 @@
com.alibaba
druid-spring-boot-starter
- 1.2.3
+ 1.2.5
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.2.5
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+
+ com.github.xiaoymin
+ knife4j-spring-boot-starter
+ 3.0.2
+
+ org.projectlombok
+ lombok
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
@@ -52,6 +117,7 @@
org.springframework.boot
spring-boot-maven-plugin
+ 2.4.5
diff --git a/src/main/java/com/example/guoyan/GuoYanApplication.java b/src/main/java/com/example/guoyan/GuoYanApplication.java
index 794cb81..934e7fd 100644
--- a/src/main/java/com/example/guoyan/GuoYanApplication.java
+++ b/src/main/java/com/example/guoyan/GuoYanApplication.java
@@ -1,9 +1,13 @@
package com.example.guoyan;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
+@Slf4j
+@EnableScheduling
public class GuoYanApplication {
public static void main(String[] args) {
diff --git a/src/main/java/com/example/guoyan/common/CustomerException.java b/src/main/java/com/example/guoyan/common/CustomerException.java
new file mode 100644
index 0000000..714e99c
--- /dev/null
+++ b/src/main/java/com/example/guoyan/common/CustomerException.java
@@ -0,0 +1,13 @@
+package com.example.guoyan.common;
+
+/**
+* 自定义一个运行时异常
+*
+*/
+public class CustomerException extends RuntimeException{
+
+ public CustomerException(String message) {
+
+ super(message);
+ }
+}
diff --git a/src/main/java/com/example/guoyan/common/GloableExceptionHandler.java b/src/main/java/com/example/guoyan/common/GloableExceptionHandler.java
new file mode 100644
index 0000000..f8dc346
--- /dev/null
+++ b/src/main/java/com/example/guoyan/common/GloableExceptionHandler.java
@@ -0,0 +1,58 @@
+package com.example.guoyan.common;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.sql.SQLIntegrityConstraintViolationException;
+
+/**
+ * 全局异常处理
+ * 基于代理实现,也就是通过AOP来对这些异常进行拦截
+ * 如果抛异常了,就一起来这里进行处理
+ * @ControllerAdvice(拦截哪些controller)
+ * @ControllerAdvice(annotations = {RestController.class, Controller.class})加入了@RestController、@Controller的注解
+ * @ResponseBody 返回Result对象时解析成json
+ */
+@ControllerAdvice(annotations = {RestController.class, Controller.class})
+@ResponseBody
+@Slf4j
+public class GloableExceptionHandler {
+ /**
+ * @ExceptionHandler({异常类型.class,异常类型.class})
+ * @param exception 异常对象,后面Get信息要用
+ * @return 返回Result对象,既然都抓异常了,肯定就要Result.error("失败信息")
+ */
+ @ExceptionHandler({SQLIntegrityConstraintViolationException.class,NullPointerException.class})
+ public Result exceptionHandler(SQLIntegrityConstraintViolationException exception){
+ log.error(exception.getMessage());
+ //这里判断出来是添加员工时出现的异常
+ if (exception.getMessage().contains("Duplicate entry")){
+ //exception对象分割,同时存储
+ String []splitErrorMessage=exception.getMessage().split(" ");
+ /**
+ * splitErrorMessage数组内存的信息
+ * Duplicate entry '新增的账号' for key 'idx_username'
+ * 下标位2是新增账号,下标位5是关联的字段名
+ */
+ String errorMessage = "这个账号重复了" + splitErrorMessage[2];
+ return Result.error(errorMessage);
+ }
+ return Result.error("失败了");
+ }
+
+ /**
+ * 自定义的全局异常处理
+ * @param customerException 自定义异常对象
+ * @return
+ */
+ @ExceptionHandler({CustomerException.class})
+ public Result exceptionHandlerCustomer(CustomerException customerException){
+ log.error(customerException.getMessage());
+ //直接返回处理信息
+ return Result.error(customerException.getMessage());
+ }
+}
diff --git a/src/main/java/com/example/guoyan/common/JacksonObjectMapper.java b/src/main/java/com/example/guoyan/common/JacksonObjectMapper.java
new file mode 100644
index 0000000..2b4fe7a
--- /dev/null
+++ b/src/main/java/com/example/guoyan/common/JacksonObjectMapper.java
@@ -0,0 +1,54 @@
+package com.example.guoyan.common;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
+
+/**
+ * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+ * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+ * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+ */
+public class JacksonObjectMapper extends ObjectMapper {
+
+ public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+ public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
+
+ public JacksonObjectMapper() {
+ super();
+ //收到未知属性时不报异常
+ this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ //反序列化时,属性不存在的兼容处理
+ this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+
+ SimpleModule simpleModule = new SimpleModule()
+ .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
+ .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+ .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
+
+ .addSerializer(BigInteger.class, ToStringSerializer.instance)
+ .addSerializer(Long.class, ToStringSerializer.instance)
+ .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
+ .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+ .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
+
+ //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+ this.registerModule(simpleModule);
+ }
+}
diff --git a/src/main/java/com/example/guoyan/common/MyMetaObjectHandler.java b/src/main/java/com/example/guoyan/common/MyMetaObjectHandler.java
new file mode 100644
index 0000000..44cf847
--- /dev/null
+++ b/src/main/java/com/example/guoyan/common/MyMetaObjectHandler.java
@@ -0,0 +1,65 @@
+package com.example.guoyan.common;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+
+/**
+ * 自定义元数据处理器
+ * MP提供的自动填充功能,通过实现MetaObjectHandler(元数据处理器),来实现服务
+ * 为加入@TableField的注解提供自动填充的功能
+ */
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+ /*退而求其次选择了注入Request对象*/
+ @Autowired
+ HttpServletRequest httpServletRequest;
+
+ /**
+ * @param metaObject 插入时自动填充
+ */
+ @Override
+ public void insertFill(MetaObject metaObject) {
+
+ //填充创建时间
+ metaObject.setValue("createTime", LocalDateTime.now());
+ //填充 更新的时间
+ metaObject.setValue("updateTime", LocalDateTime.now());
+ //BaseContext工具类获取当前登陆人员信息
+ //填充创建人信息
+ metaObject.setValue("createUser", httpServletRequest.getSession().getAttribute("employee"));
+ //填充更新人信息
+ metaObject.setValue("updateUser", httpServletRequest.getSession().getAttribute("employee"));
+ /*
+ 这里有Bug,就是封装好的BaseContext通过ThreadLocal获取不了对象,虽然都是一个线程的
+ 但就是获取不到,所以这里先写死了,后面慢慢再改吧
+ * */
+ /*//填充创建人信息
+ metaObject.setValue("createUser", 1L);
+ //填充更新人信息
+ metaObject.setValue("updateUser", 1L);*/
+
+ }
+
+ /**
+ * @param metaObject 更新时自动填充
+ */
+ @Override
+ public void updateFill(MetaObject metaObject) {
+ //因为是更新,所以不用操作创建时间
+ //更新 更新的时间
+ metaObject.setValue("updateTime", LocalDateTime.now());
+ //更新更新人员
+ /*
+ 这里有Bug,就是封装好的BaseContext通过ThreadLocal获取不了对象,所以这里先写死了,后面慢慢再改吧
+ metaObject.setValue("updateUser", 1L);
+ * */
+
+ metaObject.setValue("updateUser", httpServletRequest.getSession().getAttribute("employee"));
+ }
+}
diff --git a/src/main/java/com/example/guoyan/common/Result.java b/src/main/java/com/example/guoyan/common/Result.java
new file mode 100644
index 0000000..5f29302
--- /dev/null
+++ b/src/main/java/com/example/guoyan/common/Result.java
@@ -0,0 +1,43 @@
+package com.example.guoyan.common;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 通用返回结果,服务端响应的数据最终都会封装成此对象
+ * @param
+ */
+@Data
+public class Result implements Serializable {
+
+ private Integer code; //编码:1成功,0和其它数字为失败
+
+ private String msg; //错误信息
+
+ private T data; //数据
+
+ private Map map = new HashMap(); //动态数据
+
+ public static Result success(T object) {
+ Result r = new Result();
+ r.data = object;
+ r.code = 1;
+ return r;
+ }
+
+ public static Result error(String msg) {
+ Result r = new Result();
+ r.msg = msg;
+ r.code = 0;
+ return r;
+ }
+
+ public Result add(String key, Object value) {
+ this.map.put(key, value);
+ return this;
+ }
+
+}
diff --git a/src/main/java/com/example/guoyan/config/MybatisPlusConfig.java b/src/main/java/com/example/guoyan/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..488178b
--- /dev/null
+++ b/src/main/java/com/example/guoyan/config/MybatisPlusConfig.java
@@ -0,0 +1,24 @@
+package com.example.guoyan.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * MybatisPlus分页插件配置类
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+ //分页插件
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor(){
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
+ return interceptor;
+ }
+}
diff --git a/src/main/java/com/example/guoyan/config/RedisConfig.java b/src/main/java/com/example/guoyan/config/RedisConfig.java
new file mode 100644
index 0000000..4d88f36
--- /dev/null
+++ b/src/main/java/com/example/guoyan/config/RedisConfig.java
@@ -0,0 +1,20 @@
+package com.example.guoyan.config;
+
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+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.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig extends CachingConfigurerSupport {
+ @Bean
+ public RedisTemplate