diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 82dbec8..c3f3b0a 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 805608c..bd1ebf9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,12 @@
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">
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.4.4
+
+
com.supervision
ai-demo-platform
@@ -12,6 +18,123 @@
17
17
UTF-8
+ 1.0.0-M7
-
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ com.alibaba
+ druid-spring-boot-3-starter
+ 1.2.21
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ 3.5.7
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.5
+
+
+ org.postgresql
+ postgresql
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ cn.hutool
+ hutool-all
+ 5.8.26
+
+
+ com.alibaba
+ fastjson
+ 1.2.83_noneautotype
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.15.3
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.15.3
+
+
+ org.commonmark
+ commonmark
+ 0.21.0
+
+
+ org.commonmark
+ commonmark-ext-gfm-tables
+ 0.21.0
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.12.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.12.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.12.5
+ runtime
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
+
+ org.springframework.ai
+ spring-ai-bom
+ ${spring-ai.version}
+ pom
+ import
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/supervision/Main.java b/src/main/java/com/supervision/Main.java
deleted file mode 100644
index f7ee142..0000000
--- a/src/main/java/com/supervision/Main.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.supervision;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println("Hello world!");
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/PlatformApplication.java b/src/main/java/com/supervision/PlatformApplication.java
new file mode 100644
index 0000000..9731ae8
--- /dev/null
+++ b/src/main/java/com/supervision/PlatformApplication.java
@@ -0,0 +1,15 @@
+package com.supervision;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
+@MapperScan(basePackages = {"com.supervision.**.mapper"})
+@SpringBootApplication
+public class PlatformApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(PlatformApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/config/ExceptionHandlerConfig.java b/src/main/java/com/supervision/config/ExceptionHandlerConfig.java
new file mode 100644
index 0000000..c3fe1ed
--- /dev/null
+++ b/src/main/java/com/supervision/config/ExceptionHandlerConfig.java
@@ -0,0 +1,63 @@
+package com.supervision.config;
+
+import com.supervision.constant.ResultStatusEnum;
+import com.supervision.dto.R;
+import com.supervision.exception.BusinessException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.multipart.MaxUploadSizeExceededException;
+
+/**
+ * 统一异常处理器配置
+ *
+ * @author wb
+ * @date 2022/3/10 13:24
+ */
+@Slf4j
+@Configuration
+@RestControllerAdvice(annotations = RestController.class, basePackages = {"com.supervision.**.controller"})
+public class ExceptionHandlerConfig {
+
+ /**
+ * 添加手动校验参数的异常处理
+ *
+ * @param exception 参数验证异常
+ * @return 通用返回值
+ */
+ @ExceptionHandler(IllegalArgumentException.class)
+ public R> manualValidationExceptionResponse(IllegalArgumentException exception) {
+ log.error("=========手动校验参数异常=========>>>");
+ log.error(exception.getMessage(), exception);
+ log.error("<<<=========手动校验参数异常=========");
+ return R.fail(ResultStatusEnum.ILLEGAL_ARGUMENT.getCode(), exception.getMessage());
+ }
+
+ @ExceptionHandler(BusinessException.class)
+ public R> businessExceptionResponse(BusinessException exception) {
+ log.error("=========运行异常=========>>>");
+ log.error(exception.getMessage(), exception);
+ log.error("<<<=========运行异常=========");
+
+ return R.fail(511, exception.getMessage());
+ }
+
+ @ExceptionHandler(RuntimeException.class)
+ public R> manualValidationExceptionResponse(RuntimeException exception) {
+ log.error("=========运行异常=========>>>");
+ log.error(exception.getMessage(), exception);
+ log.error("<<<=========运行异常=========");
+
+ return R.fail(ResultStatusEnum.RUNTIME_EXCEPTION.getCode(), exception.getMessage());
+ }
+
+ @ExceptionHandler(MaxUploadSizeExceededException.class)
+ public R> handleMaxSizeException(MaxUploadSizeExceededException exception) {
+ log.error("=========文件大小超出限制异常=========>>>");
+ log.error(exception.getMessage(), exception);
+ log.error("<<<=========文件大小超出限制异常=========");
+ return R.fail(ResultStatusEnum.EXCEED_FILE_SIZE.getCode(), exception.getMessage());
+ }
+}
diff --git a/src/main/java/com/supervision/config/MyMetaObjectHandler.java b/src/main/java/com/supervision/config/MyMetaObjectHandler.java
new file mode 100644
index 0000000..28ac192
--- /dev/null
+++ b/src/main/java/com/supervision/config/MyMetaObjectHandler.java
@@ -0,0 +1,26 @@
+package com.supervision.config;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author Ray
+ */
+public class MyMetaObjectHandler implements MetaObjectHandler {
+ public MyMetaObjectHandler() {
+ }
+
+ @Override
+ public void insertFill(MetaObject metaObject) {
+ this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
+ this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
+ }
+
+ @Override
+ public void updateFill(MetaObject metaObject) {
+ this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/config/MybatisPlusConfig.java b/src/main/java/com/supervision/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..67a3759
--- /dev/null
+++ b/src/main/java/com/supervision/config/MybatisPlusConfig.java
@@ -0,0 +1,45 @@
+package com.supervision.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * MybatisPlus配置
+ *
+ * @author qmy
+ * @version 1.0.0 2020/10/22 9:47
+ * @since JDK1.8
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+ @Bean
+ public MyMetaObjectHandler myMetaObjectHandler() {
+ return new MyMetaObjectHandler();
+ }
+
+ /**
+ * 拦截器配置
+ */
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(this.paginationInterceptor());
+ return interceptor;
+ }
+
+
+ private PaginationInnerInterceptor paginationInterceptor() {
+ PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
+ paginationInterceptor.setOverflow(false);
+ /**
+ * 注意! 此处要设置数据库类型.
+ */
+ paginationInterceptor.setDbType(DbType.POSTGRE_SQL);
+ return paginationInterceptor;
+ }
+}
diff --git a/src/main/java/com/supervision/config/SecurityConfig.java b/src/main/java/com/supervision/config/SecurityConfig.java
new file mode 100644
index 0000000..d0d4884
--- /dev/null
+++ b/src/main/java/com/supervision/config/SecurityConfig.java
@@ -0,0 +1,82 @@
+package com.supervision.config;
+
+import com.supervision.filter.JwtAuthenticationFilter;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.Keys;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import java.util.Base64;
+
+
+@Configuration
+@EnableWebSecurity
+@RequiredArgsConstructor
+public class SecurityConfig {
+
+ private final JwtAuthenticationFilter jwtAuthenticationFilter;
+ private final UserDetailsService userDetailsService;
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+ http
+ .csrf(AbstractHttpConfigurer::disable) // 禁用CSRF
+ .authorizeHttpRequests(auth -> auth
+ .requestMatchers("/auth/**").permitAll()
+ .anyRequest().authenticated()
+ )
+ .sessionManagement(session -> session
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ )
+ .authenticationProvider(authenticationProvider())
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
+ // 👇 正确禁用方式(推荐)
+ .formLogin(Customizer.withDefaults()) // 启用默认配置
+ .httpBasic(Customizer.withDefaults()); // 启用默认配置
+ return http.build();
+ }
+
+
+ @Bean
+ public AuthenticationProvider authenticationProvider() {
+ // 使用DaoAuthenticationProvider,并注入自定义的UserDetailsService和PasswordEncoder
+ DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
+ authProvider.setUserDetailsService(userDetailsService); // 从数据库读取用户进行认证
+ authProvider.setPasswordEncoder(passwordEncoder()); // 使用BCrypt密码器验证密码
+ return authProvider;
+ }
+
+ @Bean
+ public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
+ // 从AuthenticationConfiguration中获取AuthenticationManager实例
+ return config.getAuthenticationManager();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ // 使用BCryptPasswordEncoder作为密码加密器
+ return new BCryptPasswordEncoder();
+ }
+
+ public static void main(String[] args) {
+ String s = Base64.getEncoder().encodeToString(Keys.secretKeyFor(SignatureAlgorithm.HS256).getEncoded());
+ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
+ String encode = bCryptPasswordEncoder.encode("123456");
+ System.out.println(encode);
+ }
+
+}
diff --git a/src/main/java/com/supervision/constant/ResultStatusEnum.java b/src/main/java/com/supervision/constant/ResultStatusEnum.java
new file mode 100644
index 0000000..91859f7
--- /dev/null
+++ b/src/main/java/com/supervision/constant/ResultStatusEnum.java
@@ -0,0 +1,55 @@
+package com.supervision.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * 响应结果状态枚举类
+ * @author qimaoyu
+ * @create 2019-07-14 10:22
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+public enum ResultStatusEnum {
+
+ AUTHENTICATION_FAILED(320, "token失效,请重新登录!"),
+ NO_ACCESS_TO_THIS_INTERFACE(320, "无权访问此接口!"),
+ FAILED_TO_GENERATE_TOKEN(321, "生成token失败!"),
+ ACCOUNT_PASSWORD_INCORRECT(322, "账号或密码错误!"),
+ ACCOUNT_NOT_CREATE(323, "账号未创建!"),
+ HAS_BEEN_PULLED_BLACK(324, "已被删除或禁用,无法登录!"),
+ USERNAME_MAIL_IS_EXIST(341, "登录名称已经被注册!"),
+ USERNAME_IS_BLANK(342, "登录名称为空!"),
+ VERIFICATION_CODE_EXPIRED(350,"验证码已过期,请重新获取。"),
+ VERIFICATION_CODE_FAILURE(351,"验证码输入错误。"),
+ OPERATE_FAIL(360,"修改毕业生信息失败。"),
+ DATA_IS_EMPTY(370,"查询到的结果为空"),
+ SYSTEM_ABNORMAL(500, "系统繁忙,请稍后重试!"),
+ UPLOAD_EXCEPTION(501, "文件上传异常!"),
+ EXPORT_EXCEPTION(502, "文件导出异常!"),
+ INCORRECT_FILE_FORMAT(503, "文件格式不正确!"),
+ PARAMETER_CANNOT_BE_EMPTY(504, "参数不能为空,操作失败!"),
+ NO_TEMP_UPLOADFILEPATH(505,"未配置文件上传临时存储路径"),
+ USER_DOES_NOT_EXIST(507, "用户不存在,操作失败!"),
+
+ ILLEGAL_ARGUMENT(508, "参数校验失败!"),
+ RUNTIME_EXCEPTION(509, "程序运行异常!"),
+ EXCEED_FILE_SIZE(510, "文件大小超出限制!"),
+ IMPORT_COMPANY_FORMAT_ERROR(521,"Excel表格格式错误!"),
+ IMPORT_COMPANY_FAIL(522,"部分数据导入失败"),
+ INSERT_FAIL(600,"新增失败"),
+ DuplicateKeyException(601,"该条信息已经存在,请勿重复添加"),
+ UPDATE_FAIL(700,"更新失败"),
+ DELETE_FAIL(800,"删除失败"),
+ YEAR_IS_CLOSE(1001,"该年度暂未开启");
+
+ @Getter
+ @Setter
+ private int code;
+
+ @Getter
+ @Setter
+ private String message;
+}
diff --git a/src/main/java/com/supervision/dto/R.java b/src/main/java/com/supervision/dto/R.java
new file mode 100644
index 0000000..29c3270
--- /dev/null
+++ b/src/main/java/com/supervision/dto/R.java
@@ -0,0 +1,131 @@
+package com.supervision.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * 响应信息主体
+ *
+ * @author qimaoyu
+ */
+@Data
+public class R implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String TOTAL_COUNT = "total";
+ public static final String RESULT_LIST = "result";
+
+ /**
+ * 成功
+ */
+ public static final int SUCCESS = 200;
+
+ /**
+ * 失败
+ */
+ public static final int FAIL = 500;
+
+ private int code;
+
+ private String msg;
+
+ private T data;
+
+ public static R ok() {
+ return restResult(null, SUCCESS, null);
+ }
+
+ public static R judgeResult(Boolean bo, String successMessage, String failMessage) {
+ if (bo) {
+ return restResult(null, SUCCESS, successMessage);
+ } else {
+ return restResult(null, FAIL, failMessage);
+ }
+ }
+
+ public static R okMsg(String msg) {
+ return restResult(null, SUCCESS, msg);
+ }
+
+ public static R ok(T data) {
+ return restResult(data, SUCCESS, null);
+ }
+
+ public static R ok(T data, String msg) {
+ return restResult(data, SUCCESS, msg);
+ }
+
+ public static R fail() {
+ return restResult(null, FAIL, null);
+ }
+
+ public static R fail(String msg) {
+ return restResult(null, FAIL, msg);
+ }
+
+ public static R fail(T data) {
+ return restResult(data, FAIL, null);
+ }
+
+ public static R fail(int code, String msg) {
+ return restResult(null, code, msg);
+ }
+
+
+
+ private static R restResult(T data, int code, String msg) {
+ R apiResult = new R<>();
+ apiResult.setCode(code);
+ apiResult.setData(data);
+ apiResult.setMsg(msg);
+ return apiResult;
+ }
+
+
+ public static Map buildDataMap(List list) {
+ Map dataMap = new HashMap<>();
+ if (list == null) {
+ dataMap.put(TOTAL_COUNT, 0);
+ dataMap.put(RESULT_LIST, new ArrayList<>());
+ } else {
+ dataMap.put(TOTAL_COUNT, list.size());
+ dataMap.put(RESULT_LIST, list);
+ }
+ return dataMap;
+ }
+
+ public static Map buildDataMap(List list, Long total) {
+ Map dataMap = new HashMap<>();
+ dataMap.put(TOTAL_COUNT, total);
+ dataMap.put(RESULT_LIST, list);
+ return dataMap;
+ }
+
+ public static Map buildDataMap(Set list) {
+ Map dataMap = new HashMap<>();
+ if (list == null) {
+ dataMap.put(TOTAL_COUNT, 0);
+ dataMap.put(RESULT_LIST, new ArrayList<>());
+ } else {
+ dataMap.put(TOTAL_COUNT, list.size());
+ dataMap.put(RESULT_LIST, list);
+ }
+ return dataMap;
+ }
+
+ public static Map buildDataMap(Object object) {
+ if (object == null) {
+ return null;
+ }
+ List