From 4daaf61f4023b9ce72e5310bfdecc9cb4022cbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=96=E9=87=91=E9=BE=99?= <46640269+JinlongLiao@users.noreply.github.com> Date: Wed, 10 Jun 2020 20:38:54 +0800 Subject: [PATCH] =?UTF-8?q?FileUtils=E4=BF=AE=E6=94=B9/=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E5=8F=AF=E9=85=8D=E7=BD=AE=20(#403)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、FileUtils 提供统一的系统临时目录获取方式 2、替换系统中异常错误打印方式 ,全部依赖改为Slf4j,实现错误信息的堆栈保留 修改配置文件 1、修改 配置信息 获取方式 2、调整原验证码 相关配置信息 3、新增多种验证码 方式 --- .../exception/BadConfigurationException.java | 98 ++++++++++ .../main/java/me/zhengjie/utils/FileUtil.java | 35 +++- .../java/me/zhengjie/utils/RedisUtils.java | 108 +++++++---- .../service/impl/GeneratorServiceImpl.java | 35 ++-- .../main/java/me/zhengjie/utils/ColUtil.java | 12 +- .../main/java/me/zhengjie/utils/GenUtil.java | 178 +++++++++--------- .../zhengjie/service/impl/LogServiceImpl.java | 27 +-- .../mnt/service/impl/DeployServiceImpl.java | 4 +- .../modules/mnt/util/ExecuteShellUtil.java | 4 +- .../zhengjie/modules/mnt/util/SqlUtils.java | 4 +- .../mnt/websocket/WebSocketServer.java | 2 +- .../config/ConfigBeanConfiguration.java | 42 +++++ .../security/config/bean/LoginCode.java | 85 +++++++++ .../security/config/bean/LoginCodeEnum.java | 43 +++++ .../security/config/bean/LoginProperties.java | 109 +++++++++++ .../config/{ => bean}/SecurityProperties.java | 37 ++-- .../rest/AuthorizationController.java | 22 +-- .../security/security/TokenFilter.java | 2 +- .../security/security/TokenProvider.java | 2 +- .../security/service/OnlineUserService.java | 4 +- .../main/resources/config/application-dev.yml | 28 ++- .../resources/config/application-prod.yml | 21 ++- .../src/main/resources/config/application.yml | 21 ++- 23 files changed, 706 insertions(+), 217 deletions(-) create mode 100644 eladmin-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java rename eladmin-system/src/main/java/me/zhengjie/modules/security/config/{ => bean}/SecurityProperties.java (69%) diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java b/eladmin-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java new file mode 100644 index 00000000..ede3691f --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/exception/BadConfigurationException.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.exception; + +/** + * 统一关于错误配置信息 异常 + * + * @author: liaojinlong + * @date: 2020/6/10 18:06 + */ +public class BadConfigurationException extends RuntimeException { + /** + * Constructs a new runtime exception with {@code null} as its + * detail message. The cause is not initialized, and may subsequently be + * initialized by a call to {@link #initCause}. + */ + public BadConfigurationException() { + super(); + } + + /** + * Constructs a new runtime exception with the specified detail message. + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public BadConfigurationException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a + * detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public BadConfigurationException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail + * message, cause, suppression enabled or disabled, and writable + * stack trace enabled or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled + * or disabled + * @param writableStackTrace whether or not the stack trace should + * be writable + * @since 1.7 + */ + protected BadConfigurationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/FileUtil.java b/eladmin-common/src/main/java/me/zhengjie/utils/FileUtil.java index b1a64af8..8868ba6d 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/FileUtil.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/FileUtil.java @@ -21,6 +21,8 @@ import cn.hutool.poi.excel.BigExcelWriter; import cn.hutool.poi.excel.ExcelUtil; import me.zhengjie.exception.BadRequestException; import org.apache.poi.util.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; @@ -41,7 +43,20 @@ import java.util.Map; * @date 2018-12-27 */ public class FileUtil extends cn.hutool.core.io.FileUtil { - + private static final Logger log = LoggerFactory.getLogger(FileUtil.class); + /** + * 系统临时目录 + *
+ * windows 包含路径分割符,但Linux 不包含, + * 在windows \\==\ 前提下, + * 为安全起见 同意拼装 路径分割符, + *

+     *       java.io.tmpdir
+     *       windows : C:\Users/xxx\AppData\Local\Temp\
+     *       linux: /temp
+     * 
+ */ + public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator; /** * 定义GB的计算常量 */ @@ -75,7 +90,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { // MultipartFile to File multipartFile.transferTo(file); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return file; } @@ -130,7 +145,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { * inputStream 转 File */ static File inputStreamToFile(InputStream ins, String name) throws Exception { - File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name); + File file = new File(SYS_TEM_DIR + name); if (file.exists()) { return file; } @@ -170,7 +185,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { file.transferTo(dest); return dest; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return null; } @@ -179,7 +194,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { * 导出excel */ public static void downloadExcel(List> list, HttpServletResponse response) throws IOException { - String tempPath = System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx"; + String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx"; File file = new File(tempPath); BigExcelWriter writer = ExcelUtil.getBigWriter(file); // 一次性写出内容,使用默认样式,强制输出标题 @@ -246,10 +261,10 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { try { System.out.println(in.read(b)); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } catch (FileNotFoundException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return null; } return b; @@ -272,7 +287,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { } return new String(str); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return null; } @@ -294,7 +309,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { IOUtils.copy(fis, response.getOutputStream()); response.flushBuffer(); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } finally { if (fis != null) { try { @@ -303,7 +318,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { file.deleteOnExit(); } } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java index fa4cfa02..5004eb84 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java @@ -15,12 +15,15 @@ */ package me.zhengjie.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; + import java.util.*; import java.util.concurrent.TimeUnit; @@ -28,9 +31,9 @@ import java.util.concurrent.TimeUnit; * @author / */ @Component -@SuppressWarnings({"unchecked","all"}) +@SuppressWarnings({"unchecked", "all"}) public class RedisUtils { - + private static final Logger log = LoggerFactory.getLogger(RedisUtils.class); private RedisTemplate redisTemplate; @Value("${jwt.online-key}") private String onlineKey; @@ -41,6 +44,7 @@ public class RedisUtils { /** * 指定缓存失效时间 + * * @param key 键 * @param time 时间(秒) */ @@ -50,7 +54,7 @@ public class RedisUtils { redisTemplate.expire(key, time, TimeUnit.SECONDS); } } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } return true; @@ -58,8 +62,9 @@ public class RedisUtils { /** * 指定缓存失效时间 - * @param key 键 - * @param time 时间(秒) + * + * @param key 键 + * @param time 时间(秒) * @param timeUnit 单位 */ public boolean expire(String key, long time, TimeUnit timeUnit) { @@ -68,7 +73,7 @@ public class RedisUtils { redisTemplate.expire(key, time, timeUnit); } } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } return true; @@ -76,6 +81,7 @@ public class RedisUtils { /** * 根据 key 获取过期时间 + * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ @@ -85,6 +91,7 @@ public class RedisUtils { /** * 查找匹配key + * * @param pattern key * @return / */ @@ -100,16 +107,17 @@ public class RedisUtils { try { RedisConnectionUtils.releaseConnection(rc, factory); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return result; } /** * 分页查询 key + * * @param patternKey key - * @param page 页码 - * @param size 每页数目 + * @param page 页码 + * @param size 每页数目 * @return / */ public List findKeysForPage(String patternKey, int page, int size) { @@ -128,7 +136,7 @@ public class RedisUtils { continue; } // 获取到满足条件的数据后,就可以退出了 - if(tmpIndex >=toIndex) { + if (tmpIndex >= toIndex) { break; } tmpIndex++; @@ -137,13 +145,14 @@ public class RedisUtils { try { RedisConnectionUtils.releaseConnection(rc, factory); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return result; } /** * 判断key是否存在 + * * @param key 键 * @return true 存在 false不存在 */ @@ -151,13 +160,14 @@ public class RedisUtils { try { return redisTemplate.hasKey(key); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 删除缓存 + * * @param key 可以传一个值 或多个 */ public void del(String... keys) { @@ -185,6 +195,7 @@ public class RedisUtils { /** * 普通缓存获取 + * * @param key 键 * @return 值 */ @@ -194,6 +205,7 @@ public class RedisUtils { /** * 批量获取 + * * @param keys * @return */ @@ -204,6 +216,7 @@ public class RedisUtils { /** * 普通缓存放入 + * * @param key 键 * @param value 值 * @return true成功 false失败 @@ -213,13 +226,14 @@ public class RedisUtils { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 普通缓存放入并设置时间 + * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 @@ -234,16 +248,17 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 普通缓存放入并设置时间 - * @param key 键 - * @param value 值 - * @param time 时间 + * + * @param key 键 + * @param value 值 + * @param time 时间 * @param timeUnit 类型 * @return true成功 false 失败 */ @@ -256,7 +271,7 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } @@ -265,6 +280,7 @@ public class RedisUtils { /** * HashGet + * * @param key 键 不能为null * @param item 项 不能为null * @return 值 @@ -275,6 +291,7 @@ public class RedisUtils { /** * 获取hashKey对应的所有键值 + * * @param key 键 * @return 对应的多个键值 */ @@ -285,6 +302,7 @@ public class RedisUtils { /** * HashSet + * * @param key 键 * @param map 对应多个键值 * @return true 成功 false 失败 @@ -294,13 +312,14 @@ public class RedisUtils { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * HashSet 并设置时间 + * * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) @@ -314,7 +333,7 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } @@ -332,7 +351,7 @@ public class RedisUtils { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } @@ -354,7 +373,7 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } @@ -416,7 +435,7 @@ public class RedisUtils { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return null; } } @@ -432,7 +451,7 @@ public class RedisUtils { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } @@ -448,13 +467,14 @@ public class RedisUtils { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } /** * 将set数据放入缓存 + * * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 @@ -468,13 +488,14 @@ public class RedisUtils { } return count; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } /** * 获取set缓存的长度 + * * @param key 键 * @return */ @@ -482,13 +503,14 @@ public class RedisUtils { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } /** * 移除值为value的 + * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 @@ -498,7 +520,7 @@ public class RedisUtils { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } @@ -507,6 +529,7 @@ public class RedisUtils { /** * 获取list缓存的内容 + * * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 @@ -516,13 +539,14 @@ public class RedisUtils { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return null; } } /** * 获取list缓存的长度 + * * @param key 键 * @return */ @@ -530,13 +554,14 @@ public class RedisUtils { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } /** * 通过索引 获取list中的值 + * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 * @return @@ -545,13 +570,14 @@ public class RedisUtils { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return null; } } /** * 将list放入缓存 + * * @param key 键 * @param value 值 * @return @@ -561,13 +587,14 @@ public class RedisUtils { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 将list放入缓存 + * * @param key 键 * @param value 值 * @param time 时间(秒) @@ -581,13 +608,14 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 将list放入缓存 + * * @param key 键 * @param value 值 * @return @@ -597,13 +625,14 @@ public class RedisUtils { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 将list放入缓存 + * * @param key 键 * @param value 值 * @param time 时间(秒) @@ -617,13 +646,14 @@ public class RedisUtils { } return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 根据索引修改list中的某条数据 + * * @param key 键 * @param index 索引 * @param value 值 @@ -634,13 +664,14 @@ public class RedisUtils { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return false; } } /** * 移除N个值为value + * * @param key 键 * @param count 移除多少个 * @param value 值 @@ -650,15 +681,14 @@ public class RedisUtils { try { return redisTemplate.opsForList().remove(key, count, value); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(), e); return 0; } } /** - * * @param prefix 前缀 - * @param ids id + * @param ids id */ public void delByKeys(String prefix, Set ids) { Set keys = new HashSet<>(); diff --git a/eladmin-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java b/eladmin-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java index 6a94fb46..1b1803b2 100644 --- a/eladmin-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java +++ b/eladmin-generator/src/main/java/me/zhengjie/service/impl/GeneratorServiceImpl.java @@ -29,9 +29,12 @@ import me.zhengjie.utils.FileUtil; import me.zhengjie.utils.GenUtil; import me.zhengjie.utils.PageUtil; import me.zhengjie.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; + import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; @@ -51,7 +54,7 @@ import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class GeneratorServiceImpl implements GeneratorService { - + private static final Logger log = LoggerFactory.getLogger(GeneratorServiceImpl.class); @PersistenceContext private EntityManager em; @@ -75,23 +78,23 @@ public class GeneratorServiceImpl implements GeneratorService { "and table_name like ? order by create_time desc"; Query query = em.createNativeQuery(sql); query.setFirstResult(startEnd[0]); - query.setMaxResults(startEnd[1]-startEnd[0]); + query.setMaxResults(startEnd[1] - startEnd[0]); query.setParameter(1, StringUtils.isNotBlank(name) ? ("%" + name + "%") : "%%"); List result = query.getResultList(); List tableInfos = new ArrayList<>(); for (Object obj : result) { Object[] arr = (Object[]) obj; - tableInfos.add(new TableInfo(arr[0],arr[1],arr[2],arr[3], ObjectUtil.isNotEmpty(arr[4])? arr[4] : "-")); + tableInfos.add(new TableInfo(arr[0], arr[1], arr[2], arr[3], ObjectUtil.isNotEmpty(arr[4]) ? arr[4] : "-")); } Query query1 = em.createNativeQuery("SELECT COUNT(*) from information_schema.tables where table_schema = (select database())"); Object totalElements = query1.getSingleResult(); - return PageUtil.toPage(tableInfos,totalElements); + return PageUtil.toPage(tableInfos, totalElements); } @Override public List getColumns(String tableName) { List columnInfos = columnInfoRepository.findByTableNameOrderByIdAsc(tableName); - if(CollectionUtil.isNotEmpty(columnInfos)){ + if (CollectionUtil.isNotEmpty(columnInfos)) { return columnInfos; } else { columnInfos = query(tableName); @@ -100,12 +103,12 @@ public class GeneratorServiceImpl implements GeneratorService { } @Override - public List query(String tableName){ + public List query(String tableName) { // 使用预编译防止sql注入 String sql = "select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns " + "where table_name = ? and table_schema = (select database()) order by ordinal_position"; Query query = em.createNativeQuery(sql); - query.setParameter(1,tableName); + query.setParameter(1, tableName); List result = query.getResultList(); List columnInfos = new ArrayList<>(); for (Object obj : result) { @@ -131,12 +134,12 @@ public class GeneratorServiceImpl implements GeneratorService { // 根据字段名称查找 List columns = columnInfos.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList()); // 如果能找到,就修改部分可能被字段 - if(CollectionUtil.isNotEmpty(columns)){ + if (CollectionUtil.isNotEmpty(columns)) { ColumnInfo column = columns.get(0); column.setColumnType(columnInfo.getColumnType()); column.setExtra(columnInfo.getExtra()); column.setKeyType(columnInfo.getKeyType()); - if(StringUtils.isBlank(column.getRemark())){ + if (StringUtils.isBlank(column.getRemark())) { column.setRemark(columnInfo.getRemark()); } columnInfoRepository.save(column); @@ -150,7 +153,7 @@ public class GeneratorServiceImpl implements GeneratorService { // 根据字段名称查找 List columns = columnInfoList.stream().filter(c -> c.getColumnName().equals(columnInfo.getColumnName())).collect(Collectors.toList()); // 如果找不到,就代表字段被删除了,则需要删除该字段 - if(CollectionUtil.isEmpty(columns)){ + if (CollectionUtil.isEmpty(columns)) { columnInfoRepository.delete(columnInfo); } } @@ -163,34 +166,34 @@ public class GeneratorServiceImpl implements GeneratorService { @Override public void generator(GenConfig genConfig, List columns) { - if(genConfig.getId() == null){ + if (genConfig.getId() == null) { throw new BadRequestException("请先配置生成器"); } try { GenUtil.generatorCode(columns, genConfig); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); throw new BadRequestException("生成失败,请手动处理已生成的文件"); } } @Override public ResponseEntity preview(GenConfig genConfig, List columns) { - if(genConfig.getId() == null){ + if (genConfig.getId() == null) { throw new BadRequestException("请先配置生成器"); } - List> genList = GenUtil.preview(columns, genConfig); + List> genList = GenUtil.preview(columns, genConfig); return new ResponseEntity<>(genList, HttpStatus.OK); } @Override public void download(GenConfig genConfig, List columns, HttpServletRequest request, HttpServletResponse response) { - if(genConfig.getId() == null){ + if (genConfig.getId() == null) { throw new BadRequestException("请先配置生成器"); } try { File file = new File(GenUtil.download(columns, genConfig)); - String zipPath = file.getPath() + ".zip"; + String zipPath = file.getPath() + ".zip"; ZipUtil.zip(file.getPath(), zipPath); FileUtil.downloadFile(request, response, new File(zipPath), true); } catch (IOException e) { diff --git a/eladmin-generator/src/main/java/me/zhengjie/utils/ColUtil.java b/eladmin-generator/src/main/java/me/zhengjie/utils/ColUtil.java index f396d755..b5fcd6b7 100644 --- a/eladmin-generator/src/main/java/me/zhengjie/utils/ColUtil.java +++ b/eladmin-generator/src/main/java/me/zhengjie/utils/ColUtil.java @@ -16,6 +16,8 @@ package me.zhengjie.utils; import org.apache.commons.configuration.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * sql字段转java @@ -24,16 +26,18 @@ import org.apache.commons.configuration.*; * @date 2019-01-03 */ public class ColUtil { + private static final Logger log = LoggerFactory.getLogger(ColUtil.class); /** * 转换mysql数据类型为java数据类型 + * * @param type 数据库字段类型 * @return String */ - static String cloToJava(String type){ + static String cloToJava(String type) { Configuration config = getConfig(); assert config != null; - return config.getString(type,"unknowType"); + return config.getString(type, "unknowType"); } /** @@ -41,9 +45,9 @@ public class ColUtil { */ public static PropertiesConfiguration getConfig() { try { - return new PropertiesConfiguration("generator.properties" ); + return new PropertiesConfiguration("generator.properties"); } catch (ConfigurationException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } return null; } diff --git a/eladmin-generator/src/main/java/me/zhengjie/utils/GenUtil.java b/eladmin-generator/src/main/java/me/zhengjie/utils/GenUtil.java index 0e41ce16..0fe677e1 100644 --- a/eladmin-generator/src/main/java/me/zhengjie/utils/GenUtil.java +++ b/eladmin-generator/src/main/java/me/zhengjie/utils/GenUtil.java @@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j; import me.zhengjie.domain.GenConfig; import me.zhengjie.domain.ColumnInfo; import org.springframework.util.ObjectUtils; + import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -28,13 +29,16 @@ import java.io.Writer; import java.time.LocalDate; import java.util.*; +import static me.zhengjie.utils.FileUtil.SYS_TEM_DIR; + /** * 代码生成 + * * @author Zheng Jie * @date 2019-01-02 */ @Slf4j -@SuppressWarnings({"unchecked","all"}) +@SuppressWarnings({"unchecked", "all"}) public class GenUtil { private static final String TIMESTAMP = "Timestamp"; @@ -47,6 +51,7 @@ public class GenUtil { /** * 获取后端代码模板名称 + * * @return List */ private static List getAdminTemplateNames() { @@ -64,6 +69,7 @@ public class GenUtil { /** * 获取前端代码模板名称 + * * @return List */ private static List getFrontTemplateNames() { @@ -74,14 +80,14 @@ public class GenUtil { } public static List> preview(List columns, GenConfig genConfig) { - Map genMap = getGenMap(columns, genConfig); - List> genList = new ArrayList<>(); + Map genMap = getGenMap(columns, genConfig); + List> genList = new ArrayList<>(); // 获取后端模版 List templates = getAdminTemplateNames(); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); for (String templateName : templates) { - Map map = new HashMap<>(1); - Template template = engine.getTemplate("generator/admin/"+templateName+".ftl"); + Map map = new HashMap<>(1); + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); map.put("content", template.render(genMap)); map.put("name", templateName); genList.add(map); @@ -89,8 +95,8 @@ public class GenUtil { // 获取前端模版 templates = getFrontTemplateNames(); for (String templateName : templates) { - Map map = new HashMap<>(1); - Template template = engine.getTemplate("generator/front/"+templateName+".ftl"); + Map map = new HashMap<>(1); + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); map.put(templateName, template.render(genMap)); map.put("content", template.render(genMap)); map.put("name", templateName); @@ -101,19 +107,19 @@ public class GenUtil { public static String download(List columns, GenConfig genConfig) throws IOException { // 拼接的路径:/tmpeladmin-gen-temp/,这个路径在Linux下需要root用户才有权限创建,非root用户会权限错误而失败,更改为: /tmp/eladmin-gen-temp/ - // String tempPath =System.getProperty("java.io.tmpdir") + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; - String tempPath =System.getProperty("java.io.tmpdir") + File.separator + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; - Map genMap = getGenMap(columns, genConfig); + // String tempPath =SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; + String tempPath = SYS_TEM_DIR + "eladmin-gen-temp" + File.separator + genConfig.getTableName() + File.separator; + Map genMap = getGenMap(columns, genConfig); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); // 生成后端代码 List templates = getAdminTemplateNames(); for (String templateName : templates) { - Template template = engine.getTemplate("generator/admin/"+templateName+".ftl"); - String filePath = getAdminFilePath(templateName,genConfig,genMap.get("className").toString(),tempPath + "eladmin" + File.separator); + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + String filePath = getAdminFilePath(templateName, genConfig, genMap.get("className").toString(), tempPath + "eladmin" + File.separator); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 - if(!genConfig.getCover() && FileUtil.exist(file)){ + if (!genConfig.getCover() && FileUtil.exist(file)) { continue; } // 生成代码 @@ -122,15 +128,15 @@ public class GenUtil { // 生成前端代码 templates = getFrontTemplateNames(); for (String templateName : templates) { - Template template = engine.getTemplate("generator/front/"+templateName+".ftl"); - String path = tempPath + "eladmin-web" + File.separator; + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); + String path = tempPath + "eladmin-web" + File.separator; String apiPath = path + "src" + File.separator + "api" + File.separator; String srcPath = path + "src" + File.separator + "views" + File.separator + genMap.get("changeClassName").toString() + File.separator; String filePath = getFrontFilePath(templateName, apiPath, srcPath, genMap.get("changeClassName").toString()); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 - if(!genConfig.getCover() && FileUtil.exist(file)){ + if (!genConfig.getCover() && FileUtil.exist(file)) { continue; } // 生成代码 @@ -140,19 +146,19 @@ public class GenUtil { } public static void generatorCode(List columnInfos, GenConfig genConfig) throws IOException { - Map genMap = getGenMap(columnInfos, genConfig); + Map genMap = getGenMap(columnInfos, genConfig); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); // 生成后端代码 List templates = getAdminTemplateNames(); for (String templateName : templates) { - Template template = engine.getTemplate("generator/admin/"+templateName+".ftl"); - String filePath = getAdminFilePath(templateName,genConfig,genMap.get("className").toString(),System.getProperty("user.dir")); + Template template = engine.getTemplate("generator/admin/" + templateName + ".ftl"); + String filePath = getAdminFilePath(templateName, genConfig, genMap.get("className").toString(), System.getProperty("user.dir")); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 - if(!genConfig.getCover() && FileUtil.exist(file)){ + if (!genConfig.getCover() && FileUtil.exist(file)) { continue; } // 生成代码 @@ -162,14 +168,14 @@ public class GenUtil { // 生成前端代码 templates = getFrontTemplateNames(); for (String templateName : templates) { - Template template = engine.getTemplate("generator/front/"+templateName+".ftl"); - String filePath = getFrontFilePath(templateName,genConfig.getApiPath(),genConfig.getPath(),genMap.get("changeClassName").toString()); + Template template = engine.getTemplate("generator/front/" + templateName + ".ftl"); + String filePath = getFrontFilePath(templateName, genConfig.getApiPath(), genConfig.getPath(), genMap.get("changeClassName").toString()); assert filePath != null; File file = new File(filePath); // 如果非覆盖生成 - if(!genConfig.getCover() && FileUtil.exist(file)){ + if (!genConfig.getCover() && FileUtil.exist(file)) { continue; } // 生成代码 @@ -178,141 +184,141 @@ public class GenUtil { } // 获取模版数据 - private static Map getGenMap(List columnInfos, GenConfig genConfig) { + private static Map getGenMap(List columnInfos, GenConfig genConfig) { // 存储模版字段数据 - Map genMap = new HashMap<>(16); + Map genMap = new HashMap<>(16); // 接口别名 - genMap.put("apiAlias",genConfig.getApiAlias()); + genMap.put("apiAlias", genConfig.getApiAlias()); // 包名称 - genMap.put("package",genConfig.getPack()); + genMap.put("package", genConfig.getPack()); // 模块名称 - genMap.put("moduleName",genConfig.getModuleName()); + genMap.put("moduleName", genConfig.getModuleName()); // 作者 - genMap.put("author",genConfig.getAuthor()); + genMap.put("author", genConfig.getAuthor()); // 创建日期 genMap.put("date", LocalDate.now().toString()); // 表名 - genMap.put("tableName",genConfig.getTableName()); + genMap.put("tableName", genConfig.getTableName()); // 大写开头的类名 String className = StringUtils.toCapitalizeCamelCase(genConfig.getTableName()); // 小写开头的类名 String changeClassName = StringUtils.toCamelCase(genConfig.getTableName()); // 判断是否去除表前缀 if (StringUtils.isNotEmpty(genConfig.getPrefix())) { - className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(genConfig.getTableName(),genConfig.getPrefix())); - changeClassName = StringUtils.toCamelCase(StrUtil.removePrefix(genConfig.getTableName(),genConfig.getPrefix())); + className = StringUtils.toCapitalizeCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); + changeClassName = StringUtils.toCamelCase(StrUtil.removePrefix(genConfig.getTableName(), genConfig.getPrefix())); } // 保存类名 genMap.put("className", className); // 保存小写开头的类名 genMap.put("changeClassName", changeClassName); // 存在 Timestamp 字段 - genMap.put("hasTimestamp",false); + genMap.put("hasTimestamp", false); // 查询类中存在 Timestamp 字段 - genMap.put("queryHasTimestamp",false); + genMap.put("queryHasTimestamp", false); // 存在 BigDecimal 字段 - genMap.put("hasBigDecimal",false); + genMap.put("hasBigDecimal", false); // 查询类中存在 BigDecimal 字段 - genMap.put("queryHasBigDecimal",false); + genMap.put("queryHasBigDecimal", false); // 是否需要创建查询 - genMap.put("hasQuery",false); + genMap.put("hasQuery", false); // 自增主键 - genMap.put("auto",false); + genMap.put("auto", false); // 存在字典 - genMap.put("hasDict",false); + genMap.put("hasDict", false); // 存在日期注解 - genMap.put("hasDateAnnotation",false); + genMap.put("hasDateAnnotation", false); // 保存字段信息 - List> columns = new ArrayList<>(); + List> columns = new ArrayList<>(); // 保存查询字段的信息 - List> queryColumns = new ArrayList<>(); + List> queryColumns = new ArrayList<>(); // 存储字典信息 List dicts = new ArrayList<>(); // 存储 between 信息 - List> betweens = new ArrayList<>(); + List> betweens = new ArrayList<>(); // 存储不为空的字段信息 - List> isNotNullColumns = new ArrayList<>(); + List> isNotNullColumns = new ArrayList<>(); for (ColumnInfo column : columnInfos) { - Map listMap = new HashMap<>(16); + Map listMap = new HashMap<>(16); // 字段描述 - listMap.put("remark",column.getRemark()); + listMap.put("remark", column.getRemark()); // 字段类型 - listMap.put("columnKey",column.getKeyType()); + listMap.put("columnKey", column.getKeyType()); // 主键类型 String colType = ColUtil.cloToJava(column.getColumnType()); // 小写开头的字段名 String changeColumnName = StringUtils.toCamelCase(column.getColumnName()); // 大写开头的字段名 String capitalColumnName = StringUtils.toCapitalizeCamelCase(column.getColumnName()); - if(PK.equals(column.getKeyType())){ + if (PK.equals(column.getKeyType())) { // 存储主键类型 - genMap.put("pkColumnType",colType); + genMap.put("pkColumnType", colType); // 存储小写开头的字段名 - genMap.put("pkChangeColName",changeColumnName); + genMap.put("pkChangeColName", changeColumnName); // 存储大写开头的字段名 - genMap.put("pkCapitalColName",capitalColumnName); + genMap.put("pkCapitalColName", capitalColumnName); } // 是否存在 Timestamp 类型的字段 - if(TIMESTAMP.equals(colType)){ - genMap.put("hasTimestamp",true); + if (TIMESTAMP.equals(colType)) { + genMap.put("hasTimestamp", true); } // 是否存在 BigDecimal 类型的字段 - if(BIGDECIMAL.equals(colType)){ - genMap.put("hasBigDecimal",true); + if (BIGDECIMAL.equals(colType)) { + genMap.put("hasBigDecimal", true); } // 主键是否自增 - if(EXTRA.equals(column.getExtra())){ - genMap.put("auto",true); + if (EXTRA.equals(column.getExtra())) { + genMap.put("auto", true); } // 主键存在字典 - if(StringUtils.isNotBlank(column.getDictName())){ - genMap.put("hasDict",true); + if (StringUtils.isNotBlank(column.getDictName())) { + genMap.put("hasDict", true); dicts.add(column.getDictName()); } // 存储字段类型 - listMap.put("columnType",colType); + listMap.put("columnType", colType); // 存储字原始段名称 - listMap.put("columnName",column.getColumnName()); + listMap.put("columnName", column.getColumnName()); // 不为空 - listMap.put("istNotNull",column.getNotNull()); + listMap.put("istNotNull", column.getNotNull()); // 字段列表显示 - listMap.put("columnShow",column.getListShow()); + listMap.put("columnShow", column.getListShow()); // 表单显示 - listMap.put("formShow",column.getFormShow()); + listMap.put("formShow", column.getFormShow()); // 表单组件类型 listMap.put("formType", StringUtils.isNotBlank(column.getFormType()) ? column.getFormType() : "Input"); // 小写开头的字段名称 - listMap.put("changeColumnName",changeColumnName); + listMap.put("changeColumnName", changeColumnName); //大写开头的字段名称 - listMap.put("capitalColumnName",capitalColumnName); + listMap.put("capitalColumnName", capitalColumnName); // 字典名称 - listMap.put("dictName",column.getDictName()); + listMap.put("dictName", column.getDictName()); // 日期注解 - listMap.put("dateAnnotation",column.getDateAnnotation()); - if(StringUtils.isNotBlank(column.getDateAnnotation())){ - genMap.put("hasDateAnnotation",true); + listMap.put("dateAnnotation", column.getDateAnnotation()); + if (StringUtils.isNotBlank(column.getDateAnnotation())) { + genMap.put("hasDateAnnotation", true); } // 添加非空字段信息 - if(column.getNotNull()){ + if (column.getNotNull()) { isNotNullColumns.add(listMap); } // 判断是否有查询,如有则把查询的字段set进columnQuery - if(!StringUtils.isBlank(column.getQueryType())){ + if (!StringUtils.isBlank(column.getQueryType())) { // 查询类型 - listMap.put("queryType",column.getQueryType()); + listMap.put("queryType", column.getQueryType()); // 是否存在查询 - genMap.put("hasQuery",true); - if(TIMESTAMP.equals(colType)){ + genMap.put("hasQuery", true); + if (TIMESTAMP.equals(colType)) { // 查询中存储 Timestamp 类型 - genMap.put("queryHasTimestamp",true); + genMap.put("queryHasTimestamp", true); } - if(BIGDECIMAL.equals(colType)){ + if (BIGDECIMAL.equals(colType)) { // 查询中存储 BigDecimal 类型 - genMap.put("queryHasBigDecimal",true); + genMap.put("queryHasBigDecimal", true); } - if("between".equalsIgnoreCase(column.getQueryType())){ + if ("between".equalsIgnoreCase(column.getQueryType())) { betweens.add(listMap); } else { // 添加到查询列表中 @@ -323,15 +329,15 @@ public class GenUtil { columns.add(listMap); } // 保存字段列表 - genMap.put("columns",columns); + genMap.put("columns", columns); // 保存查询列表 - genMap.put("queryColumns",queryColumns); + genMap.put("queryColumns", queryColumns); // 保存字段列表 - genMap.put("dicts",dicts); + genMap.put("dicts", dicts); // 保存查询列表 - genMap.put("betweens",betweens); + genMap.put("betweens", betweens); // 保存非空字段信息 - genMap.put("isNotNullColumns",isNotNullColumns); + genMap.put("isNotNullColumns", isNotNullColumns); return genMap; } @@ -340,7 +346,7 @@ public class GenUtil { */ private static String getAdminFilePath(String templateName, GenConfig genConfig, String className, String rootPath) { String projectPath = rootPath + File.separator + genConfig.getModuleName(); - String packagePath = projectPath + File.separator + "src" +File.separator+ "main" + File.separator + "java" + File.separator; + String packagePath = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator; if (!ObjectUtils.isEmpty(genConfig.getPack())) { packagePath += genConfig.getPack().replace(".", File.separator) + File.separator; } @@ -390,7 +396,7 @@ public class GenUtil { } if ("index".equals(templateName)) { - return path + File.separator + "index.vue"; + return path + File.separator + "index.vue"; } return null; diff --git a/eladmin-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java b/eladmin-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java index 45428d42..e30f4237 100644 --- a/eladmin-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java +++ b/eladmin-logging/src/main/java/me/zhengjie/service/impl/LogServiceImpl.java @@ -28,10 +28,13 @@ import me.zhengjie.service.mapstruct.LogSmallMapper; import me.zhengjie.utils.*; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; @@ -44,14 +47,14 @@ import java.util.*; @Service @RequiredArgsConstructor public class LogServiceImpl implements LogService { - + private static final Logger log = LoggerFactory.getLogger(LogServiceImpl.class); private final LogRepository logRepository; private final LogErrorMapper logErrorMapper; private final LogSmallMapper logSmallMapper; @Override - public Object queryAll(LogQueryCriteria criteria, Pageable pageable){ - Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)),pageable); + public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); String status = "ERROR"; if (status.equals(criteria.getLogType())) { return PageUtil.toPage(page.map(logErrorMapper::toDto)); @@ -66,20 +69,20 @@ public class LogServiceImpl implements LogService { @Override public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { - Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)),pageable); + Page page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); return PageUtil.toPage(page.map(logSmallMapper::toDto)); } @Override @Transactional(rollbackFor = Exception.class) - public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log){ + public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class); // 方法路径 - String methodName = joinPoint.getTarget().getClass().getName()+"."+signature.getName()+"()"; + String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; StringBuilder params = new StringBuilder("{"); //参数值 @@ -96,11 +99,11 @@ public class LogServiceImpl implements LogService { log.setRequestIp(ip); String loginPath = "login"; - if(loginPath.equals(signature.getName())){ + if (loginPath.equals(signature.getName())) { try { username = new JSONObject(argValues.get(0)).get("username").toString(); - }catch (Exception e){ - e.printStackTrace(); + } catch (Exception e) { + LogServiceImpl.log.error(e.getMessage(), e); } } log.setAddress(StringUtils.getCityInfo(log.getRequestIp())); @@ -114,16 +117,16 @@ public class LogServiceImpl implements LogService { @Override public Object findByErrDetail(Long id) { Log log = logRepository.findById(id).orElseGet(Log::new); - ValidationUtil.isNull( log.getId(),"Log","id", id); + ValidationUtil.isNull(log.getId(), "Log", "id", id); byte[] details = log.getExceptionDetail(); - return Dict.create().set("exception",new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); + return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); } @Override public void download(List logs, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); for (Log log : logs) { - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); map.put("用户名", log.getUsername()); map.put("IP", log.getRequestIp()); map.put("IP来源", log.getAddress()); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java index 3884fe4e..f2491cda 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/service/impl/DeployServiceImpl.java @@ -187,7 +187,7 @@ public class DeployServiceImpl implements DeployService { try { Thread.sleep(second * 1000); } catch (InterruptedException e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } } @@ -237,7 +237,7 @@ public class DeployServiceImpl implements DeployService { try { WebSocketServer.sendInfo(new SocketMsg(msg, msgType), "deploy"); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java index 9c99f459..a5d5b599 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ExecuteShellUtil.java @@ -45,7 +45,7 @@ public class ExecuteShellUtil { session.setConfig("StrictHostKeyChecking", "no"); session.connect(3000); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } } @@ -71,7 +71,7 @@ public class ExecuteShellUtil { System.out.println(line); } } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(),e); return -1; }finally { IoUtil.close(printWriter); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java index 2cefe910..df9c64f2 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/SqlUtils.java @@ -135,7 +135,7 @@ public class SqlUtils { try { connection.close(); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(),e); log.error("connection close error:" + e.getMessage()); } } @@ -147,7 +147,7 @@ public class SqlUtils { try { rs.close(); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java index 1aa94181..9c92165b 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/websocket/WebSocketServer.java @@ -83,7 +83,7 @@ public class WebSocketServer { try { item.sendMessage(message); } catch (IOException e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java new file mode 100644 index 00000000..78a1bd20 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/ConfigBeanConfiguration.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config; + +import me.zhengjie.modules.security.config.bean.LoginProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @apiNote 配置文件转换Pojo类的 统一配置 类 + * @author: liaojinlong + * @date: 2020/6/10 19:04 + */ +@Configuration +public class ConfigBeanConfiguration { + @Bean + @ConfigurationProperties(prefix = "login", ignoreUnknownFields = true) + public LoginProperties loginProperties() { + return new LoginProperties(); + } + + @Bean + @ConfigurationProperties(prefix = "jwt", ignoreUnknownFields = true) + public SecurityProperties securityProperties() { + return new SecurityProperties(); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java new file mode 100644 index 00000000..a27fe710 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCode.java @@ -0,0 +1,85 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +/** + * 登录验证码配置信息 + * + * @author: liaojinlong + * @date: 2020/6/10 18:53 + */ +public class LoginCode { + /** + * 验证码配置 + */ + private LoginCodeEnum codeType; + /** + * 验证码有效期 分钟 + */ + private Long expiration = 2L; + /** + * 验证码内容长度 + */ + private int length = 2; + /** + * 验证码宽度 + */ + private int width = 111; + /** + * 验证码高度 + */ + private int height = 36; + + public LoginCodeEnum getCodeType() { + return codeType; + } + + public void setCodeType(LoginCodeEnum codeType) { + this.codeType = codeType; + } + + public Long getExpiration() { + return expiration; + } + + public void setExpiration(Long expiration) { + this.expiration = expiration; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java new file mode 100644 index 00000000..9ff398f2 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginCodeEnum.java @@ -0,0 +1,43 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + +/** + * 验证码配置枚举 + * + * @author: liaojinlong + * @date: 2020/6/10 17:40 + */ + +public enum LoginCodeEnum { + /** + * 算数 + */ + arithmetic, + /** + * 中文 + */ + chinese, + /** + * 中文闪图 + */ + chinese_gif, + /** + * 闪图 + */ + gif, + spec +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java new file mode 100644 index 00000000..48f05ad0 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java @@ -0,0 +1,109 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version loginCode.length.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-loginCode.length.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.security.config.bean; + + +import com.wf.captcha.*; +import com.wf.captcha.base.Captcha; +import me.zhengjie.exception.BadConfigurationException; + +import java.util.Objects; + +/** + * 配置文件读取 + * + * @author: liaojinlong + * @date: loginCode.length0loginCode.length0/6/10 17:loginCode.length6 + */ +public class LoginProperties { + + /** + * 账号单用户 登录 + */ + private boolean singleLogin = false; + + private LoginCode loginCode; + + public boolean isSingleLogin() { + return singleLogin; + } + + public void setSingleLogin(boolean singleLogin) { + this.singleLogin = singleLogin; + } + + public LoginCode getLoginCode() { + return loginCode; + } + + public void setLoginCode(LoginCode loginCode) { + this.loginCode = loginCode; + } + + /** + * 获取验证码生产类 + * + * @return / + */ + public Captcha getCaptcha() { + if (Objects.isNull(loginCode)) { + loginCode = new LoginCode(); + if (Objects.isNull(loginCode.getCodeType())) { + loginCode.setCodeType(LoginCodeEnum.arithmetic); + } + } + Captcha captcha = switchCaptcha(loginCode); + return captcha; + } + + /** + * 依据配置信息生产验证码 + * + * @param loginCode 验证码配置信息 + * @return / + */ + private Captcha switchCaptcha(LoginCode loginCode) { + Captcha captcha; + synchronized (this) { + switch (loginCode.getCodeType()) { + case arithmetic: + // 算术类型 https://gitee.com/whvse/EasyCaptcha + captcha = new ArithmeticCaptcha(loginCode.getWidth(), loginCode.getHeight()); + // 几位数运算,默认是两位 + captcha.setLen(loginCode.getLength()); + break; + case chinese: + captcha = new ChineseCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case chinese_gif: + captcha = new ChineseGifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case gif: + captcha = new GifCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + break; + case spec: + captcha = new SpecCaptcha(loginCode.getWidth(), loginCode.getHeight()); + captcha.setLen(loginCode.getLength()); + default: + throw new BadConfigurationException("验证码配置信息错误!!!正确配置查看 me.zhengjie.modules.security.config.bean.LoginCodeEnum "); + } + } + return captcha; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityProperties.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java similarity index 69% rename from eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityProperties.java rename to eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java index 501b7a19..3b7655bb 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityProperties.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/SecurityProperties.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package me.zhengjie.modules.security.config; +package me.zhengjie.modules.security.config.bean; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -21,36 +21,51 @@ import org.springframework.context.annotation.Configuration; /** * Jwt参数配置 + * * @author Zheng Jie * @date 2019年11月28日 */ @Data -@Configuration -@ConfigurationProperties(prefix = "jwt") public class SecurityProperties { - /** Request Headers : Authorization */ + /** + * Request Headers : Authorization + */ private String header; - /** 令牌前缀,最后留个空格 Bearer */ + /** + * 令牌前缀,最后留个空格 Bearer + */ private String tokenStartWith; - /** 必须使用最少88位的Base64对该令牌进行编码 */ + /** + * 必须使用最少88位的Base64对该令牌进行编码 + */ private String base64Secret; - /** 令牌过期时间 此处单位/毫秒 */ + /** + * 令牌过期时间 此处单位/毫秒 + */ private Long tokenValidityInSeconds; - /** 在线用户 key,根据 key 查询 redis 中在线用户的数据 */ + /** + * 在线用户 key,根据 key 查询 redis 中在线用户的数据 + */ private String onlineKey; - /** 验证码 key */ + /** + * 验证码 key + */ private String codeKey; - /** token 续期检查 */ + /** + * token 续期检查 + */ private Long detect; - /** 续期时间 */ + /** + * 续期时间 + */ private Long renew; public String getTokenStartWith() { diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java index 8f4c39cd..77c84783 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java @@ -17,6 +17,7 @@ package me.zhengjie.modules.security.rest; import cn.hutool.core.util.IdUtil; import com.wf.captcha.ArithmeticCaptcha; +import com.wf.captcha.base.Captcha; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; @@ -27,7 +28,8 @@ import me.zhengjie.annotation.rest.AnonymousGetMapping; import me.zhengjie.annotation.rest.AnonymousPostMapping; import me.zhengjie.config.RsaProperties; import me.zhengjie.exception.BadRequestException; -import me.zhengjie.modules.security.config.SecurityProperties; +import me.zhengjie.modules.security.config.bean.LoginProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.modules.security.security.TokenProvider; import me.zhengjie.modules.security.service.dto.AuthUserDto; import me.zhengjie.modules.security.service.dto.JwtUserDto; @@ -46,6 +48,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @@ -62,16 +65,13 @@ import java.util.concurrent.TimeUnit; @RequiredArgsConstructor @Api(tags = "系统:系统授权接口") public class AuthorizationController { - - @Value("${loginCode.expiration}") - private Long expiration; - @Value("${single.login}") - private Boolean singleLogin; private final SecurityProperties properties; private final RedisUtils redisUtils; private final OnlineUserService onlineUserService; private final TokenProvider tokenProvider; private final AuthenticationManagerBuilder authenticationManagerBuilder; + @Resource + private LoginProperties loginProperties; @Log("用户登录") @ApiOperation("登录授权") @@ -104,7 +104,7 @@ public class AuthorizationController { put("token", properties.getTokenStartWith() + token); put("user", jwtUserDto); }}; - if (singleLogin) { + if (loginProperties.isSingleLogin()) { //踢掉之前已经登录的token onlineUserService.checkLoginOnUser(authUser.getUsername(), token); } @@ -120,15 +120,11 @@ public class AuthorizationController { @ApiOperation("获取验证码") @AnonymousGetMapping(value = "/code") public ResponseEntity getCode() { - // 算术类型 https://gitee.com/whvse/EasyCaptcha - ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36); - // 几位数运算,默认是两位 - captcha.setLen(2); // 获取运算的结果 - String result = captcha.text(); + Captcha captcha = loginProperties.getCaptcha(); String uuid = properties.getCodeKey() + IdUtil.simpleUUID(); // 保存 - redisUtils.set(uuid, result, expiration, TimeUnit.MINUTES); + redisUtils.set(uuid, captcha.text(), loginProperties.getLoginCode().getExpiration(), TimeUnit.MINUTES); // 验证码信息 Map imgResult = new HashMap(2) {{ put("img", captcha.toBase64()); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java index d24c3e12..84723b7d 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java @@ -19,7 +19,7 @@ import cn.hutool.core.util.StrUtil; import io.jsonwebtoken.ExpiredJwtException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import me.zhengjie.modules.security.config.SecurityProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.modules.security.service.dto.OnlineUserDto; import me.zhengjie.modules.security.service.OnlineUserService; import me.zhengjie.utils.SpringContextHolder; diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java index 1c2e7267..91439056 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java @@ -24,7 +24,7 @@ import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import me.zhengjie.modules.security.config.SecurityProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.utils.RedisUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java index fbc492e2..c1fd9c5a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java @@ -16,7 +16,7 @@ package me.zhengjie.modules.security.service; import lombok.extern.slf4j.Slf4j; -import me.zhengjie.modules.security.config.SecurityProperties; +import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.modules.security.service.dto.JwtUserDto; import me.zhengjie.modules.security.service.dto.OnlineUserDto; import me.zhengjie.utils.*; @@ -58,7 +58,7 @@ public class OnlineUserService { try { onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); } catch (Exception e) { - e.printStackTrace(); + log.error(e.getMessage(),e); } redisUtils.set(properties.getOnlineKey() + token, onlineUserDto, properties.getTokenValidityInSeconds()/1000); } diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 34cd066f..12cf5bcc 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -44,9 +44,22 @@ spring: config: multi-statement-allow: true -# 是否限制单用户登录 -single: - login: false +# 登录相关配置 +login: + # 是否限制单用户登录 + single: false + # 验证码 + login-code: + # 验证码类型配置 + code-type: chinese_gif + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + heigth: 36 + # 内容长度 + length: 3 #jwt jwt: @@ -70,13 +83,14 @@ jwt: generator: enabled: true -# IP 本地解析 -ip: - local-parsing: true - #是否开启 swagger-ui swagger: enabled: true +# IP 本地解析 + +ip: + local-parsing: true + # 文件存储路径 file: diff --git a/eladmin-system/src/main/resources/config/application-prod.yml b/eladmin-system/src/main/resources/config/application-prod.yml index 5889e8e2..1c16b5a8 100644 --- a/eladmin-system/src/main/resources/config/application-prod.yml +++ b/eladmin-system/src/main/resources/config/application-prod.yml @@ -46,9 +46,22 @@ spring: config: multi-statement-allow: true -# 是否限制单用户登录 -single: - login: false +# 登录相关配置 +login: + # 是否限制单用户登录 + single: false + # 验证码 + login-code: + # 验证码类型配置 + code-type: chinese_gif + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + heigth: 36 + # 内容长度 + length: 3 #jwt jwt: @@ -100,4 +113,4 @@ file: avatar: C:\eladmin\avatar\ # 文件大小 /M maxSize: 100 - avatarMaxSize: 5 \ No newline at end of file + avatarMaxSize: 5 diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index 271051ce..ee547363 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -50,9 +50,22 @@ qiniu: code: expiration: 300 -#登录图形验证码有效时间/分钟 -loginCode: - expiration: 2 +# 登录相关配置 +login: + # 是否限制单用户登录 + single: false + # 验证码 + login-code: + # 验证码类型配置 + code-type: chinese_gif + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + heigth: 36 + # 内容长度 + length: 3 #密码加密传输,前端公钥加密,后端私钥解密 rsa: @@ -60,4 +73,4 @@ rsa: # sm.ms 图床的 token smms: - token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl \ No newline at end of file + token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl