diff --git a/pom.xml b/pom.xml index 2a8521c46..40acc5618 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,7 @@ 3.15.2 2.2.1 3.4.0 + 1.2.8 @@ -181,6 +182,13 @@ ${ruoyi-vue-plus.version} + + + com.anji-plus + spring-boot-starter-captcha + ${captcha.version} + + diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 031427fc0..4834ef6f0 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -54,6 +54,12 @@ ruoyi-demo + + + com.anji-plus + spring-boot-starter-captcha + + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java deleted file mode 100644 index 2f303ba95..000000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.ruoyi.web.controller.common; - -import cn.hutool.captcha.AbstractCaptcha; -import cn.hutool.captcha.CircleCaptcha; -import cn.hutool.captcha.LineCaptcha; -import cn.hutool.captcha.ShearCaptcha; -import cn.hutool.captcha.generator.CodeGenerator; -import cn.hutool.captcha.generator.RandomGenerator; -import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.framework.captcha.UnsignedMathGenerator; -import com.ruoyi.framework.config.properties.CaptchaProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * 验证码操作处理 - * - * @author Lion Li - */ -@RestController -public class CaptchaController { - - // 圆圈干扰验证码 - @Resource(name = "CircleCaptcha") - private CircleCaptcha circleCaptcha; - // 线段干扰的验证码 - @Resource(name = "LineCaptcha") - private LineCaptcha lineCaptcha; - // 扭曲干扰验证码 - @Resource(name = "ShearCaptcha") - private ShearCaptcha shearCaptcha; - - @Autowired - private RedisCache redisCache; - - @Autowired - private CaptchaProperties captchaProperties; - - /** - * 生成验证码 - */ - @GetMapping("/captchaImage") - public AjaxResult getCode() { - Map ajax = new HashMap<>(); - Boolean enabled = captchaProperties.getEnabled(); - ajax.put("enabled", enabled); - if (!enabled) { - return AjaxResult.success(ajax); - } - // 保存验证码信息 - String uuid = IdUtil.simpleUUID(); - String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String code = null; - // 生成验证码 - CodeGenerator codeGenerator; - AbstractCaptcha captcha; - switch (captchaProperties.getType()) { - case "math": - codeGenerator = new UnsignedMathGenerator(captchaProperties.getNumberLength()); - break; - case "char": - codeGenerator = new RandomGenerator(captchaProperties.getCharLength()); - break; - default: - throw new IllegalArgumentException("验证码类型异常"); - } - switch (captchaProperties.getCategory()) { - case "line": - captcha = lineCaptcha; - break; - case "circle": - captcha = circleCaptcha; - break; - case "shear": - captcha = shearCaptcha; - break; - default: - throw new IllegalArgumentException("验证码类别异常"); - } - captcha.setGenerator(codeGenerator); - captcha.createCode(); - if ("math".equals(captchaProperties.getType())) { - code = getCodeResult(captcha.getCode()); - } else if ("char".equals(captchaProperties.getType())) { - code = captcha.getCode(); - } - redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); - ajax.put("uuid", uuid); - ajax.put("img", captcha.getImageBase64()); - return AjaxResult.success(ajax); - } - - private String getCodeResult(String capStr) { - int numberLength = captchaProperties.getNumberLength(); - int a = Convert.toInt(StrUtil.sub(capStr, 0, numberLength).trim()); - char operator = capStr.charAt(numberLength); - int b = Convert.toInt(StrUtil.sub(capStr, numberLength + 1, numberLength + 1 + numberLength).trim()); - switch (operator) { - case '*': - return a * b + ""; - case '+': - return a + b + ""; - case '-': - return a - b + ""; - default: - return ""; - } - } - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index b2b9efb3d..f7ad819dc 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -1,11 +1,15 @@ package com.ruoyi.web.controller.system; +import com.anji.captcha.model.common.ResponseModel; +import com.anji.captcha.model.vo.CaptchaVO; +import com.anji.captcha.service.CaptchaService; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.exception.BaseException; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.framework.web.service.SysLoginService; import com.ruoyi.framework.web.service.SysPermissionService; @@ -17,10 +21,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * 登录验证 @@ -28,70 +29,74 @@ import java.util.Set; * @author ruoyi */ @RestController -public class SysLoginController -{ - @Autowired - private SysLoginService loginService; +public class SysLoginController { + @Autowired + private SysLoginService loginService; - @Autowired - private ISysMenuService menuService; + @Autowired + private ISysMenuService menuService; - @Autowired - private SysPermissionService permissionService; + @Autowired + private SysPermissionService permissionService; - @Autowired - private TokenService tokenService; + @Autowired + private TokenService tokenService; - /** - * 登录方法 - * - * @param loginBody 登录信息 - * @return 结果 - */ - @PostMapping("/login") - public AjaxResult login(@RequestBody LoginBody loginBody) - { - Map ajax = new HashMap<>(); - // 生成令牌 - String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), - loginBody.getUuid()); - ajax.put(Constants.TOKEN, token); - return AjaxResult.success(ajax); - } + @Autowired + private CaptchaService captchaService; - /** - * 获取用户信息 - * - * @return 用户信息 - */ - @GetMapping("getInfo") - public AjaxResult getInfo() - { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); - SysUser user = loginUser.getUser(); - // 角色集合 - Set roles = permissionService.getRolePermission(user); - // 权限集合 - Set permissions = permissionService.getMenuPermission(user); - Map ajax = new HashMap<>(); - ajax.put("user", user); - ajax.put("roles", roles); - ajax.put("permissions", permissions); - return AjaxResult.success(ajax); - } + /** + * 登录方法 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) { + CaptchaVO vo = new CaptchaVO(); + vo.setCaptchaVerification(loginBody.getCode()); + ResponseModel verification = captchaService.verification(vo); + if (!Objects.equals("0000", verification.getRepCode())) { + throw new BaseException("验证码校验失败!"); + } + // 生成令牌 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword()); + Map result = new HashMap<>(); + result.put(Constants.TOKEN, token); + return AjaxResult.success(result); + } - /** - * 获取路由信息 - * - * @return 路由信息 - */ - @GetMapping("getRouters") - public AjaxResult getRouters() - { - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); - // 用户信息 - SysUser user = loginUser.getUser(); - List menus = menuService.selectMenuTreeByUserId(user.getUserId()); - return AjaxResult.success(menuService.buildMenus(menus)); - } + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + SysUser user = loginUser.getUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + Map ajax = new HashMap<>(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + return AjaxResult.success(ajax); + } + + /** + * 获取路由信息 + * + * @return 路由信息 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + // 用户信息 + SysUser user = loginUser.getUser(); + List menus = menuService.selectMenuTreeByUserId(user.getUserId()); + return AjaxResult.success(menuService.buildMenus(menus)); + } } diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index e153d1948..9f5d66be3 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -13,17 +13,26 @@ ruoyi: # 获取ip地址开关 addressEnabled: true -captcha: - # 验证码开关 - enabled: true - # 验证码类型 math 数组计算 char 字符验证 - type: math - # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 - category: circle - # 数字验证码位数 - numberLength: 1 - # 字符验证码长度 - charLength: 4 +aj: + captcha: + jigsaw: classpath:images/jigsaw + pic-click: classpath:images/pic-click + cache-type: local + type: default + water-mark: 美甲啦 + slip-offset: 5 + aes-status: true + interference-options: 2 + history-data-clear-enable: true + req-frequency-limit-enable: true + req-get-lock-limit: 5 + req-get-lock-seconds: 360 + # get接口一分钟内请求数限制 + req-get-minute-limit: 30 + # check接口一分钟内请求数限制 + req-check-minute-limit: 60 + # verify接口一分钟内请求数限制 + req-verify-minute-limit: 60 # 开发环境配置 server: diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg1.png b/ruoyi-admin/src/main/resources/images.pic-click/bg1.png new file mode 100644 index 000000000..51573a0c4 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg1.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg10.png b/ruoyi-admin/src/main/resources/images.pic-click/bg10.png new file mode 100644 index 000000000..f633aeed2 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg10.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg2.png b/ruoyi-admin/src/main/resources/images.pic-click/bg2.png new file mode 100644 index 000000000..909dc39ef Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg2.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg3.png b/ruoyi-admin/src/main/resources/images.pic-click/bg3.png new file mode 100644 index 000000000..59bc59c0b Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg3.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg4.png b/ruoyi-admin/src/main/resources/images.pic-click/bg4.png new file mode 100644 index 000000000..c856f4d97 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg4.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg5.png b/ruoyi-admin/src/main/resources/images.pic-click/bg5.png new file mode 100644 index 000000000..4594fcf65 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg5.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg6.png b/ruoyi-admin/src/main/resources/images.pic-click/bg6.png new file mode 100644 index 000000000..0f28d820b Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg6.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg7.png b/ruoyi-admin/src/main/resources/images.pic-click/bg7.png new file mode 100644 index 000000000..1e0449297 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg7.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg8.png b/ruoyi-admin/src/main/resources/images.pic-click/bg8.png new file mode 100644 index 000000000..f11545fd3 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg8.png differ diff --git a/ruoyi-admin/src/main/resources/images.pic-click/bg9.png b/ruoyi-admin/src/main/resources/images.pic-click/bg9.png new file mode 100644 index 000000000..2f3a86dab Binary files /dev/null and b/ruoyi-admin/src/main/resources/images.pic-click/bg9.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg1.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg1.png new file mode 100644 index 000000000..4cde9dc04 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg1.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg2.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg2.png new file mode 100644 index 000000000..93b70d4c4 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg2.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg3.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg3.png new file mode 100644 index 000000000..f60f7b735 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg3.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg4.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg4.png new file mode 100644 index 000000000..9bd65ef53 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg4.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg5.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg5.png new file mode 100644 index 000000000..13585062a Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg5.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg6.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg6.png new file mode 100644 index 000000000..0ea2b377d Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg6.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg7.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg7.png new file mode 100644 index 000000000..8c05e9c33 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg7.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg8.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg8.png new file mode 100644 index 000000000..bcd00c73c Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg8.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/original/bg9.png b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg9.png new file mode 100644 index 000000000..b74f704c2 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/original/bg9.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/1.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/1.png new file mode 100644 index 000000000..d6b975b57 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/1.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/10.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/10.png new file mode 100644 index 000000000..7cec5028c Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/10.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/11.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/11.png new file mode 100644 index 000000000..4f6133786 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/11.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/12.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/12.png new file mode 100644 index 000000000..a7827fdab Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/12.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/13.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/13.png new file mode 100644 index 000000000..9f7d813d7 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/13.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/14.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/14.png new file mode 100644 index 000000000..9abec8a73 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/14.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/15.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/15.png new file mode 100644 index 000000000..3fffdfcd2 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/15.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/16.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/16.png new file mode 100644 index 000000000..f5944a0dc Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/16.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/17.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/17.png new file mode 100644 index 000000000..e17c4fa06 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/17.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/18.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/18.png new file mode 100644 index 000000000..5d0f9097c Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/18.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/19.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/19.png new file mode 100644 index 000000000..6b39d72d9 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/19.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/8.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/8.png new file mode 100644 index 000000000..3754bee0e Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/8.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/9.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/9.png new file mode 100644 index 000000000..ff36a2156 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/9.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/1.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/1.png new file mode 100644 index 000000000..369ed871e Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/1.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/2.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/2.png new file mode 100644 index 000000000..adec30f91 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/2.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/3.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/3.png new file mode 100644 index 000000000..69324725e Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/3.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/4.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/4.png new file mode 100644 index 000000000..abfa4fdcd Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/4.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/5.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/5.png new file mode 100644 index 000000000..77105ac5a Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/5.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/6.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/6.png new file mode 100644 index 000000000..7c90bd772 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/6.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/7.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/7.png new file mode 100644 index 000000000..9c6862d9e Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/11/xin替换/7.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/2.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/2.png new file mode 100644 index 000000000..b1482d48b Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/2.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/3.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/3.png new file mode 100644 index 000000000..cdbb0b18c Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/3.png differ diff --git a/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/4.png b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/4.png new file mode 100644 index 000000000..bc69c9622 Binary files /dev/null and b/ruoyi-admin/src/main/resources/images/jigsaw/slidingBlock/4.png differ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java deleted file mode 100644 index b4f8bfc12..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/captcha/UnsignedMathGenerator.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.ruoyi.framework.captcha; - -import cn.hutool.captcha.generator.CodeGenerator; -import cn.hutool.core.math.Calculator; -import cn.hutool.core.util.CharUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.StrUtil; - -/** - * 无符号计算生成器 - * - * @author Lion Li - */ -public class UnsignedMathGenerator implements CodeGenerator { - - private static final long serialVersionUID = -5514819971774091076L; - - private static final String operators = "+-*"; - - /** - * 参与计算数字最大长度 - */ - private final int numberLength; - - /** - * 构造 - */ - public UnsignedMathGenerator() { - this(2); - } - - /** - * 构造 - * - * @param numberLength 参与计算最大数字位数 - */ - public UnsignedMathGenerator(int numberLength) { - this.numberLength = numberLength; - } - - @Override - public String generate() { - final int limit = getLimit(); - int min = RandomUtil.randomInt(limit); - int max = RandomUtil.randomInt(min, limit); - String number1 = Integer.toString(max); - String number2 = Integer.toString(min); - number1 = StrUtil.padAfter(number1, this.numberLength, CharUtil.SPACE); - number2 = StrUtil.padAfter(number2, this.numberLength, CharUtil.SPACE); - - return number1 + RandomUtil.randomChar(operators) + number2 + '='; - } - - @Override - public boolean verify(String code, String userInputCode) { - int result; - try { - result = Integer.parseInt(userInputCode); - } catch (NumberFormatException e) { - // 用户输入非数字 - return false; - } - - final int calculateResult = (int) Calculator.conversion(code); - return result == calculateResult; - } - - /** - * 获取验证码长度 - * - * @return 验证码长度 - */ - public int getLength() { - return this.numberLength * 2 + 2; - } - - /** - * 根据长度获取参与计算数字最大值 - * - * @return 最大值 - */ - private int getLimit() { - return Integer.parseInt("1" + StrUtil.repeat('0', this.numberLength)); - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java deleted file mode 100644 index 4cd99970c..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/CaptchaConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.ruoyi.framework.config; - -import java.awt.*; - -import cn.hutool.captcha.*; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * 验证码配置 - * - * @author Lion Li - */ -@Configuration -public class CaptchaConfig { - - private final int width = 160; - private final int height = 60; - private final Color background = Color.PINK; - private final Font font = new Font("Arial", Font.BOLD, 48); - - /** - * 圆圈干扰验证码 - */ - @Bean(name = "CircleCaptcha") - public CircleCaptcha getCircleCaptcha() { - CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height); - captcha.setBackground(background); - captcha.setFont(font); - return captcha; - } - - /** - * 线段干扰的验证码 - */ - @Bean(name = "LineCaptcha") - public LineCaptcha getLineCaptcha() { - LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height); - captcha.setBackground(background); - captcha.setFont(font); - return captcha; - } - - /** - * 扭曲干扰验证码 - */ - @Bean(name = "ShearCaptcha") - public ShearCaptcha getShearCaptcha() { - ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height); - captcha.setBackground(background); - captcha.setFont(font); - return captcha; - } - -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 79ade7879..078ca0247 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -101,7 +101,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter // 过滤请求 .authorizeRequests() // 对于登录login 验证码captchaImage 允许匿名访问 - .antMatchers("/login", "/captchaImage").anonymous() + .antMatchers("/login", "/captcha/get", "/captcha/check").anonymous() .antMatchers( HttpMethod.GET, "/*.html", diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java deleted file mode 100644 index 86ac70606..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/CaptchaProperties.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ruoyi.framework.config.properties; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -/** - * 验证码 配置属性 - * - * @author Lion Li - */ -@Data -@Component -@ConfigurationProperties(prefix = "captcha") -public class CaptchaProperties { - - /** - * 验证码开关 - */ - private Boolean enabled; - - /** - * 验证码类型 - */ - private String type; - - /** - * 验证码类别 - */ - private String category; - - /** - * 数字验证码位数 - */ - private Integer numberLength; - - /** - * 字符验证码长度 - */ - private Integer charLength; -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index d0b9511ea..e98fd3c76 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -5,13 +5,10 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.CustomException; -import com.ruoyi.common.exception.user.CaptchaException; -import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.framework.config.properties.CaptchaProperties; import com.ruoyi.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; @@ -29,87 +26,63 @@ import javax.servlet.http.HttpServletRequest; * @author ruoyi */ @Component -public class SysLoginService -{ - @Autowired - private TokenService tokenService; +public class SysLoginService { + @Autowired + private TokenService tokenService; - @Resource - private AuthenticationManager authenticationManager; - - @Autowired - private RedisCache redisCache; + @Resource + private AuthenticationManager authenticationManager; @Autowired - private CaptchaProperties captchaProperties; + private RedisCache redisCache; + +/* @Autowired + private CaptchaProperties captchaProperties;*/ @Autowired - private ISysUserService userService; + private ISysUserService userService; @Autowired private AsyncService asyncService; - /** - * 登录验证 - * - * @param username 用户名 - * @param password 密码 - * @param code 验证码 - * @param uuid 唯一标识 - * @return 结果 - */ - public String login(String username, String password, String code, String uuid) - { + /** + * 登录验证 + * + * @param username 用户名 + * @param password 密码 + * @return 结果 + */ + public String login(String username, String password) { HttpServletRequest request = ServletUtils.getRequest(); - if(captchaProperties.getEnabled()) { - String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String captcha = redisCache.getCacheObject(verifyKey); - redisCache.deleteObject(verifyKey); - if (captcha == null) { - asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request); - throw new CaptchaExpireException(); - } - if (!code.equalsIgnoreCase(captcha)) { - asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"), request); - throw new CaptchaException(); + // 用户验证 + Authentication authentication; + try { + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager + .authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } catch (Exception e) { + if (e instanceof BadCredentialsException) { + asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"), request); + throw new UserPasswordNotMatchException(); + } else { + asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage(), request); + throw new CustomException(e.getMessage()); } } - // 用户验证 - Authentication authentication = null; - try - { - // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername - authentication = authenticationManager - .authenticate(new UsernamePasswordAuthenticationToken(username, password)); - } - catch (Exception e) - { - if (e instanceof BadCredentialsException) - { - asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"), request); - throw new UserPasswordNotMatchException(); - } - else - { - asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage(), request); - throw new CustomException(e.getMessage()); - } - } asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request); - LoginUser loginUser = (LoginUser) authentication.getPrincipal(); - recordLoginInfo(loginUser.getUser()); - // 生成token - return tokenService.createToken(loginUser); - } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUser()); + // 生成token + return tokenService.createToken(loginUser); + } - /** - * 记录登录信息 - */ - public void recordLoginInfo(SysUser user) - { - user.setLoginIp(ServletUtils.getClientIP()); - user.setLoginDate(DateUtils.getNowDate()); + /** + * 记录登录信息 + */ + public void recordLoginInfo(SysUser user) { + user.setLoginIp(ServletUtils.getClientIP()); + user.setLoginDate(DateUtils.getNowDate()); user.setUpdateBy(user.getUserName()); - userService.updateUserProfile(user); - } + userService.updateUserProfile(user); + } } diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index af8db7e87..d1024758d 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -40,6 +40,7 @@ "axios": "0.21.0", "clipboard": "2.0.6", "core-js": "3.8.1", + "crypto-js": "^4.0.0", "echarts": "4.9.0", "element-ui": "2.15.2", "file-saver": "2.0.4", @@ -50,6 +51,7 @@ "jsencrypt": "3.0.0-rc.1", "nprogress": "0.2.0", "quill": "1.3.7", + "quill-image-super-solution-module": "^2.0.0", "screenfull": "5.0.2", "sortablejs": "1.10.2", "vue": "2.6.12", diff --git a/ruoyi-ui/src/assets/images/default.jpg b/ruoyi-ui/src/assets/images/default.jpg new file mode 100644 index 000000000..aa0237bb9 Binary files /dev/null and b/ruoyi-ui/src/assets/images/default.jpg differ diff --git a/ruoyi-ui/src/components/Verifition/Verify.vue b/ruoyi-ui/src/components/Verifition/Verify.vue new file mode 100644 index 000000000..f4f8f7746 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/Verify.vue @@ -0,0 +1,492 @@ + + + diff --git a/ruoyi-ui/src/components/Verifition/Verify/VerifyPoints.vue b/ruoyi-ui/src/components/Verifition/Verify/VerifyPoints.vue new file mode 100644 index 000000000..e257f1bc6 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/Verify/VerifyPoints.vue @@ -0,0 +1,256 @@ + + \ No newline at end of file diff --git a/ruoyi-ui/src/components/Verifition/Verify/VerifySlide.vue b/ruoyi-ui/src/components/Verifition/Verify/VerifySlide.vue new file mode 100644 index 000000000..3d550f6b2 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/Verify/VerifySlide.vue @@ -0,0 +1,359 @@ + + + diff --git a/ruoyi-ui/src/components/Verifition/api/index.js b/ruoyi-ui/src/components/Verifition/api/index.js new file mode 100644 index 000000000..e30b9762e --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/api/index.js @@ -0,0 +1,27 @@ +/** + * 此处可直接引用自己项目封装好的 axios 配合后端联调 + */ + + +import request from "./../utils/axios" //组件内部封装的axios +// import request from "@/api/axios.js" //调用项目封装的axios + +//获取验证图片 以及token +export function reqGet(data) { + return request({ + url: '/dev-api/captcha/get', + method: 'post', + data + }) +} + +//滑动或者点选验证 +export function reqCheck(data) { + return request({ + url: '/dev-api/captcha/check', + method: 'post', + data + }) +} + + diff --git a/ruoyi-ui/src/components/Verifition/utils/ase.js b/ruoyi-ui/src/components/Verifition/utils/ase.js new file mode 100644 index 000000000..4c1c55945 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/utils/ase.js @@ -0,0 +1,11 @@ +import CryptoJS from 'crypto-js' +/** + * @word 要加密的内容 + * @keyWord String 服务器随机返回的关键字 + * */ +export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){ + var key = CryptoJS.enc.Utf8.parse(keyWord); + var srcs = CryptoJS.enc.Utf8.parse(word); + var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}); + return encrypted.toString(); +} diff --git a/ruoyi-ui/src/components/Verifition/utils/axios.js b/ruoyi-ui/src/components/Verifition/utils/axios.js new file mode 100644 index 000000000..610d40323 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/utils/axios.js @@ -0,0 +1,30 @@ +import axios from 'axios'; + +axios.defaults.baseURL = process.env.BASE_API; + +const service = axios.create({ + timeout: 40000, + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'Content-Type': 'application/json; charset=UTF-8' + }, +}) +service.interceptors.request.use( + config => { + return config + }, + error => { + Promise.reject(error) + } +) + +// response interceptor +service.interceptors.response.use( + response => { + const res = response.data; + return res + }, + error => { + } +) +export default service diff --git a/ruoyi-ui/src/components/Verifition/utils/util.js b/ruoyi-ui/src/components/Verifition/utils/util.js new file mode 100644 index 000000000..55f65d426 --- /dev/null +++ b/ruoyi-ui/src/components/Verifition/utils/util.js @@ -0,0 +1,36 @@ +export function resetSize(vm) { + var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度 + + var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth + var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight + + if (vm.imgSize.width.indexOf('%') != -1) { + img_width = parseInt(this.imgSize.width) / 100 * parentWidth + 'px' + } else { + img_width = this.imgSize.width; + } + + if (vm.imgSize.height.indexOf('%') != -1) { + img_height = parseInt(this.imgSize.height) / 100 * parentHeight + 'px' + } else { + img_height = this.imgSize.height + } + + if (vm.barSize.width.indexOf('%') != -1) { + bar_width = parseInt(this.barSize.width) / 100 * parentWidth + 'px' + } else { + bar_width = this.barSize.width + } + + if (vm.barSize.height.indexOf('%') != -1) { + bar_height = parseInt(this.barSize.height) / 100 * parentHeight + 'px' + } else { + bar_height = this.barSize.height + } + + return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height} +} + +export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] +export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0'] +export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC'] \ No newline at end of file diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue index e8da56b7e..a5d813f9a 100644 --- a/ruoyi-ui/src/views/login.vue +++ b/ruoyi-ui/src/views/login.vue @@ -28,19 +28,26 @@ > - 记住密码 + + + + 登 录 登 录 中... @@ -54,12 +61,15 @@