From 1ec10e3d3861f0deccce1ef1a9ba028a53d97ac9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=83=91=E6=9D=B0?=
Date: Mon, 31 Dec 2018 16:59:03 +0800
Subject: [PATCH] =?UTF-8?q?v1.3=20=E7=89=88=E6=9C=AC=E5=8F=91=E5=B8=83?=
=?UTF-8?q?=EF=BC=8C=E8=AF=A6=E7=BB=86=E4=BF=A1=E6=81=AF=E6=9F=A5=E7=9C=8B?=
=?UTF-8?q?=E5=8F=91=E8=A1=8C=E7=89=88=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 22 ++-
pom.xml | 14 ++
sql/eladmin.sql | 111 ++++++++++-
.../me/zhengjie/common/aop/log/LogAspect.java | 3 +
.../common/exception/BadRequestException.java | 10 +
.../handler/GlobalExceptionHandler.java | 61 +++++-
.../common/utils/ElAdminConstant.java | 16 +-
.../core/config/WebSecurityConfig.java | 38 ++--
.../me/zhengjie/core/security/JwtUser.java | 4 +
.../core/service/JwtUserDetailsService.java | 1 +
.../me/zhengjie/core/utils/JwtTokenUtil.java | 16 +-
.../me/zhengjie/monitor/config/LogFilter.java | 13 +-
.../monitor/config/WebSocketConfig.java | 4 +
.../zhengjie/monitor/domain/LogMessage.java | 1 -
.../me/zhengjie/monitor/domain/Logging.java | 2 +
.../service/impl/LoggingServiceImpl.java | 4 +-
.../system/domain/VerificationCode.java | 21 +-
.../system/repository/UserRepository.java | 28 +++
.../VerificationCodeRepository.java | 8 +
.../zhengjie/system/rest/UserController.java | 90 +++++++++
.../rest/VerificationCodeController.java | 37 +++-
.../zhengjie/system/service/UserService.java | 22 +++
.../service/VerificationCodeService.java | 3 +-
.../system/service/impl/MenuServiceImpl.java | 12 +-
.../system/service/impl/UserServiceImpl.java | 19 ++
.../impl/VerificationCodeServiceImpl.java | 62 +++++-
.../zhengjie/tools/domain/AlipayConfig.java | 80 ++++++++
.../me/zhengjie/tools/domain/QiniuConfig.java | 61 ++++++
.../zhengjie/tools/domain/QiniuContent.java | 54 ++++++
.../me/zhengjie/tools/domain/vo/EmailVo.java | 4 +
.../me/zhengjie/tools/domain/vo/TradeVo.java | 65 +++++++
.../tools/repository/AlipayRepository.java | 11 ++
.../repository/QiNiuConfigRepository.java | 11 ++
.../repository/QiniuContentRepository.java | 19 ++
.../zhengjie/tools/rest/AliPayController.java | 125 ++++++++++++
.../zhengjie/tools/rest/EmailController.java | 3 -
.../zhengjie/tools/rest/QiniuController.java | 108 +++++++++++
.../zhengjie/tools/service/AlipayService.java | 48 +++++
.../zhengjie/tools/service/QiNiuService.java | 73 +++++++
.../tools/service/impl/AlipayServiceImpl.java | 135 +++++++++++++
.../tools/service/impl/EmailServiceImpl.java | 3 +-
.../service/impl/PictureServiceImpl.java | 2 +-
.../tools/service/impl/QiNiuServiceImpl.java | 179 ++++++++++++++++++
.../service/query/QiNiuQueryService.java | 66 +++++++
.../zhengjie/tools/util/AliPayStatusEnum.java | 41 ++++
.../me/zhengjie/tools/util/AlipayUtils.java | 79 ++++++++
.../me/zhengjie/tools/util/QiNiuUtil.java | 60 ++++++
src/main/resources/application.yml | 15 +-
48 files changed, 1776 insertions(+), 88 deletions(-)
create mode 100644 src/main/java/me/zhengjie/tools/domain/AlipayConfig.java
create mode 100644 src/main/java/me/zhengjie/tools/domain/QiniuConfig.java
create mode 100644 src/main/java/me/zhengjie/tools/domain/QiniuContent.java
create mode 100644 src/main/java/me/zhengjie/tools/domain/vo/TradeVo.java
create mode 100644 src/main/java/me/zhengjie/tools/repository/AlipayRepository.java
create mode 100644 src/main/java/me/zhengjie/tools/repository/QiNiuConfigRepository.java
create mode 100644 src/main/java/me/zhengjie/tools/repository/QiniuContentRepository.java
create mode 100644 src/main/java/me/zhengjie/tools/rest/AliPayController.java
create mode 100644 src/main/java/me/zhengjie/tools/rest/QiniuController.java
create mode 100644 src/main/java/me/zhengjie/tools/service/AlipayService.java
create mode 100644 src/main/java/me/zhengjie/tools/service/QiNiuService.java
create mode 100644 src/main/java/me/zhengjie/tools/service/impl/AlipayServiceImpl.java
create mode 100644 src/main/java/me/zhengjie/tools/service/impl/QiNiuServiceImpl.java
create mode 100644 src/main/java/me/zhengjie/tools/service/query/QiNiuQueryService.java
create mode 100644 src/main/java/me/zhengjie/tools/util/AliPayStatusEnum.java
create mode 100644 src/main/java/me/zhengjie/tools/util/AlipayUtils.java
create mode 100644 src/main/java/me/zhengjie/tools/util/QiNiuUtil.java
diff --git a/README.md b/README.md
index 4b7153876..26f2d9865 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# eladmin
-项目基于 Spring Boot 2.1.0 、 Spring boot Jpa、 Spring Security、redis、Vue的前后端分离的权限管理系统, 权限控制采用 RBAC 思想,支持 动态路由、项目1.0版本提供一个纯净的后台管理,第三方工具将在后面的版本中添加
+项目基于 Spring Boot 2.1.0 、 Spring boot Jpa、 Spring Security、redis、Vue的前后端分离的权限管理系统, 权限控制采用 RBAC 思想,支持动态路由
#### 前端源码
- 码云:[https://gitee.com/elunez/eladmin-qt](https://gitee.com/elunez/eladmin-qt)
@@ -14,21 +14,29 @@
#### 预览地址
[http://auauz.net](http://auauz.net)
-- 用户名: admin
+
+##### 用户账号
+
+- 管理员: admin
+- 测试用户: test
+
+##### 默认密码
+
- 密码: 123456
#### 系统功能模块
- 用户管理 提供用户的相关配置
+- 个人中心 提供修改头像,密码,邮箱验等功能
- 角色管理 角色菜单分配权限
- 权限管理 权限细化到接口
- 菜单管理 已实现动态路由,后端可配置化
- 系统日志 记录用户访问监控异常信息
-- 实时控制台 显示logback实时日志
+- 实时控制台 显示logback实时日志,可显示异常堆栈信息
- redis管理 将redis的操作可视化,提供对redis的基本操作
- redis限流 对系统的流量进行控制,由[everhopingandwaiting](https://github.com/everhopingandwaiting)提供
- SQL监控 采用 druid 监控数据库访问性能
-- 三方工具: 邮件工具,sm.ms免费图床
+- 三方工具: 邮件工具,sm.ms免费图床,支付宝支付,七牛云存储
- 富文本编辑器
#### 后端技术栈
@@ -64,11 +72,15 @@
|
+ |
+
+
+ |
#### 反馈交流
-- QQ交流群:891137268
+- QQ交流群:
- 作者邮箱:elunez@qq.com
diff --git a/pom.xml b/pom.xml
index 93c72e072..df66854cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -161,6 +161,20 @@
1.4.7
+
+
+ com.qiniu
+ qiniu-java-sdk
+ [7.2.0, 7.2.99]
+
+
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+ 3.1.0
+
+
diff --git a/sql/eladmin.sql b/sql/eladmin.sql
index 68af9a2d3..d3580bf7e 100644
--- a/sql/eladmin.sql
+++ b/sql/eladmin.sql
@@ -11,12 +11,36 @@
Target Server Version : 50559
File Encoding : 65001
- Date: 28/12/2018 17:50:46
+ Date: 31/12/2018 15:52:01
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
+-- ----------------------------
+-- Table structure for alipay_config
+-- ----------------------------
+DROP TABLE IF EXISTS `alipay_config`;
+CREATE TABLE `alipay_config` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `appID` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `charset` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `format` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `gatewayUrl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `notifyUrl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `privateKey` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `publicKey` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `returnUrl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `signType` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `sysServiceProviderId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
+-- ----------------------------
+-- Records of alipay_config
+-- ----------------------------
+INSERT INTO `alipay_config` VALUES (1, '2016091700532697', 'utf-8', 'JSON', 'https://openapi.alipaydev.com/gateway.do', 'http://api.auauz.net/api/aliPay/notify', 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5js8sInU10AJ0cAQ8UMMyXrQ+oHZEkVt5lBwsStmTJ7YikVYgbskx1YYEXTojRsWCb+SH/kDmDU4pK/u91SJ4KFCRMF2411piYuXU/jF96zKrADznYh/zAraqT6hvAIVtQAlMHN53nx16rLzZ/8jDEkaSwT7+HvHiS+7sxSojnu/3oV7BtgISoUNstmSe8WpWHOaWv19xyS+Mce9MY4BfseFhzTICUymUQdd/8hXA28/H6osUfAgsnxAKv7Wil3aJSgaJczWuflYOve0dJ3InZkhw5Cvr0atwpk8YKBQjy5CdkoHqvkOcIB+cYHXJKzOE5tqU7inSwVbHzOLQ3XbnAgMBAAECggEAVJp5eT0Ixg1eYSqFs9568WdetUNCSUchNxDBu6wxAbhUgfRUGZuJnnAll63OCTGGck+EGkFh48JjRcBpGoeoHLL88QXlZZbC/iLrea6gcDIhuvfzzOffe1RcZtDFEj9hlotg8dQj1tS0gy9pN9g4+EBH7zeu+fyv+qb2e/v1l6FkISXUjpkD7RLQr3ykjiiEw9BpeKb7j5s7Kdx1NNIzhkcQKNqlk8JrTGDNInbDM6inZfwwIO2R1DHinwdfKWkvOTODTYa2MoAvVMFT9Bec9FbLpoWp7ogv1JMV9svgrcF9XLzANZ/OQvkbe9TV9GWYvIbxN6qwQioKCWO4GPnCAQKBgQDgW5MgfhX8yjXqoaUy/d1VjI8dHeIyw8d+OBAYwaxRSlCfyQ+tieWcR2HdTzPca0T0GkWcKZm0ei5xRURgxt4DUDLXNh26HG0qObbtLJdu/AuBUuCqgOiLqJ2f1uIbrz6OZUHns+bT/jGW2Ws8+C13zTCZkZt9CaQsrp3QOGDx5wKBgQDTul39hp3ZPwGNFeZdkGoUoViOSd5Lhowd5wYMGAEXWRLlU8z+smT5v0POz9JnIbCRchIY2FAPKRdVTICzmPk2EPJFxYTcwaNbVqL6lN7J2IlXXMiit5QbiLauo55w7plwV6LQmKm9KV7JsZs5XwqF7CEovI7GevFzyD3w+uizAQKBgC3LY1eRhOlpWOIAhpjG6qOoohmeXOphvdmMlfSHq6WYFqbWwmV4rS5d/6LNpNdL6fItXqIGd8I34jzql49taCmi+A2nlR/E559j0mvM20gjGDIYeZUz5MOE8k+K6/IcrhcgofgqZ2ZED1ksHdB/E8DNWCswZl16V1FrfvjeWSNnAoGAMrBplCrIW5xz+J0Hm9rZKrs+AkK5D4fUv8vxbK/KgxZ2KaUYbNm0xv39c+PZUYuFRCz1HDGdaSPDTE6WeWjkMQd5mS6ikl9hhpqFRkyh0d0fdGToO9yLftQKOGE/q3XUEktI1XvXF0xyPwNgUCnq0QkpHyGVZPtGFxwXiDvpvgECgYA5PoB+nY8iDiRaJNko9w0hL4AeKogwf+4TbCw+KWVEn6jhuJa4LFTdSqp89PktQaoVpwv92el/AhYjWOl/jVCm122f9b7GyoelbjMNolToDwe5pF5RnSpEuDdLy9MfE8LnE3PlbE7E5BipQ3UjSebkgNboLHH/lNZA5qvEtvbfvQ==', 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAut9evKRuHJ/2QNfDlLwvN/S8l9hRAgPbb0u61bm4AtzaTGsLeMtScetxTWJnVvAVpMS9luhEJjt+Sbk5TNLArsgzzwARgaTKOLMT1TvWAK5EbHyI+eSrc3s7Awe1VYGwcubRFWDm16eQLv0k7iqiw+4mweHSz/wWyvBJVgwLoQ02btVtAQErCfSJCOmt0Q/oJQjj08YNRV4EKzB19+f5A+HQVAKy72dSybTzAK+3FPtTtNen/+b5wGeat7c32dhYHnGorPkPeXLtsqqUTp1su5fMfd4lElNdZaoCI7osZxWWUo17vBCZnyeXc9fk0qwD9mK6yRAxNbrY72Xx5VqIqwIDAQAB', 'http://api.auauz.ne/api/aliPay/return', 'RSA2', '2088102176044281');
+
-- ----------------------------
-- Table structure for email_config
-- ----------------------------
@@ -31,6 +55,24 @@ CREATE TABLE `email_config` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+-- ----------------------------
+-- Table structure for log
+-- ----------------------------
+DROP TABLE IF EXISTS `log`;
+CREATE TABLE `log` (
+ `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,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 4214 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
-- ----------------------------
-- Table structure for menu
-- ----------------------------
@@ -46,7 +88,7 @@ CREATE TABLE `menu` (
`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 = 18 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of menu
@@ -59,7 +101,7 @@ INSERT INTO `menu` VALUES (5, '2018-12-18 15:17:28', b'0', '菜单管理', 'syst
INSERT INTO `menu` VALUES (6, '2018-12-18 15:17:48', b'0', '系统监控', NULL, 0, 10, 'monitor', 'monitor');
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 (9, '2018-12-18 15:19:34', b'1', 'SQL监控', NULL, 6, 14, 'sqlMonitor', 'http://localhost:8000/druid');
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');
@@ -68,6 +110,8 @@ INSERT INTO `menu` VALUES (14, '2018-12-27 10:13:09', b'0', '邮件工具', 'too
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');
+INSERT INTO `menu` VALUES (18, '2018-12-31 11:12:15', b'0', '七牛云存储', 'tools/qiniu/index', 13, 23, 'qiniu', 'qiniu');
+INSERT INTO `menu` VALUES (19, '2018-12-31 14:52:38', b'0', '支付宝工具', 'tools/aliPay/index', 13, 24, 'alipay', 'aliPay');
-- ----------------------------
-- Table structure for menus_roles
@@ -102,6 +146,8 @@ 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 (18, 1);
+INSERT INTO `menus_roles` VALUES (19, 1);
INSERT INTO `menus_roles` VALUES (1, 2);
INSERT INTO `menus_roles` VALUES (2, 2);
INSERT INTO `menus_roles` VALUES (3, 2);
@@ -111,8 +157,11 @@ 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 (14, 2);
INSERT INTO `menus_roles` VALUES (16, 2);
INSERT INTO `menus_roles` VALUES (17, 2);
+INSERT INTO `menus_roles` VALUES (18, 2);
+INSERT INTO `menus_roles` VALUES (19, 2);
-- ----------------------------
-- Table structure for permission
@@ -176,12 +225,37 @@ CREATE TABLE `picture` (
`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;
+) ENGINE = InnoDB AUTO_INCREMENT = 47 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
+-- ----------------------------
+-- Table structure for qiniu_config
+-- ----------------------------
+DROP TABLE IF EXISTS `qiniu_config`;
+CREATE TABLE `qiniu_config` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `accessKey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `bucket` 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,
+ `secretKey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `zone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
--- Records of picture
+-- Table structure for qiniu_content
-- ----------------------------
-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');
+DROP TABLE IF EXISTS `qiniu_content`;
+CREATE TABLE `qiniu_content` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `bucket` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `name` 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,
+ `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `updateTime` datetime NULL DEFAULT NULL,
+ `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for role
@@ -246,8 +320,8 @@ CREATE TABLE `user` (
-- ----------------------------
-- 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);
+INSERT INTO `user` VALUES (1, 'https://i.loli.net/2018/12/31/5c297270b20e2.jpg', '2018-08-23 09:11:56', 'elunez@qq.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'admin', '2018-11-23 10:12:36');
+INSERT INTO `user` VALUES (3, 'https://i.loli.net/2018/12/30/5c2871d6aa101.jpg', '2018-12-27 20:05:26', 'test@qq.com', 1, '14e1b600b1fd579f47433b88e8d85291', 'test', NULL);
-- ----------------------------
-- Table structure for users_roles
@@ -279,8 +353,27 @@ CREATE TABLE `verification_code` (
`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,
+ `scenes` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+-- ----------------------------
+-- Table structure for visits
+-- ----------------------------
+DROP TABLE IF EXISTS `visits`;
+CREATE TABLE `visits` (
+ `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,
+ `createTime` datetime NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 47 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+
+-- ----------------------------
+-- Records of visits
+-- ----------------------------
+INSERT INTO `visits` VALUES (46, '2018-12-31', 1, 3, 'Mon', '2018-12-31 15:50:19');
SET FOREIGN_KEY_CHECKS = 1;
diff --git a/src/main/java/me/zhengjie/common/aop/log/LogAspect.java b/src/main/java/me/zhengjie/common/aop/log/LogAspect.java
index 1a81f7130..0017e744a 100644
--- a/src/main/java/me/zhengjie/common/aop/log/LogAspect.java
+++ b/src/main/java/me/zhengjie/common/aop/log/LogAspect.java
@@ -13,6 +13,9 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
/**
* @author jie
* @date 2018-11-24
diff --git a/src/main/java/me/zhengjie/common/exception/BadRequestException.java b/src/main/java/me/zhengjie/common/exception/BadRequestException.java
index efe7801de..bfbf7f962 100644
--- a/src/main/java/me/zhengjie/common/exception/BadRequestException.java
+++ b/src/main/java/me/zhengjie/common/exception/BadRequestException.java
@@ -3,6 +3,8 @@
import lombok.Getter;
import org.springframework.http.HttpStatus;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+
/**
* @author jie
* @date 2018-11-23
@@ -10,7 +12,15 @@
*/
@Getter
public class BadRequestException extends RuntimeException{
+
+ private Integer status = BAD_REQUEST.value();
+
public BadRequestException(String msg){
super(msg);
}
+
+ public BadRequestException(HttpStatus status,String msg){
+ super(msg);
+ this.status = status.value();
+ }
}
diff --git a/src/main/java/me/zhengjie/common/exception/handler/GlobalExceptionHandler.java b/src/main/java/me/zhengjie/common/exception/handler/GlobalExceptionHandler.java
index 7f812169a..402624314 100644
--- a/src/main/java/me/zhengjie/common/exception/handler/GlobalExceptionHandler.java
+++ b/src/main/java/me/zhengjie/common/exception/handler/GlobalExceptionHandler.java
@@ -6,10 +6,14 @@
import me.zhengjie.common.exception.EntityNotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
/**
@@ -20,6 +24,32 @@
@RestControllerAdvice
public class GlobalExceptionHandler {
+ /**
+ * 处理所有不可知的异常
+ * @param e
+ * @return
+ */
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity handleException(Exception e){
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
+ ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage());
+ return buildResponseEntity(apiError);
+ }
+
+ /**
+ * 处理 接口无权访问异常AccessDeniedException
+ * @param e
+ * @return
+ */
+ @ExceptionHandler(AccessDeniedException.class)
+ public ResponseEntity handleAccessDeniedException(AccessDeniedException e){
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
+ ApiError apiError = new ApiError(FORBIDDEN.value(),e.getMessage());
+ return buildResponseEntity(apiError);
+ }
+
/**
* 处理自定义异常
* @param e
@@ -27,8 +57,9 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(value = BadRequestException.class)
public ResponseEntity badRequestException(BadRequestException e) {
- log.error(e.getMessage());
- ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage());
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
+ ApiError apiError = new ApiError(e.getStatus(),e.getMessage());
return buildResponseEntity(apiError);
}
@@ -39,7 +70,8 @@ public ResponseEntity badRequestException(BadRequestException e) {
*/
@ExceptionHandler(value = EntityExistException.class)
public ResponseEntity entityExistException(EntityExistException e) {
- log.error(e.getMessage());
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage());
return buildResponseEntity(apiError);
}
@@ -51,7 +83,8 @@ public ResponseEntity entityExistException(EntityExistException e) {
*/
@ExceptionHandler(value = EntityNotFoundException.class)
public ResponseEntity entityNotFoundException(EntityNotFoundException e) {
- log.error(e.getMessage());
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
ApiError apiError = new ApiError(NOT_FOUND.value(),e.getMessage());
return buildResponseEntity(apiError);
}
@@ -63,7 +96,8 @@ public ResponseEntity entityNotFoundException(EntityNotFoundException
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
- log.error(e.getMessage());
+ // 打印堆栈信息
+ log.error(getStackTrace(e));
String[] str = e.getBindingResult().getAllErrors().get(0).getCodes()[1].split("\\.");
StringBuffer msg = new StringBuffer(str[1]+":");
msg.append(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
@@ -79,4 +113,21 @@ public ResponseEntity handleMethodArgumentNotValidException(MethodArgu
private ResponseEntity buildResponseEntity(ApiError apiError) {
return new ResponseEntity(apiError, HttpStatus.valueOf(apiError.getStatus()));
}
+
+ /**
+ * 获取堆栈信息
+ * @param throwable
+ * @return
+ */
+ private String getStackTrace(Throwable throwable)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ try {
+ throwable.printStackTrace(pw);
+ return "\n"+sw.toString();
+ } finally {
+ pw.close();
+ }
+ }
}
diff --git a/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java b/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java
index be69087a9..065e3320f 100644
--- a/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java
+++ b/src/main/java/me/zhengjie/common/utils/ElAdminConstant.java
@@ -7,21 +7,13 @@
*/
public class ElAdminConstant {
- /**
- * 用于七牛云zone与机房对应关系
- */
- public static class QiNiu{
-
- public static final String HUAD = "华东";
+ public static final String RESET_PASS = "重置密码";
- public static final String HUAB = "华北";
+ public static final String RESET_MAIL = "重置邮箱";
- public static final String HUAN = "华南";
+ public static final String EMAIL_CODE = "你的验证码为:";
- public static final String BEIM = "北美";
-
- public static final String DNY = "东南亚";
- }
+ public static final String EMAIL_CONTENT = "
----- 邮件来自 eladmin 后台管理系统,系统邮件请勿回复
";
/**
* 常用接口
diff --git a/src/main/java/me/zhengjie/core/config/WebSecurityConfig.java b/src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
index 8e075585c..9e3031649 100644
--- a/src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
+++ b/src/main/java/me/zhengjie/core/config/WebSecurityConfig.java
@@ -78,12 +78,18 @@ protected void configure(HttpSecurity httpSecurity) throws Exception {
.antMatchers("/auth/**").permitAll()
.antMatchers("/websocket/**").permitAll()
.antMatchers("/druid/**").anonymous()
+
+ // 支付宝回调
+ .antMatchers("/api/aliPay/return").anonymous()
+ .antMatchers("/api/aliPay/notify").anonymous()
+
// swagger start
.antMatchers("/swagger-ui.html").anonymous()
.antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous()
// swagger end
+
.antMatchers("/test/**").anonymous()
.antMatchers(HttpMethod.OPTIONS, "/**").anonymous()
// 所有请求都需要认证
@@ -96,21 +102,21 @@ protected void configure(HttpSecurity httpSecurity) throws Exception {
@Override
public void configure(WebSecurity web) throws Exception {
// AuthenticationTokenFilter will ignore the below paths
- web
- .ignoring()
- .antMatchers(
- HttpMethod.POST,
- authenticationPath
- )
- // allow anonymous resource requests
- .and()
- .ignoring()
- .antMatchers(
- HttpMethod.GET,
- "/*.html",
- "/**/*.html",
- "/**/*.css",
- "/**/*.js"
- );
+ web.ignoring()
+ .antMatchers(
+ HttpMethod.POST,
+ authenticationPath
+ )
+
+ // allow anonymous resource requests
+ .and()
+ .ignoring()
+ .antMatchers(
+ HttpMethod.GET,
+ "/*.html",
+ "/**/*.html",
+ "/**/*.css",
+ "/**/*.js"
+ );
}
}
diff --git a/src/main/java/me/zhengjie/core/security/JwtUser.java b/src/main/java/me/zhengjie/core/security/JwtUser.java
index 4967f9cd4..e72410a8a 100644
--- a/src/main/java/me/zhengjie/core/security/JwtUser.java
+++ b/src/main/java/me/zhengjie/core/security/JwtUser.java
@@ -5,6 +5,8 @@
import lombok.Getter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
+
+import java.sql.Timestamp;
import java.util.*;
/**
@@ -32,6 +34,8 @@ public class JwtUser implements UserDetails {
private final boolean enabled;
+ private Timestamp createTime;
+
@JsonIgnore
private final Date lastPasswordResetDate;
diff --git a/src/main/java/me/zhengjie/core/service/JwtUserDetailsService.java b/src/main/java/me/zhengjie/core/service/JwtUserDetailsService.java
index 5c11a18b8..560bf1596 100644
--- a/src/main/java/me/zhengjie/core/service/JwtUserDetailsService.java
+++ b/src/main/java/me/zhengjie/core/service/JwtUserDetailsService.java
@@ -64,6 +64,7 @@ public UserDetails create(User user) {
user.getEmail(),
mapToGrantedAuthorities(user.getRoles(),permissionRepository),
user.getEnabled(),
+ user.getCreateTime(),
user.getLastPasswordResetTime()
);
}
diff --git a/src/main/java/me/zhengjie/core/utils/JwtTokenUtil.java b/src/main/java/me/zhengjie/core/utils/JwtTokenUtil.java
index e7ea56cf5..80b0e0145 100644
--- a/src/main/java/me/zhengjie/core/utils/JwtTokenUtil.java
+++ b/src/main/java/me/zhengjie/core/utils/JwtTokenUtil.java
@@ -5,12 +5,10 @@
import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.core.security.JwtUser;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.authentication.AccountExpiredException;
+import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
-
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
@@ -18,13 +16,9 @@
import java.util.Map;
import java.util.function.Function;
-import static org.springframework.http.HttpStatus.UNAUTHORIZED;
-
@Component
public class JwtTokenUtil implements Serializable {
- static final String CLAIM_KEY_USERNAME = "sub";
- static final String CLAIM_KEY_CREATED = "iat";
private static final long serialVersionUID = -3301605591108950415L;
private Clock clock = DefaultClock.INSTANCE;
@@ -129,7 +123,7 @@ public String getUserName(HttpServletRequest request){
String authToken = request.getHeader(tokenHeader);
if(StringUtils.isEmpty(authToken)||authToken.length()<7){
- throw new AccountExpiredException("令牌已过期或无效");
+ throw new BadRequestException(HttpStatus.FORBIDDEN,"Token令牌无效");
}
final String token = authToken.substring(7);
@@ -137,11 +131,7 @@ public String getUserName(HttpServletRequest request){
try {
username = getUsernameFromToken(token);
} catch (ExpiredJwtException e){
- throw new AccountExpiredException("令牌已过期或无效");
- }
-
- if(StringUtils.isEmpty(username)){
- throw new AccountExpiredException("令牌已过期或无效");
+ throw new BadRequestException(HttpStatus.UNAUTHORIZED,"Token令牌已过期");
}
return username;
diff --git a/src/main/java/me/zhengjie/monitor/config/LogFilter.java b/src/main/java/me/zhengjie/monitor/config/LogFilter.java
index 0220a8f3f..1ba2ae13f 100644
--- a/src/main/java/me/zhengjie/monitor/config/LogFilter.java
+++ b/src/main/java/me/zhengjie/monitor/config/LogFilter.java
@@ -20,19 +20,12 @@ public class LogFilter extends Filter{
public FilterReply decide(ILoggingEvent event) {
String exception = "";
IThrowableProxy iThrowableProxy1 = event.getThrowableProxy();
- if(iThrowableProxy1!=null){
- exception = ""+iThrowableProxy1.getClassName()+" "+iThrowableProxy1.getMessage()+"";
- for(int i=0; i"+iThrowableProxy1.getStackTraceElementProxyArray()[i].toString()+"";
- }
- }
LogMessage loggerMessage = new LogMessage(
- event.getFormattedMessage() /* repair format message*/
- , DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())),
+ event.getFormattedMessage(),
+ DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())),
event.getThreadName(),
event.getLoggerName(),
- event.getLevel().levelStr,
- exception
+ event.getLevel().levelStr
);
LoggerQueue.getInstance().push(loggerMessage);
return FilterReply.ACCEPT;
diff --git a/src/main/java/me/zhengjie/monitor/config/WebSocketConfig.java b/src/main/java/me/zhengjie/monitor/config/WebSocketConfig.java
index a421066fe..343d27ac5 100644
--- a/src/main/java/me/zhengjie/monitor/config/WebSocketConfig.java
+++ b/src/main/java/me/zhengjie/monitor/config/WebSocketConfig.java
@@ -45,6 +45,10 @@ public void run() {
try {
LogMessage log = LoggerQueue.getInstance().poll();
if(log!=null){
+ // 格式化异常堆栈信息
+ if("ERROR".equals(log.getLevel()) && "me.zhengjie.common.exception.handler.GlobalExceptionHandler".equals(log.getClassName())){
+ log.setBody(""+log.getBody()+"
");
+ }
if(log.getClassName().equals("jdbc.resultsettable")){
log.setBody("
"+log.getBody()+"
");
}
diff --git a/src/main/java/me/zhengjie/monitor/domain/LogMessage.java b/src/main/java/me/zhengjie/monitor/domain/LogMessage.java
index fa7a264ef..66a8a4bc9 100644
--- a/src/main/java/me/zhengjie/monitor/domain/LogMessage.java
+++ b/src/main/java/me/zhengjie/monitor/domain/LogMessage.java
@@ -16,5 +16,4 @@ public class LogMessage {
private String threadName;
private String className;
private String level;
- private String exception;
}
diff --git a/src/main/java/me/zhengjie/monitor/domain/Logging.java b/src/main/java/me/zhengjie/monitor/domain/Logging.java
index 327285616..0531694e5 100644
--- a/src/main/java/me/zhengjie/monitor/domain/Logging.java
+++ b/src/main/java/me/zhengjie/monitor/domain/Logging.java
@@ -38,6 +38,7 @@ public class Logging {
/**
* 参数
*/
+ @Column(length = 1500)
private String params;
/**
@@ -58,6 +59,7 @@ public class Logging {
/**
* 异常详细
*/
+ @Column(length = 1500)
private String exceptionDetail;
/**
diff --git a/src/main/java/me/zhengjie/monitor/service/impl/LoggingServiceImpl.java b/src/main/java/me/zhengjie/monitor/service/impl/LoggingServiceImpl.java
index e1d05800c..a55bc210c 100644
--- a/src/main/java/me/zhengjie/monitor/service/impl/LoggingServiceImpl.java
+++ b/src/main/java/me/zhengjie/monitor/service/impl/LoggingServiceImpl.java
@@ -83,7 +83,9 @@ public void save(ProceedingJoinPoint joinPoint, Logging logging){
username = user.getUsername();
}
- logging.setMethod(methodName);
+ if (params.length() > 1000){
+ params = params.substring(0,999);
+ }
logging.setUsername(username);
logging.setParams(params + " }");
loggingRepository.save(logging);
diff --git a/src/main/java/me/zhengjie/system/domain/VerificationCode.java b/src/main/java/me/zhengjie/system/domain/VerificationCode.java
index 7c8f45215..b555419e8 100644
--- a/src/main/java/me/zhengjie/system/domain/VerificationCode.java
+++ b/src/main/java/me/zhengjie/system/domain/VerificationCode.java
@@ -1,9 +1,12 @@
package me.zhengjie.system.domain;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
+import javax.validation.constraints.NotBlank;
import java.sql.Timestamp;
/**
@@ -12,6 +15,8 @@
*/
@Data
@Entity
+@AllArgsConstructor
+@NoArgsConstructor
@Table(name = "verification_code")
public class VerificationCode {
@@ -22,7 +27,12 @@ public class VerificationCode {
private String code;
/**
- * true 为有效,false 为无效
+ * 使用场景,自己定义
+ */
+ private String scenes;
+
+ /**
+ * true 为有效,false 为无效,验证时状态+时间+具体的邮箱或者手机号
*/
private Boolean status = true;
@@ -30,11 +40,13 @@ public class VerificationCode {
/**
* 类型 :phone 和 email
*/
+ @NotBlank
private String type;
/**
* 具体的phone与email
*/
+ @NotBlank
private String value;
/**
@@ -42,4 +54,11 @@ public class VerificationCode {
*/
@CreationTimestamp
private Timestamp createTime;
+
+ public VerificationCode(String code, String scenes, @NotBlank String type, @NotBlank String value) {
+ this.code = code;
+ this.scenes = scenes;
+ this.type = type;
+ this.value = value;
+ }
}
diff --git a/src/main/java/me/zhengjie/system/repository/UserRepository.java b/src/main/java/me/zhengjie/system/repository/UserRepository.java
index fdf8acc10..3a4c2ab88 100644
--- a/src/main/java/me/zhengjie/system/repository/UserRepository.java
+++ b/src/main/java/me/zhengjie/system/repository/UserRepository.java
@@ -3,6 +3,7 @@
import me.zhengjie.system.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@@ -27,4 +28,31 @@ public interface UserRepository extends JpaRepository, JpaSpecificat
*/
@Query("from User u join fetch u.roles where u.email = :email")
User findByEmail(@Param("email") String email);
+
+ /**
+ * 修改密码
+ * @param id
+ * @param pass
+ */
+ @Modifying
+ @Query(value = "update user set password = ?2 where id = ?1",nativeQuery = true)
+ void updatePass(Long id, String pass);
+
+ /**
+ * 修改头像
+ * @param id
+ * @param url
+ */
+ @Modifying
+ @Query(value = "update user set avatar = ?2 where id = ?1",nativeQuery = true)
+ void updateAvatar(Long id, String url);
+
+ /**
+ * 修改邮箱
+ * @param id
+ * @param email
+ */
+ @Modifying
+ @Query(value = "update user set email = ?2 where id = ?1",nativeQuery = true)
+ void updateEmail(Long id, String email);
}
diff --git a/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java b/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java
index 813bb86af..3b5b0037f 100644
--- a/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java
+++ b/src/main/java/me/zhengjie/system/repository/VerificationCodeRepository.java
@@ -9,4 +9,12 @@
*/
public interface VerificationCodeRepository extends JpaRepository {
+ /**
+ * 获取有效的验证码
+ * @param scenes 业务场景,如重置密码,重置邮箱等等
+ * @param type
+ * @param value
+ * @return
+ */
+ VerificationCode findByScenesAndTypeAndValueAndStatusIsTrue(String scenes,String type,String value);
}
diff --git a/src/main/java/me/zhengjie/system/rest/UserController.java b/src/main/java/me/zhengjie/system/rest/UserController.java
index 481998b64..81e4e1c1d 100644
--- a/src/main/java/me/zhengjie/system/rest/UserController.java
+++ b/src/main/java/me/zhengjie/system/rest/UserController.java
@@ -2,17 +2,31 @@
import me.zhengjie.common.aop.log.Log;
import me.zhengjie.common.exception.BadRequestException;
+import me.zhengjie.common.utils.ElAdminConstant;
+import me.zhengjie.common.utils.RequestHolder;
+import me.zhengjie.core.security.JwtUser;
+import me.zhengjie.core.utils.EncryptUtils;
+import me.zhengjie.core.utils.JwtTokenUtil;
import me.zhengjie.system.domain.User;
+import me.zhengjie.system.domain.VerificationCode;
import me.zhengjie.system.service.UserService;
+import me.zhengjie.system.service.VerificationCodeService;
import me.zhengjie.system.service.dto.UserDTO;
import me.zhengjie.system.service.query.UserQueryService;
+import me.zhengjie.tools.domain.Picture;
+import me.zhengjie.tools.service.PictureService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
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.security.core.userdetails.UserDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author jie
@@ -28,6 +42,20 @@ public class UserController {
@Autowired
private UserQueryService userQueryService;
+ @Autowired
+ private JwtTokenUtil jwtTokenUtil;
+
+ @Autowired
+ @Qualifier("jwtUserDetailsService")
+ private UserDetailsService userDetailsService;
+
+ @Autowired
+ private PictureService pictureService;
+
+ @Autowired
+ private VerificationCodeService verificationCodeService;
+
+
private static final String ENTITY_NAME = "user";
@GetMapping(value = "/users/{id}")
@@ -71,4 +99,66 @@ public ResponseEntity delete(@PathVariable Long id){
userService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
+
+ /**
+ * 验证密码
+ * @param pass
+ * @return
+ */
+ @GetMapping(value = "/users/validPass/{pass}")
+ public ResponseEntity validPass(@PathVariable String pass){
+ JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
+ Map map = new HashMap();
+ map.put("status",200);
+ if(!jwtUser.getPassword().equals(EncryptUtils.encryptPassword(pass))){
+ map.put("status",400);
+ }
+ return new ResponseEntity(map,HttpStatus.OK);
+ }
+
+ /**
+ * 修改密码
+ * @param pass
+ * @return
+ */
+ @GetMapping(value = "/users/updatePass/{pass}")
+ public ResponseEntity updatePass(@PathVariable String pass){
+ JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
+ if(jwtUser.getPassword().equals(EncryptUtils.encryptPassword(pass))){
+ throw new BadRequestException("新密码不能与旧密码相同");
+ }
+ userService.updatePass(jwtUser,EncryptUtils.encryptPassword(pass));
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ /**
+ * 修改头像
+ * @param file
+ * @return
+ */
+ @PostMapping(value = "/users/updateAvatar")
+ public ResponseEntity updateAvatar(@RequestParam MultipartFile file){
+ JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
+ Picture picture = pictureService.upload(file,jwtUser.getUsername());
+ userService.updateAvatar(jwtUser,picture.getUrl());
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ /**
+ * 修改邮箱
+ * @param user
+ * @param user
+ * @return
+ */
+ @PostMapping(value = "/users/updateEmail/{code}")
+ public ResponseEntity updateEmail(@PathVariable String code,@RequestBody User user){
+ JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
+ if(!jwtUser.getPassword().equals(EncryptUtils.encryptPassword(user.getPassword()))){
+ throw new BadRequestException("密码错误");
+ }
+ VerificationCode verificationCode = new VerificationCode(code, ElAdminConstant.RESET_MAIL,"email",user.getEmail());
+ verificationCodeService.validated(verificationCode);
+ userService.updateEmail(jwtUser,user.getEmail());
+ 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
index f0ea7d682..dab85e0c1 100644
--- a/src/main/java/me/zhengjie/system/rest/VerificationCodeController.java
+++ b/src/main/java/me/zhengjie/system/rest/VerificationCodeController.java
@@ -1,10 +1,18 @@
package me.zhengjie.system.rest;
+import me.zhengjie.common.utils.ElAdminConstant;
+import me.zhengjie.common.utils.RequestHolder;
+import me.zhengjie.core.security.JwtUser;
+import me.zhengjie.core.utils.JwtTokenUtil;
import me.zhengjie.system.domain.VerificationCode;
import me.zhengjie.system.service.VerificationCodeService;
+import me.zhengjie.tools.domain.vo.EmailVo;
+import me.zhengjie.tools.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;
/**
@@ -18,10 +26,33 @@ public class VerificationCodeController {
@Autowired
private VerificationCodeService verificationCodeService;
- @PostMapping(value = "/code/sendEmail")
- public ResponseEntity sendEmail(@RequestBody VerificationCode code){
+ @Autowired
+ private JwtTokenUtil jwtTokenUtil;
+
+ @Autowired
+ @Qualifier("jwtUserDetailsService")
+ private UserDetailsService userDetailsService;
+
+ @Autowired
+ private EmailService emailService;
+
+ @PostMapping(value = "/code/resetEmail")
+ public ResponseEntity resetEmail(@RequestBody VerificationCode code) throws Exception {
+ code.setScenes(ElAdminConstant.RESET_MAIL);
+ EmailVo emailVo = verificationCodeService.sendEmail(code);
+ emailService.send(emailVo,emailService.find());
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ @PostMapping(value = "/code/email/resetPass")
+ public ResponseEntity resetPass() throws Exception {
+ JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getUserName(RequestHolder.getHttpServletRequest()));
+ VerificationCode code = new VerificationCode();
code.setType("email");
- verificationCodeService.sendEmail(code);
+ code.setValue(jwtUser.getEmail());
+ code.setScenes(ElAdminConstant.RESET_MAIL);
+ EmailVo emailVo = verificationCodeService.sendEmail(code);
+ emailService.send(emailVo,emailService.find());
return new ResponseEntity(HttpStatus.OK);
}
diff --git a/src/main/java/me/zhengjie/system/service/UserService.java b/src/main/java/me/zhengjie/system/service/UserService.java
index 966bd064c..41c66289e 100644
--- a/src/main/java/me/zhengjie/system/service/UserService.java
+++ b/src/main/java/me/zhengjie/system/service/UserService.java
@@ -1,5 +1,6 @@
package me.zhengjie.system.service;
+import me.zhengjie.core.security.JwtUser;
import me.zhengjie.system.domain.User;
import me.zhengjie.system.service.dto.UserDTO;
import org.springframework.cache.annotation.CacheConfig;
@@ -50,4 +51,25 @@ public interface UserService {
*/
@Cacheable(key = "'findByName'+#p0")
User findByName(String userName);
+
+ /**
+ * 修改密码
+ * @param jwtUser
+ * @param encryptPassword
+ */
+ void updatePass(JwtUser jwtUser, String encryptPassword);
+
+ /**
+ * 修改头像
+ * @param jwtUser
+ * @param url
+ */
+ void updateAvatar(JwtUser jwtUser, String url);
+
+ /**
+ * 修改邮箱
+ * @param jwtUser
+ * @param email
+ */
+ void updateEmail(JwtUser jwtUser, String email);
}
diff --git a/src/main/java/me/zhengjie/system/service/VerificationCodeService.java b/src/main/java/me/zhengjie/system/service/VerificationCodeService.java
index db6e5f524..76d48c213 100644
--- a/src/main/java/me/zhengjie/system/service/VerificationCodeService.java
+++ b/src/main/java/me/zhengjie/system/service/VerificationCodeService.java
@@ -1,6 +1,7 @@
package me.zhengjie.system.service;
import me.zhengjie.system.domain.VerificationCode;
+import me.zhengjie.tools.domain.vo.EmailVo;
/**
* @author jie
@@ -12,7 +13,7 @@ public interface VerificationCodeService {
* 发送邮件验证码
* @param code
*/
- void sendEmail(VerificationCode code);
+ EmailVo sendEmail(VerificationCode code);
/**
* 验证
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 c21a68760..d6bdd54d1 100644
--- a/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java
+++ b/src/main/java/me/zhengjie/system/service/impl/MenuServiceImpl.java
@@ -1,6 +1,7 @@
package me.zhengjie.system.service.impl;
import cn.hutool.core.util.StrUtil;
+import me.zhengjie.common.exception.BadRequestException;
import me.zhengjie.common.exception.EntityExistException;
import me.zhengjie.common.utils.ValidationUtil;
import me.zhengjie.system.domain.Menu;
@@ -51,6 +52,11 @@ public MenuDTO create(Menu resources) {
if(menuRepository.findByName(resources.getName()) != null){
throw new EntityExistException(Menu.class,"name",resources.getName());
}
+ if(resources.getIFrame()){
+ if (!(resources.getPath().toLowerCase().startsWith("http://")||resources.getPath().toLowerCase().startsWith("https://"))) {
+ throw new BadRequestException("外链必须以http://或者https://开头");
+ }
+ }
return menuMapper.toDto(menuRepository.save(resources));
}
@@ -59,13 +65,17 @@ public void update(Menu resources) {
Optional
";
+ emailVo = new EmailVo(Arrays.asList(code.getValue()),"eladmin后台管理系统",content);
+ timedDestruction(verificationCodeRepository.save(code));
+ // 存在就再次发送原来的验证码
+ } else {
+ content = ElAdminConstant.EMAIL_CODE + verificationCode.getCode() + "";
+ emailVo = new EmailVo(Arrays.asList(verificationCode.getValue()),"eladmin后台管理系统",content);
+ }
+ return emailVo;
}
@Override
public void validated(VerificationCode code) {
+ VerificationCode verificationCode = verificationCodeRepository.findByScenesAndTypeAndValueAndStatusIsTrue(code.getScenes(),code.getType(),code.getValue());
+ if(verificationCode == null || !verificationCode.getCode().equals(code.getCode())){
+ throw new BadRequestException("无效验证码");
+ } else {
+ verificationCode.setStatus(false);
+ verificationCodeRepository.save(verificationCode);
+ }
+ }
+ /**
+ * 定时任务,指定分钟后改变验证码状态
+ * @param verifyCode
+ */
+ private void timedDestruction(VerificationCode verifyCode) {
+ //以下示例为程序调用结束继续运行
+ ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+ try {
+ executorService.schedule(() -> {
+ verifyCode.setStatus(false);
+ verificationCodeRepository.save(verifyCode);
+ }, expiration * 60 * 1000L, TimeUnit.MILLISECONDS);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
}
}
diff --git a/src/main/java/me/zhengjie/tools/domain/AlipayConfig.java b/src/main/java/me/zhengjie/tools/domain/AlipayConfig.java
new file mode 100644
index 000000000..58256fbac
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/domain/AlipayConfig.java
@@ -0,0 +1,80 @@
+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-31
+ */
+@Data
+@Entity
+@Table(name = "alipay_config")
+public class AlipayConfig implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ /**
+ * 应用ID,APPID,收款账号既是APPID对应支付宝账号
+ */
+ @NotBlank
+ private String appID;
+
+ /**
+ * 商户私钥,您的PKCS8格式RSA2私钥
+ */
+ @NotBlank
+ @Column(length = 2000)
+ private String privateKey;
+
+ /**
+ * 支付宝公钥
+ */
+ @NotBlank
+ @Column(length = 2000)
+ private String publicKey;
+
+ /**
+ * 签名方式,固定格式
+ */
+ private String signType="RSA2";
+
+ /**
+ * 支付宝开放安全地址,一般不会变
+ */
+ private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
+
+ /**
+ * 编码,固定格式
+ */
+ private String charset= "utf-8";
+
+ /**
+ * 异步通知地址
+ */
+ @NotBlank
+ private String notifyUrl;
+
+ /**
+ * 订单完成后返回的页面
+ */
+ @NotBlank
+ private String returnUrl;
+
+ /**
+ * 类型,固定格式
+ */
+ private String format="JSON";
+
+ /**
+ * 商户号
+ */
+ @NotBlank
+ private String sysServiceProviderId;
+
+}
diff --git a/src/main/java/me/zhengjie/tools/domain/QiniuConfig.java b/src/main/java/me/zhengjie/tools/domain/QiniuConfig.java
new file mode 100644
index 000000000..39400b4af
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/domain/QiniuConfig.java
@@ -0,0 +1,61 @@
+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-31
+ */
+@Data
+@Entity
+@Table(name = "qiniu_config")
+public class QiniuConfig implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ /**
+ * 一个账号最多拥有两对密钥(Access/Secret Key)
+ */
+ @NotBlank
+ private String accessKey;
+
+ /**
+ * 一个账号最多拥有两对密钥(Access/Secret Key)
+ */
+ @NotBlank
+ private String secretKey;
+
+ /**
+ * 存储空间名称作为唯一的 Bucket 识别符
+ */
+ @NotBlank
+ private String bucket;
+
+ /**
+ * Zone表示与机房的对应关系
+ * 华东 Zone.zone0()
+ * 华北 Zone.zone1()
+ * 华南 Zone.zone2()
+ * 北美 Zone.zoneNa0()
+ * 东南亚 Zone.zoneAs0()
+ */
+ @NotBlank
+ private String zone;
+
+ /**
+ * 外链域名,可自定义,需在七牛云绑定
+ */
+ @NotBlank
+ private String host;
+
+ /**
+ * 空间类型:公开/私有
+ */
+ private String type = "公开";
+}
diff --git a/src/main/java/me/zhengjie/tools/domain/QiniuContent.java b/src/main/java/me/zhengjie/tools/domain/QiniuContent.java
new file mode 100644
index 000000000..de33fdffb
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/domain/QiniuContent.java
@@ -0,0 +1,54 @@
+package me.zhengjie.tools.domain;
+
+import lombok.Data;
+import org.hibernate.annotations.UpdateTimestamp;
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+/**
+ * 上传成功后,存储结果
+ * @author jie
+ * @date 2018-12-31
+ */
+@Data
+@Entity
+@Table(name = "qiniu_content")
+public class QiniuContent implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ /**
+ * 文件名,如qiniu.jpg
+ */
+ @Column(name = "name",unique = false)
+ private String key;
+
+ /**
+ * 空间名
+ */
+ private String bucket;
+
+ /**
+ * 大小
+ */
+ private String size;
+
+ /**
+ * 文件地址
+ */
+ private String url;
+
+ /**
+ * 空间类型:公开/私有
+ */
+ private String type = "公开";
+
+ /**
+ * 更新时间
+ */
+ @UpdateTimestamp
+ private Timestamp updateTime;
+}
diff --git a/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java b/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java
index cb8c78ccb..cbed2b8fb 100644
--- a/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java
+++ b/src/main/java/me/zhengjie/tools/domain/vo/EmailVo.java
@@ -1,6 +1,8 @@
package me.zhengjie.tools.domain.vo;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
@@ -13,6 +15,8 @@
* @date 2018/09/28 12:02:14
*/
@Data
+@AllArgsConstructor
+@NoArgsConstructor
public class EmailVo {
/**
diff --git a/src/main/java/me/zhengjie/tools/domain/vo/TradeVo.java b/src/main/java/me/zhengjie/tools/domain/vo/TradeVo.java
new file mode 100644
index 000000000..bc57634d7
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/domain/vo/TradeVo.java
@@ -0,0 +1,65 @@
+package me.zhengjie.tools.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.sql.Date;
+import java.sql.Timestamp;
+
+/**
+ * 交易详情,按需应该存入数据库,这里存入数据库,仅供临时测试
+ * @author jie
+ * @date 2018-12-31
+ */
+@Data
+public class TradeVo {
+
+ /**
+ * (必填)商品描述
+ */
+ @NotBlank
+ private String body;
+
+ /**
+ * (必填)商品名称
+ */
+ @NotBlank
+ private String subject;
+
+ /**
+ * (必填)商户订单号,应该由后台生成
+ */
+ @ApiModelProperty(hidden = true)
+ private String outTradeNo;
+
+ /**
+ * (必填)第三方订单号
+ */
+ @ApiModelProperty(hidden = true)
+ private String tradeNo;
+
+ /**
+ * (必填)价格
+ */
+ @NotBlank
+ private String totalAmount;
+
+ /**
+ * 订单状态,已支付,未支付,作废
+ */
+ @ApiModelProperty(hidden = true)
+ private String state;
+
+ /**
+ * 创建时间,存入数据库时需要
+ */
+ @ApiModelProperty(hidden = true)
+ private Timestamp createTime;
+
+ /**
+ * 作废时间,存入数据库时需要
+ */
+ @ApiModelProperty(hidden = true)
+ private Date cancelTime;
+}
diff --git a/src/main/java/me/zhengjie/tools/repository/AlipayRepository.java b/src/main/java/me/zhengjie/tools/repository/AlipayRepository.java
new file mode 100644
index 000000000..cb176035f
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/repository/AlipayRepository.java
@@ -0,0 +1,11 @@
+package me.zhengjie.tools.repository;
+
+import me.zhengjie.tools.domain.AlipayConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+public interface AlipayRepository extends JpaRepository {
+}
diff --git a/src/main/java/me/zhengjie/tools/repository/QiNiuConfigRepository.java b/src/main/java/me/zhengjie/tools/repository/QiNiuConfigRepository.java
new file mode 100644
index 000000000..481dd53a5
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/repository/QiNiuConfigRepository.java
@@ -0,0 +1,11 @@
+package me.zhengjie.tools.repository;
+
+import me.zhengjie.tools.domain.QiniuConfig;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+public interface QiNiuConfigRepository extends JpaRepository {
+}
diff --git a/src/main/java/me/zhengjie/tools/repository/QiniuContentRepository.java b/src/main/java/me/zhengjie/tools/repository/QiniuContentRepository.java
new file mode 100644
index 000000000..868f26aa5
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/repository/QiniuContentRepository.java
@@ -0,0 +1,19 @@
+package me.zhengjie.tools.repository;
+
+import me.zhengjie.tools.domain.QiniuContent;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+public interface QiniuContentRepository extends JpaRepository, JpaSpecificationExecutor {
+
+ /**
+ * 根据key查询
+ * @param key
+ * @return
+ */
+ QiniuContent findByKey(String key);
+}
diff --git a/src/main/java/me/zhengjie/tools/rest/AliPayController.java b/src/main/java/me/zhengjie/tools/rest/AliPayController.java
new file mode 100644
index 000000000..5ce574f4f
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/rest/AliPayController.java
@@ -0,0 +1,125 @@
+package me.zhengjie.tools.rest;
+
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import me.zhengjie.common.aop.log.Log;
+import me.zhengjie.tools.domain.AlipayConfig;
+import me.zhengjie.tools.domain.vo.TradeVo;
+import me.zhengjie.tools.service.AlipayService;
+import me.zhengjie.tools.util.AliPayStatusEnum;
+import me.zhengjie.tools.util.AlipayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api")
+public class AliPayController {
+
+ @Autowired
+ AlipayUtils alipayUtils;
+
+ @Autowired
+ private AlipayService alipayService;
+
+ @GetMapping(value = "/aliPay")
+ public ResponseEntity get(){
+ return new ResponseEntity(alipayService.find(),HttpStatus.OK);
+ }
+
+ @Log(description = "配置支付宝")
+ @PutMapping(value = "/aliPay")
+ public ResponseEntity payConfig(@Validated @RequestBody AlipayConfig alipayConfig){
+ alipayConfig.setId(1L);
+ alipayService.update(alipayConfig);
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ @Log(description = "支付宝PC网页支付")
+ @ApiOperation(value = "PC网页支付")
+ @PostMapping(value = "/aliPay/toPayAsPC")
+ public ResponseEntity toPayAsPC(@Validated@RequestBody TradeVo trade) throws Exception{
+ log.warn("REST request to toPayAsPC Trade : {}" +trade);
+ AlipayConfig alipay = alipayService.find();
+ trade.setOutTradeNo(alipayUtils.getOrderCode());
+ String payUrl = alipayService.toPayAsPC(alipay,trade);
+ return ResponseEntity.ok(payUrl);
+ }
+
+ @Log(description = "支付宝手机网页支付")
+ @ApiOperation(value = "手机网页支付")
+ @PostMapping(value = "/aliPay/toPayAsWeb")
+ public ResponseEntity toPayAsWeb(@Validated @RequestBody TradeVo trade) throws Exception{
+ log.warn("REST request to toPayAsWeb Trade : {}" +trade);
+ AlipayConfig alipay = alipayService.find();
+ trade.setOutTradeNo(alipayUtils.getOrderCode());
+ String payUrl = alipayService.toPayAsWeb(alipay,trade);
+ return ResponseEntity.ok(payUrl);
+ }
+
+ @ApiIgnore
+ @GetMapping("/aliPay/return")
+ @ApiOperation(value = "支付之后跳转的链接")
+ public ResponseEntity returnPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ AlipayConfig alipay = alipayService.find();
+ response.setContentType("text/html;charset=" + alipay.getCharset());
+ //内容验签,防止黑客篡改参数
+ if(alipayUtils.rsaCheck(request,alipay)){
+ //商户订单号
+ String outTradeNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
+ //支付宝交易号
+ String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
+ System.out.println("商户订单号"+outTradeNo+" "+"第三方交易号"+tradeNo);
+
+ /**
+ * 根据业务需要返回数据,这里统一返回OK
+ */
+ return new ResponseEntity("payment successful",HttpStatus.OK);
+ }else{
+ /**
+ * 根据业务需要返回数据
+ */
+ return new ResponseEntity(HttpStatus.BAD_REQUEST);
+ }
+ }
+
+ @ApiIgnore
+ @RequestMapping("/aliPay/notify")
+ @ApiOperation(value = "支付异步通知(要公网访问),接收异步通知,检查通知内容app_id、out_trade_no、total_amount是否与请求中的一致,根据trade_status进行后续业务处理")
+ public ResponseEntity notify(HttpServletRequest request) throws Exception{
+ AlipayConfig alipay = alipayService.find();
+ Map parameterMap = request.getParameterMap();
+ StringBuilder notifyBuild = new StringBuilder("/****************************** pay notify ******************************/\n");
+ parameterMap.forEach((key, value) -> notifyBuild.append(key + "=" + value[0] + "\n") );
+ //内容验签,防止黑客篡改参数
+ if (alipayUtils.rsaCheck(request,alipay)) {
+ //交易状态
+ String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
+ // 商户订单号
+ String outTradeNo = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
+ //支付宝交易号
+ String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
+ //付款金额
+ String totalAmount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
+ //验证
+ if(tradeStatus.equals(AliPayStatusEnum.SUCCESS.getValue())||tradeStatus.equals(AliPayStatusEnum.FINISHED.getValue())){
+ /**
+ * 验证通过后应该根据业务需要处理订单
+ */
+ }
+ return new ResponseEntity(HttpStatus.OK);
+ }
+ return new ResponseEntity(HttpStatus.BAD_REQUEST);
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/rest/EmailController.java b/src/main/java/me/zhengjie/tools/rest/EmailController.java
index a30f6f2e0..f9c37f653 100644
--- a/src/main/java/me/zhengjie/tools/rest/EmailController.java
+++ b/src/main/java/me/zhengjie/tools/rest/EmailController.java
@@ -25,13 +25,11 @@ 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){
@@ -39,7 +37,6 @@ public ResponseEntity emailConfig(@Validated @RequestBody EmailConfig emailConfi
return new ResponseEntity(HttpStatus.OK);
}
- @PreAuthorize("hasAnyRole('ADMIN')")
@Log(description = "发送邮件")
@PostMapping(value = "/email")
public ResponseEntity send(@Validated @RequestBody EmailVo emailVo) throws Exception {
diff --git a/src/main/java/me/zhengjie/tools/rest/QiniuController.java b/src/main/java/me/zhengjie/tools/rest/QiniuController.java
new file mode 100644
index 000000000..806c37ec6
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/rest/QiniuController.java
@@ -0,0 +1,108 @@
+package me.zhengjie.tools.rest;
+
+import lombok.extern.slf4j.Slf4j;
+import me.zhengjie.common.aop.log.Log;
+import me.zhengjie.tools.domain.QiniuConfig;
+import me.zhengjie.tools.domain.QiniuContent;
+import me.zhengjie.tools.service.QiNiuService;
+import me.zhengjie.tools.service.query.QiNiuQueryService;
+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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 发送邮件
+ * @author 郑杰
+ * @date 2018/09/28 6:55:53
+ */
+@Slf4j
+@RestController
+@RequestMapping("api")
+public class QiniuController {
+
+ @Autowired
+ private QiNiuService qiNiuService;
+
+ @Autowired
+ private QiNiuQueryService qiNiuQueryService;
+
+ @GetMapping(value = "/qiNiuConfig")
+ public ResponseEntity get(){
+ return new ResponseEntity(qiNiuService.find(), HttpStatus.OK);
+ }
+
+ @Log(description = "配置七牛云存储")
+ @PutMapping(value = "/qiNiuConfig")
+ public ResponseEntity emailConfig(@Validated @RequestBody QiniuConfig qiniuConfig){
+ qiNiuService.update(qiniuConfig);
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ @Log(description = "查询文件")
+ @GetMapping(value = "/qiNiuContent")
+ public ResponseEntity getRoles(QiniuContent resources, Pageable pageable){
+ return new ResponseEntity(qiNiuQueryService.queryAll(resources,pageable),HttpStatus.OK);
+ }
+
+ /**
+ * 上传文件到七牛云
+ * @param file
+ * @return
+ */
+ @Log(description ="上传文件")
+ @PostMapping(value = "/qiNiuContent")
+ public ResponseEntity upload(@RequestParam MultipartFile file){
+ QiniuContent qiniuContent = qiNiuService.upload(file,qiNiuService.find());
+ Map map = new HashMap();
+ map.put("errno",0);
+ map.put("id",qiniuContent.getId());
+ map.put("data",new String[]{qiniuContent.getUrl()});
+ return new ResponseEntity(map,HttpStatus.OK);
+ }
+
+ /**
+ * 同步七牛云数据到数据库
+ * @return
+ */
+ @Log(description ="同步七牛云数据")
+ @PostMapping(value = "/qiNiuContent/synchronize")
+ public ResponseEntity synchronize(){
+ log.warn("REST request to synchronize qiNiu : {}");
+ qiNiuService.synchronize(qiNiuService.find());
+ return new ResponseEntity(HttpStatus.OK);
+ }
+
+ /**
+ * 下载七牛云文件
+ * @param id
+ * @return
+ * @throws Exception
+ */
+ @Log(description ="下载文件")
+ @GetMapping(value = "/qiNiuContent/download/{id}")
+ public ResponseEntity download(@PathVariable Long id){
+ return new ResponseEntity(qiNiuService.download(qiNiuService.findByContentId(id),qiNiuService.find()),HttpStatus.OK);
+ }
+
+ /**
+ * 删除七牛云文件
+ * @param id
+ * @return
+ * @throws Exception
+ */
+ @Log(description ="删除文件")
+ @DeleteMapping(value = "/qiNiuContent/{id}")
+ public ResponseEntity delete(@PathVariable Long id){
+ qiNiuService.delete(qiNiuService.findByContentId(id),qiNiuService.find());
+ return new ResponseEntity(HttpStatus.OK);
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/service/AlipayService.java b/src/main/java/me/zhengjie/tools/service/AlipayService.java
new file mode 100644
index 000000000..68a284062
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/service/AlipayService.java
@@ -0,0 +1,48 @@
+package me.zhengjie.tools.service;
+
+import me.zhengjie.tools.domain.AlipayConfig;
+import me.zhengjie.tools.domain.vo.TradeVo;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+@CacheConfig(cacheNames = "alipay")
+public interface AlipayService {
+
+ /**
+ * 处理来自PC的交易请求
+ * @param alipay
+ * @param trade
+ * @return
+ * @throws Exception
+ */
+ String toPayAsPC(AlipayConfig alipay, TradeVo trade) throws Exception;
+
+ /**
+ * 处理来自手机网页的交易请求
+ * @param alipay
+ * @param trade
+ * @return
+ * @throws Exception
+ */
+ String toPayAsWeb(AlipayConfig alipay, TradeVo trade) throws Exception;
+
+ /**
+ * 查询配置
+ * @return
+ */
+ @Cacheable(key = "'1'")
+ AlipayConfig find();
+
+ /**
+ * 更新配置
+ * @param alipayConfig
+ * @return
+ */
+ @CachePut(key = "'1'")
+ AlipayConfig update(AlipayConfig alipayConfig);
+}
diff --git a/src/main/java/me/zhengjie/tools/service/QiNiuService.java b/src/main/java/me/zhengjie/tools/service/QiNiuService.java
new file mode 100644
index 000000000..179083855
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/service/QiNiuService.java
@@ -0,0 +1,73 @@
+package me.zhengjie.tools.service;
+
+import me.zhengjie.tools.domain.QiniuConfig;
+import me.zhengjie.tools.domain.QiniuContent;
+import org.springframework.cache.annotation.CacheConfig;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+@CacheConfig(cacheNames = "qiNiu")
+public interface QiNiuService {
+
+ /**
+ * 查配置
+ * @return
+ */
+ @Cacheable(key = "'1'")
+ QiniuConfig find();
+
+ /**
+ * 修改配置
+ * @param qiniuConfig
+ * @return
+ */
+ @CachePut(key = "'1'")
+ QiniuConfig update(QiniuConfig qiniuConfig);
+
+ /**
+ * 上传文件
+ * @param file
+ * @param qiniuConfig
+ */
+ @CacheEvict(allEntries = true)
+ QiniuContent upload(MultipartFile file, QiniuConfig qiniuConfig);
+
+ /**
+ * 查询文件
+ * @param id
+ * @return
+ */
+ @Cacheable(key = "'content:'+#p0")
+ QiniuContent findByContentId(Long id);
+
+ /**
+ * 下载文件
+ * @param content
+ * @param config
+ * @return
+ */
+ String download(QiniuContent content, QiniuConfig config);
+
+ /**
+ * 删除文件
+ * @param content
+ * @param config
+ * @return
+ */
+ @CacheEvict(allEntries = true)
+ void delete(QiniuContent content, QiniuConfig config);
+
+ /**
+ * 同步数据
+ * @param config
+ */
+ @CacheEvict(allEntries = true)
+ void synchronize(QiniuConfig config);
+}
diff --git a/src/main/java/me/zhengjie/tools/service/impl/AlipayServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/AlipayServiceImpl.java
new file mode 100644
index 000000000..d52af8d42
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/service/impl/AlipayServiceImpl.java
@@ -0,0 +1,135 @@
+package me.zhengjie.tools.service.impl;
+
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.request.AlipayTradePagePayRequest;
+import com.alipay.api.request.AlipayTradeWapPayRequest;
+import me.zhengjie.common.exception.BadRequestException;
+import me.zhengjie.tools.domain.AlipayConfig;
+import me.zhengjie.tools.domain.vo.TradeVo;
+import me.zhengjie.tools.repository.AlipayRepository;
+import me.zhengjie.tools.service.AlipayService;
+import me.zhengjie.tools.util.AlipayUtils;
+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-31
+ */
+@Service
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
+public class AlipayServiceImpl implements AlipayService {
+
+ @Autowired
+ AlipayUtils alipayUtils;
+
+ @Autowired
+ private AlipayRepository alipayRepository;
+
+ @Override
+ public String toPayAsPC(AlipayConfig alipay, TradeVo trade) throws Exception {
+
+ if(alipay.getId() == null){
+ throw new BadRequestException("请先添加相应配置,再操作");
+ }
+ AlipayClient alipayClient = new DefaultAlipayClient(alipay.getGatewayUrl(), alipay.getAppID(), alipay.getPrivateKey(), alipay.getFormat(), alipay.getCharset(), alipay.getPublicKey(), alipay.getSignType());
+
+ double money = Double.parseDouble(trade.getTotalAmount());
+ if(money <= 0 || money>=5000){
+ throw new BadRequestException("测试金额过大");
+ }
+
+ /**
+ * 创建API对应的request(电脑网页版)
+ */
+ AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
+
+ /**
+ * 订单完成后返回的页面和异步通知地址
+ */
+ request.setReturnUrl(alipay.getReturnUrl());
+ request.setNotifyUrl(alipay.getNotifyUrl());
+ /**
+ * 填充订单参数
+ */
+ request.setBizContent("{" +
+ " \"out_trade_no\":\""+trade.getOutTradeNo()+"\"," +
+ " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
+ " \"total_amount\":"+trade.getTotalAmount()+"," +
+ " \"subject\":\""+trade.getSubject()+"\"," +
+ " \"body\":\""+trade.getBody()+"\"," +
+ " \"extend_params\":{" +
+ " \"sys_service_provider_id\":\""+alipay.getSysServiceProviderId()+"\"" +
+ " }"+
+ " }");//填充业务参数
+ /**
+ * 调用SDK生成表单
+ * 通过GET方式,口可以获取url
+ */
+ return alipayClient.pageExecute(request, "GET").getBody();
+
+ }
+
+ @Override
+ public String toPayAsWeb(AlipayConfig alipay, TradeVo trade) throws Exception {
+ if(alipay.getId() == null){
+ throw new BadRequestException("请先添加相应配置,再操作");
+ }
+ AlipayClient alipayClient = new DefaultAlipayClient(alipay.getGatewayUrl(), alipay.getAppID(), alipay.getPrivateKey(), alipay.getFormat(), alipay.getCharset(), alipay.getPublicKey(), alipay.getSignType());
+
+ double money = Double.parseDouble(trade.getTotalAmount());
+ if(money <= 0 || money >= 5000){
+ throw new BadRequestException("测试金额过大");
+ }
+
+ /**
+ * 创建API对应的request(手机网页版)
+ */
+ AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
+
+ /**
+ * 订单完成后返回的页面和异步通知地址
+ */
+ request.setReturnUrl(alipay.getReturnUrl());
+ request.setNotifyUrl(alipay.getNotifyUrl());
+ /**
+ * 填充订单参数
+ */
+ request.setBizContent("{" +
+ " \"out_trade_no\":\""+trade.getOutTradeNo()+"\"," +
+ " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
+ " \"total_amount\":"+trade.getTotalAmount()+"," +
+ " \"subject\":\""+trade.getSubject()+"\"," +
+ " \"body\":\""+trade.getBody()+"\"," +
+ " \"extend_params\":{" +
+ " \"sys_service_provider_id\":\""+alipay.getSysServiceProviderId()+"\"" +
+ " }"+
+ " }");//填充业务参数
+ /**
+ * 调用SDK生成表单
+ * 通过GET方式,口可以获取url
+ */
+ return alipayClient.pageExecute(request, "GET").getBody();
+ }
+
+ @Override
+ public AlipayConfig find() {
+ Optional alipayConfig = alipayRepository.findById(1L);
+ if (alipayConfig.isPresent()){
+ return alipayConfig.get();
+ } else {
+ return new AlipayConfig();
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public AlipayConfig update(AlipayConfig alipayConfig) {
+ return alipayRepository.saveAndFlush(alipayConfig);
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java
index ffc80a92c..cd01e30bf 100644
--- a/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java
+++ b/src/main/java/me/zhengjie/tools/service/impl/EmailServiceImpl.java
@@ -3,6 +3,7 @@
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import me.zhengjie.common.exception.BadRequestException;
+import me.zhengjie.common.utils.ElAdminConstant;
import me.zhengjie.core.utils.EncryptUtils;
import me.zhengjie.tools.domain.EmailConfig;
import me.zhengjie.tools.domain.vo.EmailVo;
@@ -72,7 +73,7 @@ public void send(EmailVo emailVo, EmailConfig emailConfig){
account.setFrom(emailConfig.getUser()+"<"+emailConfig.getFromUser()+">");
//ssl方式发送
account.setStartttlsEnable(true);
- String content = emailVo.getContent()+ "----- 邮件来自 eladmin 后台管理系统
";
+ String content = emailVo.getContent()+ ElAdminConstant.EMAIL_CONTENT;
/**
* 发送
*/
diff --git a/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java
index 3deec4f9a..c5c11c48b 100644
--- a/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java
+++ b/src/main/java/me/zhengjie/tools/service/impl/PictureServiceImpl.java
@@ -70,7 +70,7 @@ public Picture upload(MultipartFile multipartFile, String username) {
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()));
+ picture.setFilename(FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename())+FileUtil.getExtensionName(multipartFile.getOriginalFilename()));
pictureRepository.save(picture);
//删除临时文件
FileUtil.deleteFile(file);
diff --git a/src/main/java/me/zhengjie/tools/service/impl/QiNiuServiceImpl.java b/src/main/java/me/zhengjie/tools/service/impl/QiNiuServiceImpl.java
new file mode 100644
index 000000000..f123321c2
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/service/impl/QiNiuServiceImpl.java
@@ -0,0 +1,179 @@
+package me.zhengjie.tools.service.impl;
+
+import com.google.gson.Gson;
+import com.qiniu.common.QiniuException;
+import com.qiniu.http.Response;
+import com.qiniu.storage.BucketManager;
+import com.qiniu.storage.Configuration;
+import com.qiniu.storage.UploadManager;
+import com.qiniu.storage.model.DefaultPutRet;
+import com.qiniu.storage.model.FileInfo;
+import com.qiniu.util.Auth;
+import me.zhengjie.common.exception.BadRequestException;
+import me.zhengjie.common.utils.FileUtil;
+import me.zhengjie.common.utils.ValidationUtil;
+import me.zhengjie.tools.domain.QiniuConfig;
+import me.zhengjie.tools.domain.QiniuContent;
+import me.zhengjie.tools.repository.QiNiuConfigRepository;
+import me.zhengjie.tools.repository.QiniuContentRepository;
+import me.zhengjie.tools.service.QiNiuService;
+import me.zhengjie.tools.util.QiNiuUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.UnsupportedEncodingException;
+import java.util.Optional;
+
+/**
+ * @author jie
+ * @date 2018-12-31
+ */
+@Service
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
+public class QiNiuServiceImpl implements QiNiuService {
+
+ @Autowired
+ private QiNiuConfigRepository qiNiuConfigRepository;
+
+ @Autowired
+ private QiniuContentRepository qiniuContentRepository;
+
+ @Value("${qiniu.max-size}")
+ private Long maxSize;
+
+ private final String TYPE = "公开";
+
+ @Override
+ public QiniuConfig find() {
+ Optional qiniuConfig = qiNiuConfigRepository.findById(1L);
+ if(qiniuConfig.isPresent()){
+ return qiniuConfig.get();
+ } else {
+ return new QiniuConfig();
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public QiniuConfig update(QiniuConfig qiniuConfig) {
+ if (!(qiniuConfig.getHost().toLowerCase().startsWith("http://")||qiniuConfig.getHost().toLowerCase().startsWith("https://"))) {
+ throw new BadRequestException("外链域名必须以http://或者https://开头");
+ }
+ qiniuConfig.setId(1L);
+ return qiNiuConfigRepository.save(qiniuConfig);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public QiniuContent upload(MultipartFile file, QiniuConfig qiniuConfig) {
+
+ Long size = maxSize * 1024 * 1024;
+ if(file.getSize() > size){
+ throw new BadRequestException("文件超出规定大小");
+ }
+ if(qiniuConfig.getId() == null){
+ throw new BadRequestException("请先添加相应配置,再操作");
+ }
+ /**
+ * 构造一个带指定Zone对象的配置类
+ */
+ Configuration cfg = QiNiuUtil.getConfiguration(qiniuConfig.getZone());
+ UploadManager uploadManager = new UploadManager(cfg);
+ Auth auth = Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
+ String upToken = auth.uploadToken(qiniuConfig.getBucket());
+ try {
+ Response response = uploadManager.put(file.getBytes(), QiNiuUtil.getKey(file.getOriginalFilename()), upToken);
+ //解析上传成功的结果
+ DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
+ //存入数据库
+ QiniuContent qiniuContent = new QiniuContent();
+ qiniuContent.setBucket(qiniuConfig.getBucket());
+ qiniuContent.setType(qiniuConfig.getType());
+ qiniuContent.setKey(putRet.key);
+ qiniuContent.setUrl(qiniuConfig.getHost()+"/"+putRet.key);
+ qiniuContent.setSize(FileUtil.getSize(Integer.parseInt(file.getSize()+"")));
+ return qiniuContentRepository.save(qiniuContent);
+ } catch (Exception e) {
+ throw new BadRequestException(e.getMessage());
+ }
+ }
+
+ @Override
+ public QiniuContent findByContentId(Long id) {
+ Optional qiniuContent = qiniuContentRepository.findById(id);
+ ValidationUtil.isNull(qiniuContent,"QiniuContent", "id",id);
+ return qiniuContent.get();
+ }
+
+ @Override
+ public String download(QiniuContent content,QiniuConfig config){
+ String finalUrl = null;
+ if(TYPE.equals(content.getType())){
+ finalUrl = content.getUrl();
+ } else {
+ Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
+ /**
+ * 1小时,可以自定义链接过期时间
+ */
+ long expireInSeconds = 3600;
+ finalUrl = auth.privateDownloadUrl(content.getUrl(), expireInSeconds);
+ }
+ return finalUrl;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void delete(QiniuContent content, QiniuConfig config) {
+ //构造一个带指定Zone对象的配置类
+ Configuration cfg = QiNiuUtil.getConfiguration(config.getZone());
+ Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
+ BucketManager bucketManager = new BucketManager(auth, cfg);
+ try {
+ bucketManager.delete(content.getBucket(), content.getKey());
+ qiniuContentRepository.delete(content);
+ } catch (QiniuException ex) {
+ System.err.println(ex.code());
+ System.err.println(ex.response.toString());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void synchronize(QiniuConfig config) {
+ if(config.getId() == null){
+ throw new BadRequestException("请先添加相应配置,再操作");
+ }
+ //构造一个带指定Zone对象的配置类
+ Configuration cfg = QiNiuUtil.getConfiguration(config.getZone());
+ Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
+ BucketManager bucketManager = new BucketManager(auth, cfg);
+ //文件名前缀
+ String prefix = "";
+ //每次迭代的长度限制,最大1000,推荐值 1000
+ int limit = 1000;
+ //指定目录分隔符,列出所有公共前缀(模拟列出目录效果)。缺省值为空字符串
+ String delimiter = "";
+ //列举空间文件列表
+ BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(config.getBucket(), prefix, limit, delimiter);
+ while (fileListIterator.hasNext()) {
+ //处理获取的file list结果
+ QiniuContent qiniuContent = null;
+ FileInfo[] items = fileListIterator.next();
+ for (FileInfo item : items) {
+ if(qiniuContentRepository.findByKey(item.key) == null){
+ qiniuContent = new QiniuContent();
+ qiniuContent.setSize(FileUtil.getSize(Integer.parseInt(item.fsize+"")));
+ qiniuContent.setKey(item.key);
+ qiniuContent.setType(config.getType());
+ qiniuContent.setBucket(config.getBucket());
+ qiniuContent.setUrl(config.getHost()+"/"+item.key);
+ qiniuContentRepository.save(qiniuContent);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/service/query/QiNiuQueryService.java b/src/main/java/me/zhengjie/tools/service/query/QiNiuQueryService.java
new file mode 100644
index 000000000..d284fc708
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/service/query/QiNiuQueryService.java
@@ -0,0 +1,66 @@
+package me.zhengjie.tools.service.query;
+
+import me.zhengjie.common.utils.PageUtil;
+import me.zhengjie.tools.domain.QiniuContent;
+import me.zhengjie.tools.repository.QiniuContentRepository;
+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-31
+ */
+@Service
+@CacheConfig(cacheNames = "qiNiu")
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
+public class QiNiuQueryService {
+
+ @Autowired
+ private QiniuContentRepository qiniuContentRepository;
+
+ /**
+ * 分页
+ */
+ @Cacheable(keyGenerator = "keyGenerator")
+ public Object queryAll(QiniuContent qiniuContent, Pageable pageable){
+ return PageUtil.toPage(qiniuContentRepository.findAll(new Spec(qiniuContent),pageable));
+ }
+
+ class Spec implements Specification {
+
+ private QiniuContent qiniuContent;
+
+ public Spec(QiniuContent qiniuContent){
+ this.qiniuContent = qiniuContent;
+ }
+
+ @Override
+ public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder cb) {
+
+ List list = new ArrayList();
+
+ if(!ObjectUtils.isEmpty(qiniuContent.getKey())){
+ /**
+ * 模糊
+ */
+ list.add(cb.like(root.get("key").as(String.class),"%"+qiniuContent.getKey()+"%"));
+ }
+
+ Predicate[] p = new Predicate[list.size()];
+ return cb.and(list.toArray(p));
+ }
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/util/AliPayStatusEnum.java b/src/main/java/me/zhengjie/tools/util/AliPayStatusEnum.java
new file mode 100644
index 000000000..a61f38296
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/util/AliPayStatusEnum.java
@@ -0,0 +1,41 @@
+package me.zhengjie.tools.util;
+
+/**
+ * 支付状态
+ * @author zhengjie
+ * @date 2018/08/01 16:45:43
+ */
+public enum AliPayStatusEnum {
+
+ /**
+ * 交易成功
+ */
+ FINISHED("交易成功", "TRADE_FINISHED"),
+
+ /**
+ * 支付成功
+ */
+ SUCCESS("支付成功", "TRADE_SUCCESS"),
+
+ /**
+ * 交易创建
+ */
+ BUYER_PAY("交易创建", "WAIT_BUYER_PAY"),
+
+ /**
+ * 交易关闭
+ */
+ CLOSED("交易关闭", "TRADE_CLOSED");
+
+ private String name;
+ private String value;
+
+ AliPayStatusEnum(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/util/AlipayUtils.java b/src/main/java/me/zhengjie/tools/util/AlipayUtils.java
new file mode 100644
index 000000000..fbdccb18e
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/util/AlipayUtils.java
@@ -0,0 +1,79 @@
+package me.zhengjie.tools.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.internal.util.AlipaySignature;
+import me.zhengjie.tools.domain.AlipayConfig;
+import org.springframework.stereotype.Component;
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * 支付宝工具类
+ * @author zhengjie
+ * @date 2018/09/30 14:04:35
+ */
+@Component
+public class AlipayUtils {
+
+ /**
+ * 生成订单号
+ * @return
+ */
+ public String getOrderCode() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ int a = (int)(Math.random() * 9000.0D) + 1000;
+ System.out.println(a);
+ Date date = new Date();
+ String str = sdf.format(date);
+ String[] split = str.split("-");
+ String s = split[0] + split[1] + split[2];
+ String[] split1 = s.split(" ");
+ String s1 = split1[0] + split1[1];
+ String[] split2 = s1.split(":");
+ String s2 = split2[0] + split2[1] + split2[2] + a;
+ return s2;
+ }
+
+ /**
+ * 校验签名
+ * @param request
+ * @return
+ */
+ public boolean rsaCheck(HttpServletRequest request, AlipayConfig alipay){
+
+ /**
+ * 获取支付宝POST过来反馈信息
+ */
+ Map params = new HashMap<>(1);
+ Map requestParams = request.getParameterMap();
+ for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
+ String name = (String) iter.next();
+ String[] values = (String[]) requestParams.get(name);
+ String valueStr = "";
+ for (int i = 0; i < values.length; i++) {
+ valueStr = (i == values.length - 1) ? valueStr + values[i]
+ : valueStr + values[i] + ",";
+ }
+ params.put(name, valueStr);
+ }
+
+ try {
+ boolean verifyResult = AlipaySignature.rsaCheckV1(params,
+ alipay.getPublicKey(),
+ alipay.getCharset(),
+ alipay.getSignType());
+ return verifyResult;
+ } catch (AlipayApiException e) {
+ return false;
+ }
+ }
+
+ public boolean isEmpty(String str){
+ return StrUtil.isEmpty(str);
+ }
+}
diff --git a/src/main/java/me/zhengjie/tools/util/QiNiuUtil.java b/src/main/java/me/zhengjie/tools/util/QiNiuUtil.java
new file mode 100644
index 000000000..c75b3e0d9
--- /dev/null
+++ b/src/main/java/me/zhengjie/tools/util/QiNiuUtil.java
@@ -0,0 +1,60 @@
+package me.zhengjie.tools.util;
+
+import com.qiniu.common.Zone;
+import com.qiniu.storage.Configuration;
+import me.zhengjie.common.utils.FileUtil;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 七牛云存储工具类
+ * @author jie
+ * @date 2018-12-31
+ */
+public class QiNiuUtil {
+
+ public static final String HUAD = "华东";
+
+ public static final String HUAB = "华北";
+
+ public static final String HUAN = "华南";
+
+ public static final String BEIM = "北美";
+
+ /**
+ * 得到机房的对应关系
+ * @param zone
+ * @return
+ */
+ public static Configuration getConfiguration(String zone){
+
+ if(HUAD.equals(zone)){
+ return new Configuration(Zone.zone0());
+ } else if(HUAB.equals(zone)){
+ return new Configuration(Zone.zone1());
+ } else if(HUAN.equals(zone)){
+ return new Configuration(Zone.zone2());
+ } else if (BEIM.equals(zone)){
+ return new Configuration(Zone.zoneNa0());
+
+ // 否则就是东南亚
+ } else {
+ return new Configuration(Zone.zoneAs0());
+ }
+ }
+
+ /**
+ * 默认不指定key的情况下,以文件内容的hash值作为文件名
+ * @param file
+ * @return
+ */
+ public static String getKey(String file){
+ StringBuffer key = new StringBuffer(FileUtil.getFileNameNoEx(file));
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ Date date = new Date();
+ key.append(sdf.format(date));
+ key.append(".");
+ key.append(FileUtil.getExtensionName(file));
+ return key.toString();
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 1f1c81e87..ff424c862 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -80,11 +80,20 @@ spring:
jwt:
header: Authorization
secret: mySecret
- # token 过期时间 1个小时
- expiration: 3600000
+ # token 过期时间 2个小时
+ expiration: 7200000
# expiration: 60000
auth:
# 授权路径
path: /login
# 获取用户信息
- account: /info
\ No newline at end of file
+ account: /info
+
+#七牛云
+qiniu:
+ # 文件大小 /M
+ max-size: 5
+
+#验证码有效时间/分钟
+code:
+ expiration: 5
\ No newline at end of file