├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── forum.sql ├── pom.xml ├── preview ├── 1.PNG └── 2.PNG └── src └── main ├── java └── com │ └── withstars │ ├── aop │ └── LogAspect.java │ ├── controller │ ├── LoginLogController.java │ ├── MainController.java │ ├── ReplyController.java │ ├── TopicController.java │ └── UserController.java │ ├── dao │ ├── LoginLogMapper.java │ ├── ReplyMapper.java │ ├── TabMapper.java │ ├── TopicMapper.java │ └── UserMapper.java │ ├── domain │ ├── BaseDomain.java │ ├── LoginLog.java │ ├── Reply.java │ ├── Tab.java │ ├── Topic.java │ └── User.java │ ├── intercepter │ └── CORSFilter.java │ ├── service │ ├── LoginLogService.java │ ├── ReplyService.java │ ├── TabService.java │ ├── TopicService.java │ ├── UserService.java │ └── impl │ │ ├── LoginLogServiceImpl.java │ │ ├── ReplyServiceImpl.java │ │ ├── TabServiceImpl.java │ │ ├── TopicServiceImpl.java │ │ └── UserServiceImpl.java │ └── util │ ├── HexConversion.java │ └── ProduceMD5.java ├── resources ├── applicationContext.xml ├── jdbc.properties ├── log4j.properties ├── mapper │ ├── LoginLogMapper.xml │ ├── ReplyMapper.xml │ ├── TabMapper.xml │ ├── TopicMapper.xml │ └── UserMapper.xml └── mybatis-config.xml └── webapp ├── WEB-INF ├── jsp │ ├── 404.jsp │ ├── cate.jsp │ ├── detail.jsp │ ├── footer.jsp │ ├── header.jsp │ ├── new.jsp │ ├── settings.jsp │ ├── side.jsp │ ├── signin.jsp │ ├── signup.jsp │ ├── update_avatar.jsp │ └── user_info.jsp ├── main-servlet.xml └── web.xml └── static ├── css ├── bootstrap.min.css ├── front-common.css └── front-footer.css ├── img ├── avatar │ ├── 1521949392720-2.PNG │ ├── avatar-default-1.png │ ├── avatar-default-10.png │ ├── avatar-default-2.png │ ├── avatar-default-3.png │ ├── avatar-default-4.png │ ├── avatar-default-5.png │ ├── avatar-default-6.png │ ├── avatar-default-7.png │ ├── avatar-default-8.png │ └── avatar-default-9.png └── icon │ ├── heart.svg │ └── magnifying-glass.svg └── js ├── bootstrap.min.js ├── jquery-3.2.1.js └── js.cookie.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | forum.iml 4 | *.log 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2018 withstars 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Genesis- 开发者社区

2 |

基于Spring+Spring MVC+Mybatis(Maven方式构建)

3 | 4 |

5 | travis-ci 6 | license 7 |

