feat:验证码(通用数字字母验证码)开发
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package com.xiang.xservice.auth.service.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CaptchaTypeEnum {
|
||||
|
||||
NORMAL_CAPTCHA_IMAGE(1, "图形验证码"),
|
||||
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
|
||||
private final String desc;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.xiang.xservice.auth.service.service;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.xiang.xservice.auth.service.enums.CaptchaTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Component
|
||||
public class CaptchaGenerateFactory {
|
||||
|
||||
private final Map<Integer, ICaptchaService> strategies = Maps.newConcurrentMap();
|
||||
|
||||
public CaptchaGenerateFactory(List<ICaptchaService> strategyList) {
|
||||
for (ICaptchaService captchaService : strategyList) {
|
||||
strategies.put(captchaService.getCaptchaType().getType(), captchaService);
|
||||
}
|
||||
}
|
||||
|
||||
public ICaptchaService get(Integer type) {
|
||||
if (Objects.isNull(type)) {
|
||||
return strategies.get(CaptchaTypeEnum.NORMAL_CAPTCHA_IMAGE.getType());
|
||||
}
|
||||
return strategies.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.xiang.xservice.auth.service.service;
|
||||
|
||||
import com.xiang.xservice.auth.service.enums.CaptchaTypeEnum;
|
||||
|
||||
public interface ICaptchaService {
|
||||
|
||||
String getCaptchaImage();
|
||||
|
||||
CaptchaTypeEnum getCaptchaType();
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.xiang.xservice.auth.service.service.impl.captcha;
|
||||
|
||||
import com.xiang.xservice.auth.service.enums.CaptchaTypeEnum;
|
||||
import com.xiang.xservice.auth.service.service.ICaptchaService;
|
||||
import com.xiang.xservice.basic.utils.RandomCodeUtils;
|
||||
import com.xiang.xservice.cache.service.IRedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.Random;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class NormalCaptchaImage implements ICaptchaService {
|
||||
|
||||
private final IRedisService redisService;
|
||||
private static final Random random = new Random();
|
||||
|
||||
private static final int WIDTH = 160;// 宽
|
||||
private static final int HEIGHT = 40;// 高
|
||||
private static final int LINE_SIZE = 30;// 干扰线数量
|
||||
private static final int STRING_NUMBER = 4;//随机产生字符的个数
|
||||
|
||||
|
||||
@Override
|
||||
public String getCaptchaImage() {
|
||||
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
|
||||
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);
|
||||
Graphics g = image.getGraphics();
|
||||
g.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
g.setColor(getRandomColor(105, 189));
|
||||
g.setFont(getFont());
|
||||
|
||||
// 绘制干扰线
|
||||
for (int i = 0; i < LINE_SIZE; i++) {
|
||||
drawLine(g);
|
||||
}
|
||||
String randomCode = "";
|
||||
// 绘制随机字符
|
||||
for (int i = 0; i < STRING_NUMBER; i++) {
|
||||
randomCode = drawString(g, randomCode, i);
|
||||
}
|
||||
log.info("生成的随机验证码:{}", randomCode);
|
||||
g.dispose();
|
||||
|
||||
String base64String = "";
|
||||
//返回 base64
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "PNG", bos);
|
||||
|
||||
byte[] bytes = bos.toByteArray();
|
||||
Base64.Encoder encoder = Base64.getEncoder();
|
||||
base64String = encoder.encodeToString(bytes);
|
||||
return base64String;
|
||||
} catch (IOException e) {
|
||||
log.error("IO异常,验证码异常", e);
|
||||
}
|
||||
return base64String;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaptchaTypeEnum getCaptchaType() {
|
||||
return CaptchaTypeEnum.NORMAL_CAPTCHA_IMAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字体
|
||||
*/
|
||||
private Font getFont() {
|
||||
return new Font("Times New Roman", Font.PLAIN, 40);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取颜色
|
||||
*/
|
||||
private static Color getRandomColor(int fc, int bc) {
|
||||
|
||||
fc = Math.min(fc, 255);
|
||||
bc = Math.min(bc, 255);
|
||||
|
||||
int r = fc + random.nextInt(bc - fc - 16);
|
||||
int g = fc + random.nextInt(bc - fc - 14);
|
||||
int b = fc + random.nextInt(bc - fc - 12);
|
||||
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制干扰线
|
||||
*/
|
||||
private void drawLine(Graphics g) {
|
||||
int x = random.nextInt(WIDTH);
|
||||
int y = random.nextInt(HEIGHT);
|
||||
int xl = random.nextInt(20);
|
||||
int yl = random.nextInt(10);
|
||||
g.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制字符串
|
||||
*/
|
||||
private String drawString(Graphics g, String randomStr, int i) {
|
||||
g.setFont(getFont());
|
||||
g.setColor(getRandomColor(108, 190));
|
||||
String rand = RandomCodeUtils.getMixtureRandomCode(1);
|
||||
randomStr += rand;
|
||||
g.translate(random.nextInt(3), random.nextInt(6));
|
||||
g.drawString(rand, 40 * i + 10, 25);
|
||||
return randomStr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="update_by" property="updateBy" />
|
||||
<result column="update_time" property="updateTime" />
|
||||
<result column="tenant_id" property="tenantId"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
@@ -36,7 +37,8 @@
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time
|
||||
update_time,
|
||||
tenant_id
|
||||
</sql>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="com.xiang.xservice.auth.service.entity.XUser">
|
||||
@@ -82,7 +84,10 @@
|
||||
update_by,
|
||||
</if>
|
||||
<if test="null != updateTime ">
|
||||
update_time
|
||||
update_time,
|
||||
</if>
|
||||
<if test="tenantId != null">
|
||||
tenant_id
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
@@ -126,14 +131,17 @@
|
||||
#{updateBy},
|
||||
</if>
|
||||
<if test="null != updateTime ">
|
||||
#{updateTime}
|
||||
#{updateTime},
|
||||
</if>
|
||||
<if test="tenantId != null">
|
||||
#{tenantId}
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<insert id="insertBatch">
|
||||
insert into x_user(name, username, password, email, phone, status) VALUES
|
||||
insert into x_user(name, username, password, email, phone, status, tenant_id) VALUES
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.name}, #{item.username}, #{item.password}, #{item.email}, #{item.phone}, #{item.status})
|
||||
(#{item.name}, #{item.username}, #{item.password}, #{item.email}, #{item.phone}, #{item.status}, #{item.tenantId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
@@ -156,7 +164,8 @@
|
||||
<if test="null != createBy and '' != createBy">create_by = #{createBy},</if>
|
||||
<if test="null != createTime ">create_time = #{createTime},</if>
|
||||
<if test="null != updateBy and '' != updateBy">update_by = #{updateBy},</if>
|
||||
<if test="null != updateTime ">update_time = #{updateTime}</if>
|
||||
<if test="null != updateTime ">update_time = #{updateTime},</if>
|
||||
<if test="null != tenantId ">tenant_id = #{tenantId}</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
Reference in New Issue
Block a user