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;