diff --git a/app-service/pom.xml b/app-service/pom.xml
index a536153..a07f263 100644
--- a/app-service/pom.xml
+++ b/app-service/pom.xml
@@ -110,6 +110,7 @@
org.springframework.boot
spring-boot-starter-data-redis
+ 2.5.4
diff --git a/app-service/src/main/java/com/depsystem/app/systemServer/securityServer/securityVO/CaptchaVO.java b/app-service/src/main/java/com/depsystem/app/loginServer/CaptchaVO.java
similarity index 78%
rename from app-service/src/main/java/com/depsystem/app/systemServer/securityServer/securityVO/CaptchaVO.java
rename to app-service/src/main/java/com/depsystem/app/loginServer/CaptchaVO.java
index c64261b..4bbb5cd 100644
--- a/app-service/src/main/java/com/depsystem/app/systemServer/securityServer/securityVO/CaptchaVO.java
+++ b/app-service/src/main/java/com/depsystem/app/loginServer/CaptchaVO.java
@@ -5,7 +5,7 @@
* @apiNote
*/
-package com.depsystem.app.systemServer.securityServer.securityVO;
+package com.depsystem.app.loginServer;
import lombok.Data;
diff --git a/app-service/src/main/java/com/depsystem/app/systemServer/util/Cache.java b/app-service/src/main/java/com/depsystem/app/systemServer/util/Cache.java
new file mode 100644
index 0000000..69c4743
--- /dev/null
+++ b/app-service/src/main/java/com/depsystem/app/systemServer/util/Cache.java
@@ -0,0 +1,221 @@
+/**
+ * @author JOJO
+ * @class Cache
+ * @date 2023/4/24
+ * @apiNote
+ */
+
+package com.depsystem.app.systemServer.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.util.StringUtils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class Cache {
+ @Autowired
+ private StringRedisTemplate redisTemplate;
+
+ private final String DEFAULT_KEY_PREFIX = "";
+ private final int EXPIRE_TIME = 1;
+ private final TimeUnit EXPIRE_TIME_TYPE = TimeUnit.DAYS;
+
+
+ /**
+ * 数据缓存至redis
+ *
+ * @param key
+ * @param value
+ * @return
+ */
+ public void add(K key, V value) {
+ try {
+ if (value != null) {
+ redisTemplate
+ .opsForValue()
+ .set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("数据缓存至redis失败"+ e.getMessage());
+ }
+ }
+
+ /**
+ * 数据缓存至redis并设置过期时间
+ *
+ * @param key
+ * @param value
+ * @return
+ */
+ public void add(K key, V value, int timeout, TimeUnit unit) {
+ try {
+ if (redisTemplate == null){
+ if (value != null) {
+ redisTemplate
+ .opsForValue()
+ .set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value), timeout, unit);
+ }
+ }
+
+ } catch (Exception e) {
+ throw new RuntimeException("数据缓存至redis失败");
+ }
+ }
+
+ /**
+ * 写入 hash-set,已经是key-value的键值,不能再写入为hash-set
+ *
+ * @param key must not be {@literal null}.
+ * @param subKey must not be {@literal null}.
+ * @param value 写入的值
+ */
+ public void addHashCache(K key, SK subKey, V value) {
+ redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
+ }
+
+ /**
+ * 写入 hash-set,并设置过期时间
+ *
+ * @param key must not be {@literal null}.
+ * @param subKey must not be {@literal null}.
+ * @param value 写入的值
+ */
+ public void addHashCache(K key, SK subKey, V value, long timeout, TimeUnit unit) {
+ redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
+ redisTemplate.expire(DEFAULT_KEY_PREFIX + key, timeout, unit);
+ }
+
+ /**
+ * 获取 hash-setvalue
+ *
+ * @param key must not be {@literal null}.
+ * @param subKey must not be {@literal null}.
+ */
+ public Object getHashCache(K key, SK subKey) {
+ return redisTemplate.opsForHash().get(DEFAULT_KEY_PREFIX + key, subKey);
+ }
+
+
+ /**
+ * 从redis中获取缓存数据,转成对象
+ *
+ * @param key must not be {@literal null}.
+ * @param clazz 对象类型
+ *
+ */
+ public V getObject(K key, Class clazz) {
+ String value = this.get(key);
+ V result = null;
+ if (!StringUtils.isEmpty(value)) {
+ result = JSONObject.parseObject(value, clazz);
+ }
+ return result;
+ }
+
+ /**
+ * 从redis中获取缓存数据,转成list
+ *
+ * @param key must not be {@literal null}.
+ * @param clazz 对象类型
+ * @return
+ */
+ public List getList(K key, Class clazz) {
+ String value = this.get(key);
+ List result = Collections.emptyList();
+ if (!StringUtils.isEmpty(value)) {
+ result = JSONArray.parseArray(value, clazz);
+ }
+ return result;
+ }
+
+ /**
+ * 功能描述:Get the value of {@code key}.
+ *
+ * @param key must not be {@literal null}.
+ * @return java.lang.String
+ * @date 2021/9/19
+ **/
+ public String get(K key) {
+ String value;
+ try {
+ value = redisTemplate.opsForValue().get(DEFAULT_KEY_PREFIX + key);
+ } catch (Exception e) {
+ throw new RuntimeException("从redis缓存中获取缓存数据失败");
+ }
+ return value;
+ }
+
+ /**
+ * 删除key
+ */
+ public void delete(String key) {
+ redisTemplate.delete(key);
+ }
+
+ /**
+ * 批量删除key
+ */
+ public void delete(Collection keys) {
+ redisTemplate.delete(keys);
+ }
+
+ /**
+ * 序列化key
+ */
+ public byte[] dump(String key) {
+ return redisTemplate.dump(key);
+ }
+
+ /**
+ * 是否存在key
+ */
+ public Boolean hasKey(String key) {
+ return redisTemplate.hasKey(key);
+ }
+
+ /**
+ * 设置过期时间
+ */
+ public Boolean expire(String key, long timeout, TimeUnit unit) {
+ return redisTemplate.expire(key, timeout, unit);
+ }
+
+ /**
+ * 设置过期时间
+ */
+ public Boolean expireAt(String key, Date date) {
+ return redisTemplate.expireAt(key, date);
+ }
+
+
+ /**
+ * 移除 key 的过期时间,key 将持久保持
+ */
+ public Boolean persist(String key) {
+ return redisTemplate.persist(key);
+ }
+
+ /**
+ * 返回 key 的剩余的过期时间
+ */
+ public Long getExpire(String key, TimeUnit unit) {
+ return redisTemplate.getExpire(key, unit);
+ }
+
+ /**
+ * 返回 key 的剩余的过期时间
+ */
+ public Long getExpire(String key) {
+ return redisTemplate.getExpire(key);
+ }
+}
diff --git a/app-service/src/main/java/com/depsystem/app/systemServer/util/CacheUtil.java b/app-service/src/main/java/com/depsystem/app/systemServer/util/CacheUtil.java
new file mode 100644
index 0000000..a6cb199
--- /dev/null
+++ b/app-service/src/main/java/com/depsystem/app/systemServer/util/CacheUtil.java
@@ -0,0 +1,514 @@
+/**
+ * @author JOJO
+ * @class CacheUtil
+ * @date 2023/4/24
+ * @apiNote
+ */
+
+package com.depsystem.app.systemServer.util;
+
+import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author youxin
+ * @program redis-study
+ * @description redis常用工具类
+ * @date 2021-11-22 17:24
+ */
+@Component
+public class CacheUtil {
+
+ @Resource
+ @Qualifier("myRedisTemplate")
+ private RedisTemplate redisTemplate;
+ // =============================common============================
+ /**
+ * 指定缓存失效时间
+ * @param key 键
+ * @param time 时间(秒)
+ * @return
+ */
+ public boolean expire(String key, long time) {
+ try {
+ if (time > 0) {
+ redisTemplate.expire(key, time, TimeUnit.SECONDS);
+ }
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * 根据key 获取过期时间
+ * @param key 键 不能为null
+ * @return 时间(秒) 返回0代表为永久有效
+ */
+ public long getExpire(String key) {
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+ }
+ /**
+ * 判断key是否存在
+ * @param key 键
+ * @return true 存在 false不存在
+ */
+ public boolean hasKey(String key) {
+ try {
+ return redisTemplate.hasKey(key);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * 删除缓存
+ * @param key 可以传一个值 或多个
+ */
+ @SuppressWarnings("unchecked")
+ public void del(String... key) {
+ if (key != null && key.length > 0) {
+ if (key.length == 1) {
+ redisTemplate.delete(key[0]);
+ } else {
+ redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
+ }
+ }
+ }
+ // ============================String=============================
+ /**
+ * 普通缓存获取
+ * @param key 键
+ * @return 值
+ */
+ public Object get(String key) {
+ return key == null ? null : redisTemplate.opsForValue().get(key);
+ }
+ /**
+ * 普通缓存放入
+ * @param key 键
+ * @param value 值
+ * @return true成功 false失败
+ */
+ public boolean set(String key, Object value) {
+ try {
+ redisTemplate.opsForValue().set(key, value);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * 普通缓存放入并设置时间
+ * @param key 键
+ * @param value 值
+ * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
+ * @return true成功 false 失败
+ */
+ public boolean set(String key, Object value, long time) {
+ try {
+ if (time > 0) {
+ redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+ } else {
+ set(key, value);
+ }
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * 递增
+ * @param key 键
+ * @param delta 要增加几(大于0)
+ * @return
+ */
+ public long incr(String key, long delta) {
+ if (delta < 0) {
+ throw new RuntimeException("递增因子必须大于0");
+ }
+ return redisTemplate.opsForValue().increment(key, delta);
+ }
+ /**
+ * 递减
+ * @param key 键
+ * @param delta 要减少几(小于0)
+ * @return
+ */
+ public long decr(String key, long delta) {
+ if (delta < 0) {
+ throw new RuntimeException("递减因子必须大于0");
+ }
+ return redisTemplate.opsForValue().increment(key, -delta);
+ }
+ // ================================Map=================================
+ /**
+ * HashGet
+ * @param key 键 不能为null
+ * @param item 项 不能为null
+ * @return 值
+ */
+ public Object hget(String key, String item) {
+ return redisTemplate.opsForHash().get(key, item);
+ }
+ /**
+ * 获取hashKey对应的所有键值
+ * @param key 键
+ * @return 对应的多个键值
+ */
+ public Map