pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-framework/pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-ui/src/views/login.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
pom.xml
@@ -21,6 +21,7 @@ <druid.version>1.1.14</druid.version> <bitwalker.version>1.19</bitwalker.version> <swagger.version>2.9.2</swagger.version> <kaptcha.version>2.3.2</kaptcha.version> <pagehelper.boot.version>1.2.5</pagehelper.boot.version> <fastjson.version>1.2.70</fastjson.version> <oshi.version>3.9.1</oshi.version> @@ -137,6 +138,13 @@ <artifactId>jjwt</artifactId> <version>${jwt.version}</version> </dependency> <!--验证码 --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>${kaptcha.version}</version> </dependency> <!-- 定时任务--> <dependency> ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -1,16 +1,20 @@ package com.ruoyi.web.controller.common; import java.io.ByteArrayOutputStream; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.FastByteArrayOutputStream; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.google.code.kaptcha.Producer; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.VerifyCodeUtils; import com.ruoyi.common.utils.sign.Base64; import com.ruoyi.common.utils.uuid.IdUtils; @@ -22,8 +26,18 @@ @RestController public class CaptchaController { @Resource(name = "captchaProducer") private Producer captchaProducer; @Resource(name = "captchaProducerMath") private Producer captchaProducerMath; @Autowired private RedisCache redisCache; // 验证码类型 @Value("${ruoyi.captchaType}") private String captchaType; /** * 生成验证码 @@ -31,32 +45,42 @@ @GetMapping("/captchaImage") public AjaxResult getCode(HttpServletResponse response) throws IOException { // 生成随机字串 String verifyCode = VerifyCodeUtils.generateVerifyCode(4); // 唯一标识 // 保存验证码信息 String uuid = IdUtils.simpleUUID(); String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; redisCache.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // 生成图片 int w = 111, h = 36; ByteArrayOutputStream stream = new ByteArrayOutputStream(); VerifyCodeUtils.outputImage(w, h, stream, verifyCode); String capStr = null, code = null; BufferedImage image = null; // 生成验证码 if ("math".equals(captchaType)) { String capText = captchaProducerMath.createText(); capStr = capText.substring(0, capText.lastIndexOf("@")); code = capText.substring(capText.lastIndexOf("@") + 1); image = captchaProducerMath.createImage(capStr); } else if ("char".equals(captchaType)) { capStr = code = captchaProducer.createText(); image = captchaProducer.createImage(capStr); } redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // 转换流信息写出 FastByteArrayOutputStream os = new FastByteArrayOutputStream(); try { AjaxResult ajax = AjaxResult.success(); ajax.put("uuid", uuid); ajax.put("img", Base64.encode(stream.toByteArray())); return ajax; ImageIO.write(image, "jpg", os); } catch (Exception e) catch (IOException e) { e.printStackTrace(); return AjaxResult.error(e.getMessage()); } finally { stream.close(); } AjaxResult ajax = AjaxResult.success(); ajax.put("uuid", uuid); ajax.put("img", Base64.encode(os.toByteArray())); return ajax; } } ruoyi-admin/src/main/resources/application.yml
@@ -12,6 +12,8 @@ profile: D:/ruoyi/uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: char # 开发环境配置 server: ruoyi-framework/pom.xml
@@ -35,6 +35,18 @@ <artifactId>druid-spring-boot-starter</artifactId> </dependency> <!-- 验证码 --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <exclusions> <exclusion> <artifactId>javax.servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion> </exclusions> </dependency> <!-- 获取系统信息 --> <dependency> <groupId>com.github.oshi</groupId> ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java
对比新文件 @@ -0,0 +1,83 @@ package com.ruoyi.framework.config; import java.util.Properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import static com.google.code.kaptcha.Constants.*; /** * 验证码配置 * * @author ruoyi */ @Configuration public class CaptchaConfig { @Bean(name = "captchaProducer") public DefaultKaptcha getKaptchaBean() { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); // 是否有边框 默认为true 我们可以自己设置yes,no properties.setProperty(KAPTCHA_BORDER, "yes"); // 验证码文本字符颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); // 验证码图片宽度 默认为200 properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); // 验证码图片高度 默认为50 properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); // 验证码文本字符大小 默认为40 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); // KAPTCHA_SESSION_KEY properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); // 验证码文本字符长度 默认为5 properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } @Bean(name = "captchaProducerMath") public DefaultKaptcha getKaptchaBeanMath() { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); // 是否有边框 默认为true 我们可以自己设置yes,no properties.setProperty(KAPTCHA_BORDER, "yes"); // 边框颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); // 验证码文本字符颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); // 验证码图片宽度 默认为200 properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); // 验证码图片高度 默认为50 properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); // 验证码文本字符大小 默认为40 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); // KAPTCHA_SESSION_KEY properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); // 验证码文本生成器 properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.framework.config.KaptchaTextCreator"); // 验证码文本字符间距 默认为2 properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); // 验证码文本字符长度 默认为5 properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); // 验证码噪点颜色 默认为Color.BLACK properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); // 干扰实现类 properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); Config config = new Config(properties); defaultKaptcha.setConfig(config); return defaultKaptcha; } } ruoyi-framework/src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java
对比新文件 @@ -0,0 +1,75 @@ package com.ruoyi.framework.config; import java.util.Random; import com.google.code.kaptcha.text.impl.DefaultTextCreator; /** * 验证码文本生成器 * * @author ruoyi */ public class KaptchaTextCreator extends DefaultTextCreator { private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); @Override public String getText() { Integer result = 0; Random random = new Random(); int x = random.nextInt(10); int y = random.nextInt(10); StringBuilder suChinese = new StringBuilder(); int randomoperands = (int) Math.round(Math.random() * 2); if (randomoperands == 0) { result = x * y; suChinese.append(CNUMBERS[x]); suChinese.append("*"); suChinese.append(CNUMBERS[y]); } else if (randomoperands == 1) { if (!(x == 0) && y % x == 0) { result = y / x; suChinese.append(CNUMBERS[y]); suChinese.append("/"); suChinese.append(CNUMBERS[x]); } else { result = x + y; suChinese.append(CNUMBERS[x]); suChinese.append("+"); suChinese.append(CNUMBERS[y]); } } else if (randomoperands == 2) { if (x >= y) { result = x - y; suChinese.append(CNUMBERS[x]); suChinese.append("-"); suChinese.append(CNUMBERS[y]); } else { result = y - x; suChinese.append(CNUMBERS[y]); suChinese.append("-"); suChinese.append(CNUMBERS[x]); } } else { result = x + y; suChinese.append(CNUMBERS[x]); suChinese.append("+"); suChinese.append(CNUMBERS[y]); } suChinese.append("=?@" + result); return suChinese.toString(); } } ruoyi-ui/src/views/login.vue
@@ -29,7 +29,7 @@ <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> </el-input> <div class="login-code"> <img :src="codeUrl" @click="getCode" /> <img :src="codeUrl" @click="getCode" class="login-code-img"/> </div> </el-form-item> <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> @@ -200,4 +200,7 @@ font-size: 12px; letter-spacing: 1px; } .login-code-img { height: 38px; } </style>