8 | 9 |
10 | 11 | ## 说明 12 | 1. 如果使用该项目出现问题,请联系我 withstars@126.com 13 | 2. 如果该项目对您有帮助,请star鼓励我 14 | 15 | ## 如何使用 16 | ```aidl 17 | $ git clone https://github.com/withstars/Genesis 18 | 19 | $ cd Genesis 20 | 21 | $ mvn clean compile 22 | 23 | $ mvn clean package 24 | 25 | $ mvn clean install 26 | 27 | $ mvn jetty:run 28 | 29 | http://localhost:8080 30 | ``` 31 | ## LICENSE 32 | `Apache 2.0` 33 | -------------------------------------------------------------------------------- /forum.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version phpStudy 2014 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- 主机: localhost 6 | -- 生成日期: 2018 年 02 月 09 日 08:10 7 | -- 服务器版本: 5.5.53 8 | -- PHP 版本: 5.4.45 9 | 10 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8 */; 18 | 19 | -- 20 | -- 数据库: `forum` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- 表的结构 `login_log` 27 | -- 28 | 29 | CREATE TABLE IF NOT EXISTS `login_log` ( 30 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志id', 31 | `user_id` int(11) NOT NULL COMMENT '用户id', 32 | `login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '登陆时间', 33 | `ip` varchar(30) NOT NULL COMMENT '登陆IP', 34 | `device` varchar(200) DEFAULT NULL COMMENT '设备', 35 | PRIMARY KEY (`id`) 36 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=80 ; 37 | 38 | -- 39 | -- 转存表中的数据 `login_log` 40 | -- 41 | 42 | INSERT INTO `login_log` (`id`, `user_id`, `login_time`, `ip`, `device`) VALUES 43 | (1, 4, '2018-01-19 09:50:44', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 44 | (2, 4, '2018-01-19 09:51:37', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 45 | (3, 4, '2018-01-19 09:54:59', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 46 | (4, 4, '2018-01-19 10:01:51', '0:0:0:0:0:0:0:1', 'Win64'), 47 | (5, 4, '2018-01-19 10:07:26', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 48 | (6, 4, '2018-01-19 10:24:16', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 49 | (7, 4, '2018-01-19 10:32:37', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 50 | (8, 4, '2018-01-19 10:32:58', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 51 | (9, 4, '2018-01-19 12:07:36', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 52 | (10, 4, '2018-01-19 12:53:28', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 53 | (11, 4, '2018-01-20 02:49:24', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 54 | (12, 4, '2018-01-20 03:13:57', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 55 | (13, 4, '2018-01-20 03:50:44', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 56 | (14, 4, '2018-01-20 03:54:05', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 57 | (15, 4, '2018-01-20 06:00:54', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 58 | (16, 4, '2018-01-20 06:03:04', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 59 | (17, 3, '2018-01-20 06:21:55', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 60 | (18, 4, '2018-01-20 07:04:02', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 61 | (19, 3, '2018-01-20 08:09:58', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 62 | (20, 4, '2018-01-20 10:30:48', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 63 | (21, 3, '2018-01-20 11:06:34', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 64 | (22, 4, '2018-01-20 12:13:21', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 65 | (23, 4, '2018-01-20 12:16:14', '0:0:0:0:0:0:0:1', 'Win64'), 66 | (24, 4, '2018-01-21 02:07:31', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 67 | (25, 4, '2018-01-21 05:25:29', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 68 | (26, 4, '2018-01-24 02:12:07', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 69 | (27, 4, '2018-01-24 05:49:59', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 70 | (28, 4, '2018-01-24 05:56:08', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 71 | (29, 4, '2018-01-24 06:00:49', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 72 | (30, 4, '2018-01-24 06:01:06', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 73 | (31, 4, '2018-01-24 06:07:04', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 74 | (32, 4, '2018-01-24 06:45:35', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 75 | (33, 4, '2018-01-24 07:32:07', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 76 | (34, 4, '2018-01-24 07:33:58', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 77 | (35, 4, '2018-01-24 07:49:06', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 78 | (36, 4, '2018-01-24 08:51:49', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 79 | (37, 4, '2018-01-24 09:28:27', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 80 | (38, 4, '2018-01-24 09:39:12', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 81 | (39, 4, '2018-01-24 10:53:04', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 82 | (40, 4, '2018-01-24 12:33:56', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'), 83 | (41, 4, '2018-01-25 03:48:10', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 84 | (42, 4, '2018-01-25 03:56:35', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 85 | (43, 4, '2018-01-25 10:55:14', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 86 | (44, 4, '2018-01-31 11:06:35', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 87 | (45, 2, '2018-01-31 12:14:32', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 88 | (46, 2, '2018-01-31 12:16:54', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'), 89 | (47, 4, '2018-02-02 07:28:24', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 90 | (48, 1, '2018-02-02 12:21:00', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 91 | (49, 1, '2018-02-02 12:25:27', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 92 | (50, 1, '2018-02-02 13:25:08', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 93 | (51, 4, '2018-02-02 14:44:04', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 94 | (52, 4, '2018-02-02 14:45:51', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 95 | (53, 4, '2018-02-02 14:45:59', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 96 | (54, 4, '2018-02-02 14:53:12', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 97 | (55, 4, '2018-02-02 14:54:50', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 98 | (56, 4, '2018-02-02 14:55:00', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 99 | (57, 4, '2018-02-03 02:17:27', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 100 | (58, 4, '2018-02-03 04:07:16', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 101 | (59, 4, '2018-02-08 11:37:41', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 102 | (60, 4, '2018-02-08 12:17:40', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 103 | (61, 4, '2018-02-08 13:04:12', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 104 | (62, 4, '2018-02-08 13:15:00', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 105 | (63, 4, '2018-02-08 13:18:10', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 106 | (64, 4, '2018-02-08 13:18:26', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 107 | (65, 4, '2018-02-08 13:25:18', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 108 | (66, 4, '2018-02-08 13:33:42', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 109 | (67, 4, '2018-02-08 13:41:53', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 110 | (68, 4, '2018-02-08 13:43:03', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 111 | (69, 1, '2018-02-08 14:31:35', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 112 | (70, 1, '2018-02-08 15:06:40', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 113 | (71, 1, '2018-02-09 03:17:36', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 114 | (72, 1, '2018-02-09 04:21:04', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 115 | (73, 1, '2018-02-09 04:22:44', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 116 | (74, 1, '2018-02-09 04:32:29', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 117 | (75, 6, '2018-02-09 04:36:54', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 118 | (76, 6, '2018-02-09 07:25:36', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 119 | (77, 6, '2018-02-09 07:29:52', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 120 | (78, 6, '2018-02-09 07:43:54', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'), 121 | (79, 6, '2018-02-09 07:50:19', '0:0:0:0:0:0:0:1', 'WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'); 122 | 123 | -- -------------------------------------------------------- 124 | 125 | -- 126 | -- 表的结构 `reply` 127 | -- 128 | 129 | CREATE TABLE IF NOT EXISTS `reply` ( 130 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '回复id', 131 | `topic_id` int(11) NOT NULL COMMENT '主题id', 132 | `reply_user_id` int(11) NOT NULL COMMENT '用户id', 133 | `content` text CHARACTER SET utf8mb4 NOT NULL COMMENT '回复内容', 134 | `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', 135 | `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', 136 | `device` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '设备', 137 | PRIMARY KEY (`id`) 138 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=29 ; 139 | 140 | -- 141 | -- 转存表中的数据 `reply` 142 | -- 143 | 144 | INSERT INTO `reply` (`id`, `topic_id`, `reply_user_id`, `content`, `create_time`, `update_time`, `device`) VALUES 145 | (1, 2, 2, '测试评论1', '2018-01-19 13:13:59', '2018-02-09 07:51:48', NULL), 146 | (2, 2, 2, '测试留言2', '2018-01-19 13:38:10', '2018-01-18 17:07:07', NULL), 147 | (3, 2, 1, '测试评论1366576', '2018-01-19 13:39:16', '2018-02-09 07:52:06', NULL), 148 | (4, 4, 4, '测试评论1287', '2018-01-20 03:54:11', '2018-02-09 07:53:31', NULL), 149 | (5, 4, 4, '测试评论7689', '2018-01-20 03:54:17', '2018-02-09 07:52:15', NULL), 150 | (6, 2, 4, '测试评论64567575', '2018-01-20 03:54:34', '2018-02-09 07:52:23', NULL), 151 | (7, 1, 4, '测试评论7654323', '2018-01-20 06:03:18', '2018-02-09 07:52:32', NULL), 152 | (8, 3, 3, '测试评论8655', '2018-01-20 07:03:14', '2018-02-09 07:53:23', NULL), 153 | (9, 5, 3, '测试评论2465', '2018-01-20 08:10:37', '2018-02-09 07:52:41', NULL), 154 | (10, 7, 4, 'version ( HTTP/1.1 or HTTP/2 ) \r\n不错!', '2018-01-20 12:14:15', '2018-01-20 12:14:15', NULL), 155 | (11, 7, 4, '测试评论787', '2018-01-20 12:14:21', '2018-02-09 07:52:52', NULL), 156 | (12, 7, 4, '要是 server 也是一行 cli 代码就好了', '2018-01-20 12:14:30', '2018-01-20 12:14:30', NULL), 157 | (13, 8, 4, '这不是队列么……', '2018-01-21 05:27:22', '2018-01-21 05:27:22', NULL), 158 | (14, 8, 4, '活太轻,放队列里去感觉没那么大必要 :-)', '2018-01-21 05:27:32', '2018-01-21 05:27:32', NULL), 159 | (15, 8, 4, '测试评论4324', '2018-01-24 06:01:52', '2018-02-09 07:54:15', NULL), 160 | (16, 9, 4, '测试评论6578', '2018-01-24 11:06:52', '2018-02-09 07:53:04', NULL), 161 | (17, 11, 2, '测试评论5466', '2018-01-31 12:21:27', '2018-02-09 07:54:42', NULL), 162 | (18, 11, 2, 'http://mvnrepository.com/', '2018-01-31 12:23:44', '2018-01-31 12:23:44', NULL), 163 | (19, 7, 4, '测试评论1230', '2018-02-08 13:18:57', '2018-02-09 07:53:13', NULL), 164 | (20, 7, 4, '测试评论3453', '2018-02-08 13:19:03', '2018-02-09 07:54:09', NULL), 165 | (21, 7, 4, '测试评论6475', '2018-02-08 13:19:07', '2018-02-09 07:54:03', NULL), 166 | (22, 1, 4, '测试评论54436', '2018-02-08 13:41:58', '2018-02-09 07:53:56', NULL), 167 | (23, 9, 4, '测试评论5524', '2018-02-08 13:43:09', '2018-02-09 07:53:49', NULL), 168 | (24, 9, 4, '测试评论6754', '2018-02-08 13:43:40', '2018-02-09 07:53:43', NULL), 169 | (25, 11, 1, '测试评论1214', '2018-02-08 14:31:48', '2018-02-09 07:53:38', NULL), 170 | (26, 12, 1, '测试评论65465', '2018-02-09 03:18:08', '2018-02-09 07:54:30', NULL), 171 | (27, 12, 6, '测试评论4364', '2018-02-09 04:38:03', '2018-02-09 07:54:24', NULL), 172 | (28, 12, 6, '嗯嗯', '2018-02-09 07:46:39', '2018-02-09 07:46:39', NULL); 173 | 174 | -- -------------------------------------------------------- 175 | 176 | -- 177 | -- 表的结构 `tab` 178 | -- 179 | 180 | CREATE TABLE IF NOT EXISTS `tab` ( 181 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '板块id', 182 | `tab_name` varchar(50) NOT NULL COMMENT '板块名', 183 | `tab_name_en` varchar(20) NOT NULL, 184 | PRIMARY KEY (`id`) 185 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=6 ; 186 | 187 | -- 188 | -- 转存表中的数据 `tab` 189 | -- 190 | 191 | INSERT INTO `tab` (`id`, `tab_name`, `tab_name_en`) VALUES 192 | (1, '技术', 'tech'), 193 | (2, '好玩', 'play'), 194 | (3, '创意', 'creative'), 195 | (4, '工作', 'jobs'), 196 | (5, '交易', 'deals'); 197 | 198 | -- -------------------------------------------------------- 199 | 200 | -- 201 | -- 表的结构 `topic` 202 | -- 203 | 204 | CREATE TABLE IF NOT EXISTS `topic` ( 205 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '帖子ID', 206 | `user_id` int(11) NOT NULL COMMENT '发帖人id', 207 | `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', 208 | `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', 209 | `title` varchar(200) NOT NULL COMMENT '标题', 210 | `content` text NOT NULL COMMENT '内容', 211 | `click` int(11) NOT NULL DEFAULT '0' COMMENT '点击量', 212 | `tab_id` tinyint(4) NOT NULL COMMENT '发布板块', 213 | PRIMARY KEY (`id`) 214 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=13 ; 215 | 216 | -- 217 | -- 转存表中的数据 `topic` 218 | -- 219 | 220 | INSERT INTO `topic` (`id`, `user_id`, `create_time`, `update_time`, `title`, `content`, `click`, `tab_id`) VALUES 221 | (1, 2, '2018-01-20 12:02:13', '2018-02-09 05:21:37', '是否有利用云计算进行异地组网的解决方案?', '现有一中大型企业,下属子公司需接入母公司内网。\r\n目前使用华为 AR1220-S 组网,使用 l2tp 搭建 vpn。使用路由器到路由器的解决方案,现已超过 10 家子公司,使用路由器通过 l2tp 接入母公司内网系统。\r\n随着公司业务增长,今年预计需增加 30 个点接入母公司网络。(未来可能需增加超过 200 个点,且分布全国各地)\r\n\r\n1.请问 AR1220-S 能否胜任,是否需要更换 AR2220-S 或 AR3220-S。\r\n2.子公司使用什么设备能较稳定连接母公司通过华为搭建的 l2tp 的 vpn。(目前使用过极路由和普联,普联表现较为稳定。因大规模部署需要,请问 TL-ER7520g 能否稳定胜任。 目前 tp 最贵的企业路由器,官网上看的。)\r\n3.大规模异地租网是否有更优方案,如利用云中转等,请各位大神们指点,谢谢。', 139, 1), 222 | (2, 3, '2018-01-20 11:55:19', '2018-02-09 07:50:38', '你心目中理想的新闻推荐系统是什么样子?', '实时?\r\n根据兴趣推荐?\r\n关注的频道优先推荐?\r\n根据天气、位置等客观参数推荐\r\n有收藏功能,能自动根据收藏发现兴趣,从而更好地推荐\r\n让更多的人变成内容的创作者而不是单单的阅读者?', 40, 1), 223 | (3, 2, '2018-01-20 11:52:38', '2018-02-08 13:47:28', ' 关于“直播答题发钱”辅助工具搜索推荐算法的讨论', '最近直播火热,网上也看到很多通过“抓图 - 文字识别 - 百度搜题推荐”的程序介绍,自己也整理了一份 \r\n###########举例###################### \r\n问题:9.中国历史上,在位时间最长的皇帝是? \r\n备选答案: [''康熙'', ''乾隆'', ''刘彻''] \r\n\r\nAnswer: [''刘彻(9.091%)'', ''康熙(63.636%)'', ''乾隆(27.273%)''] \r\n####################################### \r\n想问问大家,对搜索答案这块的算法,怎么设计,有什么高见? \r\n\r\n先抛砖引玉,目前想到的算法: \r\n1. 通过百度网页,请求问题,以答案选项作为关键字,数数判断(主流) \r\n2. 对答案采用“中文分词”,针对答案可能是 xxx-yyy-zzz 无法全字匹配的情况 \r\n3. 对问题进行“中文分词“,逆向搜索,针对 “下面那些不是美国的品牌”这类问题 \r\n\r\n对于 1 已经实现,之前也有人发过存在“不”的情况处理;目前想通过 jieba 实现 2 和 3,但是总感觉这块的思考不是“很专业”,请大家吐槽', 23, 1), 224 | (4, 2, '2018-01-20 12:06:24', '2018-02-08 13:24:29', '企业级应用开发真的需要 Vue, React 这种东西吗?', '本人一直从事后端开发,自带一点前端技能(会用 jquery,extjs 组件)。这两年各种前端框架火爆,让我在完成老板任务时有点迷失。感觉不用 MVVM 这些框架,依然能很快的实现各种业务,而且交接工作也比较简单。\r\n用这些框架要增加学习成本,同行(都是后端自带一点前端技能那种)维护成本。但最终交互给客户的界面,依然是增删改查这些功能以及后台业务表逻辑的串接。而 UI 体验很大程度上又取决于交互视觉设计,而非前端框架。\r\n所以我的问题是:企业级应用开发真的需要 Vue, React 这种东西吗?\r\n各互联网大厂又有多少 to C 页面是基于他们实现,并且提升了交付给客户的价值?\r\n为什么精通 Vue React 的前端,在感觉上比框架本身的发明者还亢奋?', 24, 1), 225 | (5, 3, '2018-01-20 11:55:17', '2018-02-08 15:00:42', '使用 Nginx 自建 CDN,关于回源问题。', '假如 3 台服务器,一台源站,2 个自建 CDN,在 Nginx 配置的时候回源方案目前想到 2 个,但不是很好,请问是否有更好的方案。\r\n\r\nA:源站\r\nB:CDN1\r\nC:CDN2\r\n方案一\r\nCDN 上进行 hosts 回源,但是自建 CDN 一多,这样很麻烦。\r\n\r\n方案二\r\n使用 DNSmasq 自建一个 DNS,然后在 nginx 设置 DNS 来指定回源。\r\n\r\n请问有更好的办法来实现回源吗?尤其是自建 CDN 节点较多的情况下。', 37, 1), 226 | (6, 3, '2018-01-20 08:11:32', '2018-02-09 07:14:58', '请问各位喜欢用 JOOQ Hibernate Mybatis 其中哪个框架', '能说一下喜欢的原因是最好的..', 3, 1), 227 | (7, 4, '2018-01-20 12:13:57', '2018-02-09 07:58:52', 'JDK 9 里的 JDK HTTP Client 的写法', 'HttpClient client = HttpClient.newHttpClient();\r\nHttpRequest request = HttpRequest.newBuilder()\r\n .uri(URI.create("http://openjdk.java.net/"))\r\n .build();\r\nclient.sendAsync(request, asString())\r\n .thenApply(HttpResponse::body)\r\n .thenAccept(System.out::println)\r\n .join();\r\n还可以指定使用 HTTP/2:\r\n\r\nHttpClient client = HttpClient.newBuilder()\r\n .version(Version.HTTP_2)\r\n .followRedirects(Redirect.SAME_PROTOCOL)\r\n .proxy(ProxySelector.of(new InetSocketAddress("www-proxy.com", 8080)))\r\n .authenticator(Authenticator.getDefault())\r\n .build();', 45, 1), 228 | (8, 4, '2018-01-21 05:26:57', '2018-02-09 07:25:23', '数据库怎么最简单实现 “栈” 结构存储?', '', 46, 1), 229 | (9, 4, '2018-01-24 08:57:44', '2018-02-09 07:14:55', '腾讯云能不能别给我发优惠券短信了', '我对你的优惠券不感兴趣啊,能不能不要发了,每天都发,有时一天还要发好几次', 63, 2), 230 | (10, 4, '2018-01-25 03:52:12', '2018-02-09 07:50:22', '应用程序在服务器上创建文件目录权限 0777,会有风险吗?', '应用程序 App (是 root )在服务器上创建了一个文件目录,权限设 0777, 会有风险吗? \r\n(当然,前提是服务器一般不会配除 root 外的其他账户,也不会把这个文件目录直接开给 web server 的公开路径)', 12, 1), 231 | (11, 4, '2018-01-25 04:04:44', '2018-02-09 07:58:45', 'P2P 直播测试,这个数据如何?', '', 114, 1), 232 | (12, 4, '2018-02-08 14:17:16', '2018-02-09 07:58:33', 'Genesis祝各位会员新年好', 'Genesis祝各位会员新年好Genesis祝各位会员新年好', 68, 1); 233 | 234 | -- -------------------------------------------------------- 235 | 236 | -- 237 | -- 表的结构 `user` 238 | -- 239 | 240 | CREATE TABLE IF NOT EXISTS `user` ( 241 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户唯一ID', 242 | `username` varchar(30) NOT NULL COMMENT '用户名', 243 | `password` varchar(50) NOT NULL COMMENT '密码', 244 | `email` varchar(50) DEFAULT NULL COMMENT '邮箱', 245 | `phone_num` varchar(15) DEFAULT NULL COMMENT '手机号', 246 | `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', 247 | `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 248 | `credit` int(11) NOT NULL COMMENT '积分', 249 | `avatar` varchar(100) DEFAULT NULL COMMENT '头像url', 250 | `type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '用户类型,0为普通用户,1为管理员', 251 | PRIMARY KEY (`id`) 252 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=7 ; 253 | 254 | -- 255 | -- 转存表中的数据 `user` 256 | -- 257 | 258 | INSERT INTO `user` (`id`, `username`, `password`, `email`, `phone_num`, `create_time`, `update_time`, `credit`, `avatar`, `type`) VALUES 259 | (1, 'likky', 'E10ADC3949BA59ABBE56E057F20F883E', '123456789@126.com', '8615712345678', '2018-02-08 15:06:40', '2018-02-09 07:57:05', 23, '/img/avatar/avatar-default-1.png', 0), 260 | (2, 'withstars', 'E10ADC3949BA59ABBE56E057F20F883E', '987654321@qq.com', '8616978945612', '2018-01-31 12:16:54', '2018-02-09 07:57:21', 10, '/img/avatar/avatar-default-2.png', 0), 261 | (3, 'yilia', 'E10ADC3949BA59ABBE56E057F20F883E', '147258369@qq.com', '8615963248962', '2018-01-20 06:18:58', '2018-02-09 07:56:29', 0, '/img/avatar/avatar-default-3.png', 0), 262 | (4, 'sassy', 'E10ADC3949BA59ABBE56E057F20F883E', '159357846@qq.com', '8612543434343', '2018-02-08 14:17:16', '2018-02-09 07:56:39', 156, '/img/avatar/avatar-default-4.png', 0), 263 | (6, 'objectc', 'A45958517604F5CD90D6EE51AD9CFDB6', '963852741@qq.com', '8619345321598', '2018-02-09 04:36:39', '2018-02-09 07:56:46', 7, '/img/avatar/avatar-default-5.png', 0); 264 | 265 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 266 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 267 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 268 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.withstars 8 | genesis 9 | 1.1 10 | war 11 | 12 | 13 | UTF-8 14 | UTF-8 15 | 4.2.2.RELEASE 16 | 5.1.29 17 | 3.0-alpha-1 18 | 1.8.1 19 | 1.9 20 | 1.4 21 | 5.0.2.Final 22 | 8.1.8.v20121106 23 | 1.7.5 24 | 6.8.7 25 | 26 | 27 | 28 | org.springframework 29 | spring-beans 30 | ${spring.version} 31 | 32 | 33 | org.springframework 34 | spring-context 35 | ${spring.version} 36 | 37 | 38 | org.springframework 39 | spring-context-support 40 | ${spring.version} 41 | 42 | 43 | org.springframework 44 | spring-jdbc 45 | ${spring.version} 46 | 47 | 48 | org.springframework 49 | spring-webmvc 50 | ${spring.version} 51 | 52 | 53 | 54 | commons-dbcp 55 | commons-dbcp 56 | ${commons-dbcp.version} 57 | 58 | 59 | mysql 60 | mysql-connector-java 61 | ${mysql.version} 62 | 63 | 64 | javax.servlet 65 | servlet-api 66 | ${servlet.version} 67 | provided 68 | 69 | 70 | org.aspectj 71 | aspectjweaver 72 | ${aspectj.version} 73 | 74 | 75 | 76 | cglib 77 | cglib 78 | 2.2.2 79 | 80 | 81 | 82 | 83 | org.testng 84 | testng 85 | ${testng.version} 86 | test 87 | 88 | 89 | org.springframework 90 | spring-test 91 | ${spring.version} 92 | test 93 | 94 | 95 | 96 | javax.servlet 97 | jstl 98 | 1.2 99 | 100 | 101 | org.mybatis 102 | mybatis 103 | 3.4.4 104 | 105 | 106 | org.mybatis 107 | mybatis-spring 108 | 1.3.0 109 | 110 | 111 | 112 | commons-codec 113 | commons-codec 114 | 1.10 115 | 116 | 117 | 118 | 119 | com.alibaba 120 | druid 121 | 1.0.29 122 | 123 | 124 | 125 | com.fasterxml.jackson.core 126 | jackson-core 127 | 2.8.8 128 | 129 | 130 | com.fasterxml.jackson.core 131 | jackson-annotations 132 | 2.8.8 133 | 134 | 135 | com.fasterxml.jackson.core 136 | jackson-databind 137 | 2.8.8 138 | 139 | 140 | 141 | ch.qos.logback 142 | logback-classic 143 | 1.1.1 144 | 145 | 146 | 147 | 148 | com.github.pagehelper 149 | pagehelper 150 | 5.1.2 151 | 152 | 153 | 154 | 155 | redis.clients 156 | jedis 157 | 2.9.0 158 | 159 | 160 | org.springframework.data 161 | spring-data-redis 162 | 2.0.0.RELEASE 163 | 164 | 165 | 166 | log4j 167 | log4j 168 | 1.2.17 169 | 170 | 171 | 172 | commons-fileupload 173 | commons-fileupload 174 | 1.3.1 175 | 176 | 177 | commons-io 178 | commons-io 179 | 2.6 180 | 181 | 182 | 183 | 184 | org.apache.shiro 185 | shiro-core 186 | 1.4.0 187 | 188 | 189 | 190 | 191 | junit 192 | junit 193 | 4.12 194 | test 195 | 196 | 197 | 198 | 199 | commons-lang 200 | commons-lang 201 | 2.6 202 | 203 | 204 | eu.bitwalker 205 | UserAgentUtils 206 | 1.20 207 | 208 | 209 | 210 | 211 | 212 | Genesis 213 | 214 | 215 | 216 | org.mortbay.jetty 217 | maven-jetty-plugin 218 | 6.1.25 219 | 220 | 221 | 222 | 8080 223 | 60000 224 | 225 | 226 | / 227 | 0 228 | 229 | 230 | 231 | 232 | org.apache.maven.plugins 233 | maven-surefire-plugin 234 | 2.19.1 235 | 236 | methods 237 | 10 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | -------------------------------------------------------------------------------- /preview/1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/preview/1.PNG -------------------------------------------------------------------------------- /preview/2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/preview/2.PNG -------------------------------------------------------------------------------- /src/main/java/com/withstars/aop/LogAspect.java: -------------------------------------------------------------------------------- 1 | package com.withstars.aop; 2 | 3 | import org.apache.commons.logging.Log; 4 | import org.apache.commons.logging.LogFactory; 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Before; 8 | import org.aspectj.lang.annotation.Pointcut; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * Description: 14 | * User: withstars 15 | * Date: 2018-02-22 16 | * Time: 20:41 17 | * Mail: withstars@126.com 18 | */ 19 | @Component 20 | @Aspect 21 | public class LogAspect { 22 | private final Log log = LogFactory.getLog(getClass()); 23 | 24 | @Before("execution(* com.withstars.controller.UserController.signin(..))") 25 | public void loginLogAspect(JoinPoint joinPoint){ 26 | String methodName=joinPoint.getSignature().toShortString(); 27 | String args=joinPoint.getArgs().toString(); 28 | log.info("---Before method "+methodName+" invoke, param:" +args+"---"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/controller/LoginLogController.java: -------------------------------------------------------------------------------- 1 | package com.withstars.controller; 2 | 3 | import com.withstars.service.impl.LoginLogServiceImpl; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Controller; 6 | 7 | /** 8 | * 登录日志控制类 9 | */ 10 | @Controller 11 | public class LoginLogController { 12 | 13 | @Autowired 14 | public LoginLogServiceImpl loginLogService; 15 | 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/controller/MainController.java: -------------------------------------------------------------------------------- 1 | package com.withstars.controller; 2 | 3 | import com.withstars.domain.Tab; 4 | import com.withstars.service.impl.ReplyServiceImpl; 5 | import com.withstars.service.impl.TabServiceImpl; 6 | import com.withstars.service.impl.TopicServiceImpl; 7 | import com.withstars.service.impl.UserServiceImpl; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import javax.jws.WebParam; 14 | import java.util.List; 15 | 16 | /** 17 | * 主控制类 18 | */ 19 | @Controller 20 | public class MainController { 21 | 22 | @Autowired 23 | public TopicServiceImpl topicService; 24 | @Autowired 25 | public ReplyServiceImpl replyService; 26 | @Autowired 27 | public UserServiceImpl userService; 28 | @Autowired 29 | public TabServiceImpl tabService; 30 | 31 | /** 32 | * 进入登录页面. 33 | */ 34 | @RequestMapping(value = {"/signin"}) 35 | public ModelAndView signin(){ 36 | ModelAndView signinPage=new ModelAndView("signin"); 37 | 38 | //获取统计信息 39 | int topicsNum=topicService.getTopicsNum(); 40 | int usersNum=userService.getUserCount(); 41 | 42 | signinPage.addObject("topicsNum",topicsNum); 43 | signinPage.addObject("usersNum",usersNum); 44 | return signinPage; 45 | } 46 | 47 | /** 48 | * 进入注册页面. 49 | */ 50 | @RequestMapping("/signup") 51 | public ModelAndView signup(){ 52 | ModelAndView signupPage=new ModelAndView("signup"); 53 | 54 | //获取统计信息 55 | int topicsNum=topicService.getTopicsNum(); 56 | int usersNum=userService.getUserCount(); 57 | 58 | signupPage.addObject("topicsNum",topicsNum); 59 | signupPage.addObject("usersNum",usersNum); 60 | return signupPage; 61 | } 62 | 63 | /** 64 | * 进入新建主题页面 65 | */ 66 | @RequestMapping(value = {"/new"}) 67 | public ModelAndView newTopic(){ 68 | ModelAndView newTopicPage=new ModelAndView("new"); 69 | List tabs=tabService.getAllTabs(); 70 | 71 | //获取统计信息 72 | int topicsNum=topicService.getTopicsNum(); 73 | int usersNum=userService.getUserCount(); 74 | 75 | newTopicPage.addObject("tabs",tabs); 76 | newTopicPage.addObject("topicsNum",topicsNum); 77 | newTopicPage.addObject("usersNum",usersNum); 78 | return newTopicPage; 79 | } 80 | 81 | /** 82 | * 配置404页面 83 | */ 84 | @RequestMapping("*") 85 | public String notFind(){ 86 | return "404"; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/controller/ReplyController.java: -------------------------------------------------------------------------------- 1 | package com.withstars.controller; 2 | 3 | import com.withstars.domain.Reply; 4 | import com.withstars.service.impl.ReplyServiceImpl; 5 | import com.withstars.service.impl.UserServiceImpl; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.servlet.ModelAndView; 11 | import org.springframework.web.servlet.mvc.support.RedirectAttributes; 12 | 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpSession; 15 | import java.util.Date; 16 | 17 | /** 18 | * 回复相关控制类 19 | */ 20 | @Controller 21 | public class ReplyController { 22 | 23 | @Autowired 24 | public ReplyServiceImpl replyService; 25 | @Autowired 26 | public UserServiceImpl userService; 27 | 28 | /** 29 | * 添加评论 30 | */ 31 | @RequestMapping(value = "/reply/add",method = RequestMethod.POST) 32 | public ModelAndView addReply(HttpServletRequest request, HttpSession session){ 33 | //处理参数 34 | Integer topicId=Integer.parseInt(request.getParameter("topicId")); 35 | Integer replyUserId=Integer.parseInt(request.getParameter("replyUserId")); 36 | String content=request.getParameter("content"); 37 | //创建reply 38 | Reply reply=new Reply(); 39 | reply.setTopicId(topicId); 40 | reply.setReplyUserId(replyUserId); 41 | reply.setContent(content); 42 | reply.setCreateTime(new Date()); 43 | reply.setUpdateTime(new Date()); 44 | //执行添加 45 | boolean ifSucc=replyService.addReply(reply); 46 | //添加积分 47 | boolean ifSuccAddCredit=userService.addCredit(1,replyUserId); 48 | 49 | //新建视图 50 | ModelAndView view=new ModelAndView("redirect:/t/"+topicId); 51 | return view; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/controller/TopicController.java: -------------------------------------------------------------------------------- 1 | package com.withstars.controller; 2 | 3 | import com.withstars.domain.Reply; 4 | import com.withstars.domain.Tab; 5 | import com.withstars.domain.Topic; 6 | import com.withstars.domain.User; 7 | import com.withstars.service.impl.ReplyServiceImpl; 8 | import com.withstars.service.impl.TabServiceImpl; 9 | import com.withstars.service.impl.TopicServiceImpl; 10 | import com.withstars.service.impl.UserServiceImpl; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | import org.springframework.web.servlet.ModelAndView; 17 | import org.springframework.web.servlet.mvc.support.RedirectAttributes; 18 | 19 | import javax.servlet.http.HttpServletRequest; 20 | import javax.servlet.http.HttpSession; 21 | import java.util.Date; 22 | import java.util.List; 23 | 24 | 25 | import org.apache.commons.logging.Log; 26 | import org.apache.commons.logging.LogFactory; 27 | 28 | /** 29 | * 主题相关控制类 30 | */ 31 | @Controller 32 | public class TopicController { 33 | 34 | @Autowired 35 | public TopicServiceImpl topicService; 36 | @Autowired 37 | public ReplyServiceImpl replyService; 38 | @Autowired 39 | public UserServiceImpl userService; 40 | @Autowired 41 | public TabServiceImpl tabService; 42 | 43 | //log4j对象 44 | private final Log log = LogFactory.getLog(getClass()); 45 | 46 | /** 47 | * 渲染首页 48 | * @param session 49 | * @return 50 | */ 51 | @RequestMapping("/") 52 | public ModelAndView toMain(HttpSession session){ 53 | ModelAndView indexPage=new ModelAndView("cate"); 54 | //全部主题 55 | List topics=topicService.listTopicsAndUsers(); 56 | 57 | //获取统计信息 58 | int topicsNum=topicService.getTopicsNum(); 59 | int usersNum=userService.getUserCount(); 60 | //获取用户信息 61 | Integer uid=(Integer) session.getAttribute("userId"); 62 | User user=userService.getUserById(uid); 63 | //最热主题 64 | List hotestTopics=topicService.listMostCommentsTopics(); 65 | 66 | indexPage.addObject("topics",topics); 67 | indexPage.addObject("hotestTopics",hotestTopics); 68 | indexPage.addObject("topicsNum",topicsNum); 69 | indexPage.addObject("usersNum",usersNum); 70 | indexPage.addObject("user",user); 71 | return indexPage; 72 | } 73 | 74 | /** 75 | * 渲染主题详细页面 76 | * @param id 77 | * @param session 78 | * @return 79 | */ 80 | @RequestMapping("/t/{id}") 81 | public ModelAndView toTopic(@PathVariable("id")Integer id,HttpSession session){ 82 | //点击量加一 83 | boolean ifSucc=topicService.clickAddOne(id); 84 | //获取主题信息 85 | Topic topic=topicService.selectById(id); 86 | //获取主题全部评论 87 | List replies=replyService.getRepliesOfTopic(id); 88 | //获取评论数 89 | int repliesNum=replyService.repliesNum(id); 90 | //获取统计信息 91 | int topicsNum=topicService.getTopicsNum(); 92 | int usersNum=userService.getUserCount(); 93 | //获取用户信息 94 | Integer uid=(Integer) session.getAttribute("userId"); 95 | User user=userService.getUserById(uid); 96 | //最热主题 97 | List hotestTopics=topicService.listMostCommentsTopics(); 98 | 99 | //渲染视图 100 | ModelAndView topicPage=new ModelAndView("detail"); 101 | topicPage.addObject("topic",topic); 102 | topicPage.addObject("replies",replies); 103 | topicPage.addObject("repliesNum",repliesNum); 104 | topicPage.addObject("topicsNum",topicsNum); 105 | topicPage.addObject("usersNum",usersNum); 106 | topicPage.addObject("user",user); 107 | topicPage.addObject("hotestTopics",hotestTopics); 108 | return topicPage; 109 | } 110 | 111 | /** 112 | * 渲染指定板块页面 113 | */ 114 | @RequestMapping("/tab/{tabNameEn}") 115 | public ModelAndView toTabPage(@PathVariable("tabNameEn")String tabNameEn,HttpSession session){ 116 | Tab tab=tabService.getByTabNameEn(tabNameEn); 117 | Integer tabId=tab.getId(); 118 | 119 | ModelAndView indexPage=new ModelAndView("cate"); 120 | //全部主题 121 | List topics=topicService.listTopicsAndUsersOfTab(tabId); 122 | 123 | //获取统计信息 124 | int topicsNum=topicService.getTopicsNum(); 125 | int usersNum=userService.getUserCount(); 126 | 127 | //获取用户信息 128 | Integer uid=(Integer) session.getAttribute("userId"); 129 | User user=userService.getUserById(uid); 130 | //最热主题 131 | List hotestTopics=topicService.listMostCommentsTopics(); 132 | 133 | indexPage.addObject("topics",topics); 134 | indexPage.addObject("topicsNum",topicsNum); 135 | indexPage.addObject("usersNum",usersNum); 136 | indexPage.addObject("tab",tab); 137 | indexPage.addObject("user",user); 138 | indexPage.addObject("hotestTopics",hotestTopics); 139 | return indexPage; 140 | } 141 | 142 | /** 143 | * 发表主题 144 | * @param request 145 | * @param session 146 | * @return 147 | */ 148 | @RequestMapping(value = "/topic/add", method = RequestMethod.POST) 149 | public ModelAndView addTopic(HttpServletRequest request,HttpSession session){ 150 | ModelAndView indexPage; 151 | //未登陆 152 | if(session.getAttribute("userId")==null){ 153 | indexPage=new ModelAndView("redirect:/signin"); 154 | return indexPage; 155 | } 156 | //处理参数 157 | Integer userId=(Integer) session.getAttribute("userId"); 158 | String title=request.getParameter("title"); 159 | String content=request.getParameter("content"); 160 | Byte tabId=Byte.parseByte(request.getParameter("tab")); 161 | //新建Topic 162 | Topic topic=new Topic(); 163 | topic.setUserId(userId); 164 | topic.setTitle(title); 165 | topic.setContent(content); 166 | topic.setTabId(tabId); 167 | topic.setCreateTime(new Date()); 168 | topic.setUpdateTime(new Date()); 169 | //添加topic 170 | boolean ifSucc=topicService.addTopic(topic); 171 | boolean ifSuccAddCredit=userService.addCredit(1,userId); 172 | if (ifSucc){ 173 | if (log.isInfoEnabled()){ 174 | log.info("添加主题成功!"); 175 | } 176 | } 177 | indexPage=new ModelAndView("redirect:/"); 178 | 179 | return indexPage; 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.withstars.controller; 2 | 3 | import com.withstars.domain.LoginLog; 4 | import com.withstars.domain.Topic; 5 | import com.withstars.domain.User; 6 | import com.withstars.service.impl.LoginLogServiceImpl; 7 | import com.withstars.service.impl.TopicServiceImpl; 8 | import com.withstars.service.impl.UserServiceImpl; 9 | import com.withstars.util.ProduceMD5; 10 | import eu.bitwalker.useragentutils.UserAgent; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.bind.annotation.*; 14 | import org.springframework.web.multipart.MultipartFile; 15 | import org.springframework.web.servlet.ModelAndView; 16 | 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpSession; 19 | import java.io.File; 20 | import java.util.*; 21 | 22 | /** 23 | * 用户相关控制类 24 | */ 25 | @Controller 26 | public class UserController { 27 | 28 | @Autowired 29 | public UserServiceImpl userService; 30 | 31 | @Autowired 32 | public LoginLogServiceImpl loginLogService; 33 | 34 | @Autowired 35 | public TopicServiceImpl topicService; 36 | 37 | 38 | /** 39 | * 用户注册 40 | */ 41 | @RequestMapping("/user/add/do") 42 | public String addUser(HttpServletRequest request){ 43 | //新建User对象 44 | User user=new User(); 45 | //处理手机号 46 | String phoneNum=request.getParameter("tel"); 47 | String areaCode=request.getParameter("areaCode"); 48 | String phone=areaCode+phoneNum; 49 | //用户类型 50 | Byte type=new Byte("0"); 51 | //密码加密处理 52 | String password= ProduceMD5.getMD5(request.getParameter("password")); 53 | //生成随机数,用于生成头像URL 54 | Random rand=new Random(); 55 | int randomNum=rand.nextInt(10)+1; 56 | String avatarUrl="/img/avatar/avatar-default-"+randomNum+".png"; 57 | //初始化User对象 58 | user.setUsername(request.getParameter("username")); 59 | user.setPassword(password); 60 | user.setEmail(request.getParameter("email")); 61 | user.setPhoneNum(phone); 62 | user.setCreateTime(new Date()); 63 | user.setUpdateTime(new Date()); 64 | user.setCredit(0); 65 | user.setType(type); 66 | user.setAvatar(avatarUrl); 67 | 68 | boolean ifSucc=userService.addUser(user); 69 | System.out.print(ifSucc); 70 | return "redirect:/"; 71 | } 72 | 73 | /** 74 | * 用户登陆 75 | * @param request 76 | * @param session 77 | * @return 0:用户名不存在 1:密码错误 2:登录成功 78 | */ 79 | 80 | @RequestMapping("/api/loginCheck") 81 | @ResponseBody 82 | public Object signin(HttpServletRequest request,HttpSession session){ 83 | //处理参数 84 | String password=ProduceMD5.getMD5(request.getParameter("password")); 85 | String username=request.getParameter("username"); 86 | //验证用户名密码 87 | int loginVerify=userService.login(username,password); 88 | 89 | HashMap res = new HashMap(); 90 | 91 | //登录成功 92 | if(loginVerify == 2){ 93 | User user =userService.getUserByUsername(username); 94 | Integer userId=user.getId(); 95 | //添加积分 96 | boolean ifSuccAddCredit=userService.addCredit(1,userId); 97 | //用户信息写入session 98 | session.setAttribute("userId",userId); 99 | session.setAttribute("username",username); 100 | //获取登录信息 101 | String ip=getRemortIP(request); 102 | UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); 103 | //获取用户的浏览器名 104 | String userbrowser = userAgent.getBrowser().toString(); 105 | //写入登录日志 106 | LoginLog log=new LoginLog(); 107 | log.setDevice(userbrowser); 108 | log.setIp(ip); 109 | log.setUserId(userId); 110 | log.setLoginTime(new Date()); 111 | boolean ifSuccAddLog=loginLogService.addLog(log); 112 | 113 | res.put("stateCode", "2"); 114 | } 115 | //密码错误 116 | else if (loginVerify == 1){ 117 | res.put("stateCode", "1"); 118 | } 119 | //用户名不存在 120 | else { 121 | res.put("stateCode", "0"); 122 | } 123 | return res; 124 | } 125 | 126 | /** 127 | * 用户登出 128 | */ 129 | @RequestMapping("/signout") 130 | public String signout(HttpSession session){ 131 | session.removeAttribute("userId"); 132 | session.removeAttribute("username"); 133 | return "redirect:/"; 134 | } 135 | 136 | /** 137 | * 获取客户端IP 138 | */ 139 | public String getRemortIP(HttpServletRequest request) { 140 | if (request.getHeader("x-forwarded-for") == null) { 141 | return request.getRemoteAddr(); 142 | } 143 | return request.getHeader("x-forwarded-for"); 144 | } 145 | 146 | /** 147 | * 用户个人主页 148 | */ 149 | @RequestMapping("/member/{username}") 150 | public ModelAndView personalCenter(@PathVariable("username")String username,HttpSession session){ 151 | boolean ifExistUser=userService.existUsername(username); 152 | //获取统计信息 153 | int topicsNum=topicService.getTopicsNum(); 154 | int usersNum=userService.getUserCount(); 155 | 156 | //获取用户信息 157 | Integer uid=(Integer) session.getAttribute("userId"); 158 | User user=userService.getUserById(uid); 159 | //最热主题 160 | List hotestTopics=topicService.listMostCommentsTopics(); 161 | 162 | ModelAndView mv=new ModelAndView("user_info"); 163 | mv.addObject("hotestTopics",hotestTopics); 164 | if (ifExistUser){ 165 | User resultUser=userService.getUserByUsername(username); 166 | mv.addObject("userInfo",resultUser); 167 | mv.addObject("topicsNum",topicsNum); 168 | mv.addObject("usersNum",usersNum); 169 | mv.addObject("user",user); 170 | return mv; 171 | }else { 172 | String errorInfo=new String("会员未找到"); 173 | mv.addObject("errorInfo",errorInfo); 174 | return mv; 175 | } 176 | } 177 | 178 | @RequestMapping("/settings") 179 | public ModelAndView settings(HttpServletRequest request, HttpSession session){ 180 | 181 | Integer uid=(Integer) session.getAttribute("userId"); 182 | User user=userService.getUserById(uid); 183 | 184 | //最热主题 185 | List hotestTopics=topicService.listMostCommentsTopics(); 186 | 187 | ModelAndView mv=new ModelAndView("settings"); 188 | mv.addObject("user",user); 189 | mv.addObject("hotestTopics",hotestTopics); 190 | return mv; 191 | } 192 | 193 | @RequestMapping(value = "/settings/avatar",method = RequestMethod.GET) 194 | public ModelAndView updateAvatar(HttpServletRequest request, HttpSession session){ 195 | 196 | Integer uid=(Integer) session.getAttribute("userId"); 197 | User user=userService.getUserById(uid); 198 | 199 | //最热主题 200 | List hotestTopics=topicService.listMostCommentsTopics(); 201 | 202 | ModelAndView mv=new ModelAndView("update_avatar"); 203 | mv.addObject("user",user); 204 | mv.addObject("hotestTopics",hotestTopics); 205 | return mv; 206 | } 207 | @RequestMapping(value = "/settings/avatar/update",method = RequestMethod.POST) 208 | public ModelAndView updateAvatarDo(@RequestPart("avatar")MultipartFile avatarFile, HttpServletRequest request, HttpSession session){ 209 | Integer uid=(Integer) session.getAttribute("userId"); 210 | 211 | String fileName=avatarFile.getOriginalFilename(); 212 | String suffix=fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()); 213 | Long date=new Date().getTime(); 214 | String newFileName=date+"-"+uid+"."+suffix; 215 | String absolutePath=session.getServletContext().getRealPath("/static/img/avatar")+"/"+newFileName; 216 | String relativePath="/img/avatar"+"/"+newFileName; 217 | User newUser=new User(); 218 | newUser.setAvatar(relativePath); 219 | newUser.setId(uid); 220 | File file=new File(absolutePath); 221 | 222 | if (!file.exists()){ 223 | try { 224 | avatarFile.transferTo(file); 225 | userService.updateUser(newUser); 226 | }catch (Exception e){ 227 | e.printStackTrace(); 228 | } 229 | } 230 | 231 | 232 | 233 | 234 | User user=userService.getUserById(uid); 235 | 236 | //最热主题 237 | List hotestTopics=topicService.listMostCommentsTopics(); 238 | 239 | ModelAndView mv=new ModelAndView("update_avatar"); 240 | mv.addObject("user",user); 241 | 242 | mv.addObject("hotestTopics",hotestTopics); 243 | return mv; 244 | } 245 | 246 | } 247 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/dao/LoginLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.withstars.dao; 2 | 3 | import com.withstars.domain.LoginLog; 4 | 5 | public interface LoginLogMapper { 6 | int deleteByPrimaryKey(Long id); 7 | 8 | int insert(LoginLog record); 9 | 10 | int insertSelective(LoginLog record); 11 | 12 | LoginLog selectByPrimaryKey(Long id); 13 | 14 | int updateByPrimaryKeySelective(LoginLog record); 15 | 16 | int updateByPrimaryKey(LoginLog record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/dao/ReplyMapper.java: -------------------------------------------------------------------------------- 1 | package com.withstars.dao; 2 | 3 | import com.withstars.domain.Reply; 4 | 5 | import java.util.List; 6 | 7 | public interface ReplyMapper { 8 | int deleteByPrimaryKey(Long id); 9 | 10 | int insert(Reply record); 11 | 12 | int insertSelective(Reply record); 13 | 14 | Reply selectByPrimaryKey(Long id); 15 | 16 | List getRepliesOfTopic(Integer topicId); 17 | 18 | int updateByPrimaryKeySelective(Reply record); 19 | 20 | int updateByPrimaryKeyWithBLOBs(Reply record); 21 | 22 | int updateByPrimaryKey(Reply record); 23 | 24 | int getRepliesNum(Integer topicId); 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/dao/TabMapper.java: -------------------------------------------------------------------------------- 1 | package com.withstars.dao; 2 | 3 | import com.withstars.domain.Tab; 4 | 5 | import java.util.List; 6 | 7 | public interface TabMapper { 8 | int deleteByPrimaryKey(Integer id); 9 | 10 | int insert(Tab record); 11 | 12 | int insertSelective(Tab record); 13 | 14 | Tab selectByPrimaryKey(Integer id); 15 | 16 | Tab getByTabNameEn(String tabName); 17 | 18 | int updateByPrimaryKeySelective(Tab record); 19 | 20 | int updateByPrimaryKey(Tab record); 21 | 22 | List getAllTabs(); 23 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/dao/TopicMapper.java: -------------------------------------------------------------------------------- 1 | package com.withstars.dao; 2 | 3 | import com.withstars.domain.Topic; 4 | 5 | import java.util.List; 6 | 7 | public interface TopicMapper { 8 | int deleteByPrimaryKey(Integer id); 9 | 10 | int insert(Topic record); 11 | 12 | int insertSelective(Topic record); 13 | 14 | Topic selectById(Integer id); 15 | 16 | List listTopicsAndUsers(); 17 | 18 | List listTopicsAndUsersOfTab(Integer tabId); 19 | 20 | List listMostCommentsTopics(); 21 | 22 | int updateByPrimaryKeySelective(Topic record); 23 | 24 | int updateByPrimaryKeyWithBLOBs(Topic record); 25 | 26 | int updateByPrimaryKey(Topic record); 27 | 28 | List getAllTopics(); 29 | 30 | int clickAddOne(Integer id); 31 | 32 | //获取主题总数 33 | int getTopicsNum(); 34 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/dao/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.withstars.dao; 2 | 3 | import com.withstars.domain.User; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | public interface UserMapper { 7 | int deleteByPrimaryKey(Integer id); 8 | 9 | //用户注册 10 | int addUser(User user); 11 | 12 | int insertSelective(User record); 13 | 14 | User selectByPrimaryKey(Integer id); 15 | 16 | 17 | User selectByUsername(String username); 18 | 19 | int updateByPrimaryKeySelective(User record); 20 | 21 | int updateByPrimaryKey(User record); 22 | 23 | //多参数注解 24 | int addCredit(@Param("points") Integer points,@Param("id")Integer id); 25 | 26 | //查询username是否存在 27 | int existUsername(String username); 28 | 29 | //查询用户数 30 | int getUserCount(); 31 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/BaseDomain.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import org.apache.commons.lang.builder.ToStringBuilder; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * Description: 10 | * User: withstars 11 | * Date: 2018-04-22 12 | * Time: 8:43 13 | * Mail: withstars@126.com 14 | */ 15 | public class BaseDomain implements Serializable { 16 | @Override 17 | public String toString() { 18 | return ToStringBuilder.reflectionToString(this); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/LoginLog.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * 登录日志实体类 8 | */ 9 | public class LoginLog extends BaseDomain { 10 | private Long id; 11 | 12 | private Integer userId; 13 | 14 | private Date loginTime; 15 | 16 | private String ip; 17 | 18 | private String device; 19 | 20 | 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public Integer getUserId() { 31 | return userId; 32 | } 33 | 34 | public void setUserId(Integer userId) { 35 | this.userId = userId; 36 | } 37 | 38 | public Date getLoginTime() { 39 | return loginTime; 40 | } 41 | 42 | public void setLoginTime(Date loginTime) { 43 | this.loginTime = loginTime; 44 | } 45 | 46 | public String getIp() { 47 | return ip; 48 | } 49 | 50 | public void setIp(String ip) { 51 | this.ip = ip == null ? null : ip.trim(); 52 | } 53 | 54 | public String getDevice() { 55 | return device; 56 | } 57 | 58 | public void setDevice(String device) { 59 | this.device = device == null ? null : device.trim(); 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/Reply.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import java.io.Serializable; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | /** 8 | * 回复实体类 9 | */ 10 | public class Reply extends BaseDomain { 11 | private User user; 12 | 13 | private Long id; 14 | 15 | private Integer topicId; 16 | 17 | private Integer replyUserId; 18 | 19 | private Date createTime; 20 | 21 | private Date updateTime; 22 | 23 | private String device; 24 | 25 | private String content; 26 | 27 | 28 | 29 | public void setUser(User user) { 30 | this.user = user; 31 | } 32 | 33 | public User getUser() { 34 | return user; 35 | } 36 | 37 | public Long getId() { 38 | return id; 39 | } 40 | 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | 45 | public Integer getTopicId() { 46 | return topicId; 47 | } 48 | 49 | public void setTopicId(Integer topicId) { 50 | this.topicId = topicId; 51 | } 52 | 53 | public Integer getReplyUserId() { 54 | return replyUserId; 55 | } 56 | 57 | public void setReplyUserId(Integer replyUserId) { 58 | this.replyUserId = replyUserId; 59 | } 60 | 61 | public Date getCreateTime() { 62 | return createTime; 63 | } 64 | 65 | public void setCreateTime(Date createTime) { 66 | this.createTime = createTime; 67 | } 68 | 69 | public Date getUpdateTime() { 70 | return updateTime; 71 | } 72 | 73 | public void setUpdateTime(Date updateTime) { 74 | this.updateTime = updateTime; 75 | } 76 | 77 | public String getDevice() { 78 | return device; 79 | } 80 | 81 | public void setDevice(String device) { 82 | this.device = device == null ? null : device.trim(); 83 | } 84 | 85 | public String getContent() { 86 | return content; 87 | } 88 | 89 | public void setContent(String content) { 90 | this.content = content == null ? null : content.trim(); 91 | } 92 | 93 | public String getLocalCreateTime() { 94 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm:ss");//设置日期格式 95 | String date = df.format(this.createTime); 96 | return date; 97 | } 98 | public String getLocalUpdateTime() { 99 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm:ss");//设置日期格式 100 | String date = df.format(updateTime); 101 | return date; 102 | } 103 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/Tab.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | /** 7 | * 主题板块实体类 8 | */ 9 | public class Tab extends BaseDomain { 10 | private Integer id; 11 | 12 | private String tabName; 13 | 14 | private String tabNameEn; 15 | 16 | private List topics; 17 | 18 | public String getTabNameEn() { 19 | return tabNameEn; 20 | } 21 | 22 | public void setTabNameEn(String tabNameEn) { 23 | this.tabNameEn = tabNameEn; 24 | } 25 | 26 | 27 | 28 | public void setTopics(List topics) { 29 | this.topics = topics; 30 | } 31 | 32 | public List getTopics() { 33 | return topics; 34 | } 35 | 36 | public Integer getId() { 37 | return id; 38 | } 39 | 40 | public void setId(Integer id) { 41 | this.id = id; 42 | } 43 | 44 | public String getTabName() { 45 | return tabName; 46 | } 47 | 48 | public void setTabName(String tabName) { 49 | this.tabName = tabName; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/Topic.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import java.io.Serializable; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | /** 8 | * 主题实体类 9 | */ 10 | public class Topic extends BaseDomain { 11 | 12 | private User user; 13 | 14 | private Tab tab; 15 | 16 | private Integer countReplies; 17 | 18 | private Integer id; 19 | 20 | private Integer userId; 21 | 22 | private Date createTime; 23 | 24 | private Date updateTime; 25 | 26 | private String title; 27 | 28 | private Integer click; 29 | 30 | private Byte tabId; 31 | 32 | private String content; 33 | 34 | 35 | 36 | 37 | public Integer getCountReplies() { 38 | return countReplies; 39 | } 40 | 41 | public void setCountReplies(Integer countReplies) { 42 | this.countReplies = countReplies; 43 | } 44 | 45 | public void setTab(Tab tab) { 46 | this.tab = tab; 47 | } 48 | 49 | public Tab getTab() { 50 | return tab; 51 | } 52 | 53 | public void setUser(User user) { 54 | this.user = user; 55 | } 56 | 57 | public User getUser() { 58 | return user; 59 | } 60 | 61 | public Integer getId() { 62 | return id; 63 | } 64 | 65 | public void setId(Integer id) { 66 | this.id = id; 67 | } 68 | 69 | public Integer getUserId() { 70 | return userId; 71 | } 72 | 73 | public void setUserId(Integer userId) { 74 | this.userId = userId; 75 | } 76 | 77 | public Date getCreateTime() { 78 | return createTime; 79 | } 80 | 81 | public void setCreateTime(Date createTime) { 82 | this.createTime = createTime; 83 | } 84 | 85 | public Date getUpdateTime() { 86 | return updateTime; 87 | } 88 | 89 | public void setUpdateTime(Date updateTime) { 90 | this.updateTime = updateTime; 91 | } 92 | 93 | public String getTitle() { 94 | return title; 95 | } 96 | 97 | public void setTitle(String title) { 98 | this.title = title == null ? null : title.trim(); 99 | } 100 | 101 | public Integer getClick() { 102 | return click; 103 | } 104 | 105 | public void setClick(Integer click) { 106 | this.click = click; 107 | } 108 | 109 | public Byte getTabId() { 110 | return tabId; 111 | } 112 | 113 | public void setTabId(Byte tabId) { 114 | this.tabId = tabId; 115 | } 116 | 117 | public String getContent() { 118 | return content; 119 | } 120 | 121 | public void setContent(String content) { 122 | this.content = content == null ? null : content.trim(); 123 | } 124 | 125 | public String getLocalCreateTime() { 126 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm:ss");//设置日期格式 127 | String date = df.format(this.createTime); 128 | return date; 129 | } 130 | public String getLocalUpdateTime() { 131 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm:ss");//设置日期格式 132 | String date = df.format(updateTime); 133 | return date; 134 | } 135 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.withstars.domain; 2 | 3 | import java.io.Serializable; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | /** 8 | * 用户信息实体类 9 | */ 10 | public class User extends BaseDomain{ 11 | private Integer id; 12 | 13 | private String username; 14 | 15 | private String password; 16 | 17 | private String email; 18 | 19 | private String phoneNum; 20 | 21 | private Date createTime; 22 | 23 | private Date updateTime; 24 | 25 | private Integer credit; 26 | 27 | private String avatar; 28 | 29 | private Byte type; 30 | 31 | 32 | public Integer getId() { 33 | return id; 34 | } 35 | 36 | public void setId(Integer id) { 37 | this.id = id; 38 | } 39 | 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | public void setUsername(String username) { 45 | this.username = username == null ? null : username.trim(); 46 | } 47 | 48 | public String getPassword() { 49 | return password; 50 | } 51 | 52 | public void setPassword(String password) { 53 | this.password = password == null ? null : password.trim(); 54 | } 55 | 56 | public String getEmail() { 57 | return email; 58 | } 59 | 60 | public void setEmail(String email) { 61 | this.email = email == null ? null : email.trim(); 62 | } 63 | 64 | public String getPhoneNum() { 65 | return phoneNum; 66 | } 67 | 68 | public void setPhoneNum(String phoneNum) { 69 | this.phoneNum = phoneNum == null ? null : phoneNum.trim(); 70 | } 71 | 72 | public Date getCreateTime() { 73 | return createTime; 74 | } 75 | 76 | public void setCreateTime(Date createTime) { 77 | this.createTime = createTime; 78 | } 79 | 80 | public Date getUpdateTime() { 81 | return updateTime; 82 | } 83 | 84 | public void setUpdateTime(Date updateTime) { 85 | this.updateTime = updateTime; 86 | } 87 | 88 | public Integer getCredit() { 89 | return credit; 90 | } 91 | 92 | public void setCredit(Integer credit) { 93 | this.credit = credit; 94 | } 95 | 96 | public String getAvatar() { 97 | return avatar; 98 | } 99 | 100 | public void setAvatar(String avatar) { 101 | this.avatar = avatar == null ? null : avatar.trim(); 102 | } 103 | 104 | public Byte getType() { 105 | return type; 106 | } 107 | 108 | public void setType(Byte type) { 109 | this.type = type; 110 | } 111 | 112 | public String getLocalCreateTime() { 113 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm");//设置日期格式 114 | String date = df.format(this.createTime); 115 | return date; 116 | } 117 | public String getLocalUpdateTime() { 118 | SimpleDateFormat df = new SimpleDateFormat("yyyy-M-dd HH:mm");//设置日期格式 119 | String date = df.format(updateTime); 120 | return date; 121 | } 122 | } -------------------------------------------------------------------------------- /src/main/java/com/withstars/intercepter/CORSFilter.java: -------------------------------------------------------------------------------- 1 | package com.withstars.intercepter; 2 | 3 | import javax.servlet.*; 4 | import javax.servlet.http.HttpServletResponse; 5 | import java.io.IOException; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * Description: 10 | * User: withstars 11 | * Date: 2018-04-18 12 | * Time: 8:25 13 | * Mail: withstars@126.com 14 | */ 15 | public class CORSFilter implements Filter { 16 | 17 | 18 | public void init(FilterConfig var1) throws ServletException {} 19 | 20 | 21 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 22 | HttpServletResponse response = (HttpServletResponse) servletResponse; 23 | response.addHeader("Access-Control-Allow-Origin", "*"); 24 | response.addHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,PUT,OPTIONS"); 25 | filterChain.doFilter(servletRequest, servletResponse); 26 | } 27 | 28 | public void destroy() {} 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/LoginLogService.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service; 2 | 3 | import com.withstars.domain.LoginLog; 4 | 5 | public interface LoginLogService { 6 | 7 | 8 | /** 9 | * 插入一条登录日志 10 | */ 11 | boolean addLog(LoginLog log); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/ReplyService.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service; 2 | 3 | import com.withstars.domain.Reply; 4 | 5 | import java.util.List; 6 | 7 | public interface ReplyService { 8 | 9 | List getRepliesOfTopic(Integer topicId); 10 | 11 | boolean addReply(Reply reply); 12 | 13 | int repliesNum(Integer topicId); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/TabService.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service; 2 | 3 | import com.withstars.domain.Tab; 4 | 5 | import java.util.List; 6 | 7 | public interface TabService { 8 | List getAllTabs(); 9 | 10 | Tab getByTabNameEn(String tabName); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/TopicService.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service; 2 | 3 | import com.withstars.domain.Topic; 4 | 5 | import java.util.List; 6 | 7 | public interface TopicService { 8 | 9 | 10 | /** 11 | * 获取全部主题 12 | */ 13 | List getAllTopics(); 14 | 15 | /** 16 | * 获取全部主题及用户信息 用于渲染首页 17 | */ 18 | List listTopicsAndUsers(); 19 | 20 | /** 21 | * 获取最多评论主题列表 22 | * @return 23 | */ 24 | List listMostCommentsTopics(); 25 | 26 | /** 27 | * 获取全部主题及用户信息 用于渲染板块页面 28 | */ 29 | List listTopicsAndUsersOfTab(Integer tabId); 30 | 31 | /** 32 | * 获取指定ID主题 33 | */ 34 | Topic selectById(Integer id); 35 | 36 | /** 37 | * 新建主题 38 | */ 39 | boolean addTopic(Topic topic); 40 | 41 | /** 42 | * 点击量加一 43 | */ 44 | boolean clickAddOne(Integer id); 45 | 46 | /** 47 | * 获取主题总数 48 | */ 49 | int getTopicsNum(); 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service; 2 | 3 | import com.withstars.domain.User; 4 | 5 | public interface UserService { 6 | 7 | /** 8 | * 用户注册 9 | */ 10 | public boolean addUser(User user); 11 | 12 | /** 13 | * 登录验证 14 | */ 15 | public int login(String username,String password); 16 | 17 | /** 18 | * 添加积分 19 | */ 20 | public boolean addCredit(Integer points,Integer id); 21 | 22 | /** 23 | * 检查username是否存在 24 | * @param username 25 | * @return 26 | */ 27 | public boolean existUsername(String username); 28 | 29 | /** 30 | * 获取用户信息 31 | * @param username 32 | * @return 33 | */ 34 | public User getUserByUsername(String username); 35 | 36 | 37 | /** 38 | * 获取用户信息 39 | * @param id 40 | * @return 41 | */ 42 | public User getUserById(Integer id); 43 | 44 | /** 45 | * 获取用户数 46 | */ 47 | public int getUserCount(); 48 | 49 | public boolean updateUser(User user); 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/impl/LoginLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service.impl; 2 | 3 | import com.withstars.dao.LoginLogMapper; 4 | import com.withstars.domain.LoginLog; 5 | import com.withstars.service.LoginLogService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class LoginLogServiceImpl implements LoginLogService { 11 | 12 | @Autowired 13 | public LoginLogMapper loginLogDao; 14 | 15 | public boolean addLog(LoginLog log) { 16 | 17 | if(loginLogDao.insert(log)>0){ 18 | return true; 19 | }else { 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/impl/ReplyServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service.impl; 2 | 3 | import com.withstars.dao.ReplyMapper; 4 | import com.withstars.domain.Reply; 5 | import com.withstars.service.ReplyService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class ReplyServiceImpl implements ReplyService { 13 | 14 | @Autowired 15 | public ReplyMapper replyDao; 16 | 17 | public List getRepliesOfTopic(Integer topicId) { 18 | return replyDao.getRepliesOfTopic(topicId); 19 | } 20 | 21 | public boolean addReply(Reply reply) { 22 | return replyDao.insert(reply)>0; 23 | } 24 | 25 | public int repliesNum(Integer topicId) { 26 | return replyDao.getRepliesNum(topicId); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/impl/TabServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service.impl; 2 | 3 | import com.withstars.dao.TabMapper; 4 | import com.withstars.domain.Tab; 5 | import com.withstars.service.TabService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class TabServiceImpl implements TabService { 13 | 14 | @Autowired 15 | public TabMapper tabDao; 16 | 17 | public List getAllTabs() { 18 | return tabDao.getAllTabs(); 19 | } 20 | 21 | public Tab getByTabNameEn(String tabNameEn) { 22 | return tabDao.getByTabNameEn(tabNameEn); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/impl/TopicServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service.impl; 2 | 3 | import com.withstars.dao.TopicMapper; 4 | import com.withstars.domain.Topic; 5 | import com.withstars.service.TopicService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class TopicServiceImpl implements TopicService { 13 | 14 | @Autowired 15 | public TopicMapper topicDao; 16 | 17 | //获取全部主题 18 | public List getAllTopics() { 19 | return topicDao.getAllTopics(); 20 | } 21 | 22 | //获取指定id主题 23 | public Topic selectById(Integer id) { 24 | Topic topic=topicDao.selectById(id); 25 | return topic; 26 | } 27 | 28 | public List listMostCommentsTopics() { 29 | return topicDao.listMostCommentsTopics(); 30 | } 31 | 32 | public boolean addTopic(Topic topic) { 33 | return topicDao.insert(topic)>0; 34 | } 35 | 36 | public boolean clickAddOne(Integer id) { 37 | return topicDao.clickAddOne(id)>0; 38 | } 39 | 40 | public int getTopicsNum() { 41 | return topicDao.getTopicsNum(); 42 | } 43 | 44 | public List listTopicsAndUsers() { 45 | return topicDao.listTopicsAndUsers(); 46 | } 47 | 48 | public List listTopicsAndUsersOfTab(Integer tabId) { 49 | return topicDao.listTopicsAndUsersOfTab(tabId); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.withstars.service.impl; 2 | 3 | import com.withstars.dao.UserMapper; 4 | import com.withstars.domain.User; 5 | import com.withstars.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class UserServiceImpl implements UserService { 11 | @Autowired 12 | public UserMapper userDao; 13 | 14 | //用户注册 15 | public boolean addUser(User user) { 16 | return userDao.addUser(user)>0; 17 | } 18 | 19 | //登录验证 0:用户名不存在 1:密码错误 2:验证成功 20 | public int login(String username,String password) { 21 | //判断username是否存在 22 | boolean existUsername=existUsername(username); 23 | //若username存在,验证密码 24 | if (existUsername){ 25 | User resUser=userDao.selectByUsername(username); 26 | if (resUser.getPassword().equals(password)){ 27 | return 2; 28 | } 29 | return 1; 30 | } 31 | return 0; 32 | } 33 | 34 | //登陆后获取用户信息 35 | public User getUserByUsername(String username){ 36 | User resUser=userDao.selectByUsername(username); 37 | return resUser; 38 | } 39 | 40 | //增加积分 41 | public boolean addCredit(Integer points,Integer id) { 42 | return userDao.addCredit(points,id)>0; 43 | } 44 | 45 | //username是否存在 46 | public boolean existUsername(String username) { 47 | return userDao.existUsername(username)==1; 48 | } 49 | 50 | public int getUserCount() { 51 | return userDao.getUserCount(); 52 | } 53 | 54 | public User getUserById(Integer id) { 55 | return userDao.selectByPrimaryKey(id); 56 | } 57 | 58 | public boolean updateUser(User user) { 59 | return userDao.updateByPrimaryKeySelective(user)>0; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/util/HexConversion.java: -------------------------------------------------------------------------------- 1 | package com.withstars.util; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * Description: 6 | * User: withstars 7 | * Date: 2018-02-15 8 | * Time: 10:57 9 | * Mail: withstars@126.com 10 | */ 11 | public class HexConversion { 12 | 13 | /** 14 | * 二进制转十六进制 15 | */ 16 | public static String bytesToHex(byte[] bytes) { 17 | StringBuffer hexStr = new StringBuffer(); 18 | int num; 19 | for (int i = 0; i < bytes.length; i++) { 20 | num = bytes[i]; 21 | if(num < 0) { 22 | num += 256; 23 | } 24 | if(num < 16){ 25 | hexStr.append("0"); 26 | } 27 | hexStr.append(Integer.toHexString(num)); 28 | } 29 | return hexStr.toString().toUpperCase(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/withstars/util/ProduceMD5.java: -------------------------------------------------------------------------------- 1 | package com.withstars.util; 2 | 3 | import java.security.MessageDigest; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * Description: 8 | * User: withstars 9 | * Date: 2018-02-15 10 | * Time: 10:56 11 | * Mail: withstars@126.com 12 | */ 13 | public class ProduceMD5 { 14 | 15 | /** 16 | * 生成MD5值 17 | */ 18 | public static String getMD5(String message) { 19 | String md5 = ""; 20 | try { 21 | MessageDigest md = MessageDigest.getInstance("MD5"); // 创建一个md5算法对象 22 | byte[] messageByte = message.getBytes("UTF-8"); 23 | byte[] md5Byte = md.digest(messageByte); // 获得MD5字节数组,16*8=128位 24 | md5 = HexConversion.bytesToHex(md5Byte); // 转换为16进制字符串 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | return md5; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/resources/jdbc.properties: -------------------------------------------------------------------------------- 1 | driver=com.mysql.jdbc.Driver 2 | url=jdbc:mysql://localhost:3306/forum?useUnicode=true&autoReconnect=true 3 | name=root 4 | password=0000 -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=WARN, stdout , R 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.Threshold = DEBUG 6 | log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n 7 | 8 | log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 9 | log4j.appender.R.File=logs\\genesis.log 10 | log4j.appender.R.Threshold = ERROR 11 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 12 | log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n 13 | 14 | log4j.logger.com.withstars=WARN 15 | log4j.logger.com.opensymphony.oscache=ERROR 16 | log4j.logger.net.sf.navigator=ERROR 17 | log4j.logger.org.apache.commons=ERROR 18 | log4j.logger.org.apache.struts=WARN 19 | log4j.logger.org.displaytag=ERROR 20 | log4j.logger.org.springframework=DEBUG 21 | log4j.logger.com.ibatis.db=WARN 22 | log4j.logger.org.apache.velocity=FATAL 23 | 24 | log4j.logger.com.canoo.webtest=WARN 25 | 26 | log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN 27 | log4j.logger.org.hibernate=WARN 28 | log4j.logger.org.logicalcobwebs=WARN -------------------------------------------------------------------------------- /src/main/resources/mapper/LoginLogMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, user_id, login_time, ip, device 13 | 14 | 20 | 21 | delete from login_log 22 | where id = #{id,jdbcType=BIGINT} 23 | 24 | 25 | insert into login_log (user_id, login_time, 26 | ip, device) 27 | values (#{userId,jdbcType=INTEGER}, #{loginTime,jdbcType=TIMESTAMP}, 28 | #{ip,jdbcType=VARCHAR}, #{device,jdbcType=VARCHAR}) 29 | 30 | 31 | insert into login_log 32 | 33 | 34 | id, 35 | 36 | 37 | user_id, 38 | 39 | 40 | login_time, 41 | 42 | 43 | ip, 44 | 45 | 46 | device, 47 | 48 | 49 | 50 | 51 | #{id,jdbcType=BIGINT}, 52 | 53 | 54 | #{userId,jdbcType=INTEGER}, 55 | 56 | 57 | #{loginTime,jdbcType=TIMESTAMP}, 58 | 59 | 60 | #{ip,jdbcType=VARCHAR}, 61 | 62 | 63 | #{device,jdbcType=VARCHAR}, 64 | 65 | 66 | 67 | 68 | update login_log 69 | 70 | 71 | user_id = #{userId,jdbcType=INTEGER}, 72 | 73 | 74 | login_time = #{loginTime,jdbcType=TIMESTAMP}, 75 | 76 | 77 | ip = #{ip,jdbcType=VARCHAR}, 78 | 79 | 80 | device = #{device,jdbcType=VARCHAR}, 81 | 82 | 83 | where id = #{id,jdbcType=BIGINT} 84 | 85 | 86 | update login_log 87 | set user_id = #{userId,jdbcType=INTEGER}, 88 | login_time = #{loginTime,jdbcType=TIMESTAMP}, 89 | ip = #{ip,jdbcType=VARCHAR}, 90 | device = #{device,jdbcType=VARCHAR} 91 | where id = #{id,jdbcType=BIGINT} 92 | 93 | -------------------------------------------------------------------------------- /src/main/resources/mapper/ReplyMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 35 | 36 | 37 | delete from reply 38 | where id = #{id,jdbcType=BIGINT} 39 | 40 | 41 | 42 | insert into reply (topic_id, reply_user_id, 43 | create_time, update_time, 44 | content) 45 | values ( #{topicId,jdbcType=INTEGER}, #{replyUserId,jdbcType=INTEGER}, 46 | #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, 47 | #{content,jdbcType=LONGVARCHAR}) 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/main/resources/mapper/TabMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, tab_name,tab_name_en 13 | 14 | 15 | 21 | 22 | 28 | 29 | 35 | 36 | 37 | 38 | delete from tab 39 | where id = #{id,jdbcType=INTEGER} 40 | 41 | 42 | 43 | insert into tab (id, tab_name) 44 | values (#{id,jdbcType=INTEGER}, #{tabName,jdbcType=INTEGER}) 45 | 46 | 47 | insert into tab 48 | 49 | 50 | id, 51 | 52 | 53 | tab_name, 54 | 55 | 56 | 57 | 58 | #{id,jdbcType=INTEGER}, 59 | 60 | 61 | #{tabName,jdbcType=INTEGER}, 62 | 63 | 64 | 65 | 66 | update tab 67 | 68 | 69 | tab_name = #{tabName,jdbcType=INTEGER}, 70 | 71 | 72 | where id = #{id,jdbcType=INTEGER} 73 | 74 | 75 | update tab 76 | set tab_name = #{tabName,jdbcType=INTEGER} 77 | where id = #{id,jdbcType=INTEGER} 78 | 79 | -------------------------------------------------------------------------------- /src/main/resources/mapper/TopicMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | id, user_id, create_time, update_time, title, click, tab_id 68 | 69 | 70 | 71 | content 72 | 73 | 74 | 80 | 81 | 87 | 88 | 91 | 92 | 93 | 94 | 100 | 101 | 106 | 107 | 110 | 111 | 112 | delete from topic 113 | where id = #{id,jdbcType=INTEGER} 114 | 115 | 116 | 117 | insert into topic (user_id, create_time, 118 | update_time, title, 119 | tab_id, content) 120 | values ( #{userId,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, 121 | #{updateTime,jdbcType=TIMESTAMP}, #{title,jdbcType=VARCHAR}, 122 | #{tabId,jdbcType=TINYINT}, #{content,jdbcType=LONGVARCHAR}) 123 | 124 | 125 | 126 | insert into topic 127 | 128 | 129 | id, 130 | 131 | 132 | user_id, 133 | 134 | 135 | create_time, 136 | 137 | 138 | update_time, 139 | 140 | 141 | title, 142 | 143 | 144 | click, 145 | 146 | 147 | tab_id, 148 | 149 | 150 | content, 151 | 152 | 153 | 154 | 155 | #{id,jdbcType=INTEGER}, 156 | 157 | 158 | #{userId,jdbcType=INTEGER}, 159 | 160 | 161 | #{createTime,jdbcType=TIMESTAMP}, 162 | 163 | 164 | #{updateTime,jdbcType=TIMESTAMP}, 165 | 166 | 167 | #{title,jdbcType=VARCHAR}, 168 | 169 | 170 | #{click,jdbcType=INTEGER}, 171 | 172 | 173 | #{tabId,jdbcType=TINYINT}, 174 | 175 | 176 | #{content,jdbcType=LONGVARCHAR}, 177 | 178 | 179 | 180 | 181 | 182 | update topic 183 | 184 | 185 | user_id = #{userId,jdbcType=INTEGER}, 186 | 187 | 188 | create_time = #{createTime,jdbcType=TIMESTAMP}, 189 | 190 | 191 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 192 | 193 | 194 | title = #{title,jdbcType=VARCHAR}, 195 | 196 | 197 | click = #{click,jdbcType=INTEGER}, 198 | 199 | 200 | tab_id = #{tabId,jdbcType=TINYINT}, 201 | 202 | 203 | content = #{content,jdbcType=LONGVARCHAR}, 204 | 205 | 206 | where id = #{id,jdbcType=INTEGER} 207 | 208 | 209 | 210 | update topic 211 | set user_id = #{userId,jdbcType=INTEGER}, 212 | create_time = #{createTime,jdbcType=TIMESTAMP}, 213 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 214 | title = #{title,jdbcType=VARCHAR}, 215 | click = #{click,jdbcType=INTEGER}, 216 | tab_id = #{tabId,jdbcType=TINYINT}, 217 | content = #{content,jdbcType=LONGVARCHAR} 218 | where id = #{id,jdbcType=INTEGER} 219 | 220 | 221 | update topic 222 | set user_id = #{userId,jdbcType=INTEGER}, 223 | create_time = #{createTime,jdbcType=TIMESTAMP}, 224 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 225 | title = #{title,jdbcType=VARCHAR}, 226 | click = #{click,jdbcType=INTEGER}, 227 | tab_id = #{tabId,jdbcType=TINYINT} 228 | where id = #{id,jdbcType=INTEGER} 229 | 230 | 231 | 232 | update topic 233 | set 234 | click = click+1 235 | where id = #{id,jdbcType=INTEGER} 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id, username, password, email, phone_num, create_time, update_time, credit, avatar, 19 | type 20 | 21 | 22 | 28 | 29 | 34 | 35 | 36 | 42 | 43 | 46 | 47 | 48 | delete from user 49 | where id = #{id,jdbcType=INTEGER} 50 | 51 | 52 | insert into user (username, password, 53 | email, phone_num, create_time, 54 | update_time, credit, 55 | type,avatar) 56 | values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 57 | #{email,jdbcType=VARCHAR}, #{phoneNum,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 58 | #{updateTime,jdbcType=TIMESTAMP}, #{credit,jdbcType=INTEGER}, 59 | #{type,jdbcType=TINYINT},#{avatar,jdbcType=VARCHAR}) 60 | 61 | 62 | insert into user 63 | 64 | 65 | id, 66 | 67 | 68 | username, 69 | 70 | 71 | password, 72 | 73 | 74 | email, 75 | 76 | 77 | phone_num, 78 | 79 | 80 | create_time, 81 | 82 | 83 | update_time, 84 | 85 | 86 | credit, 87 | 88 | 89 | avatar, 90 | 91 | 92 | type, 93 | 94 | 95 | 96 | 97 | #{id,jdbcType=INTEGER}, 98 | 99 | 100 | #{username,jdbcType=VARCHAR}, 101 | 102 | 103 | #{password,jdbcType=VARCHAR}, 104 | 105 | 106 | #{email,jdbcType=VARCHAR}, 107 | 108 | 109 | #{phoneNum,jdbcType=VARCHAR}, 110 | 111 | 112 | #{createTime,jdbcType=TIMESTAMP}, 113 | 114 | 115 | #{updateTime,jdbcType=TIMESTAMP}, 116 | 117 | 118 | #{credit,jdbcType=INTEGER}, 119 | 120 | 121 | #{avatar,jdbcType=VARCHAR}, 122 | 123 | 124 | #{type,jdbcType=TINYINT}, 125 | 126 | 127 | 128 | 129 | update user 130 | 131 | 132 | username = #{username,jdbcType=VARCHAR}, 133 | 134 | 135 | password = #{password,jdbcType=VARCHAR}, 136 | 137 | 138 | email = #{email,jdbcType=VARCHAR}, 139 | 140 | 141 | phone_num = #{phoneNum,jdbcType=VARCHAR}, 142 | 143 | 144 | create_time = #{createTime,jdbcType=TIMESTAMP}, 145 | 146 | 147 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 148 | 149 | 150 | credit = #{credit,jdbcType=INTEGER}, 151 | 152 | 153 | avatar = #{avatar,jdbcType=VARCHAR}, 154 | 155 | 156 | type = #{type,jdbcType=TINYINT}, 157 | 158 | 159 | where id = #{id,jdbcType=INTEGER} 160 | 161 | 162 | update user 163 | set username = #{username,jdbcType=VARCHAR}, 164 | password = #{password,jdbcType=VARCHAR}, 165 | email = #{email,jdbcType=VARCHAR}, 166 | phone_num = #{phoneNum,jdbcType=VARCHAR}, 167 | create_time = #{createTime,jdbcType=TIMESTAMP}, 168 | update_time = #{updateTime,jdbcType=TIMESTAMP}, 169 | credit = #{credit,jdbcType=INTEGER}, 170 | avatar = #{avatar,jdbcType=VARCHAR}, 171 | type = #{type,jdbcType=TINYINT} 172 | where id = #{id,jdbcType=INTEGER} 173 | 174 | 175 | 176 | update user set credit = credit + #{points,jdbcType=INTEGER} WHERE id = #{id,jdbcType=INTEGER} 177 | 178 | -------------------------------------------------------------------------------- /src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/404.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: 君行天下 4 | Date: 2017/7/31 5 | Time: 20:22 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 12 | 13 | 404 Not Find:( 14 | 150 | 151 | 152 |
153 |

