├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── db.sql ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── pengchaoling │ │ ├── SnsApplication.java │ │ ├── async │ │ ├── EventHandler.java │ │ ├── EventModel.java │ │ ├── EventProducer.java │ │ ├── EventType.java │ │ └── handler │ │ │ ├── AddUserHandler.java │ │ │ ├── AddWeiboHandler.java │ │ │ ├── AtmeHandler.java │ │ │ ├── EventConsumer.java │ │ │ ├── FeedHandler.java │ │ │ ├── FollowHandler.java │ │ │ └── LikeHandler.java │ │ ├── configuration │ │ ├── MyBatisConfig.java │ │ └── SnsWebConfiguration.java │ │ ├── controller │ │ ├── CommontController.java │ │ ├── FollowController.java │ │ ├── IndexController.java │ │ ├── LikeController.java │ │ ├── LoginController.java │ │ ├── MessageController.java │ │ ├── SearchController.java │ │ ├── UploadFileController.java │ │ ├── UserController.java │ │ ├── UserSettingController.java │ │ └── WeiboController.java │ │ ├── dao │ │ ├── AtmeDAO.java │ │ ├── CommentDAO.java │ │ ├── FeedDAO.java │ │ ├── FocusGroupDAO.java │ │ ├── KeepDAO.java │ │ ├── LoginTicketDAO.java │ │ ├── MessageDAO.java │ │ ├── PictureDAO.java │ │ ├── UserDAO.java │ │ ├── UserInfoDAO.java │ │ └── WeiboDAO.java │ │ ├── interceptor │ │ ├── LoginRequiredInterceptor.java │ │ └── PassportInterceptor.java │ │ ├── model │ │ ├── Atme.java │ │ ├── Comment.java │ │ ├── EntityType.java │ │ ├── Feed.java │ │ ├── FocusGroup.java │ │ ├── HostHolder.java │ │ ├── Keep.java │ │ ├── LoginTicket.java │ │ ├── Message.java │ │ ├── Picture.java │ │ ├── User.java │ │ ├── UserInfo.java │ │ ├── ViewObject.java │ │ └── Weibo.java │ │ ├── service │ │ ├── AtmeService.java │ │ ├── CommentService.java │ │ ├── FeedService.java │ │ ├── FocusGroupService.java │ │ ├── FollowService.java │ │ ├── LikeService.java │ │ ├── MessageService.java │ │ ├── SearchService.java │ │ ├── SensitiveService.java │ │ ├── UserInfoService.java │ │ ├── UserService.java │ │ └── WeiboService.java │ │ └── util │ │ ├── JedisAdapter.java │ │ ├── RedisKeyUtil.java │ │ └── SnsUtil.java └── resources │ ├── SensitiveWords.txt │ ├── application.properties │ ├── mybatis-config.xml │ ├── static │ ├── Css │ │ ├── common.css │ │ ├── login.css │ │ └── regis.css │ ├── Images │ │ ├── checked.gif │ │ ├── default.jpg │ │ ├── loading.gif │ │ ├── login_bg_fom.png │ │ ├── login_top_bg.png │ │ ├── logo.png │ │ ├── noface.gif │ │ ├── phiz │ │ │ ├── aini.gif │ │ │ ├── baibai.gif │ │ │ ├── baobao.gif │ │ │ ├── beishuang.gif │ │ │ ├── bishi.gif │ │ │ ├── bizui.gif │ │ │ ├── canzui.gif │ │ │ ├── chijing.gif │ │ │ ├── dahaqian.gif │ │ │ ├── guzhang.gif │ │ │ ├── haha.gif │ │ │ ├── haixiu.gif │ │ │ ├── han.gif │ │ │ ├── hehe.gif │ │ │ ├── heixian.gif │ │ │ ├── heng.gif │ │ │ ├── huaxin.gif │ │ │ ├── jiyan.gif │ │ │ ├── keai.gif │ │ │ ├── kelian.gif │ │ │ ├── ku.gif │ │ │ ├── kun.gif │ │ │ ├── ldln.gif │ │ │ ├── lei.gif │ │ │ ├── nu.gif │ │ │ ├── numa.gif │ │ │ ├── qian.gif │ │ │ ├── qinqin.gif │ │ │ ├── shengbin.gif │ │ │ ├── shiwang.gif │ │ │ ├── shuai.gif │ │ │ ├── shuangxin.gif │ │ │ ├── shuijiao.gif │ │ │ ├── sikao.gif │ │ │ ├── taikaixin.gif │ │ │ ├── touxiao.gif │ │ │ ├── tu.gif │ │ │ ├── wabisi.gif │ │ │ ├── weiqu.gif │ │ │ ├── xin.gif │ │ │ ├── xiu.gif │ │ │ ├── xixi.gif │ │ │ ├── yinxian.gif │ │ │ ├── yiwen.gif │ │ │ ├── youhenhen.gif │ │ │ ├── yun.gif │ │ │ ├── zuakuang.gif │ │ │ └── zuohenhen.gif │ │ ├── regis_bg.png │ │ ├── style2.jpg │ │ ├── style3.jpg │ │ ├── style4.jpg │ │ └── unchecked.gif │ ├── Js │ │ ├── DD_belatedPNG_0.0.8a-min.js │ │ ├── city.js │ │ ├── comment.js │ │ ├── edit.js │ │ ├── index.js │ │ ├── jquery-1.7.2.min.js │ │ ├── jquery-validate.js │ │ ├── letter.js │ │ ├── login.js │ │ ├── nav.js │ │ ├── register.js │ │ ├── sech-weibo.js │ │ └── weibo-list.js │ ├── Theme │ │ └── default │ │ │ ├── Css │ │ │ ├── bottom.css │ │ │ ├── comment.css │ │ │ ├── common.css │ │ │ ├── edit.css │ │ │ ├── index.css │ │ │ ├── letter.css │ │ │ ├── list.css │ │ │ ├── nav.css │ │ │ ├── sech_user.css │ │ │ ├── sech_weibo.css │ │ │ ├── user.css │ │ │ └── weibo_list.css │ │ │ └── Images │ │ │ ├── big.cur │ │ │ ├── body_bg.jpg │ │ │ ├── bottom_logo.gif │ │ │ ├── icon.png │ │ │ ├── line.png │ │ │ ├── logo.png │ │ │ ├── main_bg.png │ │ │ ├── main_bg2.png │ │ │ ├── nav_bg.png │ │ │ ├── sech_logo.png │ │ │ ├── send_weibo.png │ │ │ ├── small.cur │ │ │ ├── top_bg.png │ │ │ └── user_bg.jpg │ └── Uploadify │ │ ├── browse-btn.png │ │ ├── jquery.uploadify.min.js │ │ ├── uploadify-cancel.png │ │ ├── uploadify.css │ │ └── uploadify.swf │ ├── templates │ ├── UserSetting.html │ ├── atme.html │ ├── common │ │ ├── bottom.html │ │ ├── header.html │ │ ├── left.html │ │ ├── nav.html │ │ └── right.html │ ├── dispatch_jump.html │ ├── index.html │ ├── letter.html │ ├── letterDetail.html │ ├── login.html │ ├── profile.html │ ├── register.html │ ├── searchUser.html │ ├── searchWeibo.html │ └── square.html │ └── toolbox.xml └── test └── java └── com └── pengchaoling └── SnsApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip 2 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.pengchaoling 7 | sns 8 | 1 9 | jar 10 | 11 | sns 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.3.8.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | com.alibaba 30 | fastjson 31 | 1.2.83 32 | 33 | 34 | 35 | com.github.pagehelper 36 | pagehelper 37 | 5.3.1 38 | 39 | 40 | 41 | redis.clients 42 | jedis 43 | 2.9.0 44 | jar 45 | compile 46 | 47 | 48 | 49 | org.apache.solr 50 | solr-solrj 51 | 6.2.0 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-aop 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-velocity 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-web 64 | 65 | 66 | mysql 67 | mysql-connector-java 68 | runtime 69 | 70 | 71 | org.mybatis.spring.boot 72 | mybatis-spring-boot-starter 73 | 1.1.1 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-devtools 78 | runtime 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-starter-test 83 | test 84 | 85 | 86 | 87 | 88 | 89 | 90 | org.springframework.boot 91 | spring-boot-maven-plugin 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-compiler-plugin 97 | 98 | 1.8 99 | 1.8 100 | UTF-8 101 | 102 | 103 | D:\Program Files\Java\jdk1.8.0_20\jre\lib\rt.jar;D:\Program Files\Java\jdk1.8.0_20\jre\lib\jce.jar 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/SnsApplication.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.context.web.SpringBootServletInitializer; 7 | 8 | @SpringBootApplication 9 | public class SnsApplication extends SpringBootServletInitializer { 10 | 11 | @Override 12 | protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 13 | return builder.sources(SnsApplication.class); 14 | } 15 | 16 | 17 | public static void main(String[] args) { 18 | 19 | SpringApplication.run(SnsApplication.class, args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-21 8 | * description: 事件处理接口,提供规范 9 | */ 10 | public interface EventHandler { 11 | //处理事件 12 | void doHandle(EventModel model); 13 | //注册事件类型,这里存的事件都会去调用前面的doHandle方法 14 | List getSupportEventTypes(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/EventModel.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-21 8 | * description: 时间发送的现场 9 | */ 10 | public class EventModel { 11 | 12 | private EventType type; //事件类型 假如这是评论 13 | private int actorId; //触发者 这是谁评论了 14 | private int entityType; //触发的载体类型 是指评论 15 | private int entityId; //触发的id 评论id 16 | private int entityOwnerId; //接受者 17 | 18 | //扩展字段,可以用于存当时的一些状态 19 | private Map exts = new HashMap(); 20 | 21 | public EventModel() { 22 | 23 | } 24 | 25 | public EventModel setExt(String key, String value) { 26 | exts.put(key, value); 27 | //用this是为了便于链式操作 直接返回的是一个对象 28 | return this; 29 | } 30 | 31 | public EventModel(EventType type) { 32 | this.type = type; 33 | } 34 | 35 | public String getExt(String key) { 36 | return exts.get(key); 37 | } 38 | 39 | 40 | public EventType getType() { 41 | return type; 42 | } 43 | 44 | public EventModel setType(EventType type) { 45 | this.type = type; 46 | return this; 47 | } 48 | 49 | public int getActorId() { 50 | return actorId; 51 | } 52 | 53 | public EventModel setActorId(int actorId) { 54 | this.actorId = actorId; 55 | return this; 56 | } 57 | 58 | public int getEntityType() { 59 | return entityType; 60 | } 61 | 62 | public EventModel setEntityType(int entityType) { 63 | this.entityType = entityType; 64 | return this; 65 | } 66 | 67 | public int getEntityId() { 68 | return entityId; 69 | } 70 | 71 | public EventModel setEntityId(int entityId) { 72 | this.entityId = entityId; 73 | return this; 74 | } 75 | 76 | public int getEntityOwnerId() { 77 | return entityOwnerId; 78 | } 79 | 80 | public EventModel setEntityOwnerId(int entityOwnerId) { 81 | this.entityOwnerId = entityOwnerId; 82 | return this; 83 | } 84 | 85 | public Map getExts() { 86 | return exts; 87 | } 88 | 89 | public EventModel setExts(Map exts) { 90 | this.exts = exts; 91 | return this; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/EventProducer.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.pengchaoling.util.JedisAdapter; 5 | import com.pengchaoling.util.RedisKeyUtil; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.concurrent.ArrayBlockingQueue; 10 | import java.util.concurrent.BlockingQueue; 11 | 12 | /** 13 | * Author: Lying 14 | * Data: 2017-02-21 15 | * description: 时间的入口,生产者,用于插入事件队列 16 | */ 17 | @Service 18 | public class EventProducer { 19 | @Autowired 20 | JedisAdapter jedisAdapter; 21 | 22 | /** 23 | * 插入队列 24 | */ 25 | public boolean fireEvent(EventModel eventModel) { 26 | try { 27 | //把对象序列化之后放进队列 28 | String json = JSONObject.toJSONString(eventModel); 29 | String key = RedisKeyUtil.getEventQueueKey(); 30 | jedisAdapter.lpush(key, json); 31 | return true; 32 | } catch (Exception e) { 33 | return false; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/EventType.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async; 2 | 3 | /** 4 | * Author: Lying 5 | * Data: 2017-02-21 6 | * description: 事件类型 7 | */ 8 | public enum EventType { 9 | LIKE(0), //点赞 10 | COMMENT(1), //评论 11 | WEIBO(2), //微博 12 | MAIL(3), //邮件 13 | FOLLOW(4), //关注 14 | UNFOLLOW(5), //取消关注 15 | ADDWEIBO(6), //新增微博 16 | ADDUSER(7), //增加用户 17 | ADDCOMMENT(8), //增加评论 18 | TURNWEIBO(9); //转发微博 19 | 20 | private int value; 21 | EventType(int value) { this.value = value; } 22 | public int getValue() { return value; } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/AddUserHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.pengchaoling.async.EventHandler; 4 | import com.pengchaoling.async.EventModel; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.service.SearchService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * Author: Lying 17 | * Data: 2017-02-24 18 | * description: 新增用户 新增索引 19 | */ 20 | @Component 21 | public class AddUserHandler implements EventHandler { 22 | private static final Logger logger = LoggerFactory.getLogger(AddUserHandler.class); 23 | @Autowired 24 | SearchService searchService; 25 | 26 | @Override 27 | public void doHandle(EventModel model) { 28 | try { 29 | searchService.indexUserInfo(model.getActorId(),model.getEntityId(), 30 | model.getExt("nickname")); 31 | } catch (Exception e) { 32 | logger.error("增加微博索引失败"); 33 | } 34 | } 35 | 36 | @Override 37 | public List getSupportEventTypes() { 38 | return Arrays.asList(EventType.ADDUSER); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/AddWeiboHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.pengchaoling.async.EventHandler; 4 | import com.pengchaoling.async.EventModel; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.service.SearchService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * Author: Lying 17 | * Data: 2017-02-24 18 | * description: 新增微博的时候新增索引 19 | */ 20 | @Component 21 | public class AddWeiboHandler implements EventHandler { 22 | private static final Logger logger = LoggerFactory.getLogger(AddWeiboHandler.class); 23 | @Autowired 24 | SearchService searchService; 25 | 26 | @Override 27 | public void doHandle(EventModel model) { 28 | try { 29 | searchService.indexWeibo(model.getEntityId(), 30 | model.getExt("content")); 31 | } catch (Exception e) { 32 | logger.error("增加微博索引失败"); 33 | } 34 | } 35 | 36 | @Override 37 | public List getSupportEventTypes() { 38 | return Arrays.asList(EventType.ADDWEIBO); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/AtmeHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.pengchaoling.async.EventHandler; 4 | import com.pengchaoling.async.EventModel; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.model.Atme; 7 | import com.pengchaoling.model.UserInfo; 8 | import com.pengchaoling.service.AtmeService; 9 | import com.pengchaoling.service.UserInfoService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Component; 14 | 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.regex.Matcher; 18 | import java.util.regex.Pattern; 19 | 20 | /** 21 | * Author: Lying 22 | * Data: 2017-02-25 23 | * description: 艾特用户异步事件处理 24 | */ 25 | @Component 26 | public class AtmeHandler implements EventHandler { 27 | private static final Logger logger = LoggerFactory.getLogger(AtmeHandler.class); 28 | @Autowired 29 | AtmeService atmeService; 30 | 31 | @Autowired 32 | UserInfoService userInfoService; 33 | 34 | @Override 35 | public void doHandle(EventModel model) { 36 | try { 37 | String content = model.getExt("content"); 38 | //正则表达式匹配出所有AT用户 39 | Pattern pt = Pattern.compile("@(([\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]|[a-zA-Z])+(|\\s|,|。|?|;|!|‘|’|“|”)+?)"); 40 | Matcher mt = pt.matcher(content); 41 | while (mt.find()) { 42 | UserInfo userInfo = userInfoService.getUserInfoByNickname(mt.group().replace("@","")); 43 | if(userInfo != null){ 44 | Atme atme = new Atme(); 45 | atme.setUid(userInfo.getUid()); 46 | atme.setEntityType(model.getEntityType()); 47 | atme.setEntityId(model.getEntityId()); 48 | atmeService.addAtme(atme); 49 | } 50 | } 51 | 52 | } catch (Exception e) { 53 | logger.error("增加艾特用户引失败"); 54 | } 55 | } 56 | 57 | @Override 58 | public List getSupportEventTypes() { 59 | return Arrays.asList(new EventType[]{EventType.ADDCOMMENT, EventType.ADDWEIBO}); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/EventConsumer.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.pengchaoling.async.EventHandler; 5 | import com.pengchaoling.async.EventModel; 6 | import com.pengchaoling.async.EventType; 7 | import com.pengchaoling.util.JedisAdapter; 8 | import com.pengchaoling.util.RedisKeyUtil; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.BeansException; 12 | import org.springframework.beans.factory.InitializingBean; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.context.ApplicationContext; 15 | import org.springframework.context.ApplicationContextAware; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.concurrent.ExecutorService; 23 | import java.util.concurrent.Executors; 24 | 25 | /** 26 | * Author: Lying 27 | * Data: 2017-02-21 28 | * description: 处理队列里面的事件,一手取出并分发事件到各个Handeler 29 | * ApplicationContext 这个类可以直接获取spring配置文件中,所有有引用到的bean对象。 30 | */ 31 | @Service 32 | public class EventConsumer implements InitializingBean, ApplicationContextAware { 33 | private static final Logger logger = LoggerFactory.getLogger(EventConsumer.class); 34 | //事件以及对应的Handler 35 | private Map> config = new HashMap>(); 36 | //用于事件同步, 37 | private ApplicationContext applicationContext; 38 | 39 | @Autowired 40 | JedisAdapter jedisAdapter; 41 | 42 | /* 43 | * Spring 初始化时候会自动调用 44 | */ 45 | @Override 46 | public void afterPropertiesSet() throws Exception { 47 | //引入所有的 实现了 EwentHandler接口的类 相当于从容器里面获取 48 | Map beans = applicationContext.getBeansOfType(EventHandler.class); 49 | if (beans != null) { 50 | for (Map.Entry entry : beans.entrySet()) { 51 | //获取到的这些handler分别是什么类型的,以下代码就是把这些handler 组装到 map里面 52 | List eventTypes = entry.getValue().getSupportEventTypes(); 53 | //事件注册 弄进这个map里面 54 | for (EventType type : eventTypes) { 55 | if (!config.containsKey(type)) { 56 | config.put(type, new ArrayList()); 57 | } 58 | config.get(type).add(entry.getValue()); 59 | } 60 | } 61 | } 62 | 63 | Runnable run = new Runnable() { 64 | @Override 65 | public void run() { 66 | //取队列 67 | while(true) { 68 | String key = RedisKeyUtil.getEventQueueKey(); 69 | //从redis的队列里面取事件 brpop :取队列里面的东西,如果没有的话就卡着 70 | List events = jedisAdapter.brpop(0, key); 71 | 72 | //已经取出了事件,然后去找他们的handler去处理 73 | for (String message : events) { 74 | if (message.equals(key)) { 75 | continue; 76 | } 77 | //反序列化 解析出原来的事件 78 | EventModel eventModel = JSON.parseObject(message, EventModel.class); 79 | //判断是否包含键名 80 | if (!config.containsKey(eventModel.getType())) { 81 | logger.error("不能识别的事件"); 82 | continue; 83 | } 84 | //调用相关的handler去执行 85 | for (EventHandler handler : config.get(eventModel.getType())) { 86 | handler.doHandle(eventModel); 87 | } 88 | } 89 | } 90 | } 91 | }; 92 | 93 | //创建一个可重用固定线程数的线程池 94 | ExecutorService pool = Executors.newCachedThreadPool(); 95 | Thread t1 = new Thread(run); 96 | Thread t2 = new Thread(run); 97 | Thread t3 = new Thread(run); 98 | Thread t4 = new Thread(run); 99 | Thread t5 = new Thread(run); 100 | //将线程放入池中进行执行 101 | pool.execute(t1); 102 | pool.execute(t2); 103 | pool.execute(t3); 104 | pool.execute(t4); 105 | pool.execute(t5); 106 | //关闭线程池 107 | pool.shutdown(); 108 | 109 | } 110 | 111 | @Override 112 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 113 | this.applicationContext = applicationContext; 114 | } 115 | } -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/FeedHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.pengchaoling.async.EventHandler; 5 | import com.pengchaoling.async.EventModel; 6 | import com.pengchaoling.async.EventType; 7 | import com.pengchaoling.model.EntityType; 8 | import com.pengchaoling.model.Feed; 9 | import com.pengchaoling.model.UserInfo; 10 | import com.pengchaoling.service.*; 11 | import com.pengchaoling.util.JedisAdapter; 12 | import com.pengchaoling.util.RedisKeyUtil; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Component; 17 | 18 | import java.util.*; 19 | 20 | /** 21 | * Author: Lying 22 | * Data: 2017-02-23 23 | * description: feed异步事件处理 用与时间线 24 | */ 25 | @Component 26 | public class FeedHandler implements EventHandler { 27 | private static final Logger logger = LoggerFactory.getLogger(AtmeHandler.class); 28 | 29 | @Autowired 30 | FollowService followService; 31 | 32 | @Autowired 33 | UserService userService; 34 | 35 | @Autowired 36 | UserInfoService userInfoService; 37 | 38 | @Autowired 39 | FeedService feedService; 40 | 41 | @Autowired 42 | JedisAdapter jedisAdapter; 43 | 44 | @Autowired 45 | WeiboService weiboService; 46 | 47 | 48 | private String buildFeedData(EventModel model) { 49 | Map map = new HashMap(); 50 | // 触发用户是通用的 51 | UserInfo actor = userInfoService.getUserInfoByUid(model.getActorId()); 52 | if (actor == null) { 53 | logger.error("这里就U型了"); 54 | return null; 55 | } 56 | map.put("uid", String.valueOf(actor.getUid())); 57 | map.put("nickname", actor.getNickname()); 58 | //这是事件的类型 59 | if(model.getType()== EventType.FOLLOW){ 60 | map.put("message","关注了用户"); 61 | return JSONObject.toJSONString(map); 62 | }else if(model.getType()== EventType.LIKE){ 63 | map.put("message","赞了微博"); 64 | return JSONObject.toJSONString(map); 65 | }else if(model.getType()==EventType.ADDCOMMENT){ 66 | map.put("message","评论了微博"); 67 | return JSONObject.toJSONString(map); 68 | }else if(model.getType()==EventType.ADDWEIBO){ 69 | map.put("message","发布了微博"); 70 | return JSONObject.toJSONString(map); 71 | }else if(model.getType()==EventType.TURNWEIBO){ 72 | map.put("message","转发了微博"); 73 | return JSONObject.toJSONString(map); 74 | } 75 | 76 | return null; 77 | } 78 | 79 | @Override 80 | public void doHandle(EventModel model) { 81 | try{ 82 | 83 | // 构造一个新鲜事 84 | Feed feed = new Feed(); 85 | feed.setCreatedDate(new Date()); 86 | feed.setEvenType(model.getType().getValue()); 87 | feed.setEntityType(model.getEntityType()); 88 | feed.setEntityId(model.getEntityId()); 89 | feed.setUid(model.getActorId()); 90 | //厉害了 91 | feed.setData(buildFeedData(model)); 92 | 93 | if (feed.getData() == null) { 94 | // 不支持的feed 95 | return; 96 | } 97 | //如果插入成功才执行下面的 98 | if(feedService.addFeed(feed)) { 99 | 100 | // 获得所有粉丝额,其实这里还没有完善 只获取一百多个目前,后面需要完善 101 | List followers = followService.getFollowers(EntityType.ENTITY_USER, model.getActorId(), Integer.MAX_VALUE); 102 | //把自己也加进去,意思是自己发布东西也会插入到自己的时间线里面 103 | followers.add(model.getActorId()); 104 | // 给所有粉丝推事件 105 | for (int follower : followers) { 106 | String timelineKey = RedisKeyUtil.getTimelineKey(follower); 107 | jedisAdapter.lpush(timelineKey, String.valueOf(feed.getId())); 108 | // 限制最长长度,如果timelineKey的长度过大,就删除后面的新鲜事 109 | long len = jedisAdapter.llen(timelineKey); 110 | if (len > 100) { 111 | //删除了后面10条,这样就不需要每次超过就删一条,效率高一点 112 | jedisAdapter.ltrim(timelineKey, 0, 10); 113 | } 114 | 115 | } 116 | } 117 | }catch (Exception e){ 118 | e.printStackTrace(); 119 | } 120 | } 121 | 122 | @Override 123 | public List getSupportEventTypes() { 124 | return Arrays.asList(new EventType[]{EventType.LIKE, EventType.FOLLOW,EventType.ADDCOMMENT,EventType.ADDWEIBO,EventType.TURNWEIBO}); 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/FollowHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.pengchaoling.async.EventHandler; 4 | import com.pengchaoling.async.EventModel; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.model.EntityType; 7 | import com.pengchaoling.model.Message; 8 | import com.pengchaoling.model.UserInfo; 9 | import com.pengchaoling.service.MessageService; 10 | import com.pengchaoling.service.UserInfoService; 11 | import com.pengchaoling.service.UserService; 12 | import com.pengchaoling.util.SnsUtil; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Component; 15 | 16 | import java.util.Arrays; 17 | import java.util.Date; 18 | import java.util.List; 19 | 20 | /** 21 | * Author: Lying 22 | * Data: 2017-02-22 23 | * description:关注事件处理 发站内信 24 | */ 25 | @Component 26 | public class FollowHandler implements EventHandler { 27 | @Autowired 28 | MessageService messageService; 29 | 30 | @Autowired 31 | UserService userService; 32 | 33 | @Autowired 34 | UserInfoService userInfoService; 35 | 36 | @Override 37 | public void doHandle(EventModel model) { 38 | try{ 39 | Message message = new Message(); 40 | message.setFromId(SnsUtil.SYSTEM_USERID); 41 | message.setToId(model.getEntityOwnerId()); 42 | message.setCreatedDate(new Date()); 43 | message.setHasRead(0); 44 | UserInfo userInfo = userInfoService.getUserInfoByUid(model.getActorId()); 45 | message.setContent(userInfo.getNickname() + "关注了你"); 46 | messageService.addMessage(message); 47 | }catch (Exception e){ 48 | e.printStackTrace(); 49 | } 50 | } 51 | 52 | @Override 53 | public List getSupportEventTypes() { 54 | return Arrays.asList(EventType.FOLLOW); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/async/handler/LikeHandler.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.async.handler; 2 | 3 | import com.pengchaoling.async.EventHandler; 4 | import com.pengchaoling.async.EventModel; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.model.Message; 7 | import com.pengchaoling.model.UserInfo; 8 | import com.pengchaoling.service.MessageService; 9 | import com.pengchaoling.service.UserInfoService; 10 | import com.pengchaoling.service.UserService; 11 | import com.pengchaoling.util.SnsUtil; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Component; 14 | 15 | import java.util.Arrays; 16 | import java.util.Date; 17 | import java.util.List; 18 | 19 | /** 20 | * Author: Lying 21 | * Data: 2017-02-21 22 | * description: 点赞之后给博主发一个站内私信,说有人点了你的赞 23 | */ 24 | @Component 25 | public class LikeHandler implements EventHandler { 26 | @Autowired 27 | MessageService messageService; 28 | 29 | @Autowired 30 | UserService userService; 31 | 32 | @Autowired 33 | UserInfoService userInfoService; 34 | 35 | @Override 36 | public void doHandle(EventModel model) { 37 | try{ 38 | Message message = new Message(); 39 | message.setFromId(SnsUtil.SYSTEM_USERID); 40 | message.setToId(model.getEntityOwnerId()); 41 | message.setCreatedDate(new Date()); 42 | message.setHasRead(0); 43 | UserInfo userInfo = userInfoService.getUserInfoByUid(model.getActorId()); 44 | message.setContent(userInfo.getNickname() + "赞了你的微博\"" + model.getExt("content")+"\""); 45 | messageService.addMessage(message); 46 | }catch (Exception e){ 47 | e.printStackTrace(); 48 | } 49 | 50 | } 51 | 52 | @Override 53 | public List getSupportEventTypes() { 54 | return Arrays.asList(EventType.LIKE); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/configuration/MyBatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.configuration; 2 | import java.util.Properties; 3 | import javax.sql.DataSource; 4 | import org.apache.ibatis.plugin.Interceptor; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.mybatis.spring.SqlSessionFactoryBean; 7 | import org.mybatis.spring.SqlSessionTemplate; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.io.ClassPathResource; 12 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 13 | import org.springframework.transaction.PlatformTransactionManager; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | import org.springframework.transaction.annotation.TransactionManagementConfigurer; 16 | 17 | import com.github.pagehelper.PageHelper; 18 | @Configuration 19 | @EnableTransactionManagement 20 | public class MyBatisConfig implements TransactionManagementConfigurer { 21 | 22 | private static String MYBATIS_CONFIG = "mybatis-config.xml"; 23 | 24 | @Autowired 25 | DataSource dataSource; 26 | 27 | 28 | 29 | @Bean(name = "sqlSessionFactory") 30 | public SqlSessionFactory sqlSessionFactoryBean() { 31 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 32 | /** 设置mybatis configuration 扫描路径 */ 33 | bean.setConfigLocation(new ClassPathResource(MYBATIS_CONFIG)); 34 | bean.setDataSource(dataSource); 35 | // 分页插件 36 | PageHelper pageHelper = new PageHelper(); 37 | Properties props = new Properties(); 38 | props.setProperty("reasonable", "true"); 39 | props.setProperty("supportMethodsArguments", "true"); 40 | props.setProperty("returnPageInfo", "check"); 41 | props.setProperty("params", "count=countSql"); 42 | pageHelper.setProperties(props); 43 | // 添加插件 44 | bean.setPlugins(new Interceptor[] { pageHelper }); 45 | 46 | 47 | 48 | try { 49 | return bean.getObject(); 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | return null; 53 | } 54 | } 55 | 56 | @Bean 57 | public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { 58 | return new SqlSessionTemplate(sqlSessionFactory); 59 | } 60 | 61 | @Bean 62 | @Override 63 | public PlatformTransactionManager annotationDrivenTransactionManager() { 64 | return new DataSourceTransactionManager(dataSource); 65 | } 66 | 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/configuration/SnsWebConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.configuration; 2 | 3 | import com.pengchaoling.interceptor.LoginRequiredInterceptor; 4 | import com.pengchaoling.interceptor.PassportInterceptor; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | 10 | /** 11 | * Author: Lying 12 | * Data: 2017-02-16 13 | * description: 注册拦截器 14 | */ 15 | @Component 16 | public class SnsWebConfiguration extends WebMvcConfigurerAdapter { 17 | @Autowired 18 | PassportInterceptor passportInterceptor; 19 | 20 | @Autowired 21 | LoginRequiredInterceptor loginRequiredInterceptor; 22 | 23 | @Override 24 | public void addInterceptors(InterceptorRegistry registry) { 25 | registry.addInterceptor(passportInterceptor); 26 | registry.addInterceptor(loginRequiredInterceptor).addPathPatterns("/index","/","/userSetting","/profile","/square","/msg/*","/atme"); 27 | super.addInterceptors(registry); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/controller/CommontController.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.controller; 2 | 3 | import com.pengchaoling.model.FocusGroup; 4 | import com.pengchaoling.model.HostHolder; 5 | import com.pengchaoling.service.FocusGroupService; 6 | import com.pengchaoling.util.SnsUtil; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.core.io.ResourceLoader; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | 17 | import javax.servlet.http.HttpServletResponse; 18 | 19 | /** 20 | * Author: Lying 21 | * Data: 2017-02-17 22 | * description:公用的基础控制器,一些杂七杂八的功能写在这里 23 | * 24 | */ 25 | @Controller 26 | public class CommontController { 27 | private static final Logger logger = LoggerFactory.getLogger(CommontController.class); 28 | 29 | @Autowired 30 | HostHolder hostHolder; 31 | 32 | @Autowired 33 | FocusGroupService groupService; 34 | 35 | @Autowired 36 | ResourceLoader resourceLoader; 37 | 38 | 39 | private String fileRootPath = "E://upload/"; //文件根目录 40 | 41 | private String FacePath = fileRootPath + "face//"; //头像保存地址 42 | 43 | 44 | /** 45 | * Ajax创建新分组 46 | */ 47 | @RequestMapping(value = "/Commont/addGroup", method = {RequestMethod.POST}) 48 | @ResponseBody 49 | 50 | public String addGroup(@RequestParam("name") String name, 51 | HttpServletResponse response) { 52 | 53 | try { 54 | FocusGroup focusGroup = new FocusGroup(); 55 | focusGroup.setName(name); 56 | focusGroup.setUid(hostHolder.getUser().getId()); 57 | //如果插入成功 58 | if (groupService.addGroup(focusGroup)>0) { 59 | return SnsUtil.getJSONString(1,"增加分组成功"); 60 | } 61 | } catch (Exception e) { 62 | logger.error("增加分组失败" + e.getMessage()); 63 | } 64 | return SnsUtil.getJSONString(0, "增加分组失败"); 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/controller/FollowController.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.controller; 2 | 3 | import com.pengchaoling.async.EventModel; 4 | import com.pengchaoling.async.EventProducer; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.model.*; 7 | import com.pengchaoling.service.CommentService; 8 | import com.pengchaoling.service.FollowService; 9 | import com.pengchaoling.service.UserInfoService; 10 | import com.pengchaoling.service.UserService; 11 | import com.pengchaoling.util.SnsUtil; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.ui.Model; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * Author: Lying 24 | * Data: 2017-02-22 25 | * description:关注操作控制器 两个方法都是提供前台ajax操作的 26 | */ 27 | @Controller 28 | public class FollowController { 29 | @Autowired 30 | FollowService followService; 31 | 32 | @Autowired 33 | CommentService commentService; 34 | 35 | @Autowired 36 | UserService userService; 37 | 38 | @Autowired 39 | UserInfoService userInfoService; 40 | 41 | @Autowired 42 | HostHolder hostHolder; 43 | 44 | @Autowired 45 | EventProducer eventProducer; 46 | 47 | /** 48 | * 关注用户 49 | */ 50 | @RequestMapping(path = {"/followUser"}, method = {RequestMethod.POST, RequestMethod.GET}) 51 | @ResponseBody 52 | public String followUser(@RequestParam("uid") int uid) { 53 | 54 | boolean ret = followService.follow(hostHolder.getUser().getId(), EntityType.ENTITY_USER, uid); 55 | //关注事件,写入消息队列 56 | eventProducer.fireEvent(new EventModel(EventType.FOLLOW) 57 | .setActorId(hostHolder.getUser().getId()).setEntityId(uid) 58 | .setEntityType(EntityType.ENTITY_USER).setEntityOwnerId(uid)); 59 | 60 | // 返回关注的人数 61 | return SnsUtil.getJSONString(ret ? 1: 0, String.valueOf(followService.getFolloweeCount(hostHolder.getUser().getId(), EntityType.ENTITY_USER))); 62 | } 63 | /** 64 | * 取消关注 65 | */ 66 | @RequestMapping(path = {"/unfollowUser"}, method = {RequestMethod.POST}) 67 | @ResponseBody 68 | public String unfollowUser(@RequestParam("uid") int uid) { 69 | 70 | boolean ret = followService.unfollow(hostHolder.getUser().getId(), EntityType.ENTITY_USER, uid); 71 | //关注事件写入事件队列 72 | eventProducer.fireEvent(new EventModel(EventType.UNFOLLOW) 73 | .setActorId(hostHolder.getUser().getId()).setEntityId(uid) 74 | .setEntityType(EntityType.ENTITY_USER).setEntityOwnerId(uid)); 75 | 76 | // 返回关注的人数 77 | return SnsUtil.getJSONString(ret ? 1 : 0, String.valueOf(followService.getFolloweeCount(hostHolder.getUser().getId(), EntityType.ENTITY_USER))); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/controller/LikeController.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.controller; 2 | 3 | import com.pengchaoling.async.EventModel; 4 | import com.pengchaoling.async.EventProducer; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.model.EntityType; 7 | import com.pengchaoling.model.HostHolder; 8 | import com.pengchaoling.model.Weibo; 9 | import com.pengchaoling.service.CommentService; 10 | import com.pengchaoling.service.LikeService; 11 | import com.pengchaoling.service.WeiboService; 12 | import com.pengchaoling.util.SnsUtil; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Controller; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | import org.springframework.web.bind.annotation.RequestParam; 18 | import org.springframework.web.bind.annotation.ResponseBody; 19 | 20 | /** 21 | * Author: Lying 22 | * Data: 2017-02-21 23 | * description: 微博踩和赞 24 | */ 25 | @Controller 26 | public class LikeController { 27 | @Autowired 28 | LikeService likeService; 29 | 30 | @Autowired 31 | HostHolder hostHolder; 32 | 33 | @Autowired 34 | CommentService commentService; 35 | 36 | @Autowired 37 | WeiboService weiboService; 38 | 39 | @Autowired 40 | EventProducer eventProducer; 41 | 42 | @RequestMapping(path = {"/like"}, method = {RequestMethod.POST}) 43 | @ResponseBody 44 | public String like(@RequestParam("wid") int wid) { 45 | 46 | try{ 47 | Weibo weibo = weiboService.selectWeiboById(wid); 48 | //不能对自己的微博点赞 49 | if(weibo.getUid()==hostHolder.getUser().getId()) 50 | return SnsUtil.getJSONString(-2); 51 | 52 | 53 | long likeCount = likeService.like(hostHolder.getUser().getId(), EntityType.ENTITY_WEIBO, wid); 54 | int status = likeService.getLikeStatus(hostHolder.getUser().getId(), EntityType.ENTITY_WEIBO, wid); 55 | if(status==1){ 56 | //提交到异步事件队列去处理 通知博主被点赞了 57 | eventProducer.fireEvent(new EventModel(EventType.LIKE) 58 | .setActorId(hostHolder.getUser().getId()).setEntityId(wid) 59 | .setEntityType(EntityType.ENTITY_WEIBO).setEntityOwnerId(weibo.getUid()) 60 | .setExt("content", String.valueOf(weibo.getContent()))); 61 | //点赞 62 | return SnsUtil.getJSONString(1, String.valueOf(likeCount)); 63 | }else{ 64 | //取消赞 65 | return SnsUtil.getJSONString(-1, String.valueOf(likeCount)); 66 | } 67 | }catch (Exception e){ 68 | return SnsUtil.getJSONString(0); 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/controller/SearchController.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.controller; 2 | 3 | import com.pengchaoling.model.*; 4 | import com.pengchaoling.service.*; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Author: Lying 19 | * Data: 2017-02-24 20 | * description: 搜索 21 | */ 22 | @Controller 23 | public class SearchController { 24 | private static final Logger logger = LoggerFactory.getLogger(SearchController.class); 25 | @Autowired 26 | SearchService searchService; 27 | 28 | @Autowired 29 | FollowService followService; 30 | 31 | @Autowired 32 | WeiboService weiboService; 33 | 34 | @Autowired 35 | UserInfoService userInfoService; 36 | 37 | @Autowired 38 | HostHolder hostHolder; 39 | 40 | @Autowired 41 | LikeService likeService; 42 | 43 | 44 | 45 | @RequestMapping(path = {"/Search/searchWeibo"}, method = {RequestMethod.GET}) 46 | public String searchWeibo(Model model, @RequestParam("keyword") String keyword, 47 | @RequestParam(value = "offset", defaultValue = "0") int offset, 48 | @RequestParam(value = "count", defaultValue = "20") int count) { 49 | try { 50 | List weibosList = searchService.searchWeibo(keyword, offset, count, 51 | "", ""); 52 | List vos = new ArrayList<>(); 53 | for (Weibo wb : weibosList) { 54 | Weibo weibo = weiboService.selectWeiboById(wb.getId()); 55 | ViewObject vo = new ViewObject(); 56 | if (wb.getContent() != null) { 57 | weibo.setContent(wb.getContent()); 58 | } 59 | 60 | vo.set("weibo", weibo); 61 | vo.set("userinfo", userInfoService.getUserInfoByUid(weibo.getUid())); 62 | 63 | vo.set("picture",weiboService.selectPictureByWid(weibo.getId())); 64 | //获取是否已点赞 65 | vo.set("liked", likeService.getLikeStatus(hostHolder.getUser().getId(), EntityType.ENTITY_WEIBO, weibo.getId())); 66 | vo.set("likeCount", likeService.getLikeCount(EntityType.ENTITY_WEIBO, weibo.getId())); 67 | 68 | //如果是转发的,则获取原微博 69 | if(weibo.getIsturn()>0){ 70 | vo.set("weiboTurn",weiboService.selectWeiboById(weibo.getIsturn())); 71 | if(weiboService.selectWeiboById(weibo.getIsturn())!=null){ 72 | vo.set("userTurn",userInfoService.getUserInfoByUid(weiboService.selectWeiboById(weibo.getIsturn()).getUid())); 73 | vo.set("turnLikeCount", likeService.getLikeCount(EntityType.ENTITY_WEIBO, weibo.getIsturn())); 74 | 75 | vo.set("pictureTurn",weiboService.selectPictureByWid(weibo.getIsturn())); 76 | } 77 | } 78 | 79 | vos.add(vo); 80 | } 81 | model.addAttribute("vos", vos); 82 | model.addAttribute("keyword", keyword); 83 | } catch (Exception e) { 84 | logger.error("微博搜索" + e.getMessage()); 85 | } 86 | return "searchWeibo"; 87 | } 88 | 89 | @RequestMapping(path = {"/Search/searchUser"}, method = {RequestMethod.GET}) 90 | public String searchUser(Model model, @RequestParam("keyword") String keyword, 91 | @RequestParam(value = "offset", defaultValue = "0") int offset, 92 | @RequestParam(value = "count", defaultValue = "20") int count) { 93 | try { 94 | List userInfosList = searchService.searchUser(keyword, offset, count, 95 | "", ""); 96 | List vos = new ArrayList<>(); 97 | for (UserInfo userInfo : userInfosList) { 98 | UserInfo u = userInfoService.getUserInfoById(userInfo.getId()); 99 | ViewObject vo = new ViewObject(); 100 | vo.set("nickname",userInfo.getNickname()); 101 | vo.set("userinfo",u); 102 | //是否已关注该用户 103 | boolean followed = followService.isFollower(hostHolder.getUser().getId(), EntityType.ENTITY_USER,u.getUid()); 104 | vo.set("followed",followed); 105 | vo.set("followerCount", followService.getFollowerCount(EntityType.ENTITY_USER, u.getUid())); 106 | vo.set("followeeCount", followService.getFolloweeCount(u.getUid(), EntityType.ENTITY_USER)); 107 | vos.add(vo); 108 | } 109 | model.addAttribute("vos", vos); 110 | model.addAttribute("keyword", keyword); 111 | } catch (Exception e) { 112 | logger.error("用户搜索" + e.getMessage()); 113 | } 114 | return "searchUser"; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/controller/UserSettingController.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.controller; 2 | 3 | import com.pengchaoling.model.HostHolder; 4 | import com.pengchaoling.model.UserInfo; 5 | import com.pengchaoling.service.UserInfoService; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | /** 18 | * Author: Lying 19 | * Data: 2017-02-17 20 | * description: 用户个人信息设置 21 | */ 22 | @Controller 23 | public class UserSettingController { 24 | private static final Logger logger = LoggerFactory.getLogger(UserSettingController.class); 25 | @Autowired 26 | UserInfoService userInfoService; 27 | @Autowired 28 | HostHolder hostHolder; 29 | 30 | 31 | /** 32 | * 用户信息设置页面 33 | */ 34 | @RequestMapping(path = {"/userSetting"}, method = {RequestMethod.GET}) 35 | public String userSetting(Model model) { 36 | 37 | return "UserSetting"; 38 | } 39 | /** 40 | * 修改头像表单处理 41 | */ 42 | @RequestMapping(value = "/editFace", method = {RequestMethod.POST}) 43 | public String editFace(Model model,@RequestParam("face50") String face50, 44 | @RequestParam("face80") String face80, 45 | @RequestParam("face180") String face180, 46 | HttpServletResponse response) { 47 | 48 | try { 49 | userInfoService.updateFace(face50,face80,face180,hostHolder.getUser().getId()); 50 | model.addAttribute("success_msg", "修改头像成功"); 51 | model.addAttribute("jump_url", "/userSetting"); 52 | return "dispatch_jump"; 53 | 54 | } catch (Exception e) { 55 | logger.error("修改头像异常", e.getMessage()); 56 | model.addAttribute("error_msg", "修改头像失败"); 57 | model.addAttribute("jump_url", "/userSetting"); 58 | return "dispatch_jump"; 59 | } 60 | 61 | } 62 | 63 | /** 64 | * 修改基本信息 65 | */ 66 | @RequestMapping(value = "/editBasic", method = {RequestMethod.POST}) 67 | public String editBasci(Model model,@RequestParam("nickname") String nickname, 68 | @RequestParam("truename") String truename, 69 | @RequestParam("sex") int sex, 70 | @RequestParam("province") String province, 71 | @RequestParam("city") String city, 72 | @RequestParam("night") String night, 73 | @RequestParam("intro") String intro, 74 | HttpServletResponse response) { 75 | 76 | 77 | try { 78 | UserInfo userInfo = new UserInfo(); 79 | userInfo.setUid(hostHolder.getUser().getId()); 80 | userInfo.setNickname(nickname); 81 | userInfo.setTruename(truename); 82 | userInfo.setSex(sex); 83 | userInfo.setLocation(province+" "+city); 84 | //星座 85 | userInfo.setConstellation(night); 86 | userInfo.setIntro(intro); 87 | userInfoService.updateBasic(userInfo); 88 | 89 | 90 | model.addAttribute("success_msg", "修改信息成功"); 91 | model.addAttribute("jump_url", "/userSetting"); 92 | return "dispatch_jump"; 93 | 94 | } catch (Exception e) { 95 | logger.error("修改信息异常", e.getMessage()); 96 | model.addAttribute("error_msg", "修改信息失败"); 97 | model.addAttribute("jump_url", "/userSetting"); 98 | return "dispatch_jump"; 99 | } 100 | 101 | } 102 | 103 | /** 104 | * 修改密码 105 | */ 106 | @RequestMapping(value = "/editPwd", method = {RequestMethod.POST}) 107 | public String editPwd(Model model) { 108 | model.addAttribute("success_msg", "对不起,次功能正在开发中......"); 109 | model.addAttribute("jump_url", "/userSetting"); 110 | return "dispatch_jump"; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/AtmeDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Atme; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Select; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Author: Lying 12 | * Data: 2017-02-23 13 | * description: 艾特用户 14 | */ 15 | @Mapper 16 | public interface AtmeDAO { 17 | String TABLE_NAME = " atme "; 18 | String INSERT_FIELDS = " entity_type,entity_id,uid"; 19 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 20 | 21 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 22 | ") values (#{entityType},#{entityId},#{uid})"}) 23 | int addAtme(Atme atme); 24 | 25 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where uid=#{uid} order by id desc"}) 26 | List getAtmeByUid(int uid); 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/CommentDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Comment; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Author: Lying 13 | * Data: 2017-02-19 14 | * description: WeiboDAO 15 | */ 16 | @Mapper 17 | public interface CommentDAO { 18 | // 注意空格 19 | String TABLE_NAME = " comment "; 20 | String INSERT_FIELDS = " content,time,uid,wid "; 21 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 22 | 23 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 24 | ") values (#{content},#{time},#{uid},#{wid})"}) 25 | int addComment(Comment comment); 26 | 27 | 28 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "where wid = #{wid} order by id desc"}) 29 | List selectCommentsByWid(@Param("wid") int wid); 30 | 31 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "where id = #{id}"}) 32 | Comment getCommentById(@Param("id") int id); 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/FeedDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Feed; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | /** 10 | * Author: Lying 11 | * Data: 2017-02-23 12 | * description: 新鲜事流 13 | */ 14 | @Mapper 15 | public interface FeedDAO { 16 | String TABLE_NAME = " feed "; 17 | String INSERT_FIELDS = " uid,created_date,event_type,entity_type,entity_id,data"; 18 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 19 | 20 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 21 | ") values (#{uid},#{createdDate},#{evenType},#{entityType},#{entityId},#{data})"}) 22 | int addFeed(Feed feed); 23 | 24 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where id=#{id}"}) 25 | Feed getFeedById(int id); 26 | 27 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where uid=#{uid} and event_type=#{eventType} and entity_type=#{entityType} and entity_id=#{entityId} limit 1"}) 28 | Feed checkFeed(@Param("uid") int uidd, 29 | @Param("eventType") int eventType, 30 | @Param("entityType") int entityType, 31 | @Param("entityId") int entityId); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/FocusGroupDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.FocusGroup; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Author: Lying 10 | * Data: 2017-02-17 11 | * description: 关注分组 12 | */ 13 | @Mapper 14 | public interface FocusGroupDAO { 15 | String TABLE_NAME = " focus_group "; 16 | String INSERT_FIELDS = " name,uid "; 17 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 18 | 19 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 20 | ") values (#{name},#{uid})"}) 21 | int addGroup(FocusGroup focusGroup); 22 | 23 | 24 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "where uid = #{uid}"}) 25 | List selectFocusGroupsByUid(@Param("uid") int uid); 26 | 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/KeepDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Keep; 4 | import com.pengchaoling.model.Picture; 5 | import org.apache.ibatis.annotations.Insert; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.apache.ibatis.annotations.Select; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Author: Lying 14 | * Data: 2017-02-19 15 | * description: 16 | */ 17 | @Mapper 18 | public interface KeepDAO { 19 | // 注意空格 20 | String TABLE_NAME = " keep "; 21 | String INSERT_FIELDS = " uid, time, wid "; 22 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 23 | 24 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 25 | ") values (#{uid},#{time},#{wid})"}) 26 | int addKeep(Keep keep); 27 | 28 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where uid=#{uid} order by id desc"}) 29 | List selectKeepsByuid(@Param("uid")int uid); 30 | 31 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where uid =#{uid} and wid=#{wid}"}) 32 | Keep selectKeepByUidWid(Keep keep); 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/LoginTicketDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.LoginTicket; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | /** 7 | * Author: Lying 8 | * Data: 2017-02-16 9 | * description: 用户登录ticket 10 | */ 11 | @Mapper 12 | public interface LoginTicketDAO { 13 | String TABLE_NAME = " login_ticket "; 14 | String INSERT_FIELDS = " uid, expired, status, ticket "; 15 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 16 | 17 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 18 | ") values (#{uid},#{expired},#{status},#{ticket})"}) 19 | int addTicket(LoginTicket ticket); 20 | 21 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where ticket=#{ticket}"}) 22 | LoginTicket selectByTicket(@Param("ticket") String ticket); 23 | 24 | @Update({"update ", TABLE_NAME, " set status=#{status} where ticket=#{ticket}"}) 25 | void updateStatus(@Param("ticket") String ticket, @Param("status") int status); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/MessageDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Message; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Author: Lying 10 | * Data: 2017-02-20 11 | * description: 站内信 12 | */ 13 | 14 | @Mapper 15 | public interface MessageDAO { 16 | String TABLE_NAME = " message "; 17 | String INSERT_FIELDS = " fromId, toId, content,createdDate, hasRead, conversationId "; 18 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 19 | 20 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 21 | ") values (#{fromId},#{toId},#{content},#{createdDate},#{hasRead},#{conversationId} )"}) 22 | int addMessage(Message message); 23 | 24 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where conversationId=#{conversationId} order by id desc "}) 25 | List getConversationDetail(@Param("conversationId") String conversationId); 26 | 27 | @Select({"select count(id) from ", TABLE_NAME, " where hasRead=0 and toId=#{userId} and conversationId=#{conversationId}"}) 28 | int getConvesationUnreadCount(@Param("userId") int userId, @Param("conversationId") String conversationId); 29 | 30 | @Select({"select count(id) from ", TABLE_NAME, " where conversationId=#{conversationId}"}) 31 | int getConvesationTotalCount(@Param("conversationId") String conversationId); 32 | 33 | 34 | @Select({"select ", INSERT_FIELDS, " ,count(id) as id from ( select * from ", TABLE_NAME, " where fromId=#{userId} or toId=#{userId} order by id desc) tt group by conversationId order by createdDate desc "}) 35 | List getConversationList(@Param("userId") int userId); 36 | 37 | @Update({"update ", TABLE_NAME, " set hasRead=1 where toId=#{toId} and conversationId=#{conversationId}"}) 38 | void updateHasRead(@Param("toId") int toId,@Param("conversationId") String conversationId); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/PictureDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.Picture; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | 9 | /** 10 | * Author: Lying 11 | * Data: 2017-02-19 12 | * description: 13 | */ 14 | @Mapper 15 | public interface PictureDAO { 16 | // 注意空格 17 | String TABLE_NAME = " picture "; 18 | String INSERT_FIELDS = " mini, medium, max, wid "; 19 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 20 | 21 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 22 | ") values (#{mini},#{medium},#{max},#{wid})"}) 23 | int addWPicture(Picture picture); 24 | 25 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where wid=#{wid}"}) 26 | Picture selectPictureByWid(@Param("wid") int wid); 27 | 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/UserDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.User; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Author: Lying 10 | * Data: 2017-02-15 11 | * description: UserDao 12 | */ 13 | @Mapper 14 | public interface UserDAO { 15 | // 注意空格 16 | String TABLE_NAME = " user "; 17 | String INSERT_FIELDS = " account,nickname, password, salt, registime "; 18 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 19 | 20 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 21 | ") values (#{account},#{nickname},#{password},#{salt},#{registime})"}) 22 | int addUser(User user); 23 | 24 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where id=#{id}"}) 25 | User selectById(@Param("id") int id); 26 | 27 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where account=#{account}"}) 28 | User selectByAccount(@Param("account") String account); 29 | 30 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where nickname=#{nickname}"}) 31 | User selectByNickname(@Param("nickname") String nickname); 32 | 33 | @Update({"update ", TABLE_NAME, " set password=#{password} where id=#{id}"}) 34 | void updatePassword(User user); 35 | 36 | @Delete({"delete from ", TABLE_NAME, " where id=#{id}"}) 37 | void deleteById(@Param("id") int id); 38 | 39 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "order by id desc limit #{offset},#{limit}"}) 40 | List selectUsers(@Param("offset") int offset, 41 | @Param("limit") int limit); 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/UserInfoDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.UserInfo; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | /** 7 | * Author: Lying 8 | * Data: 2017-02-17 9 | * description: 用户额外信息 10 | */ 11 | @Mapper 12 | public interface UserInfoDAO { 13 | // 注意空格 14 | String TABLE_NAME = " userinfo "; 15 | String INSERT_FIELDS = " nickname, truename, sex, location, constellation, intro, face50,face80, face180, style, follower, followee, weibo, uid "; 16 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 17 | 18 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 19 | ") values (#{nickname},#{truename},#{sex},#{location},#{constellation},#{intro},#{face50},#{face80},#{face180},#{style},#{follower},#{followee},#{weibo},#{uid})"}) 20 | int addUserInfo(UserInfo userinfo); 21 | 22 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where uid=#{uid}"}) 23 | UserInfo selectUserInfoByUid(@Param("uid") int uid); 24 | 25 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where id=#{id}"}) 26 | UserInfo selectUserInfoById(@Param("id") int id); 27 | 28 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where nickname=#{nickname}"}) 29 | UserInfo selectUserInfoByNickname(String nickname); 30 | 31 | @Update({"update ", TABLE_NAME, " set face50=#{face50},face80=#{face80},face180=#{face180} where uid=#{uid}"}) 32 | void updateFace(UserInfo userinfo); 33 | 34 | @Update({"update ", TABLE_NAME, " set nickname=#{nickname},truename=#{truename},sex=#{sex},location=#{location},constellation=#{constellation},intro=#{intro} where uid=#{uid}"}) 35 | void updateBasic(UserInfo userinfo); 36 | 37 | //字段加一 38 | @Update({"update ", TABLE_NAME, " set weibo=weibo+1 where uid=#{uid}"}) 39 | void IncWeibo(@Param("uid") int uid); 40 | 41 | @Update({"update ", TABLE_NAME, " set weibo=weibo-1 where uid=#{uid}"}) 42 | void DecWeibo(@Param("uid") int uid); 43 | 44 | 45 | 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/dao/WeiboDAO.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.dao; 2 | 3 | import com.pengchaoling.model.User; 4 | import com.pengchaoling.model.Weibo; 5 | import org.apache.ibatis.annotations.*; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Author: Lying 11 | * Data: 2017-02-19 12 | * description: WeiboDAO 13 | */ 14 | @Mapper 15 | public interface WeiboDAO { 16 | // 注意空格 17 | String TABLE_NAME = " weibo "; 18 | String INSERT_FIELDS = " content, isturn, time, turn, keep, comment,uid "; 19 | String SELECT_FIELDS = " id, " + INSERT_FIELDS; 20 | 21 | @Insert({"insert into ", TABLE_NAME, "(", INSERT_FIELDS, 22 | ") values (#{content},#{isturn},#{time},#{turn},#{keep},#{comment},#{uid})"}) 23 | int addWeibo(Weibo weibo); 24 | 25 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, " where id=#{id}"}) 26 | Weibo selectWeiBoById(@Param("id")int id); 27 | 28 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "order by id desc "}) 29 | List selectWeibos(); 30 | 31 | @Select({"select ", SELECT_FIELDS, " from ", TABLE_NAME, "where uid =#{uid} order by id desc "}) 32 | List selectWeibosByUid(@Param("uid") int uid); 33 | 34 | @Update({"update ", TABLE_NAME, " set turn=turn+1 where id=#{wid}"}) 35 | void IncTurn(@Param("wid") int wid); 36 | 37 | @Update({"update ", TABLE_NAME, " set keep=keep+1 where id=#{wid}"}) 38 | void IncKeep(@Param("wid") int wid); 39 | 40 | @Update({"update ", TABLE_NAME, " set comment=comment+1 where id=#{wid}"}) 41 | void IncComment(@Param("wid") int wid); 42 | 43 | @Delete({"delete from ", TABLE_NAME, " where id=#{id}"}) 44 | void deleteWeiboById(@Param("id") int id); 45 | 46 | 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/interceptor/LoginRequiredInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.interceptor; 2 | 3 | import com.pengchaoling.model.HostHolder; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.HandlerInterceptor; 7 | import org.springframework.web.servlet.ModelAndView; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | /** 13 | * Author: Lying 14 | * Data: 2017-02-16 15 | * description: 登陆拦截器 16 | */ 17 | @Component 18 | public class LoginRequiredInterceptor implements HandlerInterceptor { 19 | 20 | @Autowired 21 | private HostHolder hostHolder; //这个对象是从上一个拦截器获得的 22 | 23 | /** 24 | * 处理controller之前,会先调用 25 | * 如果用户没有登录,则跳转到登陆页面 26 | */ 27 | @Override 28 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { 29 | if (hostHolder.getUser() == null) { 30 | httpServletResponse.sendRedirect("/login"); 31 | return false; 32 | } 33 | return true; 34 | } 35 | 36 | @Override 37 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { 38 | } 39 | 40 | @Override 41 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/interceptor/PassportInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.interceptor; 2 | 3 | import com.pengchaoling.dao.LoginTicketDAO; 4 | import com.pengchaoling.dao.UserDAO; 5 | import com.pengchaoling.dao.UserInfoDAO; 6 | import com.pengchaoling.model.*; 7 | import com.pengchaoling.service.FollowService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.servlet.HandlerInterceptor; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import javax.servlet.http.Cookie; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.util.Date; 17 | 18 | /** 19 | * Author: Lying 20 | * Data: 2017-02-16 21 | * description: 拦截器 22 | */ 23 | @Component 24 | public class PassportInterceptor implements HandlerInterceptor { 25 | 26 | @Autowired 27 | private LoginTicketDAO loginTicketDAO; 28 | 29 | @Autowired 30 | private UserDAO userDAO; 31 | 32 | @Autowired 33 | private HostHolder hostHolder; 34 | 35 | @Autowired 36 | private UserInfoDAO userInfoDAO; 37 | 38 | @Autowired 39 | FollowService followService; 40 | 41 | /** 42 | * 处理controller之前,会先调用 43 | * 如果用户保存有cookie,那么会从cookie里读取 44 | */ 45 | @Override 46 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { 47 | 48 | String ticket = null; 49 | 50 | if (httpServletRequest.getCookies() != null) { 51 | for (Cookie cookie : httpServletRequest.getCookies()) { 52 | if (cookie.getName().equals("ticket")) { 53 | ticket = cookie.getValue(); 54 | break; 55 | } 56 | } 57 | } 58 | 59 | if (ticket != null) { 60 | LoginTicket loginTicket = loginTicketDAO.selectByTicket(ticket); 61 | //用户还没有登陆,直接返回空信息 62 | if (loginTicket == null || loginTicket.getExpired().before(new Date()) || loginTicket.getStatus() != 0) { 63 | return true; 64 | } 65 | 66 | User user = userDAO.selectById(loginTicket.getUid()); 67 | hostHolder.setUser(user); 68 | } 69 | return true; 70 | } 71 | 72 | /** 73 | * Controller页面渲染之前,会调用这个 74 | * 把用户信息注入到每一个将要渲染的页面 75 | */ 76 | @Override 77 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { 78 | User user = hostHolder.getUser(); 79 | if (modelAndView != null && user != null) { 80 | UserInfo userInfo = userInfoDAO.selectUserInfoByUid(user.getId()); 81 | userInfo.setFollower(followService.getFollowerCount(EntityType.ENTITY_USER, user.getId())); 82 | userInfo.setFollowee(followService.getFolloweeCount(user.getId(), EntityType.ENTITY_USER)); 83 | modelAndView.addObject("user", user); 84 | modelAndView.addObject("userinfo",userInfo); 85 | } 86 | } 87 | 88 | @Override 89 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { 90 | hostHolder.clear(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Atme.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | /** 4 | * Author: Lying 5 | * Data: 2017-02-24 6 | * description: atme 艾特我 7 | */ 8 | public class Atme { 9 | private int id; 10 | private int uid; //生产者 11 | private int entityType; //触发的载体类型 评论 或 发微博 12 | private int entityId; //触发的id 评论id 或微博id 13 | 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public void setId(int id) { 20 | this.id = id; 21 | } 22 | 23 | 24 | public int getEntityType() { 25 | return entityType; 26 | } 27 | 28 | public void setEntityType(int entityType) { 29 | this.entityType = entityType; 30 | } 31 | 32 | public int getEntityId(){ 33 | return entityId; 34 | } 35 | 36 | public void setEntityId(int entityId){ 37 | this.entityId = entityId; 38 | } 39 | 40 | public int getUid() { 41 | return uid; 42 | } 43 | 44 | public void setUid(int uid) { 45 | this.uid = uid; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Comment.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-19 8 | * description: 微博评论表 9 | */ 10 | public class Comment { 11 | private int id; 12 | private String content; //评论内容 13 | private Date time; //评论时间 14 | private int uid; //评论者id 15 | private int wid; //关联微博id 16 | 17 | public Comment(){}; 18 | 19 | public int getId(){ 20 | return this.id; 21 | } 22 | 23 | public void setId(int id){ 24 | this.id = id; 25 | } 26 | 27 | public String getContent(){ 28 | return this.content; 29 | } 30 | 31 | public void setContent(String content){ 32 | this.content = content; 33 | } 34 | 35 | public Date getTime(){ 36 | return this.time; 37 | } 38 | 39 | public void setTime(Date time){ 40 | this.time = time; 41 | } 42 | 43 | public int getUid(){ 44 | return this.uid; 45 | } 46 | 47 | public void setUid(int uid){ 48 | this.uid = uid; 49 | } 50 | 51 | public int getWid(){ 52 | return this.wid; 53 | } 54 | 55 | public void setWid(int wid){ 56 | this.wid = wid; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/EntityType.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | 4 | /** 5 | * Author: Lying 6 | * Data: 2017-02-21 7 | * description: 事件类型 8 | */ 9 | public class EntityType { 10 | public static int ENTITY_COMMENT = 1; //评论 11 | public static int ENTITY_WEIBO = 2; //微博 12 | public static int ENTITY_USER = 3; //用户 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Feed.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * Author: Lying 9 | * Data: 2017-02-23 10 | * description: timeline新鲜事 feed流 11 | */ 12 | public class Feed { 13 | private int id; 14 | private int uid; //生产者 15 | private Date createdDate; //时间 16 | public int evenType; //事件类型 17 | private int entityType; //触发的载体类型 18 | private int entityId; //触发的id 19 | private String data; //数据 20 | private JSONObject dataJSON = null; //json数据格式 21 | 22 | public int getId() { 23 | return id; 24 | } 25 | 26 | public void setId(int id) { 27 | this.id = id; 28 | } 29 | 30 | public int getEvenType(){ 31 | return evenType; 32 | } 33 | 34 | public void setEvenType(int evenType){ 35 | this.evenType = evenType; 36 | } 37 | 38 | public int getEntityType() { 39 | return entityType; 40 | } 41 | 42 | public void setEntityType(int entityType) { 43 | this.entityType = entityType; 44 | } 45 | 46 | public int getEntityId(){ 47 | return entityId; 48 | } 49 | 50 | public void setEntityId(int entityId){ 51 | this.entityId = entityId; 52 | } 53 | 54 | public int getUid() { 55 | return uid; 56 | } 57 | 58 | public void setUid(int uid) { 59 | this.uid = uid; 60 | } 61 | 62 | public Date getCreatedDate() { 63 | return createdDate; 64 | } 65 | 66 | public void setCreatedDate(Date createdDate) { 67 | this.createdDate = createdDate; 68 | } 69 | 70 | public String getData() { 71 | return data; 72 | } 73 | 74 | public void setData(String data) { 75 | this.data = data; 76 | dataJSON = JSONObject.parseObject(data); 77 | } 78 | //辅助办法,通过这个来读取那个json串里面的每个字段 79 | public String get(String key) { 80 | return dataJSON == null ? null : dataJSON.getString(key); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/FocusGroup.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-17 8 | * description: 关注用户分组 9 | */ 10 | public class FocusGroup { 11 | private int id; 12 | private String name; 13 | private int uid; 14 | 15 | public FocusGroup(){} 16 | 17 | public int getId() { 18 | return id; 19 | } 20 | 21 | public void setId(int id) { 22 | this.id = id; 23 | } 24 | 25 | public String getName(){ 26 | return this.name; 27 | } 28 | 29 | public void setName(String name){ 30 | this.name = name; 31 | } 32 | 33 | public int getUid() { 34 | return uid; 35 | } 36 | 37 | public void setUid(int uid) { 38 | this.uid = uid; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/HostHolder.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-16 8 | * description: 用户连接池,负责管理用户连接信息,提供给拦截器使用 9 | */ 10 | @Component //普通实例的依赖注入 11 | public class HostHolder { 12 | //为每个线程提供独立的变量副本 13 | private static ThreadLocal users = new ThreadLocal(); 14 | 15 | public User getUser() { 16 | return users.get(); 17 | } 18 | 19 | public void setUser(User user) { 20 | users.set(user); 21 | } 22 | 23 | public void clear() { 24 | users.remove(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Keep.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-20 8 | * description: 微博收藏表 9 | */ 10 | public class Keep { 11 | 12 | private int id; 13 | private int uid; 14 | private Date time; 15 | private int wid; 16 | 17 | public Keep(){} 18 | 19 | public int getId(){ 20 | return this.id; 21 | } 22 | 23 | public void setId(int id){ 24 | this.id = id; 25 | } 26 | 27 | public int getUid(){ 28 | return this.uid; 29 | } 30 | 31 | public void setUid(int uid){ 32 | this.uid = uid; 33 | } 34 | 35 | public Date getTime(){ 36 | return this.time; 37 | } 38 | 39 | public void setTime(Date time){ 40 | this.time = time; 41 | } 42 | 43 | public int getWid(){ 44 | return this.wid; 45 | } 46 | 47 | public void setWid(int wid){ 48 | this.wid = wid; 49 | } 50 | 51 | 52 | 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/LoginTicket.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-16 8 | * description: 用户登录ticket 9 | */ 10 | public class LoginTicket { 11 | private int id; 12 | private int uid; 13 | private Date expired; 14 | private int status;// 0有效,1无效 15 | private String ticket; 16 | 17 | public String getTicket() { 18 | return ticket; 19 | } 20 | 21 | public void setTicket(String ticket) { 22 | this.ticket = ticket; 23 | } 24 | 25 | public int getId() { 26 | return id; 27 | } 28 | 29 | public void setId(int id) { 30 | this.id = id; 31 | } 32 | 33 | public int getUid() { 34 | return uid; 35 | } 36 | 37 | public void setUid(int uid) { 38 | this.uid = uid; 39 | } 40 | 41 | public Date getExpired() { 42 | return expired; 43 | } 44 | 45 | public void setExpired(Date expired) { 46 | this.expired = expired; 47 | } 48 | 49 | public int getStatus() { 50 | return status; 51 | } 52 | 53 | public void setStatus(int status) { 54 | this.status = status; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Message.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-20 8 | * description: 站内信 9 | */ 10 | 11 | public class Message { 12 | private int id; 13 | private int fromId; 14 | private int toId; 15 | private String content; 16 | private Date createdDate; 17 | private int hasRead; //是否已读 18 | private String conversationId; //每次双方对话都有唯一的对话id 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public void setId(int id) { 25 | this.id = id; 26 | } 27 | 28 | public int getFromId() { 29 | return fromId; 30 | } 31 | 32 | public void setFromId(int fromId) { 33 | this.fromId = fromId; 34 | } 35 | 36 | public int getToId() { 37 | return toId; 38 | } 39 | 40 | public void setToId(int toId) { 41 | this.toId = toId; 42 | } 43 | 44 | public String getContent() { 45 | return content; 46 | } 47 | 48 | public void setContent(String content) { 49 | this.content = content; 50 | } 51 | 52 | public Date getCreatedDate() { 53 | return createdDate; 54 | } 55 | 56 | public void setCreatedDate(Date createdDate) { 57 | this.createdDate = createdDate; 58 | } 59 | 60 | public int getHasRead() { 61 | return hasRead; 62 | } 63 | 64 | public void setHasRead(int hasRead) { 65 | this.hasRead = hasRead; 66 | } 67 | 68 | public String getConversationId() { 69 | if (fromId < toId) { 70 | return String.format("%d_%d", fromId, toId); 71 | } 72 | return String.format("%d_%d", toId, fromId); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Picture.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | /** 4 | * Author: Lying 5 | * Data: 2017-02-19 6 | * description: 微博配图 7 | */ 8 | public class Picture { 9 | private int id; 10 | private String mini; //小图 11 | private String medium; //中图 12 | private String max; //大图 13 | private int wid; //所属微博id 14 | 15 | public Picture(){ 16 | this.mini = ""; 17 | this.medium = ""; 18 | this.max = ""; 19 | } 20 | 21 | public int getId(){ 22 | return this.id; 23 | } 24 | 25 | public void setId(int id){ 26 | this.id = id; 27 | } 28 | 29 | public String getMini(){ 30 | return this.mini; 31 | } 32 | 33 | public void setMini(String mini){ 34 | this.mini = mini; 35 | } 36 | 37 | public String getMedium(){ 38 | return this.medium; 39 | } 40 | 41 | public void setMedium(String medium){ 42 | this.medium = medium; 43 | } 44 | 45 | public String getMax(){ 46 | return max; 47 | } 48 | 49 | public void setMax(String max){ 50 | this.max = max; 51 | } 52 | 53 | public int getWid(){ 54 | return this.wid; 55 | } 56 | 57 | public void setWid(int wid){ 58 | this.wid = wid; 59 | } 60 | 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/User.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-15 8 | * description: user model 9 | */ 10 | public class User { 11 | private int id; 12 | private String account; //登陆账号 13 | private String nickname; //昵称 14 | private String password; //密码 15 | private String salt; //盐值(加盐字段) 16 | private Date registime; //注册时间 17 | 18 | public User(){} 19 | 20 | public User(String account){ 21 | this.account = account; 22 | this.password = ""; 23 | this.salt = ""; 24 | } 25 | 26 | public String getAccount(){ 27 | return account; 28 | } 29 | 30 | public void setAccount(String account){ 31 | this.account = account; 32 | } 33 | 34 | public String getNickname(){ 35 | return this.nickname; 36 | } 37 | 38 | public void setNickname(String nickname){ 39 | this.nickname = nickname; 40 | } 41 | 42 | public String getPassword(){ 43 | return password; 44 | } 45 | 46 | public void setPassword(String password){ 47 | this.password = password; 48 | } 49 | 50 | public String getSalt(){ 51 | return salt; 52 | } 53 | 54 | public void setSalt(String salt){ 55 | this.salt = salt; 56 | } 57 | 58 | public Date getRegistime(){ 59 | return registime; 60 | } 61 | 62 | public void setRegistime(Date registime){ 63 | this.registime = registime; 64 | } 65 | 66 | public int getId(){ 67 | return id; 68 | } 69 | 70 | public void setId(int id){ 71 | this.id = id; 72 | } 73 | 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.security.PublicKey; 4 | import java.util.Date; 5 | 6 | /** 7 | * Author: Lying 8 | * Data: 2017-02-15 9 | * description: 用户基本信息 10 | */ 11 | public class UserInfo { 12 | private int id; 13 | private String nickname; //用户昵称 14 | private String truename; //真实姓名 15 | private int sex; //性别 0保密,1男,2女 16 | private String location; //所在地 17 | private String constellation; //星座 18 | private String intro; //一句话介绍自己 19 | private String face50; //50*50头像 20 | private String face80; //80*80头像 21 | private String face180; //180*180头像 22 | private String style; //个性模板 23 | private long followee; //关注数 其实这两个字段已经存到redis里面了 24 | private long follower; //粉丝数 25 | private int weibo; //微博数 26 | private int uid; //关联用户ID 27 | 28 | 29 | public UserInfo(){ 30 | this.nickname = ""; 31 | this.truename = ""; 32 | this.sex = 0; 33 | this.location = ""; 34 | this.constellation = ""; 35 | this.intro = ""; 36 | this.face50 = ""; 37 | this.face80 = ""; 38 | this.face180 = ""; 39 | this.style = "default"; 40 | this.followee = 0; 41 | this.follower = 0; 42 | this.weibo = 0; 43 | } 44 | 45 | public int getId(){ 46 | return id; 47 | } 48 | 49 | public void setId(int id){ 50 | this.id = id; 51 | } 52 | 53 | 54 | public String getNickname(){ 55 | return this.nickname; 56 | } 57 | 58 | public void setNickname(String nickname){ 59 | this.nickname = nickname; 60 | } 61 | 62 | public String getTruename(){ 63 | return this.truename; 64 | } 65 | 66 | public void setTruename(String truename){ 67 | this.truename = truename; 68 | } 69 | 70 | public int getSex(){ 71 | return this.sex; 72 | } 73 | 74 | public void setSex(int sex){ 75 | this.sex = sex; 76 | } 77 | 78 | public String getLocation(){ 79 | return this.location; 80 | } 81 | 82 | public void setLocation(String location){ 83 | this.location = location; 84 | } 85 | 86 | public String getConstellation(){ 87 | return this.constellation; 88 | } 89 | 90 | public void setConstellation(String constellation){ 91 | this.constellation = constellation; 92 | } 93 | 94 | public String getIntro(){ 95 | return this.intro; 96 | } 97 | 98 | public void setIntro(String intro){ 99 | this.intro = intro; 100 | } 101 | 102 | public String getFace50(){ 103 | return this.face50; 104 | } 105 | 106 | public void setFace50(String face50){ 107 | this.face50 = face50; 108 | } 109 | 110 | public String getFace80(){ 111 | return this.face80; 112 | } 113 | 114 | public void setFace80(String face80){ 115 | this.face80 = face80; 116 | } 117 | 118 | public String getFace180(){ 119 | return this.face180; 120 | } 121 | 122 | public void setFace180(String face180){ 123 | this.face180 = face180; 124 | } 125 | 126 | public String getStyle(){ 127 | return this.style; 128 | } 129 | 130 | public void setStyle(String style){ 131 | this.style = style; 132 | } 133 | 134 | public long getFollower(){ 135 | return this.follower; 136 | } 137 | 138 | public void setFollower(long follower){ 139 | this.follower = follower; 140 | } 141 | 142 | public long getFollowee(){ 143 | return this.followee; 144 | } 145 | 146 | public void setFollowee(long followee){ 147 | this.followee = followee; 148 | } 149 | 150 | public int getWeibo(){ 151 | return this.weibo; 152 | } 153 | 154 | public void setWeibo(int weibo){ 155 | this.weibo=weibo; 156 | } 157 | 158 | public int getUid(){ 159 | return this.uid; 160 | } 161 | 162 | public void setUid(int uid){ 163 | this.uid = uid; 164 | } 165 | 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/ViewObject.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Author: Lying 8 | * Data: 2017-02-15 9 | * description: 用hashmap自定义的一种数据模型 10 | */ 11 | public class ViewObject { 12 | private Map objs = new HashMap(); 13 | public void set(String key, Object value) { 14 | objs.put(key, value); 15 | } 16 | 17 | public Object get(String key) { 18 | return objs.get(key); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/model/Weibo.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * Author: Lying 7 | * Data: 2017-02-19 8 | * description: weibo 9 | */ 10 | public class Weibo { 11 | private int id; 12 | private String content; //微博内容 13 | private int isturn; //是否转发(0:原创, 如果是转发的则保存该转发微博的ID) 14 | private Date time; //发布时间 15 | private int turn; //转发次数 16 | private int keep; //收藏次数 17 | private int comment; //评论次数 18 | private int uid; //所属用户ID 19 | 20 | public Weibo(){ 21 | this.content = ""; 22 | this.isturn = 0; 23 | this.turn = 0; 24 | this.keep = 0; 25 | this.comment= 0; 26 | } 27 | 28 | public String getContent(){ 29 | return this.content; 30 | } 31 | 32 | public void setContent(String content){ 33 | this.content = content; 34 | } 35 | 36 | public int getIsturn(){ 37 | return this.isturn; 38 | } 39 | 40 | public void setIsturn(int isturn){ 41 | this.isturn = isturn; 42 | } 43 | 44 | public Date getTime(){ 45 | return this.time; 46 | } 47 | 48 | public void setTime(Date time){ 49 | this.time = time; 50 | } 51 | 52 | public int getTurn(){ 53 | return this.turn; 54 | } 55 | 56 | public void setTurn(int turn){ 57 | this.turn = turn; 58 | } 59 | 60 | public int getKeep(){ 61 | return this.keep; 62 | } 63 | 64 | public void setKeep(int keep){ 65 | this.keep = keep; 66 | } 67 | 68 | public int getComment(){ 69 | return this.comment; 70 | } 71 | 72 | public void setComment(int comment){ 73 | this.comment = comment; 74 | } 75 | 76 | public int getUid(){ 77 | return this.uid; 78 | } 79 | 80 | public void setUid(int uid){ 81 | this.uid = uid; 82 | } 83 | 84 | public int getId(){ 85 | return id; 86 | } 87 | 88 | public void setId(int id){ 89 | this.id = id; 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/AtmeService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.dao.AtmeDAO; 4 | import com.pengchaoling.model.Atme; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Author: Lying 12 | * Data: 2017-02-24 13 | * description: Atme 艾特用户 14 | */ 15 | @Service 16 | public class AtmeService { 17 | @Autowired 18 | AtmeDAO atmeDAO; 19 | 20 | public List getAtmeByUid(int uid){ 21 | return atmeDAO.getAtmeByUid(uid); 22 | } 23 | 24 | public int addAtme(Atme atme) { 25 | return atmeDAO.addAtme(atme); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/CommentService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.async.EventModel; 4 | import com.pengchaoling.async.EventProducer; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.dao.CommentDAO; 7 | import com.pengchaoling.model.Comment; 8 | import com.pengchaoling.model.EntityType; 9 | import com.pengchaoling.model.HostHolder; 10 | import com.pengchaoling.model.UserInfo; 11 | import com.pengchaoling.util.SnsUtil; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.web.util.HtmlUtils; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.regex.Matcher; 19 | import java.util.regex.Pattern; 20 | 21 | /** 22 | * Author: Lying 23 | * Data: 2017-02-19 24 | * description: 25 | */ 26 | @Service 27 | public class CommentService { 28 | 29 | @Autowired 30 | CommentDAO commentDAO; 31 | @Autowired 32 | SensitiveService sensitiveService; 33 | @Autowired 34 | EventProducer eventProducer; 35 | @Autowired 36 | HostHolder hostHolder; 37 | @Autowired 38 | UserInfoService userInfoService; 39 | 40 | public int addComment(Comment comment){ 41 | //html过滤 42 | comment.setContent(HtmlUtils.htmlEscape(comment.getContent())); 43 | //敏感词 过滤掉 44 | comment.setContent(sensitiveService.filter(comment.getContent())); 45 | int res = commentDAO.addComment(comment); 46 | //提交到异步事件队列去处理 47 | if(res>0){ 48 | eventProducer.fireEvent(new EventModel(EventType.ADDCOMMENT) 49 | .setActorId(hostHolder.getUser().getId()).setEntityId(comment.getId()) 50 | .setEntityType(EntityType.ENTITY_COMMENT).setEntityOwnerId(comment.getUid()) 51 | .setExt("content", String.valueOf(comment.getContent()))); 52 | } 53 | 54 | return res; 55 | } 56 | 57 | public Comment getCommentById(int id){ 58 | //替换艾特 59 | Comment comment = commentDAO.getCommentById(id); 60 | if(comment!=null) 61 | comment.setContent(replaceAtme(comment.getContent())); 62 | return comment; 63 | } 64 | 65 | 66 | public List selectCommentsByWid(int wid){ 67 | List comments= commentDAO.selectCommentsByWid(wid); 68 | List news = new ArrayList(); 69 | if(!comments.isEmpty()) { 70 | for (Comment comment : comments) { 71 | if(comment!=null){ 72 | comment.setContent(replaceAtme(comment.getContent())); 73 | news.add(comment); 74 | } 75 | } 76 | } 77 | return news; 78 | } 79 | 80 | //辅助方法 提供给本类使用,替换@用户名 以及替换表情包 81 | private String replaceAtme(String content){ 82 | //正则表达式匹配出所有AT用户 83 | Pattern pt = Pattern.compile("@(([\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]|[a-zA-Z])+(|\\s|,|。|?|;|!|‘|’|“|”)+?)"); 84 | Matcher mt = pt.matcher(content); 85 | while (mt.find()) { 86 | UserInfo userInfo = userInfoService.getUserInfoByNickname(mt.group().replace("@","")); 87 | if(userInfo != null){ 88 | String str = ""+mt.group()+""; 89 | content = content.replace(mt.group(),str); 90 | } 91 | } 92 | content = SnsUtil.emojiReplace(content); 93 | return content; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/FeedService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.dao.FeedDAO; 4 | import com.pengchaoling.model.Feed; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * Author: Lying 10 | * Data: 2017-02-23 11 | * description: feedserver 12 | */ 13 | @Service 14 | public class FeedService { 15 | @Autowired 16 | FeedDAO feedDAO; 17 | 18 | public boolean addFeed(Feed feed) { 19 | //去重 检查是否已经存在了 20 | Feed check = feedDAO.checkFeed(feed.getUid(),feed.getEvenType(),feed.getEntityType(),feed.getEntityId()); 21 | if(check != null) return false; 22 | feedDAO.addFeed(feed); 23 | return feed.getId() > 0; 24 | } 25 | 26 | public Feed getById(int id) { 27 | return feedDAO.getFeedById(id); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/FocusGroupService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.dao.FocusGroupDAO; 4 | import com.pengchaoling.model.FocusGroup; 5 | import com.pengchaoling.model.User; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.util.HtmlUtils; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Author: Lying 14 | * Data: 2017-02-18 15 | * description: 16 | */ 17 | @Service 18 | public class FocusGroupService { 19 | @Autowired 20 | FocusGroupDAO focusGroupDAO; 21 | 22 | public int addGroup(FocusGroup focusGroup){ 23 | //很有必要过滤一下 24 | focusGroup.setName(HtmlUtils.htmlEscape(focusGroup.getName())); 25 | return focusGroupDAO.addGroup(focusGroup); 26 | } 27 | 28 | /** 29 | * 根据uid获取该用户所有的关注分组 30 | */ 31 | public List selectFocusGroupsByUid(int uid){ 32 | return focusGroupDAO.selectFocusGroupsByUid(uid); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/FollowService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.util.JedisAdapter; 4 | import com.pengchaoling.util.RedisKeyUtil; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import redis.clients.jedis.Jedis; 8 | import redis.clients.jedis.Transaction; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Date; 12 | import java.util.List; 13 | import java.util.Set; 14 | 15 | /** 16 | * Author: Lying 17 | * Data: 2017-02-22 18 | * description: 关注服务,现在是用于关注用户,以后可以用这个服务来关注微博,关注评论等等 19 | */ 20 | @Service 21 | public class FollowService { 22 | @Autowired 23 | JedisAdapter jedisAdapter; 24 | 25 | 26 | /** 27 | * 用户关注了某个实体,可以关注问题,关注用户,关注评论等任何实体 28 | * 比如你关注一个博主,那么博主的粉丝(follower)列表里面就会有你,你(followee)的关注列表有博主 29 | */ 30 | public boolean follow(int userId, int entityType, int entityId) { 31 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 32 | String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType); 33 | Date date = new Date(); 34 | //获取一个连接对象 35 | Jedis jedis = jedisAdapter.getJedis(); 36 | //开启事务 37 | Transaction tx = jedisAdapter.multi(jedis); 38 | // 实体的粉丝 加上当前的这个用户 39 | tx.zadd(followerKey, date.getTime(), String.valueOf(userId)); 40 | // 当前用户对这类实体关注+1 41 | tx.zadd(followeeKey, date.getTime(), String.valueOf(entityId)); 42 | //执行事务 43 | List ret = jedisAdapter.exec(tx, jedis); 44 | //如果 ret执行了两条命令,而且两条命令都执行成功 则返回true 45 | return ret.size() == 2 && (Long) ret.get(0) > 0 && (Long) ret.get(1) > 0; 46 | } 47 | 48 | /** 49 | * 取消关注 50 | */ 51 | public boolean unfollow(int userId, int entityType, int entityId) { 52 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 53 | String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType); 54 | Date date = new Date(); 55 | Jedis jedis = jedisAdapter.getJedis(); 56 | Transaction tx = jedisAdapter.multi(jedis); 57 | // 实体的粉丝移除当前用户 58 | tx.zrem(followerKey, String.valueOf(userId)); 59 | // 当前用户对这类实体关注-1 60 | tx.zrem(followeeKey, String.valueOf(entityId)); 61 | List ret = jedisAdapter.exec(tx, jedis); 62 | return ret.size() == 2 && (Long) ret.get(0) > 0 && (Long) ret.get(1) > 0; 63 | } 64 | 65 | /** 66 | * 获取粉丝列表 比如多个人关注了你,那么这个就是用来获取那些粉丝的 67 | */ 68 | public List getFollowers(int entityType, int entityId, int count) { 69 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 70 | return getIdsFromSet(jedisAdapter.zrevrange(followerKey, 0, count)); 71 | } 72 | 73 | public List getFollowers(int entityType, int entityId, int offset, int count) { 74 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 75 | return getIdsFromSet(jedisAdapter.zrevrange(followerKey, offset, offset+count)); 76 | } 77 | 78 | /** 79 | * 获取关注者列表 比如你关注了多个博主,那这个就是用来去除那些博主的 80 | */ 81 | public List getFollowees(int userId, int entityType, int count) { 82 | String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType); 83 | return getIdsFromSet(jedisAdapter.zrevrange(followeeKey, 0, count)); 84 | } 85 | 86 | public List getFollowees(int userId, int entityType, int offset, int count) { 87 | String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType); 88 | return getIdsFromSet(jedisAdapter.zrevrange(followeeKey, offset, offset+count)); 89 | } 90 | 91 | /** 92 | * 获取粉丝数量 93 | */ 94 | public long getFollowerCount(int entityType, int entityId) { 95 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 96 | return jedisAdapter.zcard(followerKey); 97 | } 98 | 99 | /** 100 | * 获取关注者数量 101 | */ 102 | public long getFolloweeCount(int userId, int entityType) { 103 | String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType); 104 | return jedisAdapter.zcard(followeeKey); 105 | } 106 | 107 | /** 108 | * helper函数 把string转成int 109 | */ 110 | private List getIdsFromSet(Set idset) { 111 | List ids = new ArrayList<>(); 112 | for (String str : idset) { 113 | ids.add(Integer.parseInt(str)); 114 | } 115 | return ids; 116 | } 117 | 118 | /** 119 | * 判断用户是否关注了某个实体 判断用户是否是某个实体的粉丝 120 | * 比如判断当前登陆的用户 是否 已关注了id为entityId 的博主(entityType) 121 | */ 122 | public boolean isFollower(int userId, int entityType, int entityId) { 123 | String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId); 124 | //取他的score是否为空,就知道这个到底有没有了 125 | return jedisAdapter.zscore(followerKey, String.valueOf(userId)) != null; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/LikeService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.util.JedisAdapter; 4 | import com.pengchaoling.util.RedisKeyUtil; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * Author: Lying 10 | * Data: 2017-02-21 11 | * description: 踩赞服务 12 | */ 13 | @Service 14 | public class LikeService { 15 | @Autowired 16 | JedisAdapter jedisAdapter; 17 | 18 | /** 19 | * 返回当前like数 20 | */ 21 | public long getLikeCount(int entityType, int entityId) { 22 | String likeKey = RedisKeyUtil.getLikeKey(entityType, entityId); 23 | return jedisAdapter.scard(likeKey); 24 | } 25 | 26 | 27 | /** 28 | * 获取该用户当前微博点赞情况,如果是like则返回1,0没点赞 29 | */ 30 | public int getLikeStatus(int userId, int entityType, int entityId) { 31 | String likeKey = RedisKeyUtil.getLikeKey(entityType, entityId); 32 | if (jedisAdapter.sismember(likeKey, String.valueOf(userId))) { 33 | return 1; 34 | } 35 | return 0; 36 | } 37 | 38 | /** 39 | * 点赞 40 | */ 41 | public long like(int userId, int entityType, int entityId) { 42 | String likeKey = RedisKeyUtil.getLikeKey(entityType, entityId); 43 | //判断是否已经点赞了,如果没赞就增加进去,赞了就删除算了 44 | if(getLikeStatus(userId,entityType,entityId)==0) 45 | jedisAdapter.sadd(likeKey, String.valueOf(userId)); 46 | else 47 | jedisAdapter.srem(likeKey, String.valueOf(userId)); 48 | 49 | //处理之后重新返回这个值,因为有可能几个人这时候都点了 50 | return jedisAdapter.scard(likeKey); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/MessageService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.dao.MessageDAO; 4 | import com.pengchaoling.model.Message; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Author: Lying 13 | * Data: 2017-02-20 14 | * description: 站内信 15 | */ 16 | 17 | @Service 18 | public class MessageService { 19 | @Autowired 20 | MessageDAO messageDAO; 21 | 22 | @Autowired 23 | SensitiveService sensitiveService; 24 | 25 | public int addMessage(Message message) { 26 | message.setContent(sensitiveService.filter(message.getContent())); 27 | return messageDAO.addMessage(message); 28 | } 29 | 30 | public List getConversationDetail(String conversationId) { 31 | return messageDAO.getConversationDetail(conversationId); 32 | } 33 | 34 | public List getConversationList(int userId) { 35 | return messageDAO.getConversationList(userId); 36 | } 37 | 38 | public int getConvesationUnreadCount(int userId, String conversationId) { 39 | return messageDAO.getConvesationUnreadCount(userId, conversationId); 40 | } 41 | 42 | public int getConvesationTotalCount(String conversationId){ 43 | return messageDAO.getConvesationTotalCount(conversationId); 44 | } 45 | 46 | //把状态修改为已读 47 | public void updateHasRead(int uid,String conversationId){ 48 | messageDAO.updateHasRead(uid,conversationId); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/SearchService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | 4 | import com.pengchaoling.model.UserInfo; 5 | import com.pengchaoling.model.Weibo; 6 | import org.apache.solr.client.solrj.SolrQuery; 7 | import org.apache.solr.client.solrj.impl.HttpSolrClient; 8 | import org.apache.solr.client.solrj.response.QueryResponse; 9 | import org.apache.solr.client.solrj.response.UpdateResponse; 10 | import org.apache.solr.common.SolrInputDocument; 11 | import org.apache.solr.common.params.MapSolrParams; 12 | import org.apache.solr.common.params.SolrParams; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.ArrayList; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | /** 21 | * Author: Lying 22 | * Data: 2017-02-23 23 | * description: 整合solr 搜索服务 24 | */ 25 | @Service 26 | public class SearchService { 27 | private static final String SOLR_URL = "http://127.0.0.1:8983/solr/sns"; 28 | //服务 29 | private HttpSolrClient client = new HttpSolrClient.Builder(SOLR_URL).build(); 30 | private static final String WEIBO_CONTENT_FIELD = "weibo"; 31 | private static final String NICKNAME_CONTENT_FIELD = "nickname"; 32 | 33 | /** 34 | * 搜索微博 35 | */ 36 | public List searchWeibo(String keyword, int offset, int count, 37 | String hlPre, String hlPos) throws Exception { 38 | List weibosList = new ArrayList<>(); 39 | SolrQuery query = new SolrQuery(keyword); 40 | Map map = new HashMap(); 41 | map.put("df",WEIBO_CONTENT_FIELD); 42 | SolrParams params = new MapSolrParams(map); 43 | query.add(params); 44 | query.setRows(count); 45 | query.setStart(offset); 46 | query.setHighlight(true); //高亮 47 | query.setHighlightSimplePre(hlPre); //前缀 48 | query.setHighlightSimplePost(hlPos); //后缀 49 | query.set("hl.fl", WEIBO_CONTENT_FIELD); 50 | //查询结果 51 | QueryResponse response = client.query(query); 52 | //解析结果 53 | for (Map.Entry>> entry : response.getHighlighting().entrySet()) { 54 | Weibo weibo = new Weibo(); 55 | weibo.setId(Integer.parseInt(entry.getKey())); 56 | 57 | if (entry.getValue().containsKey(WEIBO_CONTENT_FIELD)) { 58 | List contentList = entry.getValue().get(WEIBO_CONTENT_FIELD); 59 | if (contentList.size() > 0) { 60 | weibo.setContent(contentList.get(0)); 61 | } 62 | } 63 | 64 | weibosList.add(weibo); 65 | } 66 | return weibosList; 67 | } 68 | 69 | 70 | /** 71 | * 搜索用户 72 | */ 73 | public List searchUser(String keyword, int offset, int count, 74 | String hlPre, String hlPos) throws Exception { 75 | List userInfosList = new ArrayList<>(); 76 | SolrQuery query = new SolrQuery(keyword); 77 | Map map = new HashMap(); 78 | map.put("df",NICKNAME_CONTENT_FIELD); 79 | SolrParams params = new MapSolrParams(map); 80 | query.add(params); 81 | query.setRows(count); 82 | query.setStart(offset); 83 | query.setHighlight(true); //高亮 84 | query.setHighlightSimplePre(hlPre); //前缀 85 | query.setHighlightSimplePost(hlPos); //后缀 86 | query.set("hl.fl", NICKNAME_CONTENT_FIELD); 87 | //查询结果 88 | QueryResponse response = client.query(query); 89 | //解析结果 90 | for (Map.Entry>> entry : response.getHighlighting().entrySet()) { 91 | UserInfo userInfo = new UserInfo(); 92 | userInfo.setId(Integer.parseInt(entry.getKey())); 93 | 94 | if (entry.getValue().containsKey(NICKNAME_CONTENT_FIELD)) { 95 | List nicknameList = entry.getValue().get(NICKNAME_CONTENT_FIELD); 96 | if (nicknameList.size() > 0) { 97 | userInfo.setNickname(nicknameList.get(0)); 98 | } 99 | } 100 | 101 | userInfosList.add(userInfo); 102 | } 103 | return userInfosList; 104 | } 105 | 106 | /** 107 | * 微博发布的时候索引起来 108 | */ 109 | public boolean indexWeibo(int wid, String content) throws Exception { 110 | SolrInputDocument doc = new SolrInputDocument(); 111 | doc.setField("id", wid); 112 | doc.setField(WEIBO_CONTENT_FIELD, content); 113 | UpdateResponse response = client.add(doc, 1000); 114 | return response != null && response.getStatus() == 0; 115 | } 116 | 117 | 118 | /** 119 | * 添加用户的时候也把用户索引起来 120 | */ 121 | public boolean indexUserInfo(int id,int uid, String nickname) throws Exception { 122 | SolrInputDocument doc = new SolrInputDocument(); 123 | doc.setField("id", id); 124 | doc.setField("uid", uid); 125 | doc.setField(NICKNAME_CONTENT_FIELD, nickname); 126 | UpdateResponse response = client.add(doc, 1000); 127 | return response != null && response.getStatus() == 0; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.dao.LoginTicketDAO; 4 | import com.pengchaoling.dao.UserInfoDAO; 5 | import com.pengchaoling.model.UserInfo; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.util.HtmlUtils; 9 | 10 | /** 11 | * Author: Lying 12 | * Data: 2017-02-17 13 | * description: UserInfoService 14 | */ 15 | @Service 16 | public class UserInfoService { 17 | //通过以来注入方式来生成对象,不需要每次使用都new 18 | @Autowired 19 | private UserInfoDAO userInfoDAO; 20 | @Autowired 21 | private LoginTicketDAO loginTicketDAO; 22 | @Autowired 23 | SensitiveService sensitiveService; 24 | 25 | public UserInfo getUserInfoByUid(int uid) { 26 | return userInfoDAO.selectUserInfoByUid(uid); 27 | } 28 | //这是根据userinfo表的主键id来的 29 | public UserInfo getUserInfoById(int id) { 30 | return userInfoDAO.selectUserInfoById(id); 31 | } 32 | 33 | 34 | public UserInfo getUserInfoByNickname(String nickname){ 35 | return userInfoDAO.selectUserInfoByNickname(nickname); 36 | } 37 | 38 | public void IncWeibo(int uid){ 39 | userInfoDAO.IncWeibo(uid); 40 | } 41 | 42 | public void DecWeibo(int uid){ 43 | userInfoDAO.DecWeibo(uid); 44 | } 45 | 46 | /** 47 | * 默认用户信息插入,在注册的时候会调用这个函数去生成默认的函数 48 | * @param nickname 49 | * @param uid 50 | */ 51 | public void addDefaultUserInfo(String nickname,int uid){ 52 | UserInfo userInfo = new UserInfo(); 53 | userInfo.setNickname(nickname); 54 | userInfo.setUid(uid); 55 | userInfoDAO.addUserInfo(userInfo); 56 | 57 | } 58 | /** 59 | * 修改用户头像 60 | */ 61 | public void updateFace(String face50,String face80,String face180,int uid){ 62 | UserInfo userInfo = new UserInfo(); 63 | userInfo.setFace50(face50); 64 | userInfo.setFace80(face80); 65 | userInfo.setFace180(face180); 66 | userInfo.setUid(uid); 67 | userInfoDAO.updateFace(userInfo); 68 | } 69 | /** 70 | * 修改用户基本信息 71 | */ 72 | public void updateBasic(UserInfo userInfo){ 73 | //敏感词以及html过滤 74 | userInfo.setNickname(HtmlUtils.htmlEscape(sensitiveService.filter(userInfo.getNickname()))); 75 | userInfo.setTruename(HtmlUtils.htmlEscape(sensitiveService.filter(userInfo.getTruename()))); 76 | userInfo.setIntro(HtmlUtils.htmlEscape(sensitiveService.filter(userInfo.getIntro()))); 77 | 78 | userInfoDAO.updateBasic(userInfo); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.async.EventModel; 4 | import com.pengchaoling.async.EventProducer; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.dao.LoginTicketDAO; 7 | import com.pengchaoling.dao.UserDAO; 8 | import com.pengchaoling.model.EntityType; 9 | import com.pengchaoling.model.LoginTicket; 10 | import com.pengchaoling.model.User; 11 | import com.pengchaoling.model.UserInfo; 12 | import com.pengchaoling.util.SnsUtil; 13 | import org.apache.commons.lang.StringUtils; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Service; 16 | 17 | import java.util.*; 18 | 19 | /** 20 | * Author: Lying 21 | * Data: 2017-02-15 22 | * description: UserService 23 | */ 24 | @Service 25 | public class UserService { 26 | //通过以来注入方式来生成对象,不需要每次使用都new 27 | @Autowired 28 | private UserDAO userDAO; 29 | @Autowired 30 | private LoginTicketDAO loginTicketDAO; 31 | @Autowired 32 | private UserInfoService userInfoService; 33 | @Autowired 34 | EventProducer eventProducer; 35 | 36 | public User getUserById(int id) { 37 | return userDAO.selectById(id); 38 | } 39 | 40 | public User getUserByAccount(String account){ 41 | return userDAO.selectByAccount(account); 42 | } 43 | 44 | public User getUserByNickname(String nickname){ 45 | return userDAO.selectByNickname(nickname); 46 | } 47 | 48 | public List getUsers(int offset, int limit){ 49 | return userDAO.selectUsers(offset, limit); 50 | } 51 | 52 | /** 53 | * 注册验证以及注册完成 54 | */ 55 | public Map register(String account,String nickname, String pwd,String pwded) { 56 | Map map = new HashMap(); 57 | if (StringUtils.isBlank(account)) { 58 | map.put("msg", "用户名不能为空"); 59 | return map; 60 | } 61 | 62 | if (StringUtils.isBlank(nickname)) { 63 | map.put("msg", "昵称不能为空"); 64 | return map; 65 | } 66 | 67 | if (StringUtils.isBlank(pwd)) { 68 | map.put("msg", "密码不能为空"); 69 | return map; 70 | } 71 | 72 | if(!pwd.equals(pwded)){ 73 | map.put("msg","两次输入密码不一样"); 74 | return map; 75 | } 76 | 77 | User user = userDAO.selectByAccount(account); 78 | 79 | if (user != null) { 80 | map.put("msg", "该账户已被注册"); 81 | return map; 82 | } 83 | 84 | User nick = userDAO.selectByNickname(nickname); 85 | if(nick != null){ 86 | map.put("msg","该昵称已被人使用,换一个吧"); 87 | } 88 | 89 | // 设置用户信息,密码加盐 90 | user = new User(); 91 | user.setAccount(account); 92 | user.setNickname(nickname); 93 | user.setSalt(UUID.randomUUID().toString().substring(0, 5)); 94 | user.setPassword(SnsUtil.MD5(pwd+user.getSalt())); 95 | Date date = new Date(); 96 | //date.setTime(date.getTime()+3600); 97 | user.setRegistime(date); 98 | userDAO.addUser(user); 99 | 100 | //设置useInfo 101 | userInfoService.addDefaultUserInfo(nickname,user.getId()); 102 | UserInfo userInfo = userInfoService.getUserInfoByUid(user.getId()); 103 | 104 | //提交到异步事件队列去处理 105 | eventProducer.fireEvent(new EventModel(EventType.ADDUSER) 106 | .setActorId(userInfo.getId()).setEntityId(userInfo.getUid()) 107 | .setEntityType(EntityType.ENTITY_USER).setEntityOwnerId(userInfo.getUid()) 108 | .setExt("nickname", String.valueOf(userInfo.getNickname()))); 109 | 110 | String ticket = addLoginTicket(user.getId()); 111 | map.put("ticket", ticket); 112 | return map; 113 | } 114 | /** 115 | * 登录处理 116 | */ 117 | public Map login(String account, String password) { 118 | Map map = new HashMap(); 119 | if (StringUtils.isBlank(account)) { 120 | map.put("msg", "账号不能为空"); 121 | return map; 122 | } 123 | 124 | if (StringUtils.isBlank(password)) { 125 | map.put("msg", "密码不能为空"); 126 | return map; 127 | } 128 | 129 | User user = userDAO.selectByAccount(account); 130 | 131 | if (user == null) { 132 | map.put("msg", "账号不存在"); 133 | return map; 134 | } 135 | 136 | if (!SnsUtil.MD5(password+user.getSalt()).equals(user.getPassword())) { 137 | map.put("msg", "密码不正确"); 138 | return map; 139 | } 140 | 141 | String ticket = addLoginTicket(user.getId()); 142 | map.put("ticket", ticket); 143 | return map; 144 | } 145 | /** 146 | * 登录ticket入库 147 | */ 148 | private String addLoginTicket(int uid) { 149 | LoginTicket ticket = new LoginTicket(); 150 | ticket.setUid(uid); 151 | Date date = new Date(); 152 | date.setTime(date.getTime() + 1000*3600*24); 153 | ticket.setExpired(date); 154 | ticket.setStatus(0); 155 | ticket.setTicket(UUID.randomUUID().toString().replaceAll("-", "")); 156 | loginTicketDAO.addTicket(ticket); 157 | return ticket.getTicket(); 158 | } 159 | /** 160 | * 手动安全退出登陆,修改ticket的statue,ticket将失效,下次登陆会重新生成 161 | */ 162 | public void logout(String ticket) { 163 | loginTicketDAO.updateStatus(ticket, 1); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/service/WeiboService.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.service; 2 | 3 | import com.pengchaoling.async.EventModel; 4 | import com.pengchaoling.async.EventProducer; 5 | import com.pengchaoling.async.EventType; 6 | import com.pengchaoling.dao.KeepDAO; 7 | import com.pengchaoling.dao.PictureDAO; 8 | import com.pengchaoling.dao.WeiboDAO; 9 | import com.pengchaoling.model.*; 10 | import com.pengchaoling.util.SnsUtil; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.web.util.HtmlUtils; 16 | 17 | import java.util.List; 18 | import java.util.regex.Matcher; 19 | import java.util.regex.Pattern; 20 | 21 | /** 22 | * Author: Lying 23 | * Data: 2017-02-19 24 | * description: 25 | */ 26 | @Service 27 | public class WeiboService { 28 | private static final Logger logger = LoggerFactory.getLogger(WeiboService.class); 29 | 30 | @Autowired 31 | WeiboDAO weiboDAO; 32 | @Autowired 33 | PictureDAO pictureDAO; 34 | @Autowired 35 | KeepDAO keepDAO; 36 | @Autowired 37 | SensitiveService sensitiveService; 38 | @Autowired 39 | EventProducer eventProducer; 40 | @Autowired 41 | HostHolder hostHolder; 42 | @Autowired 43 | UserInfoService userInfoService; 44 | 45 | 46 | public int addWeibo(Weibo weibo){ 47 | //html过滤 48 | weibo.setContent(HtmlUtils.htmlEscape(weibo.getContent())); 49 | //敏感词 过滤掉 50 | weibo.setContent(sensitiveService.filter(weibo.getContent())); 51 | int res = weiboDAO.addWeibo(weibo); 52 | if(res>0) { 53 | EventType eventType = weibo.getIsturn() > 0 ? EventType.TURNWEIBO : EventType.ADDWEIBO; 54 | //提交到异步事件队列去处理 55 | eventProducer.fireEvent(new EventModel(eventType) 56 | .setActorId(hostHolder.getUser().getId()).setEntityId(weibo.getId()) 57 | .setEntityType(EntityType.ENTITY_WEIBO).setEntityOwnerId(weibo.getUid()) 58 | .setExt("content", String.valueOf(weibo.getContent()))); 59 | } 60 | return res; 61 | } 62 | 63 | public int addPicture(Picture picture){ 64 | return pictureDAO.addWPicture(picture); 65 | } 66 | 67 | public Picture selectPictureByWid(int wid){ 68 | return pictureDAO.selectPictureByWid(wid); 69 | } 70 | 71 | public Weibo selectWeiboById(int id){ 72 | Weibo weibo = weiboDAO.selectWeiBoById(id); 73 | if(weibo!=null) 74 | weibo.setContent(replaceAtme(weibo.getContent())); 75 | return weibo; 76 | } 77 | 78 | public List selectWeibos(){ 79 | List weibos = weiboDAO.selectWeibos(); 80 | if(!weibos.isEmpty()){ 81 | for(int i=0;i selectWeibosByUid(int uid){ 94 | 95 | List weibos = weiboDAO.selectWeibosByUid(uid); 96 | if(!weibos.isEmpty()){ 97 | for(int i=0;i selectKeepsByuid(int uid){ 128 | return keepDAO.selectKeepsByuid(uid); 129 | } 130 | 131 | public Keep selectKeepByUidWid(Keep keep){ 132 | return keepDAO.selectKeepByUidWid(keep); 133 | } 134 | 135 | public void delectWeiboByWid(int wid){ 136 | weiboDAO.deleteWeiboById(wid); 137 | } 138 | 139 | //辅助方法 提供给本类使用,替换@用户名 以及替换 表情包 140 | private String replaceAtme(String content){ 141 | //正则表达式匹配出所有AT用户 142 | Pattern pt = Pattern.compile("@(([\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]|[a-zA-Z])+(|\\s|,|。|?|;|!|‘|’|“|”)+?)"); 143 | Matcher mt = pt.matcher(content); 144 | while (mt.find()) { 145 | UserInfo userInfo = userInfoService.getUserInfoByNickname(mt.group().replace("@","")); 146 | if(userInfo != null){ 147 | String str = ""+mt.group()+""; 148 | content = content.replace(mt.group(),str); 149 | } 150 | } 151 | content = SnsUtil.emojiReplace(content); 152 | return content; 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/com/pengchaoling/util/RedisKeyUtil.java: -------------------------------------------------------------------------------- 1 | package com.pengchaoling.util; 2 | 3 | /** 4 | * Author: Lying 5 | * Data: 2017-02-21 6 | * description: 专门用于管理redis的key 所有的key都是从这里去的 7 | */ 8 | public class RedisKeyUtil { 9 | private static String SPLIT = ":"; 10 | private static String BIZ_LIKE = "LIKE"; //喜欢 11 | private static String BIZ_EVENTQUEUE = "EVENT_QUEUE"; //事件队列 12 | // 获取粉丝 13 | private static String BIZ_FOLLOWER = "FOLLOWER"; 14 | // 关注对象 15 | private static String BIZ_FOLLOWEE = "FOLLOWEE"; 16 | //时间线 17 | private static String BIZ_TIMELINE = "TIMELINE"; 18 | 19 | public static String getLikeKey(int entityType, int entityId) { 20 | return BIZ_LIKE + SPLIT + String.valueOf(entityType) + SPLIT + String.valueOf(entityId); 21 | } 22 | 23 | // 某个实体的粉丝key 24 | public static String getFollowerKey(int entityType, int entityId) { 25 | return BIZ_FOLLOWER + SPLIT + String.valueOf(entityType) + SPLIT + String.valueOf(entityId); 26 | } 27 | 28 | // 每个用户对某类实体的关注key 某一个用户关注某一类实体 29 | public static String getFolloweeKey(int userId, int entityType) { 30 | return BIZ_FOLLOWEE + SPLIT + String.valueOf(userId) + SPLIT + String.valueOf(entityType); 31 | } 32 | 33 | public static String getEventQueueKey() { 34 | return BIZ_EVENTQUEUE; 35 | } 36 | 37 | public static String getTimelineKey(int uid) { 38 | return BIZ_TIMELINE + SPLIT + String.valueOf(uid); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/resources/SensitiveWords.txt: -------------------------------------------------------------------------------- 1 | 嫖娼 2 | 赌博 3 | 情赌 4 | 色情 -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.velocity.suffix=.html 2 | spring.datasource.url=jdbc:mysql://localhost:3306/weibo?useUnicode=true&characterEncoding=utf8&useSSL=false 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | mybatis.config-location=classpath:mybatis-config.xml 6 | spring.velocity.toolbox-config-location=toolbox.xml -------------------------------------------------------------------------------- /src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/static/Css/common.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | * { 4 | padding: 0px; 5 | margin: 0px; 6 | font-size: 13px; 7 | color: #444; 8 | font:12px/1.125 Arial,Helvetica,sans-serif;_font-family:"SimSun"; 9 | } 10 | body{ 11 | background:url(../Images/body_bg.jpg) no-repeat fixed; 12 | } 13 | ul, ol { 14 | list-style: none; 15 | } 16 | a { 17 | text-decoration: none; 18 | color:#0a8cd2; 19 | } 20 | img { 21 | border:none; 22 | } 23 | table { 24 | border-collapse: collapse; 25 | } 26 | input,textarea,select,button{ 27 | outline:none; 28 | } 29 | .main{ 30 | width:980px; 31 | height:auto; 32 | overflow: hidden; 33 | margin:0 auto; 34 | background: url(../Images/main_bg.png) repeat-y; 35 | } 36 | .fleft{ 37 | float:left; 38 | } 39 | .fright{ 40 | float:right; 41 | } 42 | .clear{ 43 | clear:both; 44 | } 45 | .hidden{ 46 | display:none; 47 | } 48 | .cur_bg{ 49 | background:#000; 50 | opacity:0.8; 51 | filter:alpha(opacity = 80); 52 | } 53 | .close{ 54 | display: block; 55 | width:16px; 56 | height:16px; 57 | background:url(../Images/icon.png) no-repeat -75px -200px; 58 | margin: 7px 10px; 59 | cursor: pointer; 60 | } 61 | .remark { 62 | color : #8B8B85; 63 | } 64 | .backToTop{ 65 | width : 20px; 66 | height : 70px; 67 | border : 1px solid #ccc; 68 | padding-top : 10px; 69 | text-align : center; 70 | border-radius : 3px; 71 | line-height : 12px; 72 | color : #B8B7B7; 73 | cursor : pointer; 74 | background : #FAFAFA; 75 | display : none; 76 | position : fixed; 77 | _position : absolute; 78 | opacity : 0.8; 79 | filter:Alpha(opacity = 80); 80 | } 81 | .icon{ 82 | display:inline-block; 83 | background:url(../Images/icon.png); 84 | } 85 | .icon-write{ 86 | width:15px; 87 | height:14px; 88 | background-position: -50px 0; 89 | } 90 | .icon-msg{ 91 | width:15px; 92 | height:14px; 93 | background-position: -50px -50px; 94 | } 95 | .icon-msg-cur{ 96 | width:15px; 97 | height:14px; 98 | background-position: -50px -75px; 99 | } 100 | .icon-setup{ 101 | width:15px; 102 | height:16px; 103 | background-position: -50px -100px; 104 | } 105 | .icon-setup-cur{ 106 | width:15px; 107 | height:16px; 108 | background-position: -50px -125px; 109 | } 110 | .icon-home{ 111 | width:19px; 112 | height:18px; 113 | background-position: -1px -26px; 114 | } 115 | .icon-at{ 116 | width:19px; 117 | height:18px; 118 | background-position: 0 -50px; 119 | } 120 | .icon-comment{ 121 | width:19px; 122 | height:18px; 123 | background-position: -1px -75px; 124 | } 125 | .icon-letter{ 126 | width:19px; 127 | height:18px; 128 | background-position: -1px -100px; 129 | } 130 | .icon-keep{ 131 | width:19px; 132 | height:18px; 133 | background-position: -1px -125px; 134 | } 135 | .icon-group{ 136 | width:16px; 137 | height:18px; 138 | background-position: 0 -175px; 139 | } 140 | .icon-phiz{ 141 | width:15px; 142 | height:15px; 143 | cursor: pointer; 144 | background-position: 250px 0; 145 | } 146 | .icon-picture{ 147 | width:15px; 148 | height:14px; 149 | cursor: pointer; 150 | background-position: 250px -25px; 151 | } 152 | .icon-packup{ 153 | width:7px; 154 | height:11px; 155 | background-position: -175px 0; 156 | } 157 | .icon-bigpic{ 158 | width:10px; 159 | height:10px; 160 | background-position: -175px -25px; 161 | } 162 | .icon-totop{ 163 | width:12px; 164 | height:12px; 165 | background-position: -75px -100px; 166 | margin-bottom: 5px; 167 | } 168 | .icon-news{ 169 | width:12px; 170 | height:12px; 171 | } 172 | .icon-girl { 173 | width: 12px; 174 | height: 12px; 175 | background-position: -301px -25px; 176 | } 177 | .icon-boy { 178 | width: 12px; 179 | height: 12px; 180 | background-position: -301px 0px; 181 | } 182 | 183 | -------------------------------------------------------------------------------- /src/main/resources/static/Css/login.css: -------------------------------------------------------------------------------- 1 | @import './common.css'; 2 | 3 | body{ 4 | background: #C4EFF4; 5 | } 6 | #top-bg{ 7 | height: 166px; 8 | background: url(../Images/login_top_bg.png) no-repeat center; 9 | margin: 0 auto; 10 | } 11 | #login-form { 12 | height: 452px; 13 | background: url(../Images/login_bg_fom.png) no-repeat center; 14 | margin: 0 auto; 15 | } 16 | #login-wrap{ 17 | width:800px; 18 | height:300px; 19 | margin:auto; 20 | padding-top: 70px; 21 | padding-left: 50px; 22 | } 23 | #login-wrap p{ 24 | height: 40px; 25 | line-height: 40px; 26 | font-size: 14px; 27 | margin-bottom: 5px; 28 | color: #999; 29 | } 30 | #login-wrap p a{ 31 | display: inline-block; 32 | width: 100px; 33 | height: 30px; 34 | line-height: 30px; 35 | border: 2px solid #C0E6EA; 36 | color: #CC0000; 37 | text-align: center; 38 | font-size: 14px; 39 | background: #fff; 40 | font-weight: bold; 41 | border-radius: 6px; 42 | margin-left: 30px; 43 | } 44 | #login-form fieldset { 45 | width: 300px; 46 | height: auto; 47 | overflow: hidden; 48 | padding: 5px; 49 | border-radius: 6px; 50 | border: 1px solid #dcdcdc; 51 | } 52 | #login-form fieldset legend { 53 | margin-left: 20px; 54 | padding: 0 10px; 55 | color: #ccc; 56 | font-size: 13px; 57 | } 58 | .input{ 59 | width: 160px; 60 | height: 24px; 61 | line-height: 24px; 62 | background: #fff; 63 | border: 1px solid #ccc; 64 | border-radius: 4px; 65 | padding:5px; 66 | } 67 | #login-form fieldset p { 68 | padding: 10px 0; 69 | } 70 | #login-form fieldset p label { 71 | display: inline-block; 72 | width: 80px; 73 | height: 26px; 74 | line-height: 26px; 75 | text-align: right; 76 | } 77 | .auto{ 78 | margin-left: 90px; 79 | } 80 | #login-form fieldset p #login{ 81 | margin-left: 90px; 82 | width: 100px; 83 | height: 28px; 84 | cursor: pointer; 85 | border: 1px solid #53CD00; 86 | background: #90D925; 87 | border-radius: 4px; 88 | color: #EEF8E6; 89 | font-weight: bold; 90 | } 91 | /*CSS3 INPUT获取焦点时效果*/ 92 | textarea:focus, 93 | select:focus, 94 | input[type="text"]:focus, 95 | input[type="password"]:focus { 96 | border-color: rgba(82, 168, 236, 0.8); 97 | outline: 0; 98 | outline: thin dotted \9; 99 | /* IE6-9 */ 100 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 101 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 102 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 103 | } 104 | 105 | /*jquery validate 错误信息*/ 106 | input.error {border: 1px solid red;} 107 | input.valid {border: 1px solid #1d95f6;} -------------------------------------------------------------------------------- /src/main/resources/static/Css/regis.css: -------------------------------------------------------------------------------- 1 | @import './common.css'; 2 | 3 | body{ 4 | background: url(../Images/regis_bg.png) repeat-x #C8E1F0; 5 | } 6 | #logo{ 7 | width: 780px; 8 | height: 38px; 9 | background: url(../Images/logo.png) no-repeat; 10 | margin: 20px auto; 11 | } 12 | #reg-wrap{ 13 | width: 740px; 14 | height: auto; 15 | overflow: hidden; 16 | border-top: 2px solid #F00; 17 | margin: 0 auto; 18 | background: #FAFAFA; 19 | padding: 20px; 20 | } 21 | #reg-wrap fieldset{ 22 | padding: 20px; 23 | border: 1px solid #ccc; 24 | border-radius: 4px; 25 | } 26 | #reg-wrap fieldset legend { 27 | padding: 0 10px; 28 | font-size: 13px; 29 | } 30 | #reg-wrap fieldset p { 31 | padding: 20px; 32 | } 33 | #reg-wrap fieldset p label { 34 | display: inline-block; 35 | width: 100px; 36 | text-align: right; 37 | padding-right: 20px; 38 | color: #777; 39 | } 40 | .input { 41 | width: 200px; 42 | height: 20px; 43 | line-height: 20px; 44 | padding: 5px; 45 | border: 1px solid #ccc; 46 | border-radius: 4px; 47 | } 48 | .run { 49 | width: 100%; 50 | text-align: center; 51 | } 52 | #verify { 53 | width: 100px; 54 | } 55 | #verify-img { 56 | display: block; 57 | float: right; 58 | margin-right: 300px; 59 | margin-top: 3px; 60 | cursor: pointer; 61 | } 62 | #regis { 63 | width:200px; 64 | height:30px; 65 | border: 1px solid #FF9B00; 66 | background: #FFA920; 67 | border-radius: 4px; 68 | color: #fff; 69 | font-weight: bold; 70 | font-size: 14px; 71 | cursor: pointer; 72 | } 73 | 74 | /*CSS3 INPUT获取焦点时效果*/ 75 | textarea:focus, 76 | select:focus, 77 | input[type="text"]:focus, 78 | input[type="password"]:focus { 79 | border-color: rgba(82, 168, 236, 0.8); 80 | outline: 0; 81 | outline: thin dotted \9; 82 | /* IE6-9 */ 83 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 84 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 85 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); 86 | } 87 | 88 | /*****jQuery Validate 错误信息*****/ 89 | input.error{ 90 | border:1px solid red; 91 | } 92 | input.valid { 93 | border:1px solid #1d95f6; 94 | } 95 | span.error{ 96 | background : url(../Images/unchecked.gif) no-repeat 0 0; 97 | padding-left: 16px; 98 | color: #f00; 99 | } 100 | span.success{ 101 | background : url(../Images/checked.gif) no-repeat 0 0; 102 | padding-left: 16px; 103 | } -------------------------------------------------------------------------------- /src/main/resources/static/Images/checked.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/checked.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/default.jpg -------------------------------------------------------------------------------- /src/main/resources/static/Images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/loading.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/login_bg_fom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/login_bg_fom.png -------------------------------------------------------------------------------- /src/main/resources/static/Images/login_top_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/login_top_bg.png -------------------------------------------------------------------------------- /src/main/resources/static/Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/logo.png -------------------------------------------------------------------------------- /src/main/resources/static/Images/noface.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/noface.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/aini.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/aini.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/baibai.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/baibai.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/baobao.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/baobao.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/beishuang.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/beishuang.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/bishi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/bishi.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/bizui.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/bizui.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/canzui.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/canzui.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/chijing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/chijing.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/dahaqian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/dahaqian.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/guzhang.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/guzhang.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/haha.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/haha.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/haixiu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/haixiu.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/han.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/han.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/hehe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/hehe.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/heixian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/heixian.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/heng.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/heng.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/huaxin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/huaxin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/jiyan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/jiyan.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/keai.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/keai.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/kelian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/kelian.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/ku.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/ku.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/kun.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/kun.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/ldln.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/ldln.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/lei.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/lei.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/nu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/nu.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/numa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/numa.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/qian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/qian.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/qinqin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/qinqin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/shengbin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/shengbin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/shiwang.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/shiwang.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/shuai.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/shuai.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/shuangxin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/shuangxin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/shuijiao.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/shuijiao.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/sikao.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/sikao.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/taikaixin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/taikaixin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/touxiao.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/touxiao.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/tu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/tu.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/wabisi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/wabisi.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/weiqu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/weiqu.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/xin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/xin.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/xiu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/xiu.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/xixi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/xixi.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/yinxian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/yinxian.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/yiwen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/yiwen.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/youhenhen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/youhenhen.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/yun.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/yun.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/zuakuang.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/zuakuang.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/phiz/zuohenhen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/phiz/zuohenhen.gif -------------------------------------------------------------------------------- /src/main/resources/static/Images/regis_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/regis_bg.png -------------------------------------------------------------------------------- /src/main/resources/static/Images/style2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/style2.jpg -------------------------------------------------------------------------------- /src/main/resources/static/Images/style3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/style3.jpg -------------------------------------------------------------------------------- /src/main/resources/static/Images/style4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/style4.jpg -------------------------------------------------------------------------------- /src/main/resources/static/Images/unchecked.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengchaoling/sns/a7b54be05dc9a04bdd9db75ffb53e04821834eeb/src/main/resources/static/Images/unchecked.gif -------------------------------------------------------------------------------- /src/main/resources/static/Js/comment.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | $('.c-reply').toggle (function () { 4 | var name = $(this).parents('dl').find('dd a').html(); 5 | var str = '回复@' + name.replace(/:$/, ' ') + ':'; 6 | $(this).parent().next().show().find('textarea').val(str); 7 | }, function () { 8 | $(this).parent().next().hide(); 9 | }); 10 | 11 | //回复按钮 12 | $('.comment_btn').click(function () { 13 | var data = { 14 | wid : $(this).attr('wid'), 15 | content : $(this).parents('ul').prev().val() 16 | }; 17 | var obj = $(this).parents('.comment_list'); 18 | 19 | $.post(replyUrl, data, function (data) { 20 | if (data) { 21 | alert('评论已回复'); 22 | obj.hide(); 23 | } else { 24 | alert('回复失败请重试...'); 25 | } 26 | }, 'json'); 27 | }); 28 | 29 | //删除评论 30 | $('.del-comment').click(function () { 31 | var data = { 32 | cid : $(this).attr('cid'), 33 | wid : $(this).attr('wid') 34 | }; 35 | var isDel = confirm('确定删除该评论?'); 36 | var obj = $(this).parents('dl'); 37 | 38 | if (isDel) { 39 | $.post(delComment, data, function (data) { 40 | if (data) { 41 | obj.slideUp('slow', function () { 42 | obj.remove(); 43 | }); 44 | } else { 45 | alert('删除失败请重试...'); 46 | } 47 | }, 'json'); 48 | } 49 | }); 50 | 51 | 52 | /** 53 | * 表情处理 54 | * 以原生JS添加点击事件,不走jQuery队列事件机制 55 | */ 56 | var phiz = $('.phiz'); 57 | for (var i = 0; i < phiz.length; i++) { 58 | phiz[i].onclick = function () { 59 | //定位表情框到对应位置 60 | $('#phiz').show().css({ 61 | 'left' : $(this).offset().left, 62 | 'top' : $(this).offset().top + $(this).height() + 5 63 | }); 64 | //为每个表情图片添加事件 65 | var phizImg = $("#phiz img"); 66 | var sign = this.getAttribute('sign'); 67 | for (var i = 0; i < phizImg.length; i++){ 68 | phizImg[i].onclick = function () { 69 | var content = $('textarea[sign = '+sign+']'); 70 | content.val(content.val() + '[' + $(this).attr('title') + ']'); 71 | $('#phiz').hide(); 72 | } 73 | } 74 | } 75 | } 76 | //关闭表情框 77 | $('.close').hover(function () { 78 | $(this).css('backgroundPosition', '-100px -200px'); 79 | }, function () { 80 | $(this).css('backgroundPosition', '-75px -200px'); 81 | }).click(function () { 82 | $(this).parent().parent().hide(); 83 | $('#phiz').hide(); 84 | if ($('#turn').css('display') == 'none') { 85 | $('#opacity_bg').remove(); 86 | }; 87 | }); 88 | }); -------------------------------------------------------------------------------- /src/main/resources/static/Js/edit.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | //修改资料选项卡 4 | $('#sel-edit li').click( function () { 5 | var index = $(this).index(); 6 | $(this).addClass('edit-cur').siblings().removeClass('edit-cur'); 7 | $('.form').hide().eq(index).show(); 8 | } ); 9 | 10 | //城市联动 11 | var province = ''; 12 | $.each(city, function (i, k) { 13 | province += ''; 14 | }); 15 | $('select[name=province]').append(province).change(function () { 16 | var option = ''; 17 | if ($(this).val() == '') { 18 | option += ''; 19 | } else { 20 | var index = $(':selected', this).attr('index'); 21 | var data = city[index].child; 22 | for (var i = 0; i < data.length; i++) { 23 | option += ''; 24 | } 25 | } 26 | 27 | $('select[name=city]').html(option); 28 | }); 29 | 30 | //所在地默认选项 31 | address = address.split(' '); 32 | $('select[name=province]').val(address[0]); 33 | $.each(city, function (i, k) { 34 | if (k.name == address[0]) { 35 | var str = ''; 36 | for (var j in k.child) { 37 | str += '