diff --git a/src/main/java/org/blue/club/configuration/CustomAuthorizationHandler.java b/src/main/java/org/blue/club/configuration/CustomAuthorizationHandler.java index de42c2b..53c6ad9 100644 --- a/src/main/java/org/blue/club/configuration/CustomAuthorizationHandler.java +++ b/src/main/java/org/blue/club/configuration/CustomAuthorizationHandler.java @@ -4,7 +4,7 @@ import lombok.RequiredArgsConstructor; import org.blue.club.annotation.Auth; import org.blue.club.dao.UserDao; import org.blue.club.entities.dto.User; -import org.blue.club.entities.vo.UserVo; +import org.blue.club.entities.vo.data.UserVo; import org.mmga.spring.boot.starter.componet.AuthorizationHandler; import org.mmga.spring.boot.starter.componet.JwtUtils; import org.mmga.spring.boot.starter.entities.Result; diff --git a/src/main/java/org/blue/club/controller/UserController.java b/src/main/java/org/blue/club/controller/UserController.java index b3c473f..2bfba8d 100644 --- a/src/main/java/org/blue/club/controller/UserController.java +++ b/src/main/java/org/blue/club/controller/UserController.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import org.blue.club.annotation.Auth; import org.blue.club.entities.dto.User; import org.blue.club.entities.dto.req.*; +import org.blue.club.entities.dto.resp.VerifyCodeResponse; import org.blue.club.services.UserServices; import org.mmga.spring.boot.starter.annotation.AuthMapping; import org.mmga.spring.boot.starter.entities.PagerData; @@ -87,7 +88,7 @@ public class UserController { @GetMapping("/verify") @Operation(description = "获取验证码") - public Result generatorVerifyCode() { + public Result generatorVerifyCode() { return userServices.getVerifyCode(); } diff --git a/src/main/java/org/blue/club/dao/UserDao.java b/src/main/java/org/blue/club/dao/UserDao.java index 27a8d92..703ea36 100644 --- a/src/main/java/org/blue/club/dao/UserDao.java +++ b/src/main/java/org/blue/club/dao/UserDao.java @@ -2,7 +2,7 @@ package org.blue.club.dao; import com.mybatisflex.core.BaseMapper; import org.apache.ibatis.annotations.Mapper; -import org.blue.club.entities.vo.UserVo; +import org.blue.club.entities.vo.data.UserVo; @Mapper public interface UserDao extends BaseMapper { diff --git a/src/main/java/org/blue/club/dao/redis/AvatarOperationDao.java b/src/main/java/org/blue/club/dao/redis/AvatarOperationDao.java index 45a13d7..e092f78 100644 --- a/src/main/java/org/blue/club/dao/redis/AvatarOperationDao.java +++ b/src/main/java/org/blue/club/dao/redis/AvatarOperationDao.java @@ -1,6 +1,6 @@ package org.blue.club.dao.redis; -import org.blue.club.entities.vo.AvatarTmpVo; +import org.blue.club.entities.vo.data.AvatarTmpVo; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/org/blue/club/entities/dto/User.java b/src/main/java/org/blue/club/entities/dto/User.java index aaa4c4f..bb4f30d 100644 --- a/src/main/java/org/blue/club/entities/dto/User.java +++ b/src/main/java/org/blue/club/entities/dto/User.java @@ -4,8 +4,8 @@ import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.RelationManyToOne; import jakarta.annotation.Nullable; import lombok.Data; -import org.blue.club.entities.vo.AuthVo; -import org.blue.club.entities.vo.ClubVo; +import org.blue.club.entities.vo.data.AuthVo; +import org.blue.club.entities.vo.data.ClubVo; import org.mmga.spring.boot.starter.interfaces.IdHolder; @Data diff --git a/src/main/java/org/blue/club/entities/dto/resp/VerifyCodeResponse.java b/src/main/java/org/blue/club/entities/dto/resp/VerifyCodeResponse.java new file mode 100644 index 0000000..3e6f26c --- /dev/null +++ b/src/main/java/org/blue/club/entities/dto/resp/VerifyCodeResponse.java @@ -0,0 +1,8 @@ +package org.blue.club.entities.dto.resp; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "验证码返回值") +public record VerifyCodeResponse(@Schema(description = "验证码图像base64") String img, + @Schema(description = "验证码验证密钥") String key) { +} diff --git a/src/main/java/org/blue/club/entities/vo/AuthPermissionVo.java b/src/main/java/org/blue/club/entities/vo/data/AuthPermissionVo.java similarity index 77% rename from src/main/java/org/blue/club/entities/vo/AuthPermissionVo.java rename to src/main/java/org/blue/club/entities/vo/data/AuthPermissionVo.java index c3f7813..89f0836 100644 --- a/src/main/java/org/blue/club/entities/vo/AuthPermissionVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/AuthPermissionVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Table; @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Table("auth_permission") -public class AuthPermissionVo extends BaseVo { +public class AuthPermissionVo extends BaseDataVo { @Column("auth_id") private Long authId; @Column("permission_id") diff --git a/src/main/java/org/blue/club/entities/vo/AuthVo.java b/src/main/java/org/blue/club/entities/vo/data/AuthVo.java similarity index 89% rename from src/main/java/org/blue/club/entities/vo/AuthVo.java rename to src/main/java/org/blue/club/entities/vo/data/AuthVo.java index febe110..b0f1ff0 100644 --- a/src/main/java/org/blue/club/entities/vo/AuthVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/AuthVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.RelationManyToMany; @@ -11,7 +11,7 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @Table("auth") @Data -public class AuthVo extends BaseVo { +public class AuthVo extends BaseDataVo { @Id private Long id; private String name; diff --git a/src/main/java/org/blue/club/entities/vo/AvatarTmpVo.java b/src/main/java/org/blue/club/entities/vo/data/AvatarTmpVo.java similarity index 88% rename from src/main/java/org/blue/club/entities/vo/AvatarTmpVo.java rename to src/main/java/org/blue/club/entities/vo/data/AvatarTmpVo.java index b316715..0e9d9e3 100644 --- a/src/main/java/org/blue/club/entities/vo/AvatarTmpVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/AvatarTmpVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; diff --git a/src/main/java/org/blue/club/entities/vo/BaseVo.java b/src/main/java/org/blue/club/entities/vo/data/BaseDataVo.java similarity index 82% rename from src/main/java/org/blue/club/entities/vo/BaseVo.java rename to src/main/java/org/blue/club/entities/vo/data/BaseDataVo.java index c1a8a3e..eb4f674 100644 --- a/src/main/java/org/blue/club/entities/vo/BaseVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/BaseDataVo.java @@ -1,10 +1,10 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Column; import java.util.Date; -public class BaseVo { +public class BaseDataVo { @Column(value = "create_time", onUpdateValue = "now()", onInsertValue = "now()") protected Date createTime; @Column(value = "update_time", onUpdateValue = "now()", onInsertValue = "now()") diff --git a/src/main/java/org/blue/club/entities/vo/ClubUserAuthVo.java b/src/main/java/org/blue/club/entities/vo/data/ClubUserAuthVo.java similarity index 79% rename from src/main/java/org/blue/club/entities/vo/ClubUserAuthVo.java rename to src/main/java/org/blue/club/entities/vo/data/ClubUserAuthVo.java index 808f9a4..2cbc266 100644 --- a/src/main/java/org/blue/club/entities/vo/ClubUserAuthVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/ClubUserAuthVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Table; @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Table("club_user_auth") @Data -public class ClubUserAuthVo extends BaseVo { +public class ClubUserAuthVo extends BaseDataVo { @Column("user_id") private Long userId; @Column("club_id") diff --git a/src/main/java/org/blue/club/entities/vo/ClubVo.java b/src/main/java/org/blue/club/entities/vo/data/ClubVo.java similarity index 77% rename from src/main/java/org/blue/club/entities/vo/ClubVo.java rename to src/main/java/org/blue/club/entities/vo/data/ClubVo.java index 36125dd..5f0762f 100644 --- a/src/main/java/org/blue/club/entities/vo/ClubVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/ClubVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Table; @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @Table("club") -public class ClubVo extends BaseVo { +public class ClubVo extends BaseDataVo { @Id private Long id; private String name; diff --git a/src/main/java/org/blue/club/entities/vo/PermissionVo.java b/src/main/java/org/blue/club/entities/vo/data/PermissionVo.java similarity index 74% rename from src/main/java/org/blue/club/entities/vo/PermissionVo.java rename to src/main/java/org/blue/club/entities/vo/data/PermissionVo.java index 7a0f690..c5341d3 100644 --- a/src/main/java/org/blue/club/entities/vo/PermissionVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/PermissionVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Table; @@ -8,7 +8,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Table("permission") @Data -public class PermissionVo extends BaseVo { +public class PermissionVo extends BaseDataVo { @Id private Long id; private String name; diff --git a/src/main/java/org/blue/club/entities/vo/UserVo.java b/src/main/java/org/blue/club/entities/vo/data/UserVo.java similarity index 92% rename from src/main/java/org/blue/club/entities/vo/UserVo.java rename to src/main/java/org/blue/club/entities/vo/data/UserVo.java index aab1e14..f3d9277 100644 --- a/src/main/java/org/blue/club/entities/vo/UserVo.java +++ b/src/main/java/org/blue/club/entities/vo/data/UserVo.java @@ -1,4 +1,4 @@ -package org.blue.club.entities.vo; +package org.blue.club.entities.vo.data; import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.RelationManyToOne; @@ -11,7 +11,7 @@ import org.mmga.spring.boot.starter.annotation.VoIgnore; @EqualsAndHashCode(callSuper = true) @Data @Table("user") -public class UserVo extends BaseVo { +public class UserVo extends BaseDataVo { @Id private Long id; private String name; diff --git a/src/main/java/org/blue/club/services/UserServices.java b/src/main/java/org/blue/club/services/UserServices.java index 4c2e9c4..148ee62 100644 --- a/src/main/java/org/blue/club/services/UserServices.java +++ b/src/main/java/org/blue/club/services/UserServices.java @@ -11,8 +11,9 @@ import org.blue.club.dao.redis.AvatarOperationDao; import org.blue.club.dao.redis.VerifyDao; import org.blue.club.entities.dto.User; import org.blue.club.entities.dto.req.*; -import org.blue.club.entities.vo.AvatarTmpVo; -import org.blue.club.entities.vo.UserVo; +import org.blue.club.entities.dto.resp.VerifyCodeResponse; +import org.blue.club.entities.vo.data.AvatarTmpVo; +import org.blue.club.entities.vo.data.UserVo; import org.blue.club.entities.vo.VerifyVo; import org.blue.club.utils.FileUtils; import org.mmga.spring.boot.starter.entities.PagerData; @@ -154,14 +155,30 @@ public class UserServices { if (byId.isEmpty()) return Result.failed(HttpStatus.NOT_FOUND, "操作码错误或过期"); AvatarTmpVo avatarTmpVo = byId.get(); File tmpFile = new File(tmpFolder, avatarOperationCode); - File targetFile = new File(avatarFolder, avatarTmpVo.sha1()); + String sha1 = avatarTmpVo.sha1(); + File targetFile = new File(avatarFolder, sha1); + Optional> booleanResult = changeAvatarFile(tmpFile, targetFile); + if (booleanResult.isPresent()) return booleanResult.get(); + avatarOperationDao.deleteById(avatarOperationCode); + UserVo userVo = new UserVo(); + userVo.setId(user.getId()); + userVo.setAvatar(user.getAvatar()); + userDao.update(userVo); + return Result.success(true); + } + + public Optional> changeAvatarFile(File tmpFile, File targetFile) { if (targetFile.exists()) { fileUtils.tryDeleteOrDeleteOnExit(targetFile); - return Result.success(true); + return Optional.empty(); } if (!tmpFile.renameTo(targetFile)) - return Result.failed(HttpStatus.INTERNAL_SERVER_ERROR, "移动头像文件失败!请联系管理员处理"); - // TODO 修改用户头像hash - return Result.success(); + return Optional.of(Result.failed(HttpStatus.INTERNAL_SERVER_ERROR, "移动头像文件失败!请联系管理员处理")); + return Optional.empty(); + } + + public Result getVerifyCode() { + + return null; } } diff --git a/src/main/java/org/blue/club/utils/VerifyCodeUtils.java b/src/main/java/org/blue/club/utils/VerifyCodeUtils.java new file mode 100644 index 0000000..be15011 --- /dev/null +++ b/src/main/java/org/blue/club/utils/VerifyCodeUtils.java @@ -0,0 +1,58 @@ +package org.blue.club.utils; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.apache.commons.codec.binary.Base64OutputStream; +import org.blue.club.dao.redis.VerifyDao; +import org.blue.club.entities.dto.resp.VerifyCodeResponse; +import org.blue.club.entities.vo.VerifyVo; +import org.mmga.spring.boot.starter.utils.RandomUtils; +import org.springframework.stereotype.Component; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.Random; + +@Component +@RequiredArgsConstructor +public class VerifyCodeUtils { + public static final int width = 120; + public static final int height = 40; + public static final int fontSize = 25; + public static final Font mainFont = new Font("宋体", Font.BOLD, fontSize); + + private final RandomUtils randomUtils; + private final VerifyDao verifyDao; + + @SneakyThrows + public VerifyCodeResponse generateVerifyCode() { + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics g = image.createGraphics(); + g.setFont(mainFont); + String text = randomUtils.generatorRandomFileName(4); + int x = 0; + for (char c : text.toCharArray()) { + Random random = new Random(); + g.setColor(new Color(20 + random.nextInt(120), 20 + random.nextInt(120), 20 + random.nextInt(120))); + g.drawString(c + "", 15 + x * 20, 20 + new Random().nextInt(10)); + for (int j = 0; j < random.nextInt(1, 5); j++) { + g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height)); + } + x++; + } + g.dispose(); + String s = randomUtils.generatorRandomString(32); + + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); Base64OutputStream base64OutputStream = new Base64OutputStream(byteArrayOutputStream)) { + ImageIO.write(image, "png", base64OutputStream); + base64OutputStream.flush(); + String base64 = byteArrayOutputStream.toString(StandardCharsets.UTF_8); + verifyDao.save(new VerifyVo(s, text, new Date())); + return new VerifyCodeResponse(base64, s); + } + } +}