diff --git a/pom.xml b/pom.xml
index 79e2925..25e235d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,5 +16,6 @@
mall-coupon
mall-order
mall-product
+ renren-fast-master
diff --git a/renren-fast-master/.gitignore b/renren-fast-master/.gitignore
new file mode 100644
index 0000000..dd851b6
--- /dev/null
+++ b/renren-fast-master/.gitignore
@@ -0,0 +1,25 @@
+# Compiled class file
+*.class
+target
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+*.iml
+.idea
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
diff --git a/renren-fast-master/Dockerfile b/renren-fast-master/Dockerfile
new file mode 100644
index 0000000..2f0c477
--- /dev/null
+++ b/renren-fast-master/Dockerfile
@@ -0,0 +1,7 @@
+FROM java:8
+EXPOSE 8080
+
+VOLUME /tmp
+ADD renren-fast.jar /app.jar
+RUN bash -c 'touch /app.jar'
+ENTRYPOINT ["java","-jar","/app.jar"]
diff --git a/renren-fast-master/LICENSE b/renren-fast-master/LICENSE
new file mode 100644
index 0000000..0148aba
--- /dev/null
+++ b/renren-fast-master/LICENSE
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "{}" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright 2019 人人开源
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/renren-fast-master/README.md b/renren-fast-master/README.md
new file mode 100644
index 0000000..53dd2ed
--- /dev/null
+++ b/renren-fast-master/README.md
@@ -0,0 +1,116 @@
+**项目说明**
+- renren-fast是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付【接私活利器】
+- 支持MySQL、Oracle、SQL Server、PostgreSQL等主流数据库
+- 前端地址:https://gitee.com/renrenio/renren-fast-vue
+- 代码生成器:https://gitee.com/renrenio/renren-generator
+
+
+
+
+**具有如下特点**
+- 友好的代码结构及注释,便于阅读及二次开发
+- 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术
+- 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求
+- 页面交互使用Vue2.x,极大的提高了开发效率
+- 完善的代码生成机制,可在线生成entity、xml、dao、service、vue、sql代码,减少70%以上的开发任务
+- 引入quartz定时任务,可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能
+- 引入API模板,根据token作为登录令牌,极大的方便了APP接口开发
+- 引入Hibernate Validator校验框架,轻松实现后端校验
+- 引入云存储服务,已支持:七牛云、阿里云、腾讯云等
+- 引入swagger文档支持,方便编写API接口文档
+
+
+**项目结构**
+```
+renren-fast
+├─db 项目SQL语句
+│
+├─common 公共模块
+│ ├─aspect 系统日志
+│ ├─exception 异常处理
+│ ├─validator 后台校验
+│ └─xss XSS过滤
+│
+├─config 配置信息
+│
+├─modules 功能模块
+│ ├─app API接口模块(APP调用)
+│ ├─job 定时任务模块
+│ ├─oss 文件服务模块
+│ └─sys 权限模块
+│
+├─RenrenApplication 项目启动类
+│
+├──resources
+│ ├─mapper SQL对应的XML文件
+│ └─static 静态资源
+
+```
+
+
+**如何交流、反馈、参与贡献?**
+- 开发文档:https://www.renren.io/guide
+- Git仓库:https://gitee.com/renrenio/renren-fast
+- [人人开源社区](https://www.renren.io/community):https://www.renren.io/community
+- 官方QQ群:324780204、145799952
+- 技术讨论、二次开发等咨询、问题和建议,请移步到人人开源社区,我会在第一时间进行解答和回复!
+- 如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持
+- 微信扫码并关注【人人开源】,获得项目最新动态及更新提醒
+
+
+
+
+
+
+
+
+**技术选型:**
+- 核心框架:Spring Boot 2.1
+- 安全框架:Apache Shiro 1.4
+- 视图框架:Spring MVC 5.0
+- 持久层框架:MyBatis 3.3
+- 定时器:Quartz 2.3
+- 数据库连接池:Druid 1.0
+- 日志管理:SLF4J 1.7、Log4j
+- 页面交互:Vue2.x
+
+
+
+ **后端部署**
+- 通过git下载源码
+- idea、eclipse需安装lombok插件,不然会提示找不到entity的get set方法
+- 创建数据库renren_fast,数据库编码为UTF-8
+- 执行db/mysql.sql文件,初始化数据
+- 修改application-dev.yml,更新MySQL账号和密码
+- Eclipse、IDEA运行RenrenApplication.java,则可启动项目
+- Swagger文档路径:http://localhost:8080/renren-fast/swagger/index.html
+- Swagger注解路径:http://localhost:8080/renren-fast/swagger-ui.html
+
+
+
+ **前端部署**
+ - 本项目是前后端分离的,还需要部署前端,才能运行起来
+ - 前端下载地址:https://gitee.com/renrenio/renren-fast-vue
+ - 前端部署文档:https://gitee.com/renrenio/renren-fast-vue/wikis/Home
+ - 前端部署完毕,就可以访问项目了,账号:admin,密码:admin
+
+
+
+ **项目演示**
+- 演示地址:http://demo.open.renren.io/renren-fast
+- 账号密码:admin/admin
+
+
+**接口文档效果图:**
+
+
+
+
+
+**效果图:**
+
+
+
+
+
+
diff --git a/renren-fast-master/db/mysql.sql b/renren-fast-master/db/mysql.sql
new file mode 100644
index 0000000..be1caef
--- /dev/null
+++ b/renren-fast-master/db/mysql.sql
@@ -0,0 +1,356 @@
+-- 菜单
+CREATE TABLE `sys_menu` (
+ `menu_id` bigint NOT NULL AUTO_INCREMENT,
+ `parent_id` bigint COMMENT '父菜单ID,一级菜单为0',
+ `name` varchar(50) COMMENT '菜单名称',
+ `url` varchar(200) COMMENT '菜单URL',
+ `perms` varchar(500) COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
+ `type` int COMMENT '类型 0:目录 1:菜单 2:按钮',
+ `icon` varchar(50) COMMENT '菜单图标',
+ `order_num` int COMMENT '排序',
+ PRIMARY KEY (`menu_id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='菜单管理';
+
+-- 系统用户
+CREATE TABLE `sys_user` (
+ `user_id` bigint NOT NULL AUTO_INCREMENT,
+ `username` varchar(50) NOT NULL COMMENT '用户名',
+ `password` varchar(100) COMMENT '密码',
+ `salt` varchar(20) COMMENT '盐',
+ `email` varchar(100) COMMENT '邮箱',
+ `mobile` varchar(100) COMMENT '手机号',
+ `status` tinyint COMMENT '状态 0:禁用 1:正常',
+ `create_user_id` bigint(20) COMMENT '创建者ID',
+ `create_time` datetime COMMENT '创建时间',
+ PRIMARY KEY (`user_id`),
+ UNIQUE INDEX (`username`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统用户';
+
+-- 系统用户Token
+CREATE TABLE `sys_user_token` (
+ `user_id` bigint(20) NOT NULL,
+ `token` varchar(100) NOT NULL COMMENT 'token',
+ `expire_time` datetime DEFAULT NULL COMMENT '过期时间',
+ `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+ PRIMARY KEY (`user_id`),
+ UNIQUE KEY `token` (`token`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统用户Token';
+
+-- 系统验证码
+CREATE TABLE `sys_captcha` (
+ `uuid` char(36) NOT NULL COMMENT 'uuid',
+ `code` varchar(6) NOT NULL COMMENT '验证码',
+ `expire_time` datetime DEFAULT NULL COMMENT '过期时间',
+ PRIMARY KEY (`uuid`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统验证码';
+
+-- 角色
+CREATE TABLE `sys_role` (
+ `role_id` bigint NOT NULL AUTO_INCREMENT,
+ `role_name` varchar(100) COMMENT '角色名称',
+ `remark` varchar(100) COMMENT '备注',
+ `create_user_id` bigint(20) COMMENT '创建者ID',
+ `create_time` datetime COMMENT '创建时间',
+ PRIMARY KEY (`role_id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='角色';
+
+-- 用户与角色对应关系
+CREATE TABLE `sys_user_role` (
+ `id` bigint NOT NULL AUTO_INCREMENT,
+ `user_id` bigint COMMENT '用户ID',
+ `role_id` bigint COMMENT '角色ID',
+ PRIMARY KEY (`id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='用户与角色对应关系';
+
+-- 角色与菜单对应关系
+CREATE TABLE `sys_role_menu` (
+ `id` bigint NOT NULL AUTO_INCREMENT,
+ `role_id` bigint COMMENT '角色ID',
+ `menu_id` bigint COMMENT '菜单ID',
+ PRIMARY KEY (`id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='角色与菜单对应关系';
+
+-- 系统配置信息
+CREATE TABLE `sys_config` (
+ `id` bigint NOT NULL AUTO_INCREMENT,
+ `param_key` varchar(50) COMMENT 'key',
+ `param_value` varchar(2000) COMMENT 'value',
+ `status` tinyint DEFAULT 1 COMMENT '状态 0:隐藏 1:显示',
+ `remark` varchar(500) COMMENT '备注',
+ PRIMARY KEY (`id`),
+ UNIQUE INDEX (`param_key`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统配置信息表';
+
+
+-- 系统日志
+CREATE TABLE `sys_log` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `username` varchar(50) COMMENT '用户名',
+ `operation` varchar(50) COMMENT '用户操作',
+ `method` varchar(200) COMMENT '请求方法',
+ `params` varchar(5000) COMMENT '请求参数',
+ `time` bigint NOT NULL COMMENT '执行时长(毫秒)',
+ `ip` varchar(64) COMMENT 'IP地址',
+ `create_date` datetime COMMENT '创建时间',
+ PRIMARY KEY (`id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统日志';
+
+
+-- 文件上传
+CREATE TABLE `sys_oss` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `url` varchar(200) COMMENT 'URL地址',
+ `create_date` datetime COMMENT '创建时间',
+ PRIMARY KEY (`id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='文件上传';
+
+
+-- 定时任务
+CREATE TABLE `schedule_job` (
+ `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务id',
+ `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
+ `params` varchar(2000) DEFAULT NULL COMMENT '参数',
+ `cron_expression` varchar(100) DEFAULT NULL COMMENT 'cron表达式',
+ `status` tinyint(4) DEFAULT NULL COMMENT '任务状态 0:正常 1:暂停',
+ `remark` varchar(255) DEFAULT NULL COMMENT '备注',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ PRIMARY KEY (`job_id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='定时任务';
+
+-- 定时任务日志
+CREATE TABLE `schedule_job_log` (
+ `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志id',
+ `job_id` bigint(20) NOT NULL COMMENT '任务id',
+ `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称',
+ `params` varchar(2000) DEFAULT NULL COMMENT '参数',
+ `status` tinyint(4) NOT NULL COMMENT '任务状态 0:成功 1:失败',
+ `error` varchar(2000) DEFAULT NULL COMMENT '失败信息',
+ `times` int(11) NOT NULL COMMENT '耗时(单位:毫秒)',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ PRIMARY KEY (`log_id`),
+ KEY `job_id` (`job_id`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='定时任务日志';
+
+
+
+-- 用户表
+CREATE TABLE `tb_user` (
+ `user_id` bigint NOT NULL AUTO_INCREMENT,
+ `username` varchar(50) NOT NULL COMMENT '用户名',
+ `mobile` varchar(20) NOT NULL COMMENT '手机号',
+ `password` varchar(64) COMMENT '密码',
+ `create_time` datetime COMMENT '创建时间',
+ PRIMARY KEY (`user_id`),
+ UNIQUE INDEX (`username`)
+) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='用户';
+
+
+
+
+
+
+-- 初始数据
+INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `create_user_id`, `create_time`) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11');
+
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7);
+INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6);
+
+INSERT INTO `sys_config` (`param_key`, `param_value`, `status`, `remark`) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{\"aliyunAccessKeyId\":\"\",\"aliyunAccessKeySecret\":\"\",\"aliyunBucketName\":\"\",\"aliyunDomain\":\"\",\"aliyunEndPoint\":\"\",\"aliyunPrefix\":\"\",\"qcloudBucketName\":\"\",\"qcloudDomain\":\"\",\"qcloudPrefix\":\"\",\"qcloudSecretId\":\"\",\"qcloudSecretKey\":\"\",\"qiniuAccessKey\":\"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ\",\"qiniuBucketName\":\"ios-app\",\"qiniuDomain\":\"http://7xqbwh.dl1.z0.glb.clouddn.com\",\"qiniuPrefix\":\"upload\",\"qiniuSecretKey\":\"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV\",\"type\":1}', '0', '云存储配置信息');
+INSERT INTO `schedule_job` (`bean_name`, `params`, `cron_expression`, `status`, `remark`, `create_time`) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', now());
+
+
+-- 账号:13612345678 密码:admin
+INSERT INTO `tb_user` (`username`, `mobile`, `password`, `create_time`) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41');
+
+
+
+
+
+
+
+
+-- quartz自带表结构
+CREATE TABLE QRTZ_JOB_DETAILS(
+SCHED_NAME VARCHAR(120) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+IS_DURABLE VARCHAR(1) NOT NULL,
+IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+NEXT_FIRE_TIME BIGINT(13) NULL,
+PREV_FIRE_TIME BIGINT(13) NULL,
+PRIORITY INTEGER NULL,
+TRIGGER_STATE VARCHAR(16) NOT NULL,
+TRIGGER_TYPE VARCHAR(8) NOT NULL,
+START_TIME BIGINT(13) NOT NULL,
+END_TIME BIGINT(13) NULL,
+CALENDAR_NAME VARCHAR(200) NULL,
+MISFIRE_INSTR SMALLINT(2) NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+REPEAT_COUNT BIGINT(7) NOT NULL,
+REPEAT_INTERVAL BIGINT(12) NOT NULL,
+TIMES_TRIGGERED BIGINT(10) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+CRON_EXPRESSION VARCHAR(120) NOT NULL,
+TIME_ZONE_ID VARCHAR(80),
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+ (
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ STR_PROP_1 VARCHAR(512) NULL,
+ STR_PROP_2 VARCHAR(512) NULL,
+ STR_PROP_3 VARCHAR(512) NULL,
+ INT_PROP_1 INT NULL,
+ INT_PROP_2 INT NULL,
+ LONG_PROP_1 BIGINT NULL,
+ LONG_PROP_2 BIGINT NULL,
+ DEC_PROP_1 NUMERIC(13,4) NULL,
+ DEC_PROP_2 NUMERIC(13,4) NULL,
+ BOOL_PROP_1 VARCHAR(1) NULL,
+ BOOL_PROP_2 VARCHAR(1) NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+BLOB_DATA BLOB NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_CALENDARS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+CALENDAR_NAME VARCHAR(200) NOT NULL,
+CALENDAR BLOB NOT NULL,
+PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+ENTRY_ID VARCHAR(95) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+FIRED_TIME BIGINT(13) NOT NULL,
+SCHED_TIME BIGINT(13) NOT NULL,
+PRIORITY INTEGER NOT NULL,
+STATE VARCHAR(16) NOT NULL,
+JOB_NAME VARCHAR(200) NULL,
+JOB_GROUP VARCHAR(200) NULL,
+IS_NONCONCURRENT VARCHAR(1) NULL,
+REQUESTS_RECOVERY VARCHAR(1) NULL,
+PRIMARY KEY (SCHED_NAME,ENTRY_ID))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+SCHED_NAME VARCHAR(120) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE QRTZ_LOCKS (
+SCHED_NAME VARCHAR(120) NOT NULL,
+LOCK_NAME VARCHAR(40) NOT NULL,
+PRIMARY KEY (SCHED_NAME,LOCK_NAME))
+ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
+
+CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
+CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
+CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
diff --git a/renren-fast-master/db/oracle.sql b/renren-fast-master/db/oracle.sql
new file mode 100644
index 0000000..56c23e5
--- /dev/null
+++ b/renren-fast-master/db/oracle.sql
@@ -0,0 +1,346 @@
+-- 菜单
+CREATE TABLE sys_menu (
+ menu_id NUMBER(20, 0) NOT NULL,
+ parent_id NUMBER(20, 0) NOT NULL,
+ name varchar2(50),
+ url varchar2(200),
+ perms varchar2(500),
+ type NUMBER(2, 0),
+ icon varchar2(50),
+ order_num NUMBER(8, 0),
+ PRIMARY KEY (menu_id)
+);
+
+-- 系统用户
+CREATE TABLE sys_user (
+ user_id NUMBER(20, 0) NOT NULL,
+ username varchar2(50) NOT NULL,
+ password varchar2(100),
+ salt varchar2(20),
+ email varchar2(100),
+ mobile varchar2(100),
+ status NUMBER(2, 0) NOT NULL,
+ create_user_id NUMBER(20, 0) NOT NULL,
+ create_time timestamp,
+ PRIMARY KEY (user_id)
+);
+CREATE UNIQUE INDEX index_sys_user_username on sys_user(username);
+
+-- 系统用户Token
+CREATE TABLE sys_user_token (
+ user_id NUMBER(20, 0) NOT NULL,
+ token varchar2(100) NOT NULL,
+ expire_time timestamp,
+ update_time timestamp,
+ PRIMARY KEY (user_id)
+);
+CREATE UNIQUE INDEX index_token on sys_user_token(token);
+
+-- 系统验证码
+CREATE TABLE sys_captcha (
+ uuid varchar2(36) NOT NULL,
+ code varchar2(6) NOT NULL,
+ expire_time timestamp,
+ PRIMARY KEY (uuid)
+);
+
+-- 角色
+CREATE TABLE sys_role (
+ role_id NUMBER(20, 0) NOT NULL,
+ role_name varchar2(100),
+ remark varchar2(100),
+ create_user_id NUMBER(20, 0) NOT NULL,
+ create_time timestamp,
+ PRIMARY KEY (role_id)
+);
+
+-- 用户与角色对应关系
+CREATE TABLE sys_user_role (
+ id NUMBER(20, 0) NOT NULL,
+ user_id NUMBER(20, 0) NOT NULL,
+ role_id NUMBER(20, 0) NOT NULL,
+ PRIMARY KEY (id)
+);
+
+-- 角色与菜单对应关系
+CREATE TABLE sys_role_menu (
+ id NUMBER(20, 0) NOT NULL,
+ role_id NUMBER(20, 0) NOT NULL,
+ menu_id NUMBER(20, 0) NOT NULL,
+ PRIMARY KEY (id)
+);
+
+-- 系统配置信息
+CREATE TABLE sys_config (
+ id NUMBER(20, 0) NOT NULL,
+ param_key varchar2(50),
+ param_value varchar2(4000),
+ status NUMBER(2, 0) DEFAULT 1 NOT NULL,
+ remark varchar2(500),
+ PRIMARY KEY (id)
+);
+CREATE UNIQUE INDEX index_param_key on sys_config(param_key);
+
+
+-- 系统日志
+CREATE TABLE sys_log (
+ id NUMBER(20, 0) NOT NULL,
+ username varchar2(50),
+ operation varchar2(50),
+ method varchar2(200),
+ params clob,
+ time NUMBER(20, 0) NOT NULL,
+ ip varchar2(64),
+ create_date timestamp,
+ PRIMARY KEY (id)
+);
+
+-- 文件上传
+CREATE TABLE sys_oss (
+ id NUMBER(20, 0) NOT NULL,
+ url varchar2(200),
+ create_date timestamp,
+ PRIMARY KEY (id)
+);
+
+-- 定时任务
+CREATE TABLE schedule_job (
+ job_id NUMBER(20, 0) NOT NULL,
+ bean_name varchar2(200),
+ params varchar2(2000),
+ cron_expression varchar2(100),
+ status NUMBER(2, 0) NOT NULL,
+ remark varchar2(255),
+ create_time timestamp,
+ PRIMARY KEY (job_id)
+);
+
+-- 定时任务日志
+CREATE TABLE schedule_job_log (
+ log_id NUMBER(20, 0) NOT NULL,
+ job_id NUMBER(20, 0) NOT NULL,
+ bean_name varchar2(200),
+ params varchar2(2000),
+ status NUMBER(2, 0) NOT NULL,
+ error varchar2(2000),
+ times NUMBER(10, 0) NOT NULL,
+ create_time timestamp,
+ PRIMARY KEY (log_id)
+);
+CREATE INDEX index_job_id on schedule_job_log(job_id);
+
+-- 用户表
+CREATE TABLE tb_user (
+ user_id NUMBER(20, 0) NOT NULL,
+ username varchar2(50) NOT NULL,
+ mobile varchar2(20) NOT NULL,
+ password varchar2(64),
+ create_time timestamp,
+ PRIMARY KEY (user_id)
+);
+CREATE UNIQUE INDEX index_tb_user_username on tb_user(username);
+
+INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', CURRENT_DATE);
+
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6);
+
+
+
+INSERT INTO sys_config (id, param_key, param_value, status, remark) VALUES (1, 'CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息');
+
+INSERT INTO schedule_job (job_id, bean_name, params, cron_expression, status, remark, create_time) VALUES (1, 'testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', CURRENT_DATE);
+
+
+-- 账号:13612345678 密码:admin
+INSERT INTO tb_user (user_id, username, mobile, password, create_time) VALUES (1, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', CURRENT_DATE);
+
+
+
+
+-- quartz自带表结构
+CREATE TABLE qrtz_job_details
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ JOB_NAME VARCHAR2(200) NOT NULL,
+ JOB_GROUP VARCHAR2(200) NOT NULL,
+ DESCRIPTION VARCHAR2(250) NULL,
+ JOB_CLASS_NAME VARCHAR2(250) NOT NULL,
+ IS_DURABLE VARCHAR2(1) NOT NULL,
+ IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
+ IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
+ REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
+ JOB_DATA BLOB NULL,
+ CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+CREATE TABLE qrtz_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ JOB_NAME VARCHAR2(200) NOT NULL,
+ JOB_GROUP VARCHAR2(200) NOT NULL,
+ DESCRIPTION VARCHAR2(250) NULL,
+ NEXT_FIRE_TIME NUMBER(13) NULL,
+ PREV_FIRE_TIME NUMBER(13) NULL,
+ PRIORITY NUMBER(13) NULL,
+ TRIGGER_STATE VARCHAR2(16) NOT NULL,
+ TRIGGER_TYPE VARCHAR2(8) NOT NULL,
+ START_TIME NUMBER(13) NOT NULL,
+ END_TIME NUMBER(13) NULL,
+ CALENDAR_NAME VARCHAR2(200) NULL,
+ MISFIRE_INSTR NUMBER(2) NULL,
+ JOB_DATA BLOB NULL,
+ CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+ REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+CREATE TABLE qrtz_simple_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ REPEAT_COUNT NUMBER(7) NOT NULL,
+ REPEAT_INTERVAL NUMBER(12) NOT NULL,
+ TIMES_TRIGGERED NUMBER(10) NOT NULL,
+ CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_cron_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ CRON_EXPRESSION VARCHAR2(120) NOT NULL,
+ TIME_ZONE_ID VARCHAR2(80),
+ CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_simprop_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ STR_PROP_1 VARCHAR2(512) NULL,
+ STR_PROP_2 VARCHAR2(512) NULL,
+ STR_PROP_3 VARCHAR2(512) NULL,
+ INT_PROP_1 NUMBER(10) NULL,
+ INT_PROP_2 NUMBER(10) NULL,
+ LONG_PROP_1 NUMBER(13) NULL,
+ LONG_PROP_2 NUMBER(13) NULL,
+ DEC_PROP_1 NUMERIC(13,4) NULL,
+ DEC_PROP_2 NUMERIC(13,4) NULL,
+ BOOL_PROP_1 VARCHAR2(1) NULL,
+ BOOL_PROP_2 VARCHAR2(1) NULL,
+ CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_blob_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ BLOB_DATA BLOB NULL,
+ CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_calendars
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ CALENDAR_NAME VARCHAR2(200) NOT NULL,
+ CALENDAR BLOB NOT NULL,
+ CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+CREATE TABLE qrtz_paused_trigger_grps
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+CREATE TABLE qrtz_fired_triggers
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ ENTRY_ID VARCHAR2(95) NOT NULL,
+ TRIGGER_NAME VARCHAR2(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+ INSTANCE_NAME VARCHAR2(200) NOT NULL,
+ FIRED_TIME NUMBER(13) NOT NULL,
+ SCHED_TIME NUMBER(13) NOT NULL,
+ PRIORITY NUMBER(13) NOT NULL,
+ STATE VARCHAR2(16) NOT NULL,
+ JOB_NAME VARCHAR2(200) NULL,
+ JOB_GROUP VARCHAR2(200) NULL,
+ IS_NONCONCURRENT VARCHAR2(1) NULL,
+ REQUESTS_RECOVERY VARCHAR2(1) NULL,
+ CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+CREATE TABLE qrtz_scheduler_state
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ INSTANCE_NAME VARCHAR2(200) NOT NULL,
+ LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
+ CHECKIN_INTERVAL NUMBER(13) NOT NULL,
+ CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+CREATE TABLE qrtz_locks
+(
+ SCHED_NAME VARCHAR2(120) NOT NULL,
+ LOCK_NAME VARCHAR2(40) NOT NULL,
+ CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
+
+
diff --git a/renren-fast-master/db/postgresql.sql b/renren-fast-master/db/postgresql.sql
new file mode 100644
index 0000000..923da2c
--- /dev/null
+++ b/renren-fast-master/db/postgresql.sql
@@ -0,0 +1,364 @@
+-- 菜单
+CREATE TABLE sys_menu (
+ menu_id bigserial,
+ parent_id int8,
+ name varchar(50),
+ url varchar(200),
+ perms varchar(500),
+ type int,
+ icon varchar(50),
+ order_num int,
+ PRIMARY KEY (menu_id)
+);
+
+
+-- 系统用户
+CREATE TABLE sys_user (
+ user_id bigserial,
+ username varchar(50) NOT NULL,
+ password varchar(100),
+ salt varchar(20),
+ email varchar(100),
+ mobile varchar(100),
+ status int,
+ create_user_id int8,
+ create_time timestamp,
+ PRIMARY KEY (user_id),
+ UNIQUE (username)
+);
+
+
+-- 系统用户Token
+CREATE TABLE sys_user_token (
+ user_id bigserial,
+ token varchar(100) NOT NULL,
+ expire_time timestamp,
+ update_time timestamp,
+ PRIMARY KEY (user_id),
+ UNIQUE (token)
+);
+
+-- 系统验证码
+CREATE TABLE sys_captcha (
+ uuid varchar(36) NOT NULL,
+ code varchar(6) NOT NULL,
+ expire_time timestamp,
+ PRIMARY KEY (uuid)
+);
+
+-- 角色
+CREATE TABLE sys_role (
+ role_id bigserial,
+ role_name varchar(100),
+ remark varchar(100),
+ create_user_id int8,
+ create_time timestamp,
+ PRIMARY KEY (role_id)
+);
+
+-- 用户与角色对应关系
+CREATE TABLE sys_user_role (
+ id bigserial,
+ user_id int8,
+ role_id int8,
+ PRIMARY KEY (id)
+);
+
+-- 角色与菜单对应关系
+CREATE TABLE sys_role_menu (
+ id bigserial,
+ role_id int8,
+ menu_id int8,
+ PRIMARY KEY (id)
+);
+
+-- 系统配置信息
+CREATE TABLE sys_config (
+ id bigserial,
+ param_key varchar(50),
+ param_value varchar(2000),
+ status int DEFAULT 1,
+ remark varchar(500),
+ PRIMARY KEY (id),
+ UNIQUE (param_key)
+);
+
+
+-- 系统日志
+CREATE TABLE sys_log (
+ id bigserial,
+ username varchar(50),
+ operation varchar(50),
+ method varchar(200),
+ params varchar(5000),
+ time int8 NOT NULL,
+ ip varchar(64),
+ create_date timestamp,
+ PRIMARY KEY (id)
+);
+
+-- 文件上传
+CREATE TABLE sys_oss (
+ id bigserial,
+ url varchar(200),
+ create_date timestamp,
+ PRIMARY KEY (id)
+);
+
+
+-- 定时任务
+CREATE TABLE schedule_job (
+ job_id bigserial,
+ bean_name varchar(200),
+ params varchar(2000),
+ cron_expression varchar(100),
+ status int,
+ remark varchar(255),
+ create_time timestamp,
+ PRIMARY KEY (job_id)
+);
+
+-- 定时任务日志
+CREATE TABLE schedule_job_log (
+ log_id bigserial,
+ job_id int8 NOT NULL,
+ bean_name varchar(200),
+ params varchar(2000),
+ status int NOT NULL,
+ error varchar(2000),
+ times int NOT NULL,
+ create_time timestamp,
+ PRIMARY KEY (log_id)
+);
+CREATE INDEX index_job_id on schedule_job_log(job_id);
+
+-- 用户表
+CREATE TABLE tb_user (
+ user_id bigserial,
+ username varchar(50) NOT NULL,
+ mobile varchar(20) NOT NULL,
+ password varchar(64),
+ create_time timestamp,
+ PRIMARY KEY (user_id),
+ UNIQUE (username)
+);
+
+
+INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11');
+
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6);
+
+
+INSERT INTO sys_config (param_key, param_value, status, remark) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息');
+
+INSERT INTO schedule_job (bean_name, params, cron_expression, status, remark, create_time) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', '2016-12-01 23:16:46');
+
+
+-- 账号:13612345678 密码:admin
+INSERT INTO tb_user (username, mobile, password, create_time) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41');
+
+
+alter sequence sys_menu_menu_id_seq restart with 31;
+alter sequence sys_user_user_id_seq restart with 2;
+
+
+-- quartz自带表结构
+
+CREATE TABLE qrtz_job_details
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ JOB_NAME VARCHAR(200) NOT NULL,
+ JOB_GROUP VARCHAR(200) NOT NULL,
+ DESCRIPTION VARCHAR(250) NULL,
+ JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+ IS_DURABLE BOOL NOT NULL,
+ IS_NONCONCURRENT BOOL NOT NULL,
+ IS_UPDATE_DATA BOOL NOT NULL,
+ REQUESTS_RECOVERY BOOL NOT NULL,
+ JOB_DATA BYTEA NULL,
+ PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ JOB_NAME VARCHAR(200) NOT NULL,
+ JOB_GROUP VARCHAR(200) NOT NULL,
+ DESCRIPTION VARCHAR(250) NULL,
+ NEXT_FIRE_TIME BIGINT NULL,
+ PREV_FIRE_TIME BIGINT NULL,
+ PRIORITY INTEGER NULL,
+ TRIGGER_STATE VARCHAR(16) NOT NULL,
+ TRIGGER_TYPE VARCHAR(8) NOT NULL,
+ START_TIME BIGINT NOT NULL,
+ END_TIME BIGINT NULL,
+ CALENDAR_NAME VARCHAR(200) NULL,
+ MISFIRE_INSTR SMALLINT NULL,
+ JOB_DATA BYTEA NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+ REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
+);
+
+CREATE TABLE qrtz_simple_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ REPEAT_COUNT BIGINT NOT NULL,
+ REPEAT_INTERVAL BIGINT NOT NULL,
+ TIMES_TRIGGERED BIGINT NOT NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_cron_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ CRON_EXPRESSION VARCHAR(120) NOT NULL,
+ TIME_ZONE_ID VARCHAR(80),
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_simprop_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ STR_PROP_1 VARCHAR(512) NULL,
+ STR_PROP_2 VARCHAR(512) NULL,
+ STR_PROP_3 VARCHAR(512) NULL,
+ INT_PROP_1 INT NULL,
+ INT_PROP_2 INT NULL,
+ LONG_PROP_1 BIGINT NULL,
+ LONG_PROP_2 BIGINT NULL,
+ DEC_PROP_1 NUMERIC(13,4) NULL,
+ DEC_PROP_2 NUMERIC(13,4) NULL,
+ BOOL_PROP_1 BOOL NULL,
+ BOOL_PROP_2 BOOL NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_blob_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ BLOB_DATA BYTEA NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+ FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+ REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_calendars
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ CALENDAR_NAME VARCHAR(200) NOT NULL,
+ CALENDAR BYTEA NOT NULL,
+ PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
+);
+
+
+CREATE TABLE qrtz_paused_trigger_grps
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
+);
+
+CREATE TABLE qrtz_fired_triggers
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ ENTRY_ID VARCHAR(95) NOT NULL,
+ TRIGGER_NAME VARCHAR(200) NOT NULL,
+ TRIGGER_GROUP VARCHAR(200) NOT NULL,
+ INSTANCE_NAME VARCHAR(200) NOT NULL,
+ FIRED_TIME BIGINT NOT NULL,
+ SCHED_TIME BIGINT NOT NULL,
+ PRIORITY INTEGER NOT NULL,
+ STATE VARCHAR(16) NOT NULL,
+ JOB_NAME VARCHAR(200) NULL,
+ JOB_GROUP VARCHAR(200) NULL,
+ IS_NONCONCURRENT BOOL NULL,
+ REQUESTS_RECOVERY BOOL NULL,
+ PRIMARY KEY (SCHED_NAME,ENTRY_ID)
+);
+
+CREATE TABLE qrtz_scheduler_state
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ INSTANCE_NAME VARCHAR(200) NOT NULL,
+ LAST_CHECKIN_TIME BIGINT NOT NULL,
+ CHECKIN_INTERVAL BIGINT NOT NULL,
+ PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
+);
+
+CREATE TABLE qrtz_locks
+(
+ SCHED_NAME VARCHAR(120) NOT NULL,
+ LOCK_NAME VARCHAR(40) NOT NULL,
+ PRIMARY KEY (SCHED_NAME,LOCK_NAME)
+);
+
+create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
+
+create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);
+create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);
+create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);
+create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);
+create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);
+create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);
+create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
+
+
+commit;
diff --git a/renren-fast-master/db/sqlserver.sql b/renren-fast-master/db/sqlserver.sql
new file mode 100644
index 0000000..de38fa8
--- /dev/null
+++ b/renren-fast-master/db/sqlserver.sql
@@ -0,0 +1,512 @@
+-- 菜单
+CREATE TABLE sys_menu (
+ menu_id bigint NOT NULL IDENTITY(1,1),
+ parent_id bigint,
+ name varchar(50),
+ url varchar(200),
+ perms varchar(500),
+ type int,
+ icon varchar(50),
+ order_num int,
+ PRIMARY KEY (menu_id)
+);
+
+-- 系统用户
+CREATE TABLE sys_user (
+ user_id bigint NOT NULL IDENTITY(1,1),
+ username varchar(50) NOT NULL,
+ password varchar(100),
+ salt varchar(20),
+ email varchar(100),
+ mobile varchar(100),
+ status tinyint,
+ create_user_id bigint,
+ create_time datetime,
+ PRIMARY KEY (user_id),
+ UNIQUE (username)
+);
+
+-- 系统用户Token
+CREATE TABLE sys_user_token (
+ user_id bigint NOT NULL,
+ token varchar(100) NOT NULL,
+ expire_time datetime,
+ update_time datetime,
+ PRIMARY KEY (user_id),
+ UNIQUE (token)
+);
+
+-- 系统验证码
+CREATE TABLE sys_captcha (
+ uuid varchar(36) NOT NULL,
+ code varchar(6) NOT NULL,
+ expire_time datetime,
+ PRIMARY KEY (uuid)
+);
+
+-- 角色
+CREATE TABLE sys_role (
+ role_id bigint NOT NULL IDENTITY(1,1),
+ role_name varchar(100),
+ remark varchar(100),
+ create_user_id bigint,
+ create_time datetime,
+PRIMARY KEY (role_id)
+);
+
+-- 用户与角色对应关系
+CREATE TABLE sys_user_role (
+ id bigint NOT NULL IDENTITY(1,1),
+ user_id bigint,
+ role_id bigint,
+PRIMARY KEY (id)
+);
+
+-- 角色与菜单对应关系
+CREATE TABLE sys_role_menu (
+ id bigint NOT NULL IDENTITY(1,1),
+ role_id bigint,
+ menu_id bigint,
+PRIMARY KEY (id)
+);
+
+-- 系统配置信息
+CREATE TABLE sys_config (
+ id bigint NOT NULL IDENTITY(1,1),
+ param_key varchar(50),
+ param_value varchar(2000),
+ status tinyint DEFAULT 1,
+ remark varchar(500),
+ PRIMARY KEY (id),
+ UNIQUE (param_key)
+);
+
+-- 系统日志
+CREATE TABLE sys_log (
+ id bigint NOT NULL IDENTITY(1,1),
+ username varchar(50),
+ operation varchar(50),
+ method varchar(200),
+ params varchar(5000),
+ time bigint NOT NULL,
+ ip varchar(64),
+ create_date datetime,
+PRIMARY KEY (id)
+);
+
+-- 文件上传
+CREATE TABLE sys_oss (
+ id bigint NOT NULL IDENTITY(1,1),
+ url varchar(200),
+ create_date datetime,
+ PRIMARY KEY (id)
+);
+
+-- 定时任务
+CREATE TABLE schedule_job (
+ job_id bigint NOT NULL IDENTITY(1,1),
+ bean_name varchar(200),
+ params varchar(2000),
+ cron_expression varchar(100),
+ status tinyint,
+ remark varchar(255),
+ create_time datetime,
+ PRIMARY KEY (job_id)
+);
+
+-- 定时任务日志
+CREATE TABLE schedule_job_log (
+ log_id bigint NOT NULL IDENTITY(1,1),
+ job_id bigint NOT NULL,
+ bean_name varchar(200),
+ params varchar(2000),
+ status tinyint NOT NULL,
+ error varchar(2000),
+ times int NOT NULL,
+ create_time datetime,
+ PRIMARY KEY (log_id),
+ INDEX job_id (job_id)
+);
+
+-- 用户表
+CREATE TABLE tb_user (
+ user_id bigint NOT NULL IDENTITY(1,1),
+ username varchar(50) NOT NULL,
+ mobile varchar(20) NOT NULL,
+ password varchar(64),
+ create_time datetime,
+ PRIMARY KEY (user_id),
+ UNIQUE (username)
+);
+
+SET IDENTITY_INSERT sys_user ON;
+INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11');
+SET IDENTITY_INSERT sys_user OFF;
+
+SET IDENTITY_INSERT sys_menu ON;
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7);
+INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6);
+
+SET IDENTITY_INSERT sys_menu OFF;
+
+
+INSERT INTO sys_config (param_key, param_value, status, remark) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息');
+
+INSERT INTO schedule_job (bean_name, params, cron_expression, status, remark, create_time) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', '2016-12-01 23:16:46');
+
+
+-- 账号:13612345678 密码:admin
+INSERT INTO tb_user (username, mobile, password, create_time) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41');
+
+
+
+
+
+-- quartz自带表结构
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
+ ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_CALENDARS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_LOCKS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_JOB_DETAILS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS]
+GO
+
+IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
+ DROP TABLE [dbo].[QRTZ_TRIGGERS]
+GO
+
+CREATE TABLE [dbo].[QRTZ_CALENDARS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [CALENDAR_NAME] [VARCHAR] (200) NOT NULL ,
+ [CALENDAR] [IMAGE] NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [CRON_EXPRESSION] [VARCHAR] (120) NOT NULL ,
+ [TIME_ZONE_ID] [VARCHAR] (80)
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [ENTRY_ID] [VARCHAR] (95) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [INSTANCE_NAME] [VARCHAR] (200) NOT NULL ,
+ [FIRED_TIME] [BIGINT] NOT NULL ,
+ [SCHED_TIME] [BIGINT] NOT NULL ,
+ [PRIORITY] [INTEGER] NOT NULL ,
+ [STATE] [VARCHAR] (16) NOT NULL,
+ [JOB_NAME] [VARCHAR] (200) NULL ,
+ [JOB_GROUP] [VARCHAR] (200) NULL ,
+ [IS_NONCONCURRENT] [VARCHAR] (1) NULL ,
+ [REQUESTS_RECOVERY] [VARCHAR] (1) NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [INSTANCE_NAME] [VARCHAR] (200) NOT NULL ,
+ [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
+ [CHECKIN_INTERVAL] [BIGINT] NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_LOCKS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [LOCK_NAME] [VARCHAR] (40) NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [JOB_NAME] [VARCHAR] (200) NOT NULL ,
+ [JOB_GROUP] [VARCHAR] (200) NOT NULL ,
+ [DESCRIPTION] [VARCHAR] (250) NULL ,
+ [JOB_CLASS_NAME] [VARCHAR] (250) NOT NULL ,
+ [IS_DURABLE] [VARCHAR] (1) NOT NULL ,
+ [IS_NONCONCURRENT] [VARCHAR] (1) NOT NULL ,
+ [IS_UPDATE_DATA] [VARCHAR] (1) NOT NULL ,
+ [REQUESTS_RECOVERY] [VARCHAR] (1) NOT NULL ,
+ [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [REPEAT_COUNT] [BIGINT] NOT NULL ,
+ [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
+ [TIMES_TRIGGERED] [BIGINT] NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [STR_PROP_1] [VARCHAR] (512) NULL,
+ [STR_PROP_2] [VARCHAR] (512) NULL,
+ [STR_PROP_3] [VARCHAR] (512) NULL,
+ [INT_PROP_1] [INT] NULL,
+ [INT_PROP_2] [INT] NULL,
+ [LONG_PROP_1] [BIGINT] NULL,
+ [LONG_PROP_2] [BIGINT] NULL,
+ [DEC_PROP_1] [NUMERIC] (13,4) NULL,
+ [DEC_PROP_2] [NUMERIC] (13,4) NULL,
+ [BOOL_PROP_1] [VARCHAR] (1) NULL,
+ [BOOL_PROP_2] [VARCHAR] (1) NULL,
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [BLOB_DATA] [IMAGE] NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
+ [SCHED_NAME] [VARCHAR] (120) NOT NULL ,
+ [TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
+ [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
+ [JOB_NAME] [VARCHAR] (200) NOT NULL ,
+ [JOB_GROUP] [VARCHAR] (200) NOT NULL ,
+ [DESCRIPTION] [VARCHAR] (250) NULL ,
+ [NEXT_FIRE_TIME] [BIGINT] NULL ,
+ [PREV_FIRE_TIME] [BIGINT] NULL ,
+ [PRIORITY] [INTEGER] NULL ,
+ [TRIGGER_STATE] [VARCHAR] (16) NOT NULL ,
+ [TRIGGER_TYPE] [VARCHAR] (8) NOT NULL ,
+ [START_TIME] [BIGINT] NOT NULL ,
+ [END_TIME] [BIGINT] NULL ,
+ [CALENDAR_NAME] [VARCHAR] (200) NULL ,
+ [MISFIRE_INSTR] [SMALLINT] NULL ,
+ [JOB_DATA] [IMAGE] NULL
+) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [CALENDAR_NAME]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [ENTRY_ID]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [TRIGGER_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [INSTANCE_NAME]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [LOCK_NAME]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [JOB_NAME],
+ [JOB_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
+ CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
+ CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON DELETE CASCADE
+GO
+
+ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
+ CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON DELETE CASCADE
+GO
+
+ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
+ CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
+ (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
+ [SCHED_NAME],
+ [TRIGGER_NAME],
+ [TRIGGER_GROUP]
+ ) ON DELETE CASCADE
+GO
+
+ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
+ CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
+ (
+ [SCHED_NAME],
+ [JOB_NAME],
+ [JOB_GROUP]
+ ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
+ [SCHED_NAME],
+ [JOB_NAME],
+ [JOB_GROUP]
+ )
+GO
+
diff --git a/renren-fast-master/docker-compose.yml b/renren-fast-master/docker-compose.yml
new file mode 100644
index 0000000..432ba38
--- /dev/null
+++ b/renren-fast-master/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '2'
+services:
+ renren-fast:
+ image: renren/fast
+ ports:
+ - "8080:8080"
+ environment:
+ - spring.profiles.active=dev
\ No newline at end of file
diff --git a/renren-fast-master/pom.xml b/renren-fast-master/pom.xml
new file mode 100644
index 0000000..10e72a9
--- /dev/null
+++ b/renren-fast-master/pom.xml
@@ -0,0 +1,338 @@
+
+
+ 4.0.0
+ io.renren
+ renren-fast
+ 3.0.0
+ jar
+ renren-fast
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.6
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 3.3.1
+ 8.0.28
+ 4.0
+ 11.2.0.3
+ 1.1.13
+ 2.3.0
+ 2.6
+ 1.2.2
+ 2.5
+ 1.10
+ 1.10
+ 1.9.0
+ 0.7.0
+ 0.0.9
+ 7.2.23
+ 2.8.3
+ 4.4
+ 2.7.0
+ 2.9.9
+ 2.8.5
+ 1.2.79
+ 4.1.1
+ 1.18.4
+
+
+ /work/renren
+ ${project.artifactId}-${project.version}.jar
+ 192.168.1.10:22
+ root
+ 123456
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework
+ spring-context-support
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ ${mybatisplus.version}
+
+
+ com.baomidou
+ mybatis-plus-generator
+
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+
+ com.oracle
+ ojdbc6
+ ${oracle.version}
+
+
+
+ com.microsoft.sqlserver
+ sqljdbc4
+ ${mssql.version}
+
+
+
+ org.postgresql
+ postgresql
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ ${druid.version}
+
+
+ org.quartz-scheduler
+ quartz
+ ${quartz.version}
+
+
+ com.mchange
+ c3p0
+
+
+
+
+ commons-lang
+ commons-lang
+ ${commons.lang.version}
+
+
+ commons-fileupload
+ commons-fileupload
+ ${commons.fileupload.version}
+
+
+ commons-io
+ commons-io
+ ${commons.io.version}
+
+
+ commons-codec
+ commons-codec
+ ${commons.codec.version}
+
+
+ commons-configuration
+ commons-configuration
+ ${commons.configuration.version}
+
+
+ org.apache.shiro
+ shiro-core
+ ${shiro.version}
+
+
+ org.apache.shiro
+ shiro-spring
+ ${shiro.version}
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jwt.version}
+
+
+ com.github.axet
+ kaptcha
+ ${kaptcha.version}
+
+
+ io.springfox
+ springfox-swagger2
+ ${swagger.version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${swagger.version}
+
+
+ com.qiniu
+ qiniu-java-sdk
+ ${qiniu.version}
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ ${aliyun.oss.version}
+
+
+ com.qcloud
+ cos_api
+ ${qcloud.cos.version}
+
+
+ org.slf4j
+ slf4j-log4j12
+
+
+
+
+ joda-time
+ joda-time
+ ${joda.time.version}
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+
+ ${project.artifactId}
+
+
+ org.apache.maven.wagon
+ wagon-ssh
+ 2.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.codehaus.mojo
+ wagon-maven-plugin
+ 1.0
+
+ target/${pack-name}
+
+
+
+ kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'`
+
+ ${service-path}/renren.log 2>&1 & ]]>
+
+
+
+
+ true
+
+
+
+
+ com.spotify
+ docker-maven-plugin
+ 0.4.14
+
+
+
+
+
+
+
+
+
+ renren/fast
+ ${project.basedir}
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.jar
+
+
+
+
+
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public/
+
+ true
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public/
+
+ true
+
+
+ false
+
+
+
+
+
diff --git a/renren-fast-master/src/main/java/io/renren/RenrenApplication.java b/renren-fast-master/src/main/java/io/renren/RenrenApplication.java
new file mode 100644
index 0000000..915d6cb
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/RenrenApplication.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+@SpringBootApplication
+public class RenrenApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(RenrenApplication.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/common/annotation/SysLog.java b/renren-fast-master/src/main/java/io/renren/common/annotation/SysLog.java
new file mode 100644
index 0000000..4653480
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/annotation/SysLog.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 系统日志注解
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SysLog {
+
+ String value() default "";
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/aspect/RedisAspect.java b/renren-fast-master/src/main/java/io/renren/common/aspect/RedisAspect.java
new file mode 100644
index 0000000..bb2a8e5
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/aspect/RedisAspect.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.aspect;
+
+import io.renren.common.exception.RRException;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Redis切面处理类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Aspect
+@Configuration
+public class RedisAspect {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+ //是否开启redis缓存 true开启 false关闭
+ @Value("${spring.redis.open: false}")
+ private boolean open;
+
+ @Around("execution(* io.renren.common.utils.RedisUtils.*(..))")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+ Object result = null;
+ if(open){
+ try{
+ result = point.proceed();
+ }catch (Exception e){
+ logger.error("redis error", e);
+ throw new RRException("Redis服务异常");
+ }
+ }
+ return result;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/aspect/SysLogAspect.java b/renren-fast-master/src/main/java/io/renren/common/aspect/SysLogAspect.java
new file mode 100644
index 0000000..ae047df
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/aspect/SysLogAspect.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.aspect;
+
+import com.google.gson.Gson;
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.HttpContextUtils;
+import io.renren.common.utils.IPUtils;
+import io.renren.modules.sys.entity.SysLogEntity;
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.service.SysLogService;
+import org.apache.shiro.SecurityUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Date;
+
+
+/**
+ * 系统日志,切面处理类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Aspect
+@Component
+public class SysLogAspect {
+ @Autowired
+ private SysLogService sysLogService;
+
+ @Pointcut("@annotation(io.renren.common.annotation.SysLog)")
+ public void logPointCut() {
+
+ }
+
+ @Around("logPointCut()")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+ long beginTime = System.currentTimeMillis();
+ //执行方法
+ Object result = point.proceed();
+ //执行时长(毫秒)
+ long time = System.currentTimeMillis() - beginTime;
+
+ //保存日志
+ saveSysLog(point, time);
+
+ return result;
+ }
+
+ private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ Method method = signature.getMethod();
+
+ SysLogEntity sysLog = new SysLogEntity();
+ SysLog syslog = method.getAnnotation(SysLog.class);
+ if(syslog != null){
+ //注解上的描述
+ sysLog.setOperation(syslog.value());
+ }
+
+ //请求的方法名
+ String className = joinPoint.getTarget().getClass().getName();
+ String methodName = signature.getName();
+ sysLog.setMethod(className + "." + methodName + "()");
+
+ //请求的参数
+ Object[] args = joinPoint.getArgs();
+ try{
+ String params = new Gson().toJson(args);
+ sysLog.setParams(params);
+ }catch (Exception e){
+
+ }
+
+ //获取request
+ HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
+ //设置IP地址
+ sysLog.setIp(IPUtils.getIpAddr(request));
+
+ //用户名
+ String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
+ sysLog.setUsername(username);
+
+ sysLog.setTime(time);
+ sysLog.setCreateDate(new Date());
+ //保存系统日志
+ sysLogService.save(sysLog);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/exception/RRException.java b/renren-fast-master/src/main/java/io/renren/common/exception/RRException.java
new file mode 100644
index 0000000..5c27351
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/exception/RRException.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.exception;
+
+/**
+ * 自定义异常
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class RRException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ private String msg;
+ private int code = 500;
+
+ public RRException(String msg) {
+ super(msg);
+ this.msg = msg;
+ }
+
+ public RRException(String msg, Throwable e) {
+ super(msg, e);
+ this.msg = msg;
+ }
+
+ public RRException(String msg, int code) {
+ super(msg);
+ this.msg = msg;
+ this.code = code;
+ }
+
+ public RRException(String msg, int code, Throwable e) {
+ super(msg, e);
+ this.msg = msg;
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/exception/RRExceptionHandler.java b/renren-fast-master/src/main/java/io/renren/common/exception/RRExceptionHandler.java
new file mode 100644
index 0000000..eb060a6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/exception/RRExceptionHandler.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.exception;
+
+import io.renren.common.utils.R;
+import org.apache.shiro.authz.AuthorizationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+/**
+ * 异常处理器
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestControllerAdvice
+public class RRExceptionHandler {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ /**
+ * 处理自定义异常
+ */
+ @ExceptionHandler(RRException.class)
+ public R handleRRException(RRException e){
+ R r = new R();
+ r.put("code", e.getCode());
+ r.put("msg", e.getMessage());
+
+ return r;
+ }
+
+ @ExceptionHandler(NoHandlerFoundException.class)
+ public R handlerNoFoundException(Exception e) {
+ logger.error(e.getMessage(), e);
+ return R.error(404, "路径不存在,请检查路径是否正确");
+ }
+
+ @ExceptionHandler(DuplicateKeyException.class)
+ public R handleDuplicateKeyException(DuplicateKeyException e){
+ logger.error(e.getMessage(), e);
+ return R.error("数据库中已存在该记录");
+ }
+
+ @ExceptionHandler(AuthorizationException.class)
+ public R handleAuthorizationException(AuthorizationException e){
+ logger.error(e.getMessage(), e);
+ return R.error("没有权限,请联系管理员授权");
+ }
+
+ @ExceptionHandler(Exception.class)
+ public R handleException(Exception e){
+ logger.error(e.getMessage(), e);
+ return R.error();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/ConfigConstant.java b/renren-fast-master/src/main/java/io/renren/common/utils/ConfigConstant.java
new file mode 100644
index 0000000..32897da
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/ConfigConstant.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+/**
+ * 系统参数相关Key
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ConfigConstant {
+ /**
+ * 云存储配置KEY
+ */
+ public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY";
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/Constant.java b/renren-fast-master/src/main/java/io/renren/common/utils/Constant.java
new file mode 100644
index 0000000..da3d5bc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/Constant.java
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import io.renren.common.validator.group.AliyunGroup;
+import io.renren.common.validator.group.QcloudGroup;
+import io.renren.common.validator.group.QiniuGroup;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * 常量
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class Constant {
+ /**
+ * 超级管理员ID
+ */
+ public static final int SUPER_ADMIN = 1;
+ /**
+ * 当前页码
+ */
+ public static final String PAGE = "page";
+ /**
+ * 每页显示记录数
+ */
+ public static final String LIMIT = "limit";
+ /**
+ * 排序字段
+ */
+ public static final String ORDER_FIELD = "sidx";
+ /**
+ * 排序方式
+ */
+ public static final String ORDER = "order";
+ /**
+ * 升序
+ */
+ public static final String ASC = "asc";
+
+ /**
+ * 菜单类型
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2016年11月15日 下午1:24:29
+ */
+ public enum MenuType {
+ /**
+ * 目录
+ */
+ CATALOG(0),
+ /**
+ * 菜单
+ */
+ MENU(1),
+ /**
+ * 按钮
+ */
+ BUTTON(2);
+
+ private int value;
+
+ MenuType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * 定时任务状态
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2016年12月3日 上午12:07:22
+ */
+ public enum ScheduleStatus {
+ /**
+ * 正常
+ */
+ NORMAL(0),
+ /**
+ * 暂停
+ */
+ PAUSE(1);
+
+ private int value;
+
+ ScheduleStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * 云服务商
+ */
+ public enum CloudService {
+ /**
+ * 七牛云
+ */
+ QINIU(1, QiniuGroup.class),
+ /**
+ * 阿里云
+ */
+ ALIYUN(2, AliyunGroup.class),
+ /**
+ * 腾讯云
+ */
+ QCLOUD(3, QcloudGroup.class);
+
+ private int value;
+
+ private Class> validatorGroupClass;
+
+ CloudService(int value, Class> validatorGroupClass) {
+ this.value = value;
+ this.validatorGroupClass = validatorGroupClass;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public Class> getValidatorGroupClass() {
+ return this.validatorGroupClass;
+ }
+
+ public static CloudService getByValue(Integer value) {
+ Optional first = Stream.of(CloudService.values()).filter(cs -> value.equals(cs.value)).findFirst();
+ if (!first.isPresent()) {
+ throw new IllegalArgumentException("非法的枚举值:" + value);
+ }
+ return first.get();
+ }
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/DateUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/DateUtils.java
new file mode 100644
index 0000000..798f7ba
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/DateUtils.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import org.apache.commons.lang.StringUtils;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 日期处理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class DateUtils {
+ /** 时间格式(yyyy-MM-dd) */
+ public final static String DATE_PATTERN = "yyyy-MM-dd";
+ /** 时间格式(yyyy-MM-dd HH:mm:ss) */
+ public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+
+ /**
+ * 日期格式化 日期格式为:yyyy-MM-dd
+ * @param date 日期
+ * @return 返回yyyy-MM-dd格式日期
+ */
+ public static String format(Date date) {
+ return format(date, DATE_PATTERN);
+ }
+
+ /**
+ * 日期格式化 日期格式为:yyyy-MM-dd
+ * @param date 日期
+ * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
+ * @return 返回yyyy-MM-dd格式日期
+ */
+ public static String format(Date date, String pattern) {
+ if(date != null){
+ SimpleDateFormat df = new SimpleDateFormat(pattern);
+ return df.format(date);
+ }
+ return null;
+ }
+
+ /**
+ * 字符串转换成日期
+ * @param strDate 日期字符串
+ * @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN
+ */
+ public static Date stringToDate(String strDate, String pattern) {
+ if (StringUtils.isBlank(strDate)){
+ return null;
+ }
+
+ DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
+ return fmt.parseLocalDateTime(strDate).toDate();
+ }
+
+ /**
+ * 根据周数,获取开始日期、结束日期
+ * @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周
+ * @return 返回date[0]开始日期、date[1]结束日期
+ */
+ public static Date[] getWeekStartAndEnd(int week) {
+ DateTime dateTime = new DateTime();
+ LocalDate date = new LocalDate(dateTime.plusWeeks(week));
+
+ date = date.dayOfWeek().withMinimumValue();
+ Date beginDate = date.toDate();
+ Date endDate = date.plusDays(6).toDate();
+ return new Date[]{beginDate, endDate};
+ }
+
+ /**
+ * 对日期的【秒】进行加/减
+ *
+ * @param date 日期
+ * @param seconds 秒数,负数为减
+ * @return 加/减几秒后的日期
+ */
+ public static Date addDateSeconds(Date date, int seconds) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusSeconds(seconds).toDate();
+ }
+
+ /**
+ * 对日期的【分钟】进行加/减
+ *
+ * @param date 日期
+ * @param minutes 分钟数,负数为减
+ * @return 加/减几分钟后的日期
+ */
+ public static Date addDateMinutes(Date date, int minutes) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusMinutes(minutes).toDate();
+ }
+
+ /**
+ * 对日期的【小时】进行加/减
+ *
+ * @param date 日期
+ * @param hours 小时数,负数为减
+ * @return 加/减几小时后的日期
+ */
+ public static Date addDateHours(Date date, int hours) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusHours(hours).toDate();
+ }
+
+ /**
+ * 对日期的【天】进行加/减
+ *
+ * @param date 日期
+ * @param days 天数,负数为减
+ * @return 加/减几天后的日期
+ */
+ public static Date addDateDays(Date date, int days) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusDays(days).toDate();
+ }
+
+ /**
+ * 对日期的【周】进行加/减
+ *
+ * @param date 日期
+ * @param weeks 周数,负数为减
+ * @return 加/减几周后的日期
+ */
+ public static Date addDateWeeks(Date date, int weeks) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusWeeks(weeks).toDate();
+ }
+
+ /**
+ * 对日期的【月】进行加/减
+ *
+ * @param date 日期
+ * @param months 月数,负数为减
+ * @return 加/减几月后的日期
+ */
+ public static Date addDateMonths(Date date, int months) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusMonths(months).toDate();
+ }
+
+ /**
+ * 对日期的【年】进行加/减
+ *
+ * @param date 日期
+ * @param years 年数,负数为减
+ * @return 加/减几年后的日期
+ */
+ public static Date addDateYears(Date date, int years) {
+ DateTime dateTime = new DateTime(date);
+ return dateTime.plusYears(years).toDate();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/HttpContextUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/HttpContextUtils.java
new file mode 100644
index 0000000..09aa2c7
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/HttpContextUtils.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class HttpContextUtils {
+
+ public static HttpServletRequest getHttpServletRequest() {
+ return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ }
+
+ public static String getDomain(){
+ HttpServletRequest request = getHttpServletRequest();
+ StringBuffer url = request.getRequestURL();
+ return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+ }
+
+ public static String getOrigin(){
+ HttpServletRequest request = getHttpServletRequest();
+ return request.getHeader("Origin");
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/IPUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/IPUtils.java
new file mode 100644
index 0000000..2f20be6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/IPUtils.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import com.alibaba.druid.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * IP地址
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class IPUtils {
+ private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
+
+ /**
+ * 获取IP地址
+ *
+ * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
+ * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
+ */
+ public static String getIpAddr(HttpServletRequest request) {
+ String ip = null;
+ try {
+ ip = request.getHeader("x-forwarded-for");
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ } catch (Exception e) {
+ logger.error("IPUtils ERROR ", e);
+ }
+
+// //使用代理,则获取第一个IP地址
+// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
+// if(ip.indexOf(",") > 0) {
+// ip = ip.substring(0, ip.indexOf(","));
+// }
+// }
+
+ return ip;
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/MapUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/MapUtils.java
new file mode 100644
index 0000000..95b6fb3
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/MapUtils.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import java.util.HashMap;
+
+
+/**
+ * Map工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class MapUtils extends HashMap {
+
+ @Override
+ public MapUtils put(String key, Object value) {
+ super.put(key, value);
+ return this;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/PageUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/PageUtils.java
new file mode 100644
index 0000000..360452d
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/PageUtils.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 分页工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class PageUtils implements Serializable {
+ private static final long serialVersionUID = 1L;
+ /**
+ * 总记录数
+ */
+ private int totalCount;
+ /**
+ * 每页记录数
+ */
+ private int pageSize;
+ /**
+ * 总页数
+ */
+ private int totalPage;
+ /**
+ * 当前页数
+ */
+ private int currPage;
+ /**
+ * 列表数据
+ */
+ private List> list;
+
+ /**
+ * 分页
+ * @param list 列表数据
+ * @param totalCount 总记录数
+ * @param pageSize 每页记录数
+ * @param currPage 当前页数
+ */
+ public PageUtils(List> list, int totalCount, int pageSize, int currPage) {
+ this.list = list;
+ this.totalCount = totalCount;
+ this.pageSize = pageSize;
+ this.currPage = currPage;
+ this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
+ }
+
+ /**
+ * 分页
+ */
+ public PageUtils(IPage> page) {
+ this.list = page.getRecords();
+ this.totalCount = (int)page.getTotal();
+ this.pageSize = (int)page.getSize();
+ this.currPage = (int)page.getCurrent();
+ this.totalPage = (int)page.getPages();
+ }
+
+ public int getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(int totalCount) {
+ this.totalCount = totalCount;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public int getTotalPage() {
+ return totalPage;
+ }
+
+ public void setTotalPage(int totalPage) {
+ this.totalPage = totalPage;
+ }
+
+ public int getCurrPage() {
+ return currPage;
+ }
+
+ public void setCurrPage(int currPage) {
+ this.currPage = currPage;
+ }
+
+ public List> getList() {
+ return list;
+ }
+
+ public void setList(List> list) {
+ this.list = list;
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/Query.java b/renren-fast-master/src/main/java/io/renren/common/utils/Query.java
new file mode 100644
index 0000000..ff825a0
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/Query.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.renren.common.xss.SQLFilter;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.Map;
+
+/**
+ * 查询参数
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class Query {
+
+ public IPage getPage(Map params) {
+ return this.getPage(params, null, false);
+ }
+
+ public IPage getPage(Map params, String defaultOrderField, boolean isAsc) {
+ //分页参数
+ long curPage = 1;
+ long limit = 10;
+
+ if(params.get(Constant.PAGE) != null){
+ curPage = Long.parseLong((String)params.get(Constant.PAGE));
+ }
+ if(params.get(Constant.LIMIT) != null){
+ limit = Long.parseLong((String)params.get(Constant.LIMIT));
+ }
+
+ //分页对象
+ Page page = new Page<>(curPage, limit);
+
+ //分页参数
+ params.put(Constant.PAGE, page);
+
+ //排序字段
+ //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险)
+ String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD));
+ String order = (String)params.get(Constant.ORDER);
+
+
+ //前端字段排序
+ if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(order)){
+ if(Constant.ASC.equalsIgnoreCase(order)) {
+ return page.addOrder(OrderItem.asc(orderField));
+ }else {
+ return page.addOrder(OrderItem.desc(orderField));
+ }
+ }
+
+ //没有排序字段,则不排序
+ if(StringUtils.isBlank(defaultOrderField)){
+ return page;
+ }
+
+ //默认排序
+ if(isAsc) {
+ page.addOrder(OrderItem.asc(defaultOrderField));
+ }else {
+ page.addOrder(OrderItem.desc(defaultOrderField));
+ }
+
+ return page;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/R.java b/renren-fast-master/src/main/java/io/renren/common/utils/R.java
new file mode 100644
index 0000000..1da0da6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/R.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import org.apache.http.HttpStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 返回数据
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class R extends HashMap {
+ private static final long serialVersionUID = 1L;
+
+ public R() {
+ put("code", 0);
+ put("msg", "success");
+ }
+
+ public static R error() {
+ return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
+ }
+
+ public static R error(String msg) {
+ return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
+ }
+
+ public static R error(int code, String msg) {
+ R r = new R();
+ r.put("code", code);
+ r.put("msg", msg);
+ return r;
+ }
+
+ public static R ok(String msg) {
+ R r = new R();
+ r.put("msg", msg);
+ return r;
+ }
+
+ public static R ok(Map map) {
+ R r = new R();
+ r.putAll(map);
+ return r;
+ }
+
+ public static R ok() {
+ return new R();
+ }
+
+ public R put(String key, Object value) {
+ super.put(key, value);
+ return this;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/RedisKeys.java b/renren-fast-master/src/main/java/io/renren/common/utils/RedisKeys.java
new file mode 100644
index 0000000..d033b05
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/RedisKeys.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+/**
+ * Redis所有Keys
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class RedisKeys {
+
+ public static String getSysConfigKey(String key){
+ return "sys:config:" + key;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/RedisUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/RedisUtils.java
new file mode 100644
index 0000000..34bbb8f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/RedisUtils.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import com.google.gson.Gson;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.*;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class RedisUtils {
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ private ValueOperations valueOperations;
+ @Autowired
+ private HashOperations hashOperations;
+ @Autowired
+ private ListOperations listOperations;
+ @Autowired
+ private SetOperations setOperations;
+ @Autowired
+ private ZSetOperations zSetOperations;
+ /** 默认过期时长,单位:秒 */
+ public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
+ /** 不设置过期时长 */
+ public final static long NOT_EXPIRE = -1;
+ private final static Gson gson = new Gson();
+
+ public void set(String key, Object value, long expire){
+ valueOperations.set(key, toJson(value));
+ if(expire != NOT_EXPIRE){
+ redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+ }
+ }
+
+ public void set(String key, Object value){
+ set(key, value, DEFAULT_EXPIRE);
+ }
+
+ public T get(String key, Class clazz, long expire) {
+ String value = valueOperations.get(key);
+ if(expire != NOT_EXPIRE){
+ redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+ }
+ return value == null ? null : fromJson(value, clazz);
+ }
+
+ public T get(String key, Class clazz) {
+ return get(key, clazz, NOT_EXPIRE);
+ }
+
+ public String get(String key, long expire) {
+ String value = valueOperations.get(key);
+ if(expire != NOT_EXPIRE){
+ redisTemplate.expire(key, expire, TimeUnit.SECONDS);
+ }
+ return value;
+ }
+
+ public String get(String key) {
+ return get(key, NOT_EXPIRE);
+ }
+
+ public void delete(String key) {
+ redisTemplate.delete(key);
+ }
+
+ /**
+ * Object转成JSON数据
+ */
+ private String toJson(Object object){
+ if(object instanceof Integer || object instanceof Long || object instanceof Float ||
+ object instanceof Double || object instanceof Boolean || object instanceof String){
+ return String.valueOf(object);
+ }
+ return gson.toJson(object);
+ }
+
+ /**
+ * JSON数据,转成Object
+ */
+ private T fromJson(String json, Class clazz){
+ return gson.fromJson(json, clazz);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/ShiroUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/ShiroUtils.java
new file mode 100644
index 0000000..fdf0f14
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/ShiroUtils.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import io.renren.common.exception.RRException;
+import io.renren.modules.sys.entity.SysUserEntity;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+
+/**
+ * Shiro工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ShiroUtils {
+
+ public static Session getSession() {
+ return SecurityUtils.getSubject().getSession();
+ }
+
+ public static Subject getSubject() {
+ return SecurityUtils.getSubject();
+ }
+
+ public static SysUserEntity getUserEntity() {
+ return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();
+ }
+
+ public static Long getUserId() {
+ return getUserEntity().getUserId();
+ }
+
+ public static void setSessionAttribute(Object key, Object value) {
+ getSession().setAttribute(key, value);
+ }
+
+ public static Object getSessionAttribute(Object key) {
+ return getSession().getAttribute(key);
+ }
+
+ public static boolean isLogin() {
+ return SecurityUtils.getSubject().getPrincipal() != null;
+ }
+
+ public static String getKaptcha(String key) {
+ Object kaptcha = getSessionAttribute(key);
+ if(kaptcha == null){
+ throw new RRException("验证码已失效");
+ }
+ getSession().removeAttribute(key);
+ return kaptcha.toString();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/utils/SpringContextUtils.java b/renren-fast-master/src/main/java/io/renren/common/utils/SpringContextUtils.java
new file mode 100644
index 0000000..84e787c
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/utils/SpringContextUtils.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring Context 工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+ public static ApplicationContext applicationContext;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ SpringContextUtils.applicationContext = applicationContext;
+ }
+
+ public static Object getBean(String name) {
+ return applicationContext.getBean(name);
+ }
+
+ public static T getBean(String name, Class requiredType) {
+ return applicationContext.getBean(name, requiredType);
+ }
+
+ public static boolean containsBean(String name) {
+ return applicationContext.containsBean(name);
+ }
+
+ public static boolean isSingleton(String name) {
+ return applicationContext.isSingleton(name);
+ }
+
+ public static Class extends Object> getType(String name) {
+ return applicationContext.getType(name);
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/Assert.java b/renren-fast-master/src/main/java/io/renren/common/validator/Assert.java
new file mode 100644
index 0000000..614e9bc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/Assert.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator;
+
+import io.renren.common.exception.RRException;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * 数据校验
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public abstract class Assert {
+
+ public static void isBlank(String str, String message) {
+ if (StringUtils.isBlank(str)) {
+ throw new RRException(message);
+ }
+ }
+
+ public static void isNull(Object object, String message) {
+ if (object == null) {
+ throw new RRException(message);
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/ValidatorUtils.java b/renren-fast-master/src/main/java/io/renren/common/validator/ValidatorUtils.java
new file mode 100644
index 0000000..06cdb0a
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/ValidatorUtils.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator;
+
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.Constant;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * hibernate-validator校验工具类
+ *
+ * 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ValidatorUtils {
+ private static Validator validator;
+
+ static {
+ validator = Validation.buildDefaultValidatorFactory().getValidator();
+ }
+
+ /**
+ * 校验对象
+ * @param object 待校验对象
+ * @param groups 待校验的组
+ * @throws RRException 校验不通过,则报RRException异常
+ */
+ public static void validateEntity(Object object, Class>... groups)
+ throws RRException {
+ Set> constraintViolations = validator.validate(object, groups);
+ if (!constraintViolations.isEmpty()) {
+ StringBuilder msg = new StringBuilder();
+ for (ConstraintViolation constraint : constraintViolations) {
+ msg.append(constraint.getMessage()).append(" ");
+ }
+ throw new RRException(msg.toString());
+ }
+ }
+
+ public static void validateEntity(Object object, Constant.CloudService type) {
+ validateEntity(object, type.getValidatorGroupClass());
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/AddGroup.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/AddGroup.java
new file mode 100644
index 0000000..81e75ad
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/AddGroup.java
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+/**
+ * 新增数据 Group
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface AddGroup {
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/AliyunGroup.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/AliyunGroup.java
new file mode 100644
index 0000000..f05a8cc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/AliyunGroup.java
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+/**
+ * 阿里云
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface AliyunGroup {
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/Group.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/Group.java
new file mode 100644
index 0000000..5004667
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/Group.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+import javax.validation.GroupSequence;
+
+/**
+ * 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@GroupSequence({AddGroup.class, UpdateGroup.class})
+public interface Group {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/QcloudGroup.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/QcloudGroup.java
new file mode 100644
index 0000000..23ad4e9
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/QcloudGroup.java
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+/**
+ * 腾讯云
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface QcloudGroup {
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/QiniuGroup.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/QiniuGroup.java
new file mode 100644
index 0000000..1297075
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/QiniuGroup.java
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+/**
+ * 七牛
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface QiniuGroup {
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/validator/group/UpdateGroup.java b/renren-fast-master/src/main/java/io/renren/common/validator/group/UpdateGroup.java
new file mode 100644
index 0000000..a917c55
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/validator/group/UpdateGroup.java
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.validator.group;
+
+/**
+ * 更新数据 Group
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+
+public interface UpdateGroup {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/xss/HTMLFilter.java b/renren-fast-master/src/main/java/io/renren/common/xss/HTMLFilter.java
new file mode 100644
index 0000000..3b5de73
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/xss/HTMLFilter.java
@@ -0,0 +1,530 @@
+package io.renren.common.xss;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * HTML filtering utility for protecting against XSS (Cross Site Scripting).
+ *
+ * This code is licensed LGPLv3
+ *
+ * This code is a Java port of the original work in PHP by Cal Hendersen.
+ * http://code.iamcal.com/php/lib_filter/
+ *
+ * The trickiest part of the translation was handling the differences in regex handling
+ * between PHP and Java. These resources were helpful in the process:
+ *
+ * http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html
+ * http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php
+ * http://www.regular-expressions.info/modifiers.html
+ *
+ * A note on naming conventions: instance variables are prefixed with a "v"; global
+ * constants are in all caps.
+ *
+ * Sample use:
+ * String input = ...
+ * String clean = new HTMLFilter().filter( input );
+ *
+ * The class is not thread safe. Create a new instance if in doubt.
+ *
+ * If you find bugs or have suggestions on improvement (especially regarding
+ * performance), please contact us. The latest version of this
+ * source, and our contact details, can be found at http://xss-html-filter.sf.net
+ *
+ * @author Joseph O'Connell
+ * @author Cal Hendersen
+ * @author Michael Semb Wever
+ */
+public final class HTMLFilter {
+
+ /** regex flag union representing /si modifiers in php **/
+ private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
+ private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL);
+ private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
+ private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
+ private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
+ private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
+ private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
+ private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
+ private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
+ private static final Pattern P_ENTITY = Pattern.compile("(\\d+);?");
+ private static final Pattern P_ENTITY_UNICODE = Pattern.compile("([0-9a-f]+);?");
+ private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
+ private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
+ private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
+ private static final Pattern P_END_ARROW = Pattern.compile("^>");
+ private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
+ private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
+ private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
+ private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
+ private static final Pattern P_AMP = Pattern.compile("&");
+ private static final Pattern P_QUOTE = Pattern.compile("<");
+ private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
+ private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
+ private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
+
+ // @xxx could grow large... maybe use sesat's ReferenceMap
+ private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap();
+ private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap();
+
+ /** set of allowed html elements, along with allowed attributes for each element **/
+ private final Map> vAllowed;
+ /** counts of open tags for each (allowable) html element **/
+ private final Map vTagCounts = new HashMap();
+
+ /** html elements which must always be self-closing (e.g. " ") **/
+ private final String[] vSelfClosingTags;
+ /** html elements which must always have separate opening and closing tags (e.g. " ") **/
+ private final String[] vNeedClosingTags;
+ /** set of disallowed html elements **/
+ private final String[] vDisallowed;
+ /** attributes which should be checked for valid protocols **/
+ private final String[] vProtocolAtts;
+ /** allowed protocols **/
+ private final String[] vAllowedProtocols;
+ /** tags which should be removed if they contain no content (e.g. " " or " ") **/
+ private final String[] vRemoveBlanks;
+ /** entities allowed within html markup **/
+ private final String[] vAllowedEntities;
+ /** flag determining whether comments are allowed in input String. */
+ private final boolean stripComment;
+ private final boolean encodeQuotes;
+ private boolean vDebug = false;
+ /**
+ * flag determining whether to try to make tags when presented with "unbalanced"
+ * angle brackets (e.g. "" becomes " text "). If set to false,
+ * unbalanced angle brackets will be html escaped.
+ */
+ private final boolean alwaysMakeTags;
+
+ /** Default constructor.
+ *
+ */
+ public HTMLFilter() {
+ vAllowed = new HashMap<>();
+
+ final ArrayList a_atts = new ArrayList();
+ a_atts.add("href");
+ a_atts.add("target");
+ vAllowed.put("a", a_atts);
+
+ final ArrayList img_atts = new ArrayList();
+ img_atts.add("src");
+ img_atts.add("width");
+ img_atts.add("height");
+ img_atts.add("alt");
+ vAllowed.put("img", img_atts);
+
+ final ArrayList no_atts = new ArrayList();
+ vAllowed.put("b", no_atts);
+ vAllowed.put("strong", no_atts);
+ vAllowed.put("i", no_atts);
+ vAllowed.put("em", no_atts);
+
+ vSelfClosingTags = new String[]{"img"};
+ vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};
+ vDisallowed = new String[]{};
+ vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.
+ vProtocolAtts = new String[]{"src", "href"};
+ vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};
+ vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};
+ stripComment = true;
+ encodeQuotes = true;
+ alwaysMakeTags = true;
+ }
+
+ /** Set debug flag to true. Otherwise use default settings. See the default constructor.
+ *
+ * @param debug turn debug on with a true argument
+ */
+ public HTMLFilter(final boolean debug) {
+ this();
+ vDebug = debug;
+
+ }
+
+ /** Map-parameter configurable constructor.
+ *
+ * @param conf map containing configuration. keys match field names.
+ */
+ public HTMLFilter(final Map conf) {
+
+ assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
+ assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
+ assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
+ assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
+ assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
+ assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
+ assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
+ assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
+
+ vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed"));
+ vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
+ vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
+ vDisallowed = (String[]) conf.get("vDisallowed");
+ vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
+ vProtocolAtts = (String[]) conf.get("vProtocolAtts");
+ vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
+ vAllowedEntities = (String[]) conf.get("vAllowedEntities");
+ stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
+ encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
+ alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
+ }
+
+ private void reset() {
+ vTagCounts.clear();
+ }
+
+ private void debug(final String msg) {
+ if (vDebug) {
+ Logger.getAnonymousLogger().info(msg);
+ }
+ }
+
+ //---------------------------------------------------------------
+ // my versions of some PHP library functions
+ public static String chr(final int decimal) {
+ return String.valueOf((char) decimal);
+ }
+
+ public static String htmlSpecialChars(final String s) {
+ String result = s;
+ result = regexReplace(P_AMP, "&", result);
+ result = regexReplace(P_QUOTE, """, result);
+ result = regexReplace(P_LEFT_ARROW, "<", result);
+ result = regexReplace(P_RIGHT_ARROW, ">", result);
+ return result;
+ }
+
+ //---------------------------------------------------------------
+ /**
+ * given a user submitted input String, filter out any invalid or restricted
+ * html.
+ *
+ * @param input text (i.e. submitted by a user) than may contain html
+ * @return "clean" version of input, with only valid, whitelisted html elements allowed
+ */
+ public String filter(final String input) {
+ reset();
+ String s = input;
+
+ debug("************************************************");
+ debug(" INPUT: " + input);
+
+ s = escapeComments(s);
+ debug(" escapeComments: " + s);
+
+ s = balanceHTML(s);
+ debug(" balanceHTML: " + s);
+
+ s = checkTags(s);
+ debug(" checkTags: " + s);
+
+ s = processRemoveBlanks(s);
+ debug("processRemoveBlanks: " + s);
+
+ s = validateEntities(s);
+ debug(" validateEntites: " + s);
+
+ debug("************************************************\n\n");
+ return s;
+ }
+
+ public boolean isAlwaysMakeTags(){
+ return alwaysMakeTags;
+ }
+
+ public boolean isStripComments(){
+ return stripComment;
+ }
+
+ private String escapeComments(final String s) {
+ final Matcher m = P_COMMENTS.matcher(s);
+ final StringBuffer buf = new StringBuffer();
+ if (m.find()) {
+ final String match = m.group(1); //(.*?)
+ m.appendReplacement(buf, Matcher.quoteReplacement(""));
+ }
+ m.appendTail(buf);
+
+ return buf.toString();
+ }
+
+ private String balanceHTML(String s) {
+ if (alwaysMakeTags) {
+ //
+ // try and form html
+ //
+ s = regexReplace(P_END_ARROW, "", s);
+ s = regexReplace(P_BODY_TO_END, "<$1>", s);
+ s = regexReplace(P_XML_CONTENT, "$1<$2", s);
+
+ } else {
+ //
+ // escape stray brackets
+ //
+ s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s);
+ s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s);
+
+ //
+ // the last regexp causes '<>' entities to appear
+ // (we need to do a lookahead assertion so that the last bracket can
+ // be used in the next pass of the regexp)
+ //
+ s = regexReplace(P_BOTH_ARROWS, "", s);
+ }
+
+ return s;
+ }
+
+ private String checkTags(String s) {
+ Matcher m = P_TAGS.matcher(s);
+
+ final StringBuffer buf = new StringBuffer();
+ while (m.find()) {
+ String replaceStr = m.group(1);
+ replaceStr = processTag(replaceStr);
+ m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
+ }
+ m.appendTail(buf);
+
+ s = buf.toString();
+
+ // these get tallied in processTag
+ // (remember to reset before subsequent calls to filter method)
+ for (String key : vTagCounts.keySet()) {
+ for (int ii = 0; ii < vTagCounts.get(key); ii++) {
+ s += "" + key + ">";
+ }
+ }
+
+ return s;
+ }
+
+ private String processRemoveBlanks(final String s) {
+ String result = s;
+ for (String tag : vRemoveBlanks) {
+ if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){
+ P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>" + tag + ">"));
+ }
+ result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
+ if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){
+ P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
+ }
+ result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
+ }
+
+ return result;
+ }
+
+ private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {
+ Matcher m = regex_pattern.matcher(s);
+ return m.replaceAll(replacement);
+ }
+
+ private String processTag(final String s) {
+ // ending tags
+ Matcher m = P_END_TAG.matcher(s);
+ if (m.find()) {
+ final String name = m.group(1).toLowerCase();
+ if (allowed(name)) {
+ if (!inArray(name, vSelfClosingTags)) {
+ if (vTagCounts.containsKey(name)) {
+ vTagCounts.put(name, vTagCounts.get(name) - 1);
+ return "" + name + ">";
+ }
+ }
+ }
+ }
+
+ // starting tags
+ m = P_START_TAG.matcher(s);
+ if (m.find()) {
+ final String name = m.group(1).toLowerCase();
+ final String body = m.group(2);
+ String ending = m.group(3);
+
+ //debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
+ if (allowed(name)) {
+ String params = "";
+
+ final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
+ final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
+ final List paramNames = new ArrayList();
+ final List paramValues = new ArrayList();
+ while (m2.find()) {
+ paramNames.add(m2.group(1)); //([a-z0-9]+)
+ paramValues.add(m2.group(3)); //(.*?)
+ }
+ while (m3.find()) {
+ paramNames.add(m3.group(1)); //([a-z0-9]+)
+ paramValues.add(m3.group(3)); //([^\"\\s']+)
+ }
+
+ String paramName, paramValue;
+ for (int ii = 0; ii < paramNames.size(); ii++) {
+ paramName = paramNames.get(ii).toLowerCase();
+ paramValue = paramValues.get(ii);
+
+// debug( "paramName='" + paramName + "'" );
+// debug( "paramValue='" + paramValue + "'" );
+// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
+
+ if (allowedAttribute(name, paramName)) {
+ if (inArray(paramName, vProtocolAtts)) {
+ paramValue = processParamProtocol(paramValue);
+ }
+ params += " " + paramName + "=\"" + paramValue + "\"";
+ }
+ }
+
+ if (inArray(name, vSelfClosingTags)) {
+ ending = " /";
+ }
+
+ if (inArray(name, vNeedClosingTags)) {
+ ending = "";
+ }
+
+ if (ending == null || ending.length() < 1) {
+ if (vTagCounts.containsKey(name)) {
+ vTagCounts.put(name, vTagCounts.get(name) + 1);
+ } else {
+ vTagCounts.put(name, 1);
+ }
+ } else {
+ ending = " /";
+ }
+ return "<" + name + params + ending + ">";
+ } else {
+ return "";
+ }
+ }
+
+ // comments
+ m = P_COMMENT.matcher(s);
+ if (!stripComment && m.find()) {
+ return "<" + m.group() + ">";
+ }
+
+ return "";
+ }
+
+ private String processParamProtocol(String s) {
+ s = decodeEntities(s);
+ final Matcher m = P_PROTOCOL.matcher(s);
+ if (m.find()) {
+ final String protocol = m.group(1);
+ if (!inArray(protocol, vAllowedProtocols)) {
+ // bad protocol, turn into local anchor link instead
+ s = "#" + s.substring(protocol.length() + 1, s.length());
+ if (s.startsWith("#//")) {
+ s = "#" + s.substring(3, s.length());
+ }
+ }
+ }
+
+ return s;
+ }
+
+ private String decodeEntities(String s) {
+ StringBuffer buf = new StringBuffer();
+
+ Matcher m = P_ENTITY.matcher(s);
+ while (m.find()) {
+ final String match = m.group(1);
+ final int decimal = Integer.decode(match).intValue();
+ m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
+ }
+ m.appendTail(buf);
+ s = buf.toString();
+
+ buf = new StringBuffer();
+ m = P_ENTITY_UNICODE.matcher(s);
+ while (m.find()) {
+ final String match = m.group(1);
+ final int decimal = Integer.valueOf(match, 16).intValue();
+ m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
+ }
+ m.appendTail(buf);
+ s = buf.toString();
+
+ buf = new StringBuffer();
+ m = P_ENCODE.matcher(s);
+ while (m.find()) {
+ final String match = m.group(1);
+ final int decimal = Integer.valueOf(match, 16).intValue();
+ m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
+ }
+ m.appendTail(buf);
+ s = buf.toString();
+
+ s = validateEntities(s);
+ return s;
+ }
+
+ private String validateEntities(final String s) {
+ StringBuffer buf = new StringBuffer();
+
+ // validate entities throughout the string
+ Matcher m = P_VALID_ENTITIES.matcher(s);
+ while (m.find()) {
+ final String one = m.group(1); //([^&;]*)
+ final String two = m.group(2); //(?=(;|&|$))
+ m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
+ }
+ m.appendTail(buf);
+
+ return encodeQuotes(buf.toString());
+ }
+
+ private String encodeQuotes(final String s){
+ if(encodeQuotes){
+ StringBuffer buf = new StringBuffer();
+ Matcher m = P_VALID_QUOTES.matcher(s);
+ while (m.find()) {
+ final String one = m.group(1); //(>|^)
+ final String two = m.group(2); //([^<]+?)
+ final String three = m.group(3); //(<|$)
+ m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three));
+ }
+ m.appendTail(buf);
+ return buf.toString();
+ }else{
+ return s;
+ }
+ }
+
+ private String checkEntity(final String preamble, final String term) {
+
+ return ";".equals(term) && isValidEntity(preamble)
+ ? '&' + preamble
+ : "&" + preamble;
+ }
+
+ private boolean isValidEntity(final String entity) {
+ return inArray(entity, vAllowedEntities);
+ }
+
+ private static boolean inArray(final String s, final String[] array) {
+ for (String item : array) {
+ if (item != null && item.equals(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean allowed(final String name) {
+ return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
+ }
+
+ private boolean allowedAttribute(final String name, final String paramName) {
+ return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/common/xss/SQLFilter.java b/renren-fast-master/src/main/java/io/renren/common/xss/SQLFilter.java
new file mode 100644
index 0000000..0675ddc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/xss/SQLFilter.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.xss;
+
+import io.renren.common.exception.RRException;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * SQL过滤
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class SQLFilter {
+
+ /**
+ * SQL注入过滤
+ * @param str 待验证的字符串
+ */
+ public static String sqlInject(String str){
+ if(StringUtils.isBlank(str)){
+ return null;
+ }
+ //去掉'|"|;|\字符
+ str = StringUtils.replace(str, "'", "");
+ str = StringUtils.replace(str, "\"", "");
+ str = StringUtils.replace(str, ";", "");
+ str = StringUtils.replace(str, "\\", "");
+
+ //转换成小写
+ str = str.toLowerCase();
+
+ //非法字符
+ String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};
+
+ //判断是否包含非法字符
+ for(String keyword : keywords){
+ if(str.indexOf(keyword) != -1){
+ throw new RRException("包含非法字符");
+ }
+ }
+
+ return str;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/common/xss/XssFilter.java b/renren-fast-master/src/main/java/io/renren/common/xss/XssFilter.java
new file mode 100644
index 0000000..f12921b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/xss/XssFilter.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.xss;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * XSS过滤
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class XssFilter implements Filter {
+
+ @Override
+ public void init(FilterConfig config) throws ServletException {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
+ (HttpServletRequest) request);
+ chain.doFilter(xssRequest, response);
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java b/renren-fast-master/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java
new file mode 100644
index 0000000..75a0e47
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.common.xss;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * XSS过滤处理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
+ //没被包装过的HttpServletRequest(特殊场景,需要自己过滤)
+ HttpServletRequest orgRequest;
+ //html过滤
+ private final static HTMLFilter htmlFilter = new HTMLFilter();
+
+ public XssHttpServletRequestWrapper(HttpServletRequest request) {
+ super(request);
+ orgRequest = request;
+ }
+
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+ //非json类型,直接返回
+ if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){
+ return super.getInputStream();
+ }
+
+ //为空,直接返回
+ String json = IOUtils.toString(super.getInputStream(), "utf-8");
+ if (StringUtils.isBlank(json)) {
+ return super.getInputStream();
+ }
+
+ //xss过滤
+ json = xssEncode(json);
+ final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
+ return new ServletInputStream() {
+ @Override
+ public boolean isFinished() {
+ return true;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+
+ }
+
+ @Override
+ public int read() throws IOException {
+ return bis.read();
+ }
+ };
+ }
+
+ @Override
+ public String getParameter(String name) {
+ String value = super.getParameter(xssEncode(name));
+ if (StringUtils.isNotBlank(value)) {
+ value = xssEncode(value);
+ }
+ return value;
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ String[] parameters = super.getParameterValues(name);
+ if (parameters == null || parameters.length == 0) {
+ return null;
+ }
+
+ for (int i = 0; i < parameters.length; i++) {
+ parameters[i] = xssEncode(parameters[i]);
+ }
+ return parameters;
+ }
+
+ @Override
+ public Map getParameterMap() {
+ Map map = new LinkedHashMap<>();
+ Map parameters = super.getParameterMap();
+ for (String key : parameters.keySet()) {
+ String[] values = parameters.get(key);
+ for (int i = 0; i < values.length; i++) {
+ values[i] = xssEncode(values[i]);
+ }
+ map.put(key, values);
+ }
+ return map;
+ }
+
+ @Override
+ public String getHeader(String name) {
+ String value = super.getHeader(xssEncode(name));
+ if (StringUtils.isNotBlank(value)) {
+ value = xssEncode(value);
+ }
+ return value;
+ }
+
+ private String xssEncode(String input) {
+ return htmlFilter.filter(input);
+ }
+
+ /**
+ * 获取最原始的request
+ */
+ public HttpServletRequest getOrgRequest() {
+ return orgRequest;
+ }
+
+ /**
+ * 获取最原始的request
+ */
+ public static HttpServletRequest getOrgRequest(HttpServletRequest request) {
+ if (request instanceof XssHttpServletRequestWrapper) {
+ return ((XssHttpServletRequestWrapper) request).getOrgRequest();
+ }
+
+ return request;
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/CorsConfig.java b/renren-fast-master/src/main/java/io/renren/config/CorsConfig.java
new file mode 100644
index 0000000..830ffce
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/CorsConfig.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOriginPatterns("*")
+ .allowCredentials(true)
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+ .maxAge(3600);
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/config/FilterConfig.java b/renren-fast-master/src/main/java/io/renren/config/FilterConfig.java
new file mode 100644
index 0000000..a6687f2
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/FilterConfig.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import io.renren.common.xss.XssFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.filter.DelegatingFilterProxy;
+
+import javax.servlet.DispatcherType;
+
+/**
+ * Filter配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class FilterConfig {
+
+ @Bean
+ public FilterRegistrationBean shiroFilterRegistration() {
+ FilterRegistrationBean registration = new FilterRegistrationBean();
+ registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
+ //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
+ registration.addInitParameter("targetFilterLifecycle", "true");
+ registration.setEnabled(true);
+ registration.setOrder(Integer.MAX_VALUE - 1);
+ registration.addUrlPatterns("/*");
+ return registration;
+ }
+
+ @Bean
+ public FilterRegistrationBean xssFilterRegistration() {
+ FilterRegistrationBean registration = new FilterRegistrationBean();
+ registration.setDispatcherTypes(DispatcherType.REQUEST);
+ registration.setFilter(new XssFilter());
+ registration.addUrlPatterns("/*");
+ registration.setName("xssFilter");
+ registration.setOrder(Integer.MAX_VALUE);
+ return registration;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/KaptchaConfig.java b/renren-fast-master/src/main/java/io/renren/config/KaptchaConfig.java
new file mode 100644
index 0000000..d22375b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/KaptchaConfig.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+
+/**
+ * 生成验证码配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class KaptchaConfig {
+
+ @Bean
+ public DefaultKaptcha producer() {
+ Properties properties = new Properties();
+ properties.put("kaptcha.border", "no");
+ properties.put("kaptcha.textproducer.font.color", "black");
+ properties.put("kaptcha.textproducer.char.space", "5");
+ properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
+ Config config = new Config(properties);
+ DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+ defaultKaptcha.setConfig(config);
+ return defaultKaptcha;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/MybatisPlusConfig.java b/renren-fast-master/src/main/java/io/renren/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..05aa984
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/MybatisPlusConfig.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * mybatis-plus配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+ /**
+ * 分页插件
+ */
+ @Bean
+ public PaginationInterceptor paginationInterceptor() {
+ return new PaginationInterceptor();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/RedisConfig.java b/renren-fast-master/src/main/java/io/renren/config/RedisConfig.java
new file mode 100644
index 0000000..97d033b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/RedisConfig.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class RedisConfig {
+ @Autowired
+ private RedisConnectionFactory factory;
+
+ @Bean
+ public RedisTemplate redisTemplate() {
+ RedisTemplate redisTemplate = new RedisTemplate<>();
+ redisTemplate.setKeySerializer(new StringRedisSerializer());
+ redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+ redisTemplate.setHashValueSerializer(new StringRedisSerializer());
+ redisTemplate.setValueSerializer(new StringRedisSerializer());
+ redisTemplate.setConnectionFactory(factory);
+ return redisTemplate;
+ }
+
+ @Bean
+ public HashOperations hashOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForHash();
+ }
+
+ @Bean
+ public ValueOperations valueOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForValue();
+ }
+
+ @Bean
+ public ListOperations listOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForList();
+ }
+
+ @Bean
+ public SetOperations setOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForSet();
+ }
+
+ @Bean
+ public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForZSet();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/ShiroConfig.java b/renren-fast-master/src/main/java/io/renren/config/ShiroConfig.java
new file mode 100644
index 0000000..0925246
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/ShiroConfig.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import io.renren.modules.sys.oauth2.OAuth2Filter;
+import io.renren.modules.sys.oauth2.OAuth2Realm;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+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.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.Filter;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Shiro配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class ShiroConfig {
+
+ @Bean("securityManager")
+ public SecurityManager securityManager(OAuth2Realm oAuth2Realm) {
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+ securityManager.setRealm(oAuth2Realm);
+ securityManager.setRememberMeManager(null);
+ return securityManager;
+ }
+
+ @Bean("shiroFilter")
+ public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
+ ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
+ shiroFilter.setSecurityManager(securityManager);
+
+ //oauth过滤
+ Map filters = new HashMap<>();
+ filters.put("oauth2", new OAuth2Filter());
+ shiroFilter.setFilters(filters);
+
+ Map filterMap = new LinkedHashMap<>();
+ filterMap.put("/webjars/**", "anon");
+ filterMap.put("/druid/**", "anon");
+ filterMap.put("/app/**", "anon");
+ filterMap.put("/sys/login", "anon");
+ filterMap.put("/swagger/**", "anon");
+ filterMap.put("/v2/api-docs", "anon");
+ filterMap.put("/swagger-ui.html", "anon");
+ filterMap.put("/swagger-resources/**", "anon");
+ filterMap.put("/captcha.jpg", "anon");
+ filterMap.put("/aaa.txt", "anon");
+ filterMap.put("/**", "oauth2");
+ shiroFilter.setFilterChainDefinitionMap(filterMap);
+
+ return shiroFilter;
+ }
+
+ @Bean("lifecycleBeanPostProcessor")
+ public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+ return new LifecycleBeanPostProcessor();
+ }
+
+ @Bean
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
+ advisor.setSecurityManager(securityManager);
+ return advisor;
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/config/SwaggerConfig.java b/renren-fast-master/src/main/java/io/renren/config/SwaggerConfig.java
new file mode 100644
index 0000000..211b6b4
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/config/SwaggerConfig.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.config;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig implements WebMvcConfigurer {
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .select()
+ //加了ApiOperation注解的类,才生成接口文档
+ .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+ //包下的类,才生成接口文档
+ //.apis(RequestHandlerSelectors.basePackage("io.renren.controller"))
+ .paths(PathSelectors.any())
+ .build()
+ .securitySchemes(security());
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("人人开源")
+ .description("renren-fast文档")
+ .termsOfServiceUrl("https://www.renren.io")
+ .version("3.0.0")
+ .build();
+ }
+
+ private List security() {
+ return newArrayList(
+ new ApiKey("token", "token", "header")
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/annotation/DataSource.java b/renren-fast-master/src/main/java/io/renren/datasource/annotation/DataSource.java
new file mode 100644
index 0000000..1dd140a
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/annotation/DataSource.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 多数据源注解
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface DataSource {
+ String value() default "";
+}
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java b/renren-fast-master/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java
new file mode 100644
index 0000000..3ee6c1f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.aspect;
+
+
+import io.renren.datasource.annotation.DataSource;
+import io.renren.datasource.config.DynamicContextHolder;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+/**
+ * 多数据源,切面处理类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Aspect
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class DataSourceAspect {
+ protected Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Pointcut("@annotation(io.renren.datasource.annotation.DataSource) " +
+ "|| @within(io.renren.datasource.annotation.DataSource)")
+ public void dataSourcePointCut() {
+
+ }
+
+ @Around("dataSourcePointCut()")
+ public Object around(ProceedingJoinPoint point) throws Throwable {
+ MethodSignature signature = (MethodSignature) point.getSignature();
+ Class targetClass = point.getTarget().getClass();
+ Method method = signature.getMethod();
+
+ DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
+ DataSource methodDataSource = method.getAnnotation(DataSource.class);
+ if(targetDataSource != null || methodDataSource != null){
+ String value;
+ if(methodDataSource != null){
+ value = methodDataSource.value();
+ }else {
+ value = targetDataSource.value();
+ }
+
+ DynamicContextHolder.push(value);
+ logger.debug("set datasource is {}", value);
+ }
+
+ try {
+ return point.proceed();
+ } finally {
+ DynamicContextHolder.poll();
+ logger.debug("clean datasource");
+ }
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicContextHolder.java b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicContextHolder.java
new file mode 100644
index 0000000..d00c5d0
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicContextHolder.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.config;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * 多数据源上下文
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class DynamicContextHolder {
+ @SuppressWarnings("unchecked")
+ private static final ThreadLocal> CONTEXT_HOLDER = new ThreadLocal() {
+ @Override
+ protected Object initialValue() {
+ return new ArrayDeque();
+ }
+ };
+
+ /**
+ * 获得当前线程数据源
+ *
+ * @return 数据源名称
+ */
+ public static String peek() {
+ return CONTEXT_HOLDER.get().peek();
+ }
+
+ /**
+ * 设置当前线程数据源
+ *
+ * @param dataSource 数据源名称
+ */
+ public static void push(String dataSource) {
+ CONTEXT_HOLDER.get().push(dataSource);
+ }
+
+ /**
+ * 清空当前线程数据源
+ */
+ public static void poll() {
+ Deque deque = CONTEXT_HOLDER.get();
+ deque.poll();
+ if (deque.isEmpty()) {
+ CONTEXT_HOLDER.remove();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSource.java b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSource.java
new file mode 100644
index 0000000..7792478
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSource.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.config;
+
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+/**
+ * 多数据源
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class DynamicDataSource extends AbstractRoutingDataSource {
+
+ @Override
+ protected Object determineCurrentLookupKey() {
+ return DynamicContextHolder.peek();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java
new file mode 100644
index 0000000..a0c8ff2
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import io.renren.datasource.properties.DataSourceProperties;
+import io.renren.datasource.properties.DynamicDataSourceProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 配置多数据源
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+@EnableConfigurationProperties(DynamicDataSourceProperties.class)
+public class DynamicDataSourceConfig {
+ @Autowired
+ private DynamicDataSourceProperties properties;
+
+ @Bean
+ @ConfigurationProperties(prefix = "spring.datasource.druid")
+ public DataSourceProperties dataSourceProperties() {
+ return new DataSourceProperties();
+ }
+
+ @Bean
+ public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) {
+ DynamicDataSource dynamicDataSource = new DynamicDataSource();
+ dynamicDataSource.setTargetDataSources(getDynamicDataSource());
+
+ //默认数据源
+ DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties);
+ dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);
+
+ return dynamicDataSource;
+ }
+
+ private Map getDynamicDataSource(){
+ Map dataSourcePropertiesMap = properties.getDatasource();
+ Map targetDataSources = new HashMap<>(dataSourcePropertiesMap.size());
+ dataSourcePropertiesMap.forEach((k, v) -> {
+ DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
+ targetDataSources.put(k, druidDataSource);
+ });
+
+ return targetDataSources;
+ }
+
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java
new file mode 100644
index 0000000..4a688e1
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import io.renren.datasource.properties.DataSourceProperties;
+
+import java.sql.SQLException;
+
+/**
+ * DruidDataSource
+ *
+ * @author Mark sunlightcs@gmail.com
+ * @since 1.0.0
+ */
+public class DynamicDataSourceFactory {
+
+ public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) {
+ DruidDataSource druidDataSource = new DruidDataSource();
+ druidDataSource.setDriverClassName(properties.getDriverClassName());
+ druidDataSource.setUrl(properties.getUrl());
+ druidDataSource.setUsername(properties.getUsername());
+ druidDataSource.setPassword(properties.getPassword());
+
+ druidDataSource.setInitialSize(properties.getInitialSize());
+ druidDataSource.setMaxActive(properties.getMaxActive());
+ druidDataSource.setMinIdle(properties.getMinIdle());
+ druidDataSource.setMaxWait(properties.getMaxWait());
+ druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
+ druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
+ druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
+ druidDataSource.setValidationQuery(properties.getValidationQuery());
+ druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());
+ druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());
+ druidDataSource.setTestOnReturn(properties.isTestOnReturn());
+ druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());
+ druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
+ druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements());
+
+ try {
+ druidDataSource.setFilters(properties.getFilters());
+ druidDataSource.init();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return druidDataSource;
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/properties/DataSourceProperties.java b/renren-fast-master/src/main/java/io/renren/datasource/properties/DataSourceProperties.java
new file mode 100644
index 0000000..6ee7ec5
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/properties/DataSourceProperties.java
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.properties;
+
+/**
+ * 多数据源属性
+ *
+ * @author Mark sunlightcs@gmail.com
+ * @since 1.0.0
+ */
+public class DataSourceProperties {
+ private String driverClassName;
+ private String url;
+ private String username;
+ private String password;
+
+ /**
+ * Druid默认参数
+ */
+ private int initialSize = 2;
+ private int maxActive = 10;
+ private int minIdle = -1;
+ private long maxWait = 60 * 1000L;
+ private long timeBetweenEvictionRunsMillis = 60 * 1000L;
+ private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;
+ private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;
+ private String validationQuery = "select 1";
+ private int validationQueryTimeout = -1;
+ private boolean testOnBorrow = false;
+ private boolean testOnReturn = false;
+ private boolean testWhileIdle = true;
+ private boolean poolPreparedStatements = false;
+ private int maxOpenPreparedStatements = -1;
+ private boolean sharePreparedStatements = false;
+ private String filters = "stat,wall";
+
+ public String getDriverClassName() {
+ return driverClassName;
+ }
+
+ public void setDriverClassName(String driverClassName) {
+ this.driverClassName = driverClassName;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public int getInitialSize() {
+ return initialSize;
+ }
+
+ public void setInitialSize(int initialSize) {
+ this.initialSize = initialSize;
+ }
+
+ public int getMaxActive() {
+ return maxActive;
+ }
+
+ public void setMaxActive(int maxActive) {
+ this.maxActive = maxActive;
+ }
+
+ public int getMinIdle() {
+ return minIdle;
+ }
+
+ public void setMinIdle(int minIdle) {
+ this.minIdle = minIdle;
+ }
+
+ public long getMaxWait() {
+ return maxWait;
+ }
+
+ public void setMaxWait(long maxWait) {
+ this.maxWait = maxWait;
+ }
+
+ public long getTimeBetweenEvictionRunsMillis() {
+ return timeBetweenEvictionRunsMillis;
+ }
+
+ public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
+ this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+ }
+
+ public long getMinEvictableIdleTimeMillis() {
+ return minEvictableIdleTimeMillis;
+ }
+
+ public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
+ this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+ }
+
+ public long getMaxEvictableIdleTimeMillis() {
+ return maxEvictableIdleTimeMillis;
+ }
+
+ public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) {
+ this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis;
+ }
+
+ public String getValidationQuery() {
+ return validationQuery;
+ }
+
+ public void setValidationQuery(String validationQuery) {
+ this.validationQuery = validationQuery;
+ }
+
+ public int getValidationQueryTimeout() {
+ return validationQueryTimeout;
+ }
+
+ public void setValidationQueryTimeout(int validationQueryTimeout) {
+ this.validationQueryTimeout = validationQueryTimeout;
+ }
+
+ public boolean isTestOnBorrow() {
+ return testOnBorrow;
+ }
+
+ public void setTestOnBorrow(boolean testOnBorrow) {
+ this.testOnBorrow = testOnBorrow;
+ }
+
+ public boolean isTestOnReturn() {
+ return testOnReturn;
+ }
+
+ public void setTestOnReturn(boolean testOnReturn) {
+ this.testOnReturn = testOnReturn;
+ }
+
+ public boolean isTestWhileIdle() {
+ return testWhileIdle;
+ }
+
+ public void setTestWhileIdle(boolean testWhileIdle) {
+ this.testWhileIdle = testWhileIdle;
+ }
+
+ public boolean isPoolPreparedStatements() {
+ return poolPreparedStatements;
+ }
+
+ public void setPoolPreparedStatements(boolean poolPreparedStatements) {
+ this.poolPreparedStatements = poolPreparedStatements;
+ }
+
+ public int getMaxOpenPreparedStatements() {
+ return maxOpenPreparedStatements;
+ }
+
+ public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
+ this.maxOpenPreparedStatements = maxOpenPreparedStatements;
+ }
+
+ public boolean isSharePreparedStatements() {
+ return sharePreparedStatements;
+ }
+
+ public void setSharePreparedStatements(boolean sharePreparedStatements) {
+ this.sharePreparedStatements = sharePreparedStatements;
+ }
+
+ public String getFilters() {
+ return filters;
+ }
+
+ public void setFilters(String filters) {
+ this.filters = filters;
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java b/renren-fast-master/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java
new file mode 100644
index 0000000..5759e7b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2018 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.datasource.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 多数据源属性
+ *
+ * @author Mark sunlightcs@gmail.com
+ * @since 1.0.0
+ */
+@ConfigurationProperties(prefix = "dynamic")
+public class DynamicDataSourceProperties {
+ private Map datasource = new LinkedHashMap<>();
+
+ public Map getDatasource() {
+ return datasource;
+ }
+
+ public void setDatasource(Map datasource) {
+ this.datasource = datasource;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/annotation/Login.java b/renren-fast-master/src/main/java/io/renren/modules/app/annotation/Login.java
new file mode 100644
index 0000000..76ec131
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/annotation/Login.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * app登录效验
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Login {
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/annotation/LoginUser.java b/renren-fast-master/src/main/java/io/renren/modules/app/annotation/LoginUser.java
new file mode 100644
index 0000000..c7b29da
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/annotation/LoginUser.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 登录用户信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LoginUser {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/config/WebMvcConfig.java b/renren-fast-master/src/main/java/io/renren/modules/app/config/WebMvcConfig.java
new file mode 100644
index 0000000..c2327a2
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/config/WebMvcConfig.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.config;
+
+import io.renren.modules.app.interceptor.AuthorizationInterceptor;
+import io.renren.modules.app.resolver.LoginUserHandlerMethodArgumentResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.List;
+
+/**
+ * MVC配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+ @Autowired
+ private AuthorizationInterceptor authorizationInterceptor;
+ @Autowired
+ private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(authorizationInterceptor).addPathPatterns("/app/**");
+ }
+
+ @Override
+ public void addArgumentResolvers(List argumentResolvers) {
+ argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppLoginController.java b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppLoginController.java
new file mode 100644
index 0000000..9834021
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppLoginController.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.controller;
+
+
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.app.form.LoginForm;
+import io.renren.modules.app.service.UserService;
+import io.renren.modules.app.utils.JwtUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * APP登录授权
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/app")
+@Api("APP登录接口")
+public class AppLoginController {
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private JwtUtils jwtUtils;
+
+ /**
+ * 登录
+ */
+ @PostMapping("login")
+ @ApiOperation("登录")
+ public R login(@RequestBody LoginForm form){
+ //表单校验
+ ValidatorUtils.validateEntity(form);
+
+ //用户登录
+ long userId = userService.login(form);
+
+ //生成token
+ String token = jwtUtils.generateToken(userId);
+
+ Map map = new HashMap<>();
+ map.put("token", token);
+ map.put("expire", jwtUtils.getExpire());
+
+ return R.ok(map);
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppRegisterController.java b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppRegisterController.java
new file mode 100644
index 0000000..89b38af
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppRegisterController.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.controller;
+
+
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.app.entity.UserEntity;
+import io.renren.modules.app.form.RegisterForm;
+import io.renren.modules.app.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+
+/**
+ * 注册
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/app")
+@Api("APP注册接口")
+public class AppRegisterController {
+ @Autowired
+ private UserService userService;
+
+ @PostMapping("register")
+ @ApiOperation("注册")
+ public R register(@RequestBody RegisterForm form){
+ //表单校验
+ ValidatorUtils.validateEntity(form);
+
+ UserEntity user = new UserEntity();
+ user.setMobile(form.getMobile());
+ user.setUsername(form.getMobile());
+ user.setPassword(DigestUtils.sha256Hex(form.getPassword()));
+ user.setCreateTime(new Date());
+ userService.save(user);
+
+ return R.ok();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppTestController.java b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppTestController.java
new file mode 100644
index 0000000..1965199
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/controller/AppTestController.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.controller;
+
+
+import io.renren.common.utils.R;
+import io.renren.modules.app.annotation.Login;
+import io.renren.modules.app.annotation.LoginUser;
+import io.renren.modules.app.entity.UserEntity;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * APP测试接口
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/app")
+@Api("APP测试接口")
+public class AppTestController {
+
+ @Login
+ @GetMapping("userInfo")
+ @ApiOperation("获取用户信息")
+ public R userInfo(@LoginUser UserEntity user){
+ return R.ok().put("user", user);
+ }
+
+ @Login
+ @GetMapping("userId")
+ @ApiOperation("获取用户ID")
+ public R userInfo(@RequestAttribute("userId") Integer userId){
+ return R.ok().put("userId", userId);
+ }
+
+ @GetMapping("notToken")
+ @ApiOperation("忽略Token验证测试")
+ public R notToken(){
+ return R.ok().put("msg", "无需token也能访问。。。");
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/dao/UserDao.java b/renren-fast-master/src/main/java/io/renren/modules/app/dao/UserDao.java
new file mode 100644
index 0000000..cb70950
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/dao/UserDao.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.app.entity.UserEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface UserDao extends BaseMapper {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/entity/UserEntity.java b/renren-fast-master/src/main/java/io/renren/modules/app/entity/UserEntity.java
new file mode 100644
index 0000000..5a4b1ed
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/entity/UserEntity.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("tb_user")
+public class UserEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID
+ */
+ @TableId
+ private Long userId;
+ /**
+ * 用户名
+ */
+ private String username;
+ /**
+ * 手机号
+ */
+ private String mobile;
+ /**
+ * 密码
+ */
+ private String password;
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/form/LoginForm.java b/renren-fast-master/src/main/java/io/renren/modules/app/form/LoginForm.java
new file mode 100644
index 0000000..8bd16c5
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/form/LoginForm.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.form;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 登录表单
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@ApiModel(value = "登录表单")
+public class LoginForm {
+ @ApiModelProperty(value = "手机号")
+ @NotBlank(message="手机号不能为空")
+ private String mobile;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank(message="密码不能为空")
+ private String password;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/form/RegisterForm.java b/renren-fast-master/src/main/java/io/renren/modules/app/form/RegisterForm.java
new file mode 100644
index 0000000..1700de1
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/form/RegisterForm.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.form;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 注册表单
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@ApiModel(value = "注册表单")
+public class RegisterForm {
+ @ApiModelProperty(value = "手机号")
+ @NotBlank(message="手机号不能为空")
+ private String mobile;
+
+ @ApiModelProperty(value = "密码")
+ @NotBlank(message="密码不能为空")
+ private String password;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java b/renren-fast-master/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java
new file mode 100644
index 0000000..f7d35de
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.interceptor;
+
+
+import io.jsonwebtoken.Claims;
+import io.renren.common.exception.RRException;
+import io.renren.modules.app.utils.JwtUtils;
+import io.renren.modules.app.annotation.Login;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 权限(Token)验证
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
+ @Autowired
+ private JwtUtils jwtUtils;
+
+ public static final String USER_KEY = "userId";
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ Login annotation;
+ if(handler instanceof HandlerMethod) {
+ annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
+ }else{
+ return true;
+ }
+
+ if(annotation == null){
+ return true;
+ }
+
+ //获取用户凭证
+ String token = request.getHeader(jwtUtils.getHeader());
+ if(StringUtils.isBlank(token)){
+ token = request.getParameter(jwtUtils.getHeader());
+ }
+
+ //凭证为空
+ if(StringUtils.isBlank(token)){
+ throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
+ }
+
+ Claims claims = jwtUtils.getClaimByToken(token);
+ if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
+ throw new RRException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
+ }
+
+ //设置userId到request里,后续根据userId,获取用户信息
+ request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject()));
+
+ return true;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java b/renren-fast-master/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java
new file mode 100644
index 0000000..5597179
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.resolver;
+
+import io.renren.modules.app.annotation.LoginUser;
+import io.renren.modules.app.entity.UserEntity;
+import io.renren.modules.app.interceptor.AuthorizationInterceptor;
+import io.renren.modules.app.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+/**
+ * 有@LoginUser注解的方法参数,注入当前登录用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
+ @Autowired
+ private UserService userService;
+
+ @Override
+ public boolean supportsParameter(MethodParameter parameter) {
+ return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
+ }
+
+ @Override
+ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
+ NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
+ //获取用户ID
+ Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
+ if(object == null){
+ return null;
+ }
+
+ //获取用户信息
+ UserEntity user = userService.getById((Long)object);
+
+ return user;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/service/UserService.java b/renren-fast-master/src/main/java/io/renren/modules/app/service/UserService.java
new file mode 100644
index 0000000..b111552
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/service/UserService.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.modules.app.entity.UserEntity;
+import io.renren.modules.app.form.LoginForm;
+
+/**
+ * 用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface UserService extends IService {
+
+ UserEntity queryByMobile(String mobile);
+
+ /**
+ * 用户登录
+ * @param form 登录表单
+ * @return 返回用户ID
+ */
+ long login(LoginForm form);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..c6b2451
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.exception.RRException;
+import io.renren.common.validator.Assert;
+import io.renren.modules.app.dao.UserDao;
+import io.renren.modules.app.entity.UserEntity;
+import io.renren.modules.app.form.LoginForm;
+import io.renren.modules.app.service.UserService;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.stereotype.Service;
+
+
+@Service("userService")
+public class UserServiceImpl extends ServiceImpl implements UserService {
+
+ @Override
+ public UserEntity queryByMobile(String mobile) {
+ return baseMapper.selectOne(new QueryWrapper().eq("mobile", mobile));
+ }
+
+ @Override
+ public long login(LoginForm form) {
+ UserEntity user = queryByMobile(form.getMobile());
+ Assert.isNull(user, "手机号或密码错误");
+
+ //密码错误
+ if(!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))){
+ throw new RRException("手机号或密码错误");
+ }
+
+ return user.getUserId();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/app/utils/JwtUtils.java b/renren-fast-master/src/main/java/io/renren/modules/app/utils/JwtUtils.java
new file mode 100644
index 0000000..05ec088
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/app/utils/JwtUtils.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.app.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * jwt工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@ConfigurationProperties(prefix = "renren.jwt")
+@Component
+public class JwtUtils {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ private String secret;
+ private long expire;
+ private String header;
+
+ /**
+ * 生成jwt token
+ */
+ public String generateToken(long userId) {
+ Date nowDate = new Date();
+ //过期时间
+ Date expireDate = new Date(nowDate.getTime() + expire * 1000);
+
+ return Jwts.builder()
+ .setHeaderParam("typ", "JWT")
+ .setSubject(userId+"")
+ .setIssuedAt(nowDate)
+ .setExpiration(expireDate)
+ .signWith(SignatureAlgorithm.HS512, secret)
+ .compact();
+ }
+
+ public Claims getClaimByToken(String token) {
+ try {
+ return Jwts.parser()
+ .setSigningKey(secret)
+ .parseClaimsJws(token)
+ .getBody();
+ }catch (Exception e){
+ logger.debug("validate is token error ", e);
+ return null;
+ }
+ }
+
+ /**
+ * token是否过期
+ * @return true:过期
+ */
+ public boolean isTokenExpired(Date expiration) {
+ return expiration.before(new Date());
+ }
+
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ public long getExpire() {
+ return expire;
+ }
+
+ public void setExpire(long expire) {
+ this.expire = expire;
+ }
+
+ public String getHeader() {
+ return header;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/config/ScheduleConfig.java b/renren-fast-master/src/main/java/io/renren/modules/job/config/ScheduleConfig.java
new file mode 100644
index 0000000..ab12541
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/config/ScheduleConfig.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+/**
+ * 定时任务配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class ScheduleConfig {
+
+ @Bean
+ public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
+ SchedulerFactoryBean factory = new SchedulerFactoryBean();
+ factory.setDataSource(dataSource);
+
+ //quartz参数
+ Properties prop = new Properties();
+ prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler");
+ prop.put("org.quartz.scheduler.instanceId", "AUTO");
+ //线程池配置
+ prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
+ prop.put("org.quartz.threadPool.threadCount", "20");
+ prop.put("org.quartz.threadPool.threadPriority", "5");
+ //JobStore配置
+ prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
+ //集群配置
+ prop.put("org.quartz.jobStore.isClustered", "true");
+ prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
+ prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
+
+ prop.put("org.quartz.jobStore.misfireThreshold", "12000");
+ prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
+ prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
+
+ //PostgreSQL数据库,需要打开此注释
+ //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate");
+
+ factory.setQuartzProperties(prop);
+
+ factory.setSchedulerName("RenrenScheduler");
+ //延时启动
+ factory.setStartupDelay(30);
+ factory.setApplicationContextSchedulerContextKey("applicationContextKey");
+ //可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
+ factory.setOverwriteExistingJobs(true);
+ //设置自动启动,默认为true
+ factory.setAutoStartup(true);
+
+ return factory;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java b/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java
new file mode 100644
index 0000000..4c3edaf
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.controller;
+
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+import io.renren.modules.job.service.ScheduleJobService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/**
+ * 定时任务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/schedule")
+public class ScheduleJobController {
+ @Autowired
+ private ScheduleJobService scheduleJobService;
+
+ /**
+ * 定时任务列表
+ */
+ @RequestMapping("/list")
+ @RequiresPermissions("sys:schedule:list")
+ public R list(@RequestParam Map params){
+ PageUtils page = scheduleJobService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+ /**
+ * 定时任务信息
+ */
+ @RequestMapping("/info/{jobId}")
+ @RequiresPermissions("sys:schedule:info")
+ public R info(@PathVariable("jobId") Long jobId){
+ ScheduleJobEntity schedule = scheduleJobService.getById(jobId);
+
+ return R.ok().put("schedule", schedule);
+ }
+
+ /**
+ * 保存定时任务
+ */
+ @SysLog("保存定时任务")
+ @RequestMapping("/save")
+ @RequiresPermissions("sys:schedule:save")
+ public R save(@RequestBody ScheduleJobEntity scheduleJob){
+ ValidatorUtils.validateEntity(scheduleJob);
+
+ scheduleJobService.saveJob(scheduleJob);
+
+ return R.ok();
+ }
+
+ /**
+ * 修改定时任务
+ */
+ @SysLog("修改定时任务")
+ @RequestMapping("/update")
+ @RequiresPermissions("sys:schedule:update")
+ public R update(@RequestBody ScheduleJobEntity scheduleJob){
+ ValidatorUtils.validateEntity(scheduleJob);
+
+ scheduleJobService.update(scheduleJob);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除定时任务
+ */
+ @SysLog("删除定时任务")
+ @RequestMapping("/delete")
+ @RequiresPermissions("sys:schedule:delete")
+ public R delete(@RequestBody Long[] jobIds){
+ scheduleJobService.deleteBatch(jobIds);
+
+ return R.ok();
+ }
+
+ /**
+ * 立即执行任务
+ */
+ @SysLog("立即执行任务")
+ @RequestMapping("/run")
+ @RequiresPermissions("sys:schedule:run")
+ public R run(@RequestBody Long[] jobIds){
+ scheduleJobService.run(jobIds);
+
+ return R.ok();
+ }
+
+ /**
+ * 暂停定时任务
+ */
+ @SysLog("暂停定时任务")
+ @RequestMapping("/pause")
+ @RequiresPermissions("sys:schedule:pause")
+ public R pause(@RequestBody Long[] jobIds){
+ scheduleJobService.pause(jobIds);
+
+ return R.ok();
+ }
+
+ /**
+ * 恢复定时任务
+ */
+ @SysLog("恢复定时任务")
+ @RequestMapping("/resume")
+ @RequiresPermissions("sys:schedule:resume")
+ public R resume(@RequestBody Long[] jobIds){
+ scheduleJobService.resume(jobIds);
+
+ return R.ok();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java b/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java
new file mode 100644
index 0000000..b24d2ab
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.controller;
+
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.modules.job.entity.ScheduleJobLogEntity;
+import io.renren.modules.job.service.ScheduleJobLogService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 定时任务日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/scheduleLog")
+public class ScheduleJobLogController {
+ @Autowired
+ private ScheduleJobLogService scheduleJobLogService;
+
+ /**
+ * 定时任务日志列表
+ */
+ @RequestMapping("/list")
+ @RequiresPermissions("sys:schedule:log")
+ public R list(@RequestParam Map params){
+ PageUtils page = scheduleJobLogService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+ /**
+ * 定时任务日志信息
+ */
+ @RequestMapping("/info/{logId}")
+ public R info(@PathVariable("logId") Long logId){
+ ScheduleJobLogEntity log = scheduleJobLogService.getById(logId);
+
+ return R.ok().put("log", log);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java b/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java
new file mode 100644
index 0000000..c5baa59
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Map;
+
+/**
+ * 定时任务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface ScheduleJobDao extends BaseMapper {
+
+ /**
+ * 批量更新状态
+ */
+ int updateBatch(Map map);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java b/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java
new file mode 100644
index 0000000..e760dc8
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.job.entity.ScheduleJobLogEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 定时任务日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface ScheduleJobLogDao extends BaseMapper {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java b/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java
new file mode 100644
index 0000000..22363fb
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 定时任务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("schedule_job")
+public class ScheduleJobEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 任务调度参数key
+ */
+ public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
+
+ /**
+ * 任务id
+ */
+ @TableId
+ private Long jobId;
+
+ /**
+ * spring bean名称
+ */
+ @NotBlank(message="bean名称不能为空")
+ private String beanName;
+
+ /**
+ * 参数
+ */
+ private String params;
+
+ /**
+ * cron表达式
+ */
+ @NotBlank(message="cron表达式不能为空")
+ private String cronExpression;
+
+ /**
+ * 任务状态
+ */
+ private Integer status;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 创建时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java b/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java
new file mode 100644
index 0000000..8587f90
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 定时任务日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("schedule_job_log")
+public class ScheduleJobLogEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 日志id
+ */
+ @TableId
+ private Long logId;
+
+ /**
+ * 任务id
+ */
+ private Long jobId;
+
+ /**
+ * spring bean名称
+ */
+ private String beanName;
+
+ /**
+ * 参数
+ */
+ private String params;
+
+ /**
+ * 任务状态 0:成功 1:失败
+ */
+ private Integer status;
+
+ /**
+ * 失败信息
+ */
+ private String error;
+
+ /**
+ * 耗时(单位:毫秒)
+ */
+ private Integer times;
+
+ /**
+ * 创建时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date createTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java b/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java
new file mode 100644
index 0000000..9e21fd8
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.job.entity.ScheduleJobLogEntity;
+
+import java.util.Map;
+
+/**
+ * 定时任务日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface ScheduleJobLogService extends IService {
+
+ PageUtils queryPage(Map params);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobService.java b/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobService.java
new file mode 100644
index 0000000..118f926
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/service/ScheduleJobService.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+
+import java.util.Map;
+
+/**
+ * 定时任务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface ScheduleJobService extends IService {
+
+ PageUtils queryPage(Map params);
+
+ /**
+ * 保存定时任务
+ */
+ void saveJob(ScheduleJobEntity scheduleJob);
+
+ /**
+ * 更新定时任务
+ */
+ void update(ScheduleJobEntity scheduleJob);
+
+ /**
+ * 批量删除定时任务
+ */
+ void deleteBatch(Long[] jobIds);
+
+ /**
+ * 批量更新定时任务状态
+ */
+ int updateBatch(Long[] jobIds, int status);
+
+ /**
+ * 立即执行
+ */
+ void run(Long[] jobIds);
+
+ /**
+ * 暂停运行
+ */
+ void pause(Long[] jobIds);
+
+ /**
+ * 恢复运行
+ */
+ void resume(Long[] jobIds);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java
new file mode 100644
index 0000000..5a55d4b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.job.dao.ScheduleJobLogDao;
+import io.renren.modules.job.entity.ScheduleJobLogEntity;
+import io.renren.modules.job.service.ScheduleJobLogService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+@Service("scheduleJobLogService")
+public class ScheduleJobLogServiceImpl extends ServiceImpl implements ScheduleJobLogService {
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String jobId = (String)params.get("jobId");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper().like(StringUtils.isNotBlank(jobId),"job_id", jobId)
+ );
+
+ return new PageUtils(page);
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java
new file mode 100644
index 0000000..56a8509
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.job.dao.ScheduleJobDao;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+import io.renren.modules.job.service.ScheduleJobService;
+import io.renren.modules.job.utils.ScheduleUtils;
+import org.apache.commons.lang.StringUtils;
+import org.quartz.CronTrigger;
+import org.quartz.Scheduler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.util.*;
+
+@Service("scheduleJobService")
+public class ScheduleJobServiceImpl extends ServiceImpl implements ScheduleJobService {
+ @Autowired
+ private Scheduler scheduler;
+
+ /**
+ * 项目启动时,初始化定时器
+ */
+ @PostConstruct
+ public void init(){
+ List scheduleJobList = this.list();
+ for(ScheduleJobEntity scheduleJob : scheduleJobList){
+ CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
+ //如果不存在,则创建
+ if(cronTrigger == null) {
+ ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
+ }else {
+ ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
+ }
+ }
+ }
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String beanName = (String)params.get("beanName");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper ().like(StringUtils.isNotBlank(beanName),"bean_name", beanName)
+ );
+
+ return new PageUtils(page);
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void saveJob(ScheduleJobEntity scheduleJob) {
+ scheduleJob.setCreateTime(new Date());
+ scheduleJob.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
+ this.save(scheduleJob);
+
+ ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(ScheduleJobEntity scheduleJob) {
+ ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
+
+ this.updateById(scheduleJob);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteBatch(Long[] jobIds) {
+ for(Long jobId : jobIds){
+ ScheduleUtils.deleteScheduleJob(scheduler, jobId);
+ }
+
+ //删除数据
+ this.removeByIds(Arrays.asList(jobIds));
+ }
+
+ @Override
+ public int updateBatch(Long[] jobIds, int status){
+ Map map = new HashMap<>(2);
+ map.put("list", Arrays.asList(jobIds));
+ map.put("status", status);
+ return baseMapper.updateBatch(map);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void run(Long[] jobIds) {
+ for(Long jobId : jobIds){
+ ScheduleUtils.run(scheduler, this.getById(jobId));
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void pause(Long[] jobIds) {
+ for(Long jobId : jobIds){
+ ScheduleUtils.pauseJob(scheduler, jobId);
+ }
+
+ updateBatch(jobIds, Constant.ScheduleStatus.PAUSE.getValue());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void resume(Long[] jobIds) {
+ for(Long jobId : jobIds){
+ ScheduleUtils.resumeJob(scheduler, jobId);
+ }
+
+ updateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue());
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/task/ITask.java b/renren-fast-master/src/main/java/io/renren/modules/job/task/ITask.java
new file mode 100644
index 0000000..3c386f5
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/task/ITask.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.task;
+
+/**
+ * 定时任务接口,所有定时任务都要实现该接口
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface ITask {
+
+ /**
+ * 执行定时任务接口
+ *
+ * @param params 参数,多参数使用JSON数据
+ */
+ void run(String params);
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/task/TestTask.java b/renren-fast-master/src/main/java/io/renren/modules/job/task/TestTask.java
new file mode 100644
index 0000000..9459cfc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/task/TestTask.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.task;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 测试定时任务(演示Demo,可删除)
+ *
+ * testTask为spring bean的名称
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component("testTask")
+public class TestTask implements ITask {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ public void run(String params){
+ logger.debug("TestTask定时任务正在执行,参数为:{}", params);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleJob.java b/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleJob.java
new file mode 100644
index 0000000..0f269e6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleJob.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.utils;
+
+import io.renren.common.utils.SpringContextUtils;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+import io.renren.modules.job.entity.ScheduleJobLogEntity;
+import io.renren.modules.job.service.ScheduleJobLogService;
+import org.apache.commons.lang.StringUtils;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+
+
+/**
+ * 定时任务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ScheduleJob extends QuartzJobBean {
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+ ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap()
+ .get(ScheduleJobEntity.JOB_PARAM_KEY);
+
+ //获取spring bean
+ ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService) SpringContextUtils.getBean("scheduleJobLogService");
+
+ //数据库保存执行记录
+ ScheduleJobLogEntity log = new ScheduleJobLogEntity();
+ log.setJobId(scheduleJob.getJobId());
+ log.setBeanName(scheduleJob.getBeanName());
+ log.setParams(scheduleJob.getParams());
+ log.setCreateTime(new Date());
+
+ //任务开始时间
+ long startTime = System.currentTimeMillis();
+
+ try {
+ //执行任务
+ logger.debug("任务准备执行,任务ID:" + scheduleJob.getJobId());
+
+ Object target = SpringContextUtils.getBean(scheduleJob.getBeanName());
+ Method method = target.getClass().getDeclaredMethod("run", String.class);
+ method.invoke(target, scheduleJob.getParams());
+
+ //任务执行总时长
+ long times = System.currentTimeMillis() - startTime;
+ log.setTimes((int)times);
+ //任务状态 0:成功 1:失败
+ log.setStatus(0);
+
+ logger.debug("任务执行完毕,任务ID:" + scheduleJob.getJobId() + " 总共耗时:" + times + "毫秒");
+ } catch (Exception e) {
+ logger.error("任务执行失败,任务ID:" + scheduleJob.getJobId(), e);
+
+ //任务执行总时长
+ long times = System.currentTimeMillis() - startTime;
+ log.setTimes((int)times);
+
+ //任务状态 0:成功 1:失败
+ log.setStatus(1);
+ log.setError(StringUtils.substring(e.toString(), 0, 2000));
+ }finally {
+ scheduleJobLogService.save(log);
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java b/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java
new file mode 100644
index 0000000..974f8bf
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.job.utils;
+
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.Constant;
+import io.renren.modules.job.entity.ScheduleJobEntity;
+import org.quartz.*;
+
+/**
+ * 定时任务工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class ScheduleUtils {
+ private final static String JOB_NAME = "TASK_";
+
+ /**
+ * 获取触发器key
+ */
+ public static TriggerKey getTriggerKey(Long jobId) {
+ return TriggerKey.triggerKey(JOB_NAME + jobId);
+ }
+
+ /**
+ * 获取jobKey
+ */
+ public static JobKey getJobKey(Long jobId) {
+ return JobKey.jobKey(JOB_NAME + jobId);
+ }
+
+ /**
+ * 获取表达式触发器
+ */
+ public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
+ try {
+ return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
+ } catch (SchedulerException e) {
+ throw new RRException("获取定时任务CronTrigger出现异常", e);
+ }
+ }
+
+ /**
+ * 创建定时任务
+ */
+ public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
+ try {
+ //构建job信息
+ JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getJobId())).build();
+
+ //表达式调度构建器
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
+ .withMisfireHandlingInstructionDoNothing();
+
+ //按新的cronExpression表达式构建一个新的trigger
+ CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getJobId())).withSchedule(scheduleBuilder).build();
+
+ //放入参数,运行时的方法可以获取
+ jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);
+
+ scheduler.scheduleJob(jobDetail, trigger);
+
+ //暂停任务
+ if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){
+ pauseJob(scheduler, scheduleJob.getJobId());
+ }
+ } catch (SchedulerException e) {
+ throw new RRException("创建定时任务失败", e);
+ }
+ }
+
+ /**
+ * 更新定时任务
+ */
+ public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
+ try {
+ TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId());
+
+ //表达式调度构建器
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
+ .withMisfireHandlingInstructionDoNothing();
+
+ CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId());
+
+ //按新的cronExpression表达式重新构建trigger
+ trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
+
+ //参数
+ trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);
+
+ scheduler.rescheduleJob(triggerKey, trigger);
+
+ //暂停任务
+ if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){
+ pauseJob(scheduler, scheduleJob.getJobId());
+ }
+
+ } catch (SchedulerException e) {
+ throw new RRException("更新定时任务失败", e);
+ }
+ }
+
+ /**
+ * 立即执行任务
+ */
+ public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
+ try {
+ //参数
+ JobDataMap dataMap = new JobDataMap();
+ dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);
+
+ scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap);
+ } catch (SchedulerException e) {
+ throw new RRException("立即执行定时任务失败", e);
+ }
+ }
+
+ /**
+ * 暂停任务
+ */
+ public static void pauseJob(Scheduler scheduler, Long jobId) {
+ try {
+ scheduler.pauseJob(getJobKey(jobId));
+ } catch (SchedulerException e) {
+ throw new RRException("暂停定时任务失败", e);
+ }
+ }
+
+ /**
+ * 恢复任务
+ */
+ public static void resumeJob(Scheduler scheduler, Long jobId) {
+ try {
+ scheduler.resumeJob(getJobKey(jobId));
+ } catch (SchedulerException e) {
+ throw new RRException("暂停定时任务失败", e);
+ }
+ }
+
+ /**
+ * 删除定时任务
+ */
+ public static void deleteScheduleJob(Scheduler scheduler, Long jobId) {
+ try {
+ scheduler.deleteJob(getJobKey(jobId));
+ } catch (SchedulerException e) {
+ throw new RRException("删除定时任务失败", e);
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java
new file mode 100644
index 0000000..5ea513f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+import com.aliyun.oss.OSSClient;
+import io.renren.common.exception.RRException;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * 阿里云存储
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class AliyunCloudStorageService extends CloudStorageService {
+ private OSSClient client;
+
+ public AliyunCloudStorageService(CloudStorageConfig config){
+ this.config = config;
+
+ //初始化
+ init();
+ }
+
+ private void init(){
+ client = new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(),
+ config.getAliyunAccessKeySecret());
+ }
+
+ @Override
+ public String upload(byte[] data, String path) {
+ return upload(new ByteArrayInputStream(data), path);
+ }
+
+ @Override
+ public String upload(InputStream inputStream, String path) {
+ try {
+ client.putObject(config.getAliyunBucketName(), path, inputStream);
+ } catch (Exception e){
+ throw new RRException("上传文件失败,请检查配置信息", e);
+ }
+
+ return config.getAliyunDomain() + "/" + path;
+ }
+
+ @Override
+ public String uploadSuffix(byte[] data, String suffix) {
+ return upload(data, getPath(config.getAliyunPrefix(), suffix));
+ }
+
+ @Override
+ public String uploadSuffix(InputStream inputStream, String suffix) {
+ return upload(inputStream, getPath(config.getAliyunPrefix(), suffix));
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java
new file mode 100644
index 0000000..ea5179c
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+
+import io.renren.common.validator.group.AliyunGroup;
+import io.renren.common.validator.group.QcloudGroup;
+import io.renren.common.validator.group.QiniuGroup;
+import lombok.Data;
+import org.hibernate.validator.constraints.Range;
+import org.hibernate.validator.constraints.URL;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 云存储配置信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+public class CloudStorageConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ //类型 1:七牛 2:阿里云 3:腾讯云
+ @Range(min=1, max=3, message = "类型错误")
+ private Integer type;
+
+ //七牛绑定的域名
+ @NotBlank(message="七牛绑定的域名不能为空", groups = QiniuGroup.class)
+ @URL(message = "七牛绑定的域名格式不正确", groups = QiniuGroup.class)
+ private String qiniuDomain;
+ //七牛路径前缀
+ private String qiniuPrefix;
+ //七牛ACCESS_KEY
+ @NotBlank(message="七牛AccessKey不能为空", groups = QiniuGroup.class)
+ private String qiniuAccessKey;
+ //七牛SECRET_KEY
+ @NotBlank(message="七牛SecretKey不能为空", groups = QiniuGroup.class)
+ private String qiniuSecretKey;
+ //七牛存储空间名
+ @NotBlank(message="七牛空间名不能为空", groups = QiniuGroup.class)
+ private String qiniuBucketName;
+
+ //阿里云绑定的域名
+ @NotBlank(message="阿里云绑定的域名不能为空", groups = AliyunGroup.class)
+ @URL(message = "阿里云绑定的域名格式不正确", groups = AliyunGroup.class)
+ private String aliyunDomain;
+ //阿里云路径前缀
+ private String aliyunPrefix;
+ //阿里云EndPoint
+ @NotBlank(message="阿里云EndPoint不能为空", groups = AliyunGroup.class)
+ private String aliyunEndPoint;
+ //阿里云AccessKeyId
+ @NotBlank(message="阿里云AccessKeyId不能为空", groups = AliyunGroup.class)
+ private String aliyunAccessKeyId;
+ //阿里云AccessKeySecret
+ @NotBlank(message="阿里云AccessKeySecret不能为空", groups = AliyunGroup.class)
+ private String aliyunAccessKeySecret;
+ //阿里云BucketName
+ @NotBlank(message="阿里云BucketName不能为空", groups = AliyunGroup.class)
+ private String aliyunBucketName;
+
+ //腾讯云绑定的域名
+ @NotBlank(message="腾讯云绑定的域名不能为空", groups = QcloudGroup.class)
+ @URL(message = "腾讯云绑定的域名格式不正确", groups = QcloudGroup.class)
+ private String qcloudDomain;
+ //腾讯云路径前缀
+ private String qcloudPrefix;
+ //腾讯云AppId
+ @NotNull(message="腾讯云AppId不能为空", groups = QcloudGroup.class)
+ private Integer qcloudAppId;
+ //腾讯云SecretId
+ @NotBlank(message="腾讯云SecretId不能为空", groups = QcloudGroup.class)
+ private String qcloudSecretId;
+ //腾讯云SecretKey
+ @NotBlank(message="腾讯云SecretKey不能为空", groups = QcloudGroup.class)
+ private String qcloudSecretKey;
+ //腾讯云BucketName
+ @NotBlank(message="腾讯云BucketName不能为空", groups = QcloudGroup.class)
+ private String qcloudBucketName;
+ //腾讯云COS所属地区
+ @NotBlank(message="所属地区不能为空", groups = QcloudGroup.class)
+ private String qcloudRegion;
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java
new file mode 100644
index 0000000..96d1093
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+import io.renren.common.utils.DateUtils;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 云存储(支持七牛、阿里云、腾讯云、又拍云)
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public abstract class CloudStorageService {
+ /** 云存储配置信息 */
+ CloudStorageConfig config;
+
+ /**
+ * 文件路径
+ * @param prefix 前缀
+ * @param suffix 后缀
+ * @return 返回上传路径
+ */
+ public String getPath(String prefix, String suffix) {
+ //生成uuid
+ String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+ //文件路径
+ String path = DateUtils.format(new Date(), "yyyyMMdd") + "/" + uuid;
+
+ if(StringUtils.isNotBlank(prefix)){
+ path = prefix + "/" + path;
+ }
+
+ return path + suffix;
+ }
+
+ /**
+ * 文件上传
+ * @param data 文件字节数组
+ * @param path 文件路径,包含文件名
+ * @return 返回http地址
+ */
+ public abstract String upload(byte[] data, String path);
+
+ /**
+ * 文件上传
+ * @param data 文件字节数组
+ * @param suffix 后缀
+ * @return 返回http地址
+ */
+ public abstract String uploadSuffix(byte[] data, String suffix);
+
+ /**
+ * 文件上传
+ * @param inputStream 字节流
+ * @param path 文件路径,包含文件名
+ * @return 返回http地址
+ */
+ public abstract String upload(InputStream inputStream, String path);
+
+ /**
+ * 文件上传
+ * @param inputStream 字节流
+ * @param suffix 后缀
+ * @return 返回http地址
+ */
+ public abstract String uploadSuffix(InputStream inputStream, String suffix);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java
new file mode 100644
index 0000000..e72dbb1
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+
+import io.renren.common.utils.ConfigConstant;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.SpringContextUtils;
+import io.renren.modules.sys.service.SysConfigService;
+
+/**
+ * 文件上传Factory
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public final class OSSFactory {
+ private static SysConfigService sysConfigService;
+
+ static {
+ OSSFactory.sysConfigService = (SysConfigService) SpringContextUtils.getBean("sysConfigService");
+ }
+
+ public static CloudStorageService build(){
+ //获取云存储配置信息
+ CloudStorageConfig config = sysConfigService.getConfigObject(ConfigConstant.CLOUD_STORAGE_CONFIG_KEY, CloudStorageConfig.class);
+
+ if(config.getType() == Constant.CloudService.QINIU.getValue()){
+ return new QiniuCloudStorageService(config);
+ }else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){
+ return new AliyunCloudStorageService(config);
+ }else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){
+ return new QcloudCloudStorageService(config);
+ }
+
+ return null;
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java
new file mode 100644
index 0000000..d1d2170
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.qcloud.cos.COSClient;
+import com.qcloud.cos.ClientConfig;
+import com.qcloud.cos.request.UploadFileRequest;
+import com.qcloud.cos.sign.Credentials;
+import io.renren.common.exception.RRException;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 腾讯云存储
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class QcloudCloudStorageService extends CloudStorageService {
+ private COSClient client;
+
+ public QcloudCloudStorageService(CloudStorageConfig config){
+ this.config = config;
+
+ //初始化
+ init();
+ }
+
+ private void init(){
+ Credentials credentials = new Credentials(config.getQcloudAppId(), config.getQcloudSecretId(),
+ config.getQcloudSecretKey());
+
+ //初始化客户端配置
+ ClientConfig clientConfig = new ClientConfig();
+ //设置bucket所在的区域,华南:gz 华北:tj 华东:sh
+ clientConfig.setRegion(config.getQcloudRegion());
+
+ client = new COSClient(clientConfig, credentials);
+ }
+
+ @Override
+ public String upload(byte[] data, String path) {
+ //腾讯云必需要以"/"开头
+ if(!path.startsWith("/")) {
+ path = "/" + path;
+ }
+
+ //上传到腾讯云
+ UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data);
+ String response = client.uploadFile(request);
+
+ JSONObject jsonObject = JSONObject.parseObject(response);
+ if(jsonObject.getInteger("code") != 0) {
+ throw new RRException("文件上传失败," + jsonObject.getString("message"));
+ }
+
+ return config.getQcloudDomain() + path;
+ }
+
+ @Override
+ public String upload(InputStream inputStream, String path) {
+ try {
+ byte[] data = IOUtils.toByteArray(inputStream);
+ return this.upload(data, path);
+ } catch (IOException e) {
+ throw new RRException("上传文件失败", e);
+ }
+ }
+
+ @Override
+ public String uploadSuffix(byte[] data, String suffix) {
+ return upload(data, getPath(config.getQcloudPrefix(), suffix));
+ }
+
+ @Override
+ public String uploadSuffix(InputStream inputStream, String suffix) {
+ return upload(inputStream, getPath(config.getQcloudPrefix(), suffix));
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java
new file mode 100644
index 0000000..db4fab9
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.cloud;
+
+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 io.renren.common.exception.RRException;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 七牛云存储
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class QiniuCloudStorageService extends CloudStorageService {
+ private UploadManager uploadManager;
+ private String token;
+
+ public QiniuCloudStorageService(CloudStorageConfig config){
+ this.config = config;
+
+ //初始化
+ init();
+ }
+
+ private void init(){
+ uploadManager = new UploadManager(new Configuration(Zone.autoZone()));
+ token = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey()).
+ uploadToken(config.getQiniuBucketName());
+ }
+
+ @Override
+ public String upload(byte[] data, String path) {
+ try {
+ Response res = uploadManager.put(data, path, token);
+ if (!res.isOK()) {
+ throw new RuntimeException("上传七牛出错:" + res.toString());
+ }
+ } catch (Exception e) {
+ throw new RRException("上传文件失败,请核对七牛配置信息", e);
+ }
+
+ return config.getQiniuDomain() + "/" + path;
+ }
+
+ @Override
+ public String upload(InputStream inputStream, String path) {
+ try {
+ byte[] data = IOUtils.toByteArray(inputStream);
+ return this.upload(data, path);
+ } catch (IOException e) {
+ throw new RRException("上传文件失败", e);
+ }
+ }
+
+ @Override
+ public String uploadSuffix(byte[] data, String suffix) {
+ return upload(data, getPath(config.getQiniuPrefix(), suffix));
+ }
+
+ @Override
+ public String uploadSuffix(InputStream inputStream, String suffix) {
+ return upload(inputStream, getPath(config.getQiniuPrefix(), suffix));
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/controller/SysOssController.java b/renren-fast-master/src/main/java/io/renren/modules/oss/controller/SysOssController.java
new file mode 100644
index 0000000..e8830ac
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/controller/SysOssController.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.controller;
+
+import com.google.gson.Gson;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.ConfigConstant;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.common.validator.group.AliyunGroup;
+import io.renren.common.validator.group.QcloudGroup;
+import io.renren.common.validator.group.QiniuGroup;
+import io.renren.modules.oss.cloud.CloudStorageConfig;
+import io.renren.modules.oss.cloud.OSSFactory;
+import io.renren.modules.oss.entity.SysOssEntity;
+import io.renren.modules.oss.service.SysOssService;
+import io.renren.modules.sys.service.SysConfigService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 文件上传
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("sys/oss")
+public class SysOssController {
+ @Autowired
+ private SysOssService sysOssService;
+ @Autowired
+ private SysConfigService sysConfigService;
+
+ private final static String KEY = ConfigConstant.CLOUD_STORAGE_CONFIG_KEY;
+
+ /**
+ * 列表
+ */
+ @GetMapping("/list")
+ @RequiresPermissions("sys:oss:all")
+ public R list(@RequestParam Map params){
+ PageUtils page = sysOssService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+
+ /**
+ * 云存储配置信息
+ */
+ @GetMapping("/config")
+ @RequiresPermissions("sys:oss:all")
+ public R config(){
+ CloudStorageConfig config = sysConfigService.getConfigObject(KEY, CloudStorageConfig.class);
+
+ return R.ok().put("config", config);
+ }
+
+
+ /**
+ * 保存云存储配置信息
+ */
+ @PostMapping("/saveConfig")
+ @RequiresPermissions("sys:oss:all")
+ public R saveConfig(@RequestBody CloudStorageConfig config){
+ //校验类型
+ ValidatorUtils.validateEntity(config);
+ ValidatorUtils.validateEntity(config, Constant.CloudService.getByValue(config.getType()));
+
+ sysConfigService.updateValueByKey(KEY, new Gson().toJson(config));
+
+ return R.ok();
+ }
+
+
+ /**
+ * 上传文件
+ */
+ @PostMapping("/upload")
+ @RequiresPermissions("sys:oss:all")
+ public R upload(@RequestParam("file") MultipartFile file) throws Exception {
+ if (file.isEmpty()) {
+ throw new RRException("上传文件不能为空");
+ }
+
+ //上传文件
+ String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
+ String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);
+
+ //保存文件信息
+ SysOssEntity ossEntity = new SysOssEntity();
+ ossEntity.setUrl(url);
+ ossEntity.setCreateDate(new Date());
+ sysOssService.save(ossEntity);
+
+ return R.ok().put("url", url);
+ }
+
+
+ /**
+ * 删除
+ */
+ @PostMapping("/delete")
+ @RequiresPermissions("sys:oss:all")
+ public R delete(@RequestBody Long[] ids){
+ sysOssService.removeByIds(Arrays.asList(ids));
+
+ return R.ok();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/dao/SysOssDao.java b/renren-fast-master/src/main/java/io/renren/modules/oss/dao/SysOssDao.java
new file mode 100644
index 0000000..e5f04f6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/dao/SysOssDao.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.oss.entity.SysOssEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 文件上传
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysOssDao extends BaseMapper {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java b/renren-fast-master/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java
new file mode 100644
index 0000000..2086eb7
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 文件上传
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_oss")
+public class SysOssEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @TableId
+ private Long id;
+ //URL地址
+ private String url;
+ //创建时间
+ private Date createDate;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/service/SysOssService.java b/renren-fast-master/src/main/java/io/renren/modules/oss/service/SysOssService.java
new file mode 100644
index 0000000..c77c00f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/service/SysOssService.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.oss.entity.SysOssEntity;
+
+import java.util.Map;
+
+/**
+ * 文件上传
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysOssService extends IService {
+
+ PageUtils queryPage(Map params);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java
new file mode 100644
index 0000000..ffaa194
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.oss.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.oss.dao.SysOssDao;
+import io.renren.modules.oss.entity.SysOssEntity;
+import io.renren.modules.oss.service.SysOssService;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+
+@Service("sysOssService")
+public class SysOssServiceImpl extends ServiceImpl implements SysOssService {
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ IPage page = this.page(
+ new Query().getPage(params)
+ );
+
+ return new PageUtils(page);
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/AbstractController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/AbstractController.java
new file mode 100644
index 0000000..608ecb3
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/AbstractController.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.modules.sys.entity.SysUserEntity;
+import org.apache.shiro.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Controller公共组件
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public abstract class AbstractController {
+ protected Logger logger = LoggerFactory.getLogger(getClass());
+
+ protected SysUserEntity getUser() {
+ return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
+ }
+
+ protected Long getUserId() {
+ return getUser().getUserId();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysConfigController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysConfigController.java
new file mode 100644
index 0000000..5314f39
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysConfigController.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.sys.entity.SysConfigEntity;
+import io.renren.modules.sys.service.SysConfigService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/**
+ * 系统配置信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/config")
+public class SysConfigController extends AbstractController {
+ @Autowired
+ private SysConfigService sysConfigService;
+
+ /**
+ * 所有配置列表
+ */
+ @GetMapping("/list")
+ @RequiresPermissions("sys:config:list")
+ public R list(@RequestParam Map params){
+ PageUtils page = sysConfigService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+
+ /**
+ * 配置信息
+ */
+ @GetMapping("/info/{id}")
+ @RequiresPermissions("sys:config:info")
+ public R info(@PathVariable("id") Long id){
+ SysConfigEntity config = sysConfigService.getById(id);
+
+ return R.ok().put("config", config);
+ }
+
+ /**
+ * 保存配置
+ */
+ @SysLog("保存配置")
+ @PostMapping("/save")
+ @RequiresPermissions("sys:config:save")
+ public R save(@RequestBody SysConfigEntity config){
+ ValidatorUtils.validateEntity(config);
+
+ sysConfigService.saveConfig(config);
+
+ return R.ok();
+ }
+
+ /**
+ * 修改配置
+ */
+ @SysLog("修改配置")
+ @PostMapping("/update")
+ @RequiresPermissions("sys:config:update")
+ public R update(@RequestBody SysConfigEntity config){
+ ValidatorUtils.validateEntity(config);
+
+ sysConfigService.update(config);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除配置
+ */
+ @SysLog("删除配置")
+ @PostMapping("/delete")
+ @RequiresPermissions("sys:config:delete")
+ public R delete(@RequestBody Long[] ids){
+ sysConfigService.deleteBatch(ids);
+
+ return R.ok();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLogController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLogController.java
new file mode 100644
index 0000000..e69af10
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLogController.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.modules.sys.service.SysLogService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.Map;
+
+
+/**
+ * 系统日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Controller
+@RequestMapping("/sys/log")
+public class SysLogController {
+ @Autowired
+ private SysLogService sysLogService;
+
+ /**
+ * 列表
+ */
+ @ResponseBody
+ @GetMapping("/list")
+ @RequiresPermissions("sys:log:list")
+ public R list(@RequestParam Map params){
+ PageUtils page = sysLogService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLoginController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
new file mode 100644
index 0000000..bb09155
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.common.utils.R;
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.form.SysLoginForm;
+import io.renren.modules.sys.service.SysCaptchaService;
+import io.renren.modules.sys.service.SysUserService;
+import io.renren.modules.sys.service.SysUserTokenService;
+import org.apache.commons.io.IOUtils;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.imageio.ImageIO;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * 登录相关
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+public class SysLoginController extends AbstractController {
+ @Autowired
+ private SysUserService sysUserService;
+ @Autowired
+ private SysUserTokenService sysUserTokenService;
+ @Autowired
+ private SysCaptchaService sysCaptchaService;
+
+ /**
+ * 验证码
+ */
+ @GetMapping("captcha.jpg")
+ public void captcha(HttpServletResponse response, String uuid)throws IOException {
+ response.setHeader("Cache-Control", "no-store, no-cache");
+ response.setContentType("image/jpeg");
+
+ //获取图片验证码
+ BufferedImage image = sysCaptchaService.getCaptcha(uuid);
+
+ ServletOutputStream out = response.getOutputStream();
+ ImageIO.write(image, "jpg", out);
+ IOUtils.closeQuietly(out);
+ }
+
+ /**
+ * 登录
+ */
+ @PostMapping("/sys/login")
+ public Map login(@RequestBody SysLoginForm form)throws IOException {
+ boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
+ if(!captcha){
+ return R.error("验证码不正确");
+ }
+
+ //用户信息
+ SysUserEntity user = sysUserService.queryByUserName(form.getUsername());
+
+ //账号不存在、密码错误
+ if(user == null || !user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
+ return R.error("账号或密码不正确");
+ }
+
+ //账号锁定
+ if(user.getStatus() == 0){
+ return R.error("账号已被锁定,请联系管理员");
+ }
+
+ //生成token,并保存到数据库
+ R r = sysUserTokenService.createToken(user.getUserId());
+ return r;
+ }
+
+
+ /**
+ * 退出
+ */
+ @PostMapping("/sys/logout")
+ public R logout() {
+ sysUserTokenService.logout(getUserId());
+ return R.ok();
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysMenuController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysMenuController.java
new file mode 100644
index 0000000..6b9eb08
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysMenuController.java
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.common.annotation.SysLog;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.R;
+import io.renren.modules.sys.entity.SysMenuEntity;
+import io.renren.modules.sys.service.ShiroService;
+import io.renren.modules.sys.service.SysMenuService;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Collections;
+
+
+/**
+ * 系统菜单
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/menu")
+public class SysMenuController extends AbstractController {
+ @Autowired
+ private SysMenuService sysMenuService;
+ @Autowired
+ private ShiroService shiroService;
+
+ /**
+ * 导航菜单
+ */
+ @GetMapping("/nav")
+ public R nav(){
+ List menuList = sysMenuService.getUserMenuList(getUserId());
+ Set permissions = shiroService.getUserPermissions(getUserId());
+ return R.ok().put("menuList", menuList).put("permissions", permissions);
+ }
+
+ /**
+ * 所有菜单列表
+ */
+ @GetMapping("/list")
+ @RequiresPermissions("sys:menu:list")
+ public List list(){
+ List menuList = sysMenuService.list();
+
+ //查询完成 对此list直接排序
+ Collections.sort(menuList);
+
+ HashMap menuMap = new HashMap<>(12);
+ for (SysMenuEntity s : menuList) {
+ menuMap.put(s.getMenuId(), s);
+ }
+ for (SysMenuEntity s : menuList) {
+ SysMenuEntity parent = menuMap.get(s.getParentId());
+ if (Objects.nonNull(parent)) {
+ s.setParentName(parent.getName());
+ }
+
+ }
+
+
+ return menuList;
+ }
+
+ /**
+ * 选择菜单(添加、修改菜单)
+ */
+ @GetMapping("/select")
+ @RequiresPermissions("sys:menu:select")
+ public R select(){
+ //查询列表数据
+ List menuList = sysMenuService.queryNotButtonList();
+
+ //添加顶级菜单
+ SysMenuEntity root = new SysMenuEntity();
+ root.setMenuId(0L);
+ root.setName("一级菜单");
+ root.setParentId(-1L);
+ root.setOpen(true);
+ menuList.add(root);
+
+ return R.ok().put("menuList", menuList);
+ }
+
+ /**
+ * 菜单信息
+ */
+ @GetMapping("/info/{menuId}")
+ @RequiresPermissions("sys:menu:info")
+ public R info(@PathVariable("menuId") Long menuId){
+ SysMenuEntity menu = sysMenuService.getById(menuId);
+ return R.ok().put("menu", menu);
+ }
+
+ /**
+ * 保存
+ */
+ @SysLog("保存菜单")
+ @PostMapping("/save")
+ @RequiresPermissions("sys:menu:save")
+ public R save(@RequestBody SysMenuEntity menu){
+ //数据校验
+ verifyForm(menu);
+
+ sysMenuService.save(menu);
+
+ return R.ok();
+ }
+
+ /**
+ * 修改
+ */
+ @SysLog("修改菜单")
+ @PostMapping("/update")
+ @RequiresPermissions("sys:menu:update")
+ public R update(@RequestBody SysMenuEntity menu){
+ //数据校验
+ verifyForm(menu);
+
+ sysMenuService.updateById(menu);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除
+ */
+ @SysLog("删除菜单")
+ @PostMapping("/delete/{menuId}")
+ @RequiresPermissions("sys:menu:delete")
+ public R delete(@PathVariable("menuId") long menuId){
+ if(menuId <= 31){
+ return R.error("系统菜单,不能删除");
+ }
+
+ //判断是否有子菜单或按钮
+ List menuList = sysMenuService.queryListParentId(menuId);
+ if(menuList.size() > 0){
+ return R.error("请先删除子菜单或按钮");
+ }
+
+ sysMenuService.delete(menuId);
+
+ return R.ok();
+ }
+
+ /**
+ * 验证参数是否正确
+ */
+ private void verifyForm(SysMenuEntity menu){
+ if(StringUtils.isBlank(menu.getName())){
+ throw new RRException("菜单名称不能为空");
+ }
+
+ if(menu.getParentId() == null){
+ throw new RRException("上级菜单不能为空");
+ }
+
+ //菜单
+ if(menu.getType() == Constant.MenuType.MENU.getValue()){
+ if(StringUtils.isBlank(menu.getUrl())){
+ throw new RRException("菜单URL不能为空");
+ }
+ }
+
+ //上级菜单类型
+ int parentType = Constant.MenuType.CATALOG.getValue();
+ if(menu.getParentId() != 0){
+ SysMenuEntity parentMenu = sysMenuService.getById(menu.getParentId());
+ parentType = parentMenu.getType();
+ }
+
+ //目录、菜单
+ if(menu.getType() == Constant.MenuType.CATALOG.getValue() ||
+ menu.getType() == Constant.MenuType.MENU.getValue()){
+ if(parentType != Constant.MenuType.CATALOG.getValue()){
+ throw new RRException("上级菜单只能为目录类型");
+ }
+ return ;
+ }
+
+ //按钮
+ if(menu.getType() == Constant.MenuType.BUTTON.getValue()){
+ if(parentType != Constant.MenuType.MENU.getValue()){
+ throw new RRException("上级菜单只能为菜单类型");
+ }
+ return ;
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysRoleController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysRoleController.java
new file mode 100644
index 0000000..5a6f9d8
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysRoleController.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.sys.entity.SysRoleEntity;
+import io.renren.modules.sys.service.SysRoleMenuService;
+import io.renren.modules.sys.service.SysRoleService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 角色管理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/role")
+public class SysRoleController extends AbstractController {
+ @Autowired
+ private SysRoleService sysRoleService;
+ @Autowired
+ private SysRoleMenuService sysRoleMenuService;
+
+ /**
+ * 角色列表
+ */
+ @GetMapping("/list")
+ @RequiresPermissions("sys:role:list")
+ public R list(@RequestParam Map params){
+ //如果不是超级管理员,则只查询自己创建的角色列表
+ if(getUserId() != Constant.SUPER_ADMIN){
+ params.put("createUserId", getUserId());
+ }
+
+ PageUtils page = sysRoleService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+ /**
+ * 角色列表
+ */
+ @GetMapping("/select")
+ @RequiresPermissions("sys:role:select")
+ public R select(){
+ Map map = new HashMap<>();
+
+ //如果不是超级管理员,则只查询自己所拥有的角色列表
+ if(getUserId() != Constant.SUPER_ADMIN){
+ map.put("create_user_id", getUserId());
+ }
+ List list = (List) sysRoleService.listByMap(map);
+
+ return R.ok().put("list", list);
+ }
+
+ /**
+ * 角色信息
+ */
+ @GetMapping("/info/{roleId}")
+ @RequiresPermissions("sys:role:info")
+ public R info(@PathVariable("roleId") Long roleId){
+ SysRoleEntity role = sysRoleService.getById(roleId);
+
+ //查询角色对应的菜单
+ List menuIdList = sysRoleMenuService.queryMenuIdList(roleId);
+ role.setMenuIdList(menuIdList);
+
+ return R.ok().put("role", role);
+ }
+
+ /**
+ * 保存角色
+ */
+ @SysLog("保存角色")
+ @PostMapping("/save")
+ @RequiresPermissions("sys:role:save")
+ public R save(@RequestBody SysRoleEntity role){
+ ValidatorUtils.validateEntity(role);
+
+ role.setCreateUserId(getUserId());
+ sysRoleService.saveRole(role);
+
+ return R.ok();
+ }
+
+ /**
+ * 修改角色
+ */
+ @SysLog("修改角色")
+ @PostMapping("/update")
+ @RequiresPermissions("sys:role:update")
+ public R update(@RequestBody SysRoleEntity role){
+ ValidatorUtils.validateEntity(role);
+
+ role.setCreateUserId(getUserId());
+ sysRoleService.update(role);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除角色
+ */
+ @SysLog("删除角色")
+ @PostMapping("/delete")
+ @RequiresPermissions("sys:role:delete")
+ public R delete(@RequestBody Long[] roleIds){
+ sysRoleService.deleteBatch(roleIds);
+
+ return R.ok();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysUserController.java b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysUserController.java
new file mode 100644
index 0000000..27c2990
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/controller/SysUserController.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.controller;
+
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.Assert;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.common.validator.group.AddGroup;
+import io.renren.common.validator.group.UpdateGroup;
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.form.PasswordForm;
+import io.renren.modules.sys.service.SysUserRoleService;
+import io.renren.modules.sys.service.SysUserService;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 系统用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@RestController
+@RequestMapping("/sys/user")
+public class SysUserController extends AbstractController {
+ @Autowired
+ private SysUserService sysUserService;
+ @Autowired
+ private SysUserRoleService sysUserRoleService;
+
+
+ /**
+ * 所有用户列表
+ */
+ @GetMapping("/list")
+ @RequiresPermissions("sys:user:list")
+ public R list(@RequestParam Map params){
+ //只有超级管理员,才能查看所有管理员列表
+ if(getUserId() != Constant.SUPER_ADMIN){
+ params.put("createUserId", getUserId());
+ }
+ PageUtils page = sysUserService.queryPage(params);
+
+ return R.ok().put("page", page);
+ }
+
+ /**
+ * 获取登录的用户信息
+ */
+ @GetMapping("/info")
+ public R info(){
+ return R.ok().put("user", getUser());
+ }
+
+ /**
+ * 修改登录用户密码
+ */
+ @SysLog("修改密码")
+ @PostMapping("/password")
+ public R password(@RequestBody PasswordForm form){
+ Assert.isBlank(form.getNewPassword(), "新密码不为能空");
+
+ //sha256加密
+ String password = new Sha256Hash(form.getPassword(), getUser().getSalt()).toHex();
+ //sha256加密
+ String newPassword = new Sha256Hash(form.getNewPassword(), getUser().getSalt()).toHex();
+
+ //更新密码
+ boolean flag = sysUserService.updatePassword(getUserId(), password, newPassword);
+ if(!flag){
+ return R.error("原密码不正确");
+ }
+
+ return R.ok();
+ }
+
+ /**
+ * 用户信息
+ */
+ @GetMapping("/info/{userId}")
+ @RequiresPermissions("sys:user:info")
+ public R info(@PathVariable("userId") Long userId){
+ SysUserEntity user = sysUserService.getById(userId);
+
+ //获取用户所属的角色列表
+ List roleIdList = sysUserRoleService.queryRoleIdList(userId);
+ user.setRoleIdList(roleIdList);
+
+ return R.ok().put("user", user);
+ }
+
+ /**
+ * 保存用户
+ */
+ @SysLog("保存用户")
+ @PostMapping("/save")
+ @RequiresPermissions("sys:user:save")
+ public R save(@RequestBody SysUserEntity user){
+ ValidatorUtils.validateEntity(user, AddGroup.class);
+
+ user.setCreateUserId(getUserId());
+ sysUserService.saveUser(user);
+
+ return R.ok();
+ }
+
+ /**
+ * 修改用户
+ */
+ @SysLog("修改用户")
+ @PostMapping("/update")
+ @RequiresPermissions("sys:user:update")
+ public R update(@RequestBody SysUserEntity user){
+ ValidatorUtils.validateEntity(user, UpdateGroup.class);
+
+ user.setCreateUserId(getUserId());
+ sysUserService.update(user);
+
+ return R.ok();
+ }
+
+ /**
+ * 删除用户
+ */
+ @SysLog("删除用户")
+ @PostMapping("/delete")
+ @RequiresPermissions("sys:user:delete")
+ public R delete(@RequestBody Long[] userIds){
+ if(ArrayUtils.contains(userIds, 1L)){
+ return R.error("系统管理员不能删除");
+ }
+
+ if(ArrayUtils.contains(userIds, getUserId())){
+ return R.error("当前用户不能删除");
+ }
+
+ sysUserService.deleteBatch(userIds);
+
+ return R.ok();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java
new file mode 100644
index 0000000..80d6d18
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysCaptchaEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 验证码
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysCaptchaDao extends BaseMapper {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java
new file mode 100644
index 0000000..0132d72
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysConfigEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 系统配置信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysConfigDao extends BaseMapper {
+
+ /**
+ * 根据key,查询value
+ */
+ SysConfigEntity queryByKey(String paramKey);
+
+ /**
+ * 根据key,更新value
+ */
+ int updateValueByKey(@Param("paramKey") String paramKey, @Param("paramValue") String paramValue);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysLogDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysLogDao.java
new file mode 100644
index 0000000..afd984d
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysLogDao.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysLogEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 系统日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysLogDao extends BaseMapper {
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java
new file mode 100644
index 0000000..4339a8c
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysMenuEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 菜单管理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysMenuDao extends BaseMapper {
+
+ /**
+ * 根据父菜单,查询子菜单
+ * @param parentId 父菜单ID
+ */
+ List queryListParentId(Long parentId);
+
+ /**
+ * 获取不包含按钮的菜单列表
+ */
+ List queryNotButtonList();
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java
new file mode 100644
index 0000000..e99c8ea
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysRoleEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 角色管理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysRoleDao extends BaseMapper {
+
+ /**
+ * 查询用户创建的角色ID列表
+ */
+ List queryRoleIdList(Long createUserId);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java
new file mode 100644
index 0000000..4dc0429
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysRoleMenuEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 角色与菜单对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysRoleMenuDao extends BaseMapper {
+
+ /**
+ * 根据角色ID,获取菜单ID列表
+ */
+ List queryMenuIdList(Long roleId);
+
+ /**
+ * 根据角色ID数组,批量删除
+ */
+ int deleteBatch(Long[] roleIds);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserDao.java
new file mode 100644
index 0000000..333c00c
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserDao.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysUserEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 系统用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysUserDao extends BaseMapper {
+
+ /**
+ * 查询用户的所有权限
+ * @param userId 用户ID
+ */
+ List queryAllPerms(Long userId);
+
+ /**
+ * 查询用户的所有菜单ID
+ */
+ List queryAllMenuId(Long userId);
+
+ /**
+ * 根据用户名,查询系统用户
+ */
+ SysUserEntity queryByUserName(String username);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java
new file mode 100644
index 0000000..298bbd6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysUserRoleEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 用户与角色对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysUserRoleDao extends BaseMapper {
+
+ /**
+ * 根据用户ID,获取角色ID列表
+ */
+ List queryRoleIdList(Long userId);
+
+
+ /**
+ * 根据角色ID数组,批量删除
+ */
+ int deleteBatch(Long[] roleIds);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java
new file mode 100644
index 0000000..546cd1d
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 系统用户Token
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Mapper
+public interface SysUserTokenDao extends BaseMapper {
+
+ SysUserTokenEntity queryByToken(String token);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java
new file mode 100644
index 0000000..70fd694
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 系统验证码
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_captcha")
+public class SysCaptchaEntity {
+ @TableId(type = IdType.INPUT)
+ private String uuid;
+ /**
+ * 验证码
+ */
+ private String code;
+ /**
+ * 过期时间
+ */
+ private Date expireTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java
new file mode 100644
index 0000000..83c83c3
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 系统配置信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_config")
+public class SysConfigEntity {
+ @TableId
+ private Long id;
+ @NotBlank(message="参数名不能为空")
+ private String paramKey;
+ @NotBlank(message="参数值不能为空")
+ private String paramValue;
+ private String remark;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java
new file mode 100644
index 0000000..6f1a4bd
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 系统日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_log")
+public class SysLogEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+ @TableId
+ private Long id;
+ //用户名
+ private String username;
+ //用户操作
+ private String operation;
+ //请求方法
+ private String method;
+ //请求参数
+ private String params;
+ //执行时长(毫秒)
+ private Long time;
+ //IP地址
+ private String ip;
+ //创建时间
+ private Date createDate;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java
new file mode 100644
index 0000000..6bc3797
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+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.ArrayList;
+import java.util.List;
+
+/**
+ * 菜单管理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_menu")
+public class SysMenuEntity implements Serializable,Comparable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 菜单ID
+ */
+ @TableId
+ private Long menuId;
+
+ /**
+ * 父菜单ID,一级菜单为0
+ */
+ private Long parentId;
+
+ /**
+ * 父菜单名称
+ */
+ @TableField(exist=false)
+ private String parentName;
+
+ /**
+ * 菜单名称
+ */
+ private String name;
+
+ /**
+ * 菜单URL
+ */
+ private String url;
+
+ /**
+ * 授权(多个用逗号分隔,如:user:list,user:create)
+ */
+ private String perms;
+
+ /**
+ * 类型 0:目录 1:菜单 2:按钮
+ */
+ private Integer type;
+
+ /**
+ * 菜单图标
+ */
+ private String icon;
+
+ /**
+ * 排序
+ */
+ private Integer orderNum;
+
+ /**
+ * ztree属性
+ */
+ @TableField(exist=false)
+ private Boolean open;
+
+ @TableField(exist=false)
+ private List list=new ArrayList<>();
+
+ @Override
+ public int compareTo(SysMenuEntity o) {
+ return this.getOrderNum()-o.getOrderNum();
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java
new file mode 100644
index 0000000..086035b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 角色
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_role")
+public class SysRoleEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 角色ID
+ */
+ @TableId
+ private Long roleId;
+
+ /**
+ * 角色名称
+ */
+ @NotBlank(message="角色名称不能为空")
+ private String roleName;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 创建者ID
+ */
+ private Long createUserId;
+
+ @TableField(exist=false)
+ private List menuIdList;
+
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java
new file mode 100644
index 0000000..d603707
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 角色与菜单对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_role_menu")
+public class SysRoleMenuEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @TableId
+ private Long id;
+
+ /**
+ * 角色ID
+ */
+ private Long roleId;
+
+ /**
+ * 菜单ID
+ */
+ private Long menuId;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java
new file mode 100644
index 0000000..ed268ca
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.renren.common.validator.group.AddGroup;
+import io.renren.common.validator.group.UpdateGroup;
+import lombok.Data;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 系统用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_user")
+public class SysUserEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户ID
+ */
+ @TableId
+ private Long userId;
+
+ /**
+ * 用户名
+ */
+ @NotBlank(message="用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
+ private String username;
+
+ /**
+ * 密码
+ */
+ @NotBlank(message="密码不能为空", groups = AddGroup.class)
+ private String password;
+
+ /**
+ * 盐
+ */
+ private String salt;
+
+ /**
+ * 邮箱
+ */
+ @NotBlank(message="邮箱不能为空", groups = {AddGroup.class, UpdateGroup.class})
+ @Email(message="邮箱格式不正确", groups = {AddGroup.class, UpdateGroup.class})
+ private String email;
+
+ /**
+ * 手机号
+ */
+ private String mobile;
+
+ /**
+ * 状态 0:禁用 1:正常
+ */
+ private Integer status;
+
+ /**
+ * 角色ID列表
+ */
+ @TableField(exist=false)
+ private List roleIdList;
+
+ /**
+ * 创建者ID
+ */
+ private Long createUserId;
+
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java
new file mode 100644
index 0000000..8f34484
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户与角色对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_user_role")
+public class SysUserRoleEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+ @TableId
+ private Long id;
+
+ /**
+ * 用户ID
+ */
+ private Long userId;
+
+ /**
+ * 角色ID
+ */
+ private Long roleId;
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java
new file mode 100644
index 0000000..70de984
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.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;
+
+
+/**
+ * 系统用户Token
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@TableName("sys_user_token")
+public class SysUserTokenEntity implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ //用户ID
+ @TableId(type = IdType.INPUT)
+ private Long userId;
+ //token
+ private String token;
+ //过期时间
+ private Date expireTime;
+ //更新时间
+ private Date updateTime;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/form/PasswordForm.java b/renren-fast-master/src/main/java/io/renren/modules/sys/form/PasswordForm.java
new file mode 100644
index 0000000..61a077b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/form/PasswordForm.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.form;
+
+import lombok.Data;
+
+/**
+ * 密码表单
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+public class PasswordForm {
+ /**
+ * 原密码
+ */
+ private String password;
+ /**
+ * 新密码
+ */
+ private String newPassword;
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/form/SysLoginForm.java b/renren-fast-master/src/main/java/io/renren/modules/sys/form/SysLoginForm.java
new file mode 100644
index 0000000..abeb6fc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/form/SysLoginForm.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.form;
+
+import lombok.Data;
+
+/**
+ * 登录表单
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+public class SysLoginForm {
+ private String username;
+ private String password;
+ private String captcha;
+ private String uuid;
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Filter.java b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Filter.java
new file mode 100644
index 0000000..1440dfb
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Filter.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.oauth2;
+
+import com.google.gson.Gson;
+import io.renren.common.utils.HttpContextUtils;
+import io.renren.common.utils.R;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpStatus;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * oauth2过滤器
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class OAuth2Filter extends AuthenticatingFilter {
+
+ @Override
+ protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
+ //获取请求token
+ String token = getRequestToken((HttpServletRequest) request);
+
+ if(StringUtils.isBlank(token)){
+ return null;
+ }
+
+ return new OAuth2Token(token);
+ }
+
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+ if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
+ //获取请求token,如果token不存在,直接返回401
+ String token = getRequestToken((HttpServletRequest) request);
+ if(StringUtils.isBlank(token)){
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
+ httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
+
+ String json = new Gson().toJson(R.error(HttpStatus.SC_UNAUTHORIZED, "invalid token"));
+
+ httpResponse.getWriter().print(json);
+
+ return false;
+ }
+
+ return executeLogin(request, response);
+ }
+
+ @Override
+ protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.setContentType("application/json;charset=utf-8");
+ httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
+ httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
+ try {
+ //处理登录失败的异常
+ Throwable throwable = e.getCause() == null ? e : e.getCause();
+ R r = R.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage());
+
+ String json = new Gson().toJson(r);
+ httpResponse.getWriter().print(json);
+ } catch (IOException e1) {
+
+ }
+
+ return false;
+ }
+
+ /**
+ * 获取请求的token
+ */
+ private String getRequestToken(HttpServletRequest httpRequest){
+ //从header中获取token
+ String token = httpRequest.getHeader("token");
+
+ //如果header中不存在token,则从参数中获取token
+ if(StringUtils.isBlank(token)){
+ token = httpRequest.getParameter("token");
+ }
+
+ return token;
+ }
+
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Realm.java b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Realm.java
new file mode 100644
index 0000000..4085d0f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Realm.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.oauth2;
+
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+import io.renren.modules.sys.service.ShiroService;
+import org.apache.shiro.authc.*;
+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.Set;
+
+/**
+ * 认证
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class OAuth2Realm extends AuthorizingRealm {
+ @Autowired
+ private ShiroService shiroService;
+
+ @Override
+ public boolean supports(AuthenticationToken token) {
+ return token instanceof OAuth2Token;
+ }
+
+ /**
+ * 授权(验证权限时调用)
+ */
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
+ Long userId = user.getUserId();
+
+ //用户权限列表
+ Set permsSet = shiroService.getUserPermissions(userId);
+
+ SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
+ info.setStringPermissions(permsSet);
+ return info;
+ }
+
+ /**
+ * 认证(登录时调用)
+ */
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+ String accessToken = (String) token.getPrincipal();
+
+ //根据accessToken,查询用户信息
+ SysUserTokenEntity tokenEntity = shiroService.queryByToken(accessToken);
+ //token失效
+ if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
+ throw new IncorrectCredentialsException("token失效,请重新登录");
+ }
+
+ //查询用户信息
+ SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId());
+ //账号锁定
+ if(user.getStatus() == 0){
+ throw new LockedAccountException("账号已被锁定,请联系管理员");
+ }
+
+ SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
+ return info;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Token.java b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Token.java
new file mode 100644
index 0000000..119f31e
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/OAuth2Token.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.oauth2;
+
+
+import org.apache.shiro.authc.AuthenticationToken;
+
+/**
+ * token
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class OAuth2Token implements AuthenticationToken {
+ private String token;
+
+ public OAuth2Token(String token){
+ this.token = token;
+ }
+
+ @Override
+ public String getPrincipal() {
+ return token;
+ }
+
+ @Override
+ public Object getCredentials() {
+ return token;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/TokenGenerator.java b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/TokenGenerator.java
new file mode 100644
index 0000000..54bdca1
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/oauth2/TokenGenerator.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.oauth2;
+
+import io.renren.common.exception.RRException;
+
+import java.security.MessageDigest;
+import java.util.UUID;
+
+/**
+ * 生成token
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class TokenGenerator {
+
+ public static String generateValue() {
+ return generateValue(UUID.randomUUID().toString());
+ }
+
+ private static final char[] hexCode = "0123456789abcdef".toCharArray();
+
+ public static String toHexString(byte[] data) {
+ if(data == null) {
+ return null;
+ }
+ StringBuilder r = new StringBuilder(data.length*2);
+ for ( byte b : data) {
+ r.append(hexCode[(b >> 4) & 0xF]);
+ r.append(hexCode[(b & 0xF)]);
+ }
+ return r.toString();
+ }
+
+ public static String generateValue(String param) {
+ try {
+ MessageDigest algorithm = MessageDigest.getInstance("MD5");
+ algorithm.reset();
+ algorithm.update(param.getBytes());
+ byte[] messageDigest = algorithm.digest();
+ return toHexString(messageDigest);
+ } catch (Exception e) {
+ throw new RRException("生成Token失败", e);
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java b/renren-fast-master/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java
new file mode 100644
index 0000000..e6857e7
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.redis;
+
+
+import io.renren.common.utils.RedisKeys;
+import io.renren.common.utils.RedisUtils;
+import io.renren.modules.sys.entity.SysConfigEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 系统配置Redis
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class SysConfigRedis {
+ @Autowired
+ private RedisUtils redisUtils;
+
+ public void saveOrUpdate(SysConfigEntity config) {
+ if(config == null){
+ return ;
+ }
+ String key = RedisKeys.getSysConfigKey(config.getParamKey());
+ redisUtils.set(key, config);
+ }
+
+ public void delete(String configKey) {
+ String key = RedisKeys.getSysConfigKey(configKey);
+ redisUtils.delete(key);
+ }
+
+ public SysConfigEntity get(String configKey){
+ String key = RedisKeys.getSysConfigKey(configKey);
+ return redisUtils.get(key, SysConfigEntity.class);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/ShiroService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/ShiroService.java
new file mode 100644
index 0000000..5872f57
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/ShiroService.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+
+import java.util.Set;
+
+/**
+ * shiro相关接口
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface ShiroService {
+ /**
+ * 获取用户权限列表
+ */
+ Set getUserPermissions(long userId);
+
+ SysUserTokenEntity queryByToken(String token);
+
+ /**
+ * 根据用户ID,查询用户
+ * @param userId
+ */
+ SysUserEntity queryUser(Long userId);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java
new file mode 100644
index 0000000..0eeaf47
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.modules.sys.entity.SysCaptchaEntity;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * 验证码
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysCaptchaService extends IService {
+
+ /**
+ * 获取图片验证码
+ */
+ BufferedImage getCaptcha(String uuid);
+
+ /**
+ * 验证码效验
+ * @param uuid uuid
+ * @param code 验证码
+ * @return true:成功 false:失败
+ */
+ boolean validate(String uuid, String code);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysConfigService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysConfigService.java
new file mode 100644
index 0000000..0f48610
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysConfigService.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysConfigEntity;
+
+import java.util.Map;
+
+/**
+ * 系统配置信息
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysConfigService extends IService {
+
+ PageUtils queryPage(Map params);
+
+ /**
+ * 保存配置信息
+ */
+ public void saveConfig(SysConfigEntity config);
+
+ /**
+ * 更新配置信息
+ */
+ public void update(SysConfigEntity config);
+
+ /**
+ * 根据key,更新value
+ */
+ public void updateValueByKey(String key, String value);
+
+ /**
+ * 删除配置信息
+ */
+ public void deleteBatch(Long[] ids);
+
+ /**
+ * 根据key,获取配置的value值
+ *
+ * @param key key
+ */
+ public String getValue(String key);
+
+ /**
+ * 根据key,获取value的Object对象
+ * @param key key
+ * @param clazz Object对象
+ */
+ public T getConfigObject(String key, Class clazz);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysLogService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysLogService.java
new file mode 100644
index 0000000..71e8f4f
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysLogService.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysLogEntity;
+
+import java.util.Map;
+
+
+/**
+ * 系统日志
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysLogService extends IService {
+
+ PageUtils queryPage(Map params);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysMenuService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysMenuService.java
new file mode 100644
index 0000000..b20056b
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysMenuService.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.modules.sys.entity.SysMenuEntity;
+
+import java.util.List;
+
+
+/**
+ * 菜单管理
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysMenuService extends IService {
+
+ /**
+ * 根据父菜单,查询子菜单
+ * @param parentId 父菜单ID
+ * @param menuIdList 用户菜单ID
+ */
+ List queryListParentId(Long parentId, List menuIdList);
+
+ /**
+ * 根据父菜单,查询子菜单
+ * @param parentId 父菜单ID
+ */
+ List queryListParentId(Long parentId);
+
+ /**
+ * 获取不包含按钮的菜单列表
+ */
+ List queryNotButtonList();
+
+ /**
+ * 获取用户菜单列表
+ */
+ List getUserMenuList(Long userId);
+
+ /**
+ * 删除
+ */
+ void delete(Long menuId);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java
new file mode 100644
index 0000000..14bd509
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.modules.sys.entity.SysRoleMenuEntity;
+
+import java.util.List;
+
+
+
+/**
+ * 角色与菜单对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysRoleMenuService extends IService {
+
+ void saveOrUpdate(Long roleId, List menuIdList);
+
+ /**
+ * 根据角色ID,获取菜单ID列表
+ */
+ List queryMenuIdList(Long roleId);
+
+ /**
+ * 根据角色ID数组,批量删除
+ */
+ int deleteBatch(Long[] roleIds);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleService.java
new file mode 100644
index 0000000..92ae5c6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysRoleService.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysRoleEntity;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 角色
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysRoleService extends IService {
+
+ PageUtils queryPage(Map params);
+
+ void saveRole(SysRoleEntity role);
+
+ void update(SysRoleEntity role);
+
+ void deleteBatch(Long[] roleIds);
+
+
+ /**
+ * 查询用户创建的角色ID列表
+ */
+ List queryRoleIdList(Long createUserId);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java
new file mode 100644
index 0000000..b4441fa
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.modules.sys.entity.SysUserRoleEntity;
+
+import java.util.List;
+
+
+
+/**
+ * 用户与角色对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysUserRoleService extends IService {
+
+ void saveOrUpdate(Long userId, List roleIdList);
+
+ /**
+ * 根据用户ID,获取角色ID列表
+ */
+ List queryRoleIdList(Long userId);
+
+ /**
+ * 根据角色ID数组,批量删除
+ */
+ int deleteBatch(Long[] roleIds);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserService.java
new file mode 100644
index 0000000..e29b038
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserService.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysUserEntity;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 系统用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysUserService extends IService {
+
+ PageUtils queryPage(Map params);
+
+ /**
+ * 查询用户的所有权限
+ * @param userId 用户ID
+ */
+ List queryAllPerms(Long userId);
+
+ /**
+ * 查询用户的所有菜单ID
+ */
+ List queryAllMenuId(Long userId);
+
+ /**
+ * 根据用户名,查询系统用户
+ */
+ SysUserEntity queryByUserName(String username);
+
+ /**
+ * 保存用户
+ */
+ void saveUser(SysUserEntity user);
+
+ /**
+ * 修改用户
+ */
+ void update(SysUserEntity user);
+
+ /**
+ * 删除用户
+ */
+ void deleteBatch(Long[] userIds);
+
+ /**
+ * 修改密码
+ * @param userId 用户ID
+ * @param password 原密码
+ * @param newPassword 新密码
+ */
+ boolean updatePassword(Long userId, String password, String newPassword);
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java
new file mode 100644
index 0000000..f4ecb5a
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.R;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+
+/**
+ * 用户Token
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public interface SysUserTokenService extends IService {
+
+ /**
+ * 生成token
+ * @param userId 用户ID
+ */
+ R createToken(long userId);
+
+ /**
+ * 退出,修改token值
+ * @param userId 用户ID
+ */
+ void logout(long userId);
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java
new file mode 100644
index 0000000..12230bc
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import io.renren.common.utils.Constant;
+import io.renren.modules.sys.dao.SysMenuDao;
+import io.renren.modules.sys.dao.SysUserDao;
+import io.renren.modules.sys.dao.SysUserTokenDao;
+import io.renren.modules.sys.entity.SysMenuEntity;
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+import io.renren.modules.sys.service.ShiroService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Service
+public class ShiroServiceImpl implements ShiroService {
+ @Autowired
+ private SysMenuDao sysMenuDao;
+ @Autowired
+ private SysUserDao sysUserDao;
+ @Autowired
+ private SysUserTokenDao sysUserTokenDao;
+
+ @Override
+ public Set getUserPermissions(long userId) {
+ List permsList;
+
+ //系统管理员,拥有最高权限
+ if(userId == Constant.SUPER_ADMIN){
+ List menuList = sysMenuDao.selectList(null);
+ permsList = new ArrayList<>(menuList.size());
+ for(SysMenuEntity menu : menuList){
+ permsList.add(menu.getPerms());
+ }
+ }else{
+ permsList = sysUserDao.queryAllPerms(userId);
+ }
+ //用户权限列表
+ Set permsSet = new HashSet<>();
+ for(String perms : permsList){
+ if(StringUtils.isBlank(perms)){
+ continue;
+ }
+ permsSet.addAll(Arrays.asList(perms.trim().split(",")));
+ }
+ return permsSet;
+ }
+
+ @Override
+ public SysUserTokenEntity queryByToken(String token) {
+ return sysUserTokenDao.queryByToken(token);
+ }
+
+ @Override
+ public SysUserEntity queryUser(Long userId) {
+ return sysUserDao.selectById(userId);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java
new file mode 100644
index 0000000..b9c991e
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.code.kaptcha.Producer;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.DateUtils;
+import io.renren.modules.sys.dao.SysCaptchaDao;
+import io.renren.modules.sys.entity.SysCaptchaEntity;
+import io.renren.modules.sys.service.SysCaptchaService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.awt.image.BufferedImage;
+import java.util.Date;
+
+/**
+ * 验证码
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Service("sysCaptchaService")
+public class SysCaptchaServiceImpl extends ServiceImpl implements SysCaptchaService {
+ @Autowired
+ private Producer producer;
+
+ @Override
+ public BufferedImage getCaptcha(String uuid) {
+ if(StringUtils.isBlank(uuid)){
+ throw new RRException("uuid不能为空");
+ }
+ //生成文字验证码
+ String code = producer.createText();
+
+ SysCaptchaEntity captchaEntity = new SysCaptchaEntity();
+ captchaEntity.setUuid(uuid);
+ captchaEntity.setCode(code);
+ //5分钟后过期
+ captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5));
+ this.save(captchaEntity);
+
+ return producer.createImage(code);
+ }
+
+ @Override
+ public boolean validate(String uuid, String code) {
+ SysCaptchaEntity captchaEntity = this.getOne(new QueryWrapper().eq("uuid", uuid));
+ if(captchaEntity == null){
+ return false;
+ }
+
+ //删除验证码
+ this.removeById(uuid);
+
+ if(captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java
new file mode 100644
index 0000000..e62763d
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysConfigDao;
+import io.renren.modules.sys.entity.SysConfigEntity;
+import io.renren.modules.sys.redis.SysConfigRedis;
+import io.renren.modules.sys.service.SysConfigService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.Map;
+
+@Service("sysConfigService")
+public class SysConfigServiceImpl extends ServiceImpl implements SysConfigService {
+ @Autowired
+ private SysConfigRedis sysConfigRedis;
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String paramKey = (String)params.get("paramKey");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper()
+ .like(StringUtils.isNotBlank(paramKey),"param_key", paramKey)
+ .eq("status", 1)
+ );
+
+ return new PageUtils(page);
+ }
+
+ @Override
+ public void saveConfig(SysConfigEntity config) {
+ this.save(config);
+ sysConfigRedis.saveOrUpdate(config);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(SysConfigEntity config) {
+ this.updateById(config);
+ sysConfigRedis.saveOrUpdate(config);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateValueByKey(String key, String value) {
+ baseMapper.updateValueByKey(key, value);
+ sysConfigRedis.delete(key);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteBatch(Long[] ids) {
+ for(Long id : ids){
+ SysConfigEntity config = this.getById(id);
+ sysConfigRedis.delete(config.getParamKey());
+ }
+
+ this.removeByIds(Arrays.asList(ids));
+ }
+
+ @Override
+ public String getValue(String key) {
+ SysConfigEntity config = sysConfigRedis.get(key);
+ if(config == null){
+ config = baseMapper.queryByKey(key);
+ sysConfigRedis.saveOrUpdate(config);
+ }
+
+ return config == null ? null : config.getParamValue();
+ }
+
+ @Override
+ public T getConfigObject(String key, Class clazz) {
+ String value = getValue(key);
+ if(StringUtils.isNotBlank(value)){
+ return new Gson().fromJson(value, clazz);
+ }
+
+ try {
+ return clazz.newInstance();
+ } catch (Exception e) {
+ throw new RRException("获取参数失败");
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java
new file mode 100644
index 0000000..517f1ec
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysLogDao;
+import io.renren.modules.sys.entity.SysLogEntity;
+import io.renren.modules.sys.service.SysLogService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+
+@Service("sysLogService")
+public class SysLogServiceImpl extends ServiceImpl implements SysLogService {
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String key = (String)params.get("key");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper().like(StringUtils.isNotBlank(key),"username", key)
+ );
+
+ return new PageUtils(page);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java
new file mode 100644
index 0000000..63a2064
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.MapUtils;
+import io.renren.modules.sys.dao.SysMenuDao;
+import io.renren.modules.sys.entity.SysMenuEntity;
+import io.renren.modules.sys.service.SysMenuService;
+import io.renren.modules.sys.service.SysRoleMenuService;
+import io.renren.modules.sys.service.SysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+
+@Service("sysMenuService")
+public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService {
+ @Autowired
+ private SysUserService sysUserService;
+ @Autowired
+ private SysRoleMenuService sysRoleMenuService;
+
+ @Override
+ public List queryListParentId(Long parentId, List menuIdList) {
+ List menuList = queryListParentId(parentId);
+ if(menuIdList == null){
+ return menuList;
+ }
+
+ List userMenuList = new ArrayList<>();
+ for(SysMenuEntity menu : menuList){
+ if(menuIdList.contains(menu.getMenuId())){
+ userMenuList.add(menu);
+ }
+ }
+ return userMenuList;
+ }
+
+ @Override
+ public List queryListParentId(Long parentId) {
+ return baseMapper.queryListParentId(parentId);
+ }
+
+ @Override
+ public List queryNotButtonList() {
+ return baseMapper.queryNotButtonList();
+ }
+
+ @Override
+ public List getUserMenuList(Long userId) {
+ //系统管理员,拥有最高权限
+ if(userId == Constant.SUPER_ADMIN){
+ return getMenuList(null);
+ }
+
+ //用户菜单列表
+ List menuIdList = sysUserService.queryAllMenuId(userId);
+ return getMenuList(menuIdList);
+ }
+
+ /**
+ * 获取拥有的菜单列表
+ * @param menuIdList
+ * @return
+ */
+ private List getMenuList(List menuIdList) {
+ // 查询拥有的所有菜单
+ List menus = this.baseMapper.selectList(new QueryWrapper()
+ .in(Objects.nonNull(menuIdList), "menu_id", menuIdList).in("type", 0, 1));
+ //查询完成 对此list直接排序
+ Collections.sort(menus);
+
+ // 将id和菜单绑定
+ HashMap menuMap = new HashMap<>(12);
+ for (SysMenuEntity s : menus) {
+ menuMap.put(s.getMenuId(), s);
+ }
+ // 使用迭代器,组装菜单的层级关系
+ Iterator iterator = menus.iterator();
+ while (iterator.hasNext()) {
+ SysMenuEntity menu = iterator.next();
+ SysMenuEntity parent = menuMap.get(menu.getParentId());
+ if (Objects.nonNull(parent)) {
+ parent.getList().add(menu);
+ // 将这个菜单从当前节点移除
+ iterator.remove();
+ }
+ }
+
+ return menus;
+ }
+
+ @Override
+ public void delete(Long menuId){
+ //删除菜单
+ this.removeById(menuId);
+ //删除菜单与角色关联
+ sysRoleMenuService.removeByMap(new MapUtils().put("menu_id", menuId));
+ }
+
+ /**
+ * 获取所有菜单列表
+ */
+ private List getAllMenuList(List menuIdList){
+ //查询根菜单列表
+ List menuList = queryListParentId(0L, menuIdList);
+ //递归获取子菜单
+ getMenuTreeList(menuList, menuIdList);
+
+ return menuList;
+ }
+
+ /**
+ * 递归
+ */
+ private List getMenuTreeList(List menuList, List menuIdList){
+ List subMenuList = new ArrayList();
+
+ for(SysMenuEntity entity : menuList){
+ //目录
+ if(entity.getType() == Constant.MenuType.CATALOG.getValue()){
+ entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList));
+ }
+ subMenuList.add(entity);
+ }
+
+ return subMenuList;
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java
new file mode 100644
index 0000000..1d86268
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.modules.sys.dao.SysRoleMenuDao;
+import io.renren.modules.sys.entity.SysRoleMenuEntity;
+import io.renren.modules.sys.service.SysRoleMenuService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+
+/**
+ * 角色与菜单对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Service("sysRoleMenuService")
+public class SysRoleMenuServiceImpl extends ServiceImpl implements SysRoleMenuService {
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void saveOrUpdate(Long roleId, List menuIdList) {
+ //先删除角色与菜单关系
+ deleteBatch(new Long[]{roleId});
+
+ if(menuIdList.size() == 0){
+ return ;
+ }
+
+ //保存角色与菜单关系
+ for(Long menuId : menuIdList){
+ SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity();
+ sysRoleMenuEntity.setMenuId(menuId);
+ sysRoleMenuEntity.setRoleId(roleId);
+
+ this.save(sysRoleMenuEntity);
+ }
+ }
+
+ @Override
+ public List queryMenuIdList(Long roleId) {
+ return baseMapper.queryMenuIdList(roleId);
+ }
+
+ @Override
+ public int deleteBatch(Long[] roleIds){
+ return baseMapper.deleteBatch(roleIds);
+ }
+
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java
new file mode 100644
index 0000000..4885831
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysRoleDao;
+import io.renren.modules.sys.dao.SysUserDao;
+import io.renren.modules.sys.entity.SysRoleEntity;
+import io.renren.modules.sys.service.SysRoleMenuService;
+import io.renren.modules.sys.service.SysRoleService;
+import io.renren.modules.sys.service.SysUserRoleService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 角色
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Service("sysRoleService")
+public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService {
+ @Autowired
+ private SysRoleMenuService sysRoleMenuService;
+ @Autowired
+ private SysUserDao sysUserDao;
+ @Autowired
+ private SysUserRoleService sysUserRoleService;
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String roleName = (String)params.get("roleName");
+ Long createUserId = (Long)params.get("createUserId");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper()
+ .like(StringUtils.isNotBlank(roleName),"role_name", roleName)
+ .eq(createUserId != null,"create_user_id", createUserId)
+ );
+
+ return new PageUtils(page);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void saveRole(SysRoleEntity role) {
+ role.setCreateTime(new Date());
+ this.save(role);
+
+ //检查权限是否越权
+ checkPrems(role);
+
+ //保存角色与菜单关系
+ sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(SysRoleEntity role) {
+ this.updateById(role);
+
+ //检查权限是否越权
+ checkPrems(role);
+
+ //更新角色与菜单关系
+ sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteBatch(Long[] roleIds) {
+ //删除角色
+ this.removeByIds(Arrays.asList(roleIds));
+
+ //删除角色与菜单关联
+ sysRoleMenuService.deleteBatch(roleIds);
+
+ //删除角色与用户关联
+ sysUserRoleService.deleteBatch(roleIds);
+ }
+
+
+ @Override
+ public List queryRoleIdList(Long createUserId) {
+ return baseMapper.queryRoleIdList(createUserId);
+ }
+
+ /**
+ * 检查权限是否越权
+ */
+ private void checkPrems(SysRoleEntity role){
+ //如果不是超级管理员,则需要判断角色的权限是否超过自己的权限
+ if(role.getCreateUserId() == Constant.SUPER_ADMIN){
+ return ;
+ }
+
+ //查询用户所拥有的菜单列表
+ List menuIdList = sysUserDao.queryAllMenuId(role.getCreateUserId());
+
+ //判断是否越权
+ if(!menuIdList.containsAll(role.getMenuIdList())){
+ throw new RRException("新增角色的权限,已超出你的权限范围");
+ }
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java
new file mode 100644
index 0000000..7235c18
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.MapUtils;
+import io.renren.modules.sys.dao.SysUserRoleDao;
+import io.renren.modules.sys.entity.SysUserRoleEntity;
+import io.renren.modules.sys.service.SysUserRoleService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+
+/**
+ * 用户与角色对应关系
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Service("sysUserRoleService")
+public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService {
+
+ @Override
+ public void saveOrUpdate(Long userId, List roleIdList) {
+ //先删除用户与角色关系
+ this.removeByMap(new MapUtils().put("user_id", userId));
+
+ if(roleIdList == null || roleIdList.size() == 0){
+ return ;
+ }
+
+ //保存用户与角色关系
+ for(Long roleId : roleIdList){
+ SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
+ sysUserRoleEntity.setUserId(userId);
+ sysUserRoleEntity.setRoleId(roleId);
+
+ this.save(sysUserRoleEntity);
+ }
+ }
+
+ @Override
+ public List queryRoleIdList(Long userId) {
+ return baseMapper.queryRoleIdList(userId);
+ }
+
+ @Override
+ public int deleteBatch(Long[] roleIds){
+ return baseMapper.deleteBatch(roleIds);
+ }
+}
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java
new file mode 100644
index 0000000..52b8290
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.exception.RRException;
+import io.renren.common.utils.Constant;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysUserDao;
+import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.service.SysRoleService;
+import io.renren.modules.sys.service.SysUserRoleService;
+import io.renren.modules.sys.service.SysUserService;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.crypto.hash.Sha256Hash;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 系统用户
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Service("sysUserService")
+public class SysUserServiceImpl extends ServiceImpl implements SysUserService {
+ @Autowired
+ private SysUserRoleService sysUserRoleService;
+ @Autowired
+ private SysRoleService sysRoleService;
+
+ @Override
+ public PageUtils queryPage(Map params) {
+ String username = (String)params.get("username");
+ Long createUserId = (Long)params.get("createUserId");
+
+ IPage page = this.page(
+ new Query().getPage(params),
+ new QueryWrapper()
+ .like(StringUtils.isNotBlank(username),"username", username)
+ .eq(createUserId != null,"create_user_id", createUserId)
+ );
+
+ return new PageUtils(page);
+ }
+
+ @Override
+ public List queryAllPerms(Long userId) {
+ return baseMapper.queryAllPerms(userId);
+ }
+
+ @Override
+ public List queryAllMenuId(Long userId) {
+ return baseMapper.queryAllMenuId(userId);
+ }
+
+ @Override
+ public SysUserEntity queryByUserName(String username) {
+ return baseMapper.queryByUserName(username);
+ }
+
+ @Override
+ @Transactional
+ public void saveUser(SysUserEntity user) {
+ user.setCreateTime(new Date());
+ //sha256加密
+ String salt = RandomStringUtils.randomAlphanumeric(20);
+ user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
+ user.setSalt(salt);
+ this.save(user);
+
+ //检查角色是否越权
+ checkRole(user);
+
+ //保存用户与角色关系
+ sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
+ }
+
+ @Override
+ @Transactional
+ public void update(SysUserEntity user) {
+ if(StringUtils.isBlank(user.getPassword())){
+ user.setPassword(null);
+ }else{
+ user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
+ }
+ this.updateById(user);
+
+ //检查角色是否越权
+ checkRole(user);
+
+ //保存用户与角色关系
+ sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
+ }
+
+ @Override
+ public void deleteBatch(Long[] userId) {
+ this.removeByIds(Arrays.asList(userId));
+ }
+
+ @Override
+ public boolean updatePassword(Long userId, String password, String newPassword) {
+ SysUserEntity userEntity = new SysUserEntity();
+ userEntity.setPassword(newPassword);
+ return this.update(userEntity,
+ new QueryWrapper().eq("user_id", userId).eq("password", password));
+ }
+
+ /**
+ * 检查角色是否越权
+ */
+ private void checkRole(SysUserEntity user){
+ if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
+ return;
+ }
+ //如果不是超级管理员,则需要判断用户的角色是否自己创建
+ if(user.getCreateUserId() == Constant.SUPER_ADMIN){
+ return ;
+ }
+
+ //查询用户创建的角色列表
+ List roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());
+
+ //判断是否越权
+ if(!roleIdList.containsAll(user.getRoleIdList())){
+ throw new RRException("新增用户所选角色,不是本人创建");
+ }
+ }
+}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java
new file mode 100644
index 0000000..53e62e6
--- /dev/null
+++ b/renren-fast-master/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2016-2019 人人开源 All rights reserved.
+ *
+ * https://www.renren.io
+ *
+ * 版权所有,侵权必究!
+ */
+
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.R;
+import io.renren.modules.sys.dao.SysUserTokenDao;
+import io.renren.modules.sys.entity.SysUserTokenEntity;
+import io.renren.modules.sys.oauth2.TokenGenerator;
+import io.renren.modules.sys.service.SysUserTokenService;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+
+@Service("sysUserTokenService")
+public class SysUserTokenServiceImpl extends ServiceImpl implements SysUserTokenService {
+ //12小时后过期
+ private final static int EXPIRE = 3600 * 12;
+
+
+ @Override
+ public R createToken(long userId) {
+ //生成一个token
+ String token = TokenGenerator.generateValue();
+
+ //当前时间
+ Date now = new Date();
+ //过期时间
+ Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
+
+ //判断是否生成过token
+ SysUserTokenEntity tokenEntity = this.getById(userId);
+ if(tokenEntity == null){
+ tokenEntity = new SysUserTokenEntity();
+ tokenEntity.setUserId(userId);
+ tokenEntity.setToken(token);
+ tokenEntity.setUpdateTime(now);
+ tokenEntity.setExpireTime(expireTime);
+
+ //保存token
+ this.save(tokenEntity);
+ }else{
+ tokenEntity.setToken(token);
+ tokenEntity.setUpdateTime(now);
+ tokenEntity.setExpireTime(expireTime);
+
+ //更新token
+ this.updateById(tokenEntity);
+ }
+
+ R r = R.ok().put("token", token).put("expire", EXPIRE);
+
+ return r;
+ }
+
+ @Override
+ public void logout(long userId) {
+ //生成一个token
+ String token = TokenGenerator.generateValue();
+
+ //修改token
+ SysUserTokenEntity tokenEntity = new SysUserTokenEntity();
+ tokenEntity.setUserId(userId);
+ tokenEntity.setToken(token);
+ this.updateById(tokenEntity);
+ }
+}
diff --git a/renren-fast-master/src/main/resources/application-dev.yml b/renren-fast-master/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..b3db583
--- /dev/null
+++ b/renren-fast-master/src/main/resources/application-dev.yml
@@ -0,0 +1,49 @@
+spring:
+ datasource:
+ type: com.alibaba.druid.pool.DruidDataSource
+ druid:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/renren-fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+ username: root
+ password: root
+ initial-size: 10
+ max-active: 100
+ min-idle: 10
+ max-wait: 60000
+ pool-prepared-statements: true
+ max-pool-prepared-statement-per-connection-size: 20
+ time-between-eviction-runs-millis: 60000
+ min-evictable-idle-time-millis: 300000
+ #Oracle需要打开注释
+ #validation-query: SELECT 1 FROM DUAL
+ test-while-idle: true
+ test-on-borrow: false
+ test-on-return: false
+ stat-view-servlet:
+ enabled: true
+ url-pattern: /druid/*
+ #login-username: admin
+ #login-password: admin
+ filter:
+ stat:
+ log-slow-sql: true
+ slow-sql-millis: 1000
+ merge-sql: false
+ wall:
+ config:
+ multi-statement-allow: true
+
+
+##多数据源的配置
+#dynamic:
+# datasource:
+# slave1:
+# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
+# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security
+# username: sa
+# password: 123456
+# slave2:
+# driver-class-name: org.postgresql.Driver
+# url: jdbc:postgresql://localhost:5432/renren_security
+# username: renren
+# password: 123456
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/application-prod.yml b/renren-fast-master/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..b3db583
--- /dev/null
+++ b/renren-fast-master/src/main/resources/application-prod.yml
@@ -0,0 +1,49 @@
+spring:
+ datasource:
+ type: com.alibaba.druid.pool.DruidDataSource
+ druid:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/renren-fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+ username: root
+ password: root
+ initial-size: 10
+ max-active: 100
+ min-idle: 10
+ max-wait: 60000
+ pool-prepared-statements: true
+ max-pool-prepared-statement-per-connection-size: 20
+ time-between-eviction-runs-millis: 60000
+ min-evictable-idle-time-millis: 300000
+ #Oracle需要打开注释
+ #validation-query: SELECT 1 FROM DUAL
+ test-while-idle: true
+ test-on-borrow: false
+ test-on-return: false
+ stat-view-servlet:
+ enabled: true
+ url-pattern: /druid/*
+ #login-username: admin
+ #login-password: admin
+ filter:
+ stat:
+ log-slow-sql: true
+ slow-sql-millis: 1000
+ merge-sql: false
+ wall:
+ config:
+ multi-statement-allow: true
+
+
+##多数据源的配置
+#dynamic:
+# datasource:
+# slave1:
+# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
+# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security
+# username: sa
+# password: 123456
+# slave2:
+# driver-class-name: org.postgresql.Driver
+# url: jdbc:postgresql://localhost:5432/renren_security
+# username: renren
+# password: 123456
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/application-test.yml b/renren-fast-master/src/main/resources/application-test.yml
new file mode 100644
index 0000000..b3db583
--- /dev/null
+++ b/renren-fast-master/src/main/resources/application-test.yml
@@ -0,0 +1,49 @@
+spring:
+ datasource:
+ type: com.alibaba.druid.pool.DruidDataSource
+ druid:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/renren-fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+ username: root
+ password: root
+ initial-size: 10
+ max-active: 100
+ min-idle: 10
+ max-wait: 60000
+ pool-prepared-statements: true
+ max-pool-prepared-statement-per-connection-size: 20
+ time-between-eviction-runs-millis: 60000
+ min-evictable-idle-time-millis: 300000
+ #Oracle需要打开注释
+ #validation-query: SELECT 1 FROM DUAL
+ test-while-idle: true
+ test-on-borrow: false
+ test-on-return: false
+ stat-view-servlet:
+ enabled: true
+ url-pattern: /druid/*
+ #login-username: admin
+ #login-password: admin
+ filter:
+ stat:
+ log-slow-sql: true
+ slow-sql-millis: 1000
+ merge-sql: false
+ wall:
+ config:
+ multi-statement-allow: true
+
+
+##多数据源的配置
+#dynamic:
+# datasource:
+# slave1:
+# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
+# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security
+# username: sa
+# password: 123456
+# slave2:
+# driver-class-name: org.postgresql.Driver
+# url: jdbc:postgresql://localhost:5432/renren_security
+# username: renren
+# password: 123456
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/application.yml b/renren-fast-master/src/main/resources/application.yml
new file mode 100644
index 0000000..b567b5f
--- /dev/null
+++ b/renren-fast-master/src/main/resources/application.yml
@@ -0,0 +1,79 @@
+# Tomcat
+server:
+ tomcat:
+ uri-encoding: UTF-8
+ threads:
+ max: 1000
+ min-spare: 30
+ connection-timeout: 5000ms
+ port: 8080
+ servlet:
+ context-path: /renren-fast
+
+spring:
+ # 环境 dev|test|prod
+ profiles:
+ active: dev
+ # jackson时间格式化
+ jackson:
+ time-zone: GMT+8
+ date-format: yyyy-MM-dd HH:mm:ss
+ servlet:
+ multipart:
+ max-file-size: 100MB
+ max-request-size: 100MB
+ enabled: true
+ redis:
+ open: false # 是否开启redis缓存 true开启 false关闭
+ database: 0
+ host: localhost
+ port: 6379
+ password: # 密码(默认为空)
+ timeout: 6000ms # 连接超时时长(毫秒)
+ jedis:
+ pool:
+ max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
+ max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
+ max-idle: 10 # 连接池中的最大空闲连接
+ min-idle: 5 # 连接池中的最小空闲连接
+ mvc:
+ throw-exception-if-no-handler-found: true
+ pathmatch:
+ matching-strategy: ANT_PATH_MATCHER
+# resources:
+# add-mappings: false
+
+
+#mybatis
+mybatis-plus:
+ mapper-locations: classpath*:/mapper/**/*.xml
+ #实体扫描,多个package用逗号或者分号分隔
+ typeAliasesPackage: io.renren.modules.*.entity
+ global-config:
+ #数据库相关配置
+ db-config:
+ #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
+ id-type: AUTO
+ logic-delete-value: -1
+ logic-not-delete-value: 0
+ banner: false
+ #原生配置
+ configuration:
+ map-underscore-to-camel-case: true
+ cache-enabled: false
+ call-setters-on-nulls: true
+ jdbc-type-for-null: 'null'
+
+
+renren:
+ redis:
+ open: false
+ shiro:
+ redis: false
+ # APP模块,是通过jwt认证的,如果要使用APP模块,则需要修改【加密秘钥】
+ jwt:
+ # 加密秘钥
+ secret: f4e2e52034348f86b67cde581c0f9eb5[www.renren.io]
+ # token有效时长,7天,单位秒
+ expire: 604800
+ header: token
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/banner.txt b/renren-fast-master/src/main/resources/banner.txt
new file mode 100644
index 0000000..ec3d43f
--- /dev/null
+++ b/renren-fast-master/src/main/resources/banner.txt
@@ -0,0 +1,5 @@
+====================================================================================================================
+
+ 欢迎使用 renren-fast 人人快速开发平台 - Powered By https://www.renren.io/
+
+====================================================================================================================
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/logback-spring.xml b/renren-fast-master/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..5deef21
--- /dev/null
+++ b/renren-fast-master/src/main/resources/logback-spring.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/app/UserDao.xml b/renren-fast-master/src/main/resources/mapper/app/UserDao.xml
new file mode 100644
index 0000000..ba7cca9
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/app/UserDao.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/job/ScheduleJobDao.xml b/renren-fast-master/src/main/resources/mapper/job/ScheduleJobDao.xml
new file mode 100644
index 0000000..bcfe54a
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/job/ScheduleJobDao.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+ update schedule_job set status = #{status} where job_id in
+
+ #{jobId}
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/job/ScheduleJobLogDao.xml b/renren-fast-master/src/main/resources/mapper/job/ScheduleJobLogDao.xml
new file mode 100644
index 0000000..82cc799
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/job/ScheduleJobLogDao.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/oss/SysOssDao.xml b/renren-fast-master/src/main/resources/mapper/oss/SysOssDao.xml
new file mode 100644
index 0000000..bbb3af4
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/oss/SysOssDao.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysConfigDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysConfigDao.xml
new file mode 100644
index 0000000..710e866
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysConfigDao.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ update sys_config set param_value = #{paramValue} where param_key = #{paramKey}
+
+
+
+
+ select * from sys_config where param_key = #{paramKey}
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysLogDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysLogDao.xml
new file mode 100644
index 0000000..d2be2f9
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysLogDao.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysMenuDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysMenuDao.xml
new file mode 100644
index 0000000..01d2370
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysMenuDao.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ select * from sys_menu where parent_id = #{parentId} order by order_num asc
+
+
+
+ select * from sys_menu where type != 2 order by order_num asc
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysRoleDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysRoleDao.xml
new file mode 100644
index 0000000..b048b8b
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysRoleDao.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+ select role_id from sys_role where create_user_id = #{createUserId}
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysRoleMenuDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysRoleMenuDao.xml
new file mode 100644
index 0000000..e9453db
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysRoleMenuDao.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+ delete from sys_role_menu where role_id in
+
+ #{roleId}
+
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysUserDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysUserDao.xml
new file mode 100644
index 0000000..b3e8a99
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysUserDao.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ select m.perms from sys_user_role ur
+ LEFT JOIN sys_role_menu rm on ur.role_id = rm.role_id
+ LEFT JOIN sys_menu m on rm.menu_id = m.menu_id
+ where ur.user_id = #{userId}
+
+
+
+
+
+
+ select * from sys_user where username = #{username}
+
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysUserRoleDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysUserRoleDao.xml
new file mode 100644
index 0000000..e88a418
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysUserRoleDao.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ delete from sys_user_role where role_id in
+
+ #{roleId}
+
+
+
+
+ select role_id from sys_user_role where user_id = #{value}
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/mapper/sys/SysUserTokenDao.xml b/renren-fast-master/src/main/resources/mapper/sys/SysUserTokenDao.xml
new file mode 100644
index 0000000..270792b
--- /dev/null
+++ b/renren-fast-master/src/main/resources/mapper/sys/SysUserTokenDao.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+ select * from sys_user_token where token = #{value}
+
+
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/favicon.ico b/renren-fast-master/src/main/resources/static/favicon.ico
new file mode 100644
index 0000000..2bd581c
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/favicon.ico differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/css/print.css b/renren-fast-master/src/main/resources/static/swagger/css/print.css
new file mode 100644
index 0000000..f2e8446
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/css/print.css
@@ -0,0 +1 @@
+.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:''}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}#header{display:none}.swagger-section .swagger-ui-wrap .model-signature pre{max-height:none}.swagger-section .swagger-ui-wrap .body-textarea,.swagger-section .swagger-ui-wrap input.parameter{width:100px}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{display:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{display:block!important}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/swagger/css/reset.css b/renren-fast-master/src/main/resources/static/swagger/css/reset.css
new file mode 100644
index 0000000..40dc830
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/css/reset.css
@@ -0,0 +1 @@
+a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/swagger/css/screen.css b/renren-fast-master/src/main/resources/static/swagger/css/screen.css
new file mode 100644
index 0000000..1f069f6
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/css/screen.css
@@ -0,0 +1 @@
+.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:''}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}.swagger-section .access,.swagger-section .auth{float:right}.swagger-section .api-ic{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .api-ic .api_information_panel{position:relative;margin-top:20px;margin-left:-5px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .api-ic .api_information_panel p .api-msg-enabled{color:green}.swagger-section .api-ic .api_information_panel p .api-msg-disabled{color:red}.swagger-section .api-ic:hover .api_information_panel{position:absolute;display:block}.swagger-section .ic-info{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-warning{background-position:-60px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-error{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-off{background-position:-90px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section .ic-on{background-position:-160px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section #header{background-color:#89bf04;padding:9px 14px 19px;height:23px;min-width:775px}.swagger-section #input_baseUrl{width:400px}.swagger-section #api_selector{display:block;clear:none;float:right}.swagger-section #api_selector .input{display:inline-block;clear:none;margin:0 10px 0 0}.swagger-section #api_selector input{font-size:.9em;padding:3px;margin:0}.swagger-section #input_apiKey{width:200px}.swagger-section #auth_container .authorize__btn,.swagger-section #explore{display:block;text-decoration:none;font-weight:700;padding:6px 8px;font-size:.9em;color:#fff;background-color:#547f00;border-radius:4px}.swagger-section #auth_container .authorize__btn:hover,.swagger-section #explore:hover{background-color:#547f00}.swagger-section #header #logo{font-size:1.5em;font-weight:700;text-decoration:none;color:#fff}.swagger-section #header #logo .logo__img{display:block;float:left;margin-top:2px}.swagger-section #header #logo .logo__title{display:inline-block;padding:5px 0 0 10px}.swagger-section #content_message{margin:10px 15px;font-style:italic;color:#999}.swagger-section #message-bar{min-height:30px;text-align:center;padding-top:10px}.swagger-section .swagger-collapse:before{content:"-"}.swagger-section .swagger-expand:before{content:"+"}.swagger-section .error{outline-color:#c00;background-color:#f2dede}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/swagger/css/style.css b/renren-fast-master/src/main/resources/static/swagger/css/style.css
new file mode 100644
index 0000000..52907e4
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/css/style.css
@@ -0,0 +1 @@
+.swagger-section #header a#logo{font-size:1.5em;font-weight:700;text-decoration:none;padding:20px 0 20px 40px}#text-head{font-size:80px;font-family:Roboto,sans-serif;color:#fff;float:right;margin-right:20%}.navbar-fixed-top .navbar-brand,.navbar-fixed-top .navbar-nav,.navbar-header{height:auto}.navbar-inverse{background-color:#000;border-color:#000}#navbar-brand{margin-left:20%}.navtext{font-size:10px}.h1,h1{font-size:60px}.navbar-default .navbar-header .navbar-brand{color:#a2dfee}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#393939;font-family:Arvo,serif;font-size:1.5em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#525252;padding-left:0;display:block;clear:none;float:left;font-family:Arvo,serif;font-weight:700}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#0a0a0a}.container1{width:1500px;margin:auto;margin-top:0;background-repeat:no-repeat;background-position:-40px -20px;margin-bottom:210px}.container-inner{width:1200px;margin:auto;background-color:hsla(192,8%,88%,.75);padding-bottom:40px;padding-top:40px;border-radius:15px}.header-content{padding:0;width:1000px}.title1{font-size:80px;font-family:Vollkorn,serif;color:#404040;text-align:center;padding-top:40px;padding-bottom:100px}#icon{margin-top:-18px}.subtext{font-size:25px;font-style:italic;color:#08b;text-align:right;padding-right:250px}.bg-primary{background-color:#00468b}.navbar-default .nav>li>a,.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:focus:hover,.navbar-default .nav>li>a:hover{color:#08b}.text-faded{font-size:25px;font-family:Vollkorn,serif}.section-heading{font-family:Vollkorn,serif;font-size:45px;padding-bottom:10px}hr{border-color:#00468b;padding-bottom:10px}.description{margin-top:20px;padding-bottom:200px}.description li{font-family:Vollkorn,serif;font-size:25px;color:#525252;margin-left:28%;padding-top:5px}.gap{margin-top:200px}.troubleshootingtext{color:hsla(0,0%,100%,.7);padding-left:30%}.troubleshootingtext li{list-style-type:circle;font-size:25px;padding-bottom:5px}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.block.response_body.json:hover{cursor:pointer}.backdrop{color:blue}#myModal{height:100%}.modal-backdrop{bottom:0;position:fixed}.curl{padding:10px;font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em;max-height:400px;margin-top:5px;overflow-y:auto;background-color:#fcf6db;border:1px solid #e5e0c6;border-radius:4px}.curl_title{font-size:1.1em;margin:0;padding:15px 0 5px;font-family:Open Sans,Helvetica Neue,Arial,sans-serif;font-weight:500;line-height:1.1}.footer{display:none}.swagger-section .swagger-ui-wrap h2{padding:0}h2{margin:0;margin-bottom:5px}.markdown p,.swagger-section .swagger-ui-wrap .code{font-size:15px;font-family:Arvo,serif}.swagger-section .swagger-ui-wrap b{font-family:Arvo,serif}#signin:hover{cursor:pointer}.dropdown-menu{padding:15px}.navbar-right .dropdown-menu{left:0;right:auto}#signinbutton{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}.navbar-default .nav>li .details{color:#000;text-transform:none;font-size:15px;font-weight:400;font-family:Open Sans,sans-serif;font-style:italic;line-height:20px;top:-2px}.navbar-default .nav>li .details:hover{color:#000}#signout{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/swagger/css/typography.css b/renren-fast-master/src/main/resources/static/swagger/css/typography.css
new file mode 100644
index 0000000..e69de29
diff --git a/renren-fast-master/src/main/resources/static/swagger/favicon-16x16.png b/renren-fast-master/src/main/resources/static/swagger/favicon-16x16.png
new file mode 100644
index 0000000..0f7e13b
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/favicon-16x16.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/favicon-32x32.png b/renren-fast-master/src/main/resources/static/swagger/favicon-32x32.png
new file mode 100644
index 0000000..b0a3352
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/favicon-32x32.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf b/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf
new file mode 100644
index 0000000..036c4d1
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans.ttf b/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans.ttf
new file mode 100644
index 0000000..e517a0c
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/fonts/DroidSans.ttf differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/collapse.gif b/renren-fast-master/src/main/resources/static/swagger/images/collapse.gif
new file mode 100644
index 0000000..8843e8c
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/collapse.gif differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/expand.gif b/renren-fast-master/src/main/resources/static/swagger/images/expand.gif
new file mode 100644
index 0000000..477bf13
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/expand.gif differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/explorer_icons.png b/renren-fast-master/src/main/resources/static/swagger/images/explorer_icons.png
new file mode 100644
index 0000000..be43b27
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/explorer_icons.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/favicon-16x16.png b/renren-fast-master/src/main/resources/static/swagger/images/favicon-16x16.png
new file mode 100644
index 0000000..0f7e13b
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/favicon-16x16.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/favicon-32x32.png b/renren-fast-master/src/main/resources/static/swagger/images/favicon-32x32.png
new file mode 100644
index 0000000..b0a3352
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/favicon-32x32.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/favicon.ico b/renren-fast-master/src/main/resources/static/swagger/images/favicon.ico
new file mode 100644
index 0000000..8b60bcf
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/favicon.ico differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/logo_small.png b/renren-fast-master/src/main/resources/static/swagger/images/logo_small.png
new file mode 100644
index 0000000..ce3908e
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/logo_small.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/pet_store_api.png b/renren-fast-master/src/main/resources/static/swagger/images/pet_store_api.png
new file mode 100644
index 0000000..1192ad8
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/pet_store_api.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/throbber.gif b/renren-fast-master/src/main/resources/static/swagger/images/throbber.gif
new file mode 100644
index 0000000..0639388
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/throbber.gif differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/images/wordnik_api.png b/renren-fast-master/src/main/resources/static/swagger/images/wordnik_api.png
new file mode 100644
index 0000000..dc0ddab
Binary files /dev/null and b/renren-fast-master/src/main/resources/static/swagger/images/wordnik_api.png differ
diff --git a/renren-fast-master/src/main/resources/static/swagger/index.html b/renren-fast-master/src/main/resources/static/swagger/index.html
new file mode 100644
index 0000000..200e5cf
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/index.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+ 接口文档 - 人人开源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/renren-fast-master/src/main/resources/static/swagger/index.yaml b/renren-fast-master/src/main/resources/static/swagger/index.yaml
new file mode 100644
index 0000000..58b7578
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/index.yaml
@@ -0,0 +1,1664 @@
+swagger: '2.0'
+info:
+ description: renren-fast是一个轻量级的Java快速开发平台,能快速开发项目并交付【接私活利器】
+ version: 1.0.0
+ title: 人人快速开发平台
+
+basePath: /renren-fast
+
+schemes:
+ - http
+
+#认证
+securityDefinitions:
+ api_key:
+ type: "apiKey"
+ name: "token"
+ in: "header"
+
+#定义接口数据
+paths:
+ /captcha.jpg:
+ get:
+ tags:
+ - 用户登录
+ summary: 获取验证码
+ produces:
+ - application/octet-stream
+ parameters:
+ - name: uuid
+ description: UUID
+ in: query
+ type: string
+ required: true
+ /sys/login:
+ post:
+ tags:
+ - 用户登录
+ summary: 用户登录
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 管理员对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/LoginForm'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/Login'
+
+ /sys/user/list:
+ get:
+ tags:
+ - 管理员管理
+ summary: 管理员列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: username
+ description: 用户名
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回管理员列表
+ schema:
+ $ref: '#/definitions/SysUserEntityList'
+ /sys/user/info:
+ get:
+ tags:
+ - 管理员管理
+ summary: 当前管理员信息
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回当前管理员信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ user:
+ $ref: '#/definitions/SysUserEntity'
+ /sys/user/info/{userId}:
+ get:
+ tags:
+ - 管理员管理
+ summary: 获取管理员信息
+ produces:
+ - application/json
+ parameters:
+ - name: userId
+ description: 用户ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回管理员信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ user:
+ $ref: '#/definitions/SysUserEntity'
+ /sys/user/password:
+ post:
+ tags:
+ - 管理员管理
+ summary: 修改密码
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 管理员对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/PasswordForm'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/user/save:
+ post:
+ tags:
+ - 管理员管理
+ summary: 添加管理员
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 管理员对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysUserEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/user/update:
+ post:
+ tags:
+ - 管理员管理
+ summary: 修改管理员
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 管理员对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysUserEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/user/delete:
+ post:
+ tags:
+ - 管理员管理
+ summary: 删除管理员
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 用户ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/role/list:
+ get:
+ tags:
+ - 角色管理
+ summary: 角色列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: roleName
+ description: 角色名
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回角色列表
+ schema:
+ $ref: '#/definitions/SysRoleEntityList'
+ /sys/role/select:
+ get:
+ tags:
+ - 角色管理
+ summary: 当前账号角色列表
+ description: 如果是超级管理员,则能查询所有的角色列表
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回角色列表
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysRoleEntity'
+ /sys/role/info/{roleId}:
+ get:
+ tags:
+ - 角色管理
+ summary: 获取角色信息
+ produces:
+ - application/json
+ parameters:
+ - name: roleId
+ description: 角色ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回角色信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ role:
+ $ref: '#/definitions/SysRoleEntity'
+ /sys/role/save:
+ post:
+ tags:
+ - 角色管理
+ summary: 添加角色
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 角色对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysRoleEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/role/update:
+ post:
+ tags:
+ - 角色管理
+ summary: 修改角色
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 角色对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysRoleEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/role/delete:
+ post:
+ tags:
+ - 角色管理
+ summary: 删除角色
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 角色ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/menu/nav:
+ get:
+ tags:
+ - 菜单管理
+ summary: 导航菜单列表
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回导航菜单列表
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ menuList:
+ description: 菜单列表
+ type: array
+ items:
+ $ref: '#/definitions/SysMenuEntity'
+ permissions:
+ description: 权限列表
+ type: array
+ items:
+ type: string
+ /sys/menu/list:
+ get:
+ tags:
+ - 菜单管理
+ summary: 菜单列表
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回菜单列表
+ schema:
+ type: array
+ items:
+ $ref: '#/definitions/SysMenuEntity'
+ /sys/menu/select:
+ get:
+ tags:
+ - 菜单管理
+ summary: 选择菜单
+ description: 添加、修改菜单的时候,选择上级菜单接口
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回菜单列表
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ menuList:
+ description: 菜单列表
+ type: array
+ items:
+ $ref: '#/definitions/SysMenuEntity'
+ /sys/menu/info/{menuId}:
+ get:
+ tags:
+ - 菜单管理
+ summary: 获取菜单信息
+ produces:
+ - application/json
+ parameters:
+ - name: menuId
+ description: 菜单ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回菜单信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ menu:
+ description: 菜单信息
+ $ref: '#/definitions/SysMenuEntity'
+ /sys/menu/save:
+ post:
+ tags:
+ - 菜单管理
+ summary: 添加菜单
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 菜单对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysMenuEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/menu/update:
+ post:
+ tags:
+ - 菜单管理
+ summary: 修改菜单
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 菜单对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysMenuEntityEdit'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/menu/delete/{menuId}:
+ post:
+ tags:
+ - 菜单管理
+ summary: 删除菜单
+ produces:
+ - application/json
+ parameters:
+ - name: menuId
+ description: 菜单ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/log/list:
+ get:
+ tags:
+ - 系统日志
+ summary: 日志列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: key
+ description: 用户名或用户操作
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回日志列表
+ schema:
+ $ref: '#/definitions/SysLogEntityList'
+
+ /sys/config/list:
+ get:
+ tags:
+ - 参数管理
+ summary: 参数列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: key
+ description: 参数名
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回参数列表
+ schema:
+ $ref: '#/definitions/SysConfigEntityList'
+ /sys/config/info/{id}:
+ get:
+ tags:
+ - 参数管理
+ summary: 获取参数信息
+ produces:
+ - application/json
+ parameters:
+ - name: id
+ description: 参数ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回参数信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ config:
+ description: 返回参数信息
+ $ref: '#/definitions/SysConfigEntity'
+ /sys/config/save:
+ post:
+ tags:
+ - 参数管理
+ summary: 添加参数
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 参数对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysConfigEntity'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/config/update:
+ post:
+ tags:
+ - 参数管理
+ summary: 修改参数
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 参数对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysConfigEntity'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/config/delete:
+ post:
+ tags:
+ - 参数管理
+ summary: 删除参数
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 参数ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/oss/list:
+ get:
+ tags:
+ - 文件服务
+ summary: 文件列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回文件列表
+ schema:
+ $ref: '#/definitions/SysOssEntityList'
+ /sys/oss/config:
+ get:
+ tags:
+ - 文件服务
+ summary: 云存储配置信息
+ produces:
+ - application/json
+ responses:
+ '200':
+ description: 返回云存储配置信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ config:
+ description: 云存储配置信息
+ $ref: '#/definitions/SysCloudStorageEntity'
+ /sys/oss/saveConfig:
+ post:
+ tags:
+ - 文件服务
+ summary: 保存云存储配置信息
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 参数对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/SysCloudStorageEntity'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/oss/upload:
+ post:
+ tags:
+ - 文件服务
+ summary: 上传文件
+ consumes:
+ - multipart/form-data
+ produces:
+ - application/json
+ parameters:
+ - name: file
+ description: 文件
+ in: formData
+ type: file
+ required: true
+ responses:
+ '200':
+ description: 返回文件列表
+ schema:
+ $ref: '#/definitions/FileUpload'
+ /sys/oss/delete:
+ post:
+ tags:
+ - 文件服务
+ summary: 删除文件
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 文件ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/schedule/list:
+ get:
+ tags:
+ - 定时任务
+ summary: 定时任务列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: beanName
+ description: spring bean名称
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回定时任务列表
+ schema:
+ $ref: '#/definitions/ScheduleJobEntityList'
+ /sys/schedule/info/{jobId}:
+ get:
+ tags:
+ - 定时任务
+ summary: 获取定时任务信息
+ produces:
+ - application/json
+ parameters:
+ - name: jobId
+ description: 定时任务ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回定时任务信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ schedule:
+ description: 定时任务信息
+ $ref: '#/definitions/ScheduleJobEntity'
+ /sys/schedule/save:
+ post:
+ tags:
+ - 定时任务
+ summary: 添加定时任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/ScheduleJobEntity'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/schedule/update:
+ post:
+ tags:
+ - 定时任务
+ summary: 修改定时任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务对象
+ in: body
+ type: string
+ schema:
+ $ref: '#/definitions/ScheduleJobEntity'
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/schedule/delete:
+ post:
+ tags:
+ - 定时任务
+ summary: 删除定时任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/schedule/run:
+ post:
+ tags:
+ - 定时任务
+ summary: 立即执行任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/schedule/pause:
+ post:
+ tags:
+ - 定时任务
+ summary: 暂停定时任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+ /sys/schedule/resume:
+ post:
+ tags:
+ - 定时任务
+ summary: 恢复定时任务
+ produces:
+ - application/json
+ parameters:
+ - name: body
+ description: 定时任务ID列表
+ in: body
+ type: array
+ items:
+ type: integer
+ format: int64
+ default: 0
+ required: true
+ responses:
+ '200':
+ schema:
+ $ref: '#/definitions/R'
+
+ /sys/scheduleLog/list:
+ get:
+ tags:
+ - 定时任务
+ summary: 定时任务日志列表
+ produces:
+ - application/json
+ parameters:
+ - name: page
+ description: 页码
+ in: query
+ type: integer
+ required: true
+ - name: limit
+ description: 每页条数
+ in: query
+ type: integer
+ required: true
+ - name: sidx
+ description: 排序字段
+ in: query
+ type: string
+ - name: order
+ description: 排序方式,如:asc、desc
+ in: query
+ type: string
+ - name: beanName
+ description: spring bean名称
+ in: query
+ type: string
+ responses:
+ '200':
+ description: 返回定时任务日志列表
+ schema:
+ $ref: '#/definitions/ScheduleJobLogEntityList'
+ /sys/scheduleLog/info/{logId}:
+ get:
+ tags:
+ - 定时任务
+ summary: 获取定时任务日志信息
+ produces:
+ - application/json
+ parameters:
+ - name: logId
+ description: 日志ID
+ in: path
+ type: integer
+ required: true
+ responses:
+ '200':
+ description: 返回定时任务日志信息
+ schema:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ schedule:
+ description: 定时任务日志信息
+ $ref: '#/definitions/ScheduleJobLogEntity'
+
+#定义数据模型
+definitions:
+ R:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ msg:
+ description: 失败原因
+ type: string
+ Login:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ token:
+ description: token
+ type: string
+ expire:
+ description: 过期时长
+ type: integer
+ format: int32
+ msg:
+ description: 失败原因
+ type: string
+ LoginForm:
+ type: object
+ properties:
+ username:
+ description: 用户名
+ type: string
+ password:
+ description: 密码
+ type: string
+ captcha:
+ description: 验证码
+ type: string
+ uuid:
+ description: UUID
+ type: string
+ PasswordForm:
+ type: object
+ properties:
+ password:
+ description: 原密码
+ type: string
+ newPassword:
+ description: 新密码
+ type: string
+ SysUserEntity:
+ type: object
+ properties:
+ userId:
+ description: 用户ID
+ type: integer
+ format: int64
+ username:
+ description: 用户名
+ type: string
+ password:
+ description: 密码
+ type: string
+ email:
+ description: 邮箱
+ type: string
+ mobile:
+ description: 手机号
+ type: string
+ status:
+ description: 状态 0:禁用 1:正常
+ type: integer
+ format: int32
+ roleIdList:
+ description: 角色ID列表
+ type: array
+ items:
+ type: integer
+ format: int64
+ createUserId:
+ description: 创建者ID
+ type: integer
+ format: int64
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ SysUserEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysUserEntity'
+ SysUserEntityEdit:
+ type: object
+ properties:
+ userId:
+ description: 用户ID
+ type: integer
+ format: int64
+ username:
+ description: 用户名
+ type: string
+ password:
+ description: 密码
+ type: string
+ email:
+ description: 邮箱
+ type: string
+ mobile:
+ description: 手机号
+ type: string
+ status:
+ description: 状态 0:禁用 1:正常
+ type: integer
+ format: int32
+ roleIdList:
+ description: 角色ID列表
+ type: array
+ items:
+ type: integer
+ format: int32
+
+ SysRoleEntity:
+ type: object
+ properties:
+ roleId:
+ description: 角色ID
+ type: integer
+ format: int64
+ roleName:
+ description: 角色名称
+ type: string
+ remark:
+ description: 备注
+ type: string
+ menuIdList:
+ description: 菜单ID列表
+ type: array
+ items:
+ type: integer
+ format: int64
+ createUserId:
+ description: 创建者ID
+ type: integer
+ format: int64
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ SysRoleEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysRoleEntity'
+ SysRoleEntityEdit:
+ type: object
+ properties:
+ roleId:
+ description: 角色ID
+ type: integer
+ format: int64
+ roleName:
+ description: 角色名称
+ type: string
+ remark:
+ description: 备注
+ type: string
+ menuIdList:
+ description: 菜单ID列表
+ type: array
+ items:
+ type: integer
+ format: int64
+
+ SysMenuEntity:
+ type: object
+ properties:
+ menuId:
+ description: 菜单ID
+ type: integer
+ format: int64
+ name:
+ description: 菜单名称
+ type: string
+ parentId:
+ description: 父菜单ID,一级菜单为0
+ type: integer
+ format: int64
+ parentName:
+ description: 父菜单名称
+ type: string
+ url:
+ description: 菜单URL
+ type: string
+ perms:
+ description: 授权标识
+ type: string
+ type:
+ description: 类型 0:目录 1:菜单 2:按钮
+ type: integer
+ format: int32
+ icon:
+ description: 菜单图标
+ type: string
+ orderNum:
+ description: 排序
+ type: integer
+ format: int32
+ open:
+ description: 是否展开 true:展开 false:不展开
+ type: boolean
+ format: int32
+ SysMenuEntityEdit:
+ type: object
+ properties:
+ menuId:
+ description: 菜单ID
+ type: integer
+ format: int64
+ name:
+ description: 菜单名称
+ type: string
+ parentId:
+ description: 父菜单ID,一级菜单为0
+ type: integer
+ format: int64
+ url:
+ description: 菜单URL
+ type: string
+ perms:
+ description: 授权标识
+ type: string
+ type:
+ description: 类型 0:目录 1:菜单 2:按钮
+ type: integer
+ format: int32
+ icon:
+ description: 菜单图标
+ type: string
+ orderNum:
+ description: 排序
+ type: integer
+ format: int32
+
+ SysLogEntity:
+ type: object
+ properties:
+ id:
+ description: 日志ID
+ type: integer
+ format: int64
+ username:
+ description: 用户名
+ type: string
+ operation:
+ description: 用户操作
+ type: string
+ method:
+ description: 请求方法
+ type: string
+ params:
+ description: 请求参数
+ type: string
+ time:
+ description: 执行时长(毫秒)
+ type: integer
+ format: int64
+ ip:
+ description: IP地址
+ type: string
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ SysLogEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysLogEntity'
+
+ SysConfigEntity:
+ type: object
+ properties:
+ id:
+ description: 参数ID
+ type: integer
+ format: int64
+ key:
+ description: 参数名
+ type: string
+ value:
+ description: 参数值
+ type: string
+ remark:
+ description: 备注
+ type: string
+ SysConfigEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysConfigEntity'
+
+ SysOssEntity:
+ type: object
+ properties:
+ id:
+ description: ID
+ type: integer
+ format: int64
+ url:
+ description: URL地址
+ type: string
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ SysOssEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/SysOssEntity'
+ SysCloudStorageEntity:
+ type: object
+ properties:
+ type:
+ description: 类型 1:七牛 2:阿里云 3:腾讯云
+ type: integer
+ format: int32
+ qiniuDomain:
+ description: 七牛绑定的域名
+ type: string
+ qiniuPrefix:
+ description: 七牛路径前缀
+ type: string
+ qiniuAccessKey:
+ description: 七牛ACCESS_KEY
+ type: string
+ qiniuSecretKey:
+ description: 七牛SECRET_KEY
+ type: string
+ qiniuBucketName:
+ description: 七牛存储空间名
+ type: string
+ aliyunDomain:
+ description: 阿里云绑定的域名
+ type: string
+ aliyunPrefix:
+ description: 阿里云路径前缀
+ type: string
+ aliyunEndPoint:
+ description: 阿里云EndPoint
+ type: string
+ aliyunAccessKeyId:
+ description: 阿里云AccessKeyId
+ type: string
+ aliyunAccessKeySecret:
+ description: 阿里云AccessKeySecret
+ type: string
+ aliyunBucketName:
+ description: 阿里云BucketName
+ type: string
+ qcloudDomain:
+ description: 腾讯云绑定的域名
+ type: string
+ qcloudPrefix:
+ description: 腾讯云路径前缀
+ type: string
+ qcloudAppId:
+ description: 腾讯云AppId
+ type: string
+ qcloudSecretId:
+ description: 腾讯云SecretId
+ type: string
+ qcloudSecretKey:
+ description: 腾讯云SecretKey
+ type: string
+ qcloudBucketName:
+ description: 腾讯云BucketName
+ type: string
+ qcloudRegion:
+ description: 腾讯云COS所属地区
+ type: string
+ FileUpload:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ url:
+ description: 文件URL地址
+ type: string
+ msg:
+ description: 失败原因
+ type: string
+
+ ScheduleJobEntity:
+ type: object
+ properties:
+ jobId:
+ description: 任务ID
+ type: integer
+ format: int64
+ beanName:
+ description: spring bean名称
+ type: string
+ methodName:
+ description: 方法名
+ type: string
+ params:
+ description: 参数
+ type: string
+ cronExpression:
+ description: cron表达式
+ type: string
+ status:
+ description: 任务状态 0:正常 1:暂停
+ type: integer
+ format: int32
+ remark:
+ description: 备注
+ type: string
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ ScheduleJobEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/ScheduleJobEntity'
+
+ ScheduleJobLogEntity:
+ type: object
+ properties:
+ logId:
+ description: 日志id
+ type: integer
+ format: int64
+ jobId:
+ description: 任务id
+ type: integer
+ format: int64
+ beanName:
+ description: spring bean名称
+ type: string
+ methodName:
+ description: 方法名
+ type: string
+ params:
+ description: 参数
+ type: string
+ status:
+ description: 任务状态 0:成功 1:失败
+ type: integer
+ format: int32
+ error:
+ description: 失败信息
+ type: string
+ times:
+ description: 耗时(单位:毫秒)
+ type: integer
+ format: int32
+ createTime:
+ description: 创建时间
+ type: string
+ format: date-time
+ ScheduleJobLogEntityList:
+ type: object
+ properties:
+ code:
+ description: 状态码 0:成功 非0:失败
+ type: integer
+ format: int32
+ page:
+ type: object
+ properties:
+ totalCount:
+ description: 总记录数
+ type: integer
+ format: int32
+ pageSize:
+ description: 每页记录数
+ type: integer
+ format: int32
+ totalPage:
+ description: 总页数
+ type: integer
+ format: int32
+ currPage:
+ description: 当前页数
+ type: integer
+ format: int32
+ list:
+ type: array
+ items:
+ $ref: '#/definitions/ScheduleJobLogEntity'
\ No newline at end of file
diff --git a/renren-fast-master/src/main/resources/static/swagger/lang/en.js b/renren-fast-master/src/main/resources/static/swagger/lang/en.js
new file mode 100644
index 0000000..9183136
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/lang/en.js
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"Warning: Deprecated",
+ "Implementation Notes":"Implementation Notes",
+ "Response Class":"Response Class",
+ "Status":"Status",
+ "Parameters":"Parameters",
+ "Parameter":"Parameter",
+ "Value":"Value",
+ "Description":"Description",
+ "Parameter Type":"Parameter Type",
+ "Data Type":"Data Type",
+ "Response Messages":"Response Messages",
+ "HTTP Status Code":"HTTP Status Code",
+ "Reason":"Reason",
+ "Response Model":"Response Model",
+ "Request URL":"Request URL",
+ "Response Body":"Response Body",
+ "Response Code":"Response Code",
+ "Response Headers":"Response Headers",
+ "Hide Response":"Hide Response",
+ "Headers":"Headers",
+ "Try it out!":"Try it out!",
+ "Show/Hide":"Show/Hide",
+ "List Operations":"List Operations",
+ "Expand Operations":"Expand Operations",
+ "Raw":"Raw",
+ "can't parse JSON. Raw result":"can't parse JSON. Raw result",
+ "Example Value":"Example Value",
+ "Model Schema":"Model Schema",
+ "Model":"Model",
+ "Click to set as parameter value":"Click to set as parameter value",
+ "apply":"apply",
+ "Username":"Username",
+ "Password":"Password",
+ "Terms of service":"Terms of service",
+ "Created by":"Created by",
+ "See more at":"See more at",
+ "Contact the developer":"Contact the developer",
+ "api version":"api version",
+ "Response Content Type":"Response Content Type",
+ "Parameter content type:":"Parameter content type:",
+ "fetching resource":"fetching resource",
+ "fetching resource list":"fetching resource list",
+ "Explore":"Explore",
+ "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.",
+ "Please specify the protocol for":"Please specify the protocol for",
+ "Can't read swagger JSON from":"Can't read swagger JSON from",
+ "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
+ "Unable to read api":"Unable to read api",
+ "from path":"from path",
+ "server returned":"server returned"
+});
diff --git a/renren-fast-master/src/main/resources/static/swagger/lang/translator.js b/renren-fast-master/src/main/resources/static/swagger/lang/translator.js
new file mode 100644
index 0000000..ffb879f
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/lang/translator.js
@@ -0,0 +1,39 @@
+'use strict';
+
+/**
+ * Translator for documentation pages.
+ *
+ * To enable translation you should include one of language-files in your index.html
+ * after .
+ * For example -
+ *
+ * If you wish to translate some new texts you should do two things:
+ * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
+ * 2. Mark that text it templates this way New Phrase or .
+ * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
+ *
+ */
+window.SwaggerTranslator = {
+
+ _words:[],
+
+ translate: function(sel) {
+ var $this = this;
+ sel = sel || '[data-sw-translate]';
+
+ $(sel).each(function() {
+ $(this).html($this._tryTranslate($(this).html()));
+
+ $(this).val($this._tryTranslate($(this).val()));
+ $(this).attr('title', $this._tryTranslate($(this).attr('title')));
+ });
+ },
+
+ _tryTranslate: function(word) {
+ return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
+ },
+
+ learn: function(wordsMap) {
+ this._words = wordsMap;
+ }
+};
diff --git a/renren-fast-master/src/main/resources/static/swagger/lang/zh-cn.js b/renren-fast-master/src/main/resources/static/swagger/lang/zh-cn.js
new file mode 100644
index 0000000..c7f55b4
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/lang/zh-cn.js
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+ "Warning: Deprecated":"警告:已过时",
+ "Implementation Notes":"接口备注",
+ "Response Class":"响应类",
+ "Status":"状态",
+ "Parameters":"参数",
+ "Parameter":"参数",
+ "Value":"值",
+ "Description":"描述",
+ "Parameter Type":"参数类型",
+ "Data Type":"数据类型",
+ "Response Messages":"响应消息",
+ "HTTP Status Code":"HTTP状态码",
+ "Reason":"原因",
+ "Response Model":"响应模型",
+ "Request URL":"请求URL",
+ "Response Body":"响应体",
+ "Response Code":"响应码",
+ "Response Headers":"响应头",
+ "Hide Response":"隐藏响应",
+ "Headers":"头",
+ "Try it out!":"试一下!",
+ "Show/Hide":"显示/隐藏",
+ "List Operations":"显示操作",
+ "Expand Operations":"展开操作",
+ "Raw":"原始",
+ "can't parse JSON. Raw result":"无法解析JSON. 原始结果",
+ "Example Value":"示例",
+ "Click to set as parameter value":"点击设置参数",
+ "Model Schema":"模型架构",
+ "Model":"模型",
+ "apply":"应用",
+ "Username":"用户名",
+ "Password":"密码",
+ "Terms of service":"服务条款",
+ "Created by":"创建者",
+ "See more at":"查看更多:",
+ "Contact the developer":"联系开发者",
+ "api version":"api版本",
+ "Response Content Type":"响应类型",
+ "Parameter content type:":"参数类型:",
+ "fetching resource":"正在获取资源",
+ "fetching resource list":"正在获取资源列表",
+ "Explore":"浏览",
+ "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
+ "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
+ "Please specify the protocol for":"请指定协议:",
+ "Can't read swagger JSON from":"无法读取swagger JSON于",
+ "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
+ "Unable to read api":"无法读取api",
+ "from path":"从路径",
+ "server returned":"服务器返回"
+});
diff --git a/renren-fast-master/src/main/resources/static/swagger/lib/backbone-min.js b/renren-fast-master/src/main/resources/static/swagger/lib/backbone-min.js
new file mode 100644
index 0000000..8eff02e
--- /dev/null
+++ b/renren-fast-master/src/main/resources/static/swagger/lib/backbone-min.js
@@ -0,0 +1 @@
+!function(t,e){if("function"==typeof define&&define.amd)define(["underscore","jquery","exports"],function(i,n,s){t.Backbone=e(t,s,i,n)});else if("undefined"!=typeof exports){var i=require("underscore");e(t,exports,i)}else t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}(this,function(t,e,i,n){var s=t.Backbone,r=[],a=(r.push,r.slice);r.splice;e.VERSION="1.1.2",e.$=n,e.noConflict=function(){return t.Backbone=s,this},e.emulateHTTP=!1,e.emulateJSON=!1;var o=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var n=this._events[t]||(this._events[t]=[]);return n.push({callback:e,context:i,ctx:i||this}),this},once:function(t,e,n){if(!c(this,"once",t,[e,n])||!e)return this;var s=this,r=i.once(function(){s.off(t,r),e.apply(this,arguments)});return r._callback=e,this.on(t,r,n)},off:function(t,e,n){var s,r,a,o,h,u,l,d;if(!this._events||!c(this,"off",t,[e,n]))return this;if(!t&&!e&&!n)return this._events=void 0,this;for(o=t?[t]:i.keys(this._events),h=0,u=o.length;h").attr(t);this.setElement(n,!1)}}}),e.sync=function(t,n,s){var r=E[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:r,dataType:"json"};if(s.url||(a.url=i.result(n,"url")||j()),null!=s.data||!n||"create"!==t&&"update"!==t&&"patch"!==t||(a.contentType="application/json",a.data=JSON.stringify(s.attrs||n.toJSON(s))),s.emulateJSON&&(a.contentType="application/x-www-form-urlencoded",a.data=a.data?{model:a.data}:{}),s.emulateHTTP&&("PUT"===r||"DELETE"===r||"PATCH"===r)){a.type="POST",s.emulateJSON&&(a.data._method=r);var o=s.beforeSend;s.beforeSend=function(t){if(t.setRequestHeader("X-HTTP-Method-Override",r),o)return o.apply(this,arguments)}}"GET"===a.type||s.emulateJSON||(a.processData=!1),"PATCH"===a.type&&x&&(a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")});var h=s.xhr=e.ajax(i.extend(a,s));return n.trigger("request",n,h,s),h};var x=!("undefined"==typeof window||!window.ActiveXObject||window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent),E={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var k=e.Router=function(t){t||(t={}),t.routes&&(this.routes=t.routes),this._bindRoutes(),this.initialize.apply(this,arguments)},T=/\((.*?)\)/g,$=/(\(\?)?:\w+/g,S=/\*\w+/g,H=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend(k.prototype,o,{initialize:function(){},route:function(t,n,s){i.isRegExp(t)||(t=this._routeToRegExp(t)),i.isFunction(n)&&(s=n,n=""),s||(s=this[n]);var r=this;return e.history.route(t,function(i){var a=r._extractParameters(t,i);r.execute(s,a),r.trigger.apply(r,["route:"+n].concat(a)),r.trigger("route",n,a),e.history.trigger("route",r,n,a)}),this},execute:function(t,e){t&&t.apply(this,e)},navigate:function(t,i){return e.history.navigate(t,i),this},_bindRoutes:function(){if(this.routes){this.routes=i.result(this,"routes");for(var t,e=i.keys(this.routes);null!=(t=e.pop());)this.route(t,this.routes[t])}},_routeToRegExp:function(t){return t=t.replace(H,"\\$&").replace(T,"(?:$1)?").replace($,function(t,e){return e?t:"([^/?]+)"}).replace(S,"([^?]*?)"),new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var n=t.exec(e).slice(1);return i.map(n,function(t,e){return e===n.length-1?t||null:t?decodeURIComponent(t):null})}});var A=e.History=function(){this.handlers=[],i.bindAll(this,"checkUrl"),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)},I=/^[#\/]|\s+$/g,N=/^\/+|\/+$/g,R=/msie [\w.]+/,O=/\/$/,P=/#.*$/;A.started=!1,i.extend(A.prototype,o,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(null==t)if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(O,"");t.indexOf(i)||(t=t.slice(i.length))}else t=this.getHash();return t.replace(I,"")},start:function(t){if(A.started)throw new Error("Backbone.history has already been started");A.started=!0,this.options=i.extend({root:"/"},this.options,t),this.root=this.options.root,this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var n=this.getFragment(),s=document.documentMode,r=R.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);if(this.root=("/"+this.root+"/").replace(N,"/"),r&&this._wantsHashChange){var a=e.$('