Repository: hacker-walker/Hacker-walker Branch: master Commit: 796b2ae16bf1 Files: 112 Total size: 216.6 KB Directory structure: gitextract_59w0rtjf/ ├── README-EN.md ├── README.md ├── hacker-db/ │ └── walker.sql ├── hacker-framework-common/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── hacker/ │ └── framework/ │ └── common/ │ ├── annotation/ │ │ ├── Constants.java │ │ ├── DistributedLock.java │ │ ├── Limiter.java │ │ └── ResponseCode.java │ ├── aspect/ │ │ ├── DistributedLockAspect.java │ │ ├── GlobalExceptionHandler.java │ │ ├── GlobalLogHandler.java │ │ ├── GlobalVariable.java │ │ ├── LimiterAspect.java │ │ ├── LockUtils.java │ │ └── SqlTimeInterceptor.java │ ├── consts/ │ │ └── CommonConst.java │ ├── enums/ │ │ └── BaseExceptionEnum.java │ ├── exception/ │ │ ├── AppException.java │ │ └── JxnhException.java │ ├── object/ │ │ ├── BaseConditionVo.java │ │ ├── PageResultVo.java │ │ ├── ResponseVo.java │ │ └── ResultUtil.java │ └── request/ │ ├── BaseCode.java │ ├── BaseResult.java │ ├── ResultBean.java │ ├── ResultInfo.java │ └── ResultInfoUtil.java ├── hacker-framework-model/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── hacker/ │ │ └── framework/ │ │ └── model/ │ │ ├── Cto/ │ │ │ ├── AdminRoles.java │ │ │ └── RolePermissions.java │ │ └── entity/ │ │ ├── Admin.java │ │ ├── Pay.java │ │ ├── Permission.java │ │ └── Role.java │ └── resources/ │ └── application.properties ├── hacker-framework-util/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── hacker/ │ │ └── framework/ │ │ └── util/ │ │ ├── ApplicationContextUtil.java │ │ ├── CommontUtil.java │ │ ├── FileUtil.java │ │ ├── LuKeIp.java │ │ ├── MD5Util.java │ │ ├── OrderUtil.java │ │ ├── SHA256.java │ │ ├── Snowflake.java │ │ ├── SnowflakeIdWorker.java │ │ ├── SslUtils.java │ │ ├── StringUtil.java │ │ ├── TestUtil.java │ │ └── TokenProccessor.java │ └── resources/ │ └── application.properties ├── hacker-govern-center/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── hacker/ │ │ └── framework/ │ │ └── center/ │ │ └── EurekaApplication.java │ └── resources/ │ ├── application.properties │ └── application.yml ├── hacker-govern-gateway/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── hacker/ │ │ └── govern/ │ │ └── gateway/ │ │ └── ZuulAppApplication.java │ └── resources/ │ ├── application.properties │ └── application.yml ├── hacker-service-channel-manage/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── hacker/ │ │ └── channel/ │ │ └── manage/ │ │ ├── App.java │ │ ├── config/ │ │ │ ├── AppInterceptor.java │ │ │ ├── AuthInterceptor.java │ │ │ ├── CorsConfig.java │ │ │ ├── MvcConfig.java │ │ │ ├── ShiroConfig.java │ │ │ ├── ShiroRealm.java │ │ │ ├── Swagger2Configuration.java │ │ │ ├── WebSocketConfig.java │ │ │ └── WebSocketServer.java │ │ ├── controller/ │ │ │ ├── AdminController.java │ │ │ ├── ErrorController.java │ │ │ ├── LiuStaticTest.java │ │ │ ├── LoginController.java │ │ │ ├── NotifyController.java │ │ │ ├── PayAliController.java │ │ │ ├── PayQuickController.java │ │ │ ├── PayWxController.java │ │ │ ├── QiniuController.java │ │ │ └── RoleController.java │ │ ├── mapper/ │ │ │ ├── AdminMapper.java │ │ │ ├── PayMapper.java │ │ │ ├── PermissionMapper.java │ │ │ └── RoleMapper.java │ │ └── service/ │ │ ├── AdminService.java │ │ ├── PayService.java │ │ ├── PermissionService.java │ │ ├── QiniuService.java │ │ ├── RoleService.java │ │ └── impl/ │ │ ├── AdminServiceImpl.java │ │ ├── PayServiceImpl.java │ │ ├── PermissionServiceImpl.java │ │ ├── QiniuServiceImpl.java │ │ └── RoleServiceImpl.java │ └── resources/ │ ├── application.properties │ ├── banner.txt │ ├── ehcache.xml │ ├── hacker/ │ │ └── channel/ │ │ └── manage/ │ │ └── mapper/ │ │ ├── AdminMapper.xml │ │ ├── PayMapper.xml │ │ └── RoleMapper.xml │ ├── logback.xml │ ├── static/ │ │ ├── css/ │ │ │ └── htshouye.css │ │ └── js/ │ │ └── base.js │ └── templates/ │ ├── dr.html │ ├── error/ │ │ ├── 010.html │ │ ├── 404.html │ │ └── 500.html │ └── qdst.html └── pom.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: README-EN.md ================================================ ### Jin Xia Nian Hua ``` Hello,Welcome to boot...SpringBoot The version number of the:v2.0.7.RELEASE Project producer:LuKe(walker) It's not easy to develop,I hope you can keep the copyright declaration for a while。Pencil lead💗💗💗 ```

hacker-walker

