diff --git a/pom.xml b/pom.xml index ed17d403..072cca42 100644 --- a/pom.xml +++ b/pom.xml @@ -151,6 +151,13 @@ 1 + + + javax.mail + mail + 1.4.7 + + diff --git a/sql/eladmin.sql b/sql/eladmin.sql index ce34c75d..68af9a2d 100644 --- a/sql/eladmin.sql +++ b/sql/eladmin.sql @@ -11,29 +11,25 @@ Target Server Version : 50559 File Encoding : 65001 - Date: 25/12/2018 11:00:27 + Date: 28/12/2018 17:50:46 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- --- Table structure for log +-- Table structure for email_config -- ---------------------------- -DROP TABLE IF EXISTS `log`; -CREATE TABLE `log` ( +DROP TABLE IF EXISTS `email_config`; +CREATE TABLE `email_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, - `createTime` datetime NULL DEFAULT NULL, - `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `exceptionDetail` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `logType` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `requestIp` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `fromUser` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `host` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `pass` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `port` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `user` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3081 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Table structure for menu @@ -46,11 +42,11 @@ CREATE TABLE `menu` ( `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `pid` bigint(20) NOT NULL, - `soft` bigint(20) NOT NULL, + `sort` bigint(20) NOT NULL, `icon` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of menu @@ -64,9 +60,14 @@ INSERT INTO `menu` VALUES (6, '2018-12-18 15:17:48', b'0', '系统监控', NULL, INSERT INTO `menu` VALUES (7, '2018-12-18 15:18:26', b'0', '系统日志', 'monitor/log/index', 6, 11, 'log', 'logs'); INSERT INTO `menu` VALUES (8, '2018-12-18 15:19:01', b'0', '系统缓存', 'monitor/redis/index', 6, 12, 'redis', 'redis'); INSERT INTO `menu` VALUES (9, '2018-12-18 15:19:34', b'1', 'SQL监控', NULL, 6, 14, 'sqlMonitor', 'http://localhost/druid'); -INSERT INTO `menu` VALUES (10, '2018-12-19 13:38:16', b'0', '组件管理', NULL, 0, 20, 'zujian', 'components'); -INSERT INTO `menu` VALUES (11, '2018-12-19 13:38:49', b'0', '图标库', 'components/IconSelect', 10, 21, 'icon', 'icon'); +INSERT INTO `menu` VALUES (10, '2018-12-19 13:38:16', b'0', '组件管理', NULL, 0, 50, 'zujian', 'components'); +INSERT INTO `menu` VALUES (11, '2018-12-19 13:38:49', b'0', '图标库', 'components/IconSelect', 10, 51, 'icon', 'icon'); INSERT INTO `menu` VALUES (12, '2018-12-24 20:37:35', b'0', '实时控制台', 'monitor/log/msg', 6, 13, 'codeConsole', 'msg'); +INSERT INTO `menu` VALUES (13, '2018-12-27 10:11:26', b'0', '三方工具', '', 0, 20, 'tools', 'tools'); +INSERT INTO `menu` VALUES (14, '2018-12-27 10:13:09', b'0', '邮件工具', 'tools/email/index', 13, 21, 'email', 'email'); +INSERT INTO `menu` VALUES (15, '2018-12-27 11:58:25', b'0', '富文本', 'components/Editor', 10, 52, 'fwb', 'tinymce'); +INSERT INTO `menu` VALUES (16, '2018-12-28 09:36:53', b'0', 'SM.MS图床', 'tools/picture/index', 13, 22, 'image', 'pictures'); +INSERT INTO `menu` VALUES (17, '2018-12-28 15:09:49', b'1', '项目地址', '', 0, 0, 'github', 'https://github.com/elunez/eladmin'); -- ---------------------------- -- Table structure for menus_roles @@ -96,6 +97,22 @@ INSERT INTO `menus_roles` VALUES (9, 1); INSERT INTO `menus_roles` VALUES (10, 1); INSERT INTO `menus_roles` VALUES (11, 1); INSERT INTO `menus_roles` VALUES (12, 1); +INSERT INTO `menus_roles` VALUES (13, 1); +INSERT INTO `menus_roles` VALUES (14, 1); +INSERT INTO `menus_roles` VALUES (15, 1); +INSERT INTO `menus_roles` VALUES (16, 1); +INSERT INTO `menus_roles` VALUES (17, 1); +INSERT INTO `menus_roles` VALUES (1, 2); +INSERT INTO `menus_roles` VALUES (2, 2); +INSERT INTO `menus_roles` VALUES (3, 2); +INSERT INTO `menus_roles` VALUES (4, 2); +INSERT INTO `menus_roles` VALUES (5, 2); +INSERT INTO `menus_roles` VALUES (6, 2); +INSERT INTO `menus_roles` VALUES (9, 2); +INSERT INTO `menus_roles` VALUES (12, 2); +INSERT INTO `menus_roles` VALUES (13, 2); +INSERT INTO `menus_roles` VALUES (16, 2); +INSERT INTO `menus_roles` VALUES (17, 2); -- ---------------------------- -- Table structure for permission @@ -108,7 +125,7 @@ CREATE TABLE `permission` ( `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `pid` int(11) NOT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 23 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of permission @@ -119,11 +136,11 @@ INSERT INTO `permission` VALUES (3, '用户查询', '2018-12-03 12:31:35', 'USER INSERT INTO `permission` VALUES (4, '用户创建', '2018-12-03 12:31:35', 'USER_CREATE', 2); INSERT INTO `permission` VALUES (5, '用户编辑', '2018-12-03 12:31:35', 'USER_EDIT', 2); INSERT INTO `permission` VALUES (6, '用户删除', '2018-12-03 12:31:35', 'USER_DELETE', 2); -INSERT INTO `permission` VALUES (7, '角色管理', '2018-12-03 12:28:19', 'ROLE_ALL', 0); -INSERT INTO `permission` VALUES (8, '角色查询', '2018-12-03 12:31:35', 'ROLE_SELECT', 7); -INSERT INTO `permission` VALUES (10, '角色创建', '2018-12-09 20:10:16', 'ROLE_CREATE', 7); -INSERT INTO `permission` VALUES (11, '角色编辑', '2018-12-09 20:10:42', 'ROLE_EDIT', 7); -INSERT INTO `permission` VALUES (12, '角色删除', '2018-12-09 20:11:07', 'ROLE_DELETE', 7); +INSERT INTO `permission` VALUES (7, '角色管理', '2018-12-03 12:28:19', 'ROLES_ALL', 0); +INSERT INTO `permission` VALUES (8, '角色查询', '2018-12-03 12:31:35', 'ROLES_SELECT', 7); +INSERT INTO `permission` VALUES (10, '角色创建', '2018-12-09 20:10:16', 'ROLES_CREATE', 7); +INSERT INTO `permission` VALUES (11, '角色编辑', '2018-12-09 20:10:42', 'ROLES_EDIT', 7); +INSERT INTO `permission` VALUES (12, '角色删除', '2018-12-09 20:11:07', 'ROLES_DELETE', 7); INSERT INTO `permission` VALUES (13, '权限管理', '2018-12-09 20:11:37', 'PERMISSION_ALL', 0); INSERT INTO `permission` VALUES (14, '权限查询', '2018-12-09 20:11:55', 'PERMISSION_SELECT', 13); INSERT INTO `permission` VALUES (15, '权限创建', '2018-12-09 20:14:10', 'PERMISSION_CREATE', 13); @@ -134,6 +151,37 @@ INSERT INTO `permission` VALUES (19, '新增缓存', '2018-12-17 13:53:44', 'RED INSERT INTO `permission` VALUES (20, '缓存查询', '2018-12-17 13:54:07', 'REDIS_SELECT', 18); INSERT INTO `permission` VALUES (21, '缓存编辑', '2018-12-17 13:54:26', 'REDIS_EDIT', 18); INSERT INTO `permission` VALUES (22, '缓存删除', '2018-12-17 13:55:04', 'REDIS_DELETE', 18); +INSERT INTO `permission` VALUES (23, '图床管理', '2018-12-27 20:31:49', 'PICTURE_ALL', 0); +INSERT INTO `permission` VALUES (24, '查询图片', '2018-12-27 20:32:04', 'PICTURE_SELECT', 23); +INSERT INTO `permission` VALUES (25, '上传图片', '2018-12-27 20:32:24', 'PICTURE_UPLOAD', 23); +INSERT INTO `permission` VALUES (26, '删除图片', '2018-12-27 20:32:45', 'PICTURE_DELETE', 23); +INSERT INTO `permission` VALUES (29, '菜单管理', '2018-12-28 17:34:31', 'MENU_ALL', 0); +INSERT INTO `permission` VALUES (30, '菜单查询', '2018-12-28 17:34:41', 'MENU_SELECT', 29); +INSERT INTO `permission` VALUES (31, '菜单创建', '2018-12-28 17:34:52', 'MENU_CREATE', 29); +INSERT INTO `permission` VALUES (32, '菜单编辑', '2018-12-28 17:35:20', 'MENU_EDIT', 29); +INSERT INTO `permission` VALUES (33, '菜单删除', '2018-12-28 17:35:29', 'MENU_DELETE', 29); + +-- ---------------------------- +-- Table structure for picture +-- ---------------------------- +DROP TABLE IF EXISTS `picture`; +CREATE TABLE `picture` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `createTime` datetime NULL DEFAULT NULL, + `delete_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `filename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `height` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `size` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `width` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; + +-- ---------------------------- +-- Records of picture +-- ---------------------------- +INSERT INTO `picture` VALUES (34, '2018-12-28 16:02:42', 'https://sm.ms/delete/JDAtayhFMH56wCXE', '1', '220', '3.73KB ', 'https://i.loli.net/2018/12/28/5c25d8a253445.jpg', 'admin', '229'); -- ---------------------------- -- Table structure for role @@ -145,7 +193,7 @@ CREATE TABLE `role` ( `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of role @@ -170,9 +218,12 @@ CREATE TABLE `roles_permissions` ( -- Records of roles_permissions -- ---------------------------- INSERT INTO `roles_permissions` VALUES (1, 1); -INSERT INTO `roles_permissions` VALUES (2, 1); INSERT INTO `roles_permissions` VALUES (2, 3); -INSERT INTO `roles_permissions` VALUES (2, 4); +INSERT INTO `roles_permissions` VALUES (2, 8); +INSERT INTO `roles_permissions` VALUES (2, 14); +INSERT INTO `roles_permissions` VALUES (2, 19); +INSERT INTO `roles_permissions` VALUES (2, 23); +INSERT INTO `roles_permissions` VALUES (2, 30); -- ---------------------------- -- Table structure for user @@ -190,12 +241,13 @@ CREATE TABLE `user` ( PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `UK_kpubos9gc2cvtkb0thktkbkes`(`email`) USING BTREE, UNIQUE INDEX `username`(`username`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'https://i.loli.net/2018/12/06/5c08894d8de21.jpg', '2018-08-23 09:11:56', 'zhengjie@tom.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'admin', '2018-11-23 10:12:36'); +INSERT INTO `user` VALUES (3, 'https://i.loli.net/2018/12/06/5c08894d8de21.jpg', '2018-12-27 20:05:26', 'test@qq.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'test', NULL); -- ---------------------------- -- Table structure for users_roles @@ -214,41 +266,21 @@ CREATE TABLE `users_roles` ( -- Records of users_roles -- ---------------------------- INSERT INTO `users_roles` VALUES (1, 1); +INSERT INTO `users_roles` VALUES (3, 2); -- ---------------------------- --- Table structure for visits +-- Table structure for verification_code -- ---------------------------- -DROP TABLE IF EXISTS `visits`; -CREATE TABLE `visits` ( +DROP TABLE IF EXISTS `verification_code`; +CREATE TABLE `verification_code` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, - `date` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, - `ip_counts` bigint(20) NULL DEFAULT NULL, - `pv_counts` bigint(20) NULL DEFAULT NULL, - `weekDay` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `createTime` datetime NULL DEFAULT NULL, + `status` bit(1) NULL DEFAULT NULL, + `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `value` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; --- ---------------------------- --- Records of visits --- ---------------------------- -INSERT INTO `visits` VALUES (1, '2018-12-06', 30, 45, 'Thu', '2018-12-06 18:06:14'); -INSERT INTO `visits` VALUES (2, '2018-12-07', 10, 30, 'Fri', '2018-12-07 18:06:19'); -INSERT INTO `visits` VALUES (3, '2018-12-08', 10, 30, 'Sat', '2018-12-08 18:06:23'); -INSERT INTO `visits` VALUES (4, '2018-12-09', 56, 50, 'Sun', '2018-12-09 18:06:27'); -INSERT INTO `visits` VALUES (5, '2018-12-10', 20, 50, 'Mon', '2018-12-10 18:06:32'); -INSERT INTO `visits` VALUES (6, '2018-12-11', 79, 50, 'Tue', '2018-12-11 18:06:35'); -INSERT INTO `visits` VALUES (7, '2018-12-12', 54, 23, 'Wed', '2018-12-12 18:06:38'); -INSERT INTO `visits` VALUES (11, '2018-12-13', 2, 2, 'Thu', '2018-12-13 20:49:27'); -INSERT INTO `visits` VALUES (13, '2018-12-14', 1, 27, 'Fri', '2018-12-14 09:21:00'); -INSERT INTO `visits` VALUES (15, '2018-12-17', 1, 19, 'Mon', '2018-12-17 12:49:28'); -INSERT INTO `visits` VALUES (16, '2018-12-18', 1, 72, 'Tue', '2018-12-18 15:13:33'); -INSERT INTO `visits` VALUES (26, '2018-12-19', 1, 51, 'Wed', '2018-12-19 12:54:12'); -INSERT INTO `visits` VALUES (27, '2018-12-20', 1, 226, 'Thu', '2018-12-20 09:21:13'); -INSERT INTO `visits` VALUES (28, '2018-12-21', 1, 80, 'Fri', '2018-12-21 09:38:04'); -INSERT INTO `visits` VALUES (29, '2018-12-22', 1, 42, 'Sat', '2018-12-22 10:06:59'); -INSERT INTO `visits` VALUES (30, '2018-12-23', 1, 2, 'Sun', '2018-12-23 11:16:52'); -INSERT INTO `visits` VALUES (35, '2018-12-24', 1, 8, 'Mon', '2018-12-24 19:12:01'); -INSERT INTO `visits` VALUES (36, '2018-12-25', 1, 6, 'Tue', '2018-12-25 00:12:35'); SET FOREIGN_KEY_CHECKS = 1; diff --git a/src/main/java/me/zhengjie/common/redis/RedisConfig.java b/src/main/java/me/zhengjie/common/redis/RedisConfig.java index 4159f5e3..0f55051d 100644 --- a/src/main/java/me/zhengjie/common/redis/RedisConfig.java +++ b/src/main/java/me/zhengjie/common/redis/RedisConfig.java @@ -94,6 +94,7 @@ public class RedisConfig extends CachingConfigurerSupport { // 建议使用这种方式,小范围指定白名单 ParserConfig.getGlobalInstance().addAccept("me.zhengjie.system.service.dto"); ParserConfig.getGlobalInstance().addAccept("me.zhengjie.system.domain"); + ParserConfig.getGlobalInstance().addAccept("me.zhengjie.tools.domain"); // key的序列化采用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); diff --git a/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java b/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java new file mode 100644 index 00000000..be69087a --- /dev/null +++ b/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java @@ -0,0 +1,32 @@ +package me.zhengjie.common.utils; + +/** + * 常用静态常量 + * @author jie + * @date 2018-12-26 + */ +public class ElAdminConstant { + + /** + * 用于七牛云zone与机房对应关系 + */ + public static class QiNiu{ + + public static final String HUAD = "华东"; + + public static final String HUAB = "华北"; + + public static final String HUAN = "华南"; + + public static final String BEIM = "北美"; + + public static final String DNY = "东南亚"; + } + + /** + * 常用接口 + */ + public static class Url{ + public static final String SM_MS_URL = "https://sm.ms/api/upload"; + } +} diff --git a/src/main/java/me/zhengjie/common/utils/FileUtil.java b/src/main/java/me/zhengjie/common/utils/FileUtil.java new file mode 100644 index 00000000..01dba3cf --- /dev/null +++ b/src/main/java/me/zhengjie/common/utils/FileUtil.java @@ -0,0 +1,119 @@ +package me.zhengjie.common.utils; + +import cn.hutool.core.util.IdUtil; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; + +/** + * File工具类 + * @author jie + * @date 2018-12-27 + */ +public class FileUtil { + + /** + * 定义GB的计算常量 + */ + private static final int GB = 1024 * 1024 * 1024; + /** + * 定义MB的计算常量 + */ + private static final int MB = 1024 * 1024; + /** + * 定义KB的计算常量 + */ + private static final int KB = 1024; + + /** + * 格式化小数 + */ + private static final DecimalFormat DF = new DecimalFormat("0.00"); + + /** + * MultipartFile转File + * @param multipartFile + * @return + */ + public static File toFile(MultipartFile multipartFile){ + // 获取文件名 + String fileName = multipartFile.getOriginalFilename(); + // 获取文件后缀 + String prefix="."+getExtensionName(fileName); + File file = null; + try { + // 用uuid作为文件名,防止生成的临时文件重复 + file = File.createTempFile(IdUtil.simpleUUID(), prefix); + // MultipartFile to File + multipartFile.transferTo(file); + } catch (IOException e) { + e.printStackTrace(); + } + return file; + } + + /** + * 删除 + * @param files + */ + public static void deleteFile(File... files) { + for (File file : files) { + if (file.exists()) { + file.delete(); + } + } + } + + /** + * 获取文件扩展名 + * @param filename + * @return + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot >-1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } + + /** + * Java文件操作 获取不带扩展名的文件名 + * @param filename + * @return + */ + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot >-1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + /** + * 文件大小转换 + * @param size + * @return + */ + public static String getSize(int size){ + String resultSize = ""; + if (size / GB >= 1) { + //如果当前Byte的值大于等于1GB + resultSize = DF.format(size / (float) GB) + "GB "; + } else if (size / MB >= 1) { + //如果当前Byte的值大于等于1MB + resultSize = DF.format(size / (float) MB) + "MB "; + } else if (size / KB >= 1) { + //如果当前Byte的值大于等于1KB + resultSize = DF.format(size / (float) KB) + "KB "; + } else { + resultSize = size + "B "; + } + return resultSize; + } +} diff --git a/src/main/java/me/zhengjie/core/utils/EncryptUtils.java b/src/main/java/me/zhengjie/core/utils/EncryptUtils.java index 4522b156..3d8164bf 100644 --- a/src/main/java/me/zhengjie/core/utils/EncryptUtils.java +++ b/src/main/java/me/zhengjie/core/utils/EncryptUtils.java @@ -1,6 +1,11 @@ package me.zhengjie.core.utils; import org.springframework.util.DigestUtils; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; /** * 加密 @@ -9,6 +14,77 @@ import org.springframework.util.DigestUtils; */ public class EncryptUtils { + private static String strKey = "Passw0rd", strParam = "Passw0rd"; + + /** + * 对称加密 + * @param source + * @return + * @throws Exception + */ + public static String desEncrypt(String source) throws Exception { + if (source == null || source.length() == 0){ + return null; + } + Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + DESKeySpec desKeySpec = new DESKeySpec(strKey.getBytes("UTF-8")); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + IvParameterSpec iv = new IvParameterSpec(strParam.getBytes("UTF-8")); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); + return byte2hex( + cipher.doFinal(source.getBytes("UTF-8"))).toUpperCase(); + } + + public static String byte2hex(byte[] inStr) { + String stmp; + StringBuffer out = new StringBuffer(inStr.length * 2); + for (int n = 0; n < inStr.length; n++) { + stmp = Integer.toHexString(inStr[n] & 0xFF); + if (stmp.length() == 1) { + // 如果是0至F的单位字符串,则添加0 + out.append("0" + stmp); + } else { + out.append(stmp); + } + } + return out.toString(); + } + + + public static byte[] hex2byte(byte[] b) { + if ((b.length % 2) != 0){ + throw new IllegalArgumentException("长度不是偶数"); + } + byte[] b2 = new byte[b.length / 2]; + for (int n = 0; n < b.length; n += 2) { + String item = new String(b, n, 2); + b2[n / 2] = (byte) Integer.parseInt(item, 16); + } + return b2; + } + + /** + * 对称解密 + * @param source + * @return + * @throws Exception + */ + public static String desDecrypt(String source) throws Exception { + if (source == null || source.length() == 0){ + return null; + } + byte[] src = hex2byte(source.getBytes()); + Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + DESKeySpec desKeySpec = new DESKeySpec(strKey.getBytes("UTF-8")); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = keyFactory.generateSecret(desKeySpec); + IvParameterSpec iv = new IvParameterSpec(strParam.getBytes("UTF-8")); + cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); + byte[] retByte = cipher.doFinal(src); + return new String(retByte); + } + /** * 密码加密 * @param password diff --git a/src/main/java/me/zhengjie/system/domain/Menu.java b/src/main/java/me/zhengjie/system/domain/Menu.java index 9845f884..170f7658 100644 --- a/src/main/java/me/zhengjie/system/domain/Menu.java +++ b/src/main/java/me/zhengjie/system/domain/Menu.java @@ -26,7 +26,7 @@ public class Menu { private String name; @Column(unique = true) - private Long soft; + private Long sort; @Column(name = "path") private String path; diff --git a/src/main/java/me/zhengjie/system/domain/VerificationCode.java b/src/main/java/me/zhengjie/system/domain/VerificationCode.java new file mode 100644 index 00000000..7c8f4521 --- /dev/null +++ b/src/main/java/me/zhengjie/system/domain/VerificationCode.java @@ -0,0 +1,45 @@ +package me.zhengjie.system.domain; + +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * @author jie + * @date 2018-12-26 + */ +@Data +@Entity +@Table(name = "verification_code") +public class VerificationCode { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String code; + + /** + * true 为有效,false 为无效 + */ + private Boolean status = true; + + + /** + * 类型 :phone 和 email + */ + private String type; + + /** + * 具体的phone与email + */ + private String value; + + /** + * 创建日期 + */ + @CreationTimestamp + private Timestamp createTime; +} diff --git a/src/main/java/me/zhengjie/system/repository/MenuRepository.java b/src/main/java/me/zhengjie/system/repository/MenuRepository.java index 3951d561..b058fe88 100644 --- a/src/main/java/me/zhengjie/system/repository/MenuRepository.java +++ b/src/main/java/me/zhengjie/system/repository/MenuRepository.java @@ -25,7 +25,7 @@ public interface MenuRepository extends JpaRepository, JpaSpecificat * @param roleSet * @return */ - Set findByRolesOrderBySoft(Set roleSet); + Set findByRolesOrderBySort(Set roleSet); /** * findByPid diff --git a/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java b/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java new file mode 100644 index 00000000..813bb86a --- /dev/null +++ b/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.system.repository; + +import me.zhengjie.system.domain.VerificationCode; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author jie + * @date 2018-12-26 + */ +public interface VerificationCodeRepository extends JpaRepository { + +} diff --git a/src/main/java/me/zhengjie/system/rest/MenuController.java b/src/main/java/me/zhengjie/system/rest/MenuController.java index de892e64..90bf3ebb 100644 --- a/src/main/java/me/zhengjie/system/rest/MenuController.java +++ b/src/main/java/me/zhengjie/system/rest/MenuController.java @@ -77,7 +77,7 @@ public class MenuController { @Log(description = "新增菜单") @PostMapping(value = "/menus") - @PreAuthorize("hasAnyRole('ADMIN','PERMISSION_ALL','PERMISSION_CREATE')") + @PreAuthorize("hasAnyRole('ADMIN','MENU_ALL','MENU_CREATE')") public ResponseEntity create(@Validated @RequestBody Menu resources){ if (resources.getId() != null) { throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); @@ -87,7 +87,7 @@ public class MenuController { @Log(description = "修改菜单") @PutMapping(value = "/menus") - @PreAuthorize("hasAnyRole('ADMIN','PERMISSION_ALL','PERMISSION_EDIT')") + @PreAuthorize("hasAnyRole('ADMIN','MENU_ALL','MENU_EDIT')") public ResponseEntity update(@Validated @RequestBody Menu resources){ if (resources.getId() == null) { throw new BadRequestException(ENTITY_NAME +" ID Can not be empty"); @@ -98,7 +98,7 @@ public class MenuController { @Log(description = "删除菜单") @DeleteMapping(value = "/menus/{id}") - @PreAuthorize("hasAnyRole('ADMIN','PERMISSION_ALL','PERMISSION_DELETE')") + @PreAuthorize("hasAnyRole('ADMIN','MENU_ALL','MENU_DELETE')") public ResponseEntity delete(@PathVariable Long id){ menuService.delete(id); return new ResponseEntity(HttpStatus.OK); diff --git a/src/main/java/me/zhengjie/system/rest/PermissionController.java b/src/main/java/me/zhengjie/system/rest/PermissionController.java index 5b64e5e7..bdf5ed91 100644 --- a/src/main/java/me/zhengjie/system/rest/PermissionController.java +++ b/src/main/java/me/zhengjie/system/rest/PermissionController.java @@ -42,7 +42,7 @@ public class PermissionController { * @return */ @GetMapping(value = "/permissions/tree") - @PreAuthorize("hasAnyRole('ADMIN','PERMISSION_ALL','ROLE_ALL','ROLE_ADD','ROLE_EDIT')") + @PreAuthorize("hasAnyRole('ADMIN','PERMISSION_ALL','PERMISSION_SELECT','ROLES_SELECT','ROLES_ALL')") public ResponseEntity getRoleTree(){ return new ResponseEntity(permissionService.getPermissionTree(permissionService.findByPid(0L)),HttpStatus.OK); } diff --git a/src/main/java/me/zhengjie/system/rest/RoleController.java b/src/main/java/me/zhengjie/system/rest/RoleController.java index 9c2afc74..573f1478 100644 --- a/src/main/java/me/zhengjie/system/rest/RoleController.java +++ b/src/main/java/me/zhengjie/system/rest/RoleController.java @@ -31,7 +31,7 @@ public class RoleController { private static final String ENTITY_NAME = "role"; @GetMapping(value = "/roles/{id}") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','ROLE_SELECT')") + @PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_SELECT')") public ResponseEntity getRoles(@PathVariable Long id){ return new ResponseEntity(roleService.findById(id), HttpStatus.OK); } @@ -41,21 +41,21 @@ public class RoleController { * @return */ @GetMapping(value = "/roles/tree") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','USER_ALL','USER_ADD','USER_EDIT')") + @PreAuthorize("hasAnyRole('ADMIN','MENU_ALL','MENU_SELECT','ROLES_ALL','USER_ALL','USER_SELECT')") public ResponseEntity getRoleTree(){ return new ResponseEntity(roleService.getRoleTree(),HttpStatus.OK); } @Log(description = "查询角色") @GetMapping(value = "/roles") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','ROLE_SELECT')") + @PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_SELECT')") public ResponseEntity getRoles(RoleDTO resources, Pageable pageable){ return new ResponseEntity(roleQueryService.queryAll(resources,pageable),HttpStatus.OK); } @Log(description = "新增角色") @PostMapping(value = "/roles") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','ROLE_CREATE')") + @PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_CREATE')") public ResponseEntity create(@Validated @RequestBody Role resources){ if (resources.getId() != null) { throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID"); @@ -65,7 +65,7 @@ public class RoleController { @Log(description = "修改角色") @PutMapping(value = "/roles") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','ROLE_EDIT')") + @PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_EDIT')") public ResponseEntity update(@Validated @RequestBody Role resources){ if (resources.getId() == null) { throw new BadRequestException(ENTITY_NAME +" ID Can not be empty"); @@ -76,7 +76,7 @@ public class RoleController { @Log(description = "删除角色") @DeleteMapping(value = "/roles/{id}") - @PreAuthorize("hasAnyRole('ADMIN','ROLE_ALL','ROLE_DELETE')") + @PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_DELETE')") public ResponseEntity delete(@PathVariable Long id){ roleService.delete(id); return new ResponseEntity(HttpStatus.OK); diff --git a/src/main/java/me/zhengjie/system/rest/VerificationCodeController.java b/src/main/java/me/zhengjie/system/rest/VerificationCodeController.java new file mode 100644 index 00000000..f0ea7d68 --- /dev/null +++ b/src/main/java/me/zhengjie/system/rest/VerificationCodeController.java @@ -0,0 +1,33 @@ +package me.zhengjie.system.rest; + +import me.zhengjie.system.domain.VerificationCode; +import me.zhengjie.system.service.VerificationCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +/** + * @author jie + * @date 2018-12-26 + */ +@RestController +@RequestMapping("api") +public class VerificationCodeController { + + @Autowired + private VerificationCodeService verificationCodeService; + + @PostMapping(value = "/code/sendEmail") + public ResponseEntity sendEmail(@RequestBody VerificationCode code){ + code.setType("email"); + verificationCodeService.sendEmail(code); + return new ResponseEntity(HttpStatus.OK); + } + + @GetMapping(value = "/code/validated") + public ResponseEntity validated(VerificationCode code){ + verificationCodeService.validated(code); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/src/main/java/me/zhengjie/system/service/VerificationCodeService.java b/src/main/java/me/zhengjie/system/service/VerificationCodeService.java new file mode 100644 index 00000000..db6e5f52 --- /dev/null +++ b/src/main/java/me/zhengjie/system/service/VerificationCodeService.java @@ -0,0 +1,22 @@ +package me.zhengjie.system.service; + +import me.zhengjie.system.domain.VerificationCode; + +/** + * @author jie + * @date 2018-12-26 + */ +public interface VerificationCodeService { + + /** + * 发送邮件验证码 + * @param code + */ + void sendEmail(VerificationCode code); + + /** + * 验证 + * @param code + */ + void validated(VerificationCode code); +} diff --git a/src/main/java/me/zhengjie/system/service/dto/MenuDTO.java b/src/main/java/me/zhengjie/system/service/dto/MenuDTO.java index 6cb15f61..03121b66 100644 --- a/src/main/java/me/zhengjie/system/service/dto/MenuDTO.java +++ b/src/main/java/me/zhengjie/system/service/dto/MenuDTO.java @@ -16,7 +16,7 @@ public class MenuDTO { private String name; - private Long soft; + private Long sort; private String path; diff --git a/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java b/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java index dd54226a..c21a6876 100644 --- a/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java +++ b/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java @@ -37,7 +37,12 @@ public class MenuServiceImpl implements MenuService { @Override public List findByRoles(Set roles) { - Set menus = menuRepository.findByRolesOrderBySoft(roles); + Set menus = new LinkedHashSet<>(); + for (Role role : roles) { + Set roleSet = new HashSet<>(); + roleSet.add(role); + menus.addAll(menuRepository.findByRolesOrderBySort(roleSet)); + } return menus.stream().map(menuMapper::toDto).collect(Collectors.toList()); } @@ -67,7 +72,7 @@ public class MenuServiceImpl implements MenuService { menu.setIcon(resources.getIcon()); menu.setIFrame(resources.getIFrame()); menu.setPid(resources.getPid()); - menu.setSoft(resources.getSoft()); + menu.setSort(resources.getSort()); menu.setRoles(resources.getRoles()); menuRepository.save(menu); } @@ -137,6 +142,8 @@ public class MenuServiceImpl implements MenuService { MenuVo menuVo = new MenuVo(); menuVo.setName(menuDTO.getName()); menuVo.setPath(menuDTO.getPath()); + + // 如果不是外链 if(!menuDTO.getIFrame()){ if(menuDTO.getPid().equals(0L)){ //一级目录需要加斜杠,不然访问不了 @@ -149,6 +156,24 @@ public class MenuServiceImpl implements MenuService { if(menuDTOList!=null && menuDTOList.size()!=0){ menuVo.setAlwaysShow(true); menuVo.setChildren(buildMenus(menuDTOList)); + // 处理是一级菜单并且没有子菜单的情况 + } else if(menuDTO.getPid().equals(0L)){ + MenuVo menuVo1 = new MenuVo(); + menuVo1.setMeta(menuVo.getMeta()); + // 非外链 + if(!menuDTO.getIFrame()){ + menuVo1.setPath("index"); + menuVo1.setName(menuVo.getName()); + menuVo1.setComponent(menuVo.getComponent()); + } else { + menuVo1.setPath(menuDTO.getPath()); + } + menuVo.setName(null); + menuVo.setMeta(null); + menuVo.setComponent("Layout"); + List list1 = new ArrayList(); + list1.add(menuVo1); + menuVo.setChildren(list1); } list.add(menuVo); } diff --git a/src/main/java/me/zhengjie/system/service/impl/VerificationCodeServiceImpl.java b/src/main/java/me/zhengjie/system/service/impl/VerificationCodeServiceImpl.java new file mode 100644 index 00000000..da922c66 --- /dev/null +++ b/src/main/java/me/zhengjie/system/service/impl/VerificationCodeServiceImpl.java @@ -0,0 +1,23 @@ +package me.zhengjie.system.service.impl; + +import me.zhengjie.system.domain.VerificationCode; +import me.zhengjie.system.service.VerificationCodeService; +import org.springframework.stereotype.Service; + +/** + * @author jie + * @date 2018-12-26 + */ +@Service +public class VerificationCodeServiceImpl implements VerificationCodeService { + + @Override + public void sendEmail(VerificationCode code) { + + } + + @Override + public void validated(VerificationCode code) { + + } +} diff --git a/src/main/java/me/zhengjie/tools/config/MultipartConfig.java b/src/main/java/me/zhengjie/tools/config/MultipartConfig.java new file mode 100644 index 00000000..528d4b5b --- /dev/null +++ b/src/main/java/me/zhengjie/tools/config/MultipartConfig.java @@ -0,0 +1,30 @@ +package me.zhengjie.tools.config; + +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import javax.servlet.MultipartConfigElement; +import java.io.File; + +/** + * @date 2018-12-28 + * @author https://blog.csdn.net/llibin1024530411/article/details/79474953 + */ +@Configuration +public class MultipartConfig { + + /** + * 文件上传临时路径 + */ + @Bean + MultipartConfigElement multipartConfigElement() { + MultipartConfigFactory factory = new MultipartConfigFactory(); + String location = System.getProperty("user.dir") + "/data/tmp"; + File tmpFile = new File(location); + if (!tmpFile.exists()) { + tmpFile.mkdirs(); + } + factory.setLocation(location); + return factory.createMultipartConfig(); + } +} \ No newline at end of file diff --git a/src/main/java/me/zhengjie/tools/domain/EmailConfig.java b/src/main/java/me/zhengjie/tools/domain/EmailConfig.java new file mode 100644 index 00000000..45aac7b9 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/domain/EmailConfig.java @@ -0,0 +1,48 @@ +package me.zhengjie.tools.domain; + +import lombok.Data; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 邮件配置类,数据存覆盖式存入数据存 + * @author jie + * @date 2018-12-26 + */ +@Entity +@Data +@Table(name = "email_config") +public class EmailConfig implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /** + *邮件服务器SMTP地址 + */ + @NotBlank + private String host; + + /** + * 邮件服务器SMTP端口 + */ + @NotBlank + private String port; + + /** + * 发件者用户名,默认为发件人邮箱前缀 + */ + @NotBlank + private String user; + + @NotBlank + private String pass; + + /** + * 发件人 + */ + @NotBlank + private String fromUser; +} diff --git a/src/main/java/me/zhengjie/tools/domain/Picture.java b/src/main/java/me/zhengjie/tools/domain/Picture.java new file mode 100644 index 00000000..6d6565c3 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/domain/Picture.java @@ -0,0 +1,51 @@ +package me.zhengjie.tools.domain; + +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * sm.ms图床 + * + * @author jie + * @date 2018-12-27 + */ +@Data +@Entity +@Table(name = "picture") +public class Picture implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String filename; + + private String url; + + private String size; + + private String height; + + private String width; + + /** + * delete URl + */ + @Column(name = "delete_url") + private String delete; + + private String username; + + @CreationTimestamp + private Timestamp createTime; + + @Override + public String toString() { + return "Picture{" + + "filename='" + filename + '\'' + + '}'; + } +} diff --git a/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java b/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java new file mode 100644 index 00000000..cb8c78cc --- /dev/null +++ b/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java @@ -0,0 +1,29 @@ +package me.zhengjie.tools.domain.vo; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.ArrayList; +import java.util.List; + +/** + * 发送邮件时,接收参数的类 + * @author 郑杰 + * @date 2018/09/28 12:02:14 + */ +@Data +public class EmailVo { + + /** + * 收件人,支持多个收件人,用逗号分隔 + */ + @NotEmpty + private List tos; + + @NotBlank + private String subject; + + @NotBlank + private String content; +} diff --git a/src/main/java/me/zhengjie/tools/repository/EmailRepository.java b/src/main/java/me/zhengjie/tools/repository/EmailRepository.java new file mode 100644 index 00000000..073df371 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/repository/EmailRepository.java @@ -0,0 +1,11 @@ +package me.zhengjie.tools.repository; + +import me.zhengjie.tools.domain.EmailConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author jie + * @date 2018-12-26 + */ +public interface EmailRepository extends JpaRepository { +} diff --git a/src/main/java/me/zhengjie/tools/repository/PictureRepository.java b/src/main/java/me/zhengjie/tools/repository/PictureRepository.java new file mode 100644 index 00000000..49d418c2 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/repository/PictureRepository.java @@ -0,0 +1,12 @@ +package me.zhengjie.tools.repository; + +import me.zhengjie.tools.domain.Picture; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** + * @author jie + * @date 2018-12-27 + */ +public interface PictureRepository extends JpaRepository, JpaSpecificationExecutor { +} diff --git a/src/main/java/me/zhengjie/tools/rest/EmailController.java b/src/main/java/me/zhengjie/tools/rest/EmailController.java new file mode 100644 index 00000000..a30f6f2e --- /dev/null +++ b/src/main/java/me/zhengjie/tools/rest/EmailController.java @@ -0,0 +1,50 @@ +package me.zhengjie.tools.rest; + +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.common.aop.log.Log; +import me.zhengjie.tools.domain.EmailConfig; +import me.zhengjie.tools.domain.vo.EmailVo; +import me.zhengjie.tools.service.EmailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * 发送邮件 + * @author 郑杰 + * @date 2018/09/28 6:55:53 + */ +@Slf4j +@RestController +@RequestMapping("api") +public class EmailController { + + @Autowired + private EmailService emailService; + + @PreAuthorize("hasAnyRole('ADMIN')") + @GetMapping(value = "/email") + public ResponseEntity get(){ + return new ResponseEntity(emailService.find(),HttpStatus.OK); + } + + @PreAuthorize("hasAnyRole('ADMIN')") + @Log(description = "配置邮件") + @PutMapping(value = "/email") + public ResponseEntity emailConfig(@Validated @RequestBody EmailConfig emailConfig){ + emailService.update(emailConfig,emailService.find()); + return new ResponseEntity(HttpStatus.OK); + } + + @PreAuthorize("hasAnyRole('ADMIN')") + @Log(description = "发送邮件") + @PostMapping(value = "/email") + public ResponseEntity send(@Validated @RequestBody EmailVo emailVo) throws Exception { + log.warn("REST request to send Email : {}" +emailVo); + emailService.send(emailVo,emailService.find()); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/src/main/java/me/zhengjie/tools/rest/PictureController.java b/src/main/java/me/zhengjie/tools/rest/PictureController.java new file mode 100644 index 00000000..6e28a776 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/rest/PictureController.java @@ -0,0 +1,74 @@ +package me.zhengjie.tools.rest; + +import me.zhengjie.common.aop.log.Log; +import me.zhengjie.common.utils.RequestHolder; +import me.zhengjie.core.utils.JwtTokenUtil; +import me.zhengjie.tools.domain.Picture; +import me.zhengjie.tools.service.PictureService; +import me.zhengjie.tools.service.query.PictureQueryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.util.HashMap; +import java.util.Map; + +/** + * @author 郑杰 + * @date 2018/09/20 14:13:32 + */ +@RestController +@RequestMapping("/api") +public class PictureController { + + @Autowired + private PictureService pictureService; + + @Autowired + private PictureQueryService pictureQueryService; + + @Autowired + private JwtTokenUtil jwtTokenUtil; + + @Log(description = "查询图片") + @PreAuthorize("hasAnyRole('ADMIN','PICTURE_ALL','PICTURE_SELECT')") + @GetMapping(value = "/pictures") + public ResponseEntity getRoles(Picture resources, Pageable pageable){ + return new ResponseEntity(pictureQueryService.queryAll(resources,pageable),HttpStatus.OK); + } + + /** + * 上传图片 + * @param file + * @return + * @throws Exception + */ + @Log(description = "上传图片") + @PreAuthorize("hasAnyRole('ADMIN','PICTURE_ALL','PICTURE_UPLOAD')") + @PostMapping(value = "/pictures") + public ResponseEntity upload(@RequestParam MultipartFile file){ + String userName = jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()); + Picture picture = pictureService.upload(file,userName); + Map map = new HashMap(); + map.put("errno",0); + map.put("id",picture.getId()); + map.put("data",new String[]{picture.getUrl()}); + return new ResponseEntity(map,HttpStatus.OK); + } + + /** + * 删除图片 + * @param id + * @return + */ + @Log(description = "删除图片") + @PreAuthorize("hasAnyRole('ADMIN','PICTURE_ALL','PICTURE_DELETE')") + @DeleteMapping(value = "/pictures/{id}") + public ResponseEntity delete(@PathVariable Long id) { + pictureService.delete(pictureService.findById(id)); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/src/main/java/me/zhengjie/tools/service/EmailService.java b/src/main/java/me/zhengjie/tools/service/EmailService.java new file mode 100644 index 00000000..4e85bf33 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/service/EmailService.java @@ -0,0 +1,41 @@ +package me.zhengjie.tools.service; + +import me.zhengjie.tools.domain.EmailConfig; +import me.zhengjie.tools.domain.vo.EmailVo; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.scheduling.annotation.Async; + +/** + * @author jie + * @date 2018-12-26 + */ +@CacheConfig(cacheNames = "email") +public interface EmailService { + + /** + * 更新邮件配置 + * @param emailConfig + * @param old + * @return + */ + @CachePut(key = "'1'") + EmailConfig update(EmailConfig emailConfig, EmailConfig old); + + /** + * 查询配置 + * @return + */ + @Cacheable(key = "'1'") + EmailConfig find(); + + /** + * 发送邮件 + * @param emailVo + * @param emailConfig + * @throws Exception + */ + @Async + void send(EmailVo emailVo, EmailConfig emailConfig) throws Exception; +} diff --git a/src/main/java/me/zhengjie/tools/service/PictureService.java b/src/main/java/me/zhengjie/tools/service/PictureService.java new file mode 100644 index 00000000..4d9d1a1b --- /dev/null +++ b/src/main/java/me/zhengjie/tools/service/PictureService.java @@ -0,0 +1,39 @@ +package me.zhengjie.tools.service; + +import me.zhengjie.tools.domain.Picture; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.web.multipart.MultipartFile; + +/** + * @author jie + * @date 2018-12-27 + */ +@CacheConfig(cacheNames = "picture") +public interface PictureService { + + /** + * 上传图片 + * @param file + * @param username + * @return + */ + @CacheEvict(allEntries = true) + Picture upload(MultipartFile file, String username); + + /** + * 根据ID查询 + * @param id + * @return + */ + @Cacheable(key = "#p0") + Picture findById(Long id); + + /** + * 删除图片 + * @param picture + */ + @CacheEvict(allEntries = true) + void delete(Picture picture); +} diff --git a/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java new file mode 100644 index 00000000..ffc80a92 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java @@ -0,0 +1,89 @@ +package me.zhengjie.tools.service.impl; + +import cn.hutool.extra.mail.MailAccount; +import cn.hutool.extra.mail.MailUtil; +import me.zhengjie.common.exception.BadRequestException; +import me.zhengjie.core.utils.EncryptUtils; +import me.zhengjie.tools.domain.EmailConfig; +import me.zhengjie.tools.domain.vo.EmailVo; +import me.zhengjie.tools.repository.EmailRepository; +import me.zhengjie.tools.service.EmailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + +/** + * @author jie + * @date 2018-12-26 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class EmailServiceImpl implements EmailService { + + @Autowired + private EmailRepository emailRepository; + + @Override + @Transactional(rollbackFor = Exception.class) + public EmailConfig update(EmailConfig emailConfig, EmailConfig old) { + try { + if(!emailConfig.getPass().equals(old.getPass())){ + // 对称加密 + emailConfig.setPass(EncryptUtils.desEncrypt(emailConfig.getPass())); + } + } catch (Exception e) { + e.printStackTrace(); + } + emailRepository.saveAndFlush(emailConfig); + return emailConfig; + } + + @Override + public EmailConfig find() { + Optional emailConfig = emailRepository.findById(1L); + if(emailConfig.isPresent()){ + return emailConfig.get(); + } else { + return new EmailConfig(); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void send(EmailVo emailVo, EmailConfig emailConfig){ + if(emailConfig == null){ + throw new BadRequestException("请先配置,再操作"); + } + /** + * 封装 + */ + MailAccount account = new MailAccount(); + account.setHost(emailConfig.getHost()); + account.setPort(Integer.parseInt(emailConfig.getPort())); + account.setAuth(true); + try { + // 对称解密 + account.setPass(EncryptUtils.desDecrypt(emailConfig.getPass())); + } catch (Exception e) { + throw new BadRequestException(e.getMessage()); + } + account.setFrom(emailConfig.getUser()+"<"+emailConfig.getFromUser()+">"); + //ssl方式发送 + account.setStartttlsEnable(true); + String content = emailVo.getContent()+ "

----- 邮件来自 eladmin 后台管理系统

"; + /** + * 发送 + */ + try { + MailUtil.send(account, + emailVo.getTos(), + emailVo.getSubject(), + content, + true); + }catch (Exception e){ + throw new BadRequestException(e.getMessage()); + } + } +} diff --git a/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java new file mode 100644 index 00000000..3deec4f9 --- /dev/null +++ b/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java @@ -0,0 +1,102 @@ +package me.zhengjie.tools.service.impl; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.common.exception.BadRequestException; +import me.zhengjie.common.utils.FileUtil; +import me.zhengjie.common.utils.ValidationUtil; +import me.zhengjie.tools.domain.Picture; +import me.zhengjie.tools.repository.PictureRepository; +import me.zhengjie.tools.service.PictureService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.util.Arrays; +import java.util.Optional; + +/** + * @author jie + * @date 2018-12-27 + */ +@Slf4j +@Service(value = "pictureService") +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class PictureServiceImpl implements PictureService { + + @Autowired + private PictureRepository pictureRepository; + + public static final String SUCCESS = "success"; + + public static final String CODE = "code"; + + public static final String MSG = "msg"; + + @Override + @Transactional(rollbackFor = Throwable.class) + public Picture upload(MultipartFile multipartFile, String username) { + File file = FileUtil.toFile(multipartFile); + //将参数合成一个请求 + RestTemplate rest = new RestTemplate(); + + FileSystemResource resource = new FileSystemResource(file); + MultiValueMap param = new LinkedMultiValueMap<>(); + param.add("smfile", resource); + + //设置头部,必须 + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"); + + HttpEntity> httpEntity = new HttpEntity>(param,headers); + ResponseEntity responseEntity = rest.exchange("https://sm.ms/api/upload", HttpMethod.POST, httpEntity, String.class); + + JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody()); + Picture picture = null; + if(!jsonObject.get(CODE).toString().equals(SUCCESS)){ + throw new BadRequestException(jsonObject.get(MSG).toString()); + } + //转成实体类 + picture = JSON.parseObject(jsonObject.get("data").toString(), Picture.class); + picture.setSize(FileUtil.getSize(Integer.valueOf(picture.getSize()))); + picture.setUsername(username); + picture.setFilename(FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename())); + pictureRepository.save(picture); + //删除临时文件 + FileUtil.deleteFile(file); + return picture; + } + + @Override + public Picture findById(Long id) { + Optional picture = pictureRepository.findById(id); + ValidationUtil.isNull(picture,"Picture","id",id); + return picture.get(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Picture picture) { + RestTemplate rest = new RestTemplate(); + try { + ResponseEntity str = rest.getForEntity(picture.getDelete(), String.class); + if(str.getStatusCode().is2xxSuccessful()){ + pictureRepository.delete(picture); + } + //如果删除的地址出错,直接删除数据库数据 + } catch(Exception e){ + pictureRepository.delete(picture); + } + + } +} diff --git a/src/main/java/me/zhengjie/tools/service/query/PictureQueryService.java b/src/main/java/me/zhengjie/tools/service/query/PictureQueryService.java new file mode 100644 index 00000000..13d8fcbe --- /dev/null +++ b/src/main/java/me/zhengjie/tools/service/query/PictureQueryService.java @@ -0,0 +1,66 @@ +package me.zhengjie.tools.service.query; + +import me.zhengjie.common.utils.PageUtil; +import me.zhengjie.tools.domain.Picture; +import me.zhengjie.tools.repository.PictureRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import java.util.ArrayList; +import java.util.List; + +/** + * @author jie + * @date 2018-12-03 + */ +@Service +@CacheConfig(cacheNames = "picture") +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class PictureQueryService { + + @Autowired + private PictureRepository pictureRepository; + + /** + * 分页 + */ + @Cacheable(keyGenerator = "keyGenerator") + public Object queryAll(Picture picture, Pageable pageable){ + return PageUtil.toPage(pictureRepository.findAll(new Spec(picture),pageable)); + } + + class Spec implements Specification { + + private Picture picture; + + public Spec(Picture picture){ + this.picture = picture; + } + + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder cb) { + + List list = new ArrayList(); + + if(!ObjectUtils.isEmpty(picture.getFilename())){ + /** + * 模糊 + */ + list.add(cb.like(root.get("filename").as(String.class),"%"+picture.getFilename()+"%")); + } + + Predicate[] p = new Predicate[list.size()]; + return cb.and(list.toArray(p)); + } + } +}