From af18cbbe6752778e3f457b0f6d3cb93d6eafe1bb Mon Sep 17 00:00:00 2001
From: wenxin <1731551615@qq.com>
Date: Mon, 25 Nov 2024 18:43:28 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=B0=E5=AF=8C=E6=A8=A1=E6=9D=BF=EF=BC=8C?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0knife4j=E4=BE=9D=E8=B5=96=E7=AD=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 25 ++-
.../ProjectApplication.java} | 8 +-
.../linxyun/project/common/entity/Result.java | 61 ++++++++
.../project/common/enums/ErrorCode.java | 122 +++++++++++++++
.../linxyun/project/config/OpenApiConfig.java | 25 +++
.../com/linxyun/project/config/WebConfig.java | 19 +++
.../com/linxyun/project/utils/FileUtils.java | 148 ++++++++++++++++++
.../linxyun/project/utils/StringUtils.java | 8 +
.../com/linxyun/project/utils/TimeUtils.java | 21 +++
src/main/resources/application.yml | 22 ++-
.../HomeworkApplicationTests.java | 2 +-
11 files changed, 450 insertions(+), 11 deletions(-)
rename src/main/java/com/linxyun/{homework/HomeworkApplication.java => project/ProjectApplication.java} (59%)
create mode 100644 src/main/java/com/linxyun/project/common/entity/Result.java
create mode 100644 src/main/java/com/linxyun/project/common/enums/ErrorCode.java
create mode 100644 src/main/java/com/linxyun/project/config/OpenApiConfig.java
create mode 100644 src/main/java/com/linxyun/project/config/WebConfig.java
create mode 100644 src/main/java/com/linxyun/project/utils/FileUtils.java
create mode 100644 src/main/java/com/linxyun/project/utils/StringUtils.java
create mode 100644 src/main/java/com/linxyun/project/utils/TimeUtils.java
rename src/test/java/com/linxyun/{homework => project}/HomeworkApplicationTests.java (86%)
diff --git a/pom.xml b/pom.xml
index 8525c28..eb9b5c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,8 +5,8 @@
com.linxyun
homework
0.0.1-SNAPSHOT
- homework
- homework
+ project
+ project
17
UTF-8
@@ -29,13 +29,28 @@
mysql-connector-java
8.0.33
-
-
com.baomidou
mybatis-plus-boot-starter
3.5.9
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.53
+
+
+ com.github.xiaoymin
+ knife4j-openapi3-spring-boot-starter
+ 4.4.0
+
com.alibaba
druid-spring-boot-starter
@@ -76,7 +91,7 @@
spring-boot-maven-plugin
${spring-boot.version}
- com.linxyun.homework.HomeworkApplication
+ com.linxyun.project.ProjectApplication
true
diff --git a/src/main/java/com/linxyun/homework/HomeworkApplication.java b/src/main/java/com/linxyun/project/ProjectApplication.java
similarity index 59%
rename from src/main/java/com/linxyun/homework/HomeworkApplication.java
rename to src/main/java/com/linxyun/project/ProjectApplication.java
index a1df4fc..452dfe3 100644
--- a/src/main/java/com/linxyun/homework/HomeworkApplication.java
+++ b/src/main/java/com/linxyun/project/ProjectApplication.java
@@ -1,15 +1,15 @@
-package com.linxyun.homework;
+package com.linxyun.project;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
-@MapperScan("com.linxyun.homework.mapper")
-public class HomeworkApplication {
+@MapperScan("com.linxyun.project.mapper")
+public class ProjectApplication {
public static void main(String[] args) {
- SpringApplication.run(HomeworkApplication.class, args);
+ SpringApplication.run(ProjectApplication.class, args);
}
}
diff --git a/src/main/java/com/linxyun/project/common/entity/Result.java b/src/main/java/com/linxyun/project/common/entity/Result.java
new file mode 100644
index 0000000..3d7a44c
--- /dev/null
+++ b/src/main/java/com/linxyun/project/common/entity/Result.java
@@ -0,0 +1,61 @@
+package com.linxyun.project.common.entity;
+
+
+import com.linxyun.project.common.enums.ErrorCode;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+@Schema(description = "统一返回结果")
+public class Result {
+ @Schema(description = "返回数据")
+ public E data;
+ @Schema(description = "状态码")
+ public String code;
+ @Schema(description = "返回信息")
+ public String msg;
+ @Schema(description = "是否成功")
+ public boolean success = true;
+
+ public Result(E data, String code, String msg, boolean success) {
+ this.data = data;
+ this.code = code;
+ this.msg = msg;
+ this.success = success;
+ }
+
+ public static Result error(ErrorCode codeEnum) {
+ return new Result<>(null, codeEnum.getCode(), codeEnum.getMessage(), false);
+
+ }
+
+ public static Result error(String code, String msg) {
+ return new Result<>(null, code, msg, false);
+ }
+
+ public static Result ok() {
+ return new Result<>(null, "0000", "操作成功", true);
+ }
+
+ public static Result ok(String msg) {
+ return new Result<>(null, "0000", msg, true);
+
+ }
+ public static Result ok(T data) {
+ return new Result<>(data, "0000", "操作成功", true);
+
+ }
+
+ public static Result ok(T data, String msg) {
+ return new Result<>(data, "0000", msg, true);
+ }
+
+ public Result() {
+ this.success = false;
+ this.code = "9999";
+ this.msg = "操作失败";
+ this.data = null;
+ }
+}
diff --git a/src/main/java/com/linxyun/project/common/enums/ErrorCode.java b/src/main/java/com/linxyun/project/common/enums/ErrorCode.java
new file mode 100644
index 0000000..cabc5f8
--- /dev/null
+++ b/src/main/java/com/linxyun/project/common/enums/ErrorCode.java
@@ -0,0 +1,122 @@
+package com.linxyun.project.common.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum ErrorCode {
+
+ // 用户不存在或密码不匹配
+ USER_NOT_FOUND_OR_PASSWORD_MISMATCH("1006", "用户不存在或密码不匹配"),
+
+ // 参数错误
+ PARAMETER_ERROR("204", "参数错误"),
+
+ // URI 不存在
+ URI_NOT_FOUND("240", "URI不存在"),
+
+ // URI 已经存在
+ URI_ALREADY_EXISTS("241", "URI已经存在"),
+
+ // 服务的路由异常,请联系管理员
+ ROUTING_EXCEPTION("320", "服务的路由异常,请联系管理员"),
+
+ // 处理超时,服务配置出错,请联系管理员
+ TIMEOUT_ERROR("998", "处理超时,服务配置出错,请联系管理员"),
+
+ // 登录超时,请重新登录
+ LOGIN_TIMEOUT("9998", "登录超时,请重新登录"),
+
+ // 登录超时,请重新登录
+ LOGIN_TIMEOUT_2("401", "登录超时,请重新登录"),
+
+ // 操作失败
+ OPERATION_FAIL("1005", "操作失败"),
+
+ // 用户已经存在
+ USER_ALREADY_EXISTS("1007", "用户已经存在"),
+
+ // 操作ID配置错误,请联系管理员
+ OPERATION_ID_ERROR("1008", "操作ID配置错误,请联系管理员"),
+
+ // 用户ID参数错误
+ USER_ID_PARAMETER_ERROR("1009", "用户ID参数错误"),
+
+ // 用户邮箱地址错误
+ USER_EMAIL_ERROR("1011", "用户邮箱地址错误"),
+
+ // 邮箱地址已经存在
+ EMAIL_ALREADY_EXISTS("1012", "邮箱地址已经存在"),
+
+ // 手机号码格式不正确
+ PHONE_NUMBER_FORMAT_ERROR("1013", "手机号码格式不正确"),
+
+ // 手机号码已经存在
+ PHONE_NUMBER_ALREADY_EXISTS("1014", "手机号码已经存在"),
+
+ // 登录验证出错
+ LOGIN_VALIDATION_ERROR("1020", "登录验证出错"),
+
+ // 用户没有登录
+ USER_NOT_LOGGED_IN("1021", "用户没有登录"),
+
+ // 用户状态不正常
+ USER_STATUS_ERROR("1022", "用户状态不正常"),
+
+ // 发送验证码失败
+ SEND_VERIFICATION_CODE_FAIL("1023", "发送验证码失败"),
+
+ // 验证码验证失败
+ VERIFICATION_CODE_FAIL("1024", "验证码验证失败"),
+
+ // 用户组已经存在
+ USER_GROUP_ALREADY_EXISTS("1030", "用户组已经存在"),
+
+ // 用户组不存在
+ USER_GROUP_NOT_EXISTS("1031", "用户组不经存在"),
+
+ // 操作出错
+ OPERATION_ERROR("1999", "操作出错"),
+
+ // 前端处理验证数据出错
+ FRONTEND_VALIDATION_ERROR("886000", "前端处理验证数据出错"),
+
+ // 请先删除内容
+ DELETE_CONTENT_FIRST("2012", "请先删除内容"),
+ // 文件不存在
+ FILE_NOT_FOUND("3000", "文件不存在"),
+ // 文件大小超出限制
+ FILE_SIZE_EXCEEDED("3001", "文件大小超出限制"),
+ // 文件上传失败
+ FILE_UPLOAD_FAILED("3002", "文件上传失败"),
+ // 请求失败
+ REQUEST_FAILED("3003", "请求失败"),
+ NONE("6666666", "站位");
+
+
+
+ private final String code;
+ private final String message;
+
+ ErrorCode(String code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ // 根据错误代码获取对应的错误信息
+ public static String getMessageByCode(String code) {
+ for (ErrorCode errorCode : values()) {
+ if (errorCode.getCode().equals(code)) {
+ return errorCode.getMessage();
+ }
+ }
+ return "未知错误";
+ }
+}
diff --git a/src/main/java/com/linxyun/project/config/OpenApiConfig.java b/src/main/java/com/linxyun/project/config/OpenApiConfig.java
new file mode 100644
index 0000000..2a9255d
--- /dev/null
+++ b/src/main/java/com/linxyun/project/config/OpenApiConfig.java
@@ -0,0 +1,25 @@
+package com.linxyun.project.config;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class OpenApiConfig {
+
+ @Bean
+ public OpenAPI springShopOpenAPI() {
+ return new OpenAPI()
+ // 接口文档标题
+ .info(new Info()
+ .title("项目接口文档")
+ // 接口文档描述
+ .description("项目接口")
+ // 接口文档版本
+ .version("v1.0")
+ .contact(new Contact().name("wenxin"))
+ );
+ }
+}
diff --git a/src/main/java/com/linxyun/project/config/WebConfig.java b/src/main/java/com/linxyun/project/config/WebConfig.java
new file mode 100644
index 0000000..b693a1d
--- /dev/null
+++ b/src/main/java/com/linxyun/project/config/WebConfig.java
@@ -0,0 +1,19 @@
+package com.linxyun.project.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+ // 全局跨域
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOriginPatterns("*")
+ .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
+ .allowCredentials(true)
+ .maxAge(3600)
+ .allowedHeaders("*");
+ }
+}
diff --git a/src/main/java/com/linxyun/project/utils/FileUtils.java b/src/main/java/com/linxyun/project/utils/FileUtils.java
new file mode 100644
index 0000000..236395c
--- /dev/null
+++ b/src/main/java/com/linxyun/project/utils/FileUtils.java
@@ -0,0 +1,148 @@
+package com.linxyun.project.utils;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+
+@Slf4j
+@Component
+public class FileUtils {
+ private static final OkHttpClient client = new OkHttpClient();
+
+ @Value("${upload.base-url}")
+ private String baseUrl;
+
+ /**
+ * 下载文件到指定目录
+ * @param fileUrl 文件 URL
+ * @param targetDir 本地目标目录
+ * @param fileName 保存的文件名
+ * @throws IOException 如果发生 IO 异常
+ */
+ public void downloadFile(String fileUrl, String targetDir, String fileName) throws IOException {
+ // 构建请求
+ Request request = new Request.Builder()
+ .url(fileUrl)
+ .build();
+
+ // 执行请求
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ throw new IOException("文件下载失败, HTTP 响应码: " + response.code());
+ }
+
+ // 确保目标目录存在
+ File directory = new File(targetDir);
+ if (!directory.exists() && !directory.mkdirs()) {
+ throw new IOException("无法创建目标目录: " + targetDir);
+ }
+
+ // 获取输入流并保存文件
+ try (InputStream inputStream = response.body().byteStream();
+ FileOutputStream outputStream = new FileOutputStream(new File(directory, fileName))) {
+
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ }
+
+ System.out.println("文件下载完成: " + targetDir + File.separator + fileName);
+ }
+ }
+
+ /**
+ * 下载指定 URL 的文件,并将内容转化为字节数组。
+ *
+ * @param fileUrl 文件的 URL
+ * @param fileName 文件名(可以用来关联下载到本地的文件)
+ * @return 文件内容的字节数组
+ */
+ public String uploadFileByUrl(String fileUrl, String fileName) {
+ // 创建 GET 请求
+ Request request = new Request.Builder()
+ .url(fileUrl)
+ .build();
+
+ // 执行请求
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) {
+ log.error("Failed to download file: " + response.message());
+ return null;
+ }
+
+ // 获取文件内容作为字节数组
+ try (ResponseBody responseBody = response.body();
+ InputStream inputStream = responseBody.byteStream();
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+
+ // 读取数据到缓冲区
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ byteArrayOutputStream.write(buffer, 0, bytesRead);
+ }
+ return uploadFile(byteArrayOutputStream.toByteArray(), fileName);
+ }
+ } catch (IOException e) {
+ log.error("FileUploadTool uploadFileByUrl exception: ", e);
+ return null;
+ }
+ }
+
+
+
+ /**
+ * 使用 OkHttp 上传文件
+ *
+ * @param fileBytes 文件字节数组
+ * @param fileName 文件名
+ * @return 上传成功时返回服务器响应的 "data" 字段;否则返回 null
+ */
+ public String uploadFile(byte[] fileBytes, String fileName) {
+ String uploadUrl = baseUrl + "/eslithe/uploadFile.action";
+ // 创建请求体
+ RequestBody fileBody = RequestBody.create(fileBytes, MediaType.parse("application/octet-stream"));
+ MultipartBody requestBody = new MultipartBody.Builder()
+ .setType(MultipartBody.FORM)
+ .addFormDataPart("file", fileName, fileBody)
+ .build();
+
+ // 创建请求
+ Request request = new Request.Builder()
+ .url(uploadUrl)
+ .post(requestBody)
+ .build();
+
+ // 执行请求
+ try (Response response = client.newCall(request).execute()) {
+ if (response.isSuccessful() && response.body() != null) {
+ String responseBody = response.body().string();
+ log.info("FileUploadTool uploadFile result: " + responseBody);
+
+ // 解析响应
+ JSONObject jsonObject = JSONObject.parseObject(responseBody);
+ if (jsonObject != null
+ && jsonObject.getBoolean("success") != null
+ && jsonObject.getBoolean("success")
+ && jsonObject.containsKey("data")) {
+ return jsonObject.getString("data");
+ } else {
+ log.error("FileUploadTool uploadFile failed: " + responseBody);
+ return null;
+ }
+ } else {
+ log.error("FileUploadTool uploadFile failed, HTTP code: " + response.code());
+ return null;
+ }
+ } catch (IOException ex) {
+ log.error("FileUploadTool uploadFile exception: ", ex);
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/linxyun/project/utils/StringUtils.java b/src/main/java/com/linxyun/project/utils/StringUtils.java
new file mode 100644
index 0000000..67613d7
--- /dev/null
+++ b/src/main/java/com/linxyun/project/utils/StringUtils.java
@@ -0,0 +1,8 @@
+package com.linxyun.project.utils;
+
+public class StringUtils {
+ public static boolean isEmpty(String str)
+ {
+ return str == null || str.isEmpty();
+ }
+}
diff --git a/src/main/java/com/linxyun/project/utils/TimeUtils.java b/src/main/java/com/linxyun/project/utils/TimeUtils.java
new file mode 100644
index 0000000..58fc48d
--- /dev/null
+++ b/src/main/java/com/linxyun/project/utils/TimeUtils.java
@@ -0,0 +1,21 @@
+package com.linxyun.project.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class TimeUtils {
+ static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); // 定义日期格式
+ public static Date toDate(String dateStr) {
+ try {
+ return dateFormat.parse(dateStr);
+ } catch (Exception e) {
+ e.printStackTrace(); // 如果有异常,输出错误信息
+ }
+ return null;
+ }
+
+ public static String getCurrentTime() {
+ Date now = new Date();
+ return dateFormat.format(now);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index ac1f6ca..bd791b2 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -32,4 +32,24 @@ mybatis-plus:
# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
call-setters-on-nulls: true
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
\ No newline at end of file
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+springdoc:
+ swagger-ui:
+ path: /swagger-ui.html
+ tags-sorter: alpha
+ operations-sorter: alpha
+ api-docs:
+ path: /v3/api-docs
+ group-configs:
+ - group: 'default'
+ paths-to-match: '/**'
+ packages-to-scan: com.linxyun.homework.controller
+# knife4j的增强配置,不需要增强可以不配
+knife4j:
+ enable: true
+ setting:
+ language: zh_cn
+
+upload:
+ base-url: http://www.linxyun.com
\ No newline at end of file
diff --git a/src/test/java/com/linxyun/homework/HomeworkApplicationTests.java b/src/test/java/com/linxyun/project/HomeworkApplicationTests.java
similarity index 86%
rename from src/test/java/com/linxyun/homework/HomeworkApplicationTests.java
rename to src/test/java/com/linxyun/project/HomeworkApplicationTests.java
index a099d9a..0ef9363 100644
--- a/src/test/java/com/linxyun/homework/HomeworkApplicationTests.java
+++ b/src/test/java/com/linxyun/project/HomeworkApplicationTests.java
@@ -1,4 +1,4 @@
-package com.linxyun.homework;
+package com.linxyun.project;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;