🇨🇳[简体中文](./README.md) | 🇺🇸English | [更新日志](https://github.com/java-aodeng/hope-plus/commits/master) [![author](https://img.shields.io/badge/author-walker-blue.svg)](https://wuxf.cn) [![JDK](https://img.shields.io/badge/JDK-1.8-orange.svg)](https://github.com/hacker-walker/hacker-walker) [![license](https://img.shields.io/badge/license-GPL--3.0-red.svg)](https://github.com/hacker-walker/hacker-walker/releases/tag/3.0) [![QQ群](https://img.shields.io/badge/chat-walkerQQ%E7%BE%A4-yellow.svg)](https://jq.qq.com/?_wv=1027&k=5mjexzD) star [![star](https://gitee.com/walker-cloud/hacker-walker/badge/star.svg?theme=dark)](https://gitee.com/walker-cloud/hacker-walker/stargazers) [![released version](https://img.shields.io/badge/release-3.0-green.svg)](https://github.com/hacker-walker/hacker-walker/releases) Wechat Public Number:Jin Xia Nian Hua ![file](https://images.gitee.com/uploads/images/2019/0610/161454_710bf233_2127888.png) ### brief introduction **Project address:https://gitee.com/walker-cloud/hacker-walker** ``` In 2019, I wish everyone who works hard a reward On the road of life, tears are on the left, laughter is on the right, and flowers of life are on both sides. Through the four seasons of life, we experienced the baptism of tears, witnessed the moment of laughter, appreciated the rise of the morning sun, gazed at the blooming of flower stamens. On the way of life, we harvest the inexhaustible gift of the God of life, and set out with her gifts and blessings. All the way, because of the harvest, we have never been cold, we have never been lonely. Netease Mailbox Communication: a18627830855@163.com | QQ Communication: 1722009230 | wx Communication: 18627830855 | QQ-Group Communication:741413607 ``` ### Account number ``` 1.Logon test: Visit URL: http://localhost:8888/success If you are not logged in, you will jump directly to the login page: http://localhost:8888/dr 2.Login account description: Login account shows that there is no server database, and SQL statement will be placed later Account Name:admin Password:abc123 Verification code (this is not done yet, it will be put on later) 3.After successful login, it will jump to the relevant success page 4.User Information Display (after login) URL: http://localhost:8888/qdst Backend API management:localhost:8888/swagger-ui.html ``` ### Modular Partitioning | Modular | Interpretation | | -- | -- | | hacker-db | DatabaseSql | | hacker-service-channel-manage | Background management module,Mapper,Service etc | | hacker-framework-common | Various forcing configurations for iso-frameworks | | hacker-framework-model | Database Core Entity Class | | hacker-govern-gateway(center) | gateway | | hacker-framework-util | Tool class | ### Instructions ``` 1.Use command pull substitution code: git clone https://gitee.com/walker-cloud/Hacker-walker.git 2.Create a database:jinnian(jin nian), character set:utf8;(Note: All you need to do is create a database) 3.IDEA is the best way to import this project 4.Warehouse Configuration open Settings option——》Choice Build Tools The following Maven tab——》Configure your own warehouse under Maven home direcdtory 5.Modify configuration A.open application.properties,Configure database connection datasource: url: Your database address username: Your database username password: Your database password 6.Running Project (Background Management Module) a.Direct operation hacker.channel.manage App in Directory b.Browser access:http://127.0.0.1:8888 ``` ### Thank - hacker-walker The birth of the project is inseparable from the following (take open source, use open source): - Spring Boot:Core Framework - Apache Shiro:Permission Framework - Thymeleaf:template engine - MyBatis-plus:Be used for Java Of MyBatis SQL Mapper frame - alibaba/druid:Database connection pool - alibaba/fastjson:Fast JSON parser/generator for Java - Lombok:Make the code more concise - swagger:Swagger(Swagger)The most popular API expression tool in the world。 - Html5:Front-end page ### Framework demonstration ``` At present, it is still in perfect development, and will be put here to show the effect, please laugh! ``` ``` Login interface ``` ![Login interface](https://images.gitee.com/uploads/images/2019/0610/180431_93d56664_2127888.png) ``` Background management interface ``` ![Background management interface](https://images.gitee.com/uploads/images/2019/0613/111333_0edb6d4e_2127888.png) ![1](https://i.loli.net/2019/07/03/5d1c94263e68624395.png) ![2](https://i.loli.net/2019/07/03/5d1c943d8714f56661.png) ![3](https://i.loli.net/2019/07/03/5d1c9443c143583430.png) ### Friendship Links - Author: Low-key Panda Blog:http://ilovey.live (Reading ten thousand books, traveling ten thousand miles, making a lot of money)Wechat Public Number: Low-key Panda - Author:walker Blog:https://wuxf.cn (Unknown Partners in Australia) Wechat Public Number:jin xia nian hua ### Last http://doc.zengrong.net/smart-questions/cn.html In order to prevent the world from being destroyed, in order to love and justice, it is recommended to look at the wisdom of asking questions. ## You thumb up encouragement is the motivation for us to move forward ![cartridge](https://i.loli.net/2019/07/13/5d29c699493f847597.png) ================================================ FILE: README.md ================================================ ### 堇夏年华 ``` Hello,Welcome to boot...SpringBoot的版本号:v2.0.7.RELEASE 项目制作人:LuKe(walker) 开发不易,希望您可以保留一下版权声明。 笔芯💗💗💗 ```

hacker-walker

🇨🇳简体中文 | 🇺🇸[English](./README-EN.md) | [更新日志](https://gitee.com/walker-cloud/hacker-walker) [![author](https://img.shields.io/badge/author-walker-blue.svg)](https://wuxf.cn) [![JDK](https://img.shields.io/badge/JDK-1.8-orange.svg)](https://github.com/hacker-walker/hacker-walker) [![license](https://img.shields.io/badge/license-GPL--3.0-red.svg)](https://github.com/hacker-walker/hacker-walker/releases/tag/3.0) [![QQ群](https://img.shields.io/badge/chat-walkerQQ%E7%BE%A4-yellow.svg)](https://jq.qq.com/?_wv=1027&k=5mjexzD) star [![star](https://gitee.com/walker-cloud/hacker-walker/badge/star.svg?theme=dark)](https://gitee.com/walker-cloud/hacker-walker/stargazers) [![发行版本](https://img.shields.io/badge/release-3.0-green.svg)](https://github.com/hacker-walker/hacker-walker/releases) 微信公众号:堇夏年华 ![file](https://images.gitee.com/uploads/images/2019/0610/161454_710bf233_2127888.png) ### 简介 **项目地址:https://gitee.com/walker-cloud/hacker-walker** 2019年,祝每一个努力的人都有所收获 人生路上,泪水在左,欢笑在右,生命的鲜花铺满两旁。 走过生命的四季,我们经历了泪水的洗礼,见证了欢笑的时刻,欣赏着朝阳的升起,凝视着花蕊的绽放。 人生途中,我们收获着生命之神不尽的惠赠,满揣着她的礼物与祝福启程。一路走来,因为收获,我们不曾寒冷,我们从未孤独。 网易邮箱 交流: a18627830855@163.com | QQ 交流: 1722009230 | wx 交流: 18627830855 | QQ群 交流:741413607 ### 账号 ``` 1.登录测试: 访问URL: http://localhost:8888/success 如果未登录会直接跳到登录页: http://localhost:8888/dr 2.登录账号说明: 此处没有放服务器数据库,后面会放sql语句 账户名:admin 密码:abc123 验证码(这个还没做,后面会放上去) 3.登录成功后会跳转到相关的成功页面 4.用户信息显示(登陆后) URL: http://localhost:8888/qdst 后端API管理:localhost:8888/swagger-ui.html ``` ### 模块划分 | 模块 | 释义 | | -- | -- | | hacker-db | 数据库sql | | hacker-service-channel-manage | 后台管理模块,Mapper,Service等 | | hacker-framework-common | 框架的各种牛逼配置 | | hacker-framework-model | 数据库核心实体类 | | hacker-govern-gateway(center) | 网关 | | hacker-framework-util | 工具类 | ### 使用说明 ``` 1.使用命令拉取代码: git clone https://gitee.com/walker-cloud/Hacker-walker.git 2.创建数据库:jinnian(堇年), 字符集:utf8;(注意:只需要你创建数据库即可) 3.最好使用IDEA导入该项目 4.仓库配置 打开Settings选项——》选择Build Tools下面的Maven选项卡——》在Maven home direcdtory下配置自己的仓库 5.修改配置 A.打开application.properties,配置数据库连接 datasource: url: 你的数据库地址 username: 你的数据库用户名 password: 你的数据库密码 6.运行项目(后台管理模块) a.直接运行hacker.channel.manage目录下的App b.浏览器访问:http://127.0.0.1:8888 ``` ### 感谢 - hacker-walker的诞生离不开下面这些项目(取之开源,用之开源): - Spring Boot:核心框架 - Apache Shiro:权限框架 - Thymeleaf:模板引擎 - MyBatis-plus:用于Java的MyBatis SQL Mapper框架 - alibaba/druid:数据库连接池 - alibaba/fastjson:用于Java的快速JSON解析器/生成器 - Lombok:让代码更简洁 - swagger:Swagger(丝袜哥)是世界上最流行的 API 表达工具。 - Html5:前端页面 ### 框架演示 ``` 目前还在完善开发,后面会放到这里展示效果,请笑纳! ``` ``` 登陆界面 ``` ![登陆界面](https://images.gitee.com/uploads/images/2019/0610/180431_93d56664_2127888.png) ``` 后台管理界面 ``` ![后台界面](https://images.gitee.com/uploads/images/2019/0613/111333_0edb6d4e_2127888.png) ![1](https://i.loli.net/2019/07/03/5d1c94263e68624395.png) ![2](https://i.loli.net/2019/07/03/5d1c943d8714f56661.png) ![3](https://i.loli.net/2019/07/03/5d1c9443c143583430.png) ### 友情链接 - 作者:低调小熊猫 博客:http://ilovey.live (读万卷书,行万里路,赚很多钱)微信公众号:低调小熊猫 - 作者:walker 博客:https://wuxf.cn (澳大利亚不知名企业合伙人) 微信公众号:堇夏年华 ### Last 为了防止世界被毁灭,为了爱情和正义,建议大家看看提出问题的智慧。 http://doc.zengrong.net/smart-questions/cn.html In order to prevent the world from being destroyed, in order to love and justice, it is recommended to look at the wisdom of asking questions. ## 你的点赞鼓励,是我前进的动力 ![笔芯](https://i.loli.net/2019/07/13/5d29c699493f847597.png) ================================================ FILE: hacker-db/walker.sql ================================================ /* SQLyog Ultimate v8.32 MySQL - 8.0.15 : Database - jinnian ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/`jinnian` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `jinnian`; /*Table structure for table `tb_admin` */ DROP TABLE IF EXISTS `tb_admin`; CREATE TABLE `tb_admin` ( `id` int(32) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `username` varchar(64) NOT NULL, `password` varchar(122) NOT NULL, `phone` varchar(64) DEFAULT NULL, `status` int(1) NOT NULL DEFAULT '1' COMMENT '状态 成功:1 失败:0', `is_readonly` int(2) NOT NULL DEFAULT '1' COMMENT '是否只允许读操作 0:否 1:是', `last_login_ip` varchar(64) NOT NULL DEFAULT '' COMMENT '登陆IP', `last_login_token` varchar(64) DEFAULT NULL COMMENT '登陆的token', `login_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '登陆时间', `created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*Data for the table `tb_admin` */ insert into `tb_admin`(`id`,`username`,`password`,`phone`,`status`,`is_readonly`,`last_login_ip`,`last_login_token`,`login_at`,`created_at`,`updated_at`) values (1,'admin','9feb61735eae35a19c709cdcda699f80e087bc3f0e1049768fbb457a0d38702b','admin',1,1,'172.20.10.2','d55f2b281e2d4fd38835ceafd4a39566','2019-08-02 15:38:37','2019-05-26 10:14:15','2019-05-26 10:14:15'); /*Table structure for table `tb_admin_role` */ DROP TABLE IF EXISTS `tb_admin_role`; CREATE TABLE `tb_admin_role` ( `role_id` int(10) unsigned NOT NULL, `admin_id` int(10) unsigned NOT NULL, PRIMARY KEY (`role_id`,`admin_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `tb_admin_role` */ insert into `tb_admin_role`(`role_id`,`admin_id`) values (1,1),(1,2),(2,1); /*Table structure for table `tb_pay` */ DROP TABLE IF EXISTS `tb_pay`; CREATE TABLE `tb_pay` ( `tradeNo` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户订单号', `userId` int(64) NOT NULL, `adminId` int(32) NOT NULL, `payTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间', `payStatus` int(2) NOT NULL DEFAULT '1' COMMENT '支付状态', `payType` int(2) NOT NULL DEFAULT '1' COMMENT '支付方式', `gmtCreate` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `merchantOutOrderNo` varchar(64) DEFAULT NULL COMMENT '商家支付订单号', PRIMARY KEY (`tradeNo`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*Data for the table `tb_pay` */ insert into `tb_pay`(`tradeNo`,`userId`,`adminId`,`payTime`,`payStatus`,`payType`,`gmtCreate`,`merchantOutOrderNo`) values (1,1,1,'2019-08-02 16:02:15',1,1,'2019-08-02 16:02:15','121'); /*Table structure for table `tb_permission` */ DROP TABLE IF EXISTS `tb_permission`; CREATE TABLE `tb_permission` ( `id` int(32) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) DEFAULT NULL COMMENT '权限对应的唯一ID', `index_name` varchar(64) NOT NULL DEFAULT '' COMMENT '前端路由', `parent_id` int(32) NOT NULL DEFAULT '0' COMMENT '父类id 根节点为0', `display_name` varchar(64) NOT NULL COMMENT '权限展示名', `is_show` int(2) NOT NULL DEFAULT '1' COMMENT '是否展示在菜单栏', `status` int(2) NOT NULL DEFAULT '1' COMMENT '状态 禁用:0 未禁用:1', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; /*Data for the table `tb_permission` */ insert into `tb_permission`(`id`,`name`,`index_name`,`parent_id`,`display_name`,`is_show`,`status`,`created_at`,`updated_at`) values (1,'sytem.admin.list','/system/admin/list',0,'管理员列表',1,1,'2019-05-24 16:21:28','2019-05-24 16:21:28'); /*Table structure for table `tb_role` */ DROP TABLE IF EXISTS `tb_role`; CREATE TABLE `tb_role` ( `id` int(32) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `display_name` varchar(64) NOT NULL COMMENT '角色展示名', `level` int(2) NOT NULL DEFAULT '0' COMMENT '角色等级', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `tb_role` */ insert into `tb_role`(`id`,`display_name`,`level`,`created_at`,`updated_at`) values (1,'超级管理员',1,'2019-05-26 10:14:15','2019-05-26 10:14:15'),(2,'管理员',0,'2019-06-25 12:42:12','2019-06-26 10:12:18'); /*Table structure for table `tb_role_permission` */ DROP TABLE IF EXISTS `tb_role_permission`; CREATE TABLE `tb_role_permission` ( `permission_id` int(10) unsigned NOT NULL, `role_id` int(10) unsigned NOT NULL, PRIMARY KEY (`permission_id`,`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*Data for the table `tb_role_permission` */ insert into `tb_role_permission`(`permission_id`,`role_id`) values (1,1),(1,2),(2,1); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; ================================================ FILE: hacker-framework-common/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: hacker-framework-common/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-framework-common Hacker.walker Hacker-framework-util 1.0-SNAPSHOT compile Hacker.walker Hacker-framework-model 1.0-SNAPSHOT compile ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/annotation/Constants.java ================================================ package hacker.framework.common.annotation; /** * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:37 */ public class Constants { public static final Short STATUS_ENABLE = 1; public static final Short STATUS_DISABLE = 0; public static final Integer PRIV_SUPER = 999; public static final String AUTH_USER = "AUTH_USER"; public static final Integer PAGE_DEF_START = 1; public static final Integer PAGE_DEF_SIZE = 10; public static final String CUSTOMER_ROLE_NAME = "超级管理员"; public static final String CUSTOMER_ROLE_DESC = "管理所有权限,该权限组无法删除!"; public static final Integer CUSTOMER_DEF_STATUS = 0; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/annotation/DistributedLock.java ================================================ package hacker.framework.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:37 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DistributedLock { /** * 当前锁的:自动过期时间 (单位:秒)默认值:1s * * @return */ long value() default 1; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/annotation/Limiter.java ================================================ package hacker.framework.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 用户级别限流 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:37 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Limiter { /** * 限流次数,配合expire使用 默认:1次/s * * @return */ int value() default 1; /** * 限流时间跨度 (单位:秒) 默认:1s * * @return */ int expire() default 1; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/annotation/ResponseCode.java ================================================ package hacker.framework.common.annotation; /** * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:34 */ public enum ResponseCode { SUCCESS("0", "OK"), ERROR("1", "数据异常!"); private String status; private String message; ResponseCode(String status, String message) { this.status = status; this.message = message; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/DistributedLockAspect.java ================================================ package hacker.framework.common.aspect; import hacker.framework.common.annotation.DistributedLock; import org.apache.commons.lang3.ArrayUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.Serializable; import java.lang.reflect.Method; import java.util.Random; /** * 分布式🔐 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:58 */ @Aspect @Component public class DistributedLockAspect { private static final Logger logger = LoggerFactory.getLogger(DistributedLockAspect.class); /** * 🔐KEY前缀 */ private static final String LOCK_KEY_PREFIX = "lock:key:"; @Autowired private LockUtils lockUtils; //当前锁的:自动过期时间 @Around(value = "@annotation(hacker.framework.common.annotation.DistributedLock)") public Object around(ProceedingJoinPoint point) throws Throwable { MethodSignature methodSignature = (MethodSignature) point.getSignature(); Method method = methodSignature.getMethod(); DistributedLock annotation = method.getAnnotation(DistributedLock.class); // timeOut long timeOut = annotation.value(); // key // sessionId Serializable sessionId = null; // TODO SessionUtils.getSessionId(); // methodName String fullMethodName = getFullMethodName(method); // hashCode int fullMethodNameHashCode = fullMethodName.hashCode(); // prefix + methodName + sessionId + hashCode String key = LOCK_KEY_PREFIX + method.getName() + ":" + sessionId + ":" + fullMethodNameHashCode; // randomVal 生成一个随机数:作为当前🔐的val long randomNum = new Random().nextInt(1000000000); String val = System.currentTimeMillis() + String.valueOf(randomNum); try { // 获取锁 boolean getLock = lockUtils.lock(key, val, timeOut); logger.debug(getLock ? "获取锁成功!KEY:" + key + " , VAL:" + val : "获取锁失败!KEY:" + key + " , VAL:" + val); // 获m取到锁 if (getLock) { // 执行原方法 Object result = point.proceed(); return result; } } catch (Exception ex) { throw ex; } finally { // 释放锁 boolean releaseLock = lockUtils.releaseLock(key, val); logger.debug(releaseLock ? "释放锁成功!KEY:" + key + " , VAL:" + val : "释放锁失败!KEY:" + key + " , VAL:" + val); } return null; } /** * method的全方法名 * * @param method * @return */ private static String getFullMethodName(Method method) { String fullMethodName = ""; String clazzName = method.getDeclaringClass().getName(); String methodName = method.getName(); fullMethodName += clazzName; fullMethodName += methodName; Class[] parameterTypes = method.getParameterTypes(); if (ArrayUtils.isNotEmpty(parameterTypes)) { for (int i = 0; i < parameterTypes.length; i++) { fullMethodName += parameterTypes[i].getName(); } } return fullMethodName; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/GlobalExceptionHandler.java ================================================ package hacker.framework.common.aspect; import com.alibaba.fastjson.JSONPathException; import hacker.framework.common.exception.JxnhException; import hacker.framework.common.request.ResultBean; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import javax.websocket.DecodeException; /** * 统一异常处理 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:12 */ @Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseStatus(value = HttpStatus.OK) @ResponseBody public ResultBean exceptionHandler(Throwable e) { return doGlobalExceptionHandler(e); } /** * 执行异常处理 * * @param e * @return */ public static ResultBean doGlobalExceptionHandler(Throwable e) { log.error(e.getMessage(), e); if (e instanceof JxnhException) { Integer code = ((JxnhException) e).getCode(); String msg = ((JxnhException) e).getMsg(); if (null == code) { return ResultBean.ofError(msg); } else { return ResultBean.ofError(code, msg); } } else if (e instanceof MissingServletRequestParameterException) { String parameterName = ((MissingServletRequestParameterException) e).getParameterName(); return ResultBean.ofError(parameterName + "不能为空"); } else if (e instanceof MethodArgumentNotValidException) { return ResultBean.ofError("表单必录数据填写不完整"); } else if (e instanceof DecodeException) { return ResultBean.ofError(e.getMessage()); } else if (e instanceof IllegalArgumentException) { return ResultBean.ofError(e.getMessage()); } else if (e instanceof NullPointerException) { return ResultBean.ofError(e.getMessage()); } else if (e instanceof NumberFormatException) { return ResultBean.ofError("参数类型转换异常"); }else if (e instanceof JSONPathException) { return ResultBean.ofError("类型转换异常"); } else if (e instanceof BadSqlGrammarException) { return ResultBean.ofError("出错啦,请稍后再试!"); } else if (e instanceof RuntimeException) { return ResultBean.ofError("出错啦,请稍后再试!"); } else if (e instanceof Exception) { return ResultBean.ofError("出错啦,请稍后再试!"); } else { String errorMsg = e.toString() == null ? e.getMessage() : e.toString(); return ResultBean.ofError(StringUtils.isBlank(errorMsg) ? "未知错误" : errorMsg); } } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/GlobalLogHandler.java ================================================ package hacker.framework.common.aspect; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * 统一日志处理 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:58 */ @Aspect @Component @Slf4j public class GlobalLogHandler { //加载包路径 @Around(value = "execution(* hacker.*.manage.controller..*.*(..))") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long startTime = System.currentTimeMillis(); // 日志记录 ------》有的方法里会出项BUG----->这里执行一次,方法里还会执行一次,第一次有值,第二次报空了 // log(pjp); // exec 反射 Object result = pjp.proceed(); // 统计时间 long totalTime = System.currentTimeMillis() - startTime; log.info("totalTime : {}s", new Double(totalTime) / 1000); return result; } /** * 记录日志 * @param pjp */ private void log(ProceedingJoinPoint pjp) { Object[] args = pjp.getArgs(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); List argList = Arrays.stream(args) .filter(arg -> !(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)) .collect(Collectors.toList()); if (CollectionUtils.isEmpty(argList)) { log.info(Arrays.asList(request.getServletPath(), getIpAddress(request)).stream().collect(Collectors.joining(" "))); } else { log.info(Arrays.asList(request.getServletPath(), getIpAddress(request), JSON.toJSONString(argList)).stream().collect(Collectors.joining(" "))); } } /** * 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 * * @param request * @return * @throws IOException */ public static String getIpAddress(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ipIsBlank(ip)) { ip = request.getHeader("Proxy-Client-IP"); if (ipIsBlank(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); if (ipIsBlank(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); if (ipIsBlank(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); if (ipIsBlank(ip)) { ip = request.getRemoteAddr(); } } } } } else if (ip.length() > 15) { // 经过多层代理后会有多个代理,取第一个ip地址就可以了 String[] ips = ip.split("\\,"); for (int index = 0; index < ips.length; index++) { String strIp = ips[index]; if (!("unknown".equalsIgnoreCase(strIp))) { ip = strIp; break; } } } return ip; } private static boolean ipIsBlank(String ip) { boolean ipIsBank = StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip); return ipIsBank; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/GlobalVariable.java ================================================ package hacker.framework.common.aspect; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 全局变量相关配置信息 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Component @Data public class GlobalVariable { /** * 消息校验token */ @Value("${token}") private String token; /** * secret */ @Value("${secret}") private String secret; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/LimiterAspect.java ================================================ package hacker.framework.common.aspect; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import hacker.framework.common.annotation.Limiter; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.scripting.support.ResourceScriptSource; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; @Aspect @Component public class LimiterAspect { /** * LIMIT-KEY 前缀 */ private static final String LIMIT_KEY_PREFIX = "limit:key:"; @Resource private StringRedisTemplate stringRedisTemplate; /** * @param point */ @Around("@annotation(hacker.framework.common.annotation.Limiter)") public Object around(ProceedingJoinPoint point) throws Throwable { // requestPath HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); String route = request.getServletPath(); MethodSignature methodSignature = (MethodSignature) point.getSignature(); Method method = methodSignature.getMethod(); Limiter limiter = method.getAnnotation(Limiter.class); int limit = limiter.value(); int expire = limiter.expire(); // 唯一:登录用户SessionId + 参数 String sessionId = null; // todo SecurityUtils.getSubject().getSession().getId().toString(); String user = sessionId + ":" + JSON.toJSONString(point.getArgs()); String userHash = String.valueOf(user.hashCode()); //判断登陆次数 if (!doLimiter(route, userHash, limit, expire)) { throw new RuntimeException("操作太过频繁,请勿重复点击!"); } return point.proceed(); } /** * 限流Redis-lua实现 * * @param route * @param userHash * @param limit * @param expire * @return */ private boolean doLimiter(String route, String userHash, Integer limit, int expire) { final String key = LIMIT_KEY_PREFIX + route + ":" + userHash; DefaultRedisScript redisScript = new DefaultRedisScript<>(); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/rateLimit.lua"))); redisScript.setResultType(Long.class); Object result = stringRedisTemplate.execute(redisScript, Lists.newArrayList(key), String.valueOf(limit), String.valueOf(expire)); if ((long) result == 1) { return true; } return false; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/LockUtils.java ================================================ package hacker.framework.common.aspect; import com.google.common.collect.Lists; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.scripting.support.ResourceScriptSource; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:37 */ @Component public class LockUtils { @Resource private StringRedisTemplate stringRedisTemplate; /** * 获取🔐 * @param key * @param randomVal * @param timeOut 单位:秒 */ public boolean lock(String key, String randomVal, Long timeOut) { DefaultRedisScript redisScript = new DefaultRedisScript<>(); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/distributedLock.lua"))); redisScript.setResultType(Long.class); Object result = stringRedisTemplate.execute(redisScript, Lists.newArrayList(key), randomVal, String.valueOf(timeOut)); if ((long) result == 1) { return true; } return false; } /** * 释放🔐 * * @param key * @param val * @return */ public boolean releaseLock(String key, String val) { Class clazz = Long.class; DefaultRedisScript redisScript = new DefaultRedisScript<>(); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/releaseLock.lua"))); redisScript.setResultType(clazz); Object result = stringRedisTemplate.execute(redisScript, Lists.newArrayList(key), val); if ((long) result == 1) { return true; } return false; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/aspect/SqlTimeInterceptor.java ================================================ package hacker.framework.common.aspect; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.type.TypeHandlerRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Properties; /** * Sql逆向工程 * SqlTimeInterceptor */ @Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) public class SqlTimeInterceptor implements Interceptor { @SuppressWarnings("unused") private Properties properties; private static Logger log = LoggerFactory.getLogger(SqlTimeInterceptor.class); @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } String sqlId = mappedStatement.getId(); BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); Object returnValue = null; long start = System.currentTimeMillis(); returnValue = invocation.proceed(); long end = System.currentTimeMillis(); long time = (end - start); // 大于time秒,则打印SQL -> 记录慢SQL用 if (time > 2000) { String sql = getSql(configuration, boundSql, sqlId, time); log.info(sql); } return returnValue; } public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId, long time) { String sql = showSql(configuration, boundSql); StringBuilder str = new StringBuilder(100); str.append(sqlId); str.append(":"); str.append(sql); str.append(": 执行耗时"); str.append(time); str.append("ms"); return str.toString(); } private static String getParameterValue(Object obj) { String value = null; if (obj instanceof String) { value = "'" + obj.toString() + "'"; } else if (obj instanceof Date) { DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA); value = "'" + formatter.format(new Date()) + "'"; } else { if (obj != null) { value = obj.toString(); } else { value = ""; } } return value; } public static String showSql(Configuration configuration, BoundSql boundSql) { Object parameterObject = boundSql.getParameterObject(); List parameterMappings = boundSql.getParameterMappings(); String sql = boundSql.getSql().replaceAll("[\\s]+", " "); if (parameterMappings.size() > 0 && parameterObject != null) { TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { sql = sql.replaceFirst("\\?", getParameterValue(parameterObject)); } else { MetaObject metaObject = configuration.newMetaObject(parameterObject); for (ParameterMapping parameterMapping : parameterMappings) { String propertyName = parameterMapping.getProperty(); if (metaObject.hasGetter(propertyName)) { Object obj = metaObject.getValue(propertyName); sql = sql.replaceFirst("\\?", getParameterValue(obj)); } else if (boundSql.hasAdditionalParameter(propertyName)) { Object obj = boundSql.getAdditionalParameter(propertyName); sql = sql.replaceFirst("\\?", getParameterValue(obj)); } } } } return sql; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties0) { this.properties = properties0; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/consts/CommonConst.java ================================================ /** * MIT License * Copyright (c) 2018 yadong.zhang * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package hacker.framework.common.consts; /** * walker公用常量类 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:25 */ public class CommonConst { /*** *uuid盐,hope专用 */ public static final String ZYD_SECURITY_KEY = "929123f8f17944e8b0a531045453e1f1"; /*** *程序错误状态码 */ public static final int DEFAULT_ERROR_CODE = 500; /*** * 程序成功状态码 */ public static final int DEFAULT_SUCCESS_CODE = 200; /*** * session key */ public static final String USER_SESSION_KEY = "user_session_key"; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/enums/BaseExceptionEnum.java ================================================ package hacker.framework.common.enums; /** * code * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:45 */ public enum BaseExceptionEnum { NOT_LOGIN(10001, "操作会话已失效,请重新登录!"), NOT_PERMISSION(10002, "您无该权限"), //目前就用到成功和失败 EC00000200(200, "success"), EC00000500(500, "系统异常"), EC00000404(404, "该接口不存在"), EC00000000(100000, "无法加载切点对象"), EC00000001(100001, "链接点参数为空"), EC00000002(100002, "类或对象访问权限限制"), EC00000003(100003, "I/O异常"), EC00000004(100004, "obj to json 失败"), EC00000005(100005, "不支持字符编码"), EC00000006(100006, "没有此算法"), EC00000007(100007, "缺少算法配置参数"), EC00000008(100008, "读取私钥失败"), EC00000009(100009, "加载私钥失败"), EC00000010(100010, "密文数据已损坏"), EC00000011(100011, "私钥长度非法"), EC00000012(100012, "私钥非法"), EC00000013(100013, "读取公钥失败"), EC00000014(100014, "加载公钥失败"), EC00000015(100015, "明文数据已损坏"), EC00000016(100016, "公钥非法"), EC00000017(100017, "公钥长度非法"), EC00000018(100018, "签名失败"), EC00000019(100019, "验签失败"), EL00000000(200000, "数据报为空"), EL00000001(200001, "转换数据报返回为空"), EL00000002(200002, "目标名称为空"), EL00000003(200003, "调用API失败"), EL00000004(200004, "参数名不能为空"), EL00000005(200005, "参数不能为空"), EA00000001(200001, "签名认证失败"); private int code; private String message; BaseExceptionEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/exception/AppException.java ================================================ package hacker.framework.common.exception; /** * @description 自定义异常类 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:34 */ public class AppException extends Exception { public AppException() { super(); } public AppException(String message) { super(message); } public AppException(String message, Throwable cause) { super(message, cause); } public AppException(Throwable cause) { super(cause); } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/exception/JxnhException.java ================================================ package hacker.framework.common.exception; import hacker.framework.common.enums.BaseExceptionEnum; /** * 自定义堇夏年华异常 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 14:58 */ public class JxnhException extends RuntimeException { private int code; private String msg; public JxnhException() { super(); } public JxnhException(Throwable cause) { super(cause); } public JxnhException(String msg) { super(msg); this.msg = msg; } public JxnhException(int code, String msg) { super(msg); this.code = code; this.msg = msg; } public JxnhException(BaseExceptionEnum exEnum) { this.code = exEnum.getCode(); this.msg = exEnum.getMessage(); } public int getCode() { return code; } public String getMsg() { return msg; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/object/BaseConditionVo.java ================================================ package hacker.framework.common.object; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; /** * 基础转换 其实分页工具会自动计算,只需要num和size即可 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:15 */ @Data @EqualsAndHashCode(callSuper = false) public class BaseConditionVo { public final static int DEFAULT_PAGE_SIZE = 10; private int pageNum = 1; private int pageSize = 0; private int pageStart = 0; private String orderField; private String orderDirection; private String keywords; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date startDate; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date endDate; public int getPageSize() { return pageSize > 0 ? pageSize : DEFAULT_PAGE_SIZE; } public int getPageStart() { return pageNum > 0 ? (pageNum - 1) * pageSize : 0; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/object/PageResultVo.java ================================================ package hacker.framework.common.object; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; /** * 用于bootstrap table返回json格式 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:15 */ @Data @EqualsAndHashCode(callSuper = false) public class PageResultVo { private Long total; private List rows; public PageResultVo(Long total, List rows) { this.total = total; this.rows = rows; } public PageResultVo() { } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/object/ResponseVo.java ================================================ package hacker.framework.common.object; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import hacker.framework.common.enums.BaseExceptionEnum; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.Collection; import java.util.List; /** * 使用阿里的fastjson * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:15 */ @Data @EqualsAndHashCode(callSuper = false) public class ResponseVo { private Integer status; private String message; private T data; public ResponseVo(Integer status, String message, T data) { this.status = status; this.message = message; this.data = data; } public ResponseVo(BaseExceptionEnum status, T data) { this(status.getCode(), status.getMessage(), data); } public String toJson() { T t = this.getData(); if (t instanceof List || t instanceof Collection) { return JSONObject.toJSONString(this, SerializerFeature.WriteNullListAsEmpty); } else { return JSONObject.toJSONString(this, SerializerFeature.WriteMapNullValue); } } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/object/ResultUtil.java ================================================ package hacker.framework.common.object; import hacker.framework.common.consts.CommonConst; import hacker.framework.common.enums.BaseExceptionEnum; import org.springframework.web.servlet.ModelAndView; import java.util.Map; /** * 接口返回工具 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:15 */ public class ResultUtil { /** * ModelAndView **/ public static ModelAndView view(String view) { return new ModelAndView(view); } public static ModelAndView view(String view, Map model) { return new ModelAndView(view, model); } public static ModelAndView redirect(String view) { return new ModelAndView("redirect:" + view); } /** * vo **/ public static ResponseVo vo(int code, String message, Object data) { return new ResponseVo<>(code, message, data); } /** * error **/ public static ResponseVo error(int code, String message) { return vo(code, message, null); } public static ResponseVo error(BaseExceptionEnum statusEnum) { return vo(statusEnum.getCode(), statusEnum.getMessage(), null); } public static ResponseVo error(String message) { return vo(CommonConst.DEFAULT_ERROR_CODE, message, null); } /** * success **/ public static ResponseVo success(String message, Object data) { return vo(CommonConst.DEFAULT_SUCCESS_CODE, message, data); } public static ResponseVo success(String message) { return success(message, null); } public static ResponseVo success(BaseExceptionEnum statusEnum) { return vo(statusEnum.getCode(), statusEnum.getMessage(), null); } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/request/BaseCode.java ================================================ package hacker.framework.common.request; import lombok.Getter; /** * 基础返回码 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 14:39 */ @Getter public enum BaseCode { /** * 成功 */ SUCCESS("200"), /** * 异常失败 */ FAIL("500"); BaseCode(String code) { this.code = code; } private String code; public static void main(String[] args) { System.out.println(BaseCode.SUCCESS.getCode()); } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/request/BaseResult.java ================================================ package hacker.framework.common.request; import lombok.Getter; import lombok.Setter; /** * @description 基础支持类 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 14:36 */ @Getter @Setter public class BaseResult { String code; String msg; Object data; public BaseResult() { } public BaseResult(String code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/request/ResultBean.java ================================================ package hacker.framework.common.request; import com.fasterxml.jackson.annotation.JsonInclude; import hacker.framework.common.enums.BaseExceptionEnum; import java.io.Serializable; import java.util.Collection; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 12:34 */ public class ResultBean implements Serializable { private static final long serialVersionUID = -2361820086956983473L; /** * 数据明细 */ private T data; private T data1; private Boolean success; private int code; private String msg; public static long getSerialVersionUID() { return serialVersionUID; } public T getData() { return data; } public void setData(T data) { this.data = data; } public T getData1() { return data1; } public void setData1(T data1) { this.data1 = data1; } public Boolean getSuccess() { return success; } public void setSuccess(Boolean success) { this.success = success; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Integer getTotalNum() { return totalNum; } public void setTotalNum(Integer totalNum) { this.totalNum = totalNum; } public Integer getPageIndex() { return pageIndex; } public void setPageIndex(Integer pageIndex) { this.pageIndex = pageIndex; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Integer getTotalPage() { return totalPage; } public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; } /** * 为null时,不参与序列化 */ @JsonInclude(JsonInclude.Include.NON_NULL) private Integer totalNum; @JsonInclude(JsonInclude.Include.NON_NULL) private Integer pageIndex; @JsonInclude(JsonInclude.Include.NON_NULL) private Integer pageSize; @JsonInclude(JsonInclude.Include.NON_NULL) private Integer totalPage; public static ResultBean ofSuccess() { return of(null, true, BaseExceptionEnum.EC00000200); } public static ResultBean ofSuccess(T data) { return of(data, true, BaseExceptionEnum.EC00000200); } public static ResultBean ofSuccess(T data, String msg) { return of(data, true, BaseExceptionEnum.EC00000200.getCode(), msg); } public static ResultBean ofSuccess(T data, T date1, String msg) { return of(data, date1, true, BaseExceptionEnum.EC00000200.getCode(), msg); } public static ResultBean ofSuccess(T data, BaseExceptionEnum baseExceptionEnum) { return of(data, true, baseExceptionEnum); } public static ResultBean ofSuccess(T data, Integer totalNum, Integer pageIndex, Integer pageSize) { return of(data, true, BaseExceptionEnum.EC00000200, totalNum, pageIndex, pageSize); } public static ResultBean ofSuccess(T data, Integer totalNum, Integer pageIndex, Integer pageSize, String msg) { return of(data, true, BaseExceptionEnum.EC00000200, totalNum, pageIndex, pageSize, msg); } public static ResultBean of(T data, boolean success, BaseExceptionEnum baseExceptionEnum, Integer totalNum, Integer pageIndex, Integer pageSize) { return of(data, success, baseExceptionEnum, totalNum, pageIndex, pageSize, null); } public static ResultBean of(T data, boolean success, BaseExceptionEnum baseExceptionEnum) { if (null != baseExceptionEnum) { return of(data, success, baseExceptionEnum.getCode(), baseExceptionEnum.getMessage()); } else { return of(data, success, null, null); } } public static ResultBean of(T data, boolean success, Integer code, String msg) { ResultBean resultBean = new ResultBean<>(); resultBean.setData(data); resultBean.setSuccess(success); resultBean.setCode(code); resultBean.setMsg(msg); if (data instanceof Collection) { resultBean.setTotalNum(((Collection) data).size()); } return resultBean; } public static ResultBean of(T data, T data1, boolean success, Integer code, String msg) { ResultBean resultBean = new ResultBean<>(); resultBean.setData(data); resultBean.setData1(data1); resultBean.setSuccess(success); resultBean.setCode(code); resultBean.setMsg(msg); if (data instanceof Collection) { resultBean.setTotalNum(((Collection) data).size()); } return resultBean; } public static ResultBean of(T data, boolean success, BaseExceptionEnum baseExceptionEnum, Integer totalNum, Integer pageIndex, Integer pageSize, String msg) { ResultBean resultBean = new ResultBean(); resultBean.setData(data); resultBean.setSuccess(success); if (null != baseExceptionEnum) { resultBean.setCode(baseExceptionEnum.getCode()); resultBean.setMsg(baseExceptionEnum.getMessage()); } if (data instanceof Collection && null == totalNum) { resultBean.setTotalNum(((Collection) data).size()); } resultBean.setTotalNum(totalNum); resultBean.setPageIndex(pageIndex); resultBean.setPageSize(pageSize); resultBean.setTotalPage((null == pageSize || pageSize == 0) ? null : (totalNum % pageSize == 0 ? totalNum / pageSize : (totalNum / pageSize + 1))); resultBean.setMsg(msg); return resultBean; } public static ResultBean ofError(BaseExceptionEnum baseExceptionEnum) { return ofError(baseExceptionEnum.getCode(), baseExceptionEnum.getMessage()); } public static ResultBean ofError(String msg) { return ofError(BaseExceptionEnum.EC00000500.getCode(), msg); } public static ResultBean ofError(int code, String msg) { ResultBean resultBean = new ResultBean(); resultBean.setSuccess(false); resultBean.setCode(code); resultBean.setMsg(msg); resultBean.setData(null); return resultBean; } } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/request/ResultInfo.java ================================================ package hacker.framework.common.request; import javafx.scene.control.Pagination; import lombok.Data; import java.io.Serializable; /** * 返回结果封装 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Data public class ResultInfo implements Serializable { private String status; private String message; private Object data; private Pagination pagination; //标记页码数 private String code; } ================================================ FILE: hacker-framework-common/src/main/java/hacker/framework/common/request/ResultInfoUtil.java ================================================ package hacker.framework.common.request; import hacker.framework.common.annotation.ResponseCode; import hacker.framework.common.request.ResultInfo; /** * 返回结果封装结果 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:54 */ public class ResultInfoUtil { /** * 提供给部分不需要出參的接口 * * @return */ public static ResultInfo success() { return success(ResponseCode.SUCCESS); } /** * 返回成功的结果 * * @param data * @return */ public static ResultInfo success(Object data) { return success(ResponseCode.SUCCESS, data); } public static ResultInfo error(String status, String message) { ResultInfo result = new ResultInfo(); result.setStatus(status); result.setMessage(message); result.setData(null); return result; } /** * 返回成功的结果 * * @param object * @return */ public static ResultInfo success(ResponseCode message, Object object) { ResultInfo resultInfo = new ResultInfo(); resultInfo.setStatus(message.getStatus()); resultInfo.setMessage(message.getMessage()); resultInfo.setData(object); return resultInfo; } public static ResultInfo error() { return error(ResponseCode.ERROR); } public static ResultInfo error(Object data) { return error(ResponseCode.ERROR, data); } public static ResultInfo error(ResponseCode message, Object object) { ResultInfo resultInfo = new ResultInfo(); resultInfo.setStatus(message.getStatus()); resultInfo.setMessage(message.getMessage()); resultInfo.setData(object); return resultInfo; } } ================================================ FILE: hacker-framework-model/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-framework-model org.apache.maven.plugins maven-compiler-plugin 8 8 ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/Cto/AdminRoles.java ================================================ package hacker.framework.model.Cto; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.List; /** * 添加角色----》封装了管理员id和所分配的角色id集合 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:35 */ @Getter @Setter public class AdminRoles{ Integer uid; Integer role; List roles; public AdminRoles() { } public AdminRoles(Integer uid, List roles) { this.uid = uid; this.roles = roles; } public AdminRoles(Integer uid, Integer role) { this.uid = uid; this.role = role; } public List getResult(){ List adminRoles = new ArrayList<>(12); roles.forEach( ro ->{ adminRoles.add(new AdminRoles(uid,ro)); }); return adminRoles; } } ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/Cto/RolePermissions.java ================================================ package hacker.framework.model.Cto; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.List; /** * 封装roleid和permissionid,用来给角色赋权 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:26 */ @Getter @Setter public class RolePermissions { Integer rid; Integer pid; List pids; public RolePermissions() { } public RolePermissions(Integer rid, List pids) { this.rid = rid; this.pids = pids; } public RolePermissions(Integer rid, Integer pid) { this.rid = rid; this.pid = pid; } public List getObj() { List list = new ArrayList<>(12); pids.forEach(pid -> { list.add(new RolePermissions(this.rid, pid)); }); return list; } } ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/entity/Admin.java ================================================ package hacker.framework.model.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; import java.util.Date; import java.util.List; /** * 管理员表 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:19 */ @Data @TableName("tb_admin") public class Admin implements Serializable { @TableId(type = IdType.AUTO) private Integer id; private String phone; private String username; private String nickname; private String password; private Integer status; //是否只允许读操作 0否 1是 private Integer is_readonly; private String last_login_token; private String last_login_ip; private Date login_at; private Date created_at; private Date updated_at; //角色和权限 @TableField(exist = false) private List roles; @TableField(exist = false) private List permissions; @Override public String toString() { return "Admin{" + "id=" + id + ", phone='" + phone + '\'' + ", username='" + username + '\'' + ", nickname='" + nickname + '\'' + ", password='" + password + '\'' + ", status=" + status + ", is_readonly=" + is_readonly + ", last_login_token='" + last_login_token + '\'' + ", last_login_ip='" + last_login_ip + '\'' + ", login_at=" + login_at + ", created_at=" + created_at + ", updated_at=" + updated_at + ", roles=" + roles + ", permissions=" + permissions + '}'; } } ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/entity/Pay.java ================================================ package hacker.framework.model.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; import java.util.Date; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 13:45 */ @Data @TableName("tb_pay") public class Pay { private Long tradeNo; //用户订单号 private Integer userId; private Integer adminId; private Date payTime; private BigDecimal payAmount; private Integer payStatus; private Integer payType; private Date gmtCreate; private String merchantOutOrderNo; //商家支付订单号 @Override public String toString() { return "Pay{" + "tradeNo=" + tradeNo + ", userId=" + userId + ", adminId=" + adminId + ", payTime=" + payTime + ", payAmount=" + payAmount + ", payStatus=" + payStatus + ", payType=" + payType + ", gmtCreate=" + gmtCreate + ", merchantOutOrderNo='" + merchantOutOrderNo + '\'' + '}'; } } ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/entity/Permission.java ================================================ package hacker.framework.model.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; import java.util.Date; /** * 权限表 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:17 */ @Data @TableName("tb_permission") public class Permission implements Serializable { @TableId(type = IdType.AUTO) private Integer id; private String name; //权限唯一ID private Integer parent_id; //父类ID,根节点为0 private String index_name; private String display_name;//权限展示名 private Integer is_show; //是否展示在菜单栏 private Integer status; //状态 1:正常 0:禁用 private Date created_at; private Date updated_at; @Override public String toString() { return "Permission{" + "id=" + id + ", name='" + name + '\'' + ", index_name='" + index_name + '\'' + ", parent_id=" + parent_id + ", display_name='" + display_name + '\'' + ", is_show=" + is_show + ", status=" + status + ", created_at=" + created_at + ", updated_at=" + updated_at + '}'; } } ================================================ FILE: hacker-framework-model/src/main/java/hacker/framework/model/entity/Role.java ================================================ package hacker.framework.model.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.io.Serializable; import java.util.Date; /** * 角色表 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:14 */ @Data @TableName("tb_role") public class Role implements Serializable { @TableId(type = IdType.AUTO) private Integer id; private String display_name;//角色展示名 private Integer level; //角色等级 private Date created_at; private Date updated_at; @Override public String toString() { return "Role{" + "id=" + id + ", display_name='" + display_name + '\'' + ", level=" + level + ", created_at=" + created_at + ", updated_at=" + updated_at + '}'; } } ================================================ FILE: hacker-framework-model/src/main/resources/application.properties ================================================ ================================================ FILE: hacker-framework-util/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: hacker-framework-util/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-framework-util org.apache.maven.plugins maven-compiler-plugin 8 8 ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/ApplicationContextUtil.java ================================================ package hacker.framework.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 14:28 * @description 获取spring 容器 */ @Component public class ApplicationContextUtil implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public ApplicationContext getApplicationContext(){ return applicationContext; } private ApplicationContextUtil() { } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/CommontUtil.java ================================================ package hacker.framework.util; import javax.servlet.http.HttpServletRequest; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.UUID; /** * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:58 * @description 通用工具 */ public class CommontUtil { private final static String UNKNOWN = "unknown"; /** * 获取ip * @param request * @return */ public static String getIpAddress(HttpServletRequest request) { String split = ","; String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } if (ip.contains(split)) { return ip.split(split)[0]; } else { return ip; } } /** * 返回uuid * @return uuid */ public static String getUUID(){ return UUID.randomUUID().toString().replace("-",""); } /** * 返回当前时间的Timestamp格式 * @return Timestamp */ public static Timestamp getTimeStampTime(){ LocalDateTime time = LocalDateTime.now(); Timestamp timestamp = Timestamp.valueOf(time); return timestamp; } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/FileUtil.java ================================================ package hacker.framework.util; /** * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/10 9:50 */ public class FileUtil { // 图片允许的后缀扩展名-----》格式 public static String[] IMAGE_FILE_EXTD = new String[] { "png", "bmp", "jpg", "jpeg","pdf" }; public static boolean isFileAllowed(String fileName) { for (String ext : IMAGE_FILE_EXTD) { if (ext.equals(fileName)) { return true; } } return false; } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/LuKeIp.java ================================================ package hacker.framework.util; import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * 获取IP的工具类 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:37 */ public class LuKeIp { /** * 获取用户IP地址 */ public static String getIpAddress(HttpServletRequest request) { String[] ipHeaders = {"x-forwarded-for", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; String[] localhostIp = {"127.0.0.1", "0:0:0:0:0:0:0:1"}; String ip = request.getRemoteAddr(); for (String header : ipHeaders) { if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) break; ip = request.getHeader(header); } for (String local : localhostIp) { if (ip != null && ip.equals(local)) { try { ip = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException ignored) { } break; } } if (ip != null && ip.length() > 15 && ip.contains(",")) { ip = ip.substring(0, ip.indexOf(',')); } return ip; } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/MD5Util.java ================================================ package hacker.framework.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 17:42 */ public class MD5Util { private static final Logger logger = LoggerFactory.getLogger( MD5Util.class ); /** * MDB加密方法 * @param s * @return */ public static final String to_32_MD5(String s) { if(StringUtil.isEmpty(s)){ throw new RuntimeException("被加密字段不能为空"); } char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; byte[] strTemp = s.getBytes(); MessageDigest mdTemp = null; try { mdTemp = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { logger.error("数据加密发生异常 {}",e.getMessage()); return null; } mdTemp.update(strTemp); byte[] md = mdTemp.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str).toUpperCase(); } /** * 16位MD5串 * @param s * @return */ public static final String to_16_MD5(String s){ if(StringUtil.isEmpty(s)){ throw new RuntimeException("被加密字段不能为空"); } String md5Str = to_32_MD5(s); md5Str = md5Str.substring(8, 24); return md5Str.toUpperCase(); } /** * 将32位的md5字符串截断成16位 * @param s * @return */ public static final String md5To16(String s){ if(StringUtil.isEmpty(s)){ throw new RuntimeException("加密字段不能为空"); } String md5Str = s.substring(8, 24); return md5Str.toUpperCase(); } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/OrderUtil.java ================================================ package hacker.framework.util; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; /** * * 订单编码码生成器,生成32位数字编码, * * @生成规则 1位单号类型+17位时间戳+14位(用户id加密&随机数) */ public class OrderUtil { /** * 订单类别头 */ private static final String ORDER_CODE = "1"; /** * 退货类别头 */ private static final String RETURN_ORDER = "2"; /** * 退款类别头 */ private static final String REFUND_ORDER = "3"; /** * 未付款重新支付别头 */ private static final String AGAIN_ORDER = "4"; /** * 随即编码 */ private static final int[] r = new int[]{7, 9, 6, 2, 8, 1, 3, 0, 5, 4}; /** * 用户id和随机数总长度 */ private static final int maxLength = 14; /** * 更具id进行加密+加随机数组成固定长度编码 */ private static String toCode(Integer id) { String idStr = id.toString(); StringBuilder idsbs = new StringBuilder(); for (int i = idStr.length() - 1; i >= 0; i--) { idsbs.append(r[idStr.charAt(i) - '0']); } return idsbs.append(getRandom(maxLength - idStr.length())).toString(); } /** * 生成时间戳 */ private static String getDateTime() { DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return sdf.format(new Date()); } /** * 生成固定长度随机码 * * @param */ private static long getRandom(long n) { long min = 1, max = 9; for (int i = 1; i < n; i++) { min *= 10; max *= 10; } long rangeLong = (((long) (new Random().nextDouble() * (max - min)))) + min; return rangeLong; } /** * 生成不带类别标头的编码 * * @param userId */ private static synchronized String getCode(Integer userId) { userId = userId == null ? 10000 : userId; return getDateTime() + toCode(userId); } /** * 生成订单单号编码 * * @param userId */ public static String getOrderCode(Integer userId) { return ORDER_CODE + getCode(userId); } /** * 生成退货单号编码 * * @param userId */ public static String getReturnCode(Integer userId) { return RETURN_ORDER + getCode(userId); } /** * 生成退款单号编码 * * @param userId */ public static String getRefundCode(Integer userId) { return REFUND_ORDER + getCode(userId); } /** * 未付款重新支付 * * @param userId */ public static String getAgainCode(Integer userId) { return AGAIN_ORDER + getCode(userId); } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/SHA256.java ================================================ package hacker.framework.util; import org.apache.commons.codec.binary.Hex; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:42 */ public class SHA256 { private static final String CHARSET_NAME = "UTF-8"; /** * SHA256加密 * @param str 明文 * @return 密文 */ public static String SHA256Encode(String str){ MessageDigest messageDigest; String encodeStr = ""; try { messageDigest = MessageDigest.getInstance("SHA-256"); byte[] hash = messageDigest.digest(str.getBytes(CHARSET_NAME)); encodeStr = Hex.encodeHexString(hash); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return encodeStr; } public static void main(String[] args) { //对自己的密码加密-----》》64位以上 String name = SHA256Encode("abc123"+"Jhuiabn9_DhiebFIJ==jel%$dafe4fs@deaerf_"); //cpu核心数 int i = Runtime.getRuntime().availableProcessors(); System.out.println(name); } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/Snowflake.java ================================================ package hacker.framework.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; /** * java edition of Twitter Snowflake, a network service for generating * unique ID numbers at high scale with some simple guarantees. * * https://github.com/twitter/snowflake */ public class Snowflake { private static Logger log = LoggerFactory.getLogger(Snowflake.class); // private static Logger /* * bits allocations for timeStamp, datacenterId, workerId and sequence */ private final long unusedBits = 1L; /** * 'time stamp' here is defined as the number of millisecond that have * elapsed since the {@link #epoch} given by users on {@link Snowflake} * instance initialization */ private final long timestampBits = 41L; private final long datacenterIdBits = 5L; private final long workerIdBits = 5L; private final long sequenceBits = 12L; /* * max values of timeStamp, workerId, datacenterId and sequence */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 2^5-1 private final long maxWorkerId = -1L ^ (-1L << workerIdBits); // 2^5-1 private final long maxSequence = -1L ^ (-1L << sequenceBits); // 2^12-1 /** * left shift bits of timeStamp, workerId and datacenterId */ private final long timestampShift = sequenceBits + datacenterIdBits + workerIdBits; private final long datacenterIdShift = sequenceBits + workerIdBits; private final long workerIdShift = sequenceBits; /* * object status variables */ /** * reference material of 'time stamp' is '2018-12-14'. its value can't be * modified after initialization. */ private final long epoch = 1451606400000L; /** * data center number the process running on, its value can't be modified * after initialization. *

* max: 2^5-1 range: [0,31] */ private final long datacenterId; /** * machine or process number, its value can't be modified after * initialization. *

* max: 2^5-1 range: [0,31] * */ private final long workerId; /** * the unique and incrementing sequence number scoped in only one * period/unit (here is ONE millisecond). its value will be increased by 1 * in the same specified period and then reset to 0 for next period. *

* max: 2^12-1 range: [0,4095] */ private long sequence = 0L; /** the time stamp last snowflake ID generated */ private long lastTimestamp = -1L; /** * generate an unique and incrementing id * * @return id */ public synchronized long nextId() { long currTimestamp = timestampGen(); if (currTimestamp < lastTimestamp) { throw new IllegalStateException( String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - currTimestamp)); } if (currTimestamp == lastTimestamp) { sequence = (sequence + 1) & maxSequence; if (sequence == 0) { // overflow: greater than max sequence currTimestamp = waitNextMillis(currTimestamp); } } else { // reset to 0 for next period/millisecond sequence = 0L; } // track and memo the time stamp last snowflake ID generated lastTimestamp = currTimestamp; return ((currTimestamp - epoch) << timestampShift) | // (datacenterId << datacenterIdShift) | // (workerId << workerIdShift) | // new line for nice looking sequence; } /** * @param datacenterId * data center number the process running on, value range: [0,31] * @param workerId * machine or process number, value range: [0,31] */ public Snowflake(long datacenterId, long workerId) { if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException( String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException( String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } this.datacenterId = datacenterId; this.workerId = workerId; } /** * track the amount of calling {@link #waitNextMillis(long)} method */ private final AtomicLong waitCount = new AtomicLong(0); /** * @return the amount of calling {@link #waitNextMillis(long)} method */ public long getWaitCount() { return waitCount.get(); } /** * running loop blocking until next millisecond * * @param currTimestamp current time stamp * @return current time stamp in millisecond */ protected long waitNextMillis(long currTimestamp) { waitCount.incrementAndGet(); while (currTimestamp <= lastTimestamp) { currTimestamp = timestampGen(); } return currTimestamp; } /** * get current time stamp * * @return current time stamp in millisecond */ protected long timestampGen() { return System.currentTimeMillis(); } /** * show settings of Snowflake */ @Override public String toString() { return "Snowflake Settings [timestampBits=" + timestampBits + ", datacenterIdBits=" + datacenterIdBits + ", workerIdBits=" + workerIdBits + ", sequenceBits=" + sequenceBits + ", epoch=" + epoch + ", datacenterId=" + datacenterId + ", workerId=" + workerId + "]"; } public long getEpoch() { return this.epoch; } /** * extract time stamp, datacenterId, workerId and sequence number * information from the given id * * @param id * a snowflake id generated by this object * @return an array containing time stamp, datacenterId, workerId and * sequence number */ public long[] parseId(long id) { long[] arr = new long[5]; arr[4] = ((id & diode(unusedBits, timestampBits)) >> timestampShift); arr[0] = arr[4] + epoch; arr[1] = (id & diode(unusedBits + timestampBits, datacenterIdBits)) >> datacenterIdShift; arr[2] = (id & diode(unusedBits + timestampBits + datacenterIdBits, workerIdBits)) >> workerIdShift; arr[3] = (id & diode(unusedBits + timestampBits + datacenterIdBits + workerIdBits, sequenceBits)); return arr; } /** * extract and display time stamp, datacenterId, workerId and sequence * number information from the given id in humanization format * * @param id snowflake id in Long format * @return snowflake id in String format */ public String formatId(long id) { long[] arr = parseId(id); String tmf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(arr[0])); return String.format("%s, #%d, @(%d,%d)", tmf, arr[3], arr[1], arr[2]); } /** * a diode is a long value whose left and right margin are ZERO, while * middle bits are ONE in binary string layout. it looks like a diode in * shape. * * @param offset * left margin position * @param length * offset+length is right margin position * @return a long value */ private long diode(long offset, long length) { int lb = (int) (64 - offset); int rb = (int) (64 - (offset + length)); return (-1L << lb) ^ (-1L << rb); } public static void main(String[] args) { Snowflake idWorker = new Snowflake(1, 2); Snowflake idWorker2 = new Snowflake(1, 3); for(int i=0;i<10;i++){ long l = idWorker.nextId(); long l2 = idWorker2.nextId(); System.out.println(l); System.out.println(l2); } } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/SnowflakeIdWorker.java ================================================ package hacker.framework.util; /** * Twitter_Snowflake
* SnowFlake的结构如下(每部分用-分开):
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
* 加起来刚好64位,为一个Long型。
* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 */ public class SnowflakeIdWorker { // ==============================Fields=========================================== /** 开始时间截 (2018-12-14) */ private final long twepoch = 1420041600000L; /** 机器id所占的位数 */ private final long workerIdBits = 5L; /** 数据标识id所占的位数 */ private final long datacenterIdBits = 5L; /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits); /** 支持的最大数据标识id,结果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); /** 序列在id中占的位数 */ private final long sequenceBits = 12L; /** 机器ID向左移12位 */ private final long workerIdShift = sequenceBits; /** 数据标识id向左移17位(12+5) */ private final long datacenterIdShift = sequenceBits + workerIdBits; /** 时间截向左移22位(5+5+12) */ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ private final long sequenceMask = -1L ^ (-1L << sequenceBits); /** 工作机器ID(0~31) */ private long workerId; /** 数据中心ID(0~31) */ private long datacenterId; /** 毫秒内序列(0~4095) */ private long sequence = 0L; /** 上次生成ID的时间截 */ private long lastTimestamp = -1L; //==============================Constructors===================================== /** * 构造函数 * @param workerId 工作ID (0~31) * @param datacenterId 数据中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } // ==============================Methods========================================== /** * 获得下一个ID (该方法是线程安全的) * @return SnowflakeId */ public synchronized long nextId() { long timestamp = timeGen(); //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 if (timestamp < lastTimestamp) { throw new RuntimeException( String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } //如果是同一时间生成的,则进行毫秒内序列 if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; //毫秒内序列溢出 if (sequence == 0) { //阻塞到下一个毫秒,获得新的时间戳 timestamp = tilNextMillis(lastTimestamp); } } //时间戳改变,毫秒内序列重置 else { sequence = 0L; } //上次生成ID的时间截 lastTimestamp = timestamp; //移位并通过或运算拼到一起组成64位的ID return ((timestamp - twepoch) << timestampLeftShift) // | (datacenterId << datacenterIdShift) // | (workerId << workerIdShift) // | sequence; } /** * 阻塞到下一个毫秒,直到获得新的时间戳 * @param lastTimestamp 上次生成ID的时间截 * @return 当前时间戳 */ protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } /** * 返回以毫秒为单位的当前时间 * @return 当前时间(毫秒) */ protected long timeGen() { return System.currentTimeMillis(); } //==============================Test============================================= /** 测试 */ public static void main(String[] args) { // System.out.println(Long.toBinaryString(5)); SnowflakeIdWorker idWorker = new SnowflakeIdWorker(1, 1); for (int i = 0; i < 1000; i++) { long id = idWorker.nextId(); System.out.println(Long.toBinaryString(id)); System.out.println(id); } } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/SslUtils.java ================================================ package hacker.framework.util; import javax.net.ssl.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * Ssl安全证书 */ public class SslUtils { private static void trustAllHttpsCertificates() throws Exception { TrustManager[] trustAllCerts = new TrustManager[1]; TrustManager tm = new miTM(); trustAllCerts[0] = tm; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, null); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } static class miTM implements TrustManager,X509TrustManager { @Override public X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(X509Certificate[] certs) { return true; } public boolean isClientTrusted(X509Certificate[] certs) { return true; } @Override public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { return; } } /** * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用 * @throws Exception */ public static void ignoreSsl() throws Exception{ HostnameVerifier hv = new HostnameVerifier() { @Override public boolean verify(String urlHostName, SSLSession session) { return true; } }; trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/StringUtil.java ================================================ package hacker.framework.util; import org.apache.commons.lang3.StringUtils; import java.util.UUID; public class StringUtil { /** * 字符串去掉前后空格后是否为空字符串 * @param source * @return */ public static final boolean isEmpty(String source){ return StringUtils.isEmpty(StringUtils.trimToEmpty(source)); } /** * 字符串去掉前后空格后是否不为空字符串 * @param source * @return */ public static final boolean isNotEmpty(String source){ return StringUtils.isNotEmpty(StringUtils.trimToEmpty(source)); } /** * 字符串去掉前后空格后是否为空 * @param source * @return */ public static final boolean isNull(String source){ return StringUtils.isBlank(StringUtils.trimToNull(source)); } /** * 字符串去掉前后空格后是否不为空 * @param source * @return */ public static final boolean isNotNull(String source){ return StringUtils.isNotBlank(StringUtils.trimToNull(source)); } /** * 获取去除间隔符号的UUID字符串 * @return */ public static final String getKey(){ String uuidStr = UUID.randomUUID().toString(); return uuidStr.replace("-", ""); } public static String toUnicodeEx(String str){ String result=""; for (int i = 0; i < str.length(); i++){ int chr1 = (char) str.charAt(i); if(chr1>=19968&&chr1<=171941){//\u4e00-\u9fa5 result+="\\\\\\\\\\u" + Integer.toHexString(chr1); }else{ if(chr1<255) { result += "\\\\\\\\\\u" + String.format("%04x", chr1); }else { result += str.charAt(i); } } } return result; } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/TestUtil.java ================================================ package hacker.framework.util; import org.apache.commons.lang3.StringUtils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.security.MessageDigest; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class TestUtil { /** *double类型数乘以100 */ public static Double doubleRide100(double d) { BigDecimal bg = new BigDecimal(d * 100); double doubleValue = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); return doubleValue; } /** * * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序),并且生成url参数串
* 实现步骤:
* * @param paraMap * 要排序的Map对象 * @param urlEncode * 是否需要URLENCODE * @param keyToLower * 是否需要将Key转换为全小写 true:key转化成小写,false:不转化 * @return */ public static String formatUrlMap(Map paraMap, boolean urlEncode, boolean keyToLower) { String buff = ""; Map tmpMap = paraMap; try { List> infoIds = new ArrayList>(tmpMap.entrySet()); // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) Collections.sort(infoIds, new Comparator>() { @Override public int compare(Map.Entry o1, Map.Entry o2) { return (o1.getKey()).toString().compareTo(o2.getKey()); } }); // 构造URL 键值对的格式 StringBuilder buf = new StringBuilder(); for (Map.Entry item : infoIds) { if (StringUtils.isNotBlank(item.getKey())) { String key = item.getKey(); String val = item.getValue(); if (urlEncode) { val = URLEncoder.encode(val, "utf-8"); } if (keyToLower) { buf.append(key.toLowerCase() + "=" + val); } else { buf.append(key + "=" + val); } buf.append("&"); } } buff = buf.toString(); if (buff.isEmpty() == false) { buff = buff.substring(0, buff.length() - 1); } } catch (Exception e) { return null; } return buff; } /** * 对字符串md5加密 * * @param str * @return */ public static String getMD5(String str){ MessageDigest md5 = null; try{ md5 = MessageDigest.getInstance("MD5"); }catch (Exception e){ System.out.println(e.toString()); e.printStackTrace(); return ""; } char[] charArray = str.toCharArray(); byte[] byteArray = new byte[charArray.length]; for (int i = 0; i < charArray.length; i++) { byteArray[i] = (byte) charArray[i]; } byte[] md5Bytes = md5.digest(byteArray); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++){ int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } /** * 接口调用 GET */ public static String sendGet(String GET_URL) { String s=null; try { URL url = new URL(GET_URL); // 把字符串转换为URL请求地址 HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 打开连接 connection.connect();// 连接会话 // 获取输入流 BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) {// 循环读取流 sb.append(line); } br.close();// 关闭流 connection.disconnect();// 断开连接 System.out.println("接口调用 GET:"+sb.toString()); s=sb.toString(); return s; } catch (Exception e) { e.printStackTrace(); System.out.println("失败!"); } return null; } /** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @param charset * 发送和接收的格式 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param,String charset) { PrintWriter out = null; BufferedReader in = null; String result = ""; String line; StringBuffer sb=new StringBuffer(); try { URL realUrl = new URL(url); //如果是https请求,忽略SSL证书 if("https".equalsIgnoreCase(realUrl.getProtocol())){ SslUtils.ignoreSsl(); } // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 设置请求格式 conn.setRequestProperty("contentType", charset); conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); //设置超时时间 conn.setConnectTimeout( 60000); conn.setReadTimeout( 60000); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 设置接收格式 in = new BufferedReader(new InputStreamReader(conn.getInputStream(),charset)); while ((line = in.readLine()) != null) { sb.append(line); } result=sb.toString(); } catch (Exception e) { System.out.println("发送 POST请求出现异常!"+e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(IOException ex){ ex.printStackTrace(); } } return result; } /** * 获取现在时间 * @author haixin * @return 返回时间类型 yyyy-MM-dd HH:mm:ss * @throws ParseException */ public static Date getNowDate() throws ParseException { SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateTime=sd.format(new Date()); Date date=sd.parse(dateTime); return date; } /** * 生成两位随机数 * @author haixin * @return 返回int类型 10-99 */ public static int random() { int max=99; int min=10; Random random = new Random(); int s = random.nextInt(max)%(max-min+1) + min; return s; } /** * 不够位数的在前面补0,保留num的长度位数字 * @param code * @return */ private static String autoGenericCode(String code, int num) { String result = ""; // 保留num的位数 // 0 代表前面补充0 // num 代表长度为4 // d 代表参数为正数型 result = String.format("%0" + num + "d", Integer.parseInt(code)); return result; } /** * @author haixin.hu * @param str:name1=value1&name2=value2类型字符串 * @return 返回类型:Map数组 * */ @SuppressWarnings("rawtypes") public static Map StrToMap(String str){ String[] strs = str.split("&"); Map m = new HashMap(); for(String s:strs){ String[] ms = s.split("="); m.put(ms[0], ms[1]); } return m; } } ================================================ FILE: hacker-framework-util/src/main/java/hacker/framework/util/TokenProccessor.java ================================================ package hacker.framework.util; import sun.misc.BASE64Encoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; /** * 生成Token的工具类 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:37 */ public class TokenProccessor { private TokenProccessor(){}; private static final TokenProccessor instance = new TokenProccessor(); public static TokenProccessor getInstance() { return instance; } /** * 生成Token * @return */ public String makeToken() { String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + ""; try { MessageDigest md = MessageDigest.getInstance("md5"); byte md5[] = md.digest(token.getBytes()); BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } ================================================ FILE: hacker-framework-util/src/main/resources/application.properties ================================================ ================================================ FILE: hacker-govern-center/.gitignore ================================================ HELP.md /target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ /build/ ### VS Code ### .vscode/ ================================================ FILE: hacker-govern-center/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-govern-center org.springframework.cloud spring-cloud-starter-netflix-eureka-server 2.0.2.RELEASE org.springframework.boot spring-boot-starter-logging Hacker-govern-center org.springframework.boot spring-boot-maven-plugin ================================================ FILE: hacker-govern-center/src/main/java/hacker/framework/center/EurekaApplication.java ================================================ package hacker.framework.center; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer // 标识此工程是一个EurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); System.out.println("标识此工程是一个EurekaServer"); } } ================================================ FILE: hacker-govern-center/src/main/resources/application.properties ================================================ #spring.profiles.active=dev #server.port=8101 #spring.application.name=Hacker-govern-model ================================================ FILE: hacker-govern-center/src/main/resources/application.yml ================================================ server: port: ${PORT:50101} #服务端口 spring: # profiles: dev application: name: Hacker-govern-model # 指定服务名 eureka: client: registerWithEureka: true # 服务注册,是否将自己注册到Eureka服务中 fetchRegistry: true # 服务发现,是否从Eureka中获取注册信息 serviceUrl: # Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口) defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/} server: enable-self-preservation: false # 是否开启自我保护模式 eviction-interval-timer-in-ms: 60000 # 服务注册表清理间隔(单位毫秒,默认是60*1000) instance: hostname: ${EUREKA_DOMAIN:127.0.0.1} ================================================ FILE: hacker-govern-gateway/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-govern-gateway org.springframework.cloud spring-cloud-netflix-zuul 2.1.1.RELEASE Hacker-govern-gateway org.springframework.boot spring-boot-maven-plugin ================================================ FILE: hacker-govern-gateway/src/main/java/hacker/govern/gateway/ZuulAppApplication.java ================================================ package hacker.govern.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy // 此工程是一个zuul网关 public class ZuulAppApplication { public static void main(String[] args) { SpringApplication.run(ZuulAppApplication.class, args); System.out.println("此工程是一个zuul网关"); } } ================================================ FILE: hacker-govern-gateway/src/main/resources/application.properties ================================================ server.servlet.context-path=/api spring.application.name=Hacker-govern-gateway ================================================ FILE: hacker-govern-gateway/src/main/resources/application.yml ================================================ #spring: # profiles: dev server: port: 50201 servlet: context-path: /api spring: application: name: Hacker-govern-gateway redis: host: 127.0.0.1 port: 6379 password: 123456 timeout: 3000 lettuce: pool: max-active: 200 max-idle: 50 min-idle: 24 max-wait: 2000 zuul: routes: Hacker-api-business-web: path: /business/** serviceId: Hacker-api-business-web # 指定服务ID(名称),网关会从eureka中获取该服务名称下的服务实例的地址 # url: http://www.baidu.com # 也可指定url,此url也可以是外网地址 (例子:将请求转发到http://www.baidu.com/business) strip-prefix: false # true:代理转发时去掉前缀,false:代理转发时不去掉前缀 sensitiveHeaders: # 默认zuul会屏蔽cookie,cookie不会传到下游服务,这里设置为空则取消默认的黑名单,如果设置了具体的头信息则不会传到下游服务 # ignoredHeaders: # 默认为空表示不过虑任何头 Hacker-api-business-app: path: /business/app/** serviceId: Hacker-api-business-app strip-prefix: false sensitiveHeaders: Hacker-api-business-alipay-shenghuohao: path: /business/alipay/shenghuohao/** serviceId: Hacker-api-business-alipay-shenghuohao strip-prefix: false sensitiveHeaders: eureka: client: registerWithEureka: true # 服务注册开关 fetchRegistry: true # 服务发现开关 serviceUrl: # Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔 defaultZone: ${EUREKA_SERVER:http://localhost:50101/eureka/,http://localhost:50102/eureka/} instance: prefer-ip-address: true # 将自己的ip地址注册到Eureka服务中 ip-address: 127.0.0.1 instance-id: ${spring.application.name}:${server.port} # 指定实例id ribbon: MaxAutoRetries: 2 # 最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试,如果eureka中找不到服务则直接走断路器 MaxAutoRetriesNextServer: 3 # 切换实例的重试次数 OkToRetryOnAllOperations: false # 对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false ConnectTimeout: 5000 # 请求连接的超时时间 ReadTimeout: 6000 # 请求处理的超时时间 ================================================ FILE: hacker-service-channel-manage/pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud 1.0-SNAPSHOT ../pom.xml Hacker-service-channel-manage Hacker.walker Hacker-framework-common 1.0-SNAPSHOT compile Hacker.walker Hacker-framework-model 1.0-SNAPSHOT compile Hacker.walker Hacker-framework-util 1.0-SNAPSHOT compile Hacker-service-channel-manage org.springframework.boot spring-boot-maven-plugin ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/App.java ================================================ package hacker.channel.manage; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.BeansException; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScans; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.bind.annotation.RequestMapping; import javax.sql.DataSource; @SpringBootApplication // 扫描common、util下的所有类 @EnableScheduling @ComponentScans(@ComponentScan("hacker.framework")) // 扫描实体类 @EntityScan("hacker.framework.model") //扫描接口 @MapperScan("hacker.channel.manage.mapper") //dao @RequestMapping(value = "/") public class App implements ApplicationContextAware { public static void main(String[] args) { SpringApplication.run(App.class, args); System.out.println("walker开源作品 个人博客:https://www.wuxf.cn 微信公众号:堇夏年华"); System.out.println("2019年,祝每一个努力的人都有所收获"); } //applicationContext private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //加载dataSource @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean(); sessionFactoryBean.setDataSource((DataSource) applicationContext.getBean("dataSource")); return sessionFactoryBean.getObject(); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/AppInterceptor.java ================================================ package hacker.channel.manage.config; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description 拦截器 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Slf4j public class AppInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String url = request.getRequestURL().toString(); log.info("=== request url: "+url); Subject subject = SecurityUtils.getSubject(); Object principal = subject.getPrincipal(); if (null == principal){ response.sendRedirect("/templates/dr"); log.info("=拦截=重定向="); return false; } log.info("拦截器放行"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器执行后"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("完成"); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/AuthInterceptor.java ================================================ package hacker.channel.manage.config; import hacker.framework.common.annotation.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Component public class AuthInterceptor implements HandlerInterceptor { Logger logger = LoggerFactory.getLogger( AuthInterceptor.class ); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info( "AuthInterceptor preHandler {}", request.getRequestURI() ); Object obj = request.getSession().getAttribute(Constants.AUTH_USER); if ( null == obj ) { response.setStatus( 401 ); return false; } // 操作权限验证TODO??? return true; } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/CorsConfig.java ================================================ package hacker.channel.manage.config; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * 跨域配置 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Configuration public class CorsConfig { @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 设置你要允许的网站域名,如果全允许则设为 * config.addAllowedOrigin("*"); // 如果要限制 HEADER 或 METHOD 请自行更改 config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); // 这个顺序很重要,为避免麻烦请设置在最前 bean.setOrder(0); return bean; } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/MvcConfig.java ================================================ package hacker.channel.manage.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @description 拦截器注册配置 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Configuration public class MvcConfig implements WebMvcConfigurer { /** * 视图跳转集中配置 * @param registry */ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/dr").setViewName("dr"); } /** * 配置拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AppInterceptor()) //放行 .addPathPatterns("/**") .excludePathPatterns("/api/login") .excludePathPatterns("/error") .excludePathPatterns("/dr") .excludePathPatterns("/**") .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**") .excludePathPatterns("/static/**"); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/ShiroConfig.java ================================================ package hacker.channel.manage.config; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** * @description shiro的Java配置 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:44 */ @Configuration public class ShiroConfig { @Autowired private ShiroRealm shiroRealm; @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map filterChainDefinitionMap = new LinkedHashMap(); //登陆url,未登陆也会重定向到此 shiroFilterFactoryBean.setLoginUrl("/dr"); //api/login/dr.html //配置退出,Shiro已经实现 filterChainDefinitionMap.put("/logout", "logout"); //过滤链定义,从上向下顺序执行,一般将/**放在最为下边 //authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问 filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/api/login", "anon"); filterChainDefinitionMap.put("/**", "authc"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 安全管理器 * @return SecurityManager */ @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm); securityManager.setCacheManager(ehCacheManager()); return securityManager; } /** * 缓存管理器 * @return EhCacheManager */ @Bean public EhCacheManager ehCacheManager(){ EhCacheManager ehCacheManager = new EhCacheManager(); //缓存 ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml"); return ehCacheManager; } //************************************* 以下是对shiro注解的支持 *****************************************// @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/ShiroRealm.java ================================================ package hacker.channel.manage.config; import hacker.channel.manage.service.AdminService; import hacker.channel.manage.service.PermissionService; import hacker.channel.manage.service.RoleService; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Permission; import hacker.framework.model.entity.Role; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; /** * @description shiro授权,认证 realm,shiro需要自己处理异常 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 11:44 */ @Component public class ShiroRealm extends AuthorizingRealm { @Autowired private AdminService adminService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; /** * 授权 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //获取当前登陆用户后查询该用户角色和权限并赋值 Admin user = (Admin) SecurityUtils.getSubject().getPrincipal(); List roles = roleService.queryRolesUser(user); List permissions = permissionService.queryByUser(user); user.setRoles(roles); user.setPermissions(permissions); roles.forEach( role ->info.addRole(role.getDisplay_name())); permissions.forEach(permission -> info.addStringPermission(permission.getName())); return info; } /** * 登陆 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { if (authenticationToken.getPrincipal() == null) { return null; } //获取用户信息 String username = authenticationToken.getPrincipal().toString(); Admin user = null; try { //调用查询的方法查询用户名 user = adminService.findByName(username); } catch (Exception e) { e.printStackTrace(); } if (user == null) { //这里返回后会报出对应异常 return null; } else { //这里验证authenticationToken和simpleAuthenticationInfo的信息 String password = user.getPassword(); SimpleAuthenticationInfo simpleAuthenticationInfo = //shiro自动检验密码 //user,密码,唯一权限id new SimpleAuthenticationInfo(user, password, getName()); return simpleAuthenticationInfo; } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/Swagger2Configuration.java ================================================ package hacker.channel.manage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * Api文档 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/9 15:44 */ @Configuration @EnableSwagger2 public class Swagger2Configuration { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("hacker"))//看自己定义,可以肆意妄为 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("API文档") .description("API文档") .termsOfServiceUrl("https://www.wuxf.cn") .version("1.0") .build(); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/WebSocketConfig.java ================================================ package hacker.channel.manage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.yeauty.standard.ServerEndpointExporter; /** * @description 开启websocket支持 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:44 */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/config/WebSocketServer.java ================================================ package hacker.channel.manage.config; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.yeauty.annotation.*; import org.yeauty.pojo.Session; import java.util.ArrayList; import java.util.List; /** * @description websocket服务 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:34 */ @Slf4j @Component @ServerEndpoint(prefix = "netty-websocket") public class WebSocketServer { /** * 打开链接 * @param session */ @OnOpen public void onOpen(Session session) { this.session = session; addSession(); //TODO 打开链接后要做什么 //在线数加1 addOnlineCount(); log.info("open"); this.session.sendText("打开链接"); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { //TODO 关闭链接后要做什么 log.info("close"); } /** * 接受到消息 * @param message * @param session */ @OnMessage public void onMessage(String message, Session session) { //TODO 接受消息的逻辑 System.out.println("收到消息:"+message); sendMessage(message); } /** * 服务端主动发送消息 * @param message 消息体 */ public void sendMessage(String message) { this.session.sendText(message); } /** * 发生错误 * @param session * @param e */ @OnError public void onError(Session session, Throwable e) { log.error("websocket错误", e); e.printStackTrace(); } /** * 连接数+1 * @return */ public int addOnlineCount(){ return WebSocketServer.count++; } /** * 添加session到容器 */ public void addSession(){ WebSocketServer.sessions.add(this.session); } private static volatile int count = 0; private static volatile List sessions = new ArrayList<>(10); private Session session = null; } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/AdminController.java ================================================ package hacker.channel.manage.controller; import org.apache.shiro.SecurityUtils; import hacker.channel.manage.service.AdminService; import hacker.framework.common.request.BaseCode; import hacker.framework.common.request.BaseResult; import hacker.framework.model.Cto.AdminRoles; import hacker.framework.model.entity.Admin; import hacker.framework.util.SHA256; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.*; /** * 管理员界面 * * @Description: J X N H * @EnglishName LuKe * @author LiuQi(walker) * @date 2019/6/3 16:17 */ @Slf4j @RestController @RequestMapping("/api") @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, origins = "*") public class AdminController { @Autowired private AdminService adminService; //slat @Value("${salt}") private String slat; /** * 新建管理用户 * * @param user 要新建的用户 * @return 返回信息 */ @PostMapping("/addUser") @ApiOperation(value = "新建管理用户") public BaseResult createAdminUser(@RequestBody Admin user) { //接收前端传过来的参数 System.out.println(user); //接收的参数不能为空 Admin loginUser = (Admin) SecurityUtils.getSubject().getPrincipal(); Assert.notNull(user.getUsername(), "用户名不可为空"); Assert.notNull(user.getPassword(), "密码不可为空"); //对密码进行加密 user.setPassword(SHA256.SHA256Encode(user.getPassword() + slat)); int us = adminService.createNewAdmin(user); if (us == -1) { return new BaseResult("-1", "用户名重复", 0); } else { log.info("用户(id=" + loginUser.getId() + ") 新建用户( name:" + user.getUsername() + ")"); return new BaseResult(BaseCode.SUCCESS.getCode(), "新建成功", 1); } } /** * 根据id删除管理员用户 * * @param id id * @return 删除信息 */ @PostMapping("/deleteById") @ApiOperation(value = "根据id删除管理员用户") public BaseResult deleteById(Integer id) { //接收前端传过来的id System.out.println(id); Admin loginUser = (Admin) SecurityUtils.getSubject().getPrincipal(); try { //调用删除的方法 adminService.deleteById(id); log.info("当前登陆用户(id:" + loginUser.getId() + " ,name:" + loginUser.getUsername() + ") 删除了当前id=" + id + "的管理员"); return new BaseResult(BaseCode.SUCCESS.getCode(), "删除成功", 1); } catch (Exception e) { e.printStackTrace(); log.error("删除管理员用户失败", e); return new BaseResult(BaseCode.FAIL.getCode(), "删除管理员用户失败", 0); } } /** * 为管理员分配角色 * * @param adminRoles 用户id和分配的角色id */ @PostMapping("/allotRole") @ApiOperation(value = "添加管理员对应的角色") public BaseResult setRoles(@RequestBody AdminRoles adminRoles) { //这里封装了uid和rid在getObj方法中,前端传uid和roles-----》对应的多个role try { adminService.setRoles(adminRoles); log.info(" 添加管理员对应的=" + adminRoles + "角色"); return new BaseResult(BaseCode.SUCCESS.getCode(), "分配成功", 1); } catch (Exception e) { e.printStackTrace(); log.error("分配角色时异常", e); return new BaseResult(BaseCode.FAIL.getCode(), "分配失败", 0); } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/ErrorController.java ================================================ package hacker.channel.manage.controller; import hacker.framework.common.object.ResultUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletResponse; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/15 23:15 */ @Api(value = "错误", description = "错误页面处理") @Controller public class ErrorController { private static final Logger log = LoggerFactory.getLogger(LoginController.class); /*** * 错误页面 * @param model * @return */ @ApiOperation( value = "错误页面", notes = "错误页面", produces = "application/json, application/xml", consumes = "application/json, application/xml") @RequestMapping("/error1") public ModelAndView error1(Model model, HttpServletResponse response) { log.info("错误页面"); response.setStatus(HttpStatus.FORBIDDEN.value()); return ResultUtil.view("templates/error/010.html"); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/LiuStaticTest.java ================================================ package hacker.channel.manage.controller; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 18:26 */ public class LiuStaticTest { public static void main(String[] args) { //测试一下输出顺序和a、b的值 staticFunction(); } //静态初始化过程中有对象初始化----会中断静态初始化 //非静态的代码块也属于成员是放在堆中的,new 对象就是初始化堆中的内容 代码块 又会比构造先执行 所以就先2了-----个人理解 //静态变量 static LiuStaticTest st = new LiuStaticTest(); int a = 10; static int b = 11; //静态代码块 static { System.out.println("1"); System.out.println("静态代码块"); System.out.println("-----------------------"); } //代码块 { System.out.println("2"); System.out.println("代码块"); System.out.println("-----------------------"); } //构造方法 LiuStaticTest() { System.out.println("3"); System.out.println("a=" + a + "," + "b=" + b); System.out.println("构造方法"); System.out.println("-----------------------"); } public static void staticFunction() { System.out.println("4"); System.out.println("静态变量放在最前面,静态初始化过程中有对象初始化,会中断静态初始化,执行结果是2、3 a=10,b=0、1、4"); System.out.println("静态变量放在静态方法后面,不会被初始化,代码块 又会比构造先执行,执行结果就是1、2、3 a=10,b=11、4"); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/LoginController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.service.AdminService; import hacker.framework.common.request.BaseResult; import hacker.framework.common.request.ResultBean; import hacker.framework.model.entity.Admin; import hacker.framework.util.SHA256; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * admin用户登陆界面 * @Description: J X N H * @EnglishName LuKe * @author LiuQi(walker) * @date 2019/6/3 14:14 */ @Slf4j @RestController @RequestMapping("/api") @Api(value = "页面入口", description = "页面入口管理") @CrossOrigin(methods = { RequestMethod.GET, RequestMethod.POST,RequestMethod.PUT,RequestMethod.DELETE }, origins = "*") public class LoginController { @Autowired private AdminService adminService; //slat @Value("${salt}") private String slat; /*** * 首页 * @return */ @ApiOperation(value = "首页", notes = "首页") @GetMapping(value = {"/", "/templates/dr", "/dr"}) public String dr() { return "templates/dr"; } /** * 登陆 * @param username 用户名 * @param password 密码 * @return 返回状态 */ @PostMapping("/login") @ApiOperation(value = "用户登录") public BaseResult login(String username, String password, HttpServletRequest request, HttpSession httpSession ){ //接收前端传过来的信息 System.out.println("登陆的用户名为:" +username); System.out.println("登陆的密码为:" +password); //密码加盐sha256加密-----》看个人习惯 password = SHA256.SHA256Encode(password + slat); //subject Subject subject = SecurityUtils.getSubject(); //token AuthenticationToken authenticationToken = new UsernamePasswordToken(username, password); //返回信息 try { //通过token和用户名去执行登陆操作 subject.login(authenticationToken); //登陆成功后------》修改用户状态-------》修改成功后、存了登陆的token、IP、登陆时间 Admin user = (Admin) subject.getPrincipal(); adminService.updateUserStatus(user, request); //用户userId Integer userId = user.getId(); //获取用户登陆的sessionId,目前没有传给前端,看后期需不需要 httpSession.setAttribute("user_id", userId); System.out.println("用户的user_sessionId为:" + httpSession.getId()); System.out.println("用户的userId为:" + userId); return new BaseResult("200","登陆成功",userId); }catch (Exception e){ e.printStackTrace(); log.error("登陆失败",e); return new BaseResult("500","登陆失败,用户名或密码错误",0); } } @GetMapping("/logout") @ApiOperation(value = "用户退出") public BaseResult logout(){ Subject subject = SecurityUtils.getSubject(); try { subject.logout(); return new BaseResult("200","退出成功",1); }catch (Exception e){ e.printStackTrace(); log.error("登陆失败",e); return new BaseResult("500","退出失败",0); } } /** * 用户名查询 * @param username 用户名 * @return 查询返回结果 */ @GetMapping("/findByName") @ApiOperation(value = "用户名查询") public ResultBean findByName(String username){ //接收前端传过来的信息 System.out.println(username); //调用查询的方法 Admin us = adminService.findByName(username); //判断是否存在 if (us != null){ return ResultBean.ofError(0,"用户名已存在"); }else { return ResultBean.ofSuccess(1,"用户名可用"); } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/NotifyController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.mapper.PayMapper; import hacker.framework.model.entity.Pay; import hacker.framework.util.TestUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 支付回调 * @Description: J X N H * @EnglishName LuKe * @author LiuQi(walker) * @date 2019/6/9 19:14 */ @RestController @RequestMapping("/api/notify") public class NotifyController { //日志 private static final Logger log = LoggerFactory.getLogger(PayAliController.class); //配置 @Value("${merid}") private String merid;// 分配的商户号 @Value("${key}") private String key;// 商户号对应的密钥 @Value("${notifyUrl}") private String notifyUrl;// 用于接收回调通知的地址 @Value("${noncestr}") private String noncestr;//随机参数 @Autowired private PayMapper payMapper; /*** * 支付回调 更新订单支付状态 * @param request * @param response * @return */ @ResponseBody @RequestMapping("/callback") public String callback(HttpServletRequest request, HttpServletResponse response) { //订单号1 String merchantOutOrderNo = request.getParameter("merchantOutOrderNo"); //商户号 String merid = request.getParameter("merid"); //订单详情 String msg = request.getParameter("msg"); //随机字符串,和商户下单时传的一致 String noncestr = request.getParameter("noncestr"); //平台订单号 String orderNo = request.getParameter("orderNo"); //支付结果 String payResult = request.getParameter("payResult"); //签名 String sign = request.getParameter("sign"); //和下单时所填id字段一致,下单时未传则为空 String id = request.getParameter("id"); //支付宝订单号 支付宝渠道才会有 String aliNo = request.getParameter("aliNo"); //拼接签名参数 Map signParamMap = new HashMap(); signParamMap.put("merchantOutOrderNo", merchantOutOrderNo); signParamMap.put("merid", merid); signParamMap.put("msg", msg); signParamMap.put("noncestr", noncestr); signParamMap.put("orderNo", orderNo); signParamMap.put("payResult", payResult); //转换为key=value模式 String signParam = TestUtil.formatUrlMap(signParamMap, false, false); //生成签名 String signLocal = TestUtil.getMD5(signParam + "&key=" + key); //对比签名 if (signLocal.equals(sign)) { //更新订单支付状态 订单返回结果,1 为成功,0为失败,3为处理中 Pay payLogDO = new Pay(); if ("1".equals(payResult)) { payLogDO.setPayTime(new Date()); payLogDO.setPayStatus(1);//支付状态:1-成功;2-失败;3-等待支付 payLogDO.setMerchantOutOrderNo(merchantOutOrderNo); payMapper.updateOrderStatus(payLogDO); } if ("0".equals(payResult)) { payLogDO.setPayTime(new Date()); payLogDO.setPayStatus(2);//支付状态:1-成功;2-失败;3-等待支付 payLogDO.setMerchantOutOrderNo(merchantOutOrderNo); payMapper.updateOrderStatus(payLogDO); } if ("3".equals(payResult)) { payLogDO.setPayTime(new Date()); payLogDO.setPayStatus(3);//支付状态:1-成功;2-失败;3-等待支付 payLogDO.setMerchantOutOrderNo(merchantOutOrderNo); payMapper.updateOrderStatus(payLogDO); } log.info("验签成功"); return "success"; } else { /*PayLogDO payLogDO=new PayLogDO(); payLogDO.setPayTime(new Date()); payLogDO.setPayStatus(2);//支付状态:1-成功;2-失败;3-等待支付 payLogDO.setMerchantOutOrderNo(merchantOutOrderNo); payLogDOMapper.updateOrderStatus(payLogDO);*/ log.info("验签失败"); return "faild"; } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/PayAliController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.service.PayService; import hacker.framework.common.request.ResultBean; import hacker.framework.model.entity.Pay; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @Description: J X N H * @EnglishName LuKe * @author LiuQi(walker) * @date 2019/6/4 16:47 * 支付宝支付 */ @RestController @RequestMapping("/admin/pay") @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, origins = "*") public class PayAliController { //日志 private static final Logger log= LoggerFactory.getLogger(PayAliController.class); @Autowired private PayService payService; /*** * 支付宝订单支付 * @param pay payAmount channelId 订单信息:用户id,支付金额,账户id * @return 返回url和状态 */ @PostMapping(value = "/pay",consumes = "application/json") @ApiOperation(value = "提交支付宝支付", notes = "true:提交成功,false:提交失败") public ResultBean Pay(@RequestBody Pay pay){ String url = payService.Pay(pay); log.info("url-[{}]",url); ResultBean resultBean = new ResultBean<>(); resultBean.setData(url); resultBean.setCode(200); resultBean.setSuccess(true); resultBean.setMsg("支付宝支付"); return resultBean; } /** * 根据ID去查询支付状态 */ @GetMapping("/findOne") @ApiOperation(value = "跟住ID去查询支付状态") public ResultBean findById(Long tradeNo){ return ResultBean.ofSuccess(payService.findById(tradeNo)); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/PayQuickController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.mapper.PayMapper; import hacker.framework.common.request.ResultBean; import hacker.framework.model.entity.Pay; import hacker.framework.util.SnowflakeIdWorker; import hacker.framework.util.TestUtil; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 17:17 * @Description: 快捷支付 * @Version 1.0 **/ @RestController @RequestMapping("/admin/quick") @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, origins = "*") public class PayQuickController { private static final Logger log= LoggerFactory.getLogger(PayAliController.class); @Value("${merid}") private String merid;// 分配的商户号 @Value("${key}") private String key;// 商户号对应的密钥 @Value("${notifyUrl}") private String notifyUrl;// 用于接收回调通知的地 @Value("${noncestr}") private String noncestr;//随机参数 @Value("${returnUrl}") private String returnUrl;//支付完成跳转页面 @Value("${subMerchantName}") private String subMerchantName;//二级商户名称 @Autowired private PayMapper payMapper; /*** * * @param pay 订单信息: 用户id,支付金额,账号id * @return */ // @RequestMapping(value = "/payLog",method = RequestMethod.POST,produces = "application/json") @PostMapping(value = "/payLog",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) @ApiOperation(value = "提交银联快捷支付", notes = "true:提交成功,false:提交失败") public ResultBean Pay(@RequestBody Pay pay){ //第三方接口 -------》换成自己的调用的第三方即可 String wxurl="https://alipay.3c-buy.com/api/createQuickOrder"; Map paramMap = new HashMap(); //产生支付单号 SnowflakeIdWorker idWorker0 = new SnowflakeIdWorker(0, 0); String merchantOutOrderNo = idWorker0.nextId()+""; //订单时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String orderTime = sdf.format(new Date()); paramMap.put("merchantOutOrderNo",merchantOutOrderNo); paramMap.put("merid",merid); paramMap.put("noncestr",noncestr); paramMap.put("notifyUrl", notifyUrl); paramMap.put("orderMoney",pay.getPayAmount().toString()); paramMap.put("orderTime",orderTime); //添加订单信息 Pay insertPayLogDO=new Pay(); insertPayLogDO.setUserId(pay.getUserId()); insertPayLogDO.setAdminId(pay.getAdminId());//账户id insertPayLogDO.setPayAmount(pay.getPayAmount()); //金额 insertPayLogDO.setPayStatus(3);//支付状态:1-成功;2-失败;3-等待支付 insertPayLogDO.setPayType(3);//支付方式:1-支付宝;2-微信;3-银联 insertPayLogDO.setGmtCreate(new Date()); insertPayLogDO.setMerchantOutOrderNo(merchantOutOrderNo); //编号 payMapper.insertSelective(insertPayLogDO); String StringA= TestUtil.formatUrlMap(paramMap,false, false);//待签名串 String sign=TestUtil.getMD5(StringA+"&key="+key);//签名 //对参数按照key=value的格式,参照参数名ASCII码排序,并对value做utf-8的encode编码后得到字符串 param String param = TestUtil.formatUrlMap(paramMap, true, false); //#二级商户名称 银联页面显示的商户名称,不填则默认,请保证该名称已在一麻袋后台的二级商户名称中添加,并通过白名单审核,否则会报“二级商户名称不合法” String url = wxurl + "?" + param + "&sign=" + sign + "&id=" + pay.getUserId()+"&returnUrl="+returnUrl;//+"&subMerchantName="+subMerchantName; log.info("url-[{}]",url); ResultBean resultBean = new ResultBean<>(); resultBean.setData(url); resultBean.setCode(200); resultBean.setSuccess(true); resultBean.setMsg("银联快捷支付"); return resultBean; } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/PayWxController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.mapper.PayMapper; import hacker.framework.common.request.ResultBean; import hacker.framework.model.entity.Pay; import hacker.framework.util.SnowflakeIdWorker; import hacker.framework.util.TestUtil; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/5/15 10:47 * 微信支付 **/ @RestController @RequestMapping("/admin/wx") @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, origins = "*") public class PayWxController { private static final Logger log= LoggerFactory.getLogger(PayAliController.class); @Value("${merid}") private String merid;// 分配的商户号 @Value("${key}") private String key;// 商户号对应的密钥 @Value("${notifyUrl}") private String notifyUrl;// 用于接收回调通知的地 @Value("${noncestr}") private String noncestr;//随机参数 @Autowired private PayMapper payMapper; /*** * * @param paylogDo 订单信息: 用户id,支付金额,账号id * @param //address 加密经纬度 * @return */ /*@RequestMapping(value = "/payLog",method = RequestMethod.POST,produces = "application/json")*/ @PostMapping(value = "/payLog",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) @ApiOperation(value = "提交微信支付", notes = "true:提交成功,false:提交失败") public ResultBean Pay(@RequestBody Pay paylogDo){ //第三方接口-----换成自己的调用的第三方即可 String wxurl="https://alipay.3c-buy.com/api/createWxOrder"; Map paramMap = new HashMap(); //产生支付单号 SnowflakeIdWorker idWorker0 = new SnowflakeIdWorker(0, 0); String merchantOutOrderNo = idWorker0.nextId()+""; //订单时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String orderTime = sdf.format(new Date()); //商户 paramMap.put("merchantOutOrderNo",merchantOutOrderNo); paramMap.put("merid",merid); paramMap.put("noncestr",noncestr); paramMap.put("notifyUrl", notifyUrl); paramMap.put("orderMoney",paylogDo.getPayAmount().toString()); paramMap.put("orderTime",orderTime); //添加订单信息 Pay insertPayLogDO=new Pay(); insertPayLogDO.setUserId(paylogDo.getUserId()); insertPayLogDO.setAdminId(paylogDo.getAdminId());//账户id insertPayLogDO.setPayAmount(paylogDo.getPayAmount()); //金额 insertPayLogDO.setPayStatus(3);//支付状态:1-成功;2-失败;3-等待支付 insertPayLogDO.setPayType(2);//支付方式:1-支付宝;2-微信;3-银联 insertPayLogDO.setGmtCreate(new Date()); insertPayLogDO.setMerchantOutOrderNo(merchantOutOrderNo); //编号 payMapper.insertSelective(insertPayLogDO); String StringA= TestUtil.formatUrlMap(paramMap,false, false);//待签名串 String sign=TestUtil.getMD5(StringA+"&key="+key);//签名 //对参数按照key=value的格式,参照参数名ASCII码排序,并对value做utf-8的encode编码后得到字符串 param String param = TestUtil.formatUrlMap(paramMap, true, false); String url = wxurl + "?" + param + "&sign=" + sign + "&id=" + paylogDo.getUserId(); log.info("url-[{}]",url); //返回信息 ResultBean resultBean = new ResultBean<>(); resultBean.setData(url); resultBean.setCode(200); resultBean.setSuccess(true); resultBean.setMsg("微信支付"); return resultBean; } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/QiniuController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.service.QiniuService; import hacker.framework.common.request.ResultInfo; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; /** * 七牛云 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/10 9:54 */ @RestController @CrossOrigin(methods = { RequestMethod.GET, RequestMethod.POST,RequestMethod.PUT,RequestMethod.DELETE }, origins = "*") public class QiniuController { @Autowired private QiniuService qiniuService; @RequestMapping(value = "/upload", method = RequestMethod.POST) @ResponseBody @ApiOperation(value = "图片上传操作") public ResultInfo uploadImage(@RequestParam("file") MultipartFile file, HttpServletRequest request) { //文件上传到七牛云 ResultInfo res = new ResultInfo(); if(file.isEmpty()) { res.setMessage("文件不存在"); return res; } try { String url=qiniuService.saveImage(file); res.setStatus("0"); res.setMessage("文件上传成功"); res.setData(url); return res; } catch (Exception e) { e.printStackTrace(); res.setMessage("文件上传失败"); return res; } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/controller/RoleController.java ================================================ package hacker.channel.manage.controller; import hacker.channel.manage.service.RoleService; import hacker.framework.common.request.BaseCode; import hacker.framework.common.request.BaseResult; import hacker.framework.model.Cto.RolePermissions; import hacker.framework.model.entity.Role; import hacker.framework.util.CommontUtil; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; /** * 角色controller * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/3 14:14 */ @Slf4j @RestController @RequestMapping("/api") @CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, origins = "*") public class RoleController { @Autowired private RoleService roleService; @PostMapping("/addRole") @ApiOperation(value = "增加角色") public BaseResult createRole(@RequestBody Role role) { //创建时获取当前创建时间 role.setCreated_at(CommontUtil.getTimeStampTime()); try { roleService.add(role); return new BaseResult(BaseCode.SUCCESS.getCode(), "增加角色成功", 1); } catch (Exception e) { e.printStackTrace(); log.error("增加角色异常", e); return new BaseResult(BaseCode.FAIL.getCode(), "增加角色异常", 0); } } @PostMapping("/deleteRoleById") @ApiOperation(value = "根据角色id删除角色") public BaseResult deleteById(Integer id) { try { roleService.deleteById(id); log.info("删除角色成功"); return new BaseResult(BaseCode.SUCCESS.getCode(), "删除角色成功", 1); } catch (Exception e) { e.printStackTrace(); log.error("删除角色异常", e); return new BaseResult(BaseCode.FAIL.getCode(), "删除角色异常", 0); } } @PostMapping("/updateRole") @ApiOperation(value = "根据id去修改角色") public BaseResult updateRole(@RequestBody Role role) { //修改成功时获取当前修改时间 role.setUpdated_at(CommontUtil.getTimeStampTime()); try { roleService.updateRole(role); log.info("修改角色成功"); return new BaseResult(BaseCode.SUCCESS.getCode(), "修改角色成功", 1); } catch (Exception e) { e.printStackTrace(); log.error("修改角色异常", e); return new BaseResult(BaseCode.FAIL.getCode(), "修改角色异常", 0); } } @GetMapping("/listPermission") @ApiOperation(value = "根据角色id查询该角色下的权限列表") public BaseResult queryPermissionRole(Integer id){ //前端传来的参数 System.out.println(id); try { List> result = roleService.queryPermissionRole(id); log.info("查询完成"); return new BaseResult(BaseCode.SUCCESS.getCode(), "查询完成", result); } catch (Exception e) { e.printStackTrace(); log.error("查询角色权限异常", e); return new BaseResult(BaseCode.FAIL.getCode(), "查询角色权限异常", 0); } } @PostMapping("/allotPermission") @ApiOperation(value = "给某角色分配权限") public BaseResult allotPermission(@RequestBody RolePermissions rolePermissions) { //这里封装了rid和Pid在getObj方法中,前端传rid和pids-----》对应的多个pid try { roleService.allotRolePermissions(rolePermissions); log.info("分配权限成功"); return new BaseResult(BaseCode.SUCCESS.getCode(),"分配权限成功",1); } catch (Exception e) { e.printStackTrace(); log.error("分配权限异常",e); return new BaseResult(BaseCode.FAIL.getCode(), "分配权限异常", 0); } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/mapper/AdminMapper.java ================================================ package hacker.channel.manage.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import hacker.framework.model.Cto.AdminRoles; import hacker.framework.model.entity.Admin; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 17:34 */ @Repository @Mapper public interface AdminMapper extends BaseMapper { //通过用户名查询 Admin findByName(String username); //修改用户状态 int updateUserStatus(Admin user); //删除账户角色 void deleteAdminRole(Integer id); //调用了封装的obj方法 void setRoles(List obj); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/mapper/PayMapper.java ================================================ package hacker.channel.manage.mapper; import hacker.framework.model.entity.Pay; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; /** * 支付 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 13:41 */ @Mapper @Repository public interface PayMapper { //跟住id查询支付状态 Pay selectByPrimaryKey(Long key); //保存 int insertSelective(Pay record); //String Pay(String id, String orderMoney); //修改订单状态 int updateOrderStatus(Pay record); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/mapper/PermissionMapper.java ================================================ package hacker.channel.manage.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Permission; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.ResultType; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; /** * 权限 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:34 */ @Mapper @Repository public interface PermissionMapper extends BaseMapper { //查询用户id的权限 @Select({"select p.* from sun_permission p " , "join tb_role_permission rp on rp.permission_id = p.id " , "join tb_role r on r.id = rp.role_id " , "join tb_admin_role ar on ar.role_id = r.id " , "join tb_admin u on u.id = ar.admin_id " , "where u.id = #{user.id} and p.status = 1"}) List queryByUser(@Param("user") Admin user); //根据角色id查询该角色对应的所有权限 @Select({"select p.id, p.name,p.index_name, p.parent_id pid, p.display_name sName, p.is_show isShow ", "from tb_permission p ", "join tb_role_permission rp on p.id = rp.permission_id ", "join tb_role r on r.id = rp.role_id ", "where r.id = #{id} and p.status = 1 ", "order by pid"}) @ResultType(Map.class) List queryByRole(Integer id); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/mapper/RoleMapper.java ================================================ package hacker.channel.manage.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import hacker.framework.model.Cto.RolePermissions; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Role; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; /** * 角色 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 16:14 */ @Mapper @Repository public interface RoleMapper extends BaseMapper { //查询用户的角色 List queryRolesUser(Admin user); //删除角色对应的权限 void deleteRolePermission(Integer id); //删除账号角色 void deleteAdminRole(Integer id); //调用了封装的obj方法 void allotPermission(List obj); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/AdminService.java ================================================ package hacker.channel.manage.service; import hacker.framework.model.Cto.AdminRoles; import hacker.framework.model.entity.Admin; import javax.servlet.http.HttpServletRequest; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:34 */ public interface AdminService { /** * 通过用户名查询 * @param username 用户名 * @return 管理员用户 */ Admin findByName(String username); /** * 新建管理员用户 * @param user 用户参数 * @return */ int createNewAdmin(Admin user); /** * 修改用户状态 * @param user * @return */ int updateUserStatus(Admin user, HttpServletRequest request); /** * 根据id删除管理员 * @param id id * @return */ void deleteById(Integer id); /** * 为管理员分配角色 * @param adminRoles 在实体类封装了管理员id和所分配的角色id集合 */ void setRoles(AdminRoles adminRoles); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/PayService.java ================================================ package hacker.channel.manage.service; import hacker.framework.model.entity.Pay; /** * 支付 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 13:39 */ public interface PayService { /** * 支付 * @param * @param pay * @return */ String Pay(Pay pay); /** * 跟住用户id查询支付状态 * @param tradeNo * @return */ Pay findById(Long tradeNo); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/PermissionService.java ================================================ package hacker.channel.manage.service; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Permission; import java.util.List; /** * 权限 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:14 */ public interface PermissionService { /** * 查询用户的权限 * @param user 用户 * @return 权限 */ List queryByUser(Admin user); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/QiniuService.java ================================================ package hacker.channel.manage.service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; /** * 七牛云 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/10 9:44 */ public interface QiniuService { String saveImage(MultipartFile file) throws IOException; } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/RoleService.java ================================================ package hacker.channel.manage.service; import hacker.framework.model.Cto.RolePermissions; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Role; import java.util.List; import java.util.Map; /** * 角色 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 14:14 */ public interface RoleService { /** * 查询用户的角色 * @param user 用户 * @return 角色 */ List queryRolesUser(Admin user); /** * 增加角色 * @param role 角色 */ void add(Role role); /** * 根据id删除角色 * @param id id */ void deleteById(Integer id); /** * 根据id修改角色 * @param role role */ void updateRole(Role role); /** * 根据角色id查询权限 * @param id 角色id */ List> queryPermissionRole(Integer id); /** * 给某角色分配权限 * @param rolePermissions 参数封装 */ void allotRolePermissions(RolePermissions rolePermissions); } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/impl/AdminServiceImpl.java ================================================ package hacker.channel.manage.service.impl; import hacker.channel.manage.mapper.AdminMapper; import hacker.channel.manage.service.AdminService; import hacker.framework.model.Cto.AdminRoles; import hacker.framework.model.entity.Admin; import hacker.framework.util.CommontUtil; import hacker.framework.util.LuKeIp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.sql.Timestamp; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:34 */ @Service public class AdminServiceImpl implements AdminService { @Autowired private AdminMapper adminMapper; //查询用户名 @Override public Admin findByName(String username) { return adminMapper.findByName(username); } //新建管理员用户 @Override public int createNewAdmin(Admin user) { //map Map map = new HashMap<>(1); //username map.put("username",user.getUsername()); //查询 List admins = adminMapper.selectByMap(map); //如果已存在该用户名的用户,新建失败 if (null != admins && admins.size() > 0) { return -1; } else { //添加创建时间 user.setCreated_at(CommontUtil.getTimeStampTime()); //执行添加操作 System.out.println(user.getUsername()); //同步手机号和用户名,保持一致 user.setPhone(user.getUsername()); //调用添加方法 return adminMapper.insert(user); } } //修改用户状态 @Override public int updateUserStatus(Admin user, HttpServletRequest request) { //CommontUtil获取IP的格式是 0:0:0:0:0:0:0:1 Timestamp timestamp = CommontUtil.getTimeStampTime(); user.setLogin_at(timestamp); //获取登陆ip----》必须要调用自己的工具类,用java获取ip地址会出现问题,获取的ip将是 0:0:0:0:0:0:0:1---->调用工具类获取当前的登陆IP String ip = LuKeIp.getIpAddress(request); user.setLast_login_ip(ip); //token user.setLast_login_token(CommontUtil.getUUID()); return adminMapper.updateUserStatus(user); } //根据id删除管理员操作 @Override public void deleteById(Integer id) { //删除主键id adminMapper.deleteById(id); //删除账号角色 adminMapper.deleteAdminRole(id); } //为管理员分配角色 @Override public void setRoles(AdminRoles adminRoles) { List obj = adminRoles.getResult(); //给管理员分配角色时,先删除该管理员对应的所有角色,重新分配角色 adminMapper.deleteAdminRole(adminRoles.getUid()); //为管理员分配角色 adminMapper.setRoles(obj); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/impl/PayServiceImpl.java ================================================ package hacker.channel.manage.service.impl; import hacker.channel.manage.mapper.PayMapper; import hacker.channel.manage.service.PayService; import hacker.framework.model.entity.Pay; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import hacker.framework.util.SnowflakeIdWorker; import hacker.framework.util.TestUtil; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 支付 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi(walker) * @date 2019/6/4 13:40 */ @Service public class PayServiceImpl implements PayService { //配置 @Value("${merid}") private String merid;// 分配的商户号 @Value("${key}") private String key;// 商户号对应的密钥 @Value("${notifyUrl}") private String notifyUrl;// 用于接收回调通知的地 @Value("${noncestr}") private String noncestr;//随机参数 @Autowired private PayMapper payMapper; /** * 支付 * @author liuqi * @param pay * @return */ @Override public String Pay(Pay pay) { Map paraMap = new HashMap(); //产生支付单号 SnowflakeIdWorker idWorker0 = new SnowflakeIdWorker(0, 0); String merchantOutOrderNo = idWorker0.nextId()+""; //订单时间---格式yyyyMMddHHmmss SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String orderTime = sdf.format(new Date()); paraMap.put("merchantOutOrderNo", merchantOutOrderNo); paraMap.put("merid", merid); paraMap.put("noncestr", noncestr); paraMap.put("orderMoney", pay.getPayAmount().toString()); paraMap.put("orderTime", orderTime); paraMap.put("notifyUrl", notifyUrl); //添加订单信息 Pay insertPay=new Pay(); insertPay.setUserId(pay.getUserId()); insertPay.setAdminId(pay.getAdminId()); //账号id insertPay.setPayAmount(pay.getPayAmount()); //金额 insertPay.setPayStatus(3);//支付状态:1-成功;2-失败;3-等待支付 insertPay.setPayType(1);//支付方式:1-支付宝;2-微信;3-银联 insertPay.setGmtCreate(new Date()); insertPay.setMerchantOutOrderNo(merchantOutOrderNo); //订单编号 //调用添加的方法 payMapper.insertSelective(insertPay); //对参数按照 key=value 的格式,并参照参数名 ASCII 码排序后得到字符串 stringA String stringA = TestUtil.formatUrlMap(paraMap, false, false); //在stringA最后拼接上key得到stringsignTemp字符串,并对stringsignTemp进行MD5运算,得到sign值 String stringsignTemp = stringA + "&key=" + key; String sign = TestUtil.getMD5(stringsignTemp); //对参数按照key=value的格式,参照参数名ASCII码排序,并对value做utf-8的encode编码后得到字符串 param String param = TestUtil.formatUrlMap(paraMap, true, false); String payUrl = "https://alipay.3c-buy.com/api/createOrder";//这是H5调支付宝的路径 //将此URL送至APP前端页面或手机浏览器打开,即可自动调起支付宝(需要安装)发起支付 String url = payUrl + "?" + param + "&sign=" + sign + "&id=" + pay.getUserId(); return url; } /** * 跟住用户id查询支付状态 * @param tradeNo * @return */ @Override public Pay findById(Long tradeNo){ //商户订单号 return payMapper.selectByPrimaryKey(tradeNo); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/impl/PermissionServiceImpl.java ================================================ package hacker.channel.manage.service.impl; import hacker.channel.manage.mapper.PermissionMapper; import hacker.channel.manage.service.PermissionService; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Permission; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 权限 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:44 */ @Service public class PermissionServiceImpl implements PermissionService { @Autowired private PermissionMapper permissionMapper; //查询用户的权限 @Override public List queryByUser(Admin user) { return permissionMapper.queryByUser(user); } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/impl/QiniuServiceImpl.java ================================================ package hacker.channel.manage.service.impl; import com.alibaba.fastjson.JSONObject; import com.qiniu.common.QiniuException; import com.qiniu.common.Zone; import com.qiniu.http.Response; import com.qiniu.storage.Configuration; import com.qiniu.storage.UploadManager; import com.qiniu.util.Auth; import hacker.channel.manage.service.QiniuService; import hacker.framework.util.FileUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.UUID; /** * 七牛云 * * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/10 9:44 */ @Service public class QiniuServiceImpl implements QiniuService { private static final Logger logger = LoggerFactory.getLogger(QiniuServiceImpl.class); //设置好账号的ACCESS_KEY和SECRET_KEY //这里我就不放真实的账号了 String ACCESS_KEY = "XPzvjptibbtEy3eZHjra-RVcTIMTsdhVO"; String SECRET_KEY = "sKKfdLMhBJW9WjGesF71WztrX-VjaEt84"; // 要上传的空间 String bucketname = "wechat"; // 密钥配置 Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY); // 构造一个带指定Zone对象的配置类,不同的七云牛存储区域调用不同的zone Configuration cfg = new Configuration(Zone.zone0()); // ...其他参数参考类注释 UploadManager uploadManager = new UploadManager(cfg); // 测试域名,只有30天有效期-----》自己去调 private static String QINIU_IMAGE_DOMAIN = "http://t.wechat.mengpark.cn/"; // 简单上传,使用默认策略,只需要设置上传的空间名就可以了 public String getUpToken() { return auth.uploadToken(bucketname); } public String saveImage(MultipartFile file) throws IOException { try { int dotPos = file.getOriginalFilename().lastIndexOf("."); if (dotPos < 0) { return null; } String fileExt = file.getOriginalFilename().substring(dotPos + 1).toLowerCase(); // 判断是否是合法的文件后缀 if (!FileUtil.isFileAllowed(fileExt)) { return null; } String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + fileExt; // 调用put方法上传 Response res = uploadManager.put(file.getBytes(), fileName, getUpToken()); // 打印返回的信息 if (res.isOK() && res.isJson()) { // 返回这张存储照片的地址 return QINIU_IMAGE_DOMAIN + JSONObject.parseObject(res.bodyString()).get("key"); } else { logger.error("七牛云异常1"+ res.bodyString()); return null; } } catch (QiniuException e) { // 请求失败时打印的异常的信息 logger.error("七牛云异常2" + e.getMessage()); return null; } } } ================================================ FILE: hacker-service-channel-manage/src/main/java/hacker/channel/manage/service/impl/RoleServiceImpl.java ================================================ package hacker.channel.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import hacker.channel.manage.mapper.PermissionMapper; import hacker.channel.manage.mapper.RoleMapper; import hacker.channel.manage.service.RoleService; import hacker.framework.model.Cto.RolePermissions; import hacker.framework.model.entity.Admin; import hacker.framework.model.entity.Role; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 角色 * @Description: J X N H * @EnglishName LuKe * @authod LiuQi * @date 2019/6/3 15:24 */ @Service public class RoleServiceImpl implements RoleService { @Autowired private RoleMapper roleMapper; @Autowired private PermissionMapper permissionMapper; //查询用户的角色 @Override public List queryRolesUser(Admin user) { return roleMapper.queryRolesUser(user); } //增加角色 @Override public void add(Role role) { roleMapper.insert(role); } //根据id删除角色 @Override public void deleteById(Integer id) { //要删除角色,先删除角色<---->权限关系,角色<---->用户关系 roleMapper.deleteRolePermission(id); roleMapper.deleteAdminRole(id); roleMapper.deleteById(id); } //根据id修改角色 @Override public void updateRole(Role role) { roleMapper.updateById(role); } //根据角色id查询权限 @Override public List> queryPermissionRole(Integer id) { //存放该角色所拥有的权限id List ids = new ArrayList<>(12); //存放一级权限的id和在result中的索引值 Map keys = new HashMap<>(16); //总的返回值 List> result = new ArrayList<>(12); //根据角色id查询该角色对应的所有权限--->map List maps = permissionMapper.queryByRole(id); QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("status", 1); //------------>对应数据库权限的状态,查询为禁用的数据 //根据 Wrapper 条件,查询全部 List> maps1 = permissionMapper.selectMaps(wrapper); //将该角色有的权限id拿出来 maps.forEach(map -> { Long pid = (Long) map.get("id"); ids.add(pid); }); //遍历所有的权限,取出一级,如果是该角色有的,做上私人标记-----------》有对应的权限会带上标记 maps1.forEach(map -> { Long pid = (Long) map.get("id"); if (ids.contains(pid)) { map.put("selected", 1); } Integer parentId = (Integer) map.get("parentId"); //----------》父类id等于0,就是最高权限---->一级权限 //筛选出一级权限 if (0 == parentId) { //将一级权限先放入返回值中 result.add(map); //一级权限id和索引放入map keys.put(pid.toString(), result.size() - 1); } }); //遍历二级,组装到一级下-----------》没有对应的权限不会带上标记,但是也会全部显示出来 maps1 .stream() //过滤掉一级 .filter(map -> (Integer) map.get("parentId") != 0) .forEach(map -> { Integer parentId = (Integer) map.get("parentId"); Integer i = (Integer) keys.get(parentId.toString()); Map parent = result.get(i); //根据二级权限的父节点id进行组装 List> children = (List>) parent.get("children"); if (null == children) { children = new ArrayList<>(); parent.put("children", children); } children.add(map); }); return result; } //给某角色分配权限 @Override public void allotRolePermissions(RolePermissions rolePermissions) { //给角色分配权限时,先删除该角色的所有权限,重新分配权限 roleMapper.deleteRolePermission(rolePermissions.getRid()); //给某角色分配权限 roleMapper.allotPermission(rolePermissions.getObj()); } } ================================================ FILE: hacker-service-channel-manage/src/main/resources/application.properties ================================================ ## server 端口 server.port=8888 server.host=localhost server.tomcat.uri-encoding=UTF-8 ## mybatis-plus 开启sql显示 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.slf4j.Slf4jImpl #数据库-----》JXNH------》这里没有换成我服务器的数据库,后面会用脚本代替 spring.datasource.url=jdbc:mysql://localhost:3306/jinnian?serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.max-idle=10 spring.datasource.max-wait=10000 spring.datasource.min-idle=5 spring.datasource.initial-size=5 #mapperXml------------->同一目录不用加 #mybatis.mapper-locations=classpath:mapper/*.xml #mybatis.config-location=classpath:mybatis-config.xml #日志生成-----》用的spring boot默认log back日志------》默认生成到本地 #debug=false #log.path=C:/logs/jn #logging.config=classpath:logback.xml # Date Convert spring.jackson.date-format=yyyy-MM-dd hh:mm:ss spring.jackson.time-zone=GMT+8 ## 文件上传支持 spring.servlet.multipart.enabled=true ## 最大文件大小 spring.servlet.multipart.max-file-size=10MB #全局变量信息,密钥 token=dy$UpUp secret=5087D91C818EE6E9 ## 密码加密所用盐 salt=Jhuiabn9_DhiebFIJ==jel%$dafe4fs@deaerf_ ## netty websocket 配置 #netty-websocket.host=0.0.0.0 netty-websocket.path=/websocket netty-websocket.port=80 ## thymeleaf模板引擎 spring.thymeleaf.cache=false spring.thymeleaf.encoding=utf-8 #支付参数 回调本地内网穿透测试 #分配的商户号---请输入自己的或者公司提供的商户号,我这里是不可用的 merid=2088912840264143962 #商户号对应的密钥 ------》输入自己对应的 key=if1Q15rGf2rOMYGmsiUkKRzbKb0s9zw6Jt #用于接收回调通知的地址 alipay.3c-buy.com替换为自己的地址 notifyUrl=http://www.wuxf.cn:8888/api/channel/notify/callback #随机参数 noncestr=jxnh #支付完成跳转页面 https://github.com/Liu777替换为自己要跳转的地址 returnUrl= #二级商户名称 银联页面显示的商户名称,不填则默认。(请保证该名称已在一麻袋后台的二级商户名称中添加,并通过白名单审核,否则会报“二级商户名称不合法”) subMerchantName= ================================================ FILE: hacker-service-channel-manage/src/main/resources/banner.txt ================================================ ${AnsiColor.YELLOW}Hello,Welcome to boot...${AnsiColor.RED}Sprin${AnsiColor.BRIGHT_YELLOW}gBoot的${AnsiColor.BRIGHT_GREEN}版本号:${AnsiColor.RED}${AnsiColor.MAGENTA} ${spring-boot.formatted-version} 项目制作人:LuKe(walker) 博客网站:https://www.wuxf.cn ${AnsiColor.BRIGHT_YELLOW} __ __ ______ .______ _______ | | | | / __ \ | _ \ | ____|${AnsiColor.YELLOW} | |__| | | | | | | |_) | | |__ ${AnsiColor.BRIGHT_GREEN} | __ | | | | | | ___/ | __| ${AnsiColor.BRIGHT_CYAN} | | | | | `--' | | | | |____ ${AnsiColor.BLUE} |__| |__| \______/ | _| |_______|${AnsiColor.MAGENTA} ${AnsiColor.MAGENTA}2019年,祝每一个努力的人都有所收获。人生路上,泪水在左,欢笑在右,生命的鲜花铺满两旁。 走过生命的四季,我们经历了泪水的洗礼,见证了欢笑的时刻,欣赏着朝阳的升起,凝视着花蕊的绽放。 人生途中,我们收获着生命之神不尽的惠赠,满揣着她的礼物与祝福启程。一路走来,因为收获,我们不曾寒冷,我们从未孤独。 ${AnsiColor.DEFAULT} ================================================ FILE: hacker-service-channel-manage/src/main/resources/ehcache.xml ================================================ ================================================ FILE: hacker-service-channel-manage/src/main/resources/hacker/channel/manage/mapper/AdminMapper.xml ================================================ UPDATE tb_admin SET last_login_ip = #{last_login_ip}, last_login_token = #{last_login_token}, login_at = #{login_at} WHERE id = #{id} delete from tb_admin_role where admin_id = #{id} INSERT INTO tb_admin_role (admin_id, role_id) VALUES (#{item.uid},#{item.role}) ================================================ FILE: hacker-service-channel-manage/src/main/resources/hacker/channel/manage/mapper/PayMapper.xml ================================================ insert into tb_pay tradeNo, userId, adminId, payTime, payAmount, payStatus, payType, gmtCreate, merchantOutOrderNo, #{tradeNo,jdbcType=BIGINT}, #{userId,jdbcType=INTEGER}, #{adminId,jdbcType=INTEGER}, #{payTime,jdbcType=TIMESTAMP}, #{payAmount,jdbcType=DECIMAL}, #{payStatus,jdbcType=INTEGER}, #{payType,jdbcType=INTEGER}, #{gmtCreate,jdbcType=TIMESTAMP}, #{merchantOutOrderNo,jdbcType=VARCHAR}, update tb_paylog userId = #{userId,jdbcType=INTEGER}, adminId = #{adminId,jdbcType=INTEGER}, payTime = #{payTime,jdbcType=TIMESTAMP}, payAmount = #{payAmount,jdbcType=DECIMAL}, payStatus = #{payStatus,jdbcType=INTEGER}, payType = #{payType,jdbcType=INTEGER}, gmtCreate = #{gmtCreate,jdbcType=TIMESTAMP}, where merchantOutOrderNo = #{merchantOutOrderNo,jdbcType=BIGINT} ================================================ FILE: hacker-service-channel-manage/src/main/resources/hacker/channel/manage/mapper/RoleMapper.xml ================================================ delete from tb_role_permission where role_id = #{id} delete from tb_admin_role where role_id = #{id} insert into tb_role_permission (permission_id, role_id) values (#{item.pid},#{item.rid}) ================================================ FILE: hacker-service-channel-manage/src/main/resources/logback.xml ================================================ logback WARN %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n ${log.path} ${log.path}.%d{yyyy-MM-dd}.zip %date %level [%thread] %logger{36} [%file : %line] %msg%n ================================================ FILE: hacker-service-channel-manage/src/main/resources/static/css/htshouye.css ================================================ * { padding: 0; margin: 0; } a { text-decoration: none; } li{ list-style: none; } input::-webkit-input-placeholder { text-indent: 10px; } input{ text-indent: 10px; } html, body { width: 100%; height: 100%; } .boxMax { width: 100%; height: 100%; box-sizing: border-box; position: relative; padding-top: 47px; min-height: 715px; min-width: 1250px; } .title { width: 100%; height: 47px; background-color: #0F0930; line-height: 47px; position: fixed; top: 0; left: 0; z-index: 799; } .title>a { margin-left: 20px; color: rgb(180, 188, 200); } .titleRight { width: 120px; height: 47px; line-height: 47px; float: right; margin-right: 20px; cursor: pointer; } .titleRight:hover { background-color: rgb(63, 79, 98); } .titleRight>img { border-radius: 50%; vertical-align: middle; margin-left: 10px; } .titleRight>span { display: inline-block; width: 58px; height: 100%; line-height: 47px; color: rgb(180, 188, 200); font-size: 14px; margin-left: 5px; } .arrowUp:after { content: ''; display: inline-block; width: 8px; height: 8px; border-right: 1px solid #a7b1c2; border-bottom: 1px solid #a7b1c2; transform: rotate(-45deg); -webkit-transform: rotate(-45deg); float: right; margin-top: 20px; } .arrowDown:after { content: ''; display: inline-block; width: 6px; height: 6px; border-bottom: 1px solid #a7b1c2; border-right: 1px solid #a7b1c2; transform: rotate(45deg); -webkit-transform: rotate(45deg); float: right; margin-top: 20px; } .titleNone { width: 118px; height: 35px; display: none; margin-top: -1px; border: 1px solid rgb(180, 180, 180); background-color:white; } .titleNone>ul>li{ height: 35px; line-height: 35px; } .titleNone>ul>li:hover { background-color: rgb(242, 242, 242); } .titleNone>ul>li>a { color: black; font-size: 14px; margin-left: 33px; } .menu { width: 220px; min-height: 100%; height: auto; background-color: #272C4F; float: left; } .menu>li { width: 100%; border-top: 1px solid rgb(61, 73, 87); text-align: center; position: relative; } .menu>li>img{ position: absolute; top: 12px; left: 30px; } .menuSpan:hover { background-color: rgb(44, 53, 66); } .menuSpan { display: inline-block; width: 100%; height: 40px; line-height: 40px; cursor: pointer; color: #a7b1c2; } .menuSpan:after { content: ''; display: inline-block; width: 8px; height: 8px; border-right: 1px solid #a7b1c2; border-bottom: 1px solid #a7b1c2; transform: rotate(-45deg); -webkit-transform: rotate(-45deg); float: right; margin-top: 15px; margin-right: 20px; } .menuSpan2:after { content: ''; display: inline-block; width: 8px; height: 8px; border-right: 1px solid #a7b1c2; border-bottom: 1px solid #a7b1c2; transform: rotate(45deg); -webkit-transform: rotate(45deg); float: right; margin-top: 15px; margin-right: 20px; } .minMenu { display: none; } .minMenu>li { width: 100%; height: 40px; line-height: 40px; text-align: center; cursor: pointer; } .minMenu>li:hover{ background-color:rgb(62,75,92); } .minMenu>li>a{ display: inline-block; width: 100%; height: 100%; color: #a7b1c2; } .clearfix:after { content: ""; height: 0; line-height: 0; display: block; visibility: hidden; clear: both; } ================================================ FILE: hacker-service-channel-manage/src/main/resources/static/js/base.js ================================================ //适配兼容 (function (doc, win) { var docEle = doc.documentElement, dpr = Math.min(win.devicePixelRatio, 3), scale = 1 / dpr, resizeEvent = 'orientationchange' in window ? 'orientationchange' : 'resize'; var metaEle = doc.createElement('meta'); metaEle.name = 'viewport'; metaEle.content = 'initial-scale=' + scale + ',maximum-scale=' + scale; docEle.firstElementChild.appendChild(metaEle); var recalCulate = function () { var width = docEle.clientWidth; docEle.style.fontSize = 100 * (width / 375) + 'px'; }; recalCulate(); if (!doc.addEventListener) return; win.addEventListener(resizeEvent, recalCulate, false); })(document, window); ================================================ FILE: hacker-service-channel-manage/src/main/resources/templates/dr.html ================================================ 登陆

堇夏年华

你若不离不弃,我必生死相依


================================================ FILE: hacker-service-channel-manage/src/main/resources/templates/error/010.html ================================================

0 1 0

sorry,您无权访问...
您可以返回主页看看
主页
================================================ FILE: hacker-service-channel-manage/src/main/resources/templates/error/404.html ================================================

404

页面未找到!

抱歉,页面好像去火星了~
================================================ FILE: hacker-service-channel-manage/src/main/resources/templates/error/500.html ================================================

500

服务器内部错误

服务器好像出错了...
您可以返回主页看看
主页
================================================ FILE: hacker-service-channel-manage/src/main/resources/templates/qdst.html ================================================ 主页
用户ID 登陆名称 用户名名称 用户状态 创建时间 操作
  • 用户ID
  • 登陆名称
  • 用户名名称
  • 用户状态
复制成功
================================================ FILE: pom.xml ================================================ 4.0.0 Hacker.walker Hacker-walker-cloud pom 1.0-SNAPSHOT Hacker-walker-cloud Hacker-framework-model Hacker-framework-common Hacker-framework-util Hacker-service-channel-manage Hacker-govern-center Hacker-govern-gateway walker开源作品 个人博客:https://wuxf.cn 微信公众号:堇夏年华 LuKe walker a18627830855@163.com https://wuxf.cn org.springframework.boot spring-boot-starter-parent 2.0.7.RELEASE UTF-8 UTF-8 1.8 2.0.7.RELEASE 2.9.2 org.springframework.boot spring-boot-starter 2.1.5.RELEASE org.springframework.boot spring-boot-starter-test 2.1.5.RELEASE org.springframework.boot spring-boot-starter-web 2.1.4.RELEASE org.projectlombok lombok 1.18.8 org.aspectj aspectjweaver 1.9.2 io.springfox springfox-swagger2 ${springfox-swagger.version} io.springfox springfox-swagger-ui ${springfox-swagger.version} com.alibaba fastjson 1.2.54 com.baomidou mybatis-plus-boot-starter 3.1.1 org.apache.commons commons-lang3 3.8 com.qiniu qiniu-java-sdk [7.2.0, 7.2.99] com.squareup.okhttp3 okhttp 3.3.1 compile com.google.code.gson gson 2.6.2 compile com.qiniu happy-dns-java 0.1.4 compile mysql mysql-connector-java 8.0.15 org.springframework.boot spring-boot-starter-data-redis 2.1.4.RELEASE commons-codec commons-codec 1.12 org.apache.shiro shiro-ehcache 1.4.1 org.yeauty netty-websocket-spring-boot-starter 0.6.5 org.apache.shiro shiro-spring 1.3.2 com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0 org.springframework.boot spring-boot-starter-thymeleaf src/main/resources true org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 UTF-8 org.apache.maven.plugins maven-source-plugin org.apache.maven.plugins maven-archetype-plugin org.apache.maven.plugins maven-surefire-plugin true aliyun-repos http://maven.aliyun.com/nexus/content/groups/public/ false aliyun-plugin http://maven.aliyun.com/nexus/content/groups/public/ false