-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
351 additions
and
2 deletions.
There are no files selected for viewing
39 changes: 39 additions & 0 deletions
39
tang-admin/src/main/java/com/tang/admin/controller/CaptchaController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.tang.admin.controller; | ||
|
||
import java.util.Base64; | ||
|
||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.tang.commons.constants.CachePrefix; | ||
import com.tang.commons.model.CaptchaModel; | ||
import com.tang.commons.utils.AjaxResult; | ||
import com.tang.commons.utils.RedisUtils; | ||
import com.tang.commons.utils.captcha.CaptchaType; | ||
import com.tang.commons.utils.captcha.CaptchaUtils; | ||
|
||
/** | ||
* 验证码逻辑控制层 | ||
* | ||
* @author Tang | ||
*/ | ||
@RestController | ||
@RequestMapping("/captcha") | ||
public class CaptchaController { | ||
|
||
private final RedisUtils redisUtils; | ||
|
||
public CaptchaController(RedisUtils redisUtils) { | ||
this.redisUtils = redisUtils; | ||
} | ||
|
||
@GetMapping | ||
public AjaxResult getCaptcha() { | ||
var captcha = CaptchaUtils.generate(CaptchaType.NUMBER); | ||
var base64 = Base64.getEncoder().encodeToString(captcha.getImage()); | ||
redisUtils.set(CachePrefix.CAPTCHA + captcha.getId(), captcha.getText(), 60); | ||
return AjaxResult.success(new CaptchaModel(captcha.getId(), base64)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
tang-commons/src/main/java/com/tang/commons/exception/CaptchaException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.tang.commons.exception; | ||
|
||
/** | ||
* 验证码异常 | ||
* | ||
* @author Tang | ||
*/ | ||
public class CaptchaException extends RuntimeException { | ||
|
||
@java.io.Serial | ||
private static final long serialVersionUID = 7891001344481580446L; | ||
|
||
public CaptchaException() { | ||
} | ||
|
||
public CaptchaException(String message) { | ||
super(message); | ||
} | ||
|
||
public CaptchaException(Throwable cause) { | ||
super(cause); | ||
} | ||
|
||
public CaptchaException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
tang-commons/src/main/java/com/tang/commons/model/CaptchaModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.tang.commons.model; | ||
|
||
import java.io.Serializable; | ||
|
||
/** | ||
* 验证码模型 | ||
* | ||
* @author Tang | ||
*/ | ||
public class CaptchaModel implements Serializable { | ||
|
||
@java.io.Serial | ||
private static final long serialVersionUID = 2521646489620204864L; | ||
|
||
/** | ||
* 验证码 ID | ||
*/ | ||
private Long id; | ||
|
||
/** | ||
* 验证码图片 | ||
*/ | ||
private String text; | ||
|
||
public CaptchaModel() { | ||
} | ||
|
||
public CaptchaModel(Long id, String text) { | ||
this.id = id; | ||
this.text = text; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public void setId(Long id) { | ||
this.id = id; | ||
} | ||
|
||
public String getText() { | ||
return text; | ||
} | ||
|
||
public void setText(String text) { | ||
this.text = text; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
tang-commons/src/main/java/com/tang/commons/utils/captcha/Captcha.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.tang.commons.utils.captcha; | ||
|
||
/** | ||
* 验证码模型 | ||
* | ||
* @author Tang | ||
*/ | ||
public class Captcha { | ||
|
||
/** | ||
* 验证码 ID | ||
*/ | ||
private Long id; | ||
|
||
/** | ||
* 答案 | ||
*/ | ||
private String text; | ||
|
||
/** | ||
* 图片 | ||
*/ | ||
private byte[] image; | ||
|
||
public Captcha() { | ||
} | ||
|
||
public Captcha(Long id, String text, byte[] image) { | ||
this.id = id; | ||
this.text = text; | ||
this.image = image; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public void setId(Long id) { | ||
this.id = id; | ||
} | ||
|
||
public String getText() { | ||
return text; | ||
} | ||
|
||
public void setText(String text) { | ||
this.text = text; | ||
} | ||
|
||
public byte[] getImage() { | ||
return image; | ||
} | ||
|
||
public void setImage(byte[] image) { | ||
this.image = image; | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
tang-commons/src/main/java/com/tang/commons/utils/captcha/CaptchaType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.tang.commons.utils.captcha; | ||
|
||
/** | ||
* @author Tang | ||
*/ | ||
public enum CaptchaType { | ||
|
||
/** | ||
* 数字 | ||
*/ | ||
NUMBER, | ||
|
||
/** | ||
* 字母(大小写敏感) | ||
*/ | ||
LETTER, | ||
|
||
/** | ||
* 字母(大小写不敏感) | ||
*/ | ||
LETTER_IGNORE_CASE, | ||
|
||
/** | ||
* 混合(大小写不敏感) | ||
*/ | ||
MIXED | ||
|
||
} |
111 changes: 111 additions & 0 deletions
111
tang-commons/src/main/java/com/tang/commons/utils/captcha/CaptchaUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package com.tang.commons.utils.captcha; | ||
|
||
import java.awt.Color; | ||
import java.awt.Font; | ||
import java.awt.image.BufferedImage; | ||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.util.Random; | ||
|
||
import javax.imageio.ImageIO; | ||
|
||
import org.slf4j.Logger; | ||
|
||
import com.tang.commons.utils.LogUtils; | ||
import com.tang.commons.utils.id.IdUtils; | ||
|
||
/** | ||
* 验证码工具类 | ||
* | ||
* @author Tang | ||
*/ | ||
public class CaptchaUtils { | ||
|
||
private CaptchaUtils() { | ||
} | ||
|
||
private static final Logger LOGGER = LogUtils.getLogger(); | ||
|
||
/** | ||
* 验证码图片宽度 | ||
*/ | ||
private static final int WIDTH = 130; | ||
|
||
/** | ||
* 验证码图片高度 | ||
*/ | ||
private static final int HEIGHT = 48; | ||
|
||
/** | ||
* 随机数 | ||
*/ | ||
private static final Random RANDOM = new Random(); | ||
|
||
/** | ||
* 验证码图片 | ||
*/ | ||
private static final BufferedImage BUFFERED_IMAGE = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); | ||
|
||
/** | ||
* 生成验证码 | ||
* | ||
* @param type 验证码类型 | ||
* @return 验证码 | ||
*/ | ||
public static Captcha generate(CaptchaType type) { | ||
final char[] characters = switch (type) { | ||
case NUMBER -> "0123456789".toCharArray(); | ||
case LETTER -> "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); | ||
case LETTER_IGNORE_CASE -> new char[0]; | ||
case MIXED -> new char[0]; | ||
}; | ||
|
||
var graphics = BUFFERED_IMAGE.getGraphics(); | ||
// 填充背景色 | ||
graphics.setColor(Color.WHITE); | ||
graphics.fillRect(0, 0, WIDTH, HEIGHT); | ||
// 绘制边框 | ||
graphics.setColor(Color.BLACK); | ||
graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1); | ||
// 绘制干扰线 | ||
graphics.setColor(Color.BLACK); | ||
for (int i = 0; i < 8; i++) { | ||
graphics.drawLine(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT), RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT)); | ||
} | ||
// 绘制干扰点 | ||
graphics.setColor(Color.BLACK); | ||
for (int i = 0; i < 6; i++) { | ||
graphics.drawOval(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT), RANDOM.nextInt(WIDTH / 2), RANDOM.nextInt(HEIGHT / 2)); | ||
} | ||
var captcha = new StringBuilder(); | ||
// 绘制验证码 | ||
for (int i = 0; i < 4; i++) { | ||
var character = characters[RANDOM.nextInt(characters.length)]; | ||
captcha.append(character); | ||
graphics.setColor(new Color(RANDOM.nextInt(255), RANDOM.nextInt(255), RANDOM.nextInt(255))); | ||
graphics.setFont(new Font("Arial", Font.BOLD, 30)); | ||
graphics.drawString(String.valueOf(character), 20 + i * 30, 35); | ||
} | ||
graphics.dispose(); | ||
|
||
return new Captcha(IdUtils.snowflake(), captcha.toString(), toByteArray()); | ||
} | ||
|
||
/** | ||
* 将验证码图片转换为字节数组 | ||
* | ||
* @return 字节数组 | ||
*/ | ||
private static byte[] toByteArray() { | ||
try (var byteArrayOutputStream = new ByteArrayOutputStream()) { | ||
ImageIO.write(BUFFERED_IMAGE, "png", byteArrayOutputStream); | ||
return byteArrayOutputStream.toByteArray(); | ||
} catch (IOException e) { | ||
LOGGER.error("生成验证码失败", e); | ||
return new byte[0]; | ||
} finally { | ||
BUFFERED_IMAGE.flush(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.