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="create_time" property="createTime" />
|
||||||
<result column="update_by" property="updateBy" />
|
<result column="update_by" property="updateBy" />
|
||||||
<result column="update_time" property="updateTime" />
|
<result column="update_time" property="updateTime" />
|
||||||
|
<result column="tenant_id" property="tenantId"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
@@ -36,7 +37,8 @@
|
|||||||
create_by,
|
create_by,
|
||||||
create_time,
|
create_time,
|
||||||
update_by,
|
update_by,
|
||||||
update_time
|
update_time,
|
||||||
|
tenant_id
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="com.xiang.xservice.auth.service.entity.XUser">
|
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id" parameterType="com.xiang.xservice.auth.service.entity.XUser">
|
||||||
@@ -82,7 +84,10 @@
|
|||||||
update_by,
|
update_by,
|
||||||
</if>
|
</if>
|
||||||
<if test="null != updateTime ">
|
<if test="null != updateTime ">
|
||||||
update_time
|
update_time,
|
||||||
|
</if>
|
||||||
|
<if test="tenantId != null">
|
||||||
|
tenant_id
|
||||||
</if>
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
@@ -126,14 +131,17 @@
|
|||||||
#{updateBy},
|
#{updateBy},
|
||||||
</if>
|
</if>
|
||||||
<if test="null != updateTime ">
|
<if test="null != updateTime ">
|
||||||
#{updateTime}
|
#{updateTime},
|
||||||
|
</if>
|
||||||
|
<if test="tenantId != null">
|
||||||
|
#{tenantId}
|
||||||
</if>
|
</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertBatch">
|
<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=",">
|
<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>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -156,7 +164,8 @@
|
|||||||
<if test="null != createBy and '' != createBy">create_by = #{createBy},</if>
|
<if test="null != createBy and '' != createBy">create_by = #{createBy},</if>
|
||||||
<if test="null != createTime ">create_time = #{createTime},</if>
|
<if test="null != createTime ">create_time = #{createTime},</if>
|
||||||
<if test="null != updateBy and '' != updateBy">update_by = #{updateBy},</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>
|
</set>
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
Reference in New Issue
Block a user