丰富模板,添加knife4j依赖等

This commit is contained in:
wenxin 2024-11-25 18:43:28 +08:00
parent cfc01c86f8
commit af18cbbe67
11 changed files with 450 additions and 11 deletions

25
pom.xml
View File

@ -5,8 +5,8 @@
<groupId>com.linxyun</groupId>
<artifactId>homework</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>homework</name>
<description>homework</description>
<name>project</name>
<description>project</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -29,13 +29,28 @@
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.53</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
@ -76,7 +91,7 @@
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.linxyun.homework.HomeworkApplication</mainClass>
<mainClass>com.linxyun.project.ProjectApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>

View File

@ -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);
}
}

View File

@ -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<E> {
@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 <T> Result<T> error(ErrorCode codeEnum) {
return new Result<>(null, codeEnum.getCode(), codeEnum.getMessage(), false);
}
public static <T> Result<T> error(String code, String msg) {
return new Result<>(null, code, msg, false);
}
public static <T> Result<T> ok() {
return new Result<>(null, "0000", "操作成功", true);
}
public static <T> Result<T> ok(String msg) {
return new Result<>(null, "0000", msg, true);
}
public static <T> Result<T> ok(T data) {
return new Result<>(data, "0000", "操作成功", true);
}
public static <T> Result<T> 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;
}
}

View File

@ -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 "未知错误";
}
}

View File

@ -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"))
);
}
}

View File

@ -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("*");
}
}

View File

@ -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;
}
}
}

View File

@ -0,0 +1,8 @@
package com.linxyun.project.utils;
public class StringUtils {
public static boolean isEmpty(String str)
{
return str == null || str.isEmpty();
}
}

View File

@ -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);
}
}

View File

@ -33,3 +33,23 @@ mybatis-plus:
call-setters-on-nulls: true
# 这个配置会将执行的sql打印出来在开发或测试的时候可以用
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

View File

@ -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;