更新用户头像上传功能
This commit is contained in:
parent
b488fcc971
commit
285e2b4534
9
pom.xml
9
pom.xml
@ -34,6 +34,8 @@
|
||||
<commons.lang3.version>3.9</commons.lang3.version>
|
||||
<commons.codec.version>1.15</commons.codec.version>
|
||||
<springfox.boot.starter.version>3.0.0</springfox.boot.starter.version>
|
||||
<minio.version>8.2.1</minio.version>
|
||||
|
||||
|
||||
<docker.image.prefix>xdclass-cloud</docker.image.prefix>
|
||||
|
||||
@ -123,6 +125,13 @@
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--MINIO-->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
@ -27,7 +27,8 @@ public enum BizCodeEnum {
|
||||
*/
|
||||
ACCOUNT_REPEAT(250001, "账号已经存在"),
|
||||
ACCOUNT_UNREGISTER(250002, "账号不存在"),
|
||||
ACCOUNT_PWD_ERROR(250003, "账号或者密码错误");
|
||||
ACCOUNT_PWD_ERROR(250003, "账号或者密码错误"),
|
||||
FILE_UPLOAD_USER_IMG_FAIL(600101, "用户头像文件上传失败");
|
||||
|
||||
@Getter
|
||||
private int code;
|
||||
|
@ -5,6 +5,7 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommonUtil {
|
||||
|
||||
@ -76,6 +77,7 @@ public class CommonUtil {
|
||||
|
||||
/**
|
||||
* 生成随机数
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
@ -90,4 +92,17 @@ public class CommonUtil {
|
||||
return stringBuilder.toString();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成UUID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String generateUUID() {
|
||||
return UUID.randomUUID().toString()
|
||||
//删除-
|
||||
.replaceAll("-", "")
|
||||
//截取前32位
|
||||
.substring(0, 32);
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,11 @@
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
@ -0,0 +1,277 @@
|
||||
package net.jieyuu.component;
|
||||
|
||||
|
||||
import io.minio.*;
|
||||
import io.minio.messages.DeleteError;
|
||||
import io.minio.messages.DeleteObject;
|
||||
import lombok.Data;
|
||||
import net.jieyuu.utils.CommonUtil;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description: minio工具类
|
||||
* @version:1.0
|
||||
*/
|
||||
@Component
|
||||
public class MinioUtils {
|
||||
@Autowired
|
||||
private MinioClient minioClient;
|
||||
|
||||
@Value("${minio.bucketName}")
|
||||
private String bucketName;
|
||||
@Value("${minio.endpoint}")
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* description: 判断bucket是否存在,不存在则创建
|
||||
*
|
||||
* @return: void
|
||||
*/
|
||||
public void existBucket(String name) {
|
||||
try {
|
||||
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
|
||||
if (!exists) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建存储bucket
|
||||
*
|
||||
* @param bucketName 存储bucket名称
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean makeBucket(String bucketName) {
|
||||
try {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除存储bucket
|
||||
*
|
||||
* @param bucketName 存储bucket名称
|
||||
* @return Boolean
|
||||
*/
|
||||
// public Boolean removeBucket(String bucketName) {
|
||||
// try {
|
||||
// minioClient.removeBucket(RemoveBucketArgs.builder()
|
||||
// .bucket(bucketName)
|
||||
// .build());
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
/**
|
||||
* description: 上传多个文件
|
||||
*
|
||||
* @param multipartFile
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
// public List<String> uploadFiles(MultipartFile[] multipartFile) {
|
||||
// List<String> names = new ArrayList<>(multipartFile.length);
|
||||
// for (MultipartFile file : multipartFile) {
|
||||
// String fileName = file.getOriginalFilename();
|
||||
// String[] split = fileName.split("\\.");
|
||||
// if (split.length > 1) {
|
||||
// fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
|
||||
// } else {
|
||||
// fileName = fileName + System.currentTimeMillis();
|
||||
// }
|
||||
// InputStream in = null;
|
||||
// try {
|
||||
// in = file.getInputStream();
|
||||
// minioClient.putObject(PutObjectArgs.builder()
|
||||
// .bucket(bucketName)
|
||||
// .object(fileName)
|
||||
// .stream(in, in.available(), -1)
|
||||
// .contentType(file.getContentType())
|
||||
// .build()
|
||||
// );
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// } finally {
|
||||
// if (in != null) {
|
||||
// try {
|
||||
// in.close();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// names.add(fileName);
|
||||
// }
|
||||
// return names;
|
||||
// }
|
||||
|
||||
/**
|
||||
* description: 上传单个文件
|
||||
*
|
||||
* @param file
|
||||
* @return: String
|
||||
*/
|
||||
public String uploadFile(MultipartFile file) {
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
|
||||
LocalDateTime localDateTime = LocalDateTime.now();
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
|
||||
|
||||
String folder = dateTimeFormatter.format(localDateTime);
|
||||
String fileName = CommonUtil.generateUUID();
|
||||
|
||||
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
|
||||
String newFileName = "user/" + folder + "/" + fileName + extension;
|
||||
|
||||
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = file.getInputStream();
|
||||
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(newFileName)
|
||||
.stream(in, in.available(), -1)
|
||||
.contentType(file.getContentType())
|
||||
.build()
|
||||
);
|
||||
if (objectWriteResponse != null) {
|
||||
String res = endpoint + "/" + bucketName + "/" + newFileName;
|
||||
return res;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* description: 下载文件
|
||||
*
|
||||
* @param fileName
|
||||
* @return: org.springframework.http.ResponseEntity<byte [ ]>
|
||||
*/
|
||||
public ResponseEntity<byte[]> download(String fileName) {
|
||||
ResponseEntity<byte[]> responseEntity = null;
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream out = null;
|
||||
try {
|
||||
in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
|
||||
out = new ByteArrayOutputStream();
|
||||
IOUtils.copy(in, out);
|
||||
//封装返回值
|
||||
byte[] bytes = out.toByteArray();
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
try {
|
||||
headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
headers.setContentLength(bytes.length);
|
||||
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
headers.setAccessControlExposeHeaders(Arrays.asList("*"));
|
||||
responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看文件对象
|
||||
*
|
||||
* @param bucketName 存储bucket名称
|
||||
* @return 存储bucket内文件对象信息
|
||||
*/
|
||||
// public List<ObjectItem> listObjects(String bucketName) {
|
||||
// Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
// ListObjectsArgs.builder().bucket(bucketName).build());
|
||||
// List<ObjectItem> objectItems = new ArrayList<>();
|
||||
// try {
|
||||
// for (Result<Item> result : results) {
|
||||
// Item item = result.get();
|
||||
// ObjectItem objectItem = new ObjectItem();
|
||||
// objectItem.setObjectName(item.objectName());
|
||||
// objectItem.setSize(item.size());
|
||||
// objectItems.add(objectItem);
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
// return objectItems;
|
||||
// }
|
||||
// @Data
|
||||
// public class ObjectItem {
|
||||
// private String objectName;
|
||||
// private Long size;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 批量删除文件对象
|
||||
*
|
||||
* @param bucketName 存储bucket名称
|
||||
* @param objects 对象名称集合
|
||||
*/
|
||||
public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {
|
||||
List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
|
||||
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
|
||||
return results;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package net.jieyuu.config;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "minio")
|
||||
@Configuration
|
||||
public class MinIoClientConfig {
|
||||
|
||||
private String endpoint;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
|
||||
/**
|
||||
* 注入minio 客户端
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public MinioClient minioClient() {
|
||||
|
||||
return MinioClient.builder()
|
||||
.endpoint(endpoint)
|
||||
.credentials(accessKeyId, accessKeySecret)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,6 @@ import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import net.jieyuu.service.AddressService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
|
@ -4,13 +4,15 @@ package net.jieyuu.controller;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import net.jieyuu.enums.BizCodeEnum;
|
||||
import net.jieyuu.service.AddressService;
|
||||
import net.jieyuu.service.FileService;
|
||||
import net.jieyuu.utils.JsonData;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -26,6 +28,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class UserController {
|
||||
@Autowired
|
||||
AddressService addressService;
|
||||
@Autowired
|
||||
FileService fileService;
|
||||
|
||||
@ApiOperation("根据id查询地址详情")
|
||||
@GetMapping("detail/{address_id}")
|
||||
@ -35,5 +39,22 @@ public class UserController {
|
||||
return addressService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户头像上传
|
||||
* 默认最大1M,超过报错
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation("用户头像上传")
|
||||
@PostMapping(value = "upload")
|
||||
public JsonData uploadUserImg(
|
||||
@ApiParam(value = "文件上传", required = true)
|
||||
@RequestPart("file") MultipartFile file) throws IOException {
|
||||
String result = fileService.uploadUserHeadImg(file);
|
||||
|
||||
return result!=null?JsonData.buildSuccess(result):JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
package net.jieyuu.service;
|
||||
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface FileService {
|
||||
public String uploadUserHeadImg(MultipartFile file) throws IOException;
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package net.jieyuu.service;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 邮件发送类
|
||||
* </p>
|
||||
*
|
||||
* @author jieyuu
|
||||
* @since 2024-02-12
|
||||
*/
|
||||
public interface MailService {
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
* @param to
|
||||
* @param subject
|
||||
* @param content
|
||||
*/
|
||||
public void sendMail(String to, String subject, String content);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package net.jieyuu.service.impl;
|
||||
|
||||
import io.minio.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.jieyuu.service.FileService;
|
||||
import net.jieyuu.utils.CommonUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FileServiceImpl implements FileService {
|
||||
|
||||
@Autowired
|
||||
private MinioClient minioClient;
|
||||
|
||||
@Value("${minio.bucketName}")
|
||||
private String bucketName;
|
||||
@Value("${minio.endpoint}")
|
||||
private String endpoint;
|
||||
|
||||
@Override
|
||||
public String uploadUserHeadImg(MultipartFile file) {
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
|
||||
LocalDateTime localDateTime = LocalDateTime.now();
|
||||
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
|
||||
String folder = dateTimeFormatter.format(localDateTime);
|
||||
|
||||
String fileName = CommonUtil.generateUUID();
|
||||
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
String newFileName = "user/" + folder + "/" + fileName + extension;
|
||||
|
||||
|
||||
try (InputStream in = file.getInputStream();){
|
||||
|
||||
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(newFileName)
|
||||
.stream(in, in.available(), -1)
|
||||
.contentType(file.getContentType())
|
||||
.build()
|
||||
);
|
||||
if (objectWriteResponse != null) {
|
||||
String res = endpoint + "/" + bucketName + "/" + newFileName;
|
||||
return res;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传头像失败:{}", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package net.jieyuu.service.impl;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.jieyuu.service.MailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MailServiceImpl implements MailService {
|
||||
|
||||
/**
|
||||
* Spring Boot 提供了一个发送邮件的简单抽象,直接注入即可使用
|
||||
*/
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
/**
|
||||
* 配置文件中的发送邮箱
|
||||
*/
|
||||
@Value("${spring.mail.from}")
|
||||
private String from;
|
||||
|
||||
@Override
|
||||
public void sendMail(String to, String subject, String content) {
|
||||
//创建SimpleMailMessage对象
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
//邮件发送人
|
||||
message.setFrom(from);
|
||||
//邮件接收人
|
||||
message.setTo(to);
|
||||
//邮件主题
|
||||
message.setSubject(subject);
|
||||
//邮件内容
|
||||
message.setText(content);
|
||||
//发送邮件
|
||||
mailSender.send(message);
|
||||
log.info("邮件发成功:{}", message.toString());
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package net.jieyuu.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.jieyuu.component.MailService;
|
||||
import net.jieyuu.enums.SendCodeEnum;
|
||||
import net.jieyuu.service.MailService;
|
||||
import net.jieyuu.service.NotifyService;
|
||||
import net.jieyuu.utils.CheckUtil;
|
||||
import net.jieyuu.utils.CommonUtil;
|
||||
@ -11,8 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class NotifyServiceImpl implements NotifyService {
|
||||
|
@ -36,4 +36,13 @@ mybatis-plus:
|
||||
#设置日志级别,ERROR/WARN/INFO/DEBUG,默认是INFO以上才显示
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
root: INFO
|
||||
|
||||
|
||||
minio:
|
||||
endpoint: http://134.175.219.253:9000
|
||||
access-key-id: Y7sQYzzcBob67Wu7agLK
|
||||
access-key-secret: PXT1QKl0U23VMMKPmCbDZvGaJiw23AhQWpd4RlO9
|
||||
bucketName: xdclass-shop-image
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ package net.jieyuu.biz;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.jieyuu.UserServiceApplication;
|
||||
import net.jieyuu.service.MailService;
|
||||
import net.jieyuu.component.MailService;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
Loading…
Reference in New Issue
Block a user