404 Not Find:(

154 |

对不起,您访问的页面不存在~

155 |

请输入正确的地址

156 |

3秒后,自动跳转到上一页

157 | 168 |
169 | 170 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/cate.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | Genesis - 一个分享创造的开发者社区 9 | 10 | 11 | 12 | 52 | 53 | 54 | 55 | <%@ include file="header.jsp"%> 56 | 57 |
58 |
59 | 活跃精华最近 60 |
61 | 62 | 85 | 86 |
87 | 88 | 89 | <%@ include file="side.jsp"%> 90 | 91 | 92 | <%@ include file="footer.jsp"%> 93 | 94 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/detail.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 3 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ${topic.title} - Genesis 12 | 13 | 14 | 15 | <%@ include file="header.jsp"%> 16 |
17 |
18 |
19 |
20 |
21 | Genesis › 主题 22 |
23 |

${topic.title}


24 |
25 | ${topic.user.username}   26 | ${topic.localCreateTime}   +08:00   27 | ${topic.click}次点击 28 |
29 |
30 | 31 |
32 | 33 |
34 |
35 | 36 |
    37 |
  • 38 | ${topic.content} 39 |
  • 40 |
41 |
42 | 43 | 44 |
45 |
46 | 47 | ${fn:length(replies)} 回复 | 直到 48 | 49 | 50 | ${reply.localCreateTime} 51 | 52 | 53 | 54 |
55 | 56 |
    57 | 58 | 59 |
  • 60 |
    61 |
    62 | 63 |
    64 |
    65 | ${reply.user.username}   66 | ${reply.localCreateTime} 67 |
    68 |
    69 |

    ${reply.content}

    70 |
    71 |
    72 |
    73 |
  • 74 |
    75 | 76 |
77 |
78 |
79 | 80 | 81 | 82 |
83 |
84 | 添加一条新回复 85 |
86 |
87 |
88 |
89 | 90 | 91 |
92 | 93 |
94 |
95 | 96 |
97 |
98 |
99 | 100 |
101 | 102 | <%@ include file="side.jsp"%> 103 | 104 | 105 | <%@ include file="footer.jsp"%> 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/footer.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 47 | 48 | 49 |
50 |
51 | 我们是高品质的开发者社区,致力于为开发者提供一个分享创造、结识伙伴、协同互助的平台。 52 |


53 |

Designed by withstars

54 |
55 |
56 |

统计信息

57 |
    58 |
  • 会员数: ${usersNum}
  • 59 |
  • 话题数: ${topicsNum}
  • 60 |
61 |
62 |
63 |

友情链接

64 | 69 |
70 |
71 |

其他信息

72 | 76 |
77 |
78 | 79 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 | 59 | 60 | 61 |
62 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/new.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 创作新主题 › Genesis 11 | 12 | 13 | 14 | <%@ include file="header.jsp"%> 15 | 16 |
17 |
18 |
19 | Genesis › 创作新主题 20 |
21 | 22 |
23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 | 33 |
34 |
35 |
36 | 41 |
42 |

43 | 44 | 45 |
46 |
47 | 48 |
49 | 50 | 51 | 52 |
53 | 54 | 55 |
56 |
57 | 发帖提示 58 |
59 |
    60 |
  • 61 |
    主题标题
    62 |

    63 | 请在标题中描述内容要点。如果一件事情在标题的长度内就已经可以说清楚,那就没有必要写正文了。 64 |

    65 |
  • 66 | 67 |
  • 68 |
    正文
    69 |

    70 | 请清楚地表达所要说明的内容。 71 |

    72 |
  • 73 |
74 |
75 | 76 | 77 |
78 |
79 | 社区指导原则 80 |
81 |
    82 |
  • 83 |
    尊重原创
    84 |

    85 | 请不要发布任何盗版下载链接,包括软件、音乐、电影等等。Genesis是创意工作者的社区,我们尊重原创。 86 |

    87 |
  • 88 | 89 |
  • 90 |
    友好互助
    91 |

    92 | 保持对陌生人的友善。用知识去帮助别人。 93 |

    94 |
  • 95 |
96 |
97 | 98 | 99 | 100 | <%@ include file="footer.jsp"%> 101 | 102 | 120 | 121 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/settings.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Genesis ›设置 11 | 12 | 13 | 14 | <%@ include file="header.jsp"%> 15 | 16 |
17 |
18 |
19 | Genesis › 设置 20 |
21 | 22 |
23 | 24 |
25 |
26 | 27 | 更换头像 28 |
29 |
30 | 31 |
32 |

${user.id}

33 |
34 |
35 |
36 | 37 |
38 |

${user.username}

39 |
40 |
41 |
42 | 43 |
44 |

${user.email}

45 |
46 |
47 |
48 | 49 |
50 |

${user.localCreateTime}

51 |
52 |
53 |
54 | 55 |
56 |

${user.credit}

57 |
58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 | 66 | 67 | 68 |
69 | 70 | 71 | <%@ include file="side.jsp"%> 72 | 73 | 74 | <%@ include file="footer.jsp"%> 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/side.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | Genesis 12 | 一个分享创造的开发者社区 13 |
14 |
15 | 21 |
22 |
23 | 24 | 25 | 26 |
27 |
28 | ${user.username} 29 |
30 | 35 |
36 |
37 | 38 |
39 |
40 | 热议主题 41 |
42 | 47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/signin.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 登录 - Genesis 8 | 9 | 10 | 11 | 12 | 13 | 53 | 54 | 55 | 56 | <%@ include file="header.jsp"%> 57 | 58 |
59 |
60 |

登录

61 |
62 |
63 | 64 |
65 | 66 | 67 |
68 |
69 | 70 | 71 |
72 |
73 | 76 | 忘记密码? 77 |
78 | 79 |


80 | 81 | 82 | 83 |
84 |
85 | 160 | 161 | <%@ include file="footer.jsp"%> 162 | 163 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/signup.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 注册 - Genesis 8 | 9 | 10 | 11 | 51 | 52 | 53 | 54 | 55 | 56 | <%@ include file="header.jsp"%> 57 | 58 |
59 |
60 |

注册

61 |
62 |
63 |
64 |
65 | 66 |
67 | 68 |

请使用半角的 a-z 或数字 0-9

69 |
70 |
71 |
72 | 73 |
74 | 75 |
76 |
77 |
78 | 79 |
80 | 81 |
82 |
83 | 84 |
85 | 86 |
87 | 92 |
93 |
94 | 95 |
96 | 97 |
98 | 99 |
100 |
101 | 102 |
103 |
104 |
105 | 106 | <%@ include file="footer.jsp"%> 107 | 108 | 121 | 122 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/update_avatar.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Genesis ›头像上传 11 | 12 | 13 | 14 | <%@ include file="header.jsp"%> 15 | 16 |
17 |
18 |
19 | Genesis › 设置 ›头像上传 20 |
21 | 22 |
23 | 24 |
25 |
26 | 27 | 28 |
29 | 30 |
31 |
32 | 33 |
34 | 35 |
36 | 37 | 38 | 39 |
40 | 41 | 42 | <%@ include file="side.jsp"%> 43 | 44 | 45 | <%@ include file="footer.jsp"%> 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/user_info.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Genesis › <c:if test="${!empty userInfo}">${userInfo.username}</c:if><c:if test="${!empty errorInfo}">会员未找到</c:if> 11 | 12 | 13 | 14 | <%@ include file="header.jsp"%> 15 | 16 |
17 |
18 |
19 | Genesis › ${userInfo.username} 20 |
21 | 22 |
23 | 24 |
25 |
26 | 27 |

28 |
29 | 30 |
31 |

${userInfo.id}

32 |
33 |
34 |
35 | 36 |
37 |

${userInfo.username}

38 |
39 |
40 |
41 | 42 |
43 |

${userInfo.email}

44 |
45 |
46 |
47 | 48 |
49 |

${userInfo.localCreateTime}

50 |
51 |
52 |
53 | 54 |
55 |

${userInfo.credit}

56 |
57 |
58 |
59 |
60 | 61 | 会员未找到! 62 | 63 |
64 |
65 |
66 | 67 | 68 | <%@ include file="side.jsp"%> 69 | 70 | 71 | <%@ include file="footer.jsp"%> 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/main-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | /common/error_fileupload 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | contextConfigLocation 11 | classpath:applicationContext.xml 12 | 13 | 14 | 15 | 16 | org.springframework.web.context.ContextLoaderListener 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | main 25 | 26 | org.springframework.web.servlet.DispatcherServlet 27 | 28 | 1 29 | 30 | 31 | 32 | main 33 | / 34 | 35 | 36 | CORSFilter 37 | com.withstars.intercepter.CORSFilter 38 | 39 | 40 | CORSFilter 41 | /* 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/static/css/front-common.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | font-size: 14px; 4 | color: #525252; 5 | font-family: NotoSansHans-Regular,AvenirNext-Regular,arial,Hiragino Sans GB,"Microsoft Yahei","Hiragino Sans GB","WenQuanYi Micro Hei",sans-serif; 6 | background: #f0f2f5; 7 | } -------------------------------------------------------------------------------- /src/main/webapp/static/css/front-footer.css: -------------------------------------------------------------------------------- 1 | li {list-style-type:none;} 2 | html, body { 3 | height: 100%; 4 | font-size: 14px; 5 | color: #525252; 6 | font-family: NotoSansHans-Regular,AvenirNext-Regular,arial,Hiragino Sans GB,"Microsoft Yahei","Hiragino Sans GB","WenQuanYi Micro Hei",sans-serif; 7 | background: #f0f2f5; 8 | } 9 | .footer { 10 | background-color: #fff; 11 | margin-top: 22px; 12 | margin-bottom: 22px; 13 | width: 100%; 14 | padding-top: 22px; 15 | color: #8A8A8A; 16 | display: block; 17 | height: 200px; 18 | border: 1px ; 19 | } 20 | 21 | .container { 22 | margin-right: 5%; 23 | margin-left: 5%; 24 | padding-left: 15px; 25 | padding-right: 15px; 26 | width: 40%; 27 | float: left; 28 | } 29 | .info { 30 | margin-right: 5%; 31 | width: 10%; 32 | float: left; 33 | } 34 | a{ 35 | color: #8A8A8A; 36 | cursor: pointer; 37 | } -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/1521949392720-2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/1521949392720-2.PNG -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-1.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-10.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-2.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-3.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-4.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-5.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-6.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-7.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-8.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/avatar/avatar-default-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/withstars/Genesis/5a8bee1df4e9b45ea4fe0e93251477e71716a9c9/src/main/webapp/static/img/avatar/avatar-default-9.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/icon/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Svg Vector Icons : http://www.sfont.cn 6 | 7 | -------------------------------------------------------------------------------- /src/main/webapp/static/img/icon/magnifying-glass.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/static/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.7 (http://getbootstrap.com) 3 | * Copyright 2011-2016 Twitter, Inc. 4 | * Licensed under the MIT license 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); -------------------------------------------------------------------------------- /src/main/webapp/static/js/js.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JavaScript Cookie v2.1.4 3 | * https://github.com/js-cookie/js-cookie 4 | * 5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack 6 | * Released under the MIT license 7 | */ 8 | ;(function (factory) { 9 | var registeredInModuleLoader = false; 10 | if (typeof define === 'function' && define.amd) { 11 | define(factory); 12 | registeredInModuleLoader = true; 13 | } 14 | if (typeof exports === 'object') { 15 | module.exports = factory(); 16 | registeredInModuleLoader = true; 17 | } 18 | if (!registeredInModuleLoader) { 19 | var OldCookies = window.Cookies; 20 | var api = window.Cookies = factory(); 21 | api.noConflict = function () { 22 | window.Cookies = OldCookies; 23 | return api; 24 | }; 25 | } 26 | }(function () { 27 | function extend () { 28 | var i = 0; 29 | var result = {}; 30 | for (; i < arguments.length; i++) { 31 | var attributes = arguments[ i ]; 32 | for (var key in attributes) { 33 | result[key] = attributes[key]; 34 | } 35 | } 36 | return result; 37 | } 38 | 39 | function init (converter) { 40 | function api (key, value, attributes) { 41 | var result; 42 | if (typeof document === 'undefined') { 43 | return; 44 | } 45 | 46 | // Write 47 | 48 | if (arguments.length > 1) { 49 | attributes = extend({ 50 | path: '/' 51 | }, api.defaults, attributes); 52 | 53 | if (typeof attributes.expires === 'number') { 54 | var expires = new Date(); 55 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); 56 | attributes.expires = expires; 57 | } 58 | 59 | // We're using "expires" because "max-age" is not supported by IE 60 | attributes.expires = attributes.expires ? attributes.expires.toUTCString() : ''; 61 | 62 | try { 63 | result = JSON.stringify(value); 64 | if (/^[\{\[]/.test(result)) { 65 | value = result; 66 | } 67 | } catch (e) {} 68 | 69 | if (!converter.write) { 70 | value = encodeURIComponent(String(value)) 71 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 72 | } else { 73 | value = converter.write(value, key); 74 | } 75 | 76 | key = encodeURIComponent(String(key)); 77 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); 78 | key = key.replace(/[\(\)]/g, escape); 79 | 80 | var stringifiedAttributes = ''; 81 | 82 | for (var attributeName in attributes) { 83 | if (!attributes[attributeName]) { 84 | continue; 85 | } 86 | stringifiedAttributes += '; ' + attributeName; 87 | if (attributes[attributeName] === true) { 88 | continue; 89 | } 90 | stringifiedAttributes += '=' + attributes[attributeName]; 91 | } 92 | return (document.cookie = key + '=' + value + stringifiedAttributes); 93 | } 94 | 95 | // Read 96 | 97 | if (!key) { 98 | result = {}; 99 | } 100 | 101 | // To prevent the for loop in the first place assign an empty array 102 | // in case there are no cookies at all. Also prevents odd result when 103 | // calling "get()" 104 | var cookies = document.cookie ? document.cookie.split('; ') : []; 105 | var rdecode = /(%[0-9A-Z]{2})+/g; 106 | var i = 0; 107 | 108 | for (; i < cookies.length; i++) { 109 | var parts = cookies[i].split('='); 110 | var cookie = parts.slice(1).join('='); 111 | 112 | if (cookie.charAt(0) === '"') { 113 | cookie = cookie.slice(1, -1); 114 | } 115 | 116 | try { 117 | var name = parts[0].replace(rdecode, decodeURIComponent); 118 | cookie = converter.read ? 119 | converter.read(cookie, name) : converter(cookie, name) || 120 | cookie.replace(rdecode, decodeURIComponent); 121 | 122 | if (this.json) { 123 | try { 124 | cookie = JSON.parse(cookie); 125 | } catch (e) {} 126 | } 127 | 128 | if (key === name) { 129 | result = cookie; 130 | break; 131 | } 132 | 133 | if (!key) { 134 | result[name] = cookie; 135 | } 136 | } catch (e) {} 137 | } 138 | 139 | return result; 140 | } 141 | 142 | api.set = api; 143 | api.get = function (key) { 144 | return api.call(api, key); 145 | }; 146 | api.getJSON = function () { 147 | return api.apply({ 148 | json: true 149 | }, [].slice.call(arguments)); 150 | }; 151 | api.defaults = {}; 152 | 153 | api.remove = function (key, attributes) { 154 | api(key, '', extend(attributes, { 155 | expires: -1 156 | })); 157 | }; 158 | 159 | api.withConverter = init; 160 | 161 | return api; 162 | } 163 | 164 | return init(function () {}); 165 | })); 166 | --------------------------------------------------------------------------------