From e85c342696821195f369a8fdcbfa49a029327361 Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Sun, 3 Jan 2021 01:45:20 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87=E9=AA=8C?=
=?UTF-8?q?=E8=AF=81=E7=A0=81=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 33 +++++++++++---
.../captcha/config/CaptchaConfig.java | 9 ++++
.../captcha/config/CaptchaProperties.java | 31 +++++++++++++
.../framework/captcha/package-info.java | 4 ++
.../common/SysCaptchaController.http | 2 +
.../common/SysCaptchaController.java | 30 +++++++++++++
.../common/vo/SysCaptchaImageRespVO.java | 23 ++++++++++
.../convert/common/SysCaptchaConvert.java | 18 ++++++++
.../modules/system/convert/package-info.java | 6 +++
...‹é“ Spring Boot å¯¹è±¡è½¬æ¢ MapStruct 入门》.md | 1 +
.../system/dal/redis/RedisKeyConstants.java | 32 ++++++++++++++
.../system/dal/redis/RedisKeyContants.java | 4 --
.../redis/dao/auth/SysLoginUserRedisDAO.java | 42 ++++++++++++++++++
.../redis/dao/common/SysCaptchaRedisDAO.java | 44 +++++++++++++++++++
.../system/dal/redis/dao/package-info.java | 4 ++
.../service/common/SysCaptchaService.java | 12 +++++
.../common/impl/SysCaptchaServiceImpl.java | 38 ++++++++++++++++
src/main/resources/application.yaml | 9 +++-
18 files changed, 331 insertions(+), 11 deletions(-)
create mode 100644 src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaConfig.java
create mode 100644 src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaProperties.java
create mode 100644 src/main/java/cn/iocoder/dashboard/framework/captcha/package-info.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/controller/common/vo/SysCaptchaImageRespVO.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/convert/common/SysCaptchaConvert.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/convert/package-info.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/convert/ã€ŠèŠ‹é“ Spring Boot å¯¹è±¡è½¬æ¢ MapStruct 入门》.md
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyConstants.java
delete mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyContants.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/package-info.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java
create mode 100644 src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java
diff --git a/pom.xml b/pom.xml
index 00701ba30..d49efbdfb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,8 +49,8 @@
3.4.1
3.13.6
- 1.16.14
- 1.3.0.Final
+ 1.16.14
+ 1.4.1.Final
0.9.1
1.2.75
5.5.6
@@ -252,7 +252,7 @@
org.projectlombok
lombok
- ${org.projectlombok.version}
+ ${lombok.version}
@@ -270,7 +270,7 @@
org.projectlombok
lombok
- ${org.projectlombok.version}
+ ${lombok.version}
@@ -280,11 +280,32 @@
1.21
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+
+
+ org.mapstruct
+ mapstruct-jdk8
+ ${mapstruct.version}
+
+
cn.hutool
hutool-core
${hutool.version}
+
+ cn.hutool
+ hutool-extra
+ ${hutool.version}
+
+
+ cn.hutool
+ hutool-captcha
+ ${hutool.version}
+
@@ -303,12 +324,12 @@
org.mapstruct
mapstruct-processor
- ${org.mapstruct.version}
+ ${mapstruct.version}
org.projectlombok
lombok
- ${org.projectlombok.version}
+ ${lombok.version}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaConfig.java b/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaConfig.java
new file mode 100644
index 000000000..b1fb8f28c
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaConfig.java
@@ -0,0 +1,9 @@
+package cn.iocoder.dashboard.framework.captcha.config;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties(CaptchaProperties.class)
+public class CaptchaConfig {
+}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaProperties.java b/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaProperties.java
new file mode 100644
index 000000000..9530ea1ee
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/captcha/config/CaptchaProperties.java
@@ -0,0 +1,31 @@
+package cn.iocoder.dashboard.framework.captcha.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotNull;
+import java.time.Duration;
+
+@ConfigurationProperties(prefix = "yudao.captcha")
+@Validated
+@Data
+public class CaptchaProperties {
+
+ /**
+ * 验è¯ç 的过期时间
+ */
+ @NotNull(message = "验è¯ç 的过期时间ä¸ä¸ºç©º")
+ private Duration timeout;
+ /**
+ * 验è¯ç 的高度
+ */
+ @NotNull(message = "验è¯ç 的高度ä¸èƒ½ä¸ºç©º")
+ private Integer height;
+ /**
+ * 验è¯ç 的宽度
+ */
+ @NotNull(message = "验è¯ç 的宽度ä¸èƒ½ä¸ºç©º")
+ private Integer width;
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/framework/captcha/package-info.java b/src/main/java/cn/iocoder/dashboard/framework/captcha/package-info.java
new file mode 100644
index 000000000..432e3d449
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/framework/captcha/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 基于 Hutool captcha 库,实现验è¯ç 功能
+ */
+package cn.iocoder.dashboard.framework.captcha;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
new file mode 100644
index 000000000..90859ca70
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.http
@@ -0,0 +1,2 @@
+### 请求 /captcha/get-image æŽ¥å£ => æˆåŠŸ
+GET {{baseUrl}}/captcha/get-image
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
new file mode 100644
index 000000000..e7b1b0373
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/SysCaptchaController.java
@@ -0,0 +1,30 @@
+package cn.iocoder.dashboard.modules.system.controller.common;
+
+import cn.iocoder.dashboard.common.pojo.CommonResult;
+import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageRespVO;
+import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
+
+@Api(tags = "验è¯ç API")
+@RestController
+@RequestMapping("/captcha")
+public class SysCaptchaController {
+
+ @Resource
+ private SysCaptchaService captchaService;
+
+ @ApiOperation("生æˆå›¾ç‰‡éªŒè¯ç ")
+ @GetMapping("/get-image")
+ private CommonResult getCaptchaImage() {
+ return success(captchaService.getCaptchaImage());
+ }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/vo/SysCaptchaImageRespVO.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/vo/SysCaptchaImageRespVO.java
new file mode 100644
index 000000000..3af4e410c
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/common/vo/SysCaptchaImageRespVO.java
@@ -0,0 +1,23 @@
+package cn.iocoder.dashboard.modules.system.controller.common.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@ApiModel("验è¯ç 图片 Response VO")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SysCaptchaImageRespVO {
+
+ @ApiModelProperty(value = "uuid", required = true, example = "1b3b7d00-83a8-4638-9e37-d67011855968", notes = "通过该 uuid 作为该验è¯ç çš„æ ‡è¯†")
+ private String uuid;
+
+ @ApiModelProperty(value = "图片", required = true, notes = "验è¯ç 的图片内容,使用 Base64 ç¼–ç ")
+ private String img;
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/common/SysCaptchaConvert.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/common/SysCaptchaConvert.java
new file mode 100644
index 000000000..992c9c9f1
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/common/SysCaptchaConvert.java
@@ -0,0 +1,18 @@
+package cn.iocoder.dashboard.modules.system.convert.common;
+
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.ICaptcha;
+import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageRespVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface SysCaptchaConvert {
+
+ SysCaptchaConvert INSTANCE = Mappers.getMapper(SysCaptchaConvert.class);
+
+ default SysCaptchaImageRespVO convert(String uuid, AbstractCaptcha captcha) {
+ return SysCaptchaImageRespVO.builder().uuid(uuid).img(captcha.getImageBase64()).build();
+ }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/system/convert/package-info.java
new file mode 100644
index 000000000..89deac94a
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * æä¾› POJO 类的实体转æ¢
+ *
+ * ç›®å‰ä½¿ç”¨ MapStruct 框架
+ */
+package cn.iocoder.dashboard.modules.system.convert;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/convert/ã€ŠèŠ‹é“ Spring Boot å¯¹è±¡è½¬æ¢ MapStruct 入门》.md b/src/main/java/cn/iocoder/dashboard/modules/system/convert/ã€ŠèŠ‹é“ Spring Boot å¯¹è±¡è½¬æ¢ MapStruct 入门》.md
new file mode 100644
index 000000000..af9fdefc5
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/convert/ã€ŠèŠ‹é“ Spring Boot å¯¹è±¡è½¬æ¢ MapStruct 入门》.md
@@ -0,0 +1 @@
+
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyConstants.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyConstants.java
new file mode 100644
index 000000000..b21019def
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyConstants.java
@@ -0,0 +1,32 @@
+package cn.iocoder.dashboard.modules.system.dal.redis;
+
+import cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine;
+import cn.iocoder.dashboard.framework.security.core.LoginUser;
+
+import java.time.Duration;
+
+import static cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
+import static cn.iocoder.dashboard.framework.redis.core.RedisKeyDefine.TIMEOUT_DYNAMIC;
+
+/**
+ * Redis Key 枚举类
+ *
+ * @author 芋é“æºç
+ */
+public interface RedisKeyConstants {
+
+ /**
+ * {@link LoginUser} 的缓å˜
+ *
+ * key çš„ format çš„å‚数是 sessionId
+ */
+ RedisKeyDefine LOGIN_USER = new RedisKeyDefine("login_user:%s", STRING, LoginUser.class, Duration.ofMinutes(30));
+
+ /**
+ * 验è¯ç 的缓å˜
+ *
+ * key çš„ format çš„å‚数是 uuid
+ */
+ RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("captcha_code:%s", STRING, String.class, TIMEOUT_DYNAMIC);
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyContants.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyContants.java
deleted file mode 100644
index cd4a5f17c..000000000
--- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyContants.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package cn.iocoder.dashboard.modules.system.dal.redis;
-
-public class RedisKeyContants {
-}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java
new file mode 100644
index 000000000..c76807178
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/auth/SysLoginUserRedisDAO.java
@@ -0,0 +1,42 @@
+package cn.iocoder.dashboard.modules.system.dal.redis.dao.auth;
+
+import cn.iocoder.dashboard.framework.security.core.LoginUser;
+import com.alibaba.fastjson.JSON;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.dashboard.modules.system.dal.redis.RedisKeyConstants.LOGIN_USER;
+
+/**
+ * {@link LoginUser} çš„ RedisDAO
+ *
+ * @author 芋é“æºç
+ */
+@Repository
+public class SysLoginUserRedisDAO {
+
+ @Resource
+ private StringRedisTemplate stringRedisTemplate;
+
+ public LoginUser get(String sessionId) {
+ String redisKey = formatKey(sessionId);
+ return JSON.parseObject(stringRedisTemplate.opsForValue().get(redisKey), LoginUser.class);
+ }
+
+ public void set(String sessionId, LoginUser loginUser) {
+ String redisKey = formatKey(sessionId);
+ stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(loginUser), LOGIN_USER.getTimeout());
+ }
+
+ public void delete(String accessToken) {
+ String redisKey = formatKey(accessToken);
+ stringRedisTemplate.delete(redisKey);
+ }
+
+ private static String formatKey(String sessionId) {
+ return String.format(LOGIN_USER.getKeyTemplate(), sessionId);
+ }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java
new file mode 100644
index 000000000..8e9d32446
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/common/SysCaptchaRedisDAO.java
@@ -0,0 +1,44 @@
+package cn.iocoder.dashboard.modules.system.dal.redis.dao.common;
+
+import cn.iocoder.dashboard.framework.security.core.LoginUser;
+import com.alibaba.fastjson.JSON;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.time.Duration;
+
+import static cn.iocoder.dashboard.modules.system.dal.redis.RedisKeyConstants.CAPTCHA_CODE;
+
+/**
+ * 验è¯ç çš„ Redis DAO
+ *
+ * @author 芋é“æºç
+ */
+@Repository
+public class SysCaptchaRedisDAO {
+
+ @Resource
+ private StringRedisTemplate stringRedisTemplate;
+
+ public String get(String uuid) {
+ String redisKey = formatKey(uuid);
+ return stringRedisTemplate.opsForValue().get(redisKey);
+ }
+
+ public void set(String uuid, String code, Duration timeout) {
+ String redisKey = formatKey(uuid);
+ stringRedisTemplate.opsForValue().set(redisKey, code, timeout);
+ }
+
+ public void delete(String uuid) {
+ String redisKey = formatKey(uuid);
+ stringRedisTemplate.delete(redisKey);
+ }
+
+ private static String formatKey(String uuid) {
+ return String.format(CAPTCHA_CODE.getKeyTemplate(), uuid);
+ }
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/package-info.java
new file mode 100644
index 000000000..a8b4123a1
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/dao/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * æä¾› Redis 访问的 DAO
+ */
+package cn.iocoder.dashboard.modules.system.dal.redis.dao;
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java
new file mode 100644
index 000000000..e7c26c2ca
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/SysCaptchaService.java
@@ -0,0 +1,12 @@
+package cn.iocoder.dashboard.modules.system.service.common;
+
+import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageRespVO;
+
+/**
+ * 验è¯ç Service 接å£
+ */
+public interface SysCaptchaService {
+
+ SysCaptchaImageRespVO getCaptchaImage();
+
+}
diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java
new file mode 100644
index 000000000..856f50b5c
--- /dev/null
+++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/common/impl/SysCaptchaServiceImpl.java
@@ -0,0 +1,38 @@
+package cn.iocoder.dashboard.modules.system.service.common.impl;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.CircleCaptcha;
+import cn.hutool.core.util.IdUtil;
+import cn.iocoder.dashboard.framework.captcha.config.CaptchaProperties;
+import cn.iocoder.dashboard.modules.system.controller.common.vo.SysCaptchaImageRespVO;
+import cn.iocoder.dashboard.modules.system.convert.common.SysCaptchaConvert;
+import cn.iocoder.dashboard.modules.system.dal.redis.dao.common.SysCaptchaRedisDAO;
+import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * 验è¯ç Service 实现类
+ */
+@Service
+public class SysCaptchaServiceImpl implements SysCaptchaService {
+
+ @Resource
+ private CaptchaProperties captchaProperties;
+
+ @Resource
+ private SysCaptchaRedisDAO captchaRedisDAO;
+
+ @Override
+ public SysCaptchaImageRespVO getCaptchaImage() {
+ // 生æˆéªŒè¯ç
+ CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
+ // 缓å˜åˆ° Redis ä¸
+ String uuid = IdUtil.fastSimpleUUID();
+ captchaRedisDAO.set(uuid, captcha.getCode(), captchaProperties.getTimeout());
+ // 返回
+ return SysCaptchaConvert.INSTANCE.convert(uuid, captcha);
+ }
+
+}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index d1cb9258f..34d01a504 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -1,4 +1,6 @@
spring:
+ application:
+ name: dashboard
# æ•°æ®æºé…置项 TODO 多数æ®æºï¼›TODO 监控é…ç½®
datasource:
url: jdbc:mysql://127.0.1:3306/ruoyi-vue-pro?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
@@ -21,9 +23,14 @@ yudao:
security:
token-header: Authorization
token-secret: abcdefghijklmnopqrstuvwxyz
- token-expires: 30m
+ token-timeout: 1d
+ session-timeout: 30m
swagger:
title: 管ç†åŽå°
description: æ供管ç†å‘˜ç®¡ç†çš„所有功能
version: 1.0.0
base-package: cn.iocoder.dashboard.modules
+ captcha:
+ timeout: 5m
+ width: 160
+ height: 60