├── .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 |
6 |
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 |
15 | select
16 |
17 | from login_log
18 | where id = #{id,jdbcType=BIGINT}
19 |
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 |
24 | SELECT reply.*,user.username,user.avatar
25 | from reply,user
26 | where reply.reply_user_id = user.id and reply.topic_id = #{topicId,jdbcType=INTEGER}
27 | order by create_time ASC ;
28 |
29 |
30 |
31 | SELECT count(id)
32 | FROM reply
33 | WHERE topic_id = #{topicId,jdbcType=INTEGER}
34 |
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 |
16 | select
17 | *
18 | from tab
19 | ORDER BY id ASC
20 |
21 |
22 |
23 | select
24 |
25 | from tab
26 | where id = #{id,jdbcType=INTEGER}
27 |
28 |
29 |
30 | select
31 |
32 | from tab
33 | where tab_name_en = #{tabNameEn,jdbcType=VARCHAR}
34 |
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 |
65 |
66 |
67 | id, user_id, create_time, update_time, title, click, tab_id
68 |
69 |
70 |
71 | content
72 |
73 |
74 |
75 | select topic.id,topic.user_id,topic.create_time,topic.update_time,topic.title,topic.click,topic.tab_id,user.username,user.avatar ,
76 | tab.tab_name,count(reply.id) as count_replies from topic LEFT JOIN user on topic.user_id = user.id
77 | LEFT JOIN tab on tab.id=topic.tab_id LEFT JOIN reply on topic.id=reply.topic_id
78 | group by topic.id order by topic.id desc ;
79 |
80 |
81 |
82 | select topic.id,topic.user_id,topic.create_time,topic.update_time,topic.title,topic.click,topic.tab_id,user.username,user.avatar ,
83 | tab.tab_name,count(reply.id) as count_replies from topic LEFT JOIN user on topic.user_id = user.id
84 | LEFT JOIN tab on tab.id=topic.tab_id LEFT JOIN reply on topic.id=reply.topic_id where tab.id = #{id,jdbcType=INTEGER}
85 | group by topic.id order by topic.id desc ;
86 |
87 |
88 |
89 | SELECT topic.*,user.username,user.avatar from topic,user where topic.user_id = user.id and topic.id = #{id,jdbcType=INTEGER};
90 |
91 |
92 |
93 |
94 |
95 | select
96 |
97 | from topic
98 | ORDER BY id DESC
99 |
100 |
101 |
102 | select
103 | COUNT(*)
104 | from topic
105 |
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 |
23 | select
24 |
25 | from user
26 | where id = #{id,jdbcType=INTEGER}
27 |
28 |
29 |
30 | select
31 | count(*)
32 | from user
33 |
34 |
35 |
36 |
37 | select
38 |
39 | from user
40 | where username = #{username,jdbcType=VARCHAR}
41 |
42 |
43 |
44 | SELECT count(*) from user where username = #{username,jdbcType=VARCHAR}
45 |
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 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
77 |
78 | ${topic.countReplies}
79 |
80 |
81 |
82 |
83 |
84 |
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 |
23 |
${topic.title}
24 |
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 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 添加一条新回复
85 |
86 |
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 |
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 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 | class="active" >技术
16 |
17 | class="active"
18 | >好玩
19 | class="active"
20 | >创意
21 | class="active"
22 | >工作
23 | class="active"
24 | >交易
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | 登录
33 |
34 |
35 | 注册
36 |
37 |
38 |
39 |
40 |
41 |
55 |
56 |
57 |
58 |
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 |
53 |
54 |
55 |
75 |
76 |
77 |
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 |
21 |
22 |
23 |
24 |
25 |
29 |
35 |
41 |
47 |
53 |
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 |
22 |
23 |
24 |
25 |
26 |
36 |
37 |
38 |
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 |
74 | 记住密码
75 |
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 |
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 |
21 |
22 |
23 |
24 |
25 |
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 › ${userInfo.username} 会员未找到
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 |
34 |
40 |
46 |
52 |
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 |
--------------------------------------------------------------